Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

iar_mods
BlueWall 2012-01-05 17:54:51 -05:00
commit f252161941
22 changed files with 730 additions and 267 deletions

View File

@ -102,7 +102,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_currentPacket = 2; m_currentPacket = 2;
} }
while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket) while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket)
{ {
sendMore = SendPacket(client); sendMore = SendPacket(client);
@ -114,17 +114,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return (m_currentPacket > m_stopPacket); return (m_currentPacket > m_stopPacket);
} }
/// <summary>
/// This is where we decide what we need to update
/// and assign the real discardLevel and packetNumber
/// assuming of course that the connected client might be bonkers
/// </summary>
public void RunUpdate() public void RunUpdate()
{ {
//This is where we decide what we need to update
//and assign the real discardLevel and packetNumber
//assuming of course that the connected client might be bonkers
if (!HasAsset) if (!HasAsset)
{ {
if (!m_assetRequested) if (!m_assetRequested)
{ {
m_assetRequested = true; m_assetRequested = true;
// m_log.DebugFormat("[J2KIMAGE]: Requesting asset {0}", TextureID);
AssetService.Get(TextureID.ToString(), this, AssetReceived); AssetService.Get(TextureID.ToString(), this, AssetReceived);
} }
} }
@ -137,6 +139,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
//Request decode //Request decode
m_decodeRequested = true; m_decodeRequested = true;
// m_log.DebugFormat("[J2KIMAGE]: Requesting decode of asset {0}", TextureID);
// Do we have a jpeg decoder? // Do we have a jpeg decoder?
if (J2KDecoder != null) if (J2KDecoder != null)
{ {
@ -149,7 +154,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Send it off to the jpeg decoder // Send it off to the jpeg decoder
J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback); J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
} }
} }
else else
{ {
@ -328,14 +332,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (m_currentPacket == 0) if (m_currentPacket == 0)
return 0; return 0;
if (m_currentPacket == 1) if (m_currentPacket == 1)
return FIRST_PACKET_SIZE; return FIRST_PACKET_SIZE;
int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE; int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
if (result < 0) if (result < 0)
{
result = FIRST_PACKET_SIZE; result = FIRST_PACKET_SIZE;
}
return result; return result;
} }
@ -374,7 +379,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
UUID assetID = UUID.Zero; UUID assetID = UUID.Zero;
if (asset != null) if (asset != null)
{
assetID = asset.FullID; assetID = asset.FullID;
}
else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule)) else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
{ {
// Unfortunately we need this here, there's no other way. // Unfortunately we need this here, there's no other way.
@ -395,7 +402,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
AssetDataCallback(assetID, asset); AssetDataCallback(assetID, asset);
} }
} }
} }

View File

@ -348,7 +348,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
protected Scene m_scene; protected Scene m_scene;
protected LLImageManager m_imageManager; private LLImageManager m_imageManager;
protected string m_firstName; protected string m_firstName;
protected string m_lastName; protected string m_lastName;
protected Thread m_clientThread; protected Thread m_clientThread;
@ -499,8 +499,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
IsActive = false; IsActive = false;
// Shutdown the image manager // Shutdown the image manager
if (m_imageManager != null) m_imageManager.Close();
m_imageManager.Close();
// Fire the callback for this connection closing // Fire the callback for this connection closing
if (OnConnectionClosed != null) if (OnConnectionClosed != null)
@ -578,7 +577,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Add a handler for the given packet type. /// Add a handler for the given packet type.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// The packet is handled on its own thread. If packets must be handled in the order in which thye /// The packet is handled on its own thread. If packets must be handled in the order in which they
/// are received then please use the synchronous version of this method. /// are received then please use the synchronous version of this method.
/// </remarks> /// </remarks>
/// <param name="packetType"></param> /// <param name="packetType"></param>
@ -3940,14 +3939,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
{
ProcessTextureRequests();
}
}
void ProcessTextureRequests()
{
if (m_imageManager != null)
m_imageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); m_imageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
} }
@ -7479,12 +7470,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if ((ImageType)block.Type == ImageType.Baked) if ((ImageType)block.Type == ImageType.Baked)
args.Priority *= 2.0f; args.Priority *= 2.0f;
// in the end, we null this, so we have to check if it's null m_imageManager.EnqueueReq(args);
if (m_imageManager != null)
{
m_imageManager.EnqueueReq(args);
}
} }
return true; return true;
} }

View File

@ -84,7 +84,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name="newRequest"></param> /// <param name="newRequest"></param>
public void EnqueueReq(TextureRequestArgs newRequest) public void EnqueueReq(TextureRequestArgs newRequest)
{ {
//Make sure we're not shutting down..
if (!m_shuttingdown) if (!m_shuttingdown)
{ {
J2KImage imgrequest; J2KImage imgrequest;
@ -99,19 +98,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
//m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID); //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);
try try
{ {
lock (m_syncRoot) lock (m_syncRoot)
m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
} }
catch (Exception) { } catch (Exception) { }
} }
else else
{ {
// m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Received duplicate of existing request for {0}, start packet {1} from {2}",
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
//m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}", //m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
//Check the packet sequence to make sure this isn't older than //Check the packet sequence to make sure this isn't older than
//one we've already received //one we've already received
if (newRequest.requestSequence > imgrequest.LastSequence) if (newRequest.requestSequence > imgrequest.LastSequence)
{ {
@ -126,11 +129,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//Update the requested priority //Update the requested priority
imgrequest.Priority = newRequest.Priority; imgrequest.Priority = newRequest.Priority;
UpdateImageInQueue(imgrequest); UpdateImageInQueue(imgrequest);
//Run an update
imgrequest.RunUpdate(); imgrequest.RunUpdate();
// J2KImage imgrequest2 = new J2KImage(this);
// imgrequest2.J2KDecoder = m_j2kDecodeModule;
// imgrequest2.AssetService = m_assetCache;
// imgrequest2.AgentID = m_client.AgentId;
// imgrequest2.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
// imgrequest2.DiscardLevel = newRequest.DiscardLevel;
// imgrequest2.StartPacket = Math.Max(1, newRequest.PacketNumber);
// imgrequest2.Priority = newRequest.Priority;
// imgrequest2.TextureID = newRequest.RequestedAssetID;
// imgrequest2.Priority = newRequest.Priority;
//
// //Add this download to the priority queue
// AddImageToQueue(imgrequest2);
//
// imgrequest2.RunUpdate();
} }
// else
// {
// m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Ignoring duplicate of existing request for {0} (sequence {1}) from {2} as its request sequence {3} is not greater",
// newRequest.RequestedAssetID, imgrequest.LastSequence, m_client.Name, newRequest.requestSequence);
// }
} }
} }
else else
@ -142,6 +168,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
// m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Received request for {0}, start packet {1} from {2}",
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
//m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}", //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
@ -159,7 +189,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//Add this download to the priority queue //Add this download to the priority queue
AddImageToQueue(imgrequest); AddImageToQueue(imgrequest);
//Run an update
imgrequest.RunUpdate(); imgrequest.RunUpdate();
} }
} }
@ -176,7 +205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// If null was returned, the texture priority queue is currently empty // If null was returned, the texture priority queue is currently empty
if (image == null) if (image == null)
return false; break;
if (image.IsDecoded) if (image.IsDecoded)
{ {
@ -194,10 +223,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// written. Undecoded textures should not be going into the priority // written. Undecoded textures should not be going into the priority
// queue, because a high priority undecoded texture will clog up the // queue, because a high priority undecoded texture will clog up the
// pipeline for a client // pipeline for a client
return true; // m_log.DebugFormat(
// "[LL IMAGE MANAGER]: Exiting image queue processing early on encountering undecoded image {0}",
// image.TextureID);
break;
} }
} }
// if (packetsSent != 0)
// m_log.DebugFormat("[LL IMAGE MANAGER]: Processed {0} packets from image queue", packetsSent);
return m_priorityQueue.Count > 0; return m_priorityQueue.Count > 0;
} }
@ -219,7 +255,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (m_priorityQueue.Count > 0) if (m_priorityQueue.Count > 0)
{ {
try { image = m_priorityQueue.FindMax(); } try
{
image = m_priorityQueue.FindMax();
}
catch (Exception) { } catch (Exception) { }
} }
} }
@ -232,7 +271,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
lock (m_syncRoot) lock (m_syncRoot)
{ {
try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); } try
{
m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
}
catch (Exception) { } catch (Exception) { }
} }
} }
@ -241,7 +283,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
lock (m_syncRoot) lock (m_syncRoot)
{ {
try { m_priorityQueue.Delete(image.PriorityQueueHandle); } try
{
m_priorityQueue.Delete(image.PriorityQueueHandle);
}
catch (Exception) { } catch (Exception) { }
} }
} }
@ -250,7 +295,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
lock (m_syncRoot) lock (m_syncRoot)
{ {
try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } try
{
m_priorityQueue.Replace(image.PriorityQueueHandle, image);
}
catch (Exception) catch (Exception)
{ {
image.PriorityQueueHandle = null; image.PriorityQueueHandle = null;

View File

@ -103,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
// If it's cached, return the cached results // If it's cached, return the cached results
if (m_decodedCache.TryGetValue(assetID, out result)) if (m_decodedCache.TryGetValue(assetID, out result))
{ {
// m_log.DebugFormat(
// "[J2KDecoderModule]: Returning existing cached {0} layers j2k decode for {1}",
// result.Length, assetID);
callback(assetID, result); callback(assetID, result);
} }
else else
@ -133,14 +137,9 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
} }
} }
/// <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); return DoJ2KDecode(assetID, j2kData);
} }
#endregion IJ2KDecoder #endregion IJ2KDecoder
@ -150,11 +149,13 @@ 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) private bool DoJ2KDecode(UUID assetID, byte[] j2kData)
{ {
// 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; OpenJPEG.J2KLayerInfo[] layers;
@ -192,6 +193,7 @@ 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
@ -200,6 +202,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
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;
} }
} }
@ -208,6 +211,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
@ -227,6 +231,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

@ -156,7 +156,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
// WriteBakedTexturesReport(sp, m_log.DebugFormat); // WriteBakedTexturesReport(sp, m_log.DebugFormat);
ValidateBakedTextureCache(sp, false); if (!ValidateBakedTextureCache(sp))
RequestRebake(sp, true);
// This appears to be set only in the final stage of the appearance // This appears to be set only in the final stage of the appearance
// update transaction. In theory, we should be able to do an immediate // update transaction. In theory, we should be able to do an immediate
@ -250,15 +251,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return true; return true;
} }
/// <summary>
/// Check for the existence of the baked texture assets.
/// </summary>
/// <param name="sp"></param>
public bool ValidateBakedTextureCache(IScenePresence sp)
{
return ValidateBakedTextureCache(sp, true);
}
/// <summary> /// <summary>
/// Queue up a request to send appearance. /// Queue up a request to send appearance.
/// </summary> /// </summary>
@ -292,17 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
} }
} }
#endregion public bool ValidateBakedTextureCache(IScenePresence sp)
#region AvatarFactoryModule private methods
/// <summary>
/// Check for the existence of the baked texture assets. Request a rebake
/// unless checkonly is true.
/// </summary>
/// <param name="client"></param>
/// <param name="checkonly"></param>
private bool ValidateBakedTextureCache(IScenePresence sp, bool checkonly)
{ {
bool defonly = true; // are we only using default textures bool defonly = true; // are we only using default textures
@ -330,16 +312,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
defonly = false; // found a non-default texture reference defonly = false; // found a non-default texture reference
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
{ return false;
if (checkonly)
return false;
m_log.DebugFormat(
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
face.TextureID, idx, sp.Name);
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
}
} }
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID); m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID);
@ -348,6 +321,57 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return (defonly ? false : true); return (defonly ? false : true);
} }
public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
{
int texturesRebaked = 0;
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
// if there is no texture entry, skip it
if (face == null)
continue;
// m_log.DebugFormat(
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
// face.TextureID, idx, client.Name, client.AgentId);
// if the texture is one of the "defaults" then skip it
// this should probably be more intelligent (skirt texture doesnt matter
// if the avatar isnt wearing a skirt) but if any of the main baked
// textures is default then the rest should be as well
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
continue;
if (missingTexturesOnly)
{
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
continue;
else
m_log.DebugFormat(
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
face.TextureID, idx, sp.Name);
}
else
{
m_log.DebugFormat(
"[AVFACTORY]: Requesting rebake of {0} ({1}) for {2}.",
face.TextureID, idx, sp.Name);
}
texturesRebaked++;
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
}
return texturesRebaked;
}
#endregion
#region AvatarFactoryModule private methods
private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp) private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
{ {
if (sp.IsChildAgent) if (sp.IsChildAgent)

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

@ -61,7 +61,32 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>true if a valid agent was found, false otherwise</returns> /// <returns>true if a valid agent was found, false otherwise</returns>
bool SaveBakedTextures(UUID agentId); bool SaveBakedTextures(UUID agentId);
/// <summary>
/// Validate that OpenSim can find the baked textures need to display a given avatar
/// </summary>
/// <param name="client"></param>
/// <param name="checkonly"></param>
/// <returns>
/// true if all the baked textures referenced by the texture IDs exist or the appearance is only using default textures. false otherwise.
/// </returns>
bool ValidateBakedTextureCache(IScenePresence sp); bool ValidateBakedTextureCache(IScenePresence sp);
/// <summary>
/// Request a rebake of textures for an avatar.
/// </summary>
/// <remarks>
/// This will send the request to the viewer, since it's there that the rebake is done.
/// </remarks>
/// <param name="sp">Avatar to rebake.</param>
/// <param name="missingTexturesOnly">
/// 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.
/// </param>
/// <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,13 @@ 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);
} }
} }

View File

@ -401,6 +401,9 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void RegionUp(GridRegion region); public delegate void RegionUp(GridRegion region);
public event RegionUp OnRegionUp; public event RegionUp OnRegionUp;
public delegate void RegionStarted(Scene scene);
public event RegionStarted OnRegionStarted;
public delegate void LoginsEnabled(string regionName); public delegate void LoginsEnabled(string regionName);
public event LoginsEnabled OnLoginsEnabled; public event LoginsEnabled OnLoginsEnabled;
@ -2243,6 +2246,27 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerOnRegionStarted(Scene scene)
{
RegionStarted handler = OnRegionStarted;
if (handler != null)
{
foreach (RegionStarted d in handler.GetInvocationList())
{
try
{
d(scene);
}
catch (Exception e)
{
m_log.ErrorFormat("[EVENT MANAGER]: Delegate for RegionStarted failed - continuing {0} - {1}",
e.Message, e.StackTrace);
}
}
}
}
public void TriggerLoginsEnabled (string regionName) public void TriggerLoginsEnabled (string regionName)
{ {
LoginsEnabled handler = OnLoginsEnabled; LoginsEnabled handler = OnLoginsEnabled;

View File

@ -1194,6 +1194,7 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
m_eventManager.TriggerOnRegionStarted(this);
while (!shuttingdown) while (!shuttingdown)
Update(); Update();

View File

@ -1960,19 +1960,13 @@ namespace OpenSim.Region.Framework.Scenes
public Vector3 GetWorldPosition() public Vector3 GetWorldPosition()
{ {
Quaternion parentRot = ParentGroup.RootPart.RotationOffset; Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
Vector3 axPos = OffsetPosition; Vector3 axPos = OffsetPosition;
axPos *= parentRot; axPos *= parentRot;
Vector3 translationOffsetPosition = axPos; Vector3 translationOffsetPosition = axPos;
if(_parentID == 0)
// m_log.DebugFormat("[SCENE OBJECT PART]: Found group pos {0} for part {1}", GroupPosition, Name); return GroupPosition;
else
Vector3 worldPos = GroupPosition + translationOffsetPosition; return ParentGroup.AbsolutePosition + translationOffsetPosition;
// m_log.DebugFormat("[SCENE OBJECT PART]: Found world pos {0} for part {1}", worldPos, Name);
return worldPos;
} }
/// <summary> /// <summary>

View File

@ -2844,7 +2844,7 @@ namespace OpenSim.Region.Framework.Scenes
Velocity = Vector3.Zero; Velocity = Vector3.Zero;
AbsolutePosition = pos; AbsolutePosition = pos;
m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition); // m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition);
AddToPhysicalScene(isFlying); AddToPhysicalScene(isFlying);
} }

View File

@ -1263,7 +1263,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString(name, flagsStr.Replace(",", "")); writer.WriteElementString(name, flagsStr.Replace(",", ""));
} }
static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene) public static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene)
{ {
if (tinv.Count > 0) // otherwise skip this if (tinv.Count > 0) // otherwise skip this
{ {
@ -1317,7 +1317,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
static void WriteShape(XmlTextWriter writer, PrimitiveBaseShape shp, Dictionary<string, object> options) public static void WriteShape(XmlTextWriter writer, PrimitiveBaseShape shp, Dictionary<string, object> options)
{ {
if (shp != null) if (shp != null)
{ {
@ -1492,7 +1492,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
return obj; return obj;
} }
static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name) public static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name)
{ {
TaskInventoryDictionary tinv = new TaskInventoryDictionary(); TaskInventoryDictionary tinv = new TaskInventoryDictionary();
@ -1538,7 +1538,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
/// <param name="name">The name of the xml element containing the shape</param> /// <param name="name">The name of the xml element containing the shape</param>
/// <param name="errors">true if any errors were encountered during parsing, false otherwise</param> /// <param name="errors">true if any errors were encountered during parsing, false otherwise</param>
/// <returns>The shape parsed</returns> /// <returns>The shape parsed</returns>
static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors) public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
{ {
errors = false; errors = false;

View File

@ -0,0 +1,145 @@
/*
* 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.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;
}
if (decoder.Decode(assetId, asset.Data))
MainConsole.Instance.OutputFormat("Successfully decoded asset {0}", assetId);
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

@ -114,6 +114,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
"Send appearance data for each avatar in the simulator to other viewers.", "Send appearance data for each avatar in the simulator to other viewers.",
"Optionally, you can specify that only a particular avatar's appearance data is sent.", "Optionally, you can specify that only a particular avatar's appearance data is sent.",
HandleSendAppearanceCommand); HandleSendAppearanceCommand);
scene.AddCommand(
this, "appearance rebake",
"appearance rebake <first-name> <last-name>",
"Send a request to the user's viewer for it to rebake and reupload its appearance textures.",
"This is currently done for all baked texture references previously received, whether the simulator can find the asset or not."
+ "\nThis will only work for texture ids that the viewer has already uploaded."
+ "\nIf the viewer has not yet sent the server any texture ids then nothing will happen"
+ "\nsince requests can only be made for ids that the client has already sent us",
HandleRebakeAppearanceCommand);
} }
private void HandleSendAppearanceCommand(string module, string[] cmd) private void HandleSendAppearanceCommand(string module, string[] cmd)
@ -210,6 +220,39 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
} }
} }
} }
} }
private void HandleRebakeAppearanceCommand(string module, string[] cmd)
{
if (cmd.Length != 4)
{
MainConsole.Instance.OutputFormat("Usage: appearance rebake <first-name> <last-name>");
return;
}
string firstname = cmd[2];
string lastname = cmd[3];
lock (m_scenes)
{
foreach (Scene scene in m_scenes.Values)
{
ScenePresence sp = scene.GetScenePresence(firstname, lastname);
if (sp != null && !sp.IsChildAgent)
{
int rebakesRequested = 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"];
@ -218,111 +200,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

@ -86,11 +86,8 @@ 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", m_ServerURI = serviceURI;
"dump asset <id> <file>",
"dump one cached asset", HandleDumpAsset);
} }
protected void SetCache(IImprovedAssetCache cache) protected void SetCache(IImprovedAssetCache cache)
@ -328,43 +325,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();
}
} }
} }

View File

@ -112,10 +112,10 @@ namespace pCampBot
" -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" + " -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" +
" -password password for the bots\n" + " -password password for the bots\n" +
" -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" + " -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" +
" current options are:" + " current options are:\n" +
" p (physics)" + " p (physics)\n" +
" g (grab)" + " g (grab)\n" +
" t (teleport)" + " t (teleport)\n" +
// " c (cross)" + // " c (cross)" +
" -wear set appearance folder to load from (default: no)\n" + " -wear set appearance folder to load from (default: no)\n" +
" -h, -help show this message"); " -h, -help show this message");

Binary file not shown.