Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs OpenSim/Region/Framework/Scenes/SceneObjectPart.csavinationmerge
commit
1ebc9d04aa
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 IProfileModule
|
||||
{
|
||||
void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID);
|
||||
|
||||
}
|
||||
}
|
|
@ -102,7 +102,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
m_currentPacket = 2;
|
||||
}
|
||||
|
||||
|
||||
while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket)
|
||||
{
|
||||
sendMore = SendPacket(client);
|
||||
|
@ -114,17 +114,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
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()
|
||||
{
|
||||
//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 (!m_assetRequested)
|
||||
{
|
||||
m_assetRequested = true;
|
||||
// m_log.DebugFormat("[J2KIMAGE]: Requesting asset {0}", TextureID);
|
||||
AssetService.Get(TextureID.ToString(), this, AssetReceived);
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +139,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
//Request decode
|
||||
m_decodeRequested = true;
|
||||
|
||||
// m_log.DebugFormat("[J2KIMAGE]: Requesting decode of asset {0}", TextureID);
|
||||
|
||||
// Do we have a jpeg decoder?
|
||||
if (J2KDecoder != null)
|
||||
{
|
||||
|
@ -149,7 +154,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// Send it off to the jpeg decoder
|
||||
J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -331,14 +335,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
if (m_currentPacket == 0)
|
||||
return 0;
|
||||
|
||||
if (m_currentPacket == 1)
|
||||
return FIRST_PACKET_SIZE;
|
||||
|
||||
int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
result = FIRST_PACKET_SIZE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -377,7 +382,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
UUID assetID = UUID.Zero;
|
||||
if (asset != null)
|
||||
{
|
||||
assetID = asset.FullID;
|
||||
}
|
||||
else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
|
||||
{
|
||||
// Unfortunately we need this here, there's no other way.
|
||||
|
@ -398,7 +405,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
|
||||
AssetDataCallback(assetID, asset);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -351,7 +351,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
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 Scene m_scene;
|
||||
protected LLImageManager m_imageManager;
|
||||
private LLImageManager m_imageManager;
|
||||
protected string m_firstName;
|
||||
protected string m_lastName;
|
||||
protected Thread m_clientThread;
|
||||
|
@ -522,8 +522,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
IsActive = false;
|
||||
|
||||
// Shutdown the image manager
|
||||
if (m_imageManager != null)
|
||||
m_imageManager.Close();
|
||||
m_imageManager.Close();
|
||||
|
||||
// Fire the callback for this connection closing
|
||||
if (OnConnectionClosed != null)
|
||||
|
@ -601,7 +600,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// Add a handler for the given packet type.
|
||||
/// </summary>
|
||||
/// <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.
|
||||
/// </remarks>
|
||||
/// <param name="packetType"></param>
|
||||
|
@ -3984,14 +3983,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
|
||||
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
||||
{
|
||||
ProcessTextureRequests();
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessTextureRequests()
|
||||
{
|
||||
if (m_imageManager != null)
|
||||
m_imageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
|
||||
}
|
||||
|
||||
|
@ -7540,12 +7531,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if ((ImageType)block.Type == ImageType.Baked)
|
||||
args.Priority *= 2.0f;
|
||||
|
||||
// in the end, we null this, so we have to check if it's null
|
||||
if (m_imageManager != null)
|
||||
{
|
||||
m_imageManager.EnqueueReq(args);
|
||||
}
|
||||
m_imageManager.EnqueueReq(args);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <param name="newRequest"></param>
|
||||
public void EnqueueReq(TextureRequestArgs newRequest)
|
||||
{
|
||||
//Make sure we're not shutting down..
|
||||
if (!m_shuttingdown)
|
||||
{
|
||||
J2KImage imgrequest;
|
||||
|
@ -99,19 +98,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
//m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
|
||||
m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
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}",
|
||||
// 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
|
||||
if (newRequest.requestSequence > imgrequest.LastSequence)
|
||||
{
|
||||
|
@ -126,11 +129,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
//Update the requested priority
|
||||
imgrequest.Priority = newRequest.Priority;
|
||||
|
||||
UpdateImageInQueue(imgrequest);
|
||||
|
||||
//Run an update
|
||||
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
|
||||
|
@ -142,6 +168,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
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}",
|
||||
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
||||
|
||||
|
@ -159,7 +189,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
//Add this download to the priority queue
|
||||
AddImageToQueue(imgrequest);
|
||||
|
||||
//Run an update
|
||||
imgrequest.RunUpdate();
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
// If null was returned, the texture priority queue is currently empty
|
||||
if (image == null)
|
||||
return false;
|
||||
break;
|
||||
|
||||
if (image.IsDecoded)
|
||||
{
|
||||
|
@ -194,10 +223,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// written. Undecoded textures should not be going into the priority
|
||||
// queue, because a high priority undecoded texture will clog up the
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -219,7 +255,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
if (m_priorityQueue.Count > 0)
|
||||
{
|
||||
try { image = m_priorityQueue.FindMax(); }
|
||||
try
|
||||
{
|
||||
image = m_priorityQueue.FindMax();
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +271,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); }
|
||||
try
|
||||
{
|
||||
m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +283,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
try { m_priorityQueue.Delete(image.PriorityQueueHandle); }
|
||||
try
|
||||
{
|
||||
m_priorityQueue.Delete(image.PriorityQueueHandle);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +295,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); }
|
||||
try
|
||||
{
|
||||
m_priorityQueue.Replace(image.PriorityQueueHandle, image);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
image.PriorityQueueHandle = null;
|
||||
|
|
|
@ -103,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
// If it's cached, return the cached results
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -156,7 +156,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
||||
// 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
|
||||
// update transaction. In theory, we should be able to do an immediate
|
||||
|
@ -250,15 +251,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
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>
|
||||
/// Queue up a request to send appearance.
|
||||
/// </summary>
|
||||
|
@ -292,17 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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)
|
||||
public bool ValidateBakedTextureCache(IScenePresence sp)
|
||||
{
|
||||
bool defonly = true; // are we only using default textures
|
||||
|
||||
|
@ -330,12 +312,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
defonly = false; // found a non-default texture reference
|
||||
|
||||
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
|
||||
{
|
||||
if (checkonly)
|
||||
return false;
|
||||
|
||||
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID);
|
||||
|
@ -344,6 +321,52 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
return (defonly ? false : true);
|
||||
}
|
||||
|
||||
public void RequestRebake(IScenePresence sp, bool missingTexturesOnly)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AvatarFactoryModule private methods
|
||||
|
||||
private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
|
||||
{
|
||||
if (sp.IsChildAgent)
|
||||
|
|
|
@ -43,7 +43,7 @@ using OpenSim.Services.Interfaces;
|
|||
namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class BasicProfileModule : ISharedRegionModule
|
||||
public class BasicProfileModule : IProfileModule, ISharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
|
@ -57,6 +57,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
|||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
// This can be reduced later as the loader will determine
|
||||
// whether we are needed
|
||||
if (config.Configs["Profile"] != null)
|
||||
{
|
||||
if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule")
|
||||
|
@ -65,14 +67,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
|||
|
||||
m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
|
||||
m_Enabled = true;
|
||||
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
|
||||
lock (m_Scenes)
|
||||
{
|
||||
if (!m_Scenes.Contains(scene))
|
||||
|
@ -80,6 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
|||
m_Scenes.Add(scene);
|
||||
// Hook up events
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.RegisterModuleInterface<IProfileModule>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +118,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
|||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
get { return typeof(IProfileModule); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -170,4 +172,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
public string LastName { get; set; }
|
||||
public string HomeURL { get; set; }
|
||||
public Dictionary<string, object> ServerURLs { get; set; }
|
||||
public string Title { get; set; }
|
||||
public int Flags { get; set; }
|
||||
public int Created { get; set; }
|
||||
}
|
||||
|
||||
public class UserManagementModule : ISharedRegionModule, IUserManagement
|
||||
|
@ -281,6 +284,94 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
public int GetUserFlags(UUID userID)
|
||||
{
|
||||
UserData userdata;
|
||||
lock (m_UserCache)
|
||||
m_UserCache.TryGetValue(userID, out userdata);
|
||||
|
||||
if (userdata.Flags == -1)
|
||||
GetUserInfo(userID);
|
||||
|
||||
if (userdata.Flags != -1)
|
||||
return userdata.Flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetUserCreated(UUID userID)
|
||||
{
|
||||
UserData userdata;
|
||||
lock (m_UserCache)
|
||||
m_UserCache.TryGetValue(userID, out userdata);
|
||||
|
||||
if (userdata.Flags == -1)
|
||||
GetUserInfo(userID);
|
||||
|
||||
if (userdata.Created != -1)
|
||||
return userdata.Created;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string GetUserTitle(UUID userID)
|
||||
{
|
||||
UserData userdata;
|
||||
lock (m_UserCache)
|
||||
m_UserCache.TryGetValue(userID, out userdata);
|
||||
|
||||
if (userdata.Flags == -1)
|
||||
GetUserInfo(userID);
|
||||
|
||||
if (userdata.Created != -1)
|
||||
return userdata.Title;
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// This will cache the user data
|
||||
// Change this to return bool
|
||||
private bool GetUserInfo(UUID userID)
|
||||
{
|
||||
UserData userdata;
|
||||
lock (m_UserCache)
|
||||
m_UserCache.TryGetValue(userID, out userdata);
|
||||
|
||||
if (userdata != null)
|
||||
{
|
||||
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Requested url type {0} for {1}", serverType, userID);
|
||||
|
||||
if (userdata.Flags >= 0)
|
||||
{
|
||||
// This is already populated
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[USER MANAGEMENT MODULE]: Requesting user flags from '{0}' for {1}",
|
||||
userdata.HomeURL, userID);
|
||||
|
||||
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
|
||||
Dictionary<string, object> info = uConn.GetUserInfo(userID);
|
||||
|
||||
// Pull our data now
|
||||
if (info["result"].ToString() == "success")
|
||||
{
|
||||
userdata.Flags = (int)info["user_flags"];
|
||||
userdata.Created = (int)info["user_created"];
|
||||
userdata.Title = (string)info["user_title"];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public string GetUserUUI(UUID userID)
|
||||
{
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
|
||||
|
@ -352,6 +443,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
{
|
||||
UserData user = new UserData();
|
||||
user.Id = id;
|
||||
user.Flags = -1;
|
||||
user.Created = -1;
|
||||
|
||||
if (creatorData != null && creatorData != string.Empty)
|
||||
{
|
||||
|
|
|
@ -61,7 +61,29 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <returns>true if a valid agent was found, false otherwise</returns>
|
||||
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);
|
||||
|
||||
/// <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>
|
||||
void RequestRebake(IScenePresence sp, bool missingTexturesOnly);
|
||||
|
||||
void QueueAppearanceSend(UUID agentid);
|
||||
void QueueAppearanceSave(UUID agentid);
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
string GetUserHomeURL(UUID uuid);
|
||||
string GetUserUUI(UUID uuid);
|
||||
string GetUserServerURL(UUID uuid, string serverType);
|
||||
int GetUserFlags(UUID userID);
|
||||
int GetUserCreated(UUID userID);
|
||||
string GetUserTitle(UUID userID);
|
||||
|
||||
/// <summary>
|
||||
/// Add a user.
|
||||
|
|
|
@ -405,6 +405,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public delegate void RegionUp(GridRegion region);
|
||||
public event RegionUp OnRegionUp;
|
||||
|
||||
public delegate void RegionStarted(Scene scene);
|
||||
public event RegionStarted OnRegionStarted;
|
||||
|
||||
public delegate void LoginsEnabled(string regionName);
|
||||
public event LoginsEnabled OnLoginsEnabled;
|
||||
|
||||
|
@ -2267,6 +2270,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)
|
||||
{
|
||||
LoginsEnabled handler = OnLoginsEnabled;
|
||||
|
|
|
@ -1236,6 +1236,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
try
|
||||
{
|
||||
m_eventManager.TriggerOnRegionStarted(this);
|
||||
while (!shuttingdown)
|
||||
Update();
|
||||
}
|
||||
|
|
|
@ -2015,13 +2015,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
axPos *= parentRot;
|
||||
Vector3 translationOffsetPosition = axPos;
|
||||
if(_parentID == 0)
|
||||
{
|
||||
return GroupPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
|
||||
}
|
||||
return GroupPosition;
|
||||
else
|
||||
return ParentGroup.AbsolutePosition + translationOffsetPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2855,7 +2855,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Velocity = Vector3.Zero;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1279,7 +1279,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
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
|
||||
{
|
||||
|
@ -1333,7 +1333,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)
|
||||
{
|
||||
|
@ -1508,7 +1508,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
return obj;
|
||||
}
|
||||
|
||||
static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name)
|
||||
public static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name)
|
||||
{
|
||||
TaskInventoryDictionary tinv = new TaskInventoryDictionary();
|
||||
|
||||
|
@ -1548,7 +1548,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
/// <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>
|
||||
/// <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;
|
||||
|
||||
|
|
|
@ -114,6 +114,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
|
|||
"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.",
|
||||
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)
|
||||
|
@ -210,6 +220,34 @@ 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)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Requesting rebake of uploaded textures for {0}",
|
||||
sp.Name, scene.RegionInfo.RegionName);
|
||||
|
||||
scene.AvatarFactory.RequestRebake(sp, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -91,6 +91,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
|
|||
|
||||
server.AddXmlRPCHandler("status_notification", StatusNotification, false);
|
||||
server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false);
|
||||
server.AddXmlRPCHandler("get_user_info", GetUserInfo, false);
|
||||
server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false);
|
||||
|
||||
server.AddXmlRPCHandler("locate_user", LocateUser, false);
|
||||
|
@ -299,6 +300,38 @@ namespace OpenSim.Server.Handlers.Hypergrid
|
|||
|
||||
}
|
||||
|
||||
public XmlRpcResponse GetUserInfo(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
// This needs checking!
|
||||
if (requestData.ContainsKey("userID"))
|
||||
{
|
||||
string userID_str = (string)requestData["userID"];
|
||||
UUID userID = UUID.Zero;
|
||||
UUID.TryParse(userID_str, out userID);
|
||||
|
||||
//int userFlags = m_HomeUsersService.GetUserFlags(userID);
|
||||
Dictionary<string,object> userInfo = m_HomeUsersService.GetUserInfo(userID);
|
||||
if (userInfo.Count > 0)
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in userInfo)
|
||||
{
|
||||
hash[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hash["result"] = "failure";
|
||||
}
|
||||
}
|
||||
|
||||
XmlRpcResponse response = new XmlRpcResponse();
|
||||
response.Value = hash;
|
||||
return response;
|
||||
}
|
||||
|
||||
public XmlRpcResponse GetServerURLs(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
|
|
|
@ -559,6 +559,60 @@ namespace OpenSim.Services.Connectors.Hypergrid
|
|||
return online;
|
||||
}
|
||||
|
||||
public Dictionary<string,object> GetUserInfo (UUID userID)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
hash["userID"] = userID.ToString();
|
||||
|
||||
IList paramList = new ArrayList();
|
||||
paramList.Add(hash);
|
||||
|
||||
XmlRpcRequest request = new XmlRpcRequest("get_user_info", paramList);
|
||||
|
||||
Dictionary<string, object> info = new Dictionary<string, object>();
|
||||
XmlRpcResponse response = null;
|
||||
try
|
||||
{
|
||||
response = request.Send(m_ServerURL, 10000);
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUserInfo", m_ServerURL);
|
||||
return info;
|
||||
}
|
||||
|
||||
if (response.IsFault)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString);
|
||||
return info;
|
||||
}
|
||||
|
||||
hash = (Hashtable)response.Value;
|
||||
try
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUserInfo Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
|
||||
return info;
|
||||
}
|
||||
|
||||
// Here is the actual response
|
||||
foreach (object key in hash.Keys)
|
||||
{
|
||||
if (hash[key] != null)
|
||||
{
|
||||
info.Add(key.ToString(), hash[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetServerURLs(UUID userID)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
|
|
|
@ -486,6 +486,31 @@ namespace OpenSim.Services.HypergridService
|
|||
return online;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetUserInfo(UUID userID)
|
||||
{
|
||||
Dictionary<string, object> info = new Dictionary<string, object>();
|
||||
|
||||
if (m_UserAccountService == null)
|
||||
{
|
||||
m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get user flags because user account service is missing");
|
||||
info["result"] = "fail";
|
||||
info["message"] = "UserAccountService is missing!";
|
||||
return info;
|
||||
}
|
||||
|
||||
UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
|
||||
|
||||
if (account != null)
|
||||
{
|
||||
info.Add("user_flags", (object)account.UserFlags);
|
||||
info.Add("user_created", (object)account.Created);
|
||||
info.Add("user_title", (object)account.UserTitle);
|
||||
info.Add("result", "success");
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetServerURLs(UUID userID)
|
||||
{
|
||||
if (m_UserAccountService == null)
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace OpenSim.Services.Interfaces
|
|||
void LogoutAgent(UUID userID, UUID sessionID);
|
||||
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
|
||||
Dictionary<string, object> GetServerURLs(UUID userID);
|
||||
Dictionary<string,object> GetUserInfo(UUID userID);
|
||||
|
||||
string LocateUser(UUID userID);
|
||||
// Tries to get the universal user identifier for the targetUserId
|
||||
|
|
|
@ -112,10 +112,10 @@ namespace pCampBot
|
|||
" -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" +
|
||||
" -password password for the bots\n" +
|
||||
" -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" +
|
||||
" current options are:" +
|
||||
" p (physics)" +
|
||||
" g (grab)" +
|
||||
" t (teleport)" +
|
||||
" current options are:\n" +
|
||||
" p (physics)\n" +
|
||||
" g (grab)\n" +
|
||||
" t (teleport)\n" +
|
||||
// " c (cross)" +
|
||||
" -wear set appearance folder to load from (default: no)\n" +
|
||||
" -h, -help show this message");
|
||||
|
|
BIN
bin/C5.dll
BIN
bin/C5.dll
Binary file not shown.
Loading…
Reference in New Issue