Merge branch 'master' into careminster

Conflicts:
	OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
avinationmerge
Melanie 2012-01-06 00:08:18 +00:00
commit fdfc4ab2a8
13 changed files with 571 additions and 183 deletions

View File

@ -0,0 +1,36 @@
/*
* 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 OpenMetaverse;
namespace OpenSim.Framework
{
public interface ISearchModule
{
}
}

View File

@ -133,18 +133,20 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
// Do Decode! // Do Decode!
if (decode) if (decode)
DoJ2KDecode(assetID, j2kData); Decode(assetID, j2kData);
} }
} }
/// <summary> public bool Decode(UUID assetID, byte[] j2kData)
/// Provides a synchronous decode so that caller can be assured that this executes before the next line
/// </summary>
/// <param name="assetID"></param>
/// <param name="j2kData"></param>
public void Decode(UUID assetID, byte[] j2kData)
{ {
DoJ2KDecode(assetID, j2kData); OpenJPEG.J2KLayerInfo[] layers;
int components;
return Decode(assetID, j2kData, out layers, out components);
}
public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
{
return DoJ2KDecode(assetID, j2kData, out layers, out components);
} }
#endregion IJ2KDecoder #endregion IJ2KDecoder
@ -154,14 +156,21 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
/// </summary> /// </summary>
/// <param name="assetID">UUID of Asset</param> /// <param name="assetID">UUID of Asset</param>
/// <param name="j2kData">JPEG2000 data</param> /// <param name="j2kData">JPEG2000 data</param>
private void DoJ2KDecode(UUID assetID, byte[] j2kData) /// <param name="layers">layer data</param>
/// <param name="components">number of components</param>
/// <returns>true if decode was successful. false otherwise.</returns>
private bool DoJ2KDecode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID); // "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID);
bool decodedSuccessfully = true;
//int DecodeTime = 0; //int DecodeTime = 0;
//DecodeTime = Environment.TickCount; //DecodeTime = Environment.TickCount;
OpenJPEG.J2KLayerInfo[] layers;
// We don't get this from CSJ2K. Is it relevant?
components = 0;
if (!TryLoadCacheForAsset(assetID, out layers)) if (!TryLoadCacheForAsset(assetID, out layers))
{ {
@ -196,14 +205,15 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
catch (Exception ex) catch (Exception ex)
{ {
m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message);
decodedSuccessfully = false;
} }
} }
else else
{ {
int components;
if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components)) if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components))
{ {
m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID); m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID);
decodedSuccessfully = false;
} }
} }
@ -212,6 +222,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults");
// Layer decoding completely failed. Guess at sane defaults for the layer boundaries // Layer decoding completely failed. Guess at sane defaults for the layer boundaries
layers = CreateDefaultLayers(j2kData.Length); layers = CreateDefaultLayers(j2kData.Length);
decodedSuccessfully = false;
} }
// Cache Decoded layers // Cache Decoded layers
@ -231,6 +242,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
m_notifyList.Remove(assetID); m_notifyList.Remove(assetID);
} }
} }
return decodedSuccessfully;
} }
private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength) private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength)

View File

@ -321,8 +321,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return (defonly ? false : true); return (defonly ? false : true);
} }
public void RequestRebake(IScenePresence sp, bool missingTexturesOnly) public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
{ {
int texturesRebaked = 0;
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{ {
int idx = AvatarAppearance.BAKE_INDICES[i]; int idx = AvatarAppearance.BAKE_INDICES[i];
@ -359,8 +361,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
face.TextureID, idx, sp.Name); face.TextureID, idx, sp.Name);
} }
texturesRebaked++;
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID); sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
} }
return texturesRebaked;
} }
#endregion #endregion

View File

@ -67,7 +67,7 @@ namespace OpenSim.Region.DataSnapshot
public void OnRegisterCaps(UUID agentID, Caps caps) public void OnRegisterCaps(UUID agentID, Caps caps)
{ {
m_log.Info("[DATASNAPSHOT]: Registering service discovery capability for " + agentID); // m_log.InfoFormat("[DATASNAPSHOT]: Registering service discovery capability for {0}", agentID);
string capsBase = "/CAPS/" + caps.CapsObjectPath; string capsBase = "/CAPS/" + caps.CapsObjectPath;
caps.RegisterHandler("PublicSnapshotDataInfo", caps.RegisterHandler("PublicSnapshotDataInfo",
new RestStreamHandler("POST", capsBase + m_discoveryPath, OnDiscoveryAttempt)); new RestStreamHandler("POST", capsBase + m_discoveryPath, OnDiscoveryAttempt));

View File

@ -82,7 +82,10 @@ namespace OpenSim.Region.Framework.Interfaces
/// If true, only request a rebake for the textures that are missing. /// If true, only request a rebake for the textures that are missing.
/// If false then we request a rebake of all textures for which we already have references. /// If false then we request a rebake of all textures for which we already have references.
/// </param> /// </param>
void RequestRebake(IScenePresence sp, bool missingTexturesOnly); /// <returns>
/// Number of rebake requests made. This will depend upon whether we've previously received texture IDs.
/// </returns>
int RequestRebake(IScenePresence sp, bool missingTexturesOnly);
void QueueAppearanceSend(UUID agentid); void QueueAppearanceSend(UUID agentid);
void QueueAppearanceSave(UUID agentid); void QueueAppearanceSave(UUID agentid);

View File

@ -35,6 +35,23 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IJ2KDecoder public interface IJ2KDecoder
{ {
void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback); void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback);
void Decode(UUID assetID, byte[] j2kData);
/// <summary>
/// Provides a synchronous decode so that caller can be assured that this executes before the next line
/// </summary>
/// <param name="assetID"></param>
/// <param name="j2kData"></param>
/// <returns>true if decode was successful. false otherwise.</returns>
bool Decode(UUID assetID, byte[] j2kData);
/// <summary>
/// Provides a synchronous decode so that caller can be assured that this executes before the next line
/// </summary>
/// <param name="assetID"></param>
/// <param name="j2kData"></param>
/// <param name="layers">layer data</param>
/// <param name="components">number of components</param>
/// <returns>true if decode was successful. false otherwise.</returns>
bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components);
} }
} }

View File

@ -0,0 +1,155 @@
/*
* 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.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.OptionalModules.Agent.TextureSender
{
/// <summary>
/// Commands for the J2KDecoder module. For debugging purposes.
/// </summary>
/// <remarks>
/// Placed here so that they can be removed if not required and to keep the J2KDecoder module itself simple.
/// </remarks>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "J2KDecoderCommandModule")]
public class J2KDecoderCommandModule : ISharedRegionModule
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
public string Name { get { return "Asset Information Module"; } }
public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source)
{
// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: INITIALIZED MODULE");
}
public void PostInitialise()
{
// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: POST INITIALIZED MODULE");
}
public void Close()
{
// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: CLOSED MODULE");
}
public void AddRegion(Scene scene)
{
// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
}
public void RemoveRegion(Scene scene)
{
// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
}
public void RegionLoaded(Scene scene)
{
// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
if (m_scene == null)
m_scene = scene;
MainConsole.Instance.Commands.AddCommand(
"j2k",
false,
"j2k decode",
"j2k decode <ID>",
"Do JPEG2000 decoding of an asset.",
"This is for debugging purposes. The asset id given must contain JPEG2000 data.",
HandleDecode);
}
void HandleDecode(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Usage is j2k decode <ID>");
return;
}
UUID assetId;
string rawAssetId = args[2];
if (!UUID.TryParse(rawAssetId, out assetId))
{
MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
return;
}
AssetBase asset = m_scene.AssetService.Get(assetId.ToString());
if (asset == null)
{
MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
return;
}
if (asset.Type != (sbyte)AssetType.Texture)
{
MainConsole.Instance.OutputFormat("ERROR: Asset {0} is not a texture type", assetId);
return;
}
IJ2KDecoder decoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
if (decoder == null)
{
MainConsole.Instance.OutputFormat("ERROR: No IJ2KDecoder module available");
return;
}
OpenJPEG.J2KLayerInfo[] layers;
int components;
if (decoder.Decode(assetId, asset.Data, out layers, out components))
{
MainConsole.Instance.OutputFormat(
"Successfully decoded asset {0} with {1} layers and {2} components",
assetId, layers.Length, components);
}
else
{
MainConsole.Instance.OutputFormat("Decode of asset {0} failed", assetId);
}
}
}
}

View File

@ -0,0 +1,185 @@
/*
* 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.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.OptionalModules.Asset
{
/// <summary>
/// A module that just holds commands for inspecting assets.
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AssetInfoModule")]
public class AssetInfoModule : ISharedRegionModule
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
public string Name { get { return "Asset Information Module"; } }
public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source)
{
// m_log.DebugFormat("[ASSET INFO MODULE]: INITIALIZED MODULE");
}
public void PostInitialise()
{
// m_log.DebugFormat("[ASSET INFO MODULE]: POST INITIALIZED MODULE");
}
public void Close()
{
// m_log.DebugFormat("[ASSET INFO MODULE]: CLOSED MODULE");
}
public void AddRegion(Scene scene)
{
// m_log.DebugFormat("[ASSET INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
}
public void RemoveRegion(Scene scene)
{
// m_log.DebugFormat("[ASSET INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
}
public void RegionLoaded(Scene scene)
{
// m_log.DebugFormat("[ASSET INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
if (m_scene == null)
m_scene = scene;
MainConsole.Instance.Commands.AddCommand(
"asset",
false,
"show asset",
"show asset <ID>",
"Show asset information",
HandleShowAsset);
MainConsole.Instance.Commands.AddCommand(
"asset", false, "dump asset",
"dump asset <id>",
"Dump an asset",
HandleDumpAsset);
}
void HandleDumpAsset(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Usage is dump asset <ID>");
return;
}
UUID assetId;
string rawAssetId = args[2];
if (!UUID.TryParse(rawAssetId, out assetId))
{
MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
return;
}
AssetBase asset = m_scene.AssetService.Get(assetId.ToString());
if (asset == null)
{
MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
return;
}
string fileName = rawAssetId;
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
bw.Write(asset.Data);
}
}
MainConsole.Instance.OutputFormat("Asset dumped to file {0}", fileName);
}
void HandleShowAsset(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Syntax: show asset <ID>");
return;
}
AssetBase asset = m_scene.AssetService.Get(args[2]);
if (asset == null || asset.Data.Length == 0)
{
MainConsole.Instance.Output("Asset not found");
return;
}
int i;
MainConsole.Instance.OutputFormat("Name: {0}", asset.Name);
MainConsole.Instance.OutputFormat("Description: {0}", asset.Description);
MainConsole.Instance.OutputFormat("Type: {0} (type number = {1})", (AssetType)asset.Type, asset.Type);
MainConsole.Instance.OutputFormat("Content-type: {0}", asset.Metadata.ContentType);
MainConsole.Instance.OutputFormat("Size: {0} bytes", asset.Data.Length);
MainConsole.Instance.OutputFormat("Temporary: {0}", asset.Temporary ? "yes" : "no");
MainConsole.Instance.OutputFormat("Flags: {0}", asset.Metadata.Flags);
for (i = 0 ; i < 5 ; i++)
{
int off = i * 16;
if (asset.Data.Length <= off)
break;
int len = 16;
if (asset.Data.Length < off + len)
len = asset.Data.Length - off;
byte[] line = new byte[len];
Array.Copy(asset.Data, off, line, 0, len);
string text = BitConverter.ToString(line);
MainConsole.Instance.Output(String.Format("{0:x4}: {1}", off, text));
}
}
}
}

View File

@ -240,11 +240,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
ScenePresence sp = scene.GetScenePresence(firstname, lastname); ScenePresence sp = scene.GetScenePresence(firstname, lastname);
if (sp != null && !sp.IsChildAgent) if (sp != null && !sp.IsChildAgent)
{ {
MainConsole.Instance.OutputFormat( int rebakesRequested = scene.AvatarFactory.RequestRebake(sp, false);
"Requesting rebake of uploaded textures for {0}",
sp.Name, scene.RegionInfo.RegionName);
scene.AvatarFactory.RequestRebake(sp, false); if (rebakesRequested > 0)
MainConsole.Instance.OutputFormat(
"Requesting rebake of {0} uploaded textures for {1} in {2}",
rebakesRequested, sp.Name, scene.RegionInfo.RegionName);
else
MainConsole.Instance.OutputFormat(
"No texture IDs available for rebake request for {0} in {1}",
sp.Name, scene.RegionInfo.RegionName);
} }
} }
} }

View File

@ -30,8 +30,7 @@ using OpenMetaverse;
using OpenMetaverse.Assets; using OpenMetaverse.Assets;
namespace OpenSim.Region.OptionalModules.Scripting.Minimodule namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
{ {
/// <summary> /// <summary>
/// This implements the methods needed to operate on individual inventory items. /// This implements the methods needed to operate on individual inventory items.
/// </summary> /// </summary>
@ -39,6 +38,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
{ {
int Type { get; } int Type { get; }
UUID AssetID { get; } UUID AssetID { get; }
T RetrieveAsset<T>() where T : Asset, new(); T RetrieveAsset<T>() where T : OpenMetaverse.Assets.Asset, new();
} }
} }

View File

@ -26,7 +26,11 @@
*/ */
using System; using System;
using System.IO;
using Nini.Config; using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Server.Base; using OpenSim.Server.Base;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
@ -67,6 +71,129 @@ namespace OpenSim.Server.Handlers.Asset
server.AddStreamHandler(new AssetServerGetHandler(m_AssetService)); server.AddStreamHandler(new AssetServerGetHandler(m_AssetService));
server.AddStreamHandler(new AssetServerPostHandler(m_AssetService)); server.AddStreamHandler(new AssetServerPostHandler(m_AssetService));
server.AddStreamHandler(new AssetServerDeleteHandler(m_AssetService, allowDelete)); server.AddStreamHandler(new AssetServerDeleteHandler(m_AssetService, allowDelete));
MainConsole.Instance.Commands.AddCommand("kfs", false,
"show asset",
"show asset <ID>",
"Show asset information",
HandleShowAsset);
MainConsole.Instance.Commands.AddCommand("kfs", false,
"delete asset",
"delete asset <ID>",
"Delete asset from database",
HandleDeleteAsset);
MainConsole.Instance.Commands.AddCommand("kfs", false,
"dump asset",
"dump asset <ID>",
"Dump asset to a file",
"The filename is the same as the ID given.",
HandleDumpAsset);
}
void HandleDeleteAsset(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Syntax: delete asset <ID>");
return;
}
AssetBase asset = m_AssetService.Get(args[2]);
if (asset == null || asset.Data.Length == 0)
{
MainConsole.Instance.Output("Asset not found");
return;
}
m_AssetService.Delete(args[2]);
//MainConsole.Instance.Output("Asset deleted");
// TODO: Implement this
MainConsole.Instance.Output("Asset deletion not supported by database");
}
void HandleDumpAsset(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Usage is dump asset <ID>");
return;
}
UUID assetId;
string rawAssetId = args[2];
if (!UUID.TryParse(rawAssetId, out assetId))
{
MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
return;
}
AssetBase asset = m_AssetService.Get(assetId.ToString());
if (asset == null)
{
MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
return;
}
string fileName = rawAssetId;
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
bw.Write(asset.Data);
}
}
MainConsole.Instance.OutputFormat("Asset dumped to file {0}", fileName);
}
void HandleShowAsset(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Syntax: show asset <ID>");
return;
}
AssetBase asset = m_AssetService.Get(args[2]);
if (asset == null || asset.Data.Length == 0)
{
MainConsole.Instance.Output("Asset not found");
return;
}
int i;
MainConsole.Instance.OutputFormat("Name: {0}", asset.Name);
MainConsole.Instance.OutputFormat("Description: {0}", asset.Description);
MainConsole.Instance.OutputFormat("Type: {0} (type number = {1})", (AssetType)asset.Type, asset.Type);
MainConsole.Instance.OutputFormat("Content-type: {0}", asset.Metadata.ContentType);
MainConsole.Instance.OutputFormat("Size: {0} bytes", asset.Data.Length);
MainConsole.Instance.OutputFormat("Temporary: {0}", asset.Temporary ? "yes" : "no");
MainConsole.Instance.OutputFormat("Flags: {0}", asset.Metadata.Flags);
for (i = 0 ; i < 5 ; i++)
{
int off = i * 16;
if (asset.Data.Length <= off)
break;
int len = 16;
if (asset.Data.Length < off + len)
len = asset.Data.Length - off;
byte[] line = new byte[len];
Array.Copy(asset.Data, off, line, 0, len);
string text = BitConverter.ToString(line);
MainConsole.Instance.Output(String.Format("{0:x4}: {1}", off, text));
}
} }
} }
} }

View File

@ -32,7 +32,6 @@ using System.Reflection;
using Nini.Config; using Nini.Config;
using log4net; using log4net;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Data; using OpenSim.Data;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenMetaverse; using OpenMetaverse;
@ -53,23 +52,6 @@ namespace OpenSim.Services.AssetService
{ {
m_RootInstance = this; m_RootInstance = this;
MainConsole.Instance.Commands.AddCommand("kfs", false,
"show digest",
"show digest <ID>",
"Show asset digest", HandleShowDigest);
MainConsole.Instance.Commands.AddCommand("kfs", false,
"delete asset",
"delete asset <ID>",
"Delete asset from database", HandleDeleteAsset);
MainConsole.Instance.Commands.AddCommand("kfs", false,
"dump asset",
"dump asset <ID>",
"Dump asset to a file",
"The filename is the same as the ID given.",
HandleDumpAsset);
if (m_AssetLoader != null) if (m_AssetLoader != null)
{ {
IConfig assetConfig = config.Configs["AssetService"]; IConfig assetConfig = config.Configs["AssetService"];
@ -221,111 +203,11 @@ namespace OpenSim.Services.AssetService
return m_Database.Delete(id); return m_Database.Delete(id);
} }
else else
{
m_log.DebugFormat("[ASSET SERVICE]: Request to delete asset {0}, but flags are not Maptile", id); m_log.DebugFormat("[ASSET SERVICE]: Request to delete asset {0}, but flags are not Maptile", id);
}
return false; return false;
} }
void HandleDumpAsset(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Usage is dump asset <ID>");
return;
}
string rawAssetId = args[2];
UUID assetId;
if (!UUID.TryParse(rawAssetId, out assetId))
{
MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
return;
}
AssetBase asset = m_Database.GetAsset(assetId);
if (asset == null)
{
MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
return;
}
string fileName = rawAssetId;
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
bw.Write(asset.Data);
}
}
MainConsole.Instance.OutputFormat("Asset dumped to file {0}", fileName);
}
void HandleShowDigest(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Syntax: show digest <ID>");
return;
}
AssetBase asset = Get(args[2]);
if (asset == null || asset.Data.Length == 0)
{
MainConsole.Instance.Output("Asset not found");
return;
}
int i;
MainConsole.Instance.OutputFormat("Name: {0}", asset.Name);
MainConsole.Instance.OutputFormat("Description: {0}", asset.Description);
MainConsole.Instance.OutputFormat("Type: {0} (type number = {1})", (AssetType)asset.Type, asset.Type);
MainConsole.Instance.OutputFormat("Content-type: {0}", asset.Metadata.ContentType);
MainConsole.Instance.OutputFormat("Flags: {0}", asset.Metadata.Flags);
for (i = 0 ; i < 5 ; i++)
{
int off = i * 16;
if (asset.Data.Length <= off)
break;
int len = 16;
if (asset.Data.Length < off + len)
len = asset.Data.Length - off;
byte[] line = new byte[len];
Array.Copy(asset.Data, off, line, 0, len);
string text = BitConverter.ToString(line);
MainConsole.Instance.Output(String.Format("{0:x4}: {1}", off, text));
}
}
void HandleDeleteAsset(string module, string[] args)
{
if (args.Length < 3)
{
MainConsole.Instance.Output("Syntax: delete asset <ID>");
return;
}
AssetBase asset = Get(args[2]);
if (asset == null || asset.Data.Length == 0)
{
MainConsole.Instance.Output("Asset not found");
return;
}
Delete(args[2]);
//MainConsole.Instance.Output("Asset deleted");
// TODO: Implement this
MainConsole.Instance.Output("Asset deletion not supported by database");
}
} }
} }

View File

@ -89,7 +89,6 @@ namespace OpenSim.Services.Connectors
m_log.Error("[ASSET CONNECTOR]: No Server URI named in section AssetService"); m_log.Error("[ASSET CONNECTOR]: No Server URI named in section AssetService");
throw new Exception("Asset connector init error"); throw new Exception("Asset connector init error");
} }
m_ServerURI = serviceURI;
MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset", MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset",
"dump asset <id> <file>", "dump asset <id> <file>",
@ -461,43 +460,5 @@ namespace OpenSim.Services.Connectors
} }
return false; return false;
} }
private void HandleDumpAsset(string module, string[] args)
{
if (args.Length != 4)
{
MainConsole.Instance.Output("Syntax: dump asset <id> <file>");
return;
}
UUID assetID;
if (!UUID.TryParse(args[2], out assetID))
{
MainConsole.Instance.Output("Invalid asset ID");
return;
}
if (m_Cache == null)
{
MainConsole.Instance.Output("Instance uses no cache");
return;
}
AssetBase asset = m_Cache.Get(assetID.ToString());
if (asset == null)
{
MainConsole.Instance.Output("Asset not found in cache");
return;
}
string fileName = args[3];
FileStream fs = File.Create(fileName);
fs.Write(asset.Data, 0, asset.Data.Length);
fs.Close();
}
} }
} }