diff options
Diffstat (limited to 'OpenSim')
3 files changed, 185 insertions, 56 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 6ec9f7f..4714bb3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -6745,7 +6745,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6745 | updatePacket.DataBlockExtended.MediaType = Utils.StringToBytes(mediaType); | 6745 | updatePacket.DataBlockExtended.MediaType = Utils.StringToBytes(mediaType); |
6746 | updatePacket.DataBlockExtended.MediaDesc = Utils.StringToBytes(mediaDesc); | 6746 | updatePacket.DataBlockExtended.MediaDesc = Utils.StringToBytes(mediaDesc); |
6747 | updatePacket.DataBlockExtended.MediaWidth = mediaWidth; | 6747 | updatePacket.DataBlockExtended.MediaWidth = mediaWidth; |
6748 | updatePacket.DataBlockExtended.MediaWidth = mediaHeight; | 6748 | updatePacket.DataBlockExtended.MediaHeight = mediaHeight; |
6749 | updatePacket.DataBlockExtended.MediaLoop = mediaLoop; | 6749 | updatePacket.DataBlockExtended.MediaLoop = mediaLoop; |
6750 | 6750 | ||
6751 | OutPacket(updatePacket, ThrottleOutPacketType.Unknown); | 6751 | OutPacket(updatePacket, ThrottleOutPacketType.Unknown); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a2c82cf..165e213 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -7184,98 +7184,224 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7184 | 7184 | ||
7185 | public void llParcelMediaCommandList(LSL_List commandList) | 7185 | public void llParcelMediaCommandList(LSL_List commandList) |
7186 | { | 7186 | { |
7187 | //TO DO: Implement the missing commands | 7187 | // TODO: Not implemented yet (missing in libomv?): |
7188 | //PARCEL_MEDIA_COMMAND_STOP Stop the media stream and go back to the first frame. | 7188 | // PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) |
7189 | //PARCEL_MEDIA_COMMAND_PAUSE Pause the media stream (stop playing but stay on current frame). | 7189 | |
7190 | //PARCEL_MEDIA_COMMAND_PLAY Start the media stream playing from the current frame and stop when the end is reached. | ||
7191 | //PARCEL_MEDIA_COMMAND_LOOP Start the media stream playing from the current frame. When the end is reached, loop to the beginning and continue. | ||
7192 | //PARCEL_MEDIA_COMMAND_TEXTURE key uuid Use this to get or set the parcel's media texture. | ||
7193 | //PARCEL_MEDIA_COMMAND_URL string url Used to get or set the parcel's media url. | ||
7194 | //PARCEL_MEDIA_COMMAND_TIME float time Move a media stream to a specific time. | ||
7195 | //PARCEL_MEDIA_COMMAND_AGENT key uuid Applies the media command to the specified agent only. | ||
7196 | //PARCEL_MEDIA_COMMAND_UNLOAD Completely unloads the movie and restores the original texture. | ||
7197 | //PARCEL_MEDIA_COMMAND_AUTO_ALIGN integer boolean Sets the parcel option 'Auto scale content'. | ||
7198 | //PARCEL_MEDIA_COMMAND_TYPE string mime_type Use this to get or set the parcel media MIME type (e.g. "text/html"). (1.19.1 RC0 or later) | ||
7199 | //PARCEL_MEDIA_COMMAND_SIZE integer x, integer y Use this to get or set the parcel media pixel resolution. (1.19.1 RC0 or later) | ||
7200 | //PARCEL_MEDIA_COMMAND_DESC string desc Use this to get or set the parcel media description. (1.19.1 RC0 or later) | ||
7201 | //PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) | ||
7202 | m_host.AddScriptLPS(1); | 7190 | m_host.AddScriptLPS(1); |
7191 | |||
7192 | // according to the docs, this command only works if script owner and land owner are the same | ||
7193 | UUID landowner = World.GetLandOwner(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | ||
7194 | if (landowner == UUID.Zero || landowner != m_host.ObjectOwner) return; | ||
7195 | |||
7196 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? | ||
7197 | |||
7198 | LandData landData = World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | ||
7199 | string url = landData.MediaURL; | ||
7200 | string texture = landData.MediaID.ToString(); | ||
7201 | bool autoAlign = landData.MediaAutoScale != 0; | ||
7202 | string mediaType = ""; // TODO these have to be added as soon as LandData supports it | ||
7203 | string description = ""; | ||
7204 | int width = 0; | ||
7205 | int height = 0; | ||
7206 | |||
7207 | ParcelMediaCommandEnum? commandToSend = null; | ||
7208 | float time = 0.0f; // default is from start | ||
7209 | |||
7210 | ScenePresence presence = null; | ||
7211 | |||
7203 | for (int i = 0; i < commandList.Data.Length; i++) | 7212 | for (int i = 0; i < commandList.Data.Length; i++) |
7204 | { | 7213 | { |
7205 | switch ((ParcelMediaCommandEnum)commandList.Data[i]) | 7214 | ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; |
7215 | switch (command) | ||
7206 | { | 7216 | { |
7207 | case ParcelMediaCommandEnum.Play: | 7217 | case ParcelMediaCommandEnum.Agent: |
7208 | List<ScenePresence> scenePresencePlayList = World.GetScenePresences(); | 7218 | // we send only to one agent |
7209 | foreach (ScenePresence agent in scenePresencePlayList) | 7219 | if ((i + 1) < commandList.Length) |
7210 | { | 7220 | { |
7211 | if (!agent.IsChildAgent) | 7221 | if (commandList.Data[i + 1] is LSL_String) |
7212 | { | 7222 | { |
7213 | agent.ControllingClient.SendParcelMediaCommand((uint)(4), ParcelMediaCommandEnum.Play, 0); | 7223 | UUID agentID; |
7224 | if (UUID.TryParse((LSL_String)commandList.Data[i + 1], out agentID)) | ||
7225 | { | ||
7226 | presence = World.GetScenePresence(agentID); | ||
7227 | } | ||
7214 | } | 7228 | } |
7229 | else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key"); | ||
7230 | ++i; | ||
7215 | } | 7231 | } |
7216 | break; | 7232 | break; |
7233 | |||
7234 | case ParcelMediaCommandEnum.Loop: | ||
7235 | case ParcelMediaCommandEnum.Play: | ||
7236 | case ParcelMediaCommandEnum.Pause: | ||
7217 | case ParcelMediaCommandEnum.Stop: | 7237 | case ParcelMediaCommandEnum.Stop: |
7218 | List<ScenePresence> scenePresenceStopList = World.GetScenePresences(); | 7238 | case ParcelMediaCommandEnum.Unload: |
7219 | foreach (ScenePresence agent in scenePresenceStopList) | 7239 | commandToSend = command; |
7240 | break; | ||
7241 | |||
7242 | case ParcelMediaCommandEnum.Url: | ||
7243 | if ((i + 1) < commandList.Length) | ||
7220 | { | 7244 | { |
7221 | if (!agent.IsChildAgent) | 7245 | if (commandList.Data[i + 1] is LSL_String) |
7222 | { | 7246 | { |
7223 | agent.ControllingClient.SendParcelMediaCommand((uint)(4), ParcelMediaCommandEnum.Stop, 0); | 7247 | url = (LSL_String)commandList.Data[i + 1]; |
7248 | update = true; | ||
7224 | } | 7249 | } |
7250 | else ShoutError("The argument of PARCEL_MEDIA_COMMAND_URL must be a string."); | ||
7251 | ++i; | ||
7225 | } | 7252 | } |
7226 | break; | 7253 | break; |
7227 | case ParcelMediaCommandEnum.Pause: | 7254 | |
7228 | List<ScenePresence> scenePresencePauseList = World.GetScenePresences(); | 7255 | case ParcelMediaCommandEnum.Texture: |
7229 | foreach (ScenePresence agent in scenePresencePauseList) | 7256 | if ((i + 1) < commandList.Length) |
7230 | { | 7257 | { |
7231 | if (!agent.IsChildAgent) | 7258 | if (commandList.Data[i + 1] is LSL_String) |
7232 | { | 7259 | { |
7233 | agent.ControllingClient.SendParcelMediaCommand((uint)(4), ParcelMediaCommandEnum.Pause, 0); | 7260 | texture = (LSL_String)commandList.Data[i + 1]; |
7261 | update = true; | ||
7234 | } | 7262 | } |
7263 | else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or key."); | ||
7264 | ++i; | ||
7235 | } | 7265 | } |
7236 | break; | 7266 | break; |
7237 | 7267 | ||
7238 | case ParcelMediaCommandEnum.Url: | 7268 | case ParcelMediaCommandEnum.Time: |
7239 | if ((i + 1) < commandList.Length) | 7269 | if ((i + 1) < commandList.Length) |
7240 | { | 7270 | { |
7241 | if (commandList.Data[i + 1] is string) | 7271 | if (commandList.Data[i + 1] is LSL_Float) |
7242 | { | 7272 | { |
7243 | UUID landowner = World.GetLandOwner(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 7273 | time = (float)(LSL_Float)commandList.Data[i + 1]; |
7274 | } | ||
7275 | else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TIME must be a float."); | ||
7276 | ++i; | ||
7277 | } | ||
7278 | break; | ||
7244 | 7279 | ||
7245 | if (landowner == UUID.Zero) | 7280 | case ParcelMediaCommandEnum.AutoAlign: |
7246 | { | 7281 | if ((i + 1) < commandList.Length) |
7247 | return; | 7282 | { |
7248 | } | 7283 | if (commandList.Data[i + 1] is LSL_Integer) |
7284 | { | ||
7285 | autoAlign = (LSL_Integer)commandList.Data[i + 1]; | ||
7286 | update = true; | ||
7287 | } | ||
7249 | 7288 | ||
7250 | if (landowner != m_host.ObjectOwner) | 7289 | else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer."); |
7251 | { | 7290 | ++i; |
7252 | return; | 7291 | } |
7253 | } | 7292 | break; |
7293 | |||
7294 | case ParcelMediaCommandEnum.Type: | ||
7295 | if ((i + 1) < commandList.Length) | ||
7296 | { | ||
7297 | if (commandList.Data[i + 1] is LSL_String) | ||
7298 | { | ||
7299 | mediaType = (LSL_String)commandList.Data[i + 1]; | ||
7300 | update = true; | ||
7301 | } | ||
7302 | else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string."); | ||
7303 | ++i; | ||
7304 | } | ||
7305 | break; | ||
7254 | 7306 | ||
7255 | World.SetLandMediaURL(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y, (string)commandList.GetLSLStringItem(i + 1)); | 7307 | case ParcelMediaCommandEnum.Desc: |
7308 | if ((i + 1) < commandList.Length) | ||
7309 | { | ||
7310 | if (commandList.Data[i + 1] is LSL_String) | ||
7311 | { | ||
7312 | description = (LSL_String)commandList.Data[i + 1]; | ||
7313 | update = true; | ||
7314 | } | ||
7315 | else ShoutError("The argument of PARCEL_MEDIA_COMMAND_DESC must be a string."); | ||
7316 | ++i; | ||
7317 | } | ||
7318 | break; | ||
7256 | 7319 | ||
7257 | List<ScenePresence> scenePresenceList = World.GetScenePresences(); | 7320 | case ParcelMediaCommandEnum.Size: |
7258 | LandData landData = World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 7321 | if ((i + 2) < commandList.Length) |
7259 | //Send an update of the mediaURL to all the clients that are in the parcel | 7322 | { |
7260 | foreach (ScenePresence agent in scenePresenceList) | 7323 | if (commandList.Data[i + 1] is LSL_Integer) |
7324 | { | ||
7325 | if (commandList.Data[i + 2] is LSL_Integer) | ||
7261 | { | 7326 | { |
7262 | if (!agent.IsChildAgent) | 7327 | width = (LSL_Integer)commandList.Data[i + 1]; |
7263 | { | 7328 | height = (LSL_Integer)commandList.Data[i + 2]; |
7264 | //Send parcel media update to the client | 7329 | update = true; |
7265 | agent.ControllingClient.SendParcelMediaUpdate(landData.MediaURL, landData.MediaID, landData.MediaAutoScale, "", landData.Description, 0, 0, 1); | ||
7266 | } | ||
7267 | } | 7330 | } |
7268 | 7331 | else ShoutError("The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer."); | |
7269 | } | 7332 | } |
7270 | i++; | 7333 | else ShoutError("The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer."); |
7334 | i += 2; | ||
7271 | } | 7335 | } |
7272 | break; | 7336 | break; |
7337 | |||
7273 | default: | 7338 | default: |
7274 | ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; | 7339 | NotImplemented("llParcelMediaCommandList parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()).ToString()); |
7275 | NotImplemented("llParcelMediaCommandList parameter do not supported yet: " + Enum.Parse(mediaCommandEnum.GetType(), commandList.Data[i].ToString()).ToString()); | ||
7276 | break; | 7340 | break; |
7277 | }//end switch | 7341 | }//end switch |
7342 | }//end for | ||
7343 | |||
7344 | // if we didn't get a presence, we send to all and change the url | ||
7345 | // if we did get a presence, we only send to the agent specified, and *don't change the land settings*! | ||
7346 | |||
7347 | // did something important change or do we only start/stop/pause? | ||
7348 | if (update) | ||
7349 | { | ||
7350 | if (presence == null) | ||
7351 | { | ||
7352 | // we send to all | ||
7353 | |||
7354 | landData.MediaID = new UUID(texture); | ||
7355 | landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0; | ||
7356 | // do that one last, it will cause a ParcelPropertiesUpdate | ||
7357 | World.SetLandMediaURL(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y, url); | ||
7358 | |||
7359 | // now send to all (non-child) agents | ||
7360 | List<ScenePresence> agents = World.GetAvatars(); | ||
7361 | foreach(ScenePresence agent in agents) | ||
7362 | { | ||
7363 | agent.ControllingClient.SendParcelMediaUpdate(landData.MediaURL, | ||
7364 | landData.MediaID, | ||
7365 | landData.MediaAutoScale, | ||
7366 | mediaType, | ||
7367 | description, | ||
7368 | width, height, | ||
7369 | 1); // TODO do some LOOP logic here | ||
7370 | } | ||
7371 | } | ||
7372 | else if(!presence.IsChildAgent) | ||
7373 | { | ||
7374 | // we only send to one (root) agent | ||
7375 | presence.ControllingClient.SendParcelMediaUpdate(url, | ||
7376 | new UUID(texture), | ||
7377 | autoAlign ? (byte)1 : (byte)0, | ||
7378 | mediaType, | ||
7379 | description, | ||
7380 | width, height, | ||
7381 | 1); // TODO do some LOOP logic here | ||
7382 | } | ||
7383 | } | ||
7278 | 7384 | ||
7385 | if (commandToSend != null) | ||
7386 | { | ||
7387 | // the commandList contained a start/stop/... command, too | ||
7388 | if (presence == null) | ||
7389 | { | ||
7390 | // send to all (non-child) agents | ||
7391 | List<ScenePresence> agents = World.GetAvatars(); | ||
7392 | foreach(ScenePresence agent in agents) | ||
7393 | { | ||
7394 | agent.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? | ||
7395 | (ParcelMediaCommandEnum)commandToSend, | ||
7396 | time); | ||
7397 | } | ||
7398 | } | ||
7399 | else if(!presence.IsChildAgent) | ||
7400 | { | ||
7401 | presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? | ||
7402 | (ParcelMediaCommandEnum)commandToSend, | ||
7403 | time); | ||
7404 | } | ||
7279 | } | 7405 | } |
7280 | // ScriptSleep(2000); | 7406 | // ScriptSleep(2000); |
7281 | } | 7407 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 2c5c0b3..c3d3270 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | |||
@@ -372,6 +372,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
372 | public const int PARCEL_MEDIA_COMMAND_AGENT = 7; | 372 | public const int PARCEL_MEDIA_COMMAND_AGENT = 7; |
373 | public const int PARCEL_MEDIA_COMMAND_UNLOAD = 8; | 373 | public const int PARCEL_MEDIA_COMMAND_UNLOAD = 8; |
374 | public const int PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; | 374 | public const int PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; |
375 | public const int PARCEL_MEDIA_COMMAND_TYPE = 10; | ||
376 | public const int PARCEL_MEDIA_COMMAND_SIZE = 11; | ||
377 | public const int PARCEL_MEDIA_COMMAND_DESC = 12; | ||
375 | 378 | ||
376 | public const int PARCEL_FLAG_ALLOW_FLY = 0x1; // parcel allows flying | 379 | public const int PARCEL_FLAG_ALLOW_FLY = 0x1; // parcel allows flying |
377 | public const int PARCEL_FLAG_ALLOW_SCRIPTS = 0x2; // parcel allows outside scripts | 380 | public const int PARCEL_FLAG_ALLOW_SCRIPTS = 0x2; // parcel allows outside scripts |