mirror of
https://github.com/opensim/opensim.git
synced 2026-08-09 18:55:58 +08:00
Merge branch 'master' into careminster-presence-refactor
This commit is contained in:
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
* 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 Mono.Addins;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
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.Avatar.Assets
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class GetMeshModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
private IAssetService m_assetService;
|
||||
private bool m_enabled = true;
|
||||
|
||||
#region IRegionModuleBase Members
|
||||
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig meshConfig = source.Configs["Mesh"];
|
||||
if (meshConfig == null)
|
||||
return;
|
||||
|
||||
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene pScene)
|
||||
{
|
||||
m_scene = pScene;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene = null;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
|
||||
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "GetMeshModule"; } }
|
||||
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
if(!m_enabled)
|
||||
return;
|
||||
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
// m_log.Info("[GETMESH]: /CAPS/" + capID);
|
||||
|
||||
caps.RegisterHandler("GetMesh",
|
||||
new RestHTTPHandler("GET", "/CAPS/" + capID,
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return ProcessGetMesh(m_dhttpMethod, agentID, caps);
|
||||
}));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
||||
{
|
||||
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 400; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Request wasn't what was expected";
|
||||
|
||||
string meshStr = string.Empty;
|
||||
|
||||
if (request.ContainsKey("mesh_id"))
|
||||
meshStr = request["mesh_id"].ToString();
|
||||
|
||||
|
||||
UUID meshID = UUID.Zero;
|
||||
if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
|
||||
{
|
||||
if (m_assetService == null)
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
AssetBase mesh;
|
||||
// Only try to fetch locally cached textures. Misses are redirected
|
||||
mesh = m_assetService.GetCached(meshID.ToString());
|
||||
if (mesh != null)
|
||||
{
|
||||
if (mesh.Type == (SByte)AssetType.Mesh)
|
||||
{
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||
responsedata["int_response_code"] = 200;
|
||||
}
|
||||
// Optionally add additional mesh types here
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh = m_assetService.Get(meshID.ToString());
|
||||
if (mesh != null)
|
||||
{
|
||||
if (mesh.Type == (SByte)AssetType.Mesh)
|
||||
{
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||
responsedata["int_response_code"] = 200;
|
||||
}
|
||||
// Optionally add additional mesh types here
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Imaging;
|
||||
using OpenSim.Framework;
|
||||
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.Avatar.ObjectCaps
|
||||
{
|
||||
#region Stream Handler
|
||||
|
||||
public delegate byte[] StreamHandlerCallback(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse);
|
||||
|
||||
public class StreamHandler : BaseStreamHandler
|
||||
{
|
||||
StreamHandlerCallback m_callback;
|
||||
|
||||
public StreamHandler(string httpMethod, string path, StreamHandlerCallback callback)
|
||||
: base(httpMethod, path)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||
{
|
||||
return m_callback(path, request, httpRequest, httpResponse);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Stream Handler
|
||||
|
||||
public class GetTextureModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene;
|
||||
private IAssetService m_assetService;
|
||||
|
||||
public const string DefaultFormat = "x-j2c";
|
||||
|
||||
// TODO: Change this to a config option
|
||||
const string REDIRECT_URL = null;
|
||||
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene pScene, IConfigSource pSource)
|
||||
{
|
||||
m_scene = pScene;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "GetTextureModule"; } }
|
||||
public bool IsSharedModule { get { return false; } }
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
// m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private byte[] ProcessGetTexture(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||
{
|
||||
//m_log.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName);
|
||||
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string textureStr = query.GetOne("texture_id");
|
||||
string format = query.GetOne("format");
|
||||
|
||||
if (m_assetService == null)
|
||||
{
|
||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return null;
|
||||
}
|
||||
|
||||
UUID textureID;
|
||||
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
|
||||
{
|
||||
string[] formats;
|
||||
if (format != null && format != string.Empty)
|
||||
{
|
||||
formats = new string[1] { format.ToLower() };
|
||||
}
|
||||
else
|
||||
{
|
||||
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
|
||||
if (formats.Length == 0)
|
||||
formats = new string[1] { DefaultFormat }; // default
|
||||
|
||||
}
|
||||
// OK, we have an array with preferred formats, possibly with only one entry
|
||||
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
foreach (string f in formats)
|
||||
{
|
||||
if (FetchTexture(httpRequest, httpResponse, textureID, f))
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
||||
}
|
||||
|
||||
httpResponse.Send();
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="httpRequest"></param>
|
||||
/// <param name="httpResponse"></param>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="format"></param>
|
||||
/// <returns>False for "caller try another codec"; true otherwise</returns>
|
||||
private bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format)
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
||||
AssetBase texture;
|
||||
|
||||
string fullID = textureID.ToString();
|
||||
if (format != DefaultFormat)
|
||||
fullID = fullID + "-" + format;
|
||||
|
||||
if (!String.IsNullOrEmpty(REDIRECT_URL))
|
||||
{
|
||||
// Only try to fetch locally cached textures. Misses are redirected
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
if (texture.Type != (sbyte)AssetType.Texture)
|
||||
{
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
string textureUrl = REDIRECT_URL + textureID.ToString();
|
||||
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
|
||||
httpResponse.RedirectLocation = textureUrl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else // no redirect
|
||||
{
|
||||
// try the cache
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
//m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
|
||||
|
||||
// Fetch locally or remotely. Misses return a 404
|
||||
texture = m_assetService.Get(textureID.ToString());
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
if (texture.Type != (sbyte)AssetType.Texture)
|
||||
{
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
if (format == DefaultFormat)
|
||||
{
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
|
||||
newTexture.Data = ConvertTextureData(texture, format);
|
||||
if (newTexture.Data.Length == 0)
|
||||
return false; // !!! Caller try another codec, please!
|
||||
|
||||
newTexture.Flags = AssetFlags.Collectable;
|
||||
newTexture.Temporary = true;
|
||||
m_assetService.Store(newTexture);
|
||||
WriteTextureData(httpRequest, httpResponse, newTexture, format);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // it was on the cache
|
||||
{
|
||||
//m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
|
||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
|
||||
{
|
||||
string range = request.Headers.GetOne("Range");
|
||||
//m_log.DebugFormat("[GETTEXTURE]: Range {0}", range);
|
||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
||||
{
|
||||
// Range request
|
||||
int start, end;
|
||||
if (TryParseRange(range, out start, out end))
|
||||
{
|
||||
// Before clamping start make sure we can satisfy it in order to avoid
|
||||
// sending back the last byte instead of an error status
|
||||
if (start >= texture.Data.Length)
|
||||
{
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
return;
|
||||
}
|
||||
|
||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
|
||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
|
||||
if (len < texture.Data.Length)
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
|
||||
response.ContentLength = len;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||
|
||||
response.Body.Write(texture.Data, start, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
|
||||
}
|
||||
}
|
||||
else // JP2's or other formats
|
||||
{
|
||||
// Full content request
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
response.ContentLength = texture.Data.Length;
|
||||
if (format == DefaultFormat)
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
else
|
||||
response.ContentType = "image/" + format;
|
||||
response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryParseRange(string header, out int start, out int end)
|
||||
{
|
||||
if (header.StartsWith("bytes="))
|
||||
{
|
||||
string[] rangeValues = header.Substring(6).Split('-');
|
||||
if (rangeValues.Length == 2)
|
||||
{
|
||||
if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
start = end = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private byte[] ConvertTextureData(AssetBase texture, string format)
|
||||
{
|
||||
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
||||
byte[] data = new byte[0];
|
||||
|
||||
MemoryStream imgstream = new MemoryStream();
|
||||
Bitmap mTexture = new Bitmap(1, 1);
|
||||
ManagedImage managedImage;
|
||||
Image image = (Image)mTexture;
|
||||
|
||||
try
|
||||
{
|
||||
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
|
||||
|
||||
imgstream = new MemoryStream();
|
||||
|
||||
// Decode image to System.Drawing.Image
|
||||
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image))
|
||||
{
|
||||
// Save to bitmap
|
||||
mTexture = new Bitmap(image);
|
||||
|
||||
EncoderParameters myEncoderParameters = new EncoderParameters();
|
||||
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
|
||||
|
||||
// Save bitmap to stream
|
||||
ImageCodecInfo codec = GetEncoderInfo("image/" + format);
|
||||
if (codec != null)
|
||||
{
|
||||
mTexture.Save(imgstream, codec, myEncoderParameters);
|
||||
// Write the stream to a byte array for output
|
||||
data = imgstream.ToArray();
|
||||
}
|
||||
else
|
||||
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Reclaim memory, these are unmanaged resources
|
||||
// If we encountered an exception, one or more of these will be null
|
||||
if (mTexture != null)
|
||||
mTexture.Dispose();
|
||||
|
||||
if (image != null)
|
||||
image.Dispose();
|
||||
|
||||
if (imgstream != null)
|
||||
{
|
||||
imgstream.Close();
|
||||
imgstream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// From msdn
|
||||
private static ImageCodecInfo GetEncoderInfo(String mimeType)
|
||||
{
|
||||
ImageCodecInfo[] encoders;
|
||||
encoders = ImageCodecInfo.GetImageEncoders();
|
||||
for (int j = 0; j < encoders.Length; ++j)
|
||||
{
|
||||
if (encoders[j].MimeType == mimeType)
|
||||
return encoders[j];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
* 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 Mono.Addins;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
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;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Assets
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
// private IAssetService m_assetService;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private bool m_enabled = true;
|
||||
|
||||
#region IRegionModuleBase Members
|
||||
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig meshConfig = source.Configs["Mesh"];
|
||||
if (meshConfig == null)
|
||||
return;
|
||||
|
||||
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene pScene)
|
||||
{
|
||||
m_scene = pScene;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene = null;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
|
||||
// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
|
||||
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
if(!m_enabled)
|
||||
return;
|
||||
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
|
||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
||||
|
||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
|
||||
"/CAPS/" + capID.ToString(),
|
||||
delegate(LLSDAssetUploadRequest req)
|
||||
{
|
||||
return NewAgentInventoryRequest(req,agentID);
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
|
||||
{
|
||||
|
||||
//TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
|
||||
// You need to be aware of this and
|
||||
|
||||
|
||||
//if (llsdRequest.asset_type == "texture" ||
|
||||
// llsdRequest.asset_type == "animation" ||
|
||||
// llsdRequest.asset_type == "sound")
|
||||
// {
|
||||
IClientAPI client = null;
|
||||
|
||||
|
||||
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
if (mm != null)
|
||||
{
|
||||
if (m_scene.TryGetClient(agentID, out client))
|
||||
{
|
||||
if (!mm.UploadCovered(client, mm.UploadCharge))
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
|
||||
string assetName = llsdRequest.name;
|
||||
string assetDes = llsdRequest.description;
|
||||
string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
|
||||
UUID newAsset = UUID.Random();
|
||||
UUID newInvItem = UUID.Random();
|
||||
UUID parentFolder = llsdRequest.folder_id;
|
||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
|
||||
|
||||
Caps.AssetUploader uploader =
|
||||
new Caps.AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
|
||||
MainServer.Instance.AddStreamHandler(
|
||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
if (MainServer.Instance.UseSSL)
|
||||
protocol = "https://";
|
||||
|
||||
string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
|
||||
uploaderPath;
|
||||
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
|
||||
|
||||
uploadResponse.rsvp = uploaderURL;
|
||||
uploadResponse.state = "upload";
|
||||
uploadResponse.resource_cost = 0;
|
||||
uploadResponse.upload_price = 0;
|
||||
|
||||
uploader.OnUpLoad += //UploadCompleteHandler;
|
||||
|
||||
delegate(
|
||||
string passetName, string passetDescription, UUID passetID,
|
||||
UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
|
||||
string passetType)
|
||||
{
|
||||
UploadCompleteHandler(passetName, passetDescription, passetID,
|
||||
pinventoryItem, pparentFolder, pdata, pinventoryType,
|
||||
passetType,agentID);
|
||||
};
|
||||
return uploadResponse;
|
||||
}
|
||||
|
||||
|
||||
public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
|
||||
UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
|
||||
string assetType,UUID AgentID)
|
||||
{
|
||||
|
||||
sbyte assType = 0;
|
||||
sbyte inType = 0;
|
||||
|
||||
if (inventoryType == "sound")
|
||||
{
|
||||
inType = 1;
|
||||
assType = 1;
|
||||
}
|
||||
else if (inventoryType == "animation")
|
||||
{
|
||||
inType = 19;
|
||||
assType = 20;
|
||||
}
|
||||
else if (inventoryType == "wearable")
|
||||
{
|
||||
inType = 18;
|
||||
switch (assetType)
|
||||
{
|
||||
case "bodypart":
|
||||
assType = 13;
|
||||
break;
|
||||
case "clothing":
|
||||
assType = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (inventoryType == "mesh")
|
||||
{
|
||||
inType = (sbyte)InventoryType.Mesh;
|
||||
assType = (sbyte)AssetType.Mesh;
|
||||
}
|
||||
|
||||
AssetBase asset;
|
||||
asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
|
||||
asset.Data = data;
|
||||
|
||||
if (m_scene.AssetService != null)
|
||||
m_scene.AssetService.Store(asset);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.Owner = AgentID;
|
||||
item.CreatorId = AgentID.ToString();
|
||||
item.ID = inventoryItem;
|
||||
item.AssetID = asset.FullID;
|
||||
item.Description = assetDescription;
|
||||
item.Name = assetName;
|
||||
item.AssetType = assType;
|
||||
item.InvType = inType;
|
||||
item.Folder = parentFolder;
|
||||
item.CurrentPermissions = (uint)PermissionMask.All;
|
||||
item.BasePermissions = (uint)PermissionMask.All;
|
||||
item.EveryOnePermissions = 0;
|
||||
item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
m_scene.AddInventoryItem(item);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,370 +0,0 @@
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using Caps=OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
|
||||
{
|
||||
public class ObjectAdd : IRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene pScene, IConfigSource pSource)
|
||||
{
|
||||
m_scene = pScene;
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
UUID capuuid = UUID.Random();
|
||||
|
||||
// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
|
||||
|
||||
caps.RegisterHandler("ObjectAdd",
|
||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/",
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
||||
}));
|
||||
}
|
||||
|
||||
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
|
||||
{
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 400; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Request wasn't what was expected";
|
||||
ScenePresence avatar;
|
||||
|
||||
if (!m_scene.TryGetScenePresence(AgentId, out avatar))
|
||||
return responsedata;
|
||||
|
||||
|
||||
OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]);
|
||||
//UUID session_id = UUID.Zero;
|
||||
bool bypass_raycast = false;
|
||||
uint everyone_mask = 0;
|
||||
uint group_mask = 0;
|
||||
uint next_owner_mask = 0;
|
||||
uint flags = 0;
|
||||
UUID group_id = UUID.Zero;
|
||||
int hollow = 0;
|
||||
int material = 0;
|
||||
int p_code = 0;
|
||||
int path_begin = 0;
|
||||
int path_curve = 0;
|
||||
int path_end = 0;
|
||||
int path_radius_offset = 0;
|
||||
int path_revolutions = 0;
|
||||
int path_scale_x = 0;
|
||||
int path_scale_y = 0;
|
||||
int path_shear_x = 0;
|
||||
int path_shear_y = 0;
|
||||
int path_skew = 0;
|
||||
int path_taper_x = 0;
|
||||
int path_taper_y = 0;
|
||||
int path_twist = 0;
|
||||
int path_twist_begin = 0;
|
||||
int profile_begin = 0;
|
||||
int profile_curve = 0;
|
||||
int profile_end = 0;
|
||||
Vector3 ray_end = Vector3.Zero;
|
||||
bool ray_end_is_intersection = false;
|
||||
Vector3 ray_start = Vector3.Zero;
|
||||
UUID ray_target_id = UUID.Zero;
|
||||
Quaternion rotation = Quaternion.Identity;
|
||||
Vector3 scale = Vector3.Zero;
|
||||
int state = 0;
|
||||
|
||||
if (r.Type != OSDType.Map) // not a proper req
|
||||
return responsedata;
|
||||
|
||||
OSDMap rm = (OSDMap)r;
|
||||
|
||||
if (rm.ContainsKey("ObjectData")) //v2
|
||||
{
|
||||
if (rm["ObjectData"].Type != OSDType.Map)
|
||||
{
|
||||
responsedata["str_response_string"] = "Has ObjectData key, but data not in expected format";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
OSDMap ObjMap = (OSDMap) rm["ObjectData"];
|
||||
|
||||
bypass_raycast = ObjMap["BypassRaycast"].AsBoolean();
|
||||
everyone_mask = readuintval(ObjMap["EveryoneMask"]);
|
||||
flags = readuintval(ObjMap["Flags"]);
|
||||
group_mask = readuintval(ObjMap["GroupMask"]);
|
||||
material = ObjMap["Material"].AsInteger();
|
||||
next_owner_mask = readuintval(ObjMap["NextOwnerMask"]);
|
||||
p_code = ObjMap["PCode"].AsInteger();
|
||||
|
||||
if (ObjMap.ContainsKey("Path"))
|
||||
{
|
||||
if (ObjMap["Path"].Type != OSDType.Map)
|
||||
{
|
||||
responsedata["str_response_string"] = "Has Path key, but data not in expected format";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
OSDMap PathMap = (OSDMap)ObjMap["Path"];
|
||||
path_begin = PathMap["Begin"].AsInteger();
|
||||
path_curve = PathMap["Curve"].AsInteger();
|
||||
path_end = PathMap["End"].AsInteger();
|
||||
path_radius_offset = PathMap["RadiusOffset"].AsInteger();
|
||||
path_revolutions = PathMap["Revolutions"].AsInteger();
|
||||
path_scale_x = PathMap["ScaleX"].AsInteger();
|
||||
path_scale_y = PathMap["ScaleY"].AsInteger();
|
||||
path_shear_x = PathMap["ShearX"].AsInteger();
|
||||
path_shear_y = PathMap["ShearY"].AsInteger();
|
||||
path_skew = PathMap["Skew"].AsInteger();
|
||||
path_taper_x = PathMap["TaperX"].AsInteger();
|
||||
path_taper_y = PathMap["TaperY"].AsInteger();
|
||||
path_twist = PathMap["Twist"].AsInteger();
|
||||
path_twist_begin = PathMap["TwistBegin"].AsInteger();
|
||||
|
||||
}
|
||||
|
||||
if (ObjMap.ContainsKey("Profile"))
|
||||
{
|
||||
if (ObjMap["Profile"].Type != OSDType.Map)
|
||||
{
|
||||
responsedata["str_response_string"] = "Has Profile key, but data not in expected format";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
OSDMap ProfileMap = (OSDMap)ObjMap["Profile"];
|
||||
|
||||
profile_begin = ProfileMap["Begin"].AsInteger();
|
||||
profile_curve = ProfileMap["Curve"].AsInteger();
|
||||
profile_end = ProfileMap["End"].AsInteger();
|
||||
hollow = ProfileMap["Hollow"].AsInteger();
|
||||
}
|
||||
ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean();
|
||||
|
||||
ray_target_id = ObjMap["RayTargetId"].AsUUID();
|
||||
state = ObjMap["State"].AsInteger();
|
||||
try
|
||||
{
|
||||
ray_end = ((OSDArray) ObjMap["RayEnd"]).AsVector3();
|
||||
ray_start = ((OSDArray) ObjMap["RayStart"]).AsVector3();
|
||||
scale = ((OSDArray) ObjMap["Scale"]).AsVector3();
|
||||
rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
if (rm.ContainsKey("AgentData"))
|
||||
{
|
||||
if (rm["AgentData"].Type != OSDType.Map)
|
||||
{
|
||||
responsedata["str_response_string"] = "Has AgentData key, but data not in expected format";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
OSDMap AgentDataMap = (OSDMap) rm["AgentData"];
|
||||
|
||||
//session_id = AgentDataMap["SessionId"].AsUUID();
|
||||
group_id = AgentDataMap["GroupId"].AsUUID();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{ //v1
|
||||
bypass_raycast = rm["bypass_raycast"].AsBoolean();
|
||||
|
||||
everyone_mask = readuintval(rm["everyone_mask"]);
|
||||
flags = readuintval(rm["flags"]);
|
||||
group_id = rm["group_id"].AsUUID();
|
||||
group_mask = readuintval(rm["group_mask"]);
|
||||
hollow = rm["hollow"].AsInteger();
|
||||
material = rm["material"].AsInteger();
|
||||
next_owner_mask = readuintval(rm["next_owner_mask"]);
|
||||
hollow = rm["hollow"].AsInteger();
|
||||
p_code = rm["p_code"].AsInteger();
|
||||
path_begin = rm["path_begin"].AsInteger();
|
||||
path_curve = rm["path_curve"].AsInteger();
|
||||
path_end = rm["path_end"].AsInteger();
|
||||
path_radius_offset = rm["path_radius_offset"].AsInteger();
|
||||
path_revolutions = rm["path_revolutions"].AsInteger();
|
||||
path_scale_x = rm["path_scale_x"].AsInteger();
|
||||
path_scale_y = rm["path_scale_y"].AsInteger();
|
||||
path_shear_x = rm["path_shear_x"].AsInteger();
|
||||
path_shear_y = rm["path_shear_y"].AsInteger();
|
||||
path_skew = rm["path_skew"].AsInteger();
|
||||
path_taper_x = rm["path_taper_x"].AsInteger();
|
||||
path_taper_y = rm["path_taper_y"].AsInteger();
|
||||
path_twist = rm["path_twist"].AsInteger();
|
||||
path_twist_begin = rm["path_twist_begin"].AsInteger();
|
||||
profile_begin = rm["profile_begin"].AsInteger();
|
||||
profile_curve = rm["profile_curve"].AsInteger();
|
||||
profile_end = rm["profile_end"].AsInteger();
|
||||
|
||||
ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean();
|
||||
|
||||
ray_target_id = rm["ray_target_id"].AsUUID();
|
||||
|
||||
|
||||
//session_id = rm["session_id"].AsUUID();
|
||||
state = rm["state"].AsInteger();
|
||||
try
|
||||
{
|
||||
ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
|
||||
ray_start = ((OSDArray)rm["ray_start"]).AsVector3();
|
||||
rotation = ((OSDArray)rm["rotation"]).AsQuaternion();
|
||||
scale = ((OSDArray)rm["scale"]).AsVector3();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false);
|
||||
|
||||
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
|
||||
|
||||
pbs.PathBegin = (ushort)path_begin;
|
||||
pbs.PathCurve = (byte)path_curve;
|
||||
pbs.PathEnd = (ushort)path_end;
|
||||
pbs.PathRadiusOffset = (sbyte)path_radius_offset;
|
||||
pbs.PathRevolutions = (byte)path_revolutions;
|
||||
pbs.PathScaleX = (byte)path_scale_x;
|
||||
pbs.PathScaleY = (byte)path_scale_y;
|
||||
pbs.PathShearX = (byte) path_shear_x;
|
||||
pbs.PathShearY = (byte)path_shear_y;
|
||||
pbs.PathSkew = (sbyte)path_skew;
|
||||
pbs.PathTaperX = (sbyte)path_taper_x;
|
||||
pbs.PathTaperY = (sbyte)path_taper_y;
|
||||
pbs.PathTwist = (sbyte)path_twist;
|
||||
pbs.PathTwistBegin = (sbyte)path_twist_begin;
|
||||
pbs.HollowShape = (HollowShape) hollow;
|
||||
pbs.PCode = (byte)p_code;
|
||||
pbs.ProfileBegin = (ushort) profile_begin;
|
||||
pbs.ProfileCurve = (byte) profile_curve;
|
||||
pbs.ProfileEnd = (ushort)profile_end;
|
||||
pbs.Scale = scale;
|
||||
pbs.State = (byte)state;
|
||||
|
||||
SceneObjectGroup obj = null; ;
|
||||
|
||||
if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
|
||||
{
|
||||
// rez ON the ground, not IN the ground
|
||||
// pos.Z += 0.25F;
|
||||
|
||||
obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs);
|
||||
}
|
||||
|
||||
|
||||
if (obj == null)
|
||||
return responsedata;
|
||||
|
||||
SceneObjectPart rootpart = obj.RootPart;
|
||||
rootpart.Shape = pbs;
|
||||
rootpart.Flags |= (PrimFlags)flags;
|
||||
rootpart.EveryoneMask = everyone_mask;
|
||||
rootpart.GroupID = group_id;
|
||||
rootpart.GroupMask = group_mask;
|
||||
rootpart.NextOwnerMask = next_owner_mask;
|
||||
rootpart.Material = (byte)material;
|
||||
|
||||
|
||||
|
||||
m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
|
||||
|
||||
responsedata["int_response_code"] = 200; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>",ConvertUintToBytes(obj.LocalId));
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
private uint readuintval(OSD obj)
|
||||
{
|
||||
byte[] tmp = obj.AsBinary();
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(tmp);
|
||||
return Utils.BytesToUInt(tmp);
|
||||
|
||||
}
|
||||
private string ConvertUintToBytes(uint val)
|
||||
{
|
||||
byte[] resultbytes = Utils.UIntToBytes(val);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(resultbytes);
|
||||
return String.Format("<binary encoding=\"base64\">{0}</binary>",Convert.ToBase64String(resultbytes));
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "ObjectAddModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,374 +0,0 @@
|
||||
/*
|
||||
* 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 Mono.Addins;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Messages.Linden;
|
||||
using OpenSim.Framework;
|
||||
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;
|
||||
using OSD = OpenMetaverse.StructuredData.OSD;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using ExtraParamType = OpenMetaverse.ExtraParamType;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class UploadObjectAssetModule : INonSharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene;
|
||||
|
||||
#region IRegionModuleBase Members
|
||||
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddRegion(Scene pScene)
|
||||
{
|
||||
m_scene = pScene;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene = null;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "UploadObjectAssetModuleModule"; } }
|
||||
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
|
||||
caps.RegisterHandler("UploadObjectAsset",
|
||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
||||
}));
|
||||
/*
|
||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
||||
|
||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
|
||||
"/CAPS/" + capID.ToString(),
|
||||
delegate(LLSDAssetUploadRequest req)
|
||||
{
|
||||
return NewAgentInventoryRequest(req,agentID);
|
||||
}));
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parses ad request
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="AgentId"></param>
|
||||
/// <param name="cap"></param>
|
||||
/// <returns></returns>
|
||||
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
|
||||
{
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 400; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Request wasn't what was expected";
|
||||
ScenePresence avatar;
|
||||
|
||||
if (!m_scene.TryGetScenePresence(AgentId, out avatar))
|
||||
return responsedata;
|
||||
|
||||
OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]);
|
||||
UploadObjectAssetMessage message = new UploadObjectAssetMessage();
|
||||
try
|
||||
{
|
||||
message.Deserialize(r);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_log.Error("[UPLOAD OBJECT ASSET MODULE]: Error deserializing message " + ex.ToString());
|
||||
message = null;
|
||||
}
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
responsedata["int_response_code"] = 400; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] =
|
||||
"<llsd><map><key>error</key><string>Error parsing Object</string></map></llsd>";
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation);
|
||||
Quaternion rot = Quaternion.Identity;
|
||||
Vector3 rootpos = Vector3.Zero;
|
||||
// Quaternion rootrot = Quaternion.Identity;
|
||||
|
||||
SceneObjectGroup rootGroup = null;
|
||||
SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length];
|
||||
for (int i = 0; i < message.Objects.Length; i++)
|
||||
{
|
||||
UploadObjectAssetMessage.Object obj = message.Objects[i];
|
||||
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
rootpos = obj.Position;
|
||||
// rootrot = obj.Rotation;
|
||||
}
|
||||
|
||||
// Combine the extraparams data into it's ugly blob again....
|
||||
//int bytelength = 0;
|
||||
//for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
|
||||
//{
|
||||
// bytelength += obj.ExtraParams[extparams].ExtraParamData.Length;
|
||||
//}
|
||||
//byte[] extraparams = new byte[bytelength];
|
||||
//int position = 0;
|
||||
|
||||
|
||||
|
||||
//for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
|
||||
//{
|
||||
// Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position,
|
||||
// obj.ExtraParams[extparams].ExtraParamData.Length);
|
||||
//
|
||||
// position += obj.ExtraParams[extparams].ExtraParamData.Length;
|
||||
// }
|
||||
|
||||
//pbs.ExtraParams = extraparams;
|
||||
for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
|
||||
{
|
||||
UploadObjectAssetMessage.Object.ExtraParam extraParam = obj.ExtraParams[extparams];
|
||||
switch ((ushort)extraParam.Type)
|
||||
{
|
||||
case (ushort)ExtraParamType.Sculpt:
|
||||
Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0);
|
||||
|
||||
pbs.SculptEntry = true;
|
||||
|
||||
pbs.SculptTexture = obj.SculptID;
|
||||
pbs.SculptType = (byte)sculpt.Type;
|
||||
|
||||
break;
|
||||
case (ushort)ExtraParamType.Flexible:
|
||||
Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0);
|
||||
pbs.FlexiEntry = true;
|
||||
pbs.FlexiDrag = flex.Drag;
|
||||
pbs.FlexiForceX = flex.Force.X;
|
||||
pbs.FlexiForceY = flex.Force.Y;
|
||||
pbs.FlexiForceZ = flex.Force.Z;
|
||||
pbs.FlexiGravity = flex.Gravity;
|
||||
pbs.FlexiSoftness = flex.Softness;
|
||||
pbs.FlexiTension = flex.Tension;
|
||||
pbs.FlexiWind = flex.Wind;
|
||||
break;
|
||||
case (ushort)ExtraParamType.Light:
|
||||
Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0);
|
||||
pbs.LightColorA = light.Color.A;
|
||||
pbs.LightColorB = light.Color.B;
|
||||
pbs.LightColorG = light.Color.G;
|
||||
pbs.LightColorR = light.Color.R;
|
||||
pbs.LightCutoff = light.Cutoff;
|
||||
pbs.LightEntry = true;
|
||||
pbs.LightFalloff = light.Falloff;
|
||||
pbs.LightIntensity = light.Intensity;
|
||||
pbs.LightRadius = light.Radius;
|
||||
break;
|
||||
case 0x40:
|
||||
pbs.ReadProjectionData(extraParam.ExtraParamData, 0);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
pbs.PathBegin = (ushort) obj.PathBegin;
|
||||
pbs.PathCurve = (byte) obj.PathCurve;
|
||||
pbs.PathEnd = (ushort) obj.PathEnd;
|
||||
pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset;
|
||||
pbs.PathRevolutions = (byte) obj.Revolutions;
|
||||
pbs.PathScaleX = (byte) obj.ScaleX;
|
||||
pbs.PathScaleY = (byte) obj.ScaleY;
|
||||
pbs.PathShearX = (byte) obj.ShearX;
|
||||
pbs.PathShearY = (byte) obj.ShearY;
|
||||
pbs.PathSkew = (sbyte) obj.Skew;
|
||||
pbs.PathTaperX = (sbyte) obj.TaperX;
|
||||
pbs.PathTaperY = (sbyte) obj.TaperY;
|
||||
pbs.PathTwist = (sbyte) obj.Twist;
|
||||
pbs.PathTwistBegin = (sbyte) obj.TwistBegin;
|
||||
pbs.HollowShape = (HollowShape) obj.ProfileHollow;
|
||||
pbs.PCode = (byte) PCode.Prim;
|
||||
pbs.ProfileBegin = (ushort) obj.ProfileBegin;
|
||||
pbs.ProfileCurve = (byte) obj.ProfileCurve;
|
||||
pbs.ProfileEnd = (ushort) obj.ProfileEnd;
|
||||
pbs.Scale = obj.Scale;
|
||||
pbs.State = (byte) 0;
|
||||
SceneObjectPart prim = new SceneObjectPart();
|
||||
prim.UUID = UUID.Random();
|
||||
prim.CreatorID = AgentId;
|
||||
prim.OwnerID = AgentId;
|
||||
prim.GroupID = obj.GroupID;
|
||||
prim.LastOwnerID = prim.OwnerID;
|
||||
prim.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
prim.Name = obj.Name;
|
||||
prim.Description = "";
|
||||
|
||||
prim.PayPrice[0] = -2;
|
||||
prim.PayPrice[1] = -2;
|
||||
prim.PayPrice[2] = -2;
|
||||
prim.PayPrice[3] = -2;
|
||||
prim.PayPrice[4] = -2;
|
||||
Primitive.TextureEntry tmp =
|
||||
new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f"));
|
||||
|
||||
for (int j = 0; j < obj.Faces.Length; j++)
|
||||
{
|
||||
UploadObjectAssetMessage.Object.Face face = obj.Faces[j];
|
||||
|
||||
Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j);
|
||||
|
||||
primFace.Bump = face.Bump;
|
||||
primFace.RGBA = face.Color;
|
||||
primFace.Fullbright = face.Fullbright;
|
||||
primFace.Glow = face.Glow;
|
||||
primFace.TextureID = face.ImageID;
|
||||
primFace.Rotation = face.ImageRot;
|
||||
primFace.MediaFlags = ((face.MediaFlags & 1) != 0);
|
||||
|
||||
primFace.OffsetU = face.OffsetS;
|
||||
primFace.OffsetV = face.OffsetT;
|
||||
primFace.RepeatU = face.ScaleS;
|
||||
primFace.RepeatV = face.ScaleT;
|
||||
primFace.TexMapType = (MappingType) (face.MediaFlags & 6);
|
||||
}
|
||||
pbs.TextureEntry = tmp.GetBytes();
|
||||
prim.Shape = pbs;
|
||||
prim.Scale = obj.Scale;
|
||||
|
||||
|
||||
SceneObjectGroup grp = new SceneObjectGroup();
|
||||
|
||||
grp.SetRootPart(prim);
|
||||
prim.ParentID = 0;
|
||||
if (i == 0)
|
||||
{
|
||||
rootGroup = grp;
|
||||
|
||||
}
|
||||
grp.AttachToScene(m_scene);
|
||||
grp.AbsolutePosition = obj.Position;
|
||||
prim.RotationOffset = obj.Rotation;
|
||||
|
||||
grp.RootPart.IsAttachment = false;
|
||||
// Required for linking
|
||||
grp.RootPart.UpdateFlag = 0;
|
||||
|
||||
if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
|
||||
{
|
||||
m_scene.AddSceneObject(grp);
|
||||
grp.AbsolutePosition = obj.Position;
|
||||
}
|
||||
allparts[i] = grp;
|
||||
|
||||
}
|
||||
|
||||
for (int j = 1; j < allparts.Length; j++)
|
||||
{
|
||||
rootGroup.RootPart.UpdateFlag = 0;
|
||||
allparts[j].RootPart.UpdateFlag = 0;
|
||||
rootGroup.LinkToGroup(allparts[j]);
|
||||
}
|
||||
|
||||
rootGroup.ScheduleGroupForFullUpdate();
|
||||
pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false);
|
||||
|
||||
responsedata["int_response_code"] = 200; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(allparts[0].LocalId));
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
private string ConvertUintToBytes(uint val)
|
||||
{
|
||||
byte[] resultbytes = Utils.UIntToBytes(val);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(resultbytes);
|
||||
return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
@@ -38,8 +39,9 @@ using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using Caps=OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
namespace OpenSim.Region.CoreModules.Framework
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
@@ -49,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
/// <summary>
|
||||
/// Each agent has its own capabilities handler.
|
||||
/// </summary>
|
||||
protected Dictionary<UUID, Caps> m_capsHandlers = new Dictionary<UUID, Caps>();
|
||||
protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>();
|
||||
|
||||
protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>();
|
||||
protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
|
||||
@@ -93,7 +95,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void AddCapsHandler(UUID agentId)
|
||||
public void CreateCaps(UUID agentId)
|
||||
{
|
||||
int flags = m_scene.GetUserFlags(agentId);
|
||||
if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
|
||||
@@ -101,12 +103,12 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
|
||||
String capsObjectPath = GetCapsPath(agentId);
|
||||
|
||||
if (m_capsHandlers.ContainsKey(agentId))
|
||||
if (m_capsObjects.ContainsKey(agentId))
|
||||
{
|
||||
Caps oldCaps = m_capsHandlers[agentId];
|
||||
Caps oldCaps = m_capsObjects[agentId];
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[CAPS]: Reregistering caps for agent {0}. Old caps path {1}, new caps path {2}. ",
|
||||
"[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ",
|
||||
agentId, oldCaps.CapsObjectPath, capsObjectPath);
|
||||
// This should not happen. The caller code is confused. We need to fix that.
|
||||
// CAPs can never be reregistered, or the client will be confused.
|
||||
@@ -114,39 +116,29 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
//return;
|
||||
}
|
||||
|
||||
Caps caps
|
||||
= new Caps(m_scene,
|
||||
m_scene.AssetService, MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
|
||||
Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
|
||||
(MainServer.Instance == null) ? 0: MainServer.Instance.Port,
|
||||
capsObjectPath, agentId, m_scene.DumpAssetsToFile, m_scene.RegionInfo.RegionName);
|
||||
capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
|
||||
|
||||
caps.RegisterHandlers();
|
||||
m_capsObjects[agentId] = caps;
|
||||
|
||||
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
|
||||
|
||||
caps.AddNewInventoryItem = m_scene.AddUploadedInventoryItem;
|
||||
caps.ItemUpdatedCall = m_scene.CapsUpdateInventoryItemAsset;
|
||||
caps.TaskScriptUpdatedCall = m_scene.CapsUpdateTaskInventoryScriptAsset;
|
||||
caps.CAPSFetchInventoryDescendents = m_scene.HandleFetchInventoryDescendentsCAPS;
|
||||
caps.GetClient = m_scene.SceneContents.GetControllingClient;
|
||||
|
||||
m_capsHandlers[agentId] = caps;
|
||||
}
|
||||
|
||||
public void RemoveCapsHandler(UUID agentId)
|
||||
public void RemoveCaps(UUID agentId)
|
||||
{
|
||||
if (childrenSeeds.ContainsKey(agentId))
|
||||
{
|
||||
childrenSeeds.Remove(agentId);
|
||||
}
|
||||
|
||||
lock (m_capsHandlers)
|
||||
lock (m_capsObjects)
|
||||
{
|
||||
if (m_capsHandlers.ContainsKey(agentId))
|
||||
if (m_capsObjects.ContainsKey(agentId))
|
||||
{
|
||||
m_capsHandlers[agentId].DeregisterHandlers();
|
||||
m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]);
|
||||
m_capsHandlers.Remove(agentId);
|
||||
m_capsObjects[agentId].DeregisterHandlers();
|
||||
m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]);
|
||||
m_capsObjects.Remove(agentId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -157,20 +149,20 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
}
|
||||
}
|
||||
|
||||
public Caps GetCapsHandlerForUser(UUID agentId)
|
||||
public Caps GetCapsForUser(UUID agentId)
|
||||
{
|
||||
lock (m_capsHandlers)
|
||||
lock (m_capsObjects)
|
||||
{
|
||||
if (m_capsHandlers.ContainsKey(agentId))
|
||||
if (m_capsObjects.ContainsKey(agentId))
|
||||
{
|
||||
return m_capsHandlers[agentId];
|
||||
return m_capsObjects[agentId];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void NewUserConnection(AgentCircuitData agent)
|
||||
public void SetAgentCapsSeeds(AgentCircuitData agent)
|
||||
{
|
||||
capsPaths[agent.AgentID] = agent.CapsPath;
|
||||
childrenSeeds[agent.AgentID]
|
||||
@@ -240,7 +232,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
System.Text.StringBuilder caps = new System.Text.StringBuilder();
|
||||
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
||||
|
||||
foreach (KeyValuePair<UUID, Caps> kvp in m_capsHandlers)
|
||||
foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects)
|
||||
{
|
||||
caps.AppendFormat("** User {0}:\n", kvp.Key);
|
||||
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); )
|
||||
@@ -248,6 +240,8 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities
|
||||
Uri uri = new Uri(kvp2.Value.ToString());
|
||||
caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery);
|
||||
}
|
||||
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
|
||||
caps.AppendFormat(" {0} = {1}\n", kvp3.Key, kvp3.Value);
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output(caps.ToString());
|
||||
@@ -1,719 +0,0 @@
|
||||
/*
|
||||
* 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.Generic;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Messages.Linden;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue<OpenMetaverse.StructuredData.OSD>;
|
||||
using Caps=OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Framework.EventQueue
|
||||
{
|
||||
public struct QueueItem
|
||||
{
|
||||
public int id;
|
||||
public OSDMap body;
|
||||
}
|
||||
|
||||
public class EventQueueGetModule : IEventQueue, IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
protected Scene m_scene = null;
|
||||
private IConfigSource m_gConfig;
|
||||
bool enabledYN = false;
|
||||
|
||||
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
||||
|
||||
private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
|
||||
private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
|
||||
private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
|
||||
|
||||
#region IRegionModule methods
|
||||
public virtual void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_gConfig = config;
|
||||
|
||||
IConfig startupConfig = m_gConfig.Configs["Startup"];
|
||||
|
||||
ReadConfigAndPopulate(scene, startupConfig, "Startup");
|
||||
|
||||
if (enabledYN)
|
||||
{
|
||||
m_scene = scene;
|
||||
scene.RegisterModuleInterface<IEventQueue>(this);
|
||||
|
||||
// Register fallback handler
|
||||
// Why does EQG Fail on region crossings!
|
||||
|
||||
//scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
|
||||
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
|
||||
// TODO: Leaving these open, or closing them when we
|
||||
// become a child is incorrect. It messes up TP in a big
|
||||
// way. CAPS/EQ need to be active as long as the UDP
|
||||
// circuit is there.
|
||||
|
||||
scene.EventManager.OnClientClosed += ClientClosed;
|
||||
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gConfig = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p)
|
||||
{
|
||||
enabledYN = startupConfig.GetBoolean("EventQueue", true);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual string Name
|
||||
{
|
||||
get { return "EventQueueGetModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Always returns a valid queue
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
/// <returns></returns>
|
||||
private Queue<OSD> TryGetQueue(UUID agentId)
|
||||
{
|
||||
lock (queues)
|
||||
{
|
||||
if (!queues.ContainsKey(agentId))
|
||||
{
|
||||
/*
|
||||
m_log.DebugFormat(
|
||||
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
|
||||
agentId, m_scene.RegionInfo.RegionName);
|
||||
*/
|
||||
queues[agentId] = new Queue<OSD>();
|
||||
}
|
||||
|
||||
return queues[agentId];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// May return a null queue
|
||||
/// </summary>
|
||||
/// <param name="agentId"></param>
|
||||
/// <returns></returns>
|
||||
private Queue<OSD> GetQueue(UUID agentId)
|
||||
{
|
||||
lock (queues)
|
||||
{
|
||||
if (queues.ContainsKey(agentId))
|
||||
{
|
||||
return queues[agentId];
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#region IEventQueue Members
|
||||
|
||||
public bool Enqueue(OSD ev, UUID avatarID)
|
||||
{
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
|
||||
try
|
||||
{
|
||||
Queue<OSD> queue = GetQueue(avatarID);
|
||||
if (queue != null)
|
||||
queue.Enqueue(ev);
|
||||
}
|
||||
catch(NullReferenceException e)
|
||||
{
|
||||
m_log.Error("[EVENTQUEUE] Caught exception: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
//client.OnLogout += ClientClosed;
|
||||
}
|
||||
|
||||
// private void ClientClosed(IClientAPI client)
|
||||
// {
|
||||
// ClientClosed(client.AgentId);
|
||||
// }
|
||||
|
||||
private void ClientClosed(UUID AgentID, Scene scene)
|
||||
{
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName);
|
||||
|
||||
int count = 0;
|
||||
while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
lock (queues)
|
||||
{
|
||||
queues.Remove(AgentID);
|
||||
}
|
||||
List<UUID> removeitems = new List<UUID>();
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
||||
{
|
||||
if (ky == AgentID)
|
||||
{
|
||||
removeitems.Add(ky);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (UUID ky in removeitems)
|
||||
{
|
||||
m_AvatarQueueUUIDMapping.Remove(ky);
|
||||
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + ky.ToString() + "/");
|
||||
}
|
||||
|
||||
}
|
||||
UUID searchval = UUID.Zero;
|
||||
|
||||
removeitems.Clear();
|
||||
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
{
|
||||
foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys)
|
||||
{
|
||||
searchval = m_QueueUUIDAvatarMapping[ky];
|
||||
|
||||
if (searchval == AgentID)
|
||||
{
|
||||
removeitems.Add(ky);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (UUID ky in removeitems)
|
||||
m_QueueUUIDAvatarMapping.Remove(ky);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void MakeChildAgent(ScenePresence avatar)
|
||||
{
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Make Child agent {0} in region {1}.", avatar.UUID, m_scene.RegionInfo.RegionName);
|
||||
//lock (m_ids)
|
||||
// {
|
||||
//if (m_ids.ContainsKey(avatar.UUID))
|
||||
//{
|
||||
// close the event queue.
|
||||
//m_ids[avatar.UUID] = -1;
|
||||
//}
|
||||
//}
|
||||
}
|
||||
|
||||
public void OnRegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
// Register an event queue for the client
|
||||
|
||||
//m_log.DebugFormat(
|
||||
// "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
|
||||
// agentID, caps, m_scene.RegionInfo.RegionName);
|
||||
|
||||
// Let's instantiate a Queue for this agent right now
|
||||
TryGetQueue(agentID);
|
||||
|
||||
string capsBase = "/CAPS/EQG/";
|
||||
UUID EventQueueGetUUID = UUID.Zero;
|
||||
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
// Reuse open queues. The client does!
|
||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
{
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
||||
EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||
}
|
||||
else
|
||||
{
|
||||
EventQueueGetUUID = UUID.Random();
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
{
|
||||
if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID))
|
||||
m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID);
|
||||
}
|
||||
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID);
|
||||
}
|
||||
|
||||
// Register this as a caps handler
|
||||
caps.RegisterHandler("EventQueueGet",
|
||||
new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/",
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return ProcessQueue(m_dhttpMethod, agentID, caps);
|
||||
}));
|
||||
|
||||
// This will persist this beyond the expiry of the caps handlers
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
||||
capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
||||
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
lock (m_ids)
|
||||
{
|
||||
if (!m_ids.ContainsKey(agentID))
|
||||
m_ids.Add(agentID, rnd.Next(30000000));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasEvents(UUID requestID, UUID agentID)
|
||||
{
|
||||
// Don't use this, because of race conditions at agent closing time
|
||||
//Queue<OSD> queue = TryGetQueue(agentID);
|
||||
|
||||
Queue<OSD> queue = GetQueue(agentID);
|
||||
if (queue != null)
|
||||
lock (queue)
|
||||
{
|
||||
if (queue.Count > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
|
||||
{
|
||||
Queue<OSD> queue = TryGetQueue(pAgentId);
|
||||
OSD element;
|
||||
lock (queue)
|
||||
{
|
||||
if (queue.Count == 0)
|
||||
return NoEvents(requestID, pAgentId);
|
||||
element = queue.Dequeue(); // 15s timeout
|
||||
}
|
||||
|
||||
|
||||
|
||||
int thisID = 0;
|
||||
lock (m_ids)
|
||||
thisID = m_ids[pAgentId];
|
||||
|
||||
OSDArray array = new OSDArray();
|
||||
if (element == null) // didn't have an event in 15s
|
||||
{
|
||||
// Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
|
||||
array.Add(EventQueueHelper.KeepAliveEvent());
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
array.Add(element);
|
||||
lock (queue)
|
||||
{
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
array.Add(queue.Dequeue());
|
||||
thisID++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSDMap events = new OSDMap();
|
||||
events.Add("events", array);
|
||||
|
||||
events.Add("id", new OSDInteger(thisID));
|
||||
lock (m_ids)
|
||||
{
|
||||
m_ids[pAgentId] = thisID + 1;
|
||||
}
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["content_type"] = "application/xml";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
public Hashtable NoEvents(UUID requestID, UUID agentID)
|
||||
{
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 502;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["reusecontext"] = false;
|
||||
responsedata["str_response_string"] = "Upstream error: ";
|
||||
responsedata["error_status_text"] = "Upstream error:";
|
||||
responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
|
||||
{
|
||||
// TODO: this has to be redone to not busy-wait (and block the thread),
|
||||
// TODO: as soon as we have a non-blocking way to handle HTTP-requests.
|
||||
|
||||
// if (m_log.IsDebugEnabled)
|
||||
// {
|
||||
// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
|
||||
// foreach (object key in request.Keys)
|
||||
// {
|
||||
// debug += key.ToString() + "=" + request[key].ToString() + " ";
|
||||
// }
|
||||
// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
|
||||
// }
|
||||
|
||||
Queue<OSD> queue = TryGetQueue(agentID);
|
||||
OSD element = queue.Dequeue(); // 15s timeout
|
||||
|
||||
Hashtable responsedata = new Hashtable();
|
||||
|
||||
int thisID = 0;
|
||||
lock (m_ids)
|
||||
thisID = m_ids[agentID];
|
||||
|
||||
if (element == null)
|
||||
{
|
||||
//m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
|
||||
if (thisID == -1) // close-request
|
||||
{
|
||||
m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Closed EQG";
|
||||
return responsedata;
|
||||
}
|
||||
responsedata["int_response_code"] = 502;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Upstream error: ";
|
||||
responsedata["error_status_text"] = "Upstream error:";
|
||||
responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
OSDArray array = new OSDArray();
|
||||
if (element == null) // didn't have an event in 15s
|
||||
{
|
||||
// Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
|
||||
array.Add(EventQueueHelper.KeepAliveEvent());
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
else
|
||||
{
|
||||
array.Add(element);
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
array.Add(queue.Dequeue());
|
||||
thisID++;
|
||||
}
|
||||
}
|
||||
|
||||
OSDMap events = new OSDMap();
|
||||
events.Add("events", array);
|
||||
|
||||
events.Add("id", new OSDInteger(thisID));
|
||||
lock (m_ids)
|
||||
{
|
||||
m_ids[agentID] = thisID + 1;
|
||||
}
|
||||
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["content_type"] = "application/xml";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
public Hashtable EventQueuePoll(Hashtable request)
|
||||
{
|
||||
return new Hashtable();
|
||||
}
|
||||
|
||||
public Hashtable EventQueuePath2(Hashtable request)
|
||||
{
|
||||
string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
|
||||
// pull off the last "/" in the path.
|
||||
Hashtable responsedata = new Hashtable();
|
||||
capuuid = capuuid.Substring(0, capuuid.Length - 1);
|
||||
capuuid = capuuid.Replace("/CAPS/EQG/", "");
|
||||
UUID AvatarID = UUID.Zero;
|
||||
UUID capUUID = UUID.Zero;
|
||||
|
||||
// parse the path and search for the avatar with it registered
|
||||
if (UUID.TryParse(capuuid, out capUUID))
|
||||
{
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
{
|
||||
if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
|
||||
{
|
||||
AvatarID = m_QueueUUIDAvatarMapping[capUUID];
|
||||
}
|
||||
}
|
||||
if (AvatarID != UUID.Zero)
|
||||
{
|
||||
return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsHandlerForUser(AvatarID));
|
||||
}
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Not Found";
|
||||
responsedata["error_status_text"] = "Not Found";
|
||||
responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
return responsedata;
|
||||
// return 404
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Not Found";
|
||||
responsedata["error_status_text"] = "Not Found";
|
||||
responsedata["http_protocol_version"] = "HTTP/1.0";
|
||||
return responsedata;
|
||||
// return 404
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public OSD EventQueueFallBack(string path, OSD request, string endpoint)
|
||||
{
|
||||
// This is a fallback element to keep the client from loosing EventQueueGet
|
||||
// Why does CAPS fail sometimes!?
|
||||
m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
|
||||
string capuuid = path.Replace("/CAPS/EQG/","");
|
||||
capuuid = capuuid.Substring(0, capuuid.Length - 1);
|
||||
|
||||
// UUID AvatarID = UUID.Zero;
|
||||
UUID capUUID = UUID.Zero;
|
||||
if (UUID.TryParse(capuuid, out capUUID))
|
||||
{
|
||||
/* Don't remove this yet code cleaners!
|
||||
* Still testing this!
|
||||
*
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
{
|
||||
if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
|
||||
{
|
||||
AvatarID = m_QueueUUIDAvatarMapping[capUUID];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (AvatarID != UUID.Zero)
|
||||
{
|
||||
// Repair the CAP!
|
||||
//OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
|
||||
//string capsBase = "/CAPS/EQG/";
|
||||
//caps.RegisterHandler("EventQueueGet",
|
||||
//new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
|
||||
//delegate(Hashtable m_dhttpMethod)
|
||||
//{
|
||||
// return ProcessQueue(m_dhttpMethod, AvatarID, caps);
|
||||
//}));
|
||||
// start new ID sequence.
|
||||
Random rnd = new Random(System.Environment.TickCount);
|
||||
lock (m_ids)
|
||||
{
|
||||
if (!m_ids.ContainsKey(AvatarID))
|
||||
m_ids.Add(AvatarID, rnd.Next(30000000));
|
||||
}
|
||||
|
||||
|
||||
int thisID = 0;
|
||||
lock (m_ids)
|
||||
thisID = m_ids[AvatarID];
|
||||
|
||||
BlockingLLSDQueue queue = GetQueue(AvatarID);
|
||||
OSDArray array = new OSDArray();
|
||||
LLSD element = queue.Dequeue(15000); // 15s timeout
|
||||
if (element == null)
|
||||
{
|
||||
|
||||
array.Add(EventQueueHelper.KeepAliveEvent());
|
||||
}
|
||||
else
|
||||
{
|
||||
array.Add(element);
|
||||
while (queue.Count() > 0)
|
||||
{
|
||||
array.Add(queue.Dequeue(1));
|
||||
thisID++;
|
||||
}
|
||||
}
|
||||
OSDMap events = new OSDMap();
|
||||
events.Add("events", array);
|
||||
|
||||
events.Add("id", new LLSDInteger(thisID));
|
||||
|
||||
lock (m_ids)
|
||||
{
|
||||
m_ids[AvatarID] = thisID + 1;
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new LLSD();
|
||||
}
|
||||
*
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
//return new LLSD();
|
||||
}
|
||||
|
||||
return new OSDString("shutdown404!");
|
||||
}
|
||||
|
||||
public void DisableSimulator(ulong handle, UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.DisableSimulator(handle);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
||||
public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.EnableSimulator(handle, endPoint);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
||||
public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath)
|
||||
{
|
||||
OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
||||
public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess,
|
||||
IPEndPoint regionExternalEndPoint,
|
||||
uint locationID, uint flags, string capsURL,
|
||||
UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
|
||||
locationID, flags, capsURL, avatarID);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
||||
public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
|
||||
IPEndPoint newRegionExternalEndPoint,
|
||||
string capsURL, UUID avatarID, UUID sessionID)
|
||||
{
|
||||
OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
|
||||
capsURL, avatarID, sessionID);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
||||
public void ChatterboxInvitation(UUID sessionID, string sessionName,
|
||||
UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
|
||||
uint timeStamp, bool offline, int parentEstateID, Vector3 position,
|
||||
uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
|
||||
{
|
||||
OSD item = EventQueueHelper.ChatterboxInvitation(sessionID, sessionName, fromAgent, message, toAgent, fromName, dialog,
|
||||
timeStamp, offline, parentEstateID, position, ttl, transactionID,
|
||||
fromGroup, binaryBucket);
|
||||
Enqueue(item, toAgent);
|
||||
//m_log.InfoFormat("########### eq ChatterboxInvitation #############\n{0}", item);
|
||||
|
||||
}
|
||||
|
||||
public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat,
|
||||
bool isModerator, bool textMute)
|
||||
{
|
||||
OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
|
||||
isModerator, textMute);
|
||||
Enqueue(item, toAgent);
|
||||
//m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
|
||||
}
|
||||
|
||||
public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
||||
public void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.GroupMembership(groupUpdate);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.PlacesQuery(groupUpdate);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,399 +0,0 @@
|
||||
/*
|
||||
* 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.Net;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Messages.Linden;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Framework.EventQueue
|
||||
{
|
||||
public class EventQueueHelper
|
||||
{
|
||||
private EventQueueHelper() {} // no construction possible, it's an utility class
|
||||
|
||||
private static byte[] ulongToByteArray(ulong uLongValue)
|
||||
{
|
||||
// Reverse endianness of RegionHandle
|
||||
return new byte[]
|
||||
{
|
||||
(byte)((uLongValue >> 56) % 256),
|
||||
(byte)((uLongValue >> 48) % 256),
|
||||
(byte)((uLongValue >> 40) % 256),
|
||||
(byte)((uLongValue >> 32) % 256),
|
||||
(byte)((uLongValue >> 24) % 256),
|
||||
(byte)((uLongValue >> 16) % 256),
|
||||
(byte)((uLongValue >> 8) % 256),
|
||||
(byte)(uLongValue % 256)
|
||||
};
|
||||
}
|
||||
|
||||
// private static byte[] uintToByteArray(uint uIntValue)
|
||||
// {
|
||||
// byte[] result = new byte[4];
|
||||
// Utils.UIntToBytesBig(uIntValue, result, 0);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public static OSD buildEvent(string eventName, OSD eventBody)
|
||||
{
|
||||
OSDMap llsdEvent = new OSDMap(2);
|
||||
llsdEvent.Add("message", new OSDString(eventName));
|
||||
llsdEvent.Add("body", eventBody);
|
||||
|
||||
return llsdEvent;
|
||||
}
|
||||
|
||||
public static OSD EnableSimulator(ulong handle, IPEndPoint endPoint)
|
||||
{
|
||||
OSDMap llsdSimInfo = new OSDMap(3);
|
||||
|
||||
llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
|
||||
llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
|
||||
llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port));
|
||||
|
||||
OSDArray arr = new OSDArray(1);
|
||||
arr.Add(llsdSimInfo);
|
||||
|
||||
OSDMap llsdBody = new OSDMap(1);
|
||||
llsdBody.Add("SimulatorInfo", arr);
|
||||
|
||||
return buildEvent("EnableSimulator", llsdBody);
|
||||
}
|
||||
|
||||
public static OSD DisableSimulator(ulong handle)
|
||||
{
|
||||
//OSDMap llsdSimInfo = new OSDMap(1);
|
||||
|
||||
//llsdSimInfo.Add("Handle", new OSDBinary(regionHandleToByteArray(handle)));
|
||||
|
||||
//OSDArray arr = new OSDArray(1);
|
||||
//arr.Add(llsdSimInfo);
|
||||
|
||||
OSDMap llsdBody = new OSDMap(0);
|
||||
//llsdBody.Add("SimulatorInfo", arr);
|
||||
|
||||
return buildEvent("DisableSimulator", llsdBody);
|
||||
}
|
||||
|
||||
public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
|
||||
IPEndPoint newRegionExternalEndPoint,
|
||||
string capsURL, UUID agentID, UUID sessionID)
|
||||
{
|
||||
OSDArray lookAtArr = new OSDArray(3);
|
||||
lookAtArr.Add(OSD.FromReal(lookAt.X));
|
||||
lookAtArr.Add(OSD.FromReal(lookAt.Y));
|
||||
lookAtArr.Add(OSD.FromReal(lookAt.Z));
|
||||
|
||||
OSDArray positionArr = new OSDArray(3);
|
||||
positionArr.Add(OSD.FromReal(pos.X));
|
||||
positionArr.Add(OSD.FromReal(pos.Y));
|
||||
positionArr.Add(OSD.FromReal(pos.Z));
|
||||
|
||||
OSDMap infoMap = new OSDMap(2);
|
||||
infoMap.Add("LookAt", lookAtArr);
|
||||
infoMap.Add("Position", positionArr);
|
||||
|
||||
OSDArray infoArr = new OSDArray(1);
|
||||
infoArr.Add(infoMap);
|
||||
|
||||
OSDMap agentDataMap = new OSDMap(2);
|
||||
agentDataMap.Add("AgentID", OSD.FromUUID(agentID));
|
||||
agentDataMap.Add("SessionID", OSD.FromUUID(sessionID));
|
||||
|
||||
OSDArray agentDataArr = new OSDArray(1);
|
||||
agentDataArr.Add(agentDataMap);
|
||||
|
||||
OSDMap regionDataMap = new OSDMap(4);
|
||||
regionDataMap.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(handle)));
|
||||
regionDataMap.Add("SeedCapability", OSD.FromString(capsURL));
|
||||
regionDataMap.Add("SimIP", OSD.FromBinary(newRegionExternalEndPoint.Address.GetAddressBytes()));
|
||||
regionDataMap.Add("SimPort", OSD.FromInteger(newRegionExternalEndPoint.Port));
|
||||
|
||||
OSDArray regionDataArr = new OSDArray(1);
|
||||
regionDataArr.Add(regionDataMap);
|
||||
|
||||
OSDMap llsdBody = new OSDMap(3);
|
||||
llsdBody.Add("Info", infoArr);
|
||||
llsdBody.Add("AgentData", agentDataArr);
|
||||
llsdBody.Add("RegionData", regionDataArr);
|
||||
|
||||
return buildEvent("CrossedRegion", llsdBody);
|
||||
}
|
||||
|
||||
public static OSD TeleportFinishEvent(
|
||||
ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
|
||||
uint locationID, uint flags, string capsURL, UUID agentID)
|
||||
{
|
||||
OSDMap info = new OSDMap();
|
||||
info.Add("AgentID", OSD.FromUUID(agentID));
|
||||
info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this?
|
||||
info.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(regionHandle)));
|
||||
info.Add("SeedCapability", OSD.FromString(capsURL));
|
||||
info.Add("SimAccess", OSD.FromInteger(simAccess));
|
||||
info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
|
||||
info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
|
||||
info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
|
||||
|
||||
OSDArray infoArr = new OSDArray();
|
||||
infoArr.Add(info);
|
||||
|
||||
OSDMap body = new OSDMap();
|
||||
body.Add("Info", infoArr);
|
||||
|
||||
return buildEvent("TeleportFinish", body);
|
||||
}
|
||||
|
||||
public static OSD ScriptRunningReplyEvent(UUID objectID, UUID itemID, bool running, bool mono)
|
||||
{
|
||||
OSDMap script = new OSDMap();
|
||||
script.Add("ObjectID", OSD.FromUUID(objectID));
|
||||
script.Add("ItemID", OSD.FromUUID(itemID));
|
||||
script.Add("Running", OSD.FromBoolean(running));
|
||||
script.Add("Mono", OSD.FromBoolean(mono));
|
||||
|
||||
OSDArray scriptArr = new OSDArray();
|
||||
scriptArr.Add(script);
|
||||
|
||||
OSDMap body = new OSDMap();
|
||||
body.Add("Script", scriptArr);
|
||||
|
||||
return buildEvent("ScriptRunningReply", body);
|
||||
}
|
||||
|
||||
public static OSD EstablishAgentCommunication(UUID agentID, string simIpAndPort, string seedcap)
|
||||
{
|
||||
OSDMap body = new OSDMap(3);
|
||||
body.Add("agent-id", new OSDUUID(agentID));
|
||||
body.Add("sim-ip-and-port", new OSDString(simIpAndPort));
|
||||
body.Add("seed-capability", new OSDString(seedcap));
|
||||
|
||||
return buildEvent("EstablishAgentCommunication", body);
|
||||
}
|
||||
|
||||
public static OSD KeepAliveEvent()
|
||||
{
|
||||
return buildEvent("FAKEEVENT", new OSDMap());
|
||||
}
|
||||
|
||||
public static OSD AgentParams(UUID agentID, bool checkEstate, int godLevel, bool limitedToEstate)
|
||||
{
|
||||
OSDMap body = new OSDMap(4);
|
||||
|
||||
body.Add("agent_id", new OSDUUID(agentID));
|
||||
body.Add("check_estate", new OSDInteger(checkEstate ? 1 : 0));
|
||||
body.Add("god_level", new OSDInteger(godLevel));
|
||||
body.Add("limited_to_estate", new OSDInteger(limitedToEstate ? 1 : 0));
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
public static OSD InstantMessageParams(UUID fromAgent, string message, UUID toAgent,
|
||||
string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID,
|
||||
Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
|
||||
{
|
||||
OSDMap messageParams = new OSDMap(15);
|
||||
messageParams.Add("type", new OSDInteger((int)dialog));
|
||||
|
||||
OSDArray positionArray = new OSDArray(3);
|
||||
positionArray.Add(OSD.FromReal(position.X));
|
||||
positionArray.Add(OSD.FromReal(position.Y));
|
||||
positionArray.Add(OSD.FromReal(position.Z));
|
||||
messageParams.Add("position", positionArray);
|
||||
|
||||
messageParams.Add("region_id", new OSDUUID(UUID.Zero));
|
||||
messageParams.Add("to_id", new OSDUUID(toAgent));
|
||||
messageParams.Add("source", new OSDInteger(0));
|
||||
|
||||
OSDMap data = new OSDMap(1);
|
||||
data.Add("binary_bucket", OSD.FromBinary(binaryBucket));
|
||||
messageParams.Add("data", data);
|
||||
messageParams.Add("message", new OSDString(message));
|
||||
messageParams.Add("id", new OSDUUID(transactionID));
|
||||
messageParams.Add("from_name", new OSDString(fromName));
|
||||
messageParams.Add("timestamp", new OSDInteger((int)timeStamp));
|
||||
messageParams.Add("offline", new OSDInteger(offline ? 1 : 0));
|
||||
messageParams.Add("parent_estate_id", new OSDInteger(parentEstateID));
|
||||
messageParams.Add("ttl", new OSDInteger((int)ttl));
|
||||
messageParams.Add("from_id", new OSDUUID(fromAgent));
|
||||
messageParams.Add("from_group", new OSDInteger(fromGroup ? 1 : 0));
|
||||
|
||||
return messageParams;
|
||||
}
|
||||
|
||||
public static OSD InstantMessage(UUID fromAgent, string message, UUID toAgent,
|
||||
string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID,
|
||||
Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket,
|
||||
bool checkEstate, int godLevel, bool limitedToEstate)
|
||||
{
|
||||
OSDMap im = new OSDMap(2);
|
||||
im.Add("message_params", InstantMessageParams(fromAgent, message, toAgent,
|
||||
fromName, dialog, timeStamp, offline, parentEstateID,
|
||||
position, ttl, transactionID, fromGroup, binaryBucket));
|
||||
|
||||
im.Add("agent_params", AgentParams(fromAgent, checkEstate, godLevel, limitedToEstate));
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
|
||||
public static OSD ChatterboxInvitation(UUID sessionID, string sessionName,
|
||||
UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
|
||||
uint timeStamp, bool offline, int parentEstateID, Vector3 position,
|
||||
uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
|
||||
{
|
||||
OSDMap body = new OSDMap(5);
|
||||
body.Add("session_id", new OSDUUID(sessionID));
|
||||
body.Add("from_name", new OSDString(fromName));
|
||||
body.Add("session_name", new OSDString(sessionName));
|
||||
body.Add("from_id", new OSDUUID(fromAgent));
|
||||
|
||||
body.Add("instantmessage", InstantMessage(fromAgent, message, toAgent,
|
||||
fromName, dialog, timeStamp, offline, parentEstateID, position,
|
||||
ttl, transactionID, fromGroup, binaryBucket, true, 0, true));
|
||||
|
||||
OSDMap chatterboxInvitation = new OSDMap(2);
|
||||
chatterboxInvitation.Add("message", new OSDString("ChatterBoxInvitation"));
|
||||
chatterboxInvitation.Add("body", body);
|
||||
return chatterboxInvitation;
|
||||
}
|
||||
|
||||
public static OSD ChatterBoxSessionAgentListUpdates(UUID sessionID,
|
||||
UUID agentID, bool canVoiceChat, bool isModerator, bool textMute)
|
||||
{
|
||||
OSDMap body = new OSDMap();
|
||||
OSDMap agentUpdates = new OSDMap();
|
||||
OSDMap infoDetail = new OSDMap();
|
||||
OSDMap mutes = new OSDMap();
|
||||
|
||||
mutes.Add("text", OSD.FromBoolean(textMute));
|
||||
infoDetail.Add("can_voice_chat", OSD.FromBoolean(canVoiceChat));
|
||||
infoDetail.Add("is_moderator", OSD.FromBoolean(isModerator));
|
||||
infoDetail.Add("mutes", mutes);
|
||||
OSDMap info = new OSDMap();
|
||||
info.Add("info", infoDetail);
|
||||
agentUpdates.Add(agentID.ToString(), info);
|
||||
body.Add("agent_updates", agentUpdates);
|
||||
body.Add("session_id", OSD.FromUUID(sessionID));
|
||||
body.Add("updates", new OSD());
|
||||
|
||||
OSDMap chatterBoxSessionAgentListUpdates = new OSDMap();
|
||||
chatterBoxSessionAgentListUpdates.Add("message", OSD.FromString("ChatterBoxSessionAgentListUpdates"));
|
||||
chatterBoxSessionAgentListUpdates.Add("body", body);
|
||||
|
||||
return chatterBoxSessionAgentListUpdates;
|
||||
}
|
||||
|
||||
public static OSD GroupMembership(AgentGroupDataUpdatePacket groupUpdatePacket)
|
||||
{
|
||||
OSDMap groupUpdate = new OSDMap();
|
||||
groupUpdate.Add("message", OSD.FromString("AgentGroupDataUpdate"));
|
||||
|
||||
OSDMap body = new OSDMap();
|
||||
OSDArray agentData = new OSDArray();
|
||||
OSDMap agentDataMap = new OSDMap();
|
||||
agentDataMap.Add("AgentID", OSD.FromUUID(groupUpdatePacket.AgentData.AgentID));
|
||||
agentData.Add(agentDataMap);
|
||||
body.Add("AgentData", agentData);
|
||||
|
||||
OSDArray groupData = new OSDArray();
|
||||
|
||||
foreach (AgentGroupDataUpdatePacket.GroupDataBlock groupDataBlock in groupUpdatePacket.GroupData)
|
||||
{
|
||||
OSDMap groupDataMap = new OSDMap();
|
||||
groupDataMap.Add("ListInProfile", OSD.FromBoolean(false));
|
||||
groupDataMap.Add("GroupID", OSD.FromUUID(groupDataBlock.GroupID));
|
||||
groupDataMap.Add("GroupInsigniaID", OSD.FromUUID(groupDataBlock.GroupInsigniaID));
|
||||
groupDataMap.Add("Contribution", OSD.FromInteger(groupDataBlock.Contribution));
|
||||
groupDataMap.Add("GroupPowers", OSD.FromBinary(ulongToByteArray(groupDataBlock.GroupPowers)));
|
||||
groupDataMap.Add("GroupName", OSD.FromString(Utils.BytesToString(groupDataBlock.GroupName)));
|
||||
groupDataMap.Add("AcceptNotices", OSD.FromBoolean(groupDataBlock.AcceptNotices));
|
||||
|
||||
groupData.Add(groupDataMap);
|
||||
|
||||
}
|
||||
body.Add("GroupData", groupData);
|
||||
groupUpdate.Add("body", body);
|
||||
|
||||
return groupUpdate;
|
||||
}
|
||||
|
||||
public static OSD PlacesQuery(PlacesReplyPacket PlacesReply)
|
||||
{
|
||||
OSDMap placesReply = new OSDMap();
|
||||
placesReply.Add("message", OSD.FromString("PlacesReplyMessage"));
|
||||
|
||||
OSDMap body = new OSDMap();
|
||||
OSDArray agentData = new OSDArray();
|
||||
OSDMap agentDataMap = new OSDMap();
|
||||
agentDataMap.Add("AgentID", OSD.FromUUID(PlacesReply.AgentData.AgentID));
|
||||
agentDataMap.Add("QueryID", OSD.FromUUID(PlacesReply.AgentData.QueryID));
|
||||
agentDataMap.Add("TransactionID", OSD.FromUUID(PlacesReply.TransactionData.TransactionID));
|
||||
agentData.Add(agentDataMap);
|
||||
body.Add("AgentData", agentData);
|
||||
|
||||
OSDArray QueryData = new OSDArray();
|
||||
|
||||
foreach (PlacesReplyPacket.QueryDataBlock groupDataBlock in PlacesReply.QueryData)
|
||||
{
|
||||
OSDMap QueryDataMap = new OSDMap();
|
||||
QueryDataMap.Add("ActualArea", OSD.FromInteger(groupDataBlock.ActualArea));
|
||||
QueryDataMap.Add("BillableArea", OSD.FromInteger(groupDataBlock.BillableArea));
|
||||
QueryDataMap.Add("Description", OSD.FromBinary(groupDataBlock.Desc));
|
||||
QueryDataMap.Add("Dwell", OSD.FromInteger((int)groupDataBlock.Dwell));
|
||||
QueryDataMap.Add("Flags", OSD.FromString(Convert.ToString(groupDataBlock.Flags)));
|
||||
QueryDataMap.Add("GlobalX", OSD.FromInteger((int)groupDataBlock.GlobalX));
|
||||
QueryDataMap.Add("GlobalY", OSD.FromInteger((int)groupDataBlock.GlobalY));
|
||||
QueryDataMap.Add("GlobalZ", OSD.FromInteger((int)groupDataBlock.GlobalZ));
|
||||
QueryDataMap.Add("Name", OSD.FromBinary(groupDataBlock.Name));
|
||||
QueryDataMap.Add("OwnerID", OSD.FromUUID(groupDataBlock.OwnerID));
|
||||
QueryDataMap.Add("SimName", OSD.FromBinary(groupDataBlock.SimName));
|
||||
QueryDataMap.Add("SnapShotID", OSD.FromUUID(groupDataBlock.SnapshotID));
|
||||
QueryDataMap.Add("ProductSku", OSD.FromInteger(0));
|
||||
QueryDataMap.Add("Price", OSD.FromInteger(groupDataBlock.Price));
|
||||
|
||||
QueryData.Add(QueryDataMap);
|
||||
}
|
||||
body.Add("QueryData", QueryData);
|
||||
placesReply.Add("QueryData[]", body);
|
||||
|
||||
return placesReply;
|
||||
}
|
||||
|
||||
public static OSD ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage)
|
||||
{
|
||||
OSDMap message = new OSDMap();
|
||||
message.Add("message", OSD.FromString("ParcelProperties"));
|
||||
OSD message_body = parcelPropertiesMessage.Serialize();
|
||||
message.Add("body", message_body);
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -575,7 +575,7 @@ namespace OpenSim.Region.CoreModules.InterGrid
|
||||
string derezAvatarPath = "/agent/" + AvatarRezCapUUID + "/rez_avatar/derez";
|
||||
// Get a reference to the user's cap so we can pull out the Caps Object Path
|
||||
Caps userCap
|
||||
= homeScene.CapsModule.GetCapsHandlerForUser(agentData.AgentID);
|
||||
= homeScene.CapsModule.GetCapsForUser(agentData.AgentID);
|
||||
|
||||
string rezHttpProtocol = "http://";
|
||||
string regionCapsHttpProtocol = "http://";
|
||||
@@ -700,7 +700,7 @@ namespace OpenSim.Region.CoreModules.InterGrid
|
||||
{
|
||||
// Get a referenceokay - to their Cap object so we can pull out the capobjectroot
|
||||
Caps userCap
|
||||
= homeScene.CapsModule.GetCapsHandlerForUser(userData.AgentID);
|
||||
= homeScene.CapsModule.GetCapsForUser(userData.AgentID);
|
||||
|
||||
//Update the circuit data in the region so this user is authorized
|
||||
homeScene.UpdateCircuitData(userData);
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
<RegionModule id="PrimCountModule" type="OpenSim.Region.CoreModules.World.Land.PrimCountModule" />
|
||||
<RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" />
|
||||
<RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" />
|
||||
<RegionModule id="CapabilitiesModule" type="OpenSim.Region.CoreModules.Agent.Capabilities.CapabilitiesModule" />
|
||||
<RegionModule id="TerrainModule" type="OpenSim.Region.CoreModules.World.Terrain.TerrainModule" />
|
||||
<RegionModule id="WorldMapModule" type="OpenSim.Region.CoreModules.World.WorldMap.WorldMapModule" />
|
||||
<RegionModule id="Warp3DImageModule" type="OpenSim.Region.CoreModules.World.Warp3DMap.Warp3DImageModule" />
|
||||
|
||||
Reference in New Issue
Block a user