/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.Messages.Linden;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Region.CoreModules.Media.Moap
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MoapModule")]
public class MoapModule : INonSharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public string Name { get { return "MoapModule"; } }
public Type ReplaceableInterface { get { return null; } }
protected Scene m_scene;
public void Initialise(IConfigSource config) {}
public void AddRegion(Scene scene)
{
m_scene = scene;
}
public void RemoveRegion(Scene scene) {}
public void RegionLoaded(Scene scene)
{
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
public void Close() {}
public void RegisterCaps(UUID agentID, Caps caps)
{
m_log.DebugFormat(
"[MOAP]: Registering ObjectMedia and ObjectMediaNavigate capabilities for agent {0}", agentID);
// We do receive a post to ObjectMedia when a new avatar enters the region - though admittedly this is the
// avatar that set the texture in the first place.
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
"ObjectMedia", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaRequest));
// We do get these posts when the url has been changed.
// Even though we're registering for POST we're going to get GETS and UPDATES too
caps.RegisterHandler(
"ObjectMediaNavigate", new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), HandleObjectMediaNavigateRequest));
}
///
/// Sets or gets per face media textures.
///
///
///
///
///
///
///
protected string HandleObjectMediaRequest(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMedia raw request [{0}]", request);
Hashtable osdParams = new Hashtable();
osdParams = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
foreach (Object key in osdParams.Keys)
m_log.DebugFormat("[MOAP]: Param {0}={1}", key, osdParams[key]);
string verb = (string)osdParams["verb"];
if ("GET" == verb)
return HandleObjectMediaRequestGet(path, osdParams, httpRequest, httpResponse);
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
// TODO: Persist in memory
// TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
// TODO: Persist in database
return string.Empty;
}
protected string HandleObjectMediaRequestGet(
string path, Hashtable osdParams, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
UUID primId = (UUID)osdParams["object_id"];
SceneObjectPart part = m_scene.GetSceneObjectPart(primId);
if (null == part)
{
m_log.WarnFormat(
"[MOAP]: Received a GET ObjectMediaRequest for prim {0} but this doesn't exist in the scene",
primId);
return string.Empty;
}
int faces = part.GetNumberOfSides();
m_log.DebugFormat("[MOAP]: Faces [{0}] for [{1}]", faces, primId);
MediaEntry[] media = new MediaEntry[faces];
for (int i = 0; i < faces; i++)
{
MediaEntry me = new MediaEntry();
me.HomeURL = "google.com";
me.CurrentURL = "google.com";
me.AutoScale = true;
//me.Height = 300;
//me.Width = 240;
media[i] = me;
}
ObjectMediaResponse resp = new ObjectMediaResponse();
resp.PrimID = (UUID)osdParams["object_id"];
resp.FaceMedia = media;
// I know this has to end with the last avatar to edit and the version code shouldn't always be 16. Just trying
// to minimally satisfy for now to get something working
resp.Version = "x-mv:0000000016/" + UUID.Random();
//string rawResp = resp.Serialize().ToString();
string rawResp = OSDParser.SerializeLLSDXmlString(resp.Serialize());
m_log.DebugFormat("[MOAP]: Got HandleObjectMediaRequestGet raw response is [{0}]", rawResp);
return rawResp;
}
///
/// Received from the viewer if a user has changed the url of a media texture.
///
///
///
///
/// /param>
/// /param>
///
protected string HandleObjectMediaNavigateRequest(
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MOAP]: Got ObjectMediaNavigate request for {0}", path);
//NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
// TODO: Persist in memory
// TODO: Tell other agents in the region about the change via the ObjectMediaResponse (?) message
// TODO: Persist in database
return string.Empty;
}
}
}