diff options
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to 'OpenSim')
32 files changed, 1635 insertions, 178 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index d6cb91f..7c176c7 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | |||
@@ -327,7 +327,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID) | |||
327 | ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, | 327 | ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, |
328 | SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, | 328 | SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, |
329 | ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, | 329 | ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, |
330 | LinkNumber = @LinkNumber | 330 | LinkNumber = @LinkNumber, MediaURL = @MediaURL |
331 | WHERE UUID = @UUID | 331 | WHERE UUID = @UUID |
332 | END | 332 | END |
333 | ELSE | 333 | ELSE |
@@ -342,7 +342,7 @@ ELSE | |||
342 | PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, | 342 | PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, |
343 | OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, | 343 | OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, |
344 | ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, | 344 | ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, |
345 | ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber | 345 | ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL |
346 | ) VALUES ( | 346 | ) VALUES ( |
347 | @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, | 347 | @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, |
348 | @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, | 348 | @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, |
@@ -352,7 +352,7 @@ ELSE | |||
352 | @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, | 352 | @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, |
353 | @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, | 353 | @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, |
354 | @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, | 354 | @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, |
355 | @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber | 355 | @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL |
356 | ) | 356 | ) |
357 | END"; | 357 | END"; |
358 | 358 | ||
@@ -385,7 +385,7 @@ IF EXISTS (SELECT UUID FROM primshapes WHERE UUID = @UUID) | |||
385 | PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions, | 385 | PathSkew = @PathSkew, PathCurve = @PathCurve, PathRadiusOffset = @PathRadiusOffset, PathRevolutions = @PathRevolutions, |
386 | PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin, | 386 | PathTaperX = @PathTaperX, PathTaperY = @PathTaperY, PathTwist = @PathTwist, PathTwistBegin = @PathTwistBegin, |
387 | ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow, | 387 | ProfileBegin = @ProfileBegin, ProfileEnd = @ProfileEnd, ProfileCurve = @ProfileCurve, ProfileHollow = @ProfileHollow, |
388 | Texture = @Texture, ExtraParams = @ExtraParams, State = @State | 388 | Texture = @Texture, ExtraParams = @ExtraParams, State = @State, Media = @Media |
389 | WHERE UUID = @UUID | 389 | WHERE UUID = @UUID |
390 | END | 390 | END |
391 | ELSE | 391 | ELSE |
@@ -394,11 +394,11 @@ ELSE | |||
394 | primshapes ( | 394 | primshapes ( |
395 | UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, | 395 | UUID, Shape, ScaleX, ScaleY, ScaleZ, PCode, PathBegin, PathEnd, PathScaleX, PathScaleY, PathShearX, PathShearY, |
396 | PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, | 396 | PathSkew, PathCurve, PathRadiusOffset, PathRevolutions, PathTaperX, PathTaperY, PathTwist, PathTwistBegin, ProfileBegin, |
397 | ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State | 397 | ProfileEnd, ProfileCurve, ProfileHollow, Texture, ExtraParams, State, Media |
398 | ) VALUES ( | 398 | ) VALUES ( |
399 | @UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY, | 399 | @UUID, @Shape, @ScaleX, @ScaleY, @ScaleZ, @PCode, @PathBegin, @PathEnd, @PathScaleX, @PathScaleY, @PathShearX, @PathShearY, |
400 | @PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin, | 400 | @PathSkew, @PathCurve, @PathRadiusOffset, @PathRevolutions, @PathTaperX, @PathTaperY, @PathTwist, @PathTwistBegin, @ProfileBegin, |
401 | @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State | 401 | @ProfileEnd, @ProfileCurve, @ProfileHollow, @Texture, @ExtraParams, @State, @Media |
402 | ) | 402 | ) |
403 | END"; | 403 | END"; |
404 | 404 | ||
@@ -1127,6 +1127,9 @@ VALUES | |||
1127 | if (Convert.ToInt16(primRow["PassTouches"]) != 0) | 1127 | if (Convert.ToInt16(primRow["PassTouches"]) != 0) |
1128 | prim.PassTouches = true; | 1128 | prim.PassTouches = true; |
1129 | prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); | 1129 | prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); |
1130 | |||
1131 | if (!(primRow["MediaURL"] is System.DBNull)) | ||
1132 | prim.MediaUrl = (string)primRow["MediaURL"]; | ||
1130 | 1133 | ||
1131 | return prim; | 1134 | return prim; |
1132 | } | 1135 | } |
@@ -1180,6 +1183,9 @@ VALUES | |||
1180 | { | 1183 | { |
1181 | } | 1184 | } |
1182 | 1185 | ||
1186 | if (!(shapeRow["Media"] is System.DBNull)) | ||
1187 | baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]); | ||
1188 | |||
1183 | return baseShape; | 1189 | return baseShape; |
1184 | } | 1190 | } |
1185 | 1191 | ||
@@ -1509,7 +1515,8 @@ VALUES | |||
1509 | parameters.Add(_Database.CreateParameter("PassTouches", 1)); | 1515 | parameters.Add(_Database.CreateParameter("PassTouches", 1)); |
1510 | else | 1516 | else |
1511 | parameters.Add(_Database.CreateParameter("PassTouches", 0)); | 1517 | parameters.Add(_Database.CreateParameter("PassTouches", 0)); |
1512 | parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); | 1518 | parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); |
1519 | parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl)); | ||
1513 | 1520 | ||
1514 | return parameters.ToArray(); | 1521 | return parameters.ToArray(); |
1515 | } | 1522 | } |
@@ -1557,6 +1564,7 @@ VALUES | |||
1557 | parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); | 1564 | parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); |
1558 | parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); | 1565 | parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); |
1559 | parameters.Add(_Database.CreateParameter("State", s.State)); | 1566 | parameters.Add(_Database.CreateParameter("State", s.State)); |
1567 | parameters.Add(_Database.CreateParameter("Media", null == s.Media ? null : s.Media.ToXml())); | ||
1560 | 1568 | ||
1561 | return parameters.ToArray(); | 1569 | return parameters.ToArray(); |
1562 | } | 1570 | } |
diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations index e912d64..e2e8cbb 100644 --- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations | |||
@@ -1,4 +1,4 @@ | |||
1 | | 1 | |
2 | :VERSION 1 | 2 | :VERSION 1 |
3 | 3 | ||
4 | CREATE TABLE [dbo].[prims]( | 4 | CREATE TABLE [dbo].[prims]( |
@@ -925,5 +925,12 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0 | |||
925 | 925 | ||
926 | COMMIT | 926 | COMMIT |
927 | 927 | ||
928 | :VERSION 24 | ||
929 | -- Added post 0.7 | ||
930 | |||
931 | BEGIN TRANSACTION | ||
928 | 932 | ||
933 | ALTER TABLE prims ADD COLUMN MediaURL varchar(255) | ||
934 | ALTER TABLE primshapes ADD COLUMN Media TEXT | ||
929 | 935 | ||
936 | COMMIT \ No newline at end of file | ||
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index bfeae12..d8debc5 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | |||
@@ -174,7 +174,7 @@ namespace OpenSim.Data.MySQL | |||
174 | "ParticleSystem, ClickAction, Material, " + | 174 | "ParticleSystem, ClickAction, Material, " + |
175 | "CollisionSound, CollisionSoundVolume, " + | 175 | "CollisionSound, CollisionSoundVolume, " + |
176 | "PassTouches, " + | 176 | "PassTouches, " + |
177 | "LinkNumber) values (" + "?UUID, " + | 177 | "LinkNumber, MediaURL) values (" + "?UUID, " + |
178 | "?CreationDate, ?Name, ?Text, " + | 178 | "?CreationDate, ?Name, ?Text, " + |
179 | "?Description, ?SitName, ?TouchName, " + | 179 | "?Description, ?SitName, ?TouchName, " + |
180 | "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + | 180 | "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + |
@@ -205,7 +205,7 @@ namespace OpenSim.Data.MySQL | |||
205 | "?SaleType, ?ColorR, ?ColorG, " + | 205 | "?SaleType, ?ColorR, ?ColorG, " + |
206 | "?ColorB, ?ColorA, ?ParticleSystem, " + | 206 | "?ColorB, ?ColorA, ?ParticleSystem, " + |
207 | "?ClickAction, ?Material, ?CollisionSound, " + | 207 | "?ClickAction, ?Material, ?CollisionSound, " + |
208 | "?CollisionSoundVolume, ?PassTouches, ?LinkNumber)"; | 208 | "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; |
209 | 209 | ||
210 | FillPrimCommand(cmd, prim, obj.UUID, regionUUID); | 210 | FillPrimCommand(cmd, prim, obj.UUID, regionUUID); |
211 | 211 | ||
@@ -222,7 +222,7 @@ namespace OpenSim.Data.MySQL | |||
222 | "PathTaperX, PathTaperY, PathTwist, " + | 222 | "PathTaperX, PathTaperY, PathTwist, " + |
223 | "PathTwistBegin, ProfileBegin, ProfileEnd, " + | 223 | "PathTwistBegin, ProfileBegin, ProfileEnd, " + |
224 | "ProfileCurve, ProfileHollow, Texture, " + | 224 | "ProfileCurve, ProfileHollow, Texture, " + |
225 | "ExtraParams, State) values (?UUID, " + | 225 | "ExtraParams, State, Media) values (?UUID, " + |
226 | "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + | 226 | "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + |
227 | "?PCode, ?PathBegin, ?PathEnd, " + | 227 | "?PCode, ?PathBegin, ?PathEnd, " + |
228 | "?PathScaleX, ?PathScaleY, " + | 228 | "?PathScaleX, ?PathScaleY, " + |
@@ -233,7 +233,7 @@ namespace OpenSim.Data.MySQL | |||
233 | "?PathTwistBegin, ?ProfileBegin, " + | 233 | "?PathTwistBegin, ?ProfileBegin, " + |
234 | "?ProfileEnd, ?ProfileCurve, " + | 234 | "?ProfileEnd, ?ProfileCurve, " + |
235 | "?ProfileHollow, ?Texture, ?ExtraParams, " + | 235 | "?ProfileHollow, ?Texture, ?ExtraParams, " + |
236 | "?State)"; | 236 | "?State, ?Media)"; |
237 | 237 | ||
238 | FillShapeCommand(cmd, prim); | 238 | FillShapeCommand(cmd, prim); |
239 | 239 | ||
@@ -1184,6 +1184,9 @@ namespace OpenSim.Data.MySQL | |||
1184 | 1184 | ||
1185 | prim.PassTouches = ((sbyte)row["PassTouches"] != 0); | 1185 | prim.PassTouches = ((sbyte)row["PassTouches"] != 0); |
1186 | prim.LinkNum = (int)row["LinkNumber"]; | 1186 | prim.LinkNum = (int)row["LinkNumber"]; |
1187 | |||
1188 | if (!(row["MediaURL"] is System.DBNull)) | ||
1189 | prim.MediaUrl = (string)row["MediaURL"]; | ||
1187 | 1190 | ||
1188 | return prim; | 1191 | return prim; |
1189 | } | 1192 | } |
@@ -1521,6 +1524,7 @@ namespace OpenSim.Data.MySQL | |||
1521 | cmd.Parameters.AddWithValue("PassTouches", 0); | 1524 | cmd.Parameters.AddWithValue("PassTouches", 0); |
1522 | 1525 | ||
1523 | cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); | 1526 | cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); |
1527 | cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); | ||
1524 | } | 1528 | } |
1525 | 1529 | ||
1526 | /// <summary> | 1530 | /// <summary> |
@@ -1700,6 +1704,9 @@ namespace OpenSim.Data.MySQL | |||
1700 | s.ExtraParams = (byte[])row["ExtraParams"]; | 1704 | s.ExtraParams = (byte[])row["ExtraParams"]; |
1701 | 1705 | ||
1702 | s.State = (byte)(int)row["State"]; | 1706 | s.State = (byte)(int)row["State"]; |
1707 | |||
1708 | if (!(row["Media"] is System.DBNull)) | ||
1709 | s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); | ||
1703 | 1710 | ||
1704 | return s; | 1711 | return s; |
1705 | } | 1712 | } |
@@ -1743,6 +1750,7 @@ namespace OpenSim.Data.MySQL | |||
1743 | cmd.Parameters.AddWithValue("Texture", s.TextureEntry); | 1750 | cmd.Parameters.AddWithValue("Texture", s.TextureEntry); |
1744 | cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); | 1751 | cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); |
1745 | cmd.Parameters.AddWithValue("State", s.State); | 1752 | cmd.Parameters.AddWithValue("State", s.State); |
1753 | cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml()); | ||
1746 | } | 1754 | } |
1747 | 1755 | ||
1748 | public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) | 1756 | public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) |
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index 88ee748..ce99ce4 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations | |||
@@ -1,4 +1,4 @@ | |||
1 | | 1 | |
2 | :VERSION 1 #--------------------- | 2 | :VERSION 1 #--------------------- |
3 | 3 | ||
4 | BEGIN; | 4 | BEGIN; |
@@ -800,3 +800,10 @@ BEGIN; | |||
800 | ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`; | 800 | ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` FLOAT(4,2) NOT NULL DEFAULT '0.20' AFTER `cloud_detail_density`, CHANGE COLUMN `cloud_scroll_y` `cloud_scroll_y` FLOAT(4,2) NOT NULL DEFAULT '0.01' AFTER `cloud_scroll_x_lock`; |
801 | COMMIT; | 801 | COMMIT; |
802 | 802 | ||
803 | :VERSION 35 #--------------------- | ||
804 | -- Added post 0.7 | ||
805 | |||
806 | BEGIN; | ||
807 | ALTER TABLE prims ADD COLUMN MediaURL varchar(255); | ||
808 | ALTER TABLE primshapes ADD COLUMN Media TEXT; | ||
809 | COMMIT; \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/Resources/020_RegionStore.sql b/OpenSim/Data/SQLite/Resources/020_RegionStore.sql new file mode 100644 index 0000000..39cb752 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/020_RegionStore.sql | |||
@@ -0,0 +1,6 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | ALTER TABLE prims ADD COLUMN MediaURL varchar(255); | ||
4 | ALTER TABLE primshapes ADD COLUMN Media TEXT; | ||
5 | |||
6 | COMMIT; \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 81d0ac4..4208050 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs | |||
@@ -34,6 +34,7 @@ using System.Reflection; | |||
34 | using log4net; | 34 | using log4net; |
35 | using Mono.Data.Sqlite; | 35 | using Mono.Data.Sqlite; |
36 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | using OpenMetaverse.StructuredData; | ||
37 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
38 | using OpenSim.Region.Framework.Interfaces; | 39 | using OpenSim.Region.Framework.Interfaces; |
39 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
@@ -974,6 +975,8 @@ namespace OpenSim.Data.SQLite | |||
974 | createCol(prims, "CollisionSoundVolume", typeof(Double)); | 975 | createCol(prims, "CollisionSoundVolume", typeof(Double)); |
975 | 976 | ||
976 | createCol(prims, "VolumeDetect", typeof(Int16)); | 977 | createCol(prims, "VolumeDetect", typeof(Int16)); |
978 | |||
979 | createCol(prims, "MediaURL", typeof(String)); | ||
977 | 980 | ||
978 | // Add in contraints | 981 | // Add in contraints |
979 | prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]}; | 982 | prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]}; |
@@ -1021,6 +1024,7 @@ namespace OpenSim.Data.SQLite | |||
1021 | // way to specify this as a blob atm | 1024 | // way to specify this as a blob atm |
1022 | createCol(shapes, "Texture", typeof (Byte[])); | 1025 | createCol(shapes, "Texture", typeof (Byte[])); |
1023 | createCol(shapes, "ExtraParams", typeof (Byte[])); | 1026 | createCol(shapes, "ExtraParams", typeof (Byte[])); |
1027 | createCol(shapes, "Media", typeof(String)); | ||
1024 | 1028 | ||
1025 | shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]}; | 1029 | shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]}; |
1026 | 1030 | ||
@@ -1339,6 +1343,12 @@ namespace OpenSim.Data.SQLite | |||
1339 | 1343 | ||
1340 | if (Convert.ToInt16(row["VolumeDetect"]) != 0) | 1344 | if (Convert.ToInt16(row["VolumeDetect"]) != 0) |
1341 | prim.VolumeDetectActive = true; | 1345 | prim.VolumeDetectActive = true; |
1346 | |||
1347 | if (!(row["MediaURL"] is System.DBNull)) | ||
1348 | { | ||
1349 | //m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType()); | ||
1350 | prim.MediaUrl = (string)row["MediaURL"]; | ||
1351 | } | ||
1342 | 1352 | ||
1343 | return prim; | 1353 | return prim; |
1344 | } | 1354 | } |
@@ -1614,7 +1624,6 @@ namespace OpenSim.Data.SQLite | |||
1614 | row["PayButton3"] = prim.PayPrice[3]; | 1624 | row["PayButton3"] = prim.PayPrice[3]; |
1615 | row["PayButton4"] = prim.PayPrice[4]; | 1625 | row["PayButton4"] = prim.PayPrice[4]; |
1616 | 1626 | ||
1617 | |||
1618 | row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation); | 1627 | row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation); |
1619 | row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem); | 1628 | row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem); |
1620 | 1629 | ||
@@ -1674,7 +1683,8 @@ namespace OpenSim.Data.SQLite | |||
1674 | row["VolumeDetect"] = 1; | 1683 | row["VolumeDetect"] = 1; |
1675 | else | 1684 | else |
1676 | row["VolumeDetect"] = 0; | 1685 | row["VolumeDetect"] = 0; |
1677 | 1686 | ||
1687 | row["MediaURL"] = prim.MediaUrl; | ||
1678 | } | 1688 | } |
1679 | 1689 | ||
1680 | /// <summary> | 1690 | /// <summary> |
@@ -1849,6 +1859,10 @@ namespace OpenSim.Data.SQLite | |||
1849 | s.TextureEntry = textureEntry; | 1859 | s.TextureEntry = textureEntry; |
1850 | 1860 | ||
1851 | s.ExtraParams = (byte[]) row["ExtraParams"]; | 1861 | s.ExtraParams = (byte[]) row["ExtraParams"]; |
1862 | |||
1863 | if (!(row["Media"] is System.DBNull)) | ||
1864 | s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); | ||
1865 | |||
1852 | return s; | 1866 | return s; |
1853 | } | 1867 | } |
1854 | 1868 | ||
@@ -1892,17 +1906,19 @@ namespace OpenSim.Data.SQLite | |||
1892 | 1906 | ||
1893 | row["Texture"] = s.TextureEntry; | 1907 | row["Texture"] = s.TextureEntry; |
1894 | row["ExtraParams"] = s.ExtraParams; | 1908 | row["ExtraParams"] = s.ExtraParams; |
1909 | |||
1910 | if (s.Media != null) | ||
1911 | row["Media"] = s.Media.ToXml(); | ||
1895 | } | 1912 | } |
1896 | 1913 | ||
1897 | /// <summary> | 1914 | /// <summary> |
1898 | /// | 1915 | /// Persistently store a prim. |
1899 | /// </summary> | 1916 | /// </summary> |
1900 | /// <param name="prim"></param> | 1917 | /// <param name="prim"></param> |
1901 | /// <param name="sceneGroupID"></param> | 1918 | /// <param name="sceneGroupID"></param> |
1902 | /// <param name="regionUUID"></param> | 1919 | /// <param name="regionUUID"></param> |
1903 | private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) | 1920 | private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) |
1904 | { | 1921 | { |
1905 | |||
1906 | DataTable prims = ds.Tables["prims"]; | 1922 | DataTable prims = ds.Tables["prims"]; |
1907 | DataTable shapes = ds.Tables["primshapes"]; | 1923 | DataTable shapes = ds.Tables["primshapes"]; |
1908 | 1924 | ||
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 990c859..a4587d8 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs | |||
@@ -26,12 +26,17 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.Drawing; | 30 | using System.Drawing; |
30 | using System.Drawing.Imaging; | 31 | using System.Drawing.Imaging; |
32 | using System.IO; | ||
31 | using System.Reflection; | 33 | using System.Reflection; |
34 | using System.Xml; | ||
35 | using System.Xml.Schema; | ||
32 | using System.Xml.Serialization; | 36 | using System.Xml.Serialization; |
33 | using log4net; | 37 | using log4net; |
34 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using OpenMetaverse.StructuredData; | ||
35 | 40 | ||
36 | namespace OpenSim.Framework | 41 | namespace OpenSim.Framework |
37 | { | 42 | { |
@@ -170,6 +175,13 @@ namespace OpenSim.Framework | |||
170 | } | 175 | } |
171 | } | 176 | } |
172 | } | 177 | } |
178 | |||
179 | /// <summary> | ||
180 | /// Entries to store media textures on each face | ||
181 | /// </summary> | ||
182 | /// Do not change this value directly - always do it through an IMoapModule. | ||
183 | /// Lock before manipulating. | ||
184 | public MediaList Media { get; set; } | ||
173 | 185 | ||
174 | public PrimitiveBaseShape() | 186 | public PrimitiveBaseShape() |
175 | { | 187 | { |
@@ -1207,5 +1219,104 @@ namespace OpenSim.Framework | |||
1207 | 1219 | ||
1208 | return prim; | 1220 | return prim; |
1209 | } | 1221 | } |
1210 | } | 1222 | |
1211 | } | 1223 | /// <summary> |
1224 | /// Encapsulates a list of media entries. | ||
1225 | /// </summary> | ||
1226 | /// This class is necessary because we want to replace auto-serialization of MediaEntry with something more | ||
1227 | /// OSD like and less vulnerable to change. | ||
1228 | public class MediaList : List<MediaEntry>, IXmlSerializable | ||
1229 | { | ||
1230 | public const string MEDIA_TEXTURE_TYPE = "sl"; | ||
1231 | |||
1232 | public MediaList() : base() {} | ||
1233 | public MediaList(IEnumerable<MediaEntry> collection) : base(collection) {} | ||
1234 | public MediaList(int capacity) : base(capacity) {} | ||
1235 | |||
1236 | public XmlSchema GetSchema() | ||
1237 | { | ||
1238 | return null; | ||
1239 | } | ||
1240 | |||
1241 | public string ToXml() | ||
1242 | { | ||
1243 | lock (this) | ||
1244 | { | ||
1245 | using (StringWriter sw = new StringWriter()) | ||
1246 | { | ||
1247 | using (XmlTextWriter xtw = new XmlTextWriter(sw)) | ||
1248 | { | ||
1249 | xtw.WriteStartElement("OSMedia"); | ||
1250 | xtw.WriteAttributeString("type", MEDIA_TEXTURE_TYPE); | ||
1251 | xtw.WriteAttributeString("version", "0.1"); | ||
1252 | |||
1253 | OSDArray meArray = new OSDArray(); | ||
1254 | foreach (MediaEntry me in this) | ||
1255 | { | ||
1256 | OSD osd = (null == me ? new OSD() : me.GetOSD()); | ||
1257 | meArray.Add(osd); | ||
1258 | } | ||
1259 | |||
1260 | xtw.WriteStartElement("OSData"); | ||
1261 | xtw.WriteRaw(OSDParser.SerializeLLSDXmlString(meArray)); | ||
1262 | xtw.WriteEndElement(); | ||
1263 | |||
1264 | xtw.WriteEndElement(); | ||
1265 | |||
1266 | xtw.Flush(); | ||
1267 | return sw.ToString(); | ||
1268 | } | ||
1269 | } | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1273 | public void WriteXml(XmlWriter writer) | ||
1274 | { | ||
1275 | writer.WriteRaw(ToXml()); | ||
1276 | } | ||
1277 | |||
1278 | public static MediaList FromXml(string rawXml) | ||
1279 | { | ||
1280 | MediaList ml = new MediaList(); | ||
1281 | ml.ReadXml(rawXml); | ||
1282 | return ml; | ||
1283 | } | ||
1284 | |||
1285 | public void ReadXml(string rawXml) | ||
1286 | { | ||
1287 | using (StringReader sr = new StringReader(rawXml)) | ||
1288 | { | ||
1289 | using (XmlTextReader xtr = new XmlTextReader(sr)) | ||
1290 | { | ||
1291 | xtr.MoveToContent(); | ||
1292 | |||
1293 | string type = xtr.GetAttribute("type"); | ||
1294 | //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); | ||
1295 | |||
1296 | if (type != MEDIA_TEXTURE_TYPE) | ||
1297 | return; | ||
1298 | |||
1299 | xtr.ReadStartElement("OSMedia"); | ||
1300 | |||
1301 | OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); | ||
1302 | foreach (OSD osdMe in osdMeArray) | ||
1303 | { | ||
1304 | MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); | ||
1305 | Add(me); | ||
1306 | } | ||
1307 | |||
1308 | xtr.ReadEndElement(); | ||
1309 | } | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | public void ReadXml(XmlReader reader) | ||
1314 | { | ||
1315 | if (reader.IsEmptyElement) | ||
1316 | return; | ||
1317 | |||
1318 | ReadXml(reader.ReadInnerXml()); | ||
1319 | } | ||
1320 | } | ||
1321 | } | ||
1322 | } \ No newline at end of file | ||
diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs index 475a9de..3143e3b 100644 --- a/OpenSim/Framework/Serialization/ArchiveConstants.cs +++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Text; | ||
30 | using OpenMetaverse; | 31 | using OpenMetaverse; |
31 | 32 | ||
32 | namespace OpenSim.Framework.Serialization | 33 | namespace OpenSim.Framework.Serialization |
@@ -171,6 +172,30 @@ namespace OpenSim.Framework.Serialization | |||
171 | public static string CreateOarObjectPath(string objectName, UUID uuid, Vector3 pos) | 172 | public static string CreateOarObjectPath(string objectName, UUID uuid, Vector3 pos) |
172 | { | 173 | { |
173 | return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos); | 174 | return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos); |
174 | } | 175 | } |
176 | |||
177 | /// <summary> | ||
178 | /// Extract a plain path from an IAR path | ||
179 | /// </summary> | ||
180 | /// <param name="iarPath"></param> | ||
181 | /// <returns></returns> | ||
182 | public static string ExtractPlainPathFromIarPath(string iarPath) | ||
183 | { | ||
184 | List<string> plainDirs = new List<string>(); | ||
185 | |||
186 | string[] iarDirs = iarPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | ||
187 | |||
188 | foreach (string iarDir in iarDirs) | ||
189 | { | ||
190 | if (!iarDir.Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR)) | ||
191 | plainDirs.Add(iarDir); | ||
192 | |||
193 | int i = iarDir.LastIndexOf(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); | ||
194 | |||
195 | plainDirs.Add(iarDir.Remove(i)); | ||
196 | } | ||
197 | |||
198 | return string.Join("/", plainDirs.ToArray()); | ||
199 | } | ||
175 | } | 200 | } |
176 | } | 201 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 8123f2f..ffa30d5 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -362,7 +362,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
362 | string path = request.RawUrl; | 362 | string path = request.RawUrl; |
363 | string handlerKey = GetHandlerKey(request.HttpMethod, path); | 363 | string handlerKey = GetHandlerKey(request.HttpMethod, path); |
364 | 364 | ||
365 | //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); | 365 | // m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); |
366 | 366 | ||
367 | if (TryGetStreamHandler(handlerKey, out requestHandler)) | 367 | if (TryGetStreamHandler(handlerKey, out requestHandler)) |
368 | { | 368 | { |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index cd7c11b..d2d1e8f 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -4328,8 +4328,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4328 | 4328 | ||
4329 | public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) | 4329 | public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) |
4330 | { | 4330 | { |
4331 | |||
4332 | |||
4333 | int notifyCount = ownersAndCount.Count; | 4331 | int notifyCount = ownersAndCount.Count; |
4334 | ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); | 4332 | ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); |
4335 | 4333 | ||
@@ -4601,6 +4599,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4601 | update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; | 4599 | update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; |
4602 | update.Scale = data.Shape.Scale; | 4600 | update.Scale = data.Shape.Scale; |
4603 | update.Text = Util.StringToBytes256(data.Text); | 4601 | update.Text = Util.StringToBytes256(data.Text); |
4602 | update.MediaURL = Util.StringToBytes256(data.MediaUrl); | ||
4604 | 4603 | ||
4605 | #region PrimFlags | 4604 | #region PrimFlags |
4606 | 4605 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 31dfe14..7683288 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -54,6 +54,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
54 | 54 | ||
55 | private UserAccount m_userInfo; | 55 | private UserAccount m_userInfo; |
56 | private string m_invPath; | 56 | private string m_invPath; |
57 | |||
58 | /// <summary> | ||
59 | /// Do we want to merge this load with existing inventory? | ||
60 | /// </summary> | ||
61 | protected bool m_merge; | ||
57 | 62 | ||
58 | /// <value> | 63 | /// <value> |
59 | /// We only use this to request modules | 64 | /// We only use this to request modules |
@@ -66,19 +71,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
66 | private Stream m_loadStream; | 71 | private Stream m_loadStream; |
67 | 72 | ||
68 | public InventoryArchiveReadRequest( | 73 | public InventoryArchiveReadRequest( |
69 | Scene scene, UserAccount userInfo, string invPath, string loadPath) | 74 | Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) |
70 | : this( | 75 | : this( |
71 | scene, | 76 | scene, |
72 | userInfo, | 77 | userInfo, |
73 | invPath, | 78 | invPath, |
74 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress)) | 79 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), |
80 | merge) | ||
75 | { | 81 | { |
76 | } | 82 | } |
77 | 83 | ||
78 | public InventoryArchiveReadRequest( | 84 | public InventoryArchiveReadRequest( |
79 | Scene scene, UserAccount userInfo, string invPath, Stream loadStream) | 85 | Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge) |
80 | { | 86 | { |
81 | m_scene = scene; | 87 | m_scene = scene; |
88 | m_merge = merge; | ||
82 | m_userInfo = userInfo; | 89 | m_userInfo = userInfo; |
83 | m_invPath = invPath; | 90 | m_invPath = invPath; |
84 | m_loadStream = loadStream; | 91 | m_loadStream = loadStream; |
@@ -91,7 +98,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
91 | /// A list of the inventory nodes loaded. If folders were loaded then only the root folders are | 98 | /// A list of the inventory nodes loaded. If folders were loaded then only the root folders are |
92 | /// returned | 99 | /// returned |
93 | /// </returns> | 100 | /// </returns> |
94 | public List<InventoryNodeBase> Execute() | 101 | public HashSet<InventoryNodeBase> Execute() |
95 | { | 102 | { |
96 | try | 103 | try |
97 | { | 104 | { |
@@ -100,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
100 | int failedAssetRestores = 0; | 107 | int failedAssetRestores = 0; |
101 | int successfulItemRestores = 0; | 108 | int successfulItemRestores = 0; |
102 | 109 | ||
103 | List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>(); | 110 | HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>(); |
104 | 111 | ||
105 | List<InventoryFolderBase> folderCandidates | 112 | List<InventoryFolderBase> folderCandidates |
106 | = InventoryArchiveUtils.FindFolderByPath( | 113 | = InventoryArchiveUtils.FindFolderByPath( |
@@ -158,9 +165,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
158 | { | 165 | { |
159 | successfulItemRestores++; | 166 | successfulItemRestores++; |
160 | 167 | ||
161 | // If we're loading an item directly into the given destination folder then we need to record | 168 | // If we aren't loading the folder containing the item then well need to update the |
162 | // it separately from any loaded root folders | 169 | // viewer separately for that item. |
163 | if (rootDestinationFolder == foundFolder) | 170 | if (!loadedNodes.Contains(foundFolder)) |
164 | loadedNodes.Add(item); | 171 | loadedNodes.Add(item); |
165 | } | 172 | } |
166 | } | 173 | } |
@@ -205,14 +212,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
205 | string iarPath, | 212 | string iarPath, |
206 | InventoryFolderBase rootDestFolder, | 213 | InventoryFolderBase rootDestFolder, |
207 | Dictionary <string, InventoryFolderBase> resolvedFolders, | 214 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
208 | List<InventoryNodeBase> loadedNodes) | 215 | HashSet<InventoryNodeBase> loadedNodes) |
209 | { | 216 | { |
210 | string iarPathExisting = iarPath; | 217 | string iarPathExisting = iarPath; |
211 | 218 | ||
212 | // m_log.DebugFormat( | 219 | // m_log.DebugFormat( |
213 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); | 220 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); |
214 | 221 | ||
215 | InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); | 222 | InventoryFolderBase destFolder |
223 | = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); | ||
216 | 224 | ||
217 | // m_log.DebugFormat( | 225 | // m_log.DebugFormat( |
218 | // "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", | 226 | // "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", |
@@ -251,46 +259,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
251 | { | 259 | { |
252 | // string originalArchivePath = archivePath; | 260 | // string originalArchivePath = archivePath; |
253 | 261 | ||
254 | InventoryFolderBase destFolder = null; | 262 | while (archivePath.Length > 0) |
255 | |||
256 | if (archivePath.Length > 0) | ||
257 | { | 263 | { |
258 | while (null == destFolder && archivePath.Length > 0) | 264 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); |
265 | |||
266 | if (resolvedFolders.ContainsKey(archivePath)) | ||
267 | { | ||
268 | // m_log.DebugFormat( | ||
269 | // "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); | ||
270 | return resolvedFolders[archivePath]; | ||
271 | } | ||
272 | else | ||
259 | { | 273 | { |
260 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); | 274 | if (m_merge) |
275 | { | ||
276 | // TODO: Using m_invPath is totally wrong - what we need to do is strip the uuid from the | ||
277 | // iar name and try to find that instead. | ||
278 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); | ||
279 | List<InventoryFolderBase> folderCandidates | ||
280 | = InventoryArchiveUtils.FindFolderByPath( | ||
281 | m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); | ||
282 | |||
283 | if (folderCandidates.Count != 0) | ||
284 | { | ||
285 | InventoryFolderBase destFolder = folderCandidates[0]; | ||
286 | resolvedFolders[archivePath] = destFolder; | ||
287 | return destFolder; | ||
288 | } | ||
289 | } | ||
261 | 290 | ||
262 | if (resolvedFolders.ContainsKey(archivePath)) | 291 | // Don't include the last slash so find the penultimate one |
292 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); | ||
293 | |||
294 | if (penultimateSlashIndex >= 0) | ||
263 | { | 295 | { |
264 | // m_log.DebugFormat( | 296 | // Remove the last section of path so that we can see if we've already resolved the parent |
265 | // "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); | 297 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); |
266 | destFolder = resolvedFolders[archivePath]; | ||
267 | } | 298 | } |
268 | else | 299 | else |
269 | { | 300 | { |
270 | // Don't include the last slash so find the penultimate one | 301 | // m_log.DebugFormat( |
271 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); | 302 | // "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}", |
272 | 303 | // originalArchivePath); | |
273 | if (penultimateSlashIndex >= 0) | 304 | archivePath = string.Empty; |
274 | { | 305 | return rootDestFolder; |
275 | // Remove the last section of path so that we can see if we've already resolved the parent | ||
276 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); | ||
277 | } | ||
278 | else | ||
279 | { | ||
280 | // m_log.DebugFormat( | ||
281 | // "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}", | ||
282 | // originalArchivePath); | ||
283 | archivePath = string.Empty; | ||
284 | destFolder = rootDestFolder; | ||
285 | } | ||
286 | } | 306 | } |
287 | } | 307 | } |
288 | } | 308 | } |
289 | 309 | ||
290 | if (null == destFolder) | 310 | return rootDestFolder; |
291 | destFolder = rootDestFolder; | ||
292 | |||
293 | return destFolder; | ||
294 | } | 311 | } |
295 | 312 | ||
296 | /// <summary> | 313 | /// <summary> |
@@ -316,24 +333,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
316 | string iarPathExisting, | 333 | string iarPathExisting, |
317 | string iarPathToReplicate, | 334 | string iarPathToReplicate, |
318 | Dictionary <string, InventoryFolderBase> resolvedFolders, | 335 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
319 | List<InventoryNodeBase> loadedNodes) | 336 | HashSet<InventoryNodeBase> loadedNodes) |
320 | { | 337 | { |
321 | string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | 338 | string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); |
322 | int i = 0; | ||
323 | 339 | ||
324 | while (i < rawDirsToCreate.Length) | 340 | for (int i = 0; i < rawDirsToCreate.Length; i++) |
325 | { | 341 | { |
326 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]); | 342 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]); |
327 | 343 | ||
344 | if (!rawDirsToCreate[i].Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR)) | ||
345 | continue; | ||
346 | |||
328 | int identicalNameIdentifierIndex | 347 | int identicalNameIdentifierIndex |
329 | = rawDirsToCreate[i].LastIndexOf( | 348 | = rawDirsToCreate[i].LastIndexOf( |
330 | ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); | 349 | ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); |
331 | 350 | ||
332 | if (identicalNameIdentifierIndex < 0) | ||
333 | { | ||
334 | i++; | ||
335 | continue; | ||
336 | } | ||
337 | string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); | 351 | string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); |
338 | 352 | ||
339 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); | 353 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); |
@@ -356,8 +370,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
356 | 370 | ||
357 | if (0 == i) | 371 | if (0 == i) |
358 | loadedNodes.Add(destFolder); | 372 | loadedNodes.Add(destFolder); |
359 | |||
360 | i++; | ||
361 | } | 373 | } |
362 | } | 374 | } |
363 | 375 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index f7a2b09..f03f2a1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -91,12 +91,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
91 | 91 | ||
92 | scene.AddCommand( | 92 | scene.AddCommand( |
93 | this, "load iar", | 93 | this, "load iar", |
94 | "load iar <first> <last> <inventory path> <password> [<IAR path>]", | 94 | "load iar <first> <last> <inventory path> <password> [<IAR path>]", |
95 | //"load iar [--merge] <first> <last> <inventory path> <password> [<IAR path>]", | 95 | //"load iar [--merge] <first> <last> <inventory path> <password> [<IAR path>]", |
96 | "Load user inventory archive (IAR).", | 96 | "Load user inventory archive (IAR).", |
97 | //"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" | 97 | //"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" |
98 | //+ "<first> is user's first name." + Environment.NewLine | 98 | //+ "<first> is user's first name." + Environment.NewLine |
99 | "<first> is user's first name." + Environment.NewLine | 99 | "<first> is user's first name." + Environment.NewLine |
100 | + "<last> is user's last name." + Environment.NewLine | 100 | + "<last> is user's last name." + Environment.NewLine |
101 | + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine | 101 | + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine |
102 | + "<password> is the user's password." + Environment.NewLine | 102 | + "<password> is the user's password." + Environment.NewLine |
@@ -136,16 +136,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
136 | if (handlerInventoryArchiveSaved != null) | 136 | if (handlerInventoryArchiveSaved != null) |
137 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); | 137 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); |
138 | } | 138 | } |
139 | 139 | ||
140 | public bool ArchiveInventory( | 140 | public bool ArchiveInventory( |
141 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) | 141 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) |
142 | { | 142 | { |
143 | return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>()); | 143 | return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>()); |
144 | } | 144 | } |
145 | 145 | ||
146 | public bool ArchiveInventory( | 146 | public bool ArchiveInventory( |
147 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, | 147 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, |
148 | Dictionary<string, object> options) | 148 | Dictionary<string, object> options) |
149 | { | 149 | { |
150 | if (m_scenes.Count > 0) | 150 | if (m_scenes.Count > 0) |
151 | { | 151 | { |
@@ -184,8 +184,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
184 | } | 184 | } |
185 | 185 | ||
186 | public bool ArchiveInventory( | 186 | public bool ArchiveInventory( |
187 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, | 187 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, |
188 | Dictionary<string, object> options) | 188 | Dictionary<string, object> options) |
189 | { | 189 | { |
190 | if (m_scenes.Count > 0) | 190 | if (m_scenes.Count > 0) |
191 | { | 191 | { |
@@ -224,13 +224,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
224 | } | 224 | } |
225 | 225 | ||
226 | public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream) | 226 | public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream) |
227 | { | 227 | { |
228 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); | 228 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); |
229 | } | 229 | } |
230 | 230 | ||
231 | public bool DearchiveInventory( | 231 | public bool DearchiveInventory( |
232 | string firstName, string lastName, string invPath, string pass, Stream loadStream, | 232 | string firstName, string lastName, string invPath, string pass, Stream loadStream, |
233 | Dictionary<string, object> options) | 233 | Dictionary<string, object> options) |
234 | { | 234 | { |
235 | if (m_scenes.Count > 0) | 235 | if (m_scenes.Count > 0) |
236 | { | 236 | { |
@@ -241,10 +241,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
241 | if (CheckPresence(userInfo.PrincipalID)) | 241 | if (CheckPresence(userInfo.PrincipalID)) |
242 | { | 242 | { |
243 | InventoryArchiveReadRequest request; | 243 | InventoryArchiveReadRequest request; |
244 | bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); | ||
244 | 245 | ||
245 | try | 246 | try |
246 | { | 247 | { |
247 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream); | 248 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); |
248 | } | 249 | } |
249 | catch (EntryPointNotFoundException e) | 250 | catch (EntryPointNotFoundException e) |
250 | { | 251 | { |
@@ -273,8 +274,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
273 | } | 274 | } |
274 | 275 | ||
275 | public bool DearchiveInventory( | 276 | public bool DearchiveInventory( |
276 | string firstName, string lastName, string invPath, string pass, string loadPath, | 277 | string firstName, string lastName, string invPath, string pass, string loadPath, |
277 | Dictionary<string, object> options) | 278 | Dictionary<string, object> options) |
278 | { | 279 | { |
279 | if (m_scenes.Count > 0) | 280 | if (m_scenes.Count > 0) |
280 | { | 281 | { |
@@ -285,10 +286,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
285 | if (CheckPresence(userInfo.PrincipalID)) | 286 | if (CheckPresence(userInfo.PrincipalID)) |
286 | { | 287 | { |
287 | InventoryArchiveReadRequest request; | 288 | InventoryArchiveReadRequest request; |
289 | bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); | ||
288 | 290 | ||
289 | try | 291 | try |
290 | { | 292 | { |
291 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath); | 293 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); |
292 | } | 294 | } |
293 | catch (EntryPointNotFoundException e) | 295 | catch (EntryPointNotFoundException e) |
294 | { | 296 | { |
@@ -334,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
334 | if (mainParams.Count < 6) | 336 | if (mainParams.Count < 6) |
335 | { | 337 | { |
336 | m_log.Error( | 338 | m_log.Error( |
337 | "[INVENTORY ARCHIVER]: usage is load iar <first name> <last name> <inventory path> <user password> [<load file path>]"); | 339 | "[INVENTORY ARCHIVER]: usage is load iar [--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); |
338 | return; | 340 | return; |
339 | } | 341 | } |
340 | 342 | ||
@@ -356,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
356 | catch (InventoryArchiverException e) | 358 | catch (InventoryArchiverException e) |
357 | { | 359 | { |
358 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); | 360 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); |
359 | } | 361 | } |
360 | } | 362 | } |
361 | 363 | ||
362 | /// <summary> | 364 | /// <summary> |
@@ -469,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
469 | /// Notify the client of loaded nodes if they are logged in | 471 | /// Notify the client of loaded nodes if they are logged in |
470 | /// </summary> | 472 | /// </summary> |
471 | /// <param name="loadedNodes">Can be empty. In which case, nothing happens</param> | 473 | /// <param name="loadedNodes">Can be empty. In which case, nothing happens</param> |
472 | private void UpdateClientWithLoadedNodes(UserAccount userInfo, List<InventoryNodeBase> loadedNodes) | 474 | private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet<InventoryNodeBase> loadedNodes) |
473 | { | 475 | { |
474 | if (loadedNodes.Count == 0) | 476 | if (loadedNodes.Count == 0) |
475 | return; | 477 | return; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 4531bfd..2d80382 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | |||
@@ -629,7 +629,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
629 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); | 629 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); |
630 | 630 | ||
631 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); | 631 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); |
632 | List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>(); | 632 | HashSet<InventoryNodeBase> nodesLoaded = new HashSet<InventoryNodeBase>(); |
633 | 633 | ||
634 | string folder1Name = "1"; | 634 | string folder1Name = "1"; |
635 | string folder2aName = "2a"; | 635 | string folder2aName = "2a"; |
@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
644 | 644 | ||
645 | { | 645 | { |
646 | // Test replication of path1 | 646 | // Test replication of path1 |
647 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) | 647 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) |
648 | .ReplicateArchivePathToUserInventory( | 648 | .ReplicateArchivePathToUserInventory( |
649 | iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 649 | iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
650 | foldersCreated, nodesLoaded); | 650 | foldersCreated, nodesLoaded); |
@@ -661,7 +661,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
661 | 661 | ||
662 | { | 662 | { |
663 | // Test replication of path2 | 663 | // Test replication of path2 |
664 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) | 664 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) |
665 | .ReplicateArchivePathToUserInventory( | 665 | .ReplicateArchivePathToUserInventory( |
666 | iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 666 | iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
667 | foldersCreated, nodesLoaded); | 667 | foldersCreated, nodesLoaded); |
@@ -707,10 +707,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
707 | 707 | ||
708 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); | 708 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); |
709 | 709 | ||
710 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) | 710 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) |
711 | .ReplicateArchivePathToUserInventory( | 711 | .ReplicateArchivePathToUserInventory( |
712 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 712 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
713 | new Dictionary<string, InventoryFolderBase>(), new List<InventoryNodeBase>()); | 713 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); |
714 | 714 | ||
715 | List<InventoryFolderBase> folder1PostCandidates | 715 | List<InventoryFolderBase> folder1PostCandidates |
716 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 716 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); |
@@ -732,5 +732,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
732 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); | 732 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); |
733 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); | 733 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); |
734 | } | 734 | } |
735 | |||
736 | /// <summary> | ||
737 | /// Test replication of a partly existing archive path to the user's inventory. This should create | ||
738 | /// a merged path. | ||
739 | /// </summary> | ||
740 | [Test] | ||
741 | public void TestMergeIarPath() | ||
742 | { | ||
743 | TestHelper.InMethod(); | ||
744 | log4net.Config.XmlConfigurator.Configure(); | ||
745 | |||
746 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | ||
747 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); | ||
748 | |||
749 | string folder1ExistingName = "a"; | ||
750 | string folder2Name = "b"; | ||
751 | |||
752 | InventoryFolderBase folder1 | ||
753 | = UserInventoryTestUtils.CreateInventoryFolder( | ||
754 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | ||
755 | |||
756 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); | ||
757 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); | ||
758 | |||
759 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); | ||
760 | |||
761 | new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true) | ||
762 | .ReplicateArchivePathToUserInventory( | ||
763 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | ||
764 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); | ||
765 | |||
766 | List<InventoryFolderBase> folder1PostCandidates | ||
767 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | ||
768 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); | ||
769 | Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); | ||
770 | |||
771 | List<InventoryFolderBase> folder2PostCandidates | ||
772 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b"); | ||
773 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); | ||
774 | } | ||
735 | } | 775 | } |
736 | } \ No newline at end of file | 776 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index 36dae6b..9c20d68 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -173,16 +173,16 @@ namespace OpenSim.Region.CoreModules.Framework.Library | |||
173 | m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); | 173 | m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); |
174 | simpleName = GetInventoryPathFromName(simpleName); | 174 | simpleName = GetInventoryPathFromName(simpleName); |
175 | 175 | ||
176 | InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName); | 176 | InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false); |
177 | try | 177 | try |
178 | { | 178 | { |
179 | List<InventoryNodeBase> nodes = archread.Execute(); | 179 | HashSet<InventoryNodeBase> nodes = archread.Execute(); |
180 | if (nodes != null && nodes.Count == 0) | 180 | if (nodes != null && nodes.Count == 0) |
181 | { | 181 | { |
182 | // didn't find the subfolder with the given name; place it on the top | 182 | // didn't find the subfolder with the given name; place it on the top |
183 | m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); | 183 | m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); |
184 | archread.Close(); | 184 | archread.Close(); |
185 | archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName); | 185 | archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); |
186 | archread.Execute(); | 186 | archread.Execute(); |
187 | } | 187 | } |
188 | foreach (InventoryNodeBase node in nodes) | 188 | foreach (InventoryNodeBase node in nodes) |
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs new file mode 100644 index 0000000..82ad109 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | |||
@@ -0,0 +1,596 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Collections.Specialized; | ||
32 | using System.Reflection; | ||
33 | using System.IO; | ||
34 | using System.Web; | ||
35 | using System.Xml; | ||
36 | using log4net; | ||
37 | using Mono.Addins; | ||
38 | using Nini.Config; | ||
39 | using OpenMetaverse; | ||
40 | using OpenMetaverse.Messages.Linden; | ||
41 | using OpenMetaverse.StructuredData; | ||
42 | using OpenSim.Framework; | ||
43 | using OpenSim.Framework.Capabilities; | ||
44 | using OpenSim.Framework.Servers; | ||
45 | using OpenSim.Framework.Servers.HttpServer; | ||
46 | using OpenSim.Region.Framework.Interfaces; | ||
47 | using OpenSim.Region.Framework.Scenes; | ||
48 | using OpenSim.Services.Interfaces; | ||
49 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
50 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; | ||
51 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | ||
52 | |||
53 | namespace OpenSim.Region.CoreModules.Media.Moap | ||
54 | { | ||
55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")] | ||
56 | public class MoapModule : INonSharedRegionModule, IMoapModule | ||
57 | { | ||
58 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
59 | |||
60 | public string Name { get { return "MoapModule"; } } | ||
61 | public Type ReplaceableInterface { get { return null; } } | ||
62 | |||
63 | /// <summary> | ||
64 | /// Is this module enabled? | ||
65 | /// </summary> | ||
66 | protected bool m_isEnabled = true; | ||
67 | |||
68 | /// <summary> | ||
69 | /// The scene to which this module is attached | ||
70 | /// </summary> | ||
71 | protected Scene m_scene; | ||
72 | |||
73 | /// <summary> | ||
74 | /// Track the ObjectMedia capabilities given to users keyed by path | ||
75 | /// </summary> | ||
76 | protected Dictionary<string, UUID> m_omCapUsers = new Dictionary<string, UUID>(); | ||
77 | |||
78 | /// <summary> | ||
79 | /// Track the ObjectMedia capabilities given to users keyed by agent. Lock m_omCapUsers to manipulate. | ||
80 | /// </summary> | ||
81 | protected Dictionary<UUID, string> m_omCapUrls = new Dictionary<UUID, string>(); | ||
82 | |||
83 | /// <summary> | ||
84 | /// Track the ObjectMediaUpdate capabilities given to users keyed by path | ||
85 | /// </summary> | ||
86 | protected Dictionary<string, UUID> m_omuCapUsers = new Dictionary<string, UUID>(); | ||
87 | |||
88 | /// <summary> | ||
89 | /// Track the ObjectMediaUpdate capabilities given to users keyed by agent. Lock m_omuCapUsers to manipulate | ||
90 | /// </summary> | ||
91 | protected Dictionary<UUID, string> m_omuCapUrls = new Dictionary<UUID, string>(); | ||
92 | |||
93 | public void Initialise(IConfigSource configSource) | ||
94 | { | ||
95 | IConfig config = configSource.Configs["MediaOnAPrim"]; | ||
96 | |||
97 | if (config != null && !config.GetBoolean("Enabled", false)) | ||
98 | m_isEnabled = false; | ||
99 | // else | ||
100 | // m_log.Debug("[MOAP]: Initialised module.")l | ||
101 | } | ||
102 | |||
103 | public void AddRegion(Scene scene) | ||
104 | { | ||
105 | if (!m_isEnabled) | ||
106 | return; | ||
107 | |||
108 | m_scene = scene; | ||
109 | m_scene.RegisterModuleInterface<IMoapModule>(this); | ||
110 | } | ||
111 | |||
112 | public void RemoveRegion(Scene scene) {} | ||
113 | |||
114 | public void RegionLoaded(Scene scene) | ||
115 | { | ||
116 | if (!m_isEnabled) | ||
117 | return; | ||
118 | |||
119 | m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; | ||
120 | m_scene.EventManager.OnDeregisterCaps += OnDeregisterCaps; | ||
121 | m_scene.EventManager.OnSceneObjectPartCopy += OnSceneObjectPartCopy; | ||
122 | } | ||
123 | |||
124 | public void Close() | ||
125 | { | ||
126 | if (!m_isEnabled) | ||
127 | return; | ||
128 | |||
129 | m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps; | ||
130 | m_scene.EventManager.OnDeregisterCaps -= OnDeregisterCaps; | ||
131 | m_scene.EventManager.OnSceneObjectPartCopy -= OnSceneObjectPartCopy; | ||
132 | } | ||
133 | |||
134 | public void OnRegisterCaps(UUID agentID, Caps caps) | ||
135 | { | ||
136 | // m_log.DebugFormat( | ||
137 | // "[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID); | ||
138 | |||
139 | string omCapUrl = "/CAPS/" + UUID.Random(); | ||
140 | |||
141 | lock (m_omCapUsers) | ||
142 | { | ||
143 | m_omCapUsers[omCapUrl] = agentID; | ||
144 | m_omCapUrls[agentID] = omCapUrl; | ||
145 | |||
146 | // Even though we're registering for POST we're going to get GETS and UPDATES too | ||
147 | caps.RegisterHandler( | ||
148 | "ObjectMedia", new RestStreamHandler("POST", omCapUrl, HandleObjectMediaMessage)); | ||
149 | } | ||
150 | |||
151 | string omuCapUrl = "/CAPS/" + UUID.Random(); | ||
152 | |||
153 | lock (m_omuCapUsers) | ||
154 | { | ||
155 | m_omuCapUsers[omuCapUrl] = agentID; | ||
156 | m_omuCapUrls[agentID] = omuCapUrl; | ||
157 | |||
158 | // Even though we're registering for POST we're going to get GETS and UPDATES too | ||
159 | caps.RegisterHandler( | ||
160 | "ObjectMediaNavigate", new RestStreamHandler("POST", omuCapUrl, HandleObjectMediaNavigateMessage)); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | public void OnDeregisterCaps(UUID agentID, Caps caps) | ||
165 | { | ||
166 | lock (m_omCapUsers) | ||
167 | { | ||
168 | string path = m_omCapUrls[agentID]; | ||
169 | m_omCapUrls.Remove(agentID); | ||
170 | m_omCapUsers.Remove(path); | ||
171 | } | ||
172 | |||
173 | lock (m_omuCapUsers) | ||
174 | { | ||
175 | string path = m_omuCapUrls[agentID]; | ||
176 | m_omuCapUrls.Remove(agentID); | ||
177 | m_omuCapUsers.Remove(path); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | protected void OnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed) | ||
182 | { | ||
183 | if (original.Shape.Media != null) | ||
184 | { | ||
185 | PrimitiveBaseShape.MediaList dupeMedia = new PrimitiveBaseShape.MediaList(); | ||
186 | lock (original.Shape.Media) | ||
187 | { | ||
188 | foreach (MediaEntry me in original.Shape.Media) | ||
189 | { | ||
190 | if (me != null) | ||
191 | dupeMedia.Add(MediaEntry.FromOSD(me.GetOSD())); | ||
192 | else | ||
193 | dupeMedia.Add(null); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | copy.Shape.Media = dupeMedia; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | public MediaEntry GetMediaEntry(SceneObjectPart part, int face) | ||
202 | { | ||
203 | MediaEntry me = null; | ||
204 | |||
205 | CheckFaceParam(part, face); | ||
206 | |||
207 | List<MediaEntry> media = part.Shape.Media; | ||
208 | |||
209 | if (null == media) | ||
210 | { | ||
211 | me = null; | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | lock (media) | ||
216 | me = media[face]; | ||
217 | |||
218 | // TODO: Really need a proper copy constructor down in libopenmetaverse | ||
219 | if (me != null) | ||
220 | me = MediaEntry.FromOSD(me.GetOSD()); | ||
221 | } | ||
222 | |||
223 | // m_log.DebugFormat("[MOAP]: GetMediaEntry for {0} face {1} found {2}", part.Name, face, me); | ||
224 | |||
225 | return me; | ||
226 | } | ||
227 | |||
228 | public void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me) | ||
229 | { | ||
230 | CheckFaceParam(part, face); | ||
231 | |||
232 | if (null == part.Shape.Media) | ||
233 | part.Shape.Media = new PrimitiveBaseShape.MediaList(new MediaEntry[part.GetNumberOfSides()]); | ||
234 | |||
235 | lock (part.Shape.Media) | ||
236 | part.Shape.Media[face] = me; | ||
237 | |||
238 | UpdateMediaUrl(part, UUID.Zero); | ||
239 | part.ScheduleFullUpdate(); | ||
240 | part.TriggerScriptChangedEvent(Changed.MEDIA); | ||
241 | } | ||
242 | |||
243 | public void ClearMediaEntry(SceneObjectPart part, int face) | ||
244 | { | ||
245 | SetMediaEntry(part, face, null); | ||
246 | } | ||
247 | |||
248 | /// <summary> | ||
249 | /// Sets or gets per face media textures. | ||
250 | /// </summary> | ||
251 | /// <param name="request"></param> | ||
252 | /// <param name="path"></param> | ||
253 | /// <param name="param"></param> | ||
254 | /// <param name="httpRequest"></param> | ||
255 | /// <param name="httpResponse"></param> | ||
256 | /// <returns></returns> | ||
257 | protected string HandleObjectMediaMessage( | ||
258 | string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||
259 | { | ||
260 | // m_log.DebugFormat("[MOAP]: Got ObjectMedia path [{0}], raw request [{1}]", path, request); | ||
261 | |||
262 | OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request); | ||
263 | ObjectMediaMessage omm = new ObjectMediaMessage(); | ||
264 | omm.Deserialize(osd); | ||
265 | |||
266 | if (omm.Request is ObjectMediaRequest) | ||
267 | return HandleObjectMediaRequest(omm.Request as ObjectMediaRequest); | ||
268 | else if (omm.Request is ObjectMediaUpdate) | ||
269 | return HandleObjectMediaUpdate(path, omm.Request as ObjectMediaUpdate); | ||
270 | |||
271 | throw new Exception( | ||
272 | string.Format( | ||
273 | "[MOAP]: ObjectMediaMessage has unrecognized ObjectMediaBlock of {0}", | ||
274 | omm.Request.GetType())); | ||
275 | } | ||
276 | |||
277 | /// <summary> | ||
278 | /// Handle a fetch request for media textures | ||
279 | /// </summary> | ||
280 | /// <param name="omr"></param> | ||
281 | /// <returns></returns> | ||
282 | protected string HandleObjectMediaRequest(ObjectMediaRequest omr) | ||
283 | { | ||
284 | UUID primId = omr.PrimID; | ||
285 | |||
286 | SceneObjectPart part = m_scene.GetSceneObjectPart(primId); | ||
287 | |||
288 | if (null == part) | ||
289 | { | ||
290 | m_log.WarnFormat( | ||
291 | "[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", | ||
292 | primId, m_scene.RegionInfo.RegionName); | ||
293 | return string.Empty; | ||
294 | } | ||
295 | |||
296 | if (null == part.Shape.Media) | ||
297 | return string.Empty; | ||
298 | |||
299 | ObjectMediaResponse resp = new ObjectMediaResponse(); | ||
300 | |||
301 | resp.PrimID = primId; | ||
302 | |||
303 | lock (part.Shape.Media) | ||
304 | resp.FaceMedia = part.Shape.Media.ToArray(); | ||
305 | |||
306 | resp.Version = part.MediaUrl; | ||
307 | |||
308 | string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize()); | ||
309 | |||
310 | // m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp); | ||
311 | |||
312 | return rawResp; | ||
313 | } | ||
314 | |||
315 | /// <summary> | ||
316 | /// Handle an update of media textures. | ||
317 | /// </summary> | ||
318 | /// <param name="path">Path on which this request was made</param> | ||
319 | /// <param name="omu">/param> | ||
320 | /// <returns></returns> | ||
321 | protected string HandleObjectMediaUpdate(string path, ObjectMediaUpdate omu) | ||
322 | { | ||
323 | UUID primId = omu.PrimID; | ||
324 | |||
325 | SceneObjectPart part = m_scene.GetSceneObjectPart(primId); | ||
326 | |||
327 | if (null == part) | ||
328 | { | ||
329 | m_log.WarnFormat( | ||
330 | "[MOAP]: Received an UPDATE ObjectMediaRequest for prim {0} but this doesn't exist in region {1}", | ||
331 | primId, m_scene.RegionInfo.RegionName); | ||
332 | return string.Empty; | ||
333 | } | ||
334 | |||
335 | // m_log.DebugFormat("[MOAP]: Received {0} media entries for prim {1}", omu.FaceMedia.Length, primId); | ||
336 | |||
337 | // for (int i = 0; i < omu.FaceMedia.Length; i++) | ||
338 | // { | ||
339 | // MediaEntry me = omu.FaceMedia[i]; | ||
340 | // string v = (null == me ? "null": OSDParser.SerializeLLSDXmlString(me.GetOSD())); | ||
341 | // m_log.DebugFormat("[MOAP]: Face {0} [{1}]", i, v); | ||
342 | // } | ||
343 | |||
344 | if (omu.FaceMedia.Length > part.GetNumberOfSides()) | ||
345 | { | ||
346 | m_log.WarnFormat( | ||
347 | "[MOAP]: Received {0} media entries from client for prim {1} {2} but this prim has only {3} faces. Dropping request.", | ||
348 | omu.FaceMedia.Length, part.Name, part.UUID, part.GetNumberOfSides()); | ||
349 | return string.Empty; | ||
350 | } | ||
351 | |||
352 | UUID agentId = default(UUID); | ||
353 | |||
354 | lock (m_omCapUsers) | ||
355 | agentId = m_omCapUsers[path]; | ||
356 | |||
357 | List<MediaEntry> media = part.Shape.Media; | ||
358 | |||
359 | if (null == media) | ||
360 | { | ||
361 | // m_log.DebugFormat("[MOAP]: Setting all new media list for {0}", part.Name); | ||
362 | part.Shape.Media = new PrimitiveBaseShape.MediaList(omu.FaceMedia); | ||
363 | |||
364 | for (int i = 0; i < omu.FaceMedia.Length; i++) | ||
365 | { | ||
366 | if (omu.FaceMedia[i] != null) | ||
367 | { | ||
368 | // FIXME: Race condition here since some other texture entry manipulator may overwrite/get | ||
369 | // overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry | ||
370 | // directly. | ||
371 | Primitive.TextureEntry te = part.Shape.Textures; | ||
372 | Primitive.TextureEntryFace face = te.CreateFace((uint)i); | ||
373 | face.MediaFlags = true; | ||
374 | part.Shape.Textures = te; | ||
375 | // m_log.DebugFormat( | ||
376 | // "[MOAP]: Media flags for face {0} is {1}", | ||
377 | // i, part.Shape.Textures.FaceTextures[i].MediaFlags); | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | // We need to go through the media textures one at a time to make sure that we have permission | ||
384 | // to change them | ||
385 | |||
386 | // FIXME: Race condition here since some other texture entry manipulator may overwrite/get | ||
387 | // overwritten. Unfortunately, PrimitiveBaseShape does not allow us to change texture entry | ||
388 | // directly. | ||
389 | Primitive.TextureEntry te = part.Shape.Textures; | ||
390 | |||
391 | lock (media) | ||
392 | { | ||
393 | for (int i = 0; i < media.Count; i++) | ||
394 | { | ||
395 | if (m_scene.Permissions.CanControlPrimMedia(agentId, part.UUID, i)) | ||
396 | { | ||
397 | media[i] = omu.FaceMedia[i]; | ||
398 | |||
399 | // When a face is cleared this is done by setting the MediaFlags in the TextureEntry via a normal | ||
400 | // texture update, so we don't need to worry about clearing MediaFlags here. | ||
401 | if (null == media[i]) | ||
402 | continue; | ||
403 | |||
404 | Primitive.TextureEntryFace face = te.CreateFace((uint)i); | ||
405 | face.MediaFlags = true; | ||
406 | |||
407 | // m_log.DebugFormat( | ||
408 | // "[MOAP]: Media flags for face {0} is {1}", | ||
409 | // i, face.MediaFlags); | ||
410 | // m_log.DebugFormat("[MOAP]: Set media entry for face {0} on {1}", i, part.Name); | ||
411 | } | ||
412 | } | ||
413 | } | ||
414 | |||
415 | part.Shape.Textures = te; | ||
416 | |||
417 | // for (int i2 = 0; i2 < part.Shape.Textures.FaceTextures.Length; i2++) | ||
418 | // m_log.DebugFormat("[MOAP]: FaceTexture[{0}] is {1}", i2, part.Shape.Textures.FaceTextures[i2]); | ||
419 | } | ||
420 | |||
421 | UpdateMediaUrl(part, agentId); | ||
422 | |||
423 | // Arguably, we could avoid sending a full update to the avatar that just changed the texture. | ||
424 | part.ScheduleFullUpdate(); | ||
425 | |||
426 | part.TriggerScriptChangedEvent(Changed.MEDIA); | ||
427 | |||
428 | return string.Empty; | ||
429 | } | ||
430 | |||
431 | /// <summary> | ||
432 | /// Received from the viewer if a user has changed the url of a media texture. | ||
433 | /// </summary> | ||
434 | /// <param name="request"></param> | ||
435 | /// <param name="path"></param> | ||
436 | /// <param name="param"></param> | ||
437 | /// <param name="httpRequest">/param> | ||
438 | /// <param name="httpResponse">/param> | ||
439 | /// <returns></returns> | ||
440 | protected string HandleObjectMediaNavigateMessage( | ||
441 | string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||
442 | { | ||
443 | // m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request [{0}]", request); | ||
444 | |||
445 | OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request); | ||
446 | ObjectMediaNavigateMessage omn = new ObjectMediaNavigateMessage(); | ||
447 | omn.Deserialize(osd); | ||
448 | |||
449 | UUID primId = omn.PrimID; | ||
450 | |||
451 | SceneObjectPart part = m_scene.GetSceneObjectPart(primId); | ||
452 | |||
453 | if (null == part) | ||
454 | { | ||
455 | m_log.WarnFormat( | ||
456 | "[MOAP]: Received an ObjectMediaNavigateMessage for prim {0} but this doesn't exist in region {1}", | ||
457 | primId, m_scene.RegionInfo.RegionName); | ||
458 | return string.Empty; | ||
459 | } | ||
460 | |||
461 | UUID agentId = default(UUID); | ||
462 | |||
463 | lock (m_omuCapUsers) | ||
464 | agentId = m_omuCapUsers[path]; | ||
465 | |||
466 | if (!m_scene.Permissions.CanInteractWithPrimMedia(agentId, part.UUID, omn.Face)) | ||
467 | return string.Empty; | ||
468 | |||
469 | // m_log.DebugFormat( | ||
470 | // "[MOAP]: Received request to update media entry for face {0} on prim {1} {2} to {3}", | ||
471 | // omn.Face, part.Name, part.UUID, omn.URL); | ||
472 | |||
473 | // If media has never been set for this prim, then just return. | ||
474 | if (null == part.Shape.Media) | ||
475 | return string.Empty; | ||
476 | |||
477 | MediaEntry me = null; | ||
478 | |||
479 | lock (part.Shape.Media) | ||
480 | me = part.Shape.Media[omn.Face]; | ||
481 | |||
482 | // Do the same if media has not been set up for a specific face | ||
483 | if (null == me) | ||
484 | return string.Empty; | ||
485 | |||
486 | if (me.EnableWhiteList) | ||
487 | { | ||
488 | if (!CheckUrlAgainstWhitelist(omn.URL, me.WhiteList)) | ||
489 | { | ||
490 | // m_log.DebugFormat( | ||
491 | // "[MOAP]: Blocking change of face {0} on prim {1} {2} to {3} since it's not on the enabled whitelist", | ||
492 | // omn.Face, part.Name, part.UUID, omn.URL); | ||
493 | |||
494 | return string.Empty; | ||
495 | } | ||
496 | } | ||
497 | |||
498 | me.CurrentURL = omn.URL; | ||
499 | |||
500 | UpdateMediaUrl(part, agentId); | ||
501 | |||
502 | part.ScheduleFullUpdate(); | ||
503 | |||
504 | part.TriggerScriptChangedEvent(Changed.MEDIA); | ||
505 | |||
506 | return OSDParser.SerializeLLSDXmlString(new OSD()); | ||
507 | } | ||
508 | |||
509 | /// <summary> | ||
510 | /// Check that the face number is valid for the given prim. | ||
511 | /// </summary> | ||
512 | /// <param name="part"></param> | ||
513 | /// <param name="face"></param> | ||
514 | protected void CheckFaceParam(SceneObjectPart part, int face) | ||
515 | { | ||
516 | if (face < 0) | ||
517 | throw new ArgumentException("Face cannot be less than zero"); | ||
518 | |||
519 | int maxFaces = part.GetNumberOfSides() - 1; | ||
520 | if (face > maxFaces) | ||
521 | throw new ArgumentException( | ||
522 | string.Format("Face argument was {0} but max is {1}", face, maxFaces)); | ||
523 | } | ||
524 | |||
525 | /// <summary> | ||
526 | /// Update the media url of the given part | ||
527 | /// </summary> | ||
528 | /// <param name="part"></param> | ||
529 | /// <param name="updateId"> | ||
530 | /// The id to attach to this update. Normally, this is the user that changed the | ||
531 | /// texture | ||
532 | /// </param> | ||
533 | protected void UpdateMediaUrl(SceneObjectPart part, UUID updateId) | ||
534 | { | ||
535 | if (null == part.MediaUrl) | ||
536 | { | ||
537 | // TODO: We can't set the last changer until we start tracking which cap we give to which agent id | ||
538 | part.MediaUrl = "x-mv:0000000000/" + updateId; | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | string rawVersion = part.MediaUrl.Substring(5, 10); | ||
543 | int version = int.Parse(rawVersion); | ||
544 | part.MediaUrl = string.Format("x-mv:{0:D10}/{1}", ++version, updateId); | ||
545 | } | ||
546 | |||
547 | // m_log.DebugFormat("[MOAP]: Storing media url [{0}] in prim {1} {2}", part.MediaUrl, part.Name, part.UUID); | ||
548 | } | ||
549 | |||
550 | /// <summary> | ||
551 | /// Check the given url against the given whitelist. | ||
552 | /// </summary> | ||
553 | /// <param name="rawUrl"></param> | ||
554 | /// <param name="whitelist"></param> | ||
555 | /// <returns>true if the url matches an entry on the whitelist, false otherwise</returns> | ||
556 | protected bool CheckUrlAgainstWhitelist(string rawUrl, string[] whitelist) | ||
557 | { | ||
558 | Uri url = new Uri(rawUrl); | ||
559 | |||
560 | foreach (string origWlUrl in whitelist) | ||
561 | { | ||
562 | string wlUrl = origWlUrl; | ||
563 | |||
564 | // Deal with a line-ending wildcard | ||
565 | if (wlUrl.EndsWith("*")) | ||
566 | wlUrl = wlUrl.Remove(wlUrl.Length - 1); | ||
567 | |||
568 | // m_log.DebugFormat("[MOAP]: Checking whitelist URL pattern {0}", origWlUrl); | ||
569 | |||
570 | // Handle a line starting wildcard slightly differently since this can only match the domain, not the path | ||
571 | if (wlUrl.StartsWith("*")) | ||
572 | { | ||
573 | wlUrl = wlUrl.Substring(1); | ||
574 | |||
575 | if (url.Host.Contains(wlUrl)) | ||
576 | { | ||
577 | // m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl); | ||
578 | return true; | ||
579 | } | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | string urlToMatch = url.Authority + url.AbsolutePath; | ||
584 | |||
585 | if (urlToMatch.StartsWith(wlUrl)) | ||
586 | { | ||
587 | // m_log.DebugFormat("[MOAP]: Whitelist URL {0} matches {1}", origWlUrl, rawUrl); | ||
588 | return true; | ||
589 | } | ||
590 | } | ||
591 | } | ||
592 | |||
593 | return false; | ||
594 | } | ||
595 | } | ||
596 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 8223f12..b1747ef 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | |||
@@ -164,6 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
164 | private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>(); | 164 | private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>(); |
165 | private IFriendsModule m_friendsModule; | 165 | private IFriendsModule m_friendsModule; |
166 | private IGroupsModule m_groupsModule; | 166 | private IGroupsModule m_groupsModule; |
167 | private IMoapModule m_moapModule; | ||
167 | 168 | ||
168 | #endregion | 169 | #endregion |
169 | 170 | ||
@@ -177,7 +178,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
177 | 178 | ||
178 | string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); | 179 | string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); |
179 | 180 | ||
180 | List<string> modules=new List<string>(permissionModules.Split(',')); | 181 | List<string> modules = new List<string>(permissionModules.Split(',')); |
181 | 182 | ||
182 | if (!modules.Contains("DefaultPermissionsModule")) | 183 | if (!modules.Contains("DefaultPermissionsModule")) |
183 | return; | 184 | return; |
@@ -249,6 +250,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
249 | m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED | 250 | m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED |
250 | 251 | ||
251 | m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED | 252 | m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED |
253 | |||
254 | m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia; | ||
255 | m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia; | ||
252 | 256 | ||
253 | m_scene.AddCommand(this, "bypass permissions", | 257 | m_scene.AddCommand(this, "bypass permissions", |
254 | "bypass permissions <true / false>", | 258 | "bypass permissions <true / false>", |
@@ -394,6 +398,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
394 | 398 | ||
395 | if (m_groupsModule == null) | 399 | if (m_groupsModule == null) |
396 | m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work"); | 400 | m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work"); |
401 | |||
402 | m_moapModule = m_scene.RequestModuleInterface<IMoapModule>(); | ||
403 | |||
404 | // This log line will be commented out when no longer required for debugging | ||
405 | // if (m_moapModule == null) | ||
406 | // m_log.Warn("[PERMISSIONS]: Media on a prim module not found, media on a prim permissions will not work"); | ||
397 | } | 407 | } |
398 | 408 | ||
399 | public void Close() | 409 | public void Close() |
@@ -1894,5 +1904,80 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
1894 | } | 1904 | } |
1895 | return(false); | 1905 | return(false); |
1896 | } | 1906 | } |
1907 | |||
1908 | private bool CanControlPrimMedia(UUID agentID, UUID primID, int face) | ||
1909 | { | ||
1910 | // m_log.DebugFormat( | ||
1911 | // "[PERMISSONS]: Performing CanControlPrimMedia check with agentID {0}, primID {1}, face {2}", | ||
1912 | // agentID, primID, face); | ||
1913 | |||
1914 | if (null == m_moapModule) | ||
1915 | return false; | ||
1916 | |||
1917 | SceneObjectPart part = m_scene.GetSceneObjectPart(primID); | ||
1918 | if (null == part) | ||
1919 | return false; | ||
1920 | |||
1921 | MediaEntry me = m_moapModule.GetMediaEntry(part, face); | ||
1922 | |||
1923 | // If there is no existing media entry then it can be controlled (in this context, created). | ||
1924 | if (null == me) | ||
1925 | return true; | ||
1926 | |||
1927 | // m_log.DebugFormat( | ||
1928 | // "[PERMISSIONS]: Checking CanControlPrimMedia for {0} on {1} face {2} with control permissions {3}", | ||
1929 | // agentID, primID, face, me.ControlPermissions); | ||
1930 | |||
1931 | return GenericPrimMediaPermission(part, agentID, me.ControlPermissions); | ||
1932 | } | ||
1933 | |||
1934 | private bool CanInteractWithPrimMedia(UUID agentID, UUID primID, int face) | ||
1935 | { | ||
1936 | // m_log.DebugFormat( | ||
1937 | // "[PERMISSONS]: Performing CanInteractWithPrimMedia check with agentID {0}, primID {1}, face {2}", | ||
1938 | // agentID, primID, face); | ||
1939 | |||
1940 | if (null == m_moapModule) | ||
1941 | return false; | ||
1942 | |||
1943 | SceneObjectPart part = m_scene.GetSceneObjectPart(primID); | ||
1944 | if (null == part) | ||
1945 | return false; | ||
1946 | |||
1947 | MediaEntry me = m_moapModule.GetMediaEntry(part, face); | ||
1948 | |||
1949 | // If there is no existing media entry then it can be controlled (in this context, created). | ||
1950 | if (null == me) | ||
1951 | return true; | ||
1952 | |||
1953 | // m_log.DebugFormat( | ||
1954 | // "[PERMISSIONS]: Checking CanInteractWithPrimMedia for {0} on {1} face {2} with interact permissions {3}", | ||
1955 | // agentID, primID, face, me.InteractPermissions); | ||
1956 | |||
1957 | return GenericPrimMediaPermission(part, agentID, me.InteractPermissions); | ||
1958 | } | ||
1959 | |||
1960 | private bool GenericPrimMediaPermission(SceneObjectPart part, UUID agentID, MediaPermission perms) | ||
1961 | { | ||
1962 | // if (IsAdministrator(agentID)) | ||
1963 | // return true; | ||
1964 | |||
1965 | if ((perms & MediaPermission.Anyone) == MediaPermission.Anyone) | ||
1966 | return true; | ||
1967 | |||
1968 | if ((perms & MediaPermission.Owner) == MediaPermission.Owner) | ||
1969 | { | ||
1970 | if (agentID == part.OwnerID) | ||
1971 | return true; | ||
1972 | } | ||
1973 | |||
1974 | if ((perms & MediaPermission.Group) == MediaPermission.Group) | ||
1975 | { | ||
1976 | if (IsGroupMember(part.GroupID, agentID, 0)) | ||
1977 | return true; | ||
1978 | } | ||
1979 | |||
1980 | return false; | ||
1981 | } | ||
1897 | } | 1982 | } |
1898 | } | 1983 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Interfaces/IMoapModule.cs b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs new file mode 100644 index 0000000..24b6860 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IMoapModule.cs | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using OpenMetaverse; | ||
30 | using OpenSim.Region.Framework.Scenes; | ||
31 | |||
32 | namespace OpenSim.Region.Framework.Interfaces | ||
33 | { | ||
34 | /// <summary> | ||
35 | /// Provides methods from manipulating media-on-a-prim | ||
36 | /// </summary> | ||
37 | public interface IMoapModule | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// Get the media entry for a given prim face. | ||
41 | /// </summary> | ||
42 | /// A copy of the media entry is returned rather than the original, so this can be altered at will without | ||
43 | /// affecting the original settings. | ||
44 | /// <param name="part"></param> | ||
45 | /// <param name="face"></param> | ||
46 | /// <returns></returns> | ||
47 | MediaEntry GetMediaEntry(SceneObjectPart part, int face); | ||
48 | |||
49 | /// <summary> | ||
50 | /// Set the media entry for a given prim face. | ||
51 | /// </summary> | ||
52 | /// <param name="SceneObjectPart"></param> | ||
53 | /// <param name="face"></param> | ||
54 | /// <param name="me"></param> | ||
55 | void SetMediaEntry(SceneObjectPart part, int face, MediaEntry me); | ||
56 | |||
57 | /// <summary> | ||
58 | /// Clear the media entry for a given prim face. | ||
59 | /// </summary> | ||
60 | /// | ||
61 | /// This is the equivalent of setting a media entry of null | ||
62 | /// | ||
63 | /// <param name="part"></param> | ||
64 | /// <param name="face">/param> | ||
65 | void ClearMediaEntry(SceneObjectPart part, int face); | ||
66 | } | ||
67 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index e060c05..52e6e92 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs | |||
@@ -334,10 +334,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
334 | /// If the object is being attached, then the avatarID will be present. If the object is being detached then | 334 | /// If the object is being attached, then the avatarID will be present. If the object is being detached then |
335 | /// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical). | 335 | /// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical). |
336 | public delegate void Attach(uint localID, UUID itemID, UUID avatarID); | 336 | public delegate void Attach(uint localID, UUID itemID, UUID avatarID); |
337 | public event Attach OnAttach; | 337 | public event Attach OnAttach; |
338 | |||
339 | /// <summary> | ||
340 | /// Called immediately after an object is loaded from storage. | ||
341 | /// </summary> | ||
342 | public event SceneObjectDelegate OnSceneObjectLoaded; | ||
343 | public delegate void SceneObjectDelegate(SceneObjectGroup so); | ||
344 | |||
345 | /// <summary> | ||
346 | /// Called immediately before an object is saved to storage. | ||
347 | /// </summary> | ||
348 | /// <param name="persistingSo"> | ||
349 | /// The scene object being persisted. | ||
350 | /// This is actually a copy of the original scene object so changes made here will be saved to storage but will not be kept in memory. | ||
351 | /// </param> | ||
352 | /// <param name="originalSo"> | ||
353 | /// The original scene object being persisted. Changes here will stay in memory but will not be saved to storage on this save. | ||
354 | /// </param> | ||
355 | public event SceneObjectPreSaveDelegate OnSceneObjectPreSave; | ||
356 | public delegate void SceneObjectPreSaveDelegate(SceneObjectGroup persistingSo, SceneObjectGroup originalSo); | ||
357 | |||
358 | /// <summary> | ||
359 | /// Called when a scene object part is cloned within the region. | ||
360 | /// </summary> | ||
361 | /// <param name="copy"></param> | ||
362 | /// <param name="original"></param> | ||
363 | /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param> | ||
364 | public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy; | ||
365 | public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed); | ||
338 | 366 | ||
339 | public delegate void RegionUp(GridRegion region); | 367 | public delegate void RegionUp(GridRegion region); |
340 | public event RegionUp OnRegionUp; | 368 | public event RegionUp OnRegionUp; |
341 | 369 | ||
342 | public class MoneyTransferArgs : EventArgs | 370 | public class MoneyTransferArgs : EventArgs |
343 | { | 371 | { |
@@ -2037,5 +2065,68 @@ namespace OpenSim.Region.Framework.Scenes | |||
2037 | } | 2065 | } |
2038 | } | 2066 | } |
2039 | } | 2067 | } |
2068 | |||
2069 | public void TriggerOnSceneObjectLoaded(SceneObjectGroup so) | ||
2070 | { | ||
2071 | SceneObjectDelegate handler = OnSceneObjectLoaded; | ||
2072 | if (handler != null) | ||
2073 | { | ||
2074 | foreach (SceneObjectDelegate d in handler.GetInvocationList()) | ||
2075 | { | ||
2076 | try | ||
2077 | { | ||
2078 | d(so); | ||
2079 | } | ||
2080 | catch (Exception e) | ||
2081 | { | ||
2082 | m_log.ErrorFormat( | ||
2083 | "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectLoaded failed - continuing. {0} {1}", | ||
2084 | e.Message, e.StackTrace); | ||
2085 | } | ||
2086 | } | ||
2087 | } | ||
2088 | } | ||
2089 | |||
2090 | public void TriggerOnSceneObjectPreSave(SceneObjectGroup persistingSo, SceneObjectGroup originalSo) | ||
2091 | { | ||
2092 | SceneObjectPreSaveDelegate handler = OnSceneObjectPreSave; | ||
2093 | if (handler != null) | ||
2094 | { | ||
2095 | foreach (SceneObjectPreSaveDelegate d in handler.GetInvocationList()) | ||
2096 | { | ||
2097 | try | ||
2098 | { | ||
2099 | d(persistingSo, originalSo); | ||
2100 | } | ||
2101 | catch (Exception e) | ||
2102 | { | ||
2103 | m_log.ErrorFormat( | ||
2104 | "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPreSave failed - continuing. {0} {1}", | ||
2105 | e.Message, e.StackTrace); | ||
2106 | } | ||
2107 | } | ||
2108 | } | ||
2109 | } | ||
2110 | |||
2111 | public void TriggerOnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed) | ||
2112 | { | ||
2113 | SceneObjectPartCopyDelegate handler = OnSceneObjectPartCopy; | ||
2114 | if (handler != null) | ||
2115 | { | ||
2116 | foreach (SceneObjectPartCopyDelegate d in handler.GetInvocationList()) | ||
2117 | { | ||
2118 | try | ||
2119 | { | ||
2120 | d(copy, original, userExposed); | ||
2121 | } | ||
2122 | catch (Exception e) | ||
2123 | { | ||
2124 | m_log.ErrorFormat( | ||
2125 | "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPartCopy failed - continuing. {0} {1}", | ||
2126 | e.Message, e.StackTrace); | ||
2127 | } | ||
2128 | } | ||
2129 | } | ||
2130 | } | ||
2040 | } | 2131 | } |
2041 | } | 2132 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index a523351..4e80bf2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -82,6 +82,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
82 | public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID); | 82 | public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID); |
83 | public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID); | 83 | public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID); |
84 | public delegate bool TeleportHandler(UUID userID, Scene scene); | 84 | public delegate bool TeleportHandler(UUID userID, Scene scene); |
85 | public delegate bool ControlPrimMediaHandler(UUID userID, UUID primID, int face); | ||
86 | public delegate bool InteractWithPrimMediaHandler(UUID userID, UUID primID, int face); | ||
85 | #endregion | 87 | #endregion |
86 | 88 | ||
87 | public class ScenePermissions | 89 | public class ScenePermissions |
@@ -141,6 +143,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
141 | public event CopyUserInventoryHandler OnCopyUserInventory; | 143 | public event CopyUserInventoryHandler OnCopyUserInventory; |
142 | public event DeleteUserInventoryHandler OnDeleteUserInventory; | 144 | public event DeleteUserInventoryHandler OnDeleteUserInventory; |
143 | public event TeleportHandler OnTeleport; | 145 | public event TeleportHandler OnTeleport; |
146 | public event ControlPrimMediaHandler OnControlPrimMedia; | ||
147 | public event InteractWithPrimMediaHandler OnInteractWithPrimMedia; | ||
144 | #endregion | 148 | #endregion |
145 | 149 | ||
146 | #region Object Permission Checks | 150 | #region Object Permission Checks |
@@ -964,5 +968,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
964 | } | 968 | } |
965 | return true; | 969 | return true; |
966 | } | 970 | } |
971 | |||
972 | public bool CanControlPrimMedia(UUID userID, UUID primID, int face) | ||
973 | { | ||
974 | ControlPrimMediaHandler handler = OnControlPrimMedia; | ||
975 | if (handler != null) | ||
976 | { | ||
977 | Delegate[] list = handler.GetInvocationList(); | ||
978 | foreach (ControlPrimMediaHandler h in list) | ||
979 | { | ||
980 | if (h(userID, primID, face) == false) | ||
981 | return false; | ||
982 | } | ||
983 | } | ||
984 | return true; | ||
985 | } | ||
986 | |||
987 | public bool CanInteractWithPrimMedia(UUID userID, UUID primID, int face) | ||
988 | { | ||
989 | InteractWithPrimMediaHandler handler = OnInteractWithPrimMedia; | ||
990 | if (handler != null) | ||
991 | { | ||
992 | Delegate[] list = handler.GetInvocationList(); | ||
993 | foreach (InteractWithPrimMediaHandler h in list) | ||
994 | { | ||
995 | if (h(userID, primID, face) == false) | ||
996 | return false; | ||
997 | } | ||
998 | } | ||
999 | return true; | ||
1000 | } | ||
967 | } | 1001 | } |
968 | } | 1002 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ea52ffb..6c17be8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1918,9 +1918,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1918 | 1918 | ||
1919 | foreach (SceneObjectGroup group in PrimsFromDB) | 1919 | foreach (SceneObjectGroup group in PrimsFromDB) |
1920 | { | 1920 | { |
1921 | EventManager.TriggerOnSceneObjectLoaded(group); | ||
1922 | |||
1921 | if (group.RootPart == null) | 1923 | if (group.RootPart == null) |
1922 | { | 1924 | { |
1923 | m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children", | 1925 | m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", |
1924 | group.Children == null ? 0 : group.Children.Count); | 1926 | group.Children == null ? 0 : group.Children.Count); |
1925 | } | 1927 | } |
1926 | 1928 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5a3dc20..8ce79a2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1745,6 +1745,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1745 | backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; | 1745 | backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; |
1746 | HasGroupChanged = false; | 1746 | HasGroupChanged = false; |
1747 | 1747 | ||
1748 | m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); | ||
1748 | datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); | 1749 | datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); |
1749 | 1750 | ||
1750 | backup_group.ForEachPart(delegate(SceneObjectPart part) | 1751 | backup_group.ForEachPart(delegate(SceneObjectPart part) |
@@ -1795,6 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1795 | /// <summary> | 1796 | /// <summary> |
1796 | /// Duplicates this object, including operations such as physics set up and attaching to the backup event. | 1797 | /// Duplicates this object, including operations such as physics set up and attaching to the backup event. |
1797 | /// </summary> | 1798 | /// </summary> |
1799 | /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param> | ||
1798 | /// <returns></returns> | 1800 | /// <returns></returns> |
1799 | public SceneObjectGroup Copy(bool userExposed) | 1801 | public SceneObjectGroup Copy(bool userExposed) |
1800 | { | 1802 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index badd357..efdc19c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -59,6 +59,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
59 | REGION = 256, | 59 | REGION = 256, |
60 | TELEPORT = 512, | 60 | TELEPORT = 512, |
61 | REGION_RESTART = 1024, | 61 | REGION_RESTART = 1024, |
62 | MEDIA = 2048, | ||
62 | ANIMATION = 16384 | 63 | ANIMATION = 16384 |
63 | } | 64 | } |
64 | 65 | ||
@@ -330,6 +331,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
330 | protected Vector3 m_lastAcceleration; | 331 | protected Vector3 m_lastAcceleration; |
331 | protected Vector3 m_lastAngularVelocity; | 332 | protected Vector3 m_lastAngularVelocity; |
332 | protected int m_lastTerseSent; | 333 | protected int m_lastTerseSent; |
334 | |||
335 | /// <summary> | ||
336 | /// Stores media texture data | ||
337 | /// </summary> | ||
338 | protected string m_mediaUrl; | ||
333 | 339 | ||
334 | // TODO: Those have to be changed into persistent properties at some later point, | 340 | // TODO: Those have to be changed into persistent properties at some later point, |
335 | // or sit-camera on vehicles will break on sim-crossing. | 341 | // or sit-camera on vehicles will break on sim-crossing. |
@@ -984,18 +990,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
984 | TriggerScriptChangedEvent(Changed.SCALE); | 990 | TriggerScriptChangedEvent(Changed.SCALE); |
985 | } | 991 | } |
986 | } | 992 | } |
993 | |||
987 | public byte UpdateFlag | 994 | public byte UpdateFlag |
988 | { | 995 | { |
989 | get { return m_updateFlag; } | 996 | get { return m_updateFlag; } |
990 | set { m_updateFlag = value; } | 997 | set { m_updateFlag = value; } |
991 | } | 998 | } |
999 | |||
1000 | /// <summary> | ||
1001 | /// Used for media on a prim. | ||
1002 | /// </summary> | ||
1003 | /// Do not change this value directly - always do it through an IMoapModule. | ||
1004 | public string MediaUrl | ||
1005 | { | ||
1006 | get | ||
1007 | { | ||
1008 | return m_mediaUrl; | ||
1009 | } | ||
1010 | |||
1011 | set | ||
1012 | { | ||
1013 | m_mediaUrl = value; | ||
1014 | |||
1015 | if (ParentGroup != null) | ||
1016 | ParentGroup.HasGroupChanged = true; | ||
1017 | } | ||
1018 | } | ||
992 | 1019 | ||
993 | [XmlIgnore] | 1020 | [XmlIgnore] |
994 | public bool CreateSelected | 1021 | public bool CreateSelected |
995 | { | 1022 | { |
996 | get { return m_createSelected; } | 1023 | get { return m_createSelected; } |
997 | set { m_createSelected = value; } | 1024 | set { m_createSelected = value; } |
998 | } | 1025 | } |
999 | 1026 | ||
1000 | #endregion | 1027 | #endregion |
1001 | 1028 | ||
@@ -1553,6 +1580,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1553 | /// <summary> | 1580 | /// <summary> |
1554 | /// Duplicates this part. | 1581 | /// Duplicates this part. |
1555 | /// </summary> | 1582 | /// </summary> |
1583 | /// <param name="localID"></param> | ||
1584 | /// <param name="AgentID"></param> | ||
1585 | /// <param name="GroupID"></param> | ||
1586 | /// <param name="linkNum"></param> | ||
1587 | /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param> | ||
1556 | /// <returns></returns> | 1588 | /// <returns></returns> |
1557 | public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) | 1589 | public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) |
1558 | { | 1590 | { |
@@ -1616,7 +1648,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1616 | dupe.DoPhysicsPropertyUpdate(UsePhysics, true); | 1648 | dupe.DoPhysicsPropertyUpdate(UsePhysics, true); |
1617 | } | 1649 | } |
1618 | 1650 | ||
1619 | return dupe; | 1651 | ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); |
1652 | |||
1653 | // m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); | ||
1654 | |||
1655 | return dupe; | ||
1620 | } | 1656 | } |
1621 | 1657 | ||
1622 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 1658 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 44c3d12..b3fa2f4 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1059,7 +1059,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1059 | /// </summary> | 1059 | /// </summary> |
1060 | public void MakeChildAgent() | 1060 | public void MakeChildAgent() |
1061 | { | 1061 | { |
1062 | Animator.ResetAnimations(); | 1062 | // It looks like m_animator is set to null somewhere, and MakeChild |
1063 | // is called after that. Probably in aborted teleports. | ||
1064 | if (m_animator == null) | ||
1065 | m_animator = new ScenePresenceAnimator(this); | ||
1066 | else | ||
1067 | Animator.ResetAnimations(); | ||
1063 | 1068 | ||
1064 | // m_log.DebugFormat( | 1069 | // m_log.DebugFormat( |
1065 | // "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", | 1070 | // "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 236458c..a711ebf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2111,7 +2111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2111 | return; | 2111 | return; |
2112 | 2112 | ||
2113 | // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) | 2113 | // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) |
2114 | LSL_Vector currentPos = llGetLocalPos(); | 2114 | LSL_Vector currentPos = GetPartLocalPos(part); |
2115 | 2115 | ||
2116 | float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); | 2116 | float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); |
2117 | bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); | 2117 | bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); |
@@ -2144,33 +2144,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2144 | public LSL_Vector llGetLocalPos() | 2144 | public LSL_Vector llGetLocalPos() |
2145 | { | 2145 | { |
2146 | m_host.AddScriptLPS(1); | 2146 | m_host.AddScriptLPS(1); |
2147 | if (m_host.IsAttachment == true) { | 2147 | return GetPartLocalPos(m_host); |
2148 | if (m_host.IsRoot == true) | 2148 | } |
2149 | { | ||
2150 | return new LSL_Vector(m_host.AbsolutePosition.X, | ||
2151 | m_host.AbsolutePosition.Y, | ||
2152 | m_host.AbsolutePosition.Z); | ||
2153 | |||
2154 | } | ||
2155 | else | ||
2156 | { | ||
2157 | return new LSL_Vector(m_host.OffsetPosition.X, | ||
2158 | m_host.OffsetPosition.Y, | ||
2159 | m_host.OffsetPosition.Z); | ||
2160 | } | ||
2161 | } | ||
2162 | 2149 | ||
2163 | if (m_host.ParentID != 0) | 2150 | protected LSL_Vector GetPartLocalPos(SceneObjectPart part) |
2151 | { | ||
2152 | m_host.AddScriptLPS(1); | ||
2153 | if (part.ParentID != 0) | ||
2164 | { | 2154 | { |
2165 | return new LSL_Vector(m_host.OffsetPosition.X, | 2155 | return new LSL_Vector(part.OffsetPosition.X, |
2166 | m_host.OffsetPosition.Y, | 2156 | part.OffsetPosition.Y, |
2167 | m_host.OffsetPosition.Z); | 2157 | part.OffsetPosition.Z); |
2168 | } | 2158 | } |
2169 | else | 2159 | else |
2170 | { | 2160 | { |
2171 | return new LSL_Vector(m_host.AbsolutePosition.X, | 2161 | return new LSL_Vector(part.AbsolutePosition.X, |
2172 | m_host.AbsolutePosition.Y, | 2162 | part.AbsolutePosition.Y, |
2173 | m_host.AbsolutePosition.Z); | 2163 | part.AbsolutePosition.Z); |
2174 | } | 2164 | } |
2175 | } | 2165 | } |
2176 | 2166 | ||
@@ -8300,6 +8290,241 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8300 | return res; | 8290 | return res; |
8301 | } | 8291 | } |
8302 | 8292 | ||
8293 | public LSL_List llGetPrimMediaParams(int face, LSL_List rules) | ||
8294 | { | ||
8295 | m_host.AddScriptLPS(1); | ||
8296 | ScriptSleep(1000); | ||
8297 | |||
8298 | // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid | ||
8299 | // TODO: Need to correctly handle case where a face has no media (which gives back an empty list). | ||
8300 | // Assuming silently fail means give back an empty list. Ideally, need to check this. | ||
8301 | if (face < 0 || face > m_host.GetNumberOfSides() - 1) | ||
8302 | return new LSL_List(); | ||
8303 | |||
8304 | return GetPrimMediaParams(face, rules); | ||
8305 | } | ||
8306 | |||
8307 | private LSL_List GetPrimMediaParams(int face, LSL_List rules) | ||
8308 | { | ||
8309 | IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); | ||
8310 | if (null == module) | ||
8311 | throw new Exception("Media on a prim functions not available"); | ||
8312 | |||
8313 | MediaEntry me = module.GetMediaEntry(m_host, face); | ||
8314 | |||
8315 | // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams | ||
8316 | if (null == me) | ||
8317 | return new LSL_List(); | ||
8318 | |||
8319 | LSL_List res = new LSL_List(); | ||
8320 | |||
8321 | for (int i = 0; i < rules.Length; i++) | ||
8322 | { | ||
8323 | int code = (int)rules.GetLSLIntegerItem(i); | ||
8324 | |||
8325 | switch (code) | ||
8326 | { | ||
8327 | case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: | ||
8328 | // Not implemented | ||
8329 | res.Add(new LSL_Integer(0)); | ||
8330 | break; | ||
8331 | |||
8332 | case ScriptBaseClass.PRIM_MEDIA_CONTROLS: | ||
8333 | if (me.Controls == MediaControls.Standard) | ||
8334 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD)); | ||
8335 | else | ||
8336 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI)); | ||
8337 | break; | ||
8338 | |||
8339 | case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: | ||
8340 | res.Add(new LSL_String(me.CurrentURL)); | ||
8341 | break; | ||
8342 | |||
8343 | case ScriptBaseClass.PRIM_MEDIA_HOME_URL: | ||
8344 | res.Add(new LSL_String(me.HomeURL)); | ||
8345 | break; | ||
8346 | |||
8347 | case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: | ||
8348 | res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); | ||
8349 | break; | ||
8350 | |||
8351 | case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: | ||
8352 | res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); | ||
8353 | break; | ||
8354 | |||
8355 | case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: | ||
8356 | res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); | ||
8357 | break; | ||
8358 | |||
8359 | case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: | ||
8360 | res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); | ||
8361 | break; | ||
8362 | |||
8363 | case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: | ||
8364 | res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); | ||
8365 | break; | ||
8366 | |||
8367 | case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS: | ||
8368 | res.Add(new LSL_Integer(me.Width)); | ||
8369 | break; | ||
8370 | |||
8371 | case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS: | ||
8372 | res.Add(new LSL_Integer(me.Height)); | ||
8373 | break; | ||
8374 | |||
8375 | case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE: | ||
8376 | res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); | ||
8377 | break; | ||
8378 | |||
8379 | case ScriptBaseClass.PRIM_MEDIA_WHITELIST: | ||
8380 | string[] urls = (string[])me.WhiteList.Clone(); | ||
8381 | |||
8382 | for (int j = 0; j < urls.Length; j++) | ||
8383 | urls[j] = Uri.EscapeDataString(urls[j]); | ||
8384 | |||
8385 | res.Add(new LSL_String(string.Join(", ", urls))); | ||
8386 | break; | ||
8387 | |||
8388 | case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT: | ||
8389 | res.Add(new LSL_Integer((int)me.InteractPermissions)); | ||
8390 | break; | ||
8391 | |||
8392 | case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL: | ||
8393 | res.Add(new LSL_Integer((int)me.ControlPermissions)); | ||
8394 | break; | ||
8395 | } | ||
8396 | } | ||
8397 | |||
8398 | return res; | ||
8399 | } | ||
8400 | |||
8401 | public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules) | ||
8402 | { | ||
8403 | m_host.AddScriptLPS(1); | ||
8404 | ScriptSleep(1000); | ||
8405 | |||
8406 | // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid | ||
8407 | // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this. | ||
8408 | // Don't perform the media check directly | ||
8409 | if (face < 0 || face > m_host.GetNumberOfSides() - 1) | ||
8410 | return ScriptBaseClass.LSL_STATUS_OK; | ||
8411 | |||
8412 | return SetPrimMediaParams(face, rules); | ||
8413 | } | ||
8414 | |||
8415 | private LSL_Integer SetPrimMediaParams(int face, LSL_List rules) | ||
8416 | { | ||
8417 | IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); | ||
8418 | if (null == module) | ||
8419 | throw new Exception("Media on a prim functions not available"); | ||
8420 | |||
8421 | MediaEntry me = module.GetMediaEntry(m_host, face); | ||
8422 | if (null == me) | ||
8423 | me = new MediaEntry(); | ||
8424 | |||
8425 | int i = 0; | ||
8426 | |||
8427 | while (i < rules.Length - 1) | ||
8428 | { | ||
8429 | int code = rules.GetLSLIntegerItem(i++); | ||
8430 | |||
8431 | switch (code) | ||
8432 | { | ||
8433 | case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: | ||
8434 | me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false); | ||
8435 | break; | ||
8436 | |||
8437 | case ScriptBaseClass.PRIM_MEDIA_CONTROLS: | ||
8438 | int v = rules.GetLSLIntegerItem(i++); | ||
8439 | if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v) | ||
8440 | me.Controls = MediaControls.Standard; | ||
8441 | else | ||
8442 | me.Controls = MediaControls.Mini; | ||
8443 | break; | ||
8444 | |||
8445 | case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: | ||
8446 | me.CurrentURL = rules.GetLSLStringItem(i++); | ||
8447 | break; | ||
8448 | |||
8449 | case ScriptBaseClass.PRIM_MEDIA_HOME_URL: | ||
8450 | me.HomeURL = rules.GetLSLStringItem(i++); | ||
8451 | break; | ||
8452 | |||
8453 | case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: | ||
8454 | me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); | ||
8455 | break; | ||
8456 | |||
8457 | case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: | ||
8458 | me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); | ||
8459 | break; | ||
8460 | |||
8461 | case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: | ||
8462 | me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); | ||
8463 | break; | ||
8464 | |||
8465 | case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: | ||
8466 | me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); | ||
8467 | break; | ||
8468 | |||
8469 | case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: | ||
8470 | me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); | ||
8471 | break; | ||
8472 | |||
8473 | case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS: | ||
8474 | me.Width = (int)rules.GetLSLIntegerItem(i++); | ||
8475 | break; | ||
8476 | |||
8477 | case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS: | ||
8478 | me.Height = (int)rules.GetLSLIntegerItem(i++); | ||
8479 | break; | ||
8480 | |||
8481 | case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE: | ||
8482 | me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); | ||
8483 | break; | ||
8484 | |||
8485 | case ScriptBaseClass.PRIM_MEDIA_WHITELIST: | ||
8486 | string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' }); | ||
8487 | List<string> whiteListUrls = new List<string>(); | ||
8488 | Array.ForEach( | ||
8489 | rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); }); | ||
8490 | me.WhiteList = whiteListUrls.ToArray(); | ||
8491 | break; | ||
8492 | |||
8493 | case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT: | ||
8494 | me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++); | ||
8495 | break; | ||
8496 | |||
8497 | case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL: | ||
8498 | me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++); | ||
8499 | break; | ||
8500 | } | ||
8501 | } | ||
8502 | |||
8503 | module.SetMediaEntry(m_host, face, me); | ||
8504 | |||
8505 | return ScriptBaseClass.LSL_STATUS_OK; | ||
8506 | } | ||
8507 | |||
8508 | public LSL_Integer llClearPrimMedia(LSL_Integer face) | ||
8509 | { | ||
8510 | m_host.AddScriptLPS(1); | ||
8511 | ScriptSleep(1000); | ||
8512 | |||
8513 | // LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid | ||
8514 | // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this. | ||
8515 | // FIXME: Don't perform the media check directly | ||
8516 | if (face < 0 || face > m_host.GetNumberOfSides() - 1) | ||
8517 | return ScriptBaseClass.LSL_STATUS_OK; | ||
8518 | |||
8519 | IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); | ||
8520 | if (null == module) | ||
8521 | throw new Exception("Media on a prim functions not available"); | ||
8522 | |||
8523 | module.ClearMediaEntry(m_host, face); | ||
8524 | |||
8525 | return ScriptBaseClass.LSL_STATUS_OK; | ||
8526 | } | ||
8527 | |||
8303 | // <remarks> | 8528 | // <remarks> |
8304 | // <para> | 8529 | // <para> |
8305 | // The .NET definition of base 64 is: | 8530 | // The .NET definition of base 64 is: |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 1fa8c30..fffe65c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index cba46a3..561e3b3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | |||
@@ -62,6 +62,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
62 | void llBreakLink(int linknum); | 62 | void llBreakLink(int linknum); |
63 | LSL_Integer llCeil(double f); | 63 | LSL_Integer llCeil(double f); |
64 | void llClearCameraParams(); | 64 | void llClearCameraParams(); |
65 | LSL_Integer llClearPrimMedia(LSL_Integer face); | ||
65 | void llCloseRemoteDataChannel(string channel); | 66 | void llCloseRemoteDataChannel(string channel); |
66 | LSL_Float llCloud(LSL_Vector offset); | 67 | LSL_Float llCloud(LSL_Vector offset); |
67 | void llCollisionFilter(string name, string id, int accept); | 68 | void llCollisionFilter(string name, string id, int accept); |
@@ -162,6 +163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
162 | LSL_List llGetParcelPrimOwners(LSL_Vector pos); | 163 | LSL_List llGetParcelPrimOwners(LSL_Vector pos); |
163 | LSL_Integer llGetPermissions(); | 164 | LSL_Integer llGetPermissions(); |
164 | LSL_Key llGetPermissionsKey(); | 165 | LSL_Key llGetPermissionsKey(); |
166 | LSL_List llGetPrimMediaParams(int face, LSL_List rules); | ||
165 | LSL_Vector llGetPos(); | 167 | LSL_Vector llGetPos(); |
166 | LSL_List llGetPrimitiveParams(LSL_List rules); | 168 | LSL_List llGetPrimitiveParams(LSL_List rules); |
167 | LSL_Integer llGetRegionAgentCount(); | 169 | LSL_Integer llGetRegionAgentCount(); |
@@ -332,6 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
332 | void llSetParcelMusicURL(string url); | 334 | void llSetParcelMusicURL(string url); |
333 | void llSetPayPrice(int price, LSL_List quick_pay_buttons); | 335 | void llSetPayPrice(int price, LSL_List quick_pay_buttons); |
334 | void llSetPos(LSL_Vector pos); | 336 | void llSetPos(LSL_Vector pos); |
337 | LSL_Integer llSetPrimMediaParams(int face, LSL_List rules); | ||
335 | void llSetPrimitiveParams(LSL_List rules); | 338 | void llSetPrimitiveParams(LSL_List rules); |
336 | void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); | 339 | void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); |
337 | void llSetPrimURL(string url); | 340 | void llSetPrimURL(string url); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 69f48c9..5da6bb9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | |||
@@ -277,6 +277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
277 | public const int CHANGED_TELEPORT = 512; | 277 | public const int CHANGED_TELEPORT = 512; |
278 | public const int CHANGED_REGION_RESTART = 1024; | 278 | public const int CHANGED_REGION_RESTART = 1024; |
279 | public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART | 279 | public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART |
280 | public const int CHANGED_MEDIA = 2048; | ||
280 | public const int CHANGED_ANIMATION = 16384; | 281 | public const int CHANGED_ANIMATION = 16384; |
281 | public const int TYPE_INVALID = 0; | 282 | public const int TYPE_INVALID = 0; |
282 | public const int TYPE_INTEGER = 1; | 283 | public const int TYPE_INTEGER = 1; |
@@ -518,6 +519,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
518 | public const int TOUCH_INVALID_FACE = -1; | 519 | public const int TOUCH_INVALID_FACE = -1; |
519 | public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); | 520 | public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); |
520 | public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; | 521 | public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; |
522 | |||
523 | // constants for llGetPrimMediaParams/llSetPrimMediaParams | ||
524 | public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0; | ||
525 | public const int PRIM_MEDIA_CONTROLS = 1; | ||
526 | public const int PRIM_MEDIA_CURRENT_URL = 2; | ||
527 | public const int PRIM_MEDIA_HOME_URL = 3; | ||
528 | public const int PRIM_MEDIA_AUTO_LOOP = 4; | ||
529 | public const int PRIM_MEDIA_AUTO_PLAY = 5; | ||
530 | public const int PRIM_MEDIA_AUTO_SCALE = 6; | ||
531 | public const int PRIM_MEDIA_AUTO_ZOOM = 7; | ||
532 | public const int PRIM_MEDIA_FIRST_CLICK_INTERACT = 8; | ||
533 | public const int PRIM_MEDIA_WIDTH_PIXELS = 9; | ||
534 | public const int PRIM_MEDIA_HEIGHT_PIXELS = 10; | ||
535 | public const int PRIM_MEDIA_WHITELIST_ENABLE = 11; | ||
536 | public const int PRIM_MEDIA_WHITELIST = 12; | ||
537 | public const int PRIM_MEDIA_PERMS_INTERACT = 13; | ||
538 | public const int PRIM_MEDIA_PERMS_CONTROL = 14; | ||
539 | |||
540 | public const int PRIM_MEDIA_CONTROLS_STANDARD = 0; | ||
541 | public const int PRIM_MEDIA_CONTROLS_MINI = 1; | ||
542 | |||
543 | public const int PRIM_MEDIA_PERM_NONE = 0; | ||
544 | public const int PRIM_MEDIA_PERM_OWNER = 1; | ||
545 | public const int PRIM_MEDIA_PERM_GROUP = 2; | ||
546 | public const int PRIM_MEDIA_PERM_ANYONE = 4; | ||
547 | |||
548 | // extra constants for llSetPrimMediaParams | ||
549 | public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); | ||
550 | public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); | ||
551 | public static readonly LSLInteger LSL_STATUS_TYPE_MISMATCH = new LSLInteger(1001); | ||
552 | public static readonly LSLInteger LSL_STATUS_BOUNDS_ERROR = new LSLInteger(1002); | ||
553 | public static readonly LSLInteger LSL_STATUS_NOT_FOUND = new LSLInteger(1003); | ||
554 | public static readonly LSLInteger LSL_STATUS_NOT_SUPPORTED = new LSLInteger(1004); | ||
555 | public static readonly LSLInteger LSL_STATUS_INTERNAL_ERROR = new LSLInteger(1999); | ||
556 | public static readonly LSLInteger LSL_STATUS_WHITELIST_FAILED = new LSLInteger(2001); | ||
521 | 557 | ||
522 | // Constants for default textures | 558 | // Constants for default textures |
523 | public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f"; | 559 | public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f"; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index e86d08c..f14967e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | |||
@@ -1834,5 +1834,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
1834 | { | 1834 | { |
1835 | return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2); | 1835 | return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2); |
1836 | } | 1836 | } |
1837 | |||
1838 | public LSL_List llGetPrimMediaParams(int face, LSL_List rules) | ||
1839 | { | ||
1840 | return m_LSL_Functions.llGetPrimMediaParams(face, rules); | ||
1841 | } | ||
1842 | |||
1843 | public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules) | ||
1844 | { | ||
1845 | return m_LSL_Functions.llSetPrimMediaParams(face, rules); | ||
1846 | } | ||
1847 | |||
1848 | public LSL_Integer llClearPrimMedia(LSL_Integer face) | ||
1849 | { | ||
1850 | return m_LSL_Functions.llClearPrimMedia(face); | ||
1851 | } | ||
1837 | } | 1852 | } |
1838 | } | 1853 | } |
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 42eca05..96d2605 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs | |||
@@ -358,7 +358,7 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
358 | 358 | ||
359 | private bool GetBoolResponse(XmlRpcRequest request, out string reason) | 359 | private bool GetBoolResponse(XmlRpcRequest request, out string reason) |
360 | { | 360 | { |
361 | //m_log.Debug("[HGrid]: Linking to " + uri); | 361 | //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL); |
362 | XmlRpcResponse response = null; | 362 | XmlRpcResponse response = null; |
363 | try | 363 | try |
364 | { | 364 | { |
@@ -366,14 +366,14 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
366 | } | 366 | } |
367 | catch (Exception e) | 367 | catch (Exception e) |
368 | { | 368 | { |
369 | m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server "); | 369 | m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); |
370 | reason = "Exception: " + e.Message; | 370 | reason = "Exception: " + e.Message; |
371 | return false; | 371 | return false; |
372 | } | 372 | } |
373 | 373 | ||
374 | if (response.IsFault) | 374 | if (response.IsFault) |
375 | { | 375 | { |
376 | m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); | 376 | m_log.ErrorFormat("[HGrid]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); |
377 | reason = "XMLRPC Fault"; | 377 | reason = "XMLRPC Fault"; |
378 | return false; | 378 | return false; |
379 | } | 379 | } |
@@ -383,15 +383,29 @@ namespace OpenSim.Services.Connectors.Hypergrid | |||
383 | // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); | 383 | // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); |
384 | try | 384 | try |
385 | { | 385 | { |
386 | if (hash == null) | ||
387 | { | ||
388 | m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got null response from {0}! THIS IS BAAAAD", m_ServerURL); | ||
389 | reason = "Internal error 1"; | ||
390 | return false; | ||
391 | } | ||
386 | bool success = false; | 392 | bool success = false; |
387 | reason = string.Empty; | 393 | reason = string.Empty; |
388 | Boolean.TryParse((string)hash["result"], out success); | 394 | if (hash.ContainsKey("result")) |
395 | Boolean.TryParse((string)hash["result"], out success); | ||
396 | else | ||
397 | { | ||
398 | reason = "Internal error 2"; | ||
399 | m_log.WarnFormat("[USER AGENT CONNECTOR]: response from {0} does not have expected key 'result'", m_ServerURL); | ||
400 | } | ||
389 | 401 | ||
390 | return success; | 402 | return success; |
391 | } | 403 | } |
392 | catch (Exception e) | 404 | catch (Exception e) |
393 | { | 405 | { |
394 | m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace); | 406 | m_log.ErrorFormat("[HGrid]: Got exception on GetBoolResponse response."); |
407 | if (hash.ContainsKey("result") && hash["result"] != null) | ||
408 | m_log.ErrorFormat("Reply was ", (string)hash["result"]); | ||
395 | reason = "Exception: " + e.Message; | 409 | reason = "Exception: " + e.Message; |
396 | return false; | 410 | return false; |
397 | } | 411 | } |
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 3fc9327..3aaafe8 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs | |||
@@ -73,7 +73,7 @@ namespace OpenSim.Services.HypergridService | |||
73 | throw new Exception(String.Format("No section GatekeeperService in config file")); | 73 | throw new Exception(String.Format("No section GatekeeperService in config file")); |
74 | 74 | ||
75 | string accountService = serverConfig.GetString("UserAccountService", String.Empty); | 75 | string accountService = serverConfig.GetString("UserAccountService", String.Empty); |
76 | string homeUsersService = serverConfig.GetString("HomeUsersSecurityService", string.Empty); | 76 | string homeUsersService = serverConfig.GetString("UserAgentService", string.Empty); |
77 | string gridService = serverConfig.GetString("GridService", String.Empty); | 77 | string gridService = serverConfig.GetString("GridService", String.Empty); |
78 | string presenceService = serverConfig.GetString("PresenceService", String.Empty); | 78 | string presenceService = serverConfig.GetString("PresenceService", String.Empty); |
79 | string simulationService = serverConfig.GetString("SimulationService", String.Empty); | 79 | string simulationService = serverConfig.GetString("SimulationService", String.Empty); |
@@ -283,18 +283,23 @@ namespace OpenSim.Services.HypergridService | |||
283 | return false; | 283 | return false; |
284 | } | 284 | } |
285 | 285 | ||
286 | Object[] args = new Object[] { userURL }; | 286 | if (userURL == m_ExternalName) |
287 | IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); //ServerUtils.LoadPlugin<IUserAgentService>(m_AuthDll, args); | 287 | return m_UserAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID); |
288 | if (userAgentService != null) | 288 | else |
289 | { | 289 | { |
290 | try | 290 | Object[] args = new Object[] { userURL }; |
291 | IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); | ||
292 | if (userAgentService != null) | ||
291 | { | 293 | { |
292 | return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID); | 294 | try |
293 | } | 295 | { |
294 | catch | 296 | return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID); |
295 | { | 297 | } |
296 | m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL); | 298 | catch |
297 | return false; | 299 | { |
300 | m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL); | ||
301 | return false; | ||
302 | } | ||
298 | } | 303 | } |
299 | } | 304 | } |
300 | 305 | ||
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 4bee4b5..181d7f2 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs | |||
@@ -61,9 +61,11 @@ namespace OpenSim.Services.HypergridService | |||
61 | 61 | ||
62 | protected static IGridUserService m_GridUserService; | 62 | protected static IGridUserService m_GridUserService; |
63 | protected static IGridService m_GridService; | 63 | protected static IGridService m_GridService; |
64 | //protected static GatekeeperServiceConnector m_GatekeeperConnector; | 64 | protected static GatekeeperServiceConnector m_GatekeeperConnector; |
65 | protected static IGatekeeperService m_GatekeeperService; | 65 | protected static IGatekeeperService m_GatekeeperService; |
66 | 66 | ||
67 | protected static string m_GridName; | ||
68 | |||
67 | protected static bool m_BypassClientVerification; | 69 | protected static bool m_BypassClientVerification; |
68 | 70 | ||
69 | public UserAgentService(IConfigSource config) | 71 | public UserAgentService(IConfigSource config) |
@@ -90,8 +92,15 @@ namespace OpenSim.Services.HypergridService | |||
90 | Object[] args = new Object[] { config }; | 92 | Object[] args = new Object[] { config }; |
91 | m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args); | 93 | m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args); |
92 | m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args); | 94 | m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args); |
93 | //m_GatekeeperConnector = new GatekeeperServiceConnector(); | 95 | m_GatekeeperConnector = new GatekeeperServiceConnector(); |
94 | m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args); | 96 | m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args); |
97 | |||
98 | m_GridName = serverConfig.GetString("ExternalName", string.Empty); | ||
99 | if (m_GridName == string.Empty) | ||
100 | { | ||
101 | serverConfig = config.Configs["GatekeeperService"]; | ||
102 | m_GridName = serverConfig.GetString("ExternalName", string.Empty); | ||
103 | } | ||
95 | } | 104 | } |
96 | } | 105 | } |
97 | 106 | ||
@@ -139,7 +148,12 @@ namespace OpenSim.Services.HypergridService | |||
139 | TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); | 148 | TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); |
140 | 149 | ||
141 | //bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason); | 150 | //bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason); |
142 | bool success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); | 151 | bool success = false; |
152 | string gridName = "http://" + gatekeeper.ExternalHostName + ":" + gatekeeper.HttpPort; | ||
153 | if (m_GridName == gridName) | ||
154 | success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); | ||
155 | else | ||
156 | success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason); | ||
143 | 157 | ||
144 | if (!success) | 158 | if (!success) |
145 | { | 159 | { |
@@ -179,7 +193,7 @@ namespace OpenSim.Services.HypergridService | |||
179 | m_TravelingAgents[agentCircuit.SessionID] = travel; | 193 | m_TravelingAgents[agentCircuit.SessionID] = travel; |
180 | } | 194 | } |
181 | travel.UserID = agentCircuit.AgentID; | 195 | travel.UserID = agentCircuit.AgentID; |
182 | travel.GridExternalName = region.ExternalHostName + ":" + region.HttpPort; | 196 | travel.GridExternalName = "http://" + region.ExternalHostName + ":" + region.HttpPort; |
183 | travel.ServiceToken = agentCircuit.ServiceSessionID; | 197 | travel.ServiceToken = agentCircuit.ServiceSessionID; |
184 | if (old != null) | 198 | if (old != null) |
185 | travel.ClientToken = old.ClientToken; | 199 | travel.ClientToken = old.ClientToken; |
@@ -215,6 +229,7 @@ namespace OpenSim.Services.HypergridService | |||
215 | return false; | 229 | return false; |
216 | 230 | ||
217 | TravelingAgentInfo travel = m_TravelingAgents[sessionID]; | 231 | TravelingAgentInfo travel = m_TravelingAgents[sessionID]; |
232 | |||
218 | return travel.GridExternalName == thisGridExternalName; | 233 | return travel.GridExternalName == thisGridExternalName; |
219 | } | 234 | } |
220 | 235 | ||
diff --git a/OpenSim/Tools/Configger/ConfigurationLoader.cs b/OpenSim/Tools/Configger/ConfigurationLoader.cs index 3d1b668..e74debb 100644 --- a/OpenSim/Tools/Configger/ConfigurationLoader.cs +++ b/OpenSim/Tools/Configger/ConfigurationLoader.cs | |||
@@ -241,21 +241,6 @@ namespace OpenSim.Tools.Configger | |||
241 | config.Set("EventQueue", true); | 241 | config.Set("EventQueue", true); |
242 | } | 242 | } |
243 | 243 | ||
244 | { | ||
245 | IConfig config = defaultConfig.Configs["Network"]; | ||
246 | |||
247 | if (null == config) | ||
248 | config = defaultConfig.AddConfig("Network"); | ||
249 | |||
250 | config.Set("default_location_x", 1000); | ||
251 | config.Set("default_location_y", 1000); | ||
252 | config.Set("grid_send_key", "null"); | ||
253 | config.Set("grid_recv_key", "null"); | ||
254 | config.Set("user_send_key", "null"); | ||
255 | config.Set("user_recv_key", "null"); | ||
256 | config.Set("secure_inventory_server", "true"); | ||
257 | } | ||
258 | |||
259 | return defaultConfig; | 244 | return defaultConfig; |
260 | } | 245 | } |
261 | 246 | ||