diff --git a/OpenSim/Framework/IProfileModule.cs b/OpenSim/Framework/IProfileModule.cs
new file mode 100644
index 0000000000..ef03d4a62a
--- /dev/null
+++ b/OpenSim/Framework/IProfileModule.cs
@@ -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);
+
+ }
+}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index 2bbc6c7477..8aa2ff3018 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -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);
}
+ ///
+ /// 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
+ ///
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);
-
}
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 083dcc0b0c..4d3a30ccd2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -351,7 +351,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected Dictionary m_packetHandlers = new Dictionary();
protected Dictionary m_genericPacketHandlers = new Dictionary(); //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.
///
///
- /// 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.
///
///
@@ -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;
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
index e3a881f790..3e31b7d9cc 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
@@ -84,7 +84,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
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();
+// 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;
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index 7dd90874b6..14dee84c24 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -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
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index bc7bf664c2..9df0592d4c 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -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;
}
- ///
- /// Check for the existence of the baked texture assets.
- ///
- ///
- public bool ValidateBakedTextureCache(IScenePresence sp)
- {
- return ValidateBakedTextureCache(sp, true);
- }
-
///
/// Queue up a request to send appearance.
///
@@ -292,17 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
}
}
- #endregion
-
- #region AvatarFactoryModule private methods
-
- ///
- /// Check for the existence of the baked texture assets. Request a rebake
- /// unless checkonly is true.
- ///
- ///
- ///
- 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 GetBakedTextureFaces(ScenePresence sp)
{
if (sp.IsChildAgent)
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
index dee0ad4bfc..eb1e4b5f13 100644
--- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -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(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
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index dbe2560493..37292d66fd 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -50,6 +50,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public string LastName { get; set; }
public string HomeURL { get; set; }
public Dictionary 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 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)
{
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
index 8670229e8b..04df9c3723 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
@@ -61,7 +61,29 @@ namespace OpenSim.Region.Framework.Interfaces
/// true if a valid agent was found, false otherwise
bool SaveBakedTextures(UUID agentId);
+ ///
+ /// Validate that OpenSim can find the baked textures need to display a given avatar
+ ///
+ ///
+ ///
+ ///
+ /// true if all the baked textures referenced by the texture IDs exist or the appearance is only using default textures. false otherwise.
+ ///
bool ValidateBakedTextureCache(IScenePresence sp);
+
+ ///
+ /// Request a rebake of textures for an avatar.
+ ///
+ ///
+ /// This will send the request to the viewer, since it's there that the rebake is done.
+ ///
+ /// Avatar to rebake.
+ ///
+ /// 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.
+ ///
+ void RequestRebake(IScenePresence sp, bool missingTexturesOnly);
+
void QueueAppearanceSend(UUID agentid);
void QueueAppearanceSave(UUID agentid);
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index ea0ba5935b..54dfaf4c63 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -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);
///
/// Add a user.
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 209a0a639e..74d9e60c49 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -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;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 26f915b28e..d2e0ab0790 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1236,6 +1236,7 @@ namespace OpenSim.Region.Framework.Scenes
try
{
+ m_eventManager.TriggerOnRegionStarted(this);
while (!shuttingdown)
Update();
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index fa8b1c0174..c45cfb8f0a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -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;
}
///
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 845553a678..a301ccb304 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -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);
}
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 5f2f7d8119..3f249911fb 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -1279,7 +1279,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString(name, flagsStr.Replace(",", ""));
}
- static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary options, Scene scene)
+ public static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary 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 options)
+ public static void WriteShape(XmlTextWriter writer, PrimitiveBaseShape shp, Dictionary 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
/// The name of the xml element containing the shape
/// true if any errors were encountered during parsing, false otherwise
/// The shape parsed
- static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
+ public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
{
errors = false;
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index 1ce24f1745..7e15718c45 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -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 ",
+ "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 ");
+ 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);
+ }
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index 07c69624b7..1bd37062db 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -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 userInfo = m_HomeUsersService.GetUserInfo(userID);
+ if (userInfo.Count > 0)
+ {
+ foreach (KeyValuePair 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();
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index a73bf9e946..d617aee04b 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -559,6 +559,60 @@ namespace OpenSim.Services.Connectors.Hypergrid
return online;
}
+ public Dictionary 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 info = new Dictionary();
+ 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 GetServerURLs(UUID userID)
{
Hashtable hash = new Hashtable();
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 38bcce6906..1a839f3338 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -486,6 +486,31 @@ namespace OpenSim.Services.HypergridService
return online;
}
+ public Dictionary GetUserInfo(UUID userID)
+ {
+ Dictionary info = new Dictionary();
+
+ 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 GetServerURLs(UUID userID)
{
if (m_UserAccountService == null)
diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs
index e86ec519e5..5b293acbee 100644
--- a/OpenSim/Services/Interfaces/IHypergridServices.cs
+++ b/OpenSim/Services/Interfaces/IHypergridServices.cs
@@ -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 GetServerURLs(UUID userID);
+ Dictionary GetUserInfo(UUID userID);
string LocateUser(UUID userID);
// Tries to get the universal user identifier for the targetUserId
diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs
index 6249fae019..a73fcbec8f 100644
--- a/OpenSim/Tools/pCampBot/pCampBot.cs
+++ b/OpenSim/Tools/pCampBot/pCampBot.cs
@@ -112,10 +112,10 @@ namespace pCampBot
" -lastname lastname for the bots. Each lastname will have _ 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");
diff --git a/bin/C5.dll b/bin/C5.dll
index 1234ce9ff8..42093e5f84 100755
Binary files a/bin/C5.dll and b/bin/C5.dll differ