public DateTime llParcelMediaCommandList(LSL_List commandList)
{
if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return DateTime.Now;
// according to the docs, this command only works if script owner and land owner are the same
// lets add estate owners and gods, too, and use the generic permission check.
IParcelManagementModule parcelManagement = World.RequestModuleInterface<IParcelManagementModule>();
if (parcelManagement != null)
{
ILandObject landObject = parcelManagement.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
if (landObject == null)
return DateTime.Now;
if (!World.Permissions.CanEditParcel(m_host.OwnerID, landObject))
return DateTime.Now;
bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
byte loop = 0;
LandData landData = landObject.LandData;
string url = landData.MediaURL;
string texture = landData.MediaID.ToString();
bool autoAlign = landData.MediaAutoScale != 0;
string mediaType = landData.MediaType;
string description = landData.MediaDescription;
int width = landData.MediaWidth;
int height = landData.MediaHeight;
float mediaLoopSet = landData.MediaLoopSet;
ParcelMediaCommandEnum? commandToSend = null;
float time = 0.0f; // default is from start
IScenePresence presence = null;
for (int i = 0; i < commandList.Data.Length; i++)
{
int tmp = ((LSL_Integer)commandList.Data[i]).value;
ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)tmp;
switch (command)
{
case ParcelMediaCommandEnum.Agent:
// we send only to one agent
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_String)
{
UUID agentID;
if (UUID.TryParse((LSL_String)commandList.Data[i + 1], out agentID))
{
presence = World.GetScenePresence(agentID);
}
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key");
++i;
}
break;
case ParcelMediaCommandEnum.Loop:
loop = 1;
commandToSend = command;
update = true; //need to send the media update packet to set looping
break;
case ParcelMediaCommandEnum.LoopSet:
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_Float)
{
mediaLoopSet = (float)((LSL_Float)commandList.Data[i + 1]).value;
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_LOOP_SET must be a float");
++i;
}
commandToSend = command;
break;
case ParcelMediaCommandEnum.Play:
loop = 0;
commandToSend = command;
update = true; //need to send the media update packet to make sure it doesn't loop
break;
case ParcelMediaCommandEnum.Pause:
case ParcelMediaCommandEnum.Stop:
case ParcelMediaCommandEnum.Unload:
commandToSend = command;
break;
case ParcelMediaCommandEnum.Url:
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_String)
{
url = (LSL_String)commandList.Data[i + 1];
update = true;
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_URL must be a string.");
++i;
}
break;
case ParcelMediaCommandEnum.Texture:
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_String)
{
texture = (LSL_String)commandList.Data[i + 1];
update = true;
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or key.");
++i;
}
break;
case ParcelMediaCommandEnum.Time:
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_Float)
{
time = (float)(LSL_Float)commandList.Data[i + 1];
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TIME must be a float.");
++i;
}
commandToSend = command;
break;
case ParcelMediaCommandEnum.AutoAlign:
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_Integer)
{
autoAlign = (LSL_Integer)commandList.Data[i + 1];
update = true;
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer.");
++i;
}
break;
case ParcelMediaCommandEnum.Type:
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_String)
{
mediaType = (LSL_String)commandList.Data[i + 1];
update = true;
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string.");
++i;
}
break;
case ParcelMediaCommandEnum.Desc:
if ((i + 1) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_String)
{
description = (LSL_String)commandList.Data[i + 1];
update = true;
}
else ShoutError("The argument of PARCEL_MEDIA_COMMAND_DESC must be a string.");
++i;
}
break;
case ParcelMediaCommandEnum.Size:
if ((i + 2) < commandList.Length)
{
if (commandList.Data[i + 1] is LSL_Integer)
{
if (commandList.Data[i + 2] is LSL_Integer)
{
width = (LSL_Integer)commandList.Data[i + 1];
height = (LSL_Integer)commandList.Data[i + 2];
update = true;
}
else ShoutError("The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer.");
}
else ShoutError("The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer.");
i += 2;
}
break;
default:
NotImplemented("llParcelMediaCommandList parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()));
break;
}//end switch
}//end for
// if we didn't get a presence, we send to all and change the url
// if we did get a presence, we only send to the agent specified, and *don't change the land settings*!
// did something important change or do we only start/stop/pause?
if (update)
{
if (presence == null)
{
// we send to all
landData.MediaID = new UUID(texture);
landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0;
landData.MediaWidth = width;
landData.MediaHeight = height;
landData.MediaType = mediaType;
landData.MediaDescription = description;
landData.MediaLoop = loop == 1;
landData.MediaLoopSet = mediaLoopSet;
// do that one last, it will cause a ParcelPropertiesUpdate
landObject.SetMediaUrl(url);
// now send to all (non-child) agents
World.ForEachScenePresence(delegate(IScenePresence sp)
{
if (!sp.IsChildAgent && (sp.CurrentParcelUUID == landData.GlobalID))
{
sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL,
landData.MediaID,
landData.MediaAutoScale,
mediaType,
description,
width, height,
loop);
}
});
}
else if (!presence.IsChildAgent)
{
// we only send to one (root) agent
presence.ControllingClient.SendParcelMediaUpdate(url,
new UUID(texture),
autoAlign ? (byte)1 : (byte)0,
mediaType,
description,
width, height,
loop);
}
}
if (commandToSend != null)
{
float ParamToSend = time;
if ((ParcelMediaCommandEnum)commandToSend == ParcelMediaCommandEnum.LoopSet)
ParamToSend = mediaLoopSet;
// the commandList contained a start/stop/... command, too
if (presence == null)
{
// send to all (non-child) agents
World.ForEachScenePresence(delegate(IScenePresence sp)
{
if (!sp.IsChildAgent)
{
sp.ControllingClient.SendParcelMediaCommand(landData.Flags,
(ParcelMediaCommandEnum)commandToSend,
ParamToSend);
}
});
}
else if (!presence.IsChildAgent)
{
presence.ControllingClient.SendParcelMediaCommand(landData.Flags,
(ParcelMediaCommandEnum)commandToSend,
ParamToSend);
}
}
}
return PScriptSleep(2000);
}