aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2010-08-06 18:28:53 +0100
committerJustin Clark-Casey (justincc)2010-08-06 18:29:30 +0100
commit1270727c969db07831866947b611d49873031739 (patch)
tree8fd490eaf5c49d69be948fd9e58c0be1f7e38331 /OpenSim
parentChange XEngine to use the new constant (diff)
parentfix mysql/mssql prim serialization problem (diff)
downloadopensim-SC-1270727c969db07831866947b611d49873031739.zip
opensim-SC-1270727c969db07831866947b611d49873031739.tar.gz
opensim-SC-1270727c969db07831866947b611d49873031739.tar.bz2
opensim-SC-1270727c969db07831866947b611d49873031739.tar.xz
Merge branch 'moap'
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs22
-rw-r--r--OpenSim/Data/MSSQL/Resources/RegionStore.migrations9
-rw-r--r--OpenSim/Data/MySQL/MySQLLegacyRegionData.cs16
-rw-r--r--OpenSim/Data/MySQL/Resources/RegionStore.migrations9
-rw-r--r--OpenSim/Data/SQLite/Resources/020_RegionStore.sql6
-rw-r--r--OpenSim/Data/SQLite/SQLiteRegionData.cs24
-rw-r--r--OpenSim/Framework/PrimitiveBaseShape.cs115
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs2
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs596
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs89
-rw-r--r--OpenSim/Region/Framework/Interfaces/IMoapModule.cs67
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs97
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Permissions.cs38
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs40
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs235
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs15
21 files changed, 1396 insertions, 32 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
333ELSE 333ELSE
@@ -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
391ELSE 391ELSE
@@ -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
4CREATE TABLE [dbo].[prims]( 4CREATE TABLE [dbo].[prims](
@@ -925,5 +925,12 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
925 925
926COMMIT 926COMMIT
927 927
928:VERSION 24
929-- Added post 0.7
930
931BEGIN TRANSACTION
928 932
933ALTER TABLE prims ADD COLUMN MediaURL varchar(255)
934ALTER TABLE primshapes ADD COLUMN Media TEXT
929 935
936COMMIT \ 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 3f644f9..1369704 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
4BEGIN; 4BEGIN;
@@ -800,3 +800,10 @@ BEGIN;
800ALTER 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`; 800ALTER 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`;
801COMMIT; 801COMMIT;
802 802
803:VERSION 35 #---------------------
804-- Added post 0.7
805
806BEGIN;
807ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
808ALTER TABLE primshapes ADD COLUMN Media TEXT;
809COMMIT; \ 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 @@
1BEGIN;
2
3ALTER TABLE prims ADD COLUMN MediaURL varchar(255);
4ALTER TABLE primshapes ADD COLUMN Media TEXT;
5
6COMMIT; \ 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;
34using log4net; 34using log4net;
35using Mono.Data.Sqlite; 35using Mono.Data.Sqlite;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 40using 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 4d1de22..70a61cc 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -26,12 +26,17 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Drawing; 30using System.Drawing;
30using System.Drawing.Imaging; 31using System.Drawing.Imaging;
32using System.IO;
31using System.Reflection; 33using System.Reflection;
34using System.Xml;
35using System.Xml.Schema;
32using System.Xml.Serialization; 36using System.Xml.Serialization;
33using log4net; 37using log4net;
34using OpenMetaverse; 38using OpenMetaverse;
39using OpenMetaverse.StructuredData;
35 40
36namespace OpenSim.Framework 41namespace 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/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 0aec01a..c59eedf 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -4288,8 +4288,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4288 4288
4289 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) 4289 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
4290 { 4290 {
4291
4292
4293 int notifyCount = ownersAndCount.Count; 4291 int notifyCount = ownersAndCount.Count;
4294 ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); 4292 ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
4295 4293
@@ -4561,6 +4559,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4561 update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; 4559 update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
4562 update.Scale = data.Shape.Scale; 4560 update.Scale = data.Shape.Scale;
4563 update.Text = Util.StringToBytes256(data.Text); 4561 update.Text = Util.StringToBytes256(data.Text);
4562 update.MediaURL = Util.StringToBytes256(data.MediaUrl);
4564 4563
4565 #region PrimFlags 4564 #region PrimFlags
4566 4565
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Collections.Specialized;
32using System.Reflection;
33using System.IO;
34using System.Web;
35using System.Xml;
36using log4net;
37using Mono.Addins;
38using Nini.Config;
39using OpenMetaverse;
40using OpenMetaverse.Messages.Linden;
41using OpenMetaverse.StructuredData;
42using OpenSim.Framework;
43using OpenSim.Framework.Capabilities;
44using OpenSim.Framework.Servers;
45using OpenSim.Framework.Servers.HttpServer;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Services.Interfaces;
49using Caps = OpenSim.Framework.Capabilities.Caps;
50using OSDArray = OpenMetaverse.StructuredData.OSDArray;
51using OSDMap = OpenMetaverse.StructuredData.OSDMap;
52
53namespace 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 1d70546..bc54997 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
28using System;
29using OpenMetaverse;
30using OpenSim.Region.Framework.Scenes;
31
32namespace 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 9db2e41..0ae3146 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -330,10 +330,38 @@ namespace OpenSim.Region.Framework.Scenes
330 /// If the object is being attached, then the avatarID will be present. If the object is being detached then 330 /// If the object is being attached, then the avatarID will be present. If the object is being detached then
331 /// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical). 331 /// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
332 public delegate void Attach(uint localID, UUID itemID, UUID avatarID); 332 public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
333 public event Attach OnAttach; 333 public event Attach OnAttach;
334
335 /// <summary>
336 /// Called immediately after an object is loaded from storage.
337 /// </summary>
338 public event SceneObjectDelegate OnSceneObjectLoaded;
339 public delegate void SceneObjectDelegate(SceneObjectGroup so);
340
341 /// <summary>
342 /// Called immediately before an object is saved to storage.
343 /// </summary>
344 /// <param name="persistingSo">
345 /// The scene object being persisted.
346 /// 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.
347 /// </param>
348 /// <param name="originalSo">
349 /// The original scene object being persisted. Changes here will stay in memory but will not be saved to storage on this save.
350 /// </param>
351 public event SceneObjectPreSaveDelegate OnSceneObjectPreSave;
352 public delegate void SceneObjectPreSaveDelegate(SceneObjectGroup persistingSo, SceneObjectGroup originalSo);
353
354 /// <summary>
355 /// Called when a scene object part is cloned within the region.
356 /// </summary>
357 /// <param name="copy"></param>
358 /// <param name="original"></param>
359 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
360 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy;
361 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed);
334 362
335 public delegate void RegionUp(GridRegion region); 363 public delegate void RegionUp(GridRegion region);
336 public event RegionUp OnRegionUp; 364 public event RegionUp OnRegionUp;
337 365
338 public class MoneyTransferArgs : EventArgs 366 public class MoneyTransferArgs : EventArgs
339 { 367 {
@@ -2013,5 +2041,68 @@ namespace OpenSim.Region.Framework.Scenes
2013 } 2041 }
2014 } 2042 }
2015 } 2043 }
2044
2045 public void TriggerOnSceneObjectLoaded(SceneObjectGroup so)
2046 {
2047 SceneObjectDelegate handler = OnSceneObjectLoaded;
2048 if (handler != null)
2049 {
2050 foreach (SceneObjectDelegate d in handler.GetInvocationList())
2051 {
2052 try
2053 {
2054 d(so);
2055 }
2056 catch (Exception e)
2057 {
2058 m_log.ErrorFormat(
2059 "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectLoaded failed - continuing. {0} {1}",
2060 e.Message, e.StackTrace);
2061 }
2062 }
2063 }
2064 }
2065
2066 public void TriggerOnSceneObjectPreSave(SceneObjectGroup persistingSo, SceneObjectGroup originalSo)
2067 {
2068 SceneObjectPreSaveDelegate handler = OnSceneObjectPreSave;
2069 if (handler != null)
2070 {
2071 foreach (SceneObjectPreSaveDelegate d in handler.GetInvocationList())
2072 {
2073 try
2074 {
2075 d(persistingSo, originalSo);
2076 }
2077 catch (Exception e)
2078 {
2079 m_log.ErrorFormat(
2080 "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPreSave failed - continuing. {0} {1}",
2081 e.Message, e.StackTrace);
2082 }
2083 }
2084 }
2085 }
2086
2087 public void TriggerOnSceneObjectPartCopy(SceneObjectPart copy, SceneObjectPart original, bool userExposed)
2088 {
2089 SceneObjectPartCopyDelegate handler = OnSceneObjectPartCopy;
2090 if (handler != null)
2091 {
2092 foreach (SceneObjectPartCopyDelegate d in handler.GetInvocationList())
2093 {
2094 try
2095 {
2096 d(copy, original, userExposed);
2097 }
2098 catch (Exception e)
2099 {
2100 m_log.ErrorFormat(
2101 "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPartCopy failed - continuing. {0} {1}",
2102 e.Message, e.StackTrace);
2103 }
2104 }
2105 }
2106 }
2016 } 2107 }
2017} 2108} \ 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 93f684c..dcd7f3d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1887,9 +1887,11 @@ namespace OpenSim.Region.Framework.Scenes
1887 1887
1888 foreach (SceneObjectGroup group in PrimsFromDB) 1888 foreach (SceneObjectGroup group in PrimsFromDB)
1889 { 1889 {
1890 EventManager.TriggerOnSceneObjectLoaded(group);
1891
1890 if (group.RootPart == null) 1892 if (group.RootPart == null)
1891 { 1893 {
1892 m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children", 1894 m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
1893 group.Children == null ? 0 : group.Children.Count); 1895 group.Children == null ? 0 : group.Children.Count);
1894 } 1896 }
1895 1897
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 17275d0..e26e4ae 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1479,6 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes
1479 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; 1479 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
1480 HasGroupChanged = false; 1480 HasGroupChanged = false;
1481 1481
1482 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
1482 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); 1483 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
1483 1484
1484 backup_group.ForEachPart(delegate(SceneObjectPart part) 1485 backup_group.ForEachPart(delegate(SceneObjectPart part)
@@ -1527,6 +1528,7 @@ namespace OpenSim.Region.Framework.Scenes
1527 /// <summary> 1528 /// <summary>
1528 /// Duplicates this object, including operations such as physics set up and attaching to the backup event. 1529 /// Duplicates this object, including operations such as physics set up and attaching to the backup event.
1529 /// </summary> 1530 /// </summary>
1531 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
1530 /// <returns></returns> 1532 /// <returns></returns>
1531 public SceneObjectGroup Copy(bool userExposed) 1533 public SceneObjectGroup Copy(bool userExposed)
1532 { 1534 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 69f9627..3dac0ad 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
@@ -321,6 +322,11 @@ namespace OpenSim.Region.Framework.Scenes
321 protected Vector3 m_lastAcceleration; 322 protected Vector3 m_lastAcceleration;
322 protected Vector3 m_lastAngularVelocity; 323 protected Vector3 m_lastAngularVelocity;
323 protected int m_lastTerseSent; 324 protected int m_lastTerseSent;
325
326 /// <summary>
327 /// Stores media texture data
328 /// </summary>
329 protected string m_mediaUrl;
324 330
325 // TODO: Those have to be changed into persistent properties at some later point, 331 // TODO: Those have to be changed into persistent properties at some later point,
326 // or sit-camera on vehicles will break on sim-crossing. 332 // or sit-camera on vehicles will break on sim-crossing.
@@ -965,18 +971,39 @@ namespace OpenSim.Region.Framework.Scenes
965 TriggerScriptChangedEvent(Changed.SCALE); 971 TriggerScriptChangedEvent(Changed.SCALE);
966 } 972 }
967 } 973 }
974
968 public byte UpdateFlag 975 public byte UpdateFlag
969 { 976 {
970 get { return m_updateFlag; } 977 get { return m_updateFlag; }
971 set { m_updateFlag = value; } 978 set { m_updateFlag = value; }
972 } 979 }
980
981 /// <summary>
982 /// Used for media on a prim.
983 /// </summary>
984 /// Do not change this value directly - always do it through an IMoapModule.
985 public string MediaUrl
986 {
987 get
988 {
989 return m_mediaUrl;
990 }
991
992 set
993 {
994 m_mediaUrl = value;
995
996 if (ParentGroup != null)
997 ParentGroup.HasGroupChanged = true;
998 }
999 }
973 1000
974 [XmlIgnore] 1001 [XmlIgnore]
975 public bool CreateSelected 1002 public bool CreateSelected
976 { 1003 {
977 get { return m_createSelected; } 1004 get { return m_createSelected; }
978 set { m_createSelected = value; } 1005 set { m_createSelected = value; }
979 } 1006 }
980 1007
981 #endregion 1008 #endregion
982 1009
@@ -1527,6 +1554,11 @@ namespace OpenSim.Region.Framework.Scenes
1527 /// <summary> 1554 /// <summary>
1528 /// Duplicates this part. 1555 /// Duplicates this part.
1529 /// </summary> 1556 /// </summary>
1557 /// <param name="localID"></param>
1558 /// <param name="AgentID"></param>
1559 /// <param name="GroupID"></param>
1560 /// <param name="linkNum"></param>
1561 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
1530 /// <returns></returns> 1562 /// <returns></returns>
1531 public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) 1563 public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed)
1532 { 1564 {
@@ -1590,7 +1622,11 @@ namespace OpenSim.Region.Framework.Scenes
1590 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1622 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1591 } 1623 }
1592 1624
1593 return dupe; 1625 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1626
1627// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
1628
1629 return dupe;
1594 } 1630 }
1595 1631
1596 protected void AssetReceived(string id, Object sender, AssetBase asset) 1632 protected void AssetReceived(string id, Object sender, AssetBase asset)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index f26fc2e..139b4f1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7842,6 +7842,241 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 return res; 7842 return res;
7843 } 7843 }
7844 7844
7845 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
7846 {
7847 m_host.AddScriptLPS(1);
7848 ScriptSleep(1000);
7849
7850 // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
7851 // TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
7852 // Assuming silently fail means give back an empty list. Ideally, need to check this.
7853 if (face < 0 || face > m_host.GetNumberOfSides() - 1)
7854 return new LSL_List();
7855
7856 return GetPrimMediaParams(face, rules);
7857 }
7858
7859 private LSL_List GetPrimMediaParams(int face, LSL_List rules)
7860 {
7861 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
7862 if (null == module)
7863 throw new Exception("Media on a prim functions not available");
7864
7865 MediaEntry me = module.GetMediaEntry(m_host, face);
7866
7867 // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
7868 if (null == me)
7869 return new LSL_List();
7870
7871 LSL_List res = new LSL_List();
7872
7873 for (int i = 0; i < rules.Length; i++)
7874 {
7875 int code = (int)rules.GetLSLIntegerItem(i);
7876
7877 switch (code)
7878 {
7879 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
7880 // Not implemented
7881 res.Add(new LSL_Integer(0));
7882 break;
7883
7884 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
7885 if (me.Controls == MediaControls.Standard)
7886 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD));
7887 else
7888 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI));
7889 break;
7890
7891 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
7892 res.Add(new LSL_String(me.CurrentURL));
7893 break;
7894
7895 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
7896 res.Add(new LSL_String(me.HomeURL));
7897 break;
7898
7899 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
7900 res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
7901 break;
7902
7903 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
7904 res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
7905 break;
7906
7907 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
7908 res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
7909 break;
7910
7911 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
7912 res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
7913 break;
7914
7915 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
7916 res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
7917 break;
7918
7919 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
7920 res.Add(new LSL_Integer(me.Width));
7921 break;
7922
7923 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
7924 res.Add(new LSL_Integer(me.Height));
7925 break;
7926
7927 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
7928 res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
7929 break;
7930
7931 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
7932 string[] urls = (string[])me.WhiteList.Clone();
7933
7934 for (int j = 0; j < urls.Length; j++)
7935 urls[j] = Uri.EscapeDataString(urls[j]);
7936
7937 res.Add(new LSL_String(string.Join(", ", urls)));
7938 break;
7939
7940 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
7941 res.Add(new LSL_Integer((int)me.InteractPermissions));
7942 break;
7943
7944 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
7945 res.Add(new LSL_Integer((int)me.ControlPermissions));
7946 break;
7947 }
7948 }
7949
7950 return res;
7951 }
7952
7953 public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
7954 {
7955 m_host.AddScriptLPS(1);
7956 ScriptSleep(1000);
7957
7958 // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
7959 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
7960 // Don't perform the media check directly
7961 if (face < 0 || face > m_host.GetNumberOfSides() - 1)
7962 return ScriptBaseClass.LSL_STATUS_OK;
7963
7964 return SetPrimMediaParams(face, rules);
7965 }
7966
7967 private LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
7968 {
7969 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
7970 if (null == module)
7971 throw new Exception("Media on a prim functions not available");
7972
7973 MediaEntry me = module.GetMediaEntry(m_host, face);
7974 if (null == me)
7975 me = new MediaEntry();
7976
7977 int i = 0;
7978
7979 while (i < rules.Length - 1)
7980 {
7981 int code = rules.GetLSLIntegerItem(i++);
7982
7983 switch (code)
7984 {
7985 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
7986 me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
7987 break;
7988
7989 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
7990 int v = rules.GetLSLIntegerItem(i++);
7991 if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
7992 me.Controls = MediaControls.Standard;
7993 else
7994 me.Controls = MediaControls.Mini;
7995 break;
7996
7997 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
7998 me.CurrentURL = rules.GetLSLStringItem(i++);
7999 break;
8000
8001 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
8002 me.HomeURL = rules.GetLSLStringItem(i++);
8003 break;
8004
8005 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
8006 me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8007 break;
8008
8009 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
8010 me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8011 break;
8012
8013 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
8014 me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8015 break;
8016
8017 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
8018 me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8019 break;
8020
8021 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
8022 me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8023 break;
8024
8025 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
8026 me.Width = (int)rules.GetLSLIntegerItem(i++);
8027 break;
8028
8029 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
8030 me.Height = (int)rules.GetLSLIntegerItem(i++);
8031 break;
8032
8033 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
8034 me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8035 break;
8036
8037 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
8038 string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
8039 List<string> whiteListUrls = new List<string>();
8040 Array.ForEach(
8041 rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
8042 me.WhiteList = whiteListUrls.ToArray();
8043 break;
8044
8045 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
8046 me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
8047 break;
8048
8049 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
8050 me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
8051 break;
8052 }
8053 }
8054
8055 module.SetMediaEntry(m_host, face, me);
8056
8057 return ScriptBaseClass.LSL_STATUS_OK;
8058 }
8059
8060 public LSL_Integer llClearPrimMedia(LSL_Integer face)
8061 {
8062 m_host.AddScriptLPS(1);
8063 ScriptSleep(1000);
8064
8065 // LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid
8066 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
8067 // FIXME: Don't perform the media check directly
8068 if (face < 0 || face > m_host.GetNumberOfSides() - 1)
8069 return ScriptBaseClass.LSL_STATUS_OK;
8070
8071 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8072 if (null == module)
8073 throw new Exception("Media on a prim functions not available");
8074
8075 module.ClearMediaEntry(m_host, face);
8076
8077 return ScriptBaseClass.LSL_STATUS_OK;
8078 }
8079
7845 // <remarks> 8080 // <remarks>
7846 // <para> 8081 // <para>
7847 // The .NET definition of base 64 is: 8082 // The .NET definition of base 64 is:
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 3339995..451163f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -1832,5 +1832,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1832 { 1832 {
1833 return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2); 1833 return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2);
1834 } 1834 }
1835
1836 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
1837 {
1838 return m_LSL_Functions.llGetPrimMediaParams(face, rules);
1839 }
1840
1841 public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
1842 {
1843 return m_LSL_Functions.llSetPrimMediaParams(face, rules);
1844 }
1845
1846 public LSL_Integer llClearPrimMedia(LSL_Integer face)
1847 {
1848 return m_LSL_Functions.llClearPrimMedia(face);
1849 }
1835 } 1850 }
1836} 1851}