From e6eeaaea6717f68c1ad622c4fbd308917b3d1408 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 17 Nov 2010 22:55:06 +0000 Subject: [PATCH 1/7] minor: add some method comments --- OpenSim/Framework/Util.cs | 8 ++++++++ .../Framework/EntityTransfer/EntityTransferModule.cs | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index addfe5d1af..e8f8e012de 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -451,6 +451,14 @@ namespace OpenSim.Framework return (x + y - (min >> 1) - (min >> 2) + (min >> 4)); } + /// + /// Are the co-ordinates of the new region visible from the old region? + /// + /// Old region x-coord + /// New region x-coord + /// Old region y-coord + /// New region y-coord + /// public static bool IsOutsideView(uint oldx, uint newx, uint oldy, uint newy) { // Eventually this will be a function of the draw distance / camera position too. diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b5cab84e67..f02a9228e5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1228,11 +1228,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); - } - } + /// + /// Return the list of regions that are considered to be neighbours to the given scene. + /// + /// + /// + /// + /// protected List RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY) { RegionInfo m_regionInfo = pScene.RegionInfo; From 2a17c39dfe97b0637aab9f24b7152d5080da0969 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 17 Nov 2010 19:39:12 +0000 Subject: [PATCH 2/7] Fix "show queues" console command For each agent, this command shows how many packets have been sent/received and how many bytes remain in each of the send queues (resend, land, texture, etc.) Sometimes useful for diagnostics --- OpenSim/Region/Application/OpenSim.cs | 97 +++++++++++++------ .../ClientStack/LindenUDP/LLUDPClient.cs | 22 ++++- 2 files changed, 86 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index f80cb342af..c20a4e81a4 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Text; using System.Timers; using log4net; using Nini.Config; @@ -988,38 +989,74 @@ namespace OpenSim /// private string GetQueuesReport() { - string report = String.Empty; + StringBuilder report = new StringBuilder(); + + int columnPadding = 2; + int maxNameLength = 18; + int maxRegionNameLength = 14; + int maxTypeLength = 5; + int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding; + + report.AppendFormat("{0,-" + maxNameLength + "}{1,-" + columnPadding + "}", "User", ""); + report.AppendFormat("{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}", "Region", ""); + report.AppendFormat("{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", "Type", ""); + + report.AppendFormat( + "{0,9} {1,10} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7} {9,7}\n", + "Packets", + "Packets", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes", + "Bytes"); + + report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); + report.AppendFormat( + "{0,9} {1,10} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7} {9,7}\n", + "Sent", + "Received", + "Resend", + "Land", + "Wind", + "Cloud", + "Task", + "Texture", + "Asset", + "State"); + + m_sceneManager.ForEachScene( + delegate(Scene scene) + { + scene.ForEachClient( + delegate(IClientAPI client) + { + if (client is IStatsCollector) + { + string name = client.Name; + string regionName = scene.RegionInfo.RegionName; + + report.AppendFormat( + "{0,-" + maxNameLength + "}{1,-" + columnPadding + "}", + name.Length > maxNameLength ? name.Substring(0, maxNameLength) : name, ""); + report.AppendFormat( + "{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}", + regionName.Length > maxRegionNameLength ? regionName.Substring(0, maxRegionNameLength) : regionName, ""); + report.AppendFormat( + "{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", + scene.PresenceChildStatus(client.AgentId) ? "Child" : "Root", ""); - m_sceneManager.ForEachScene(delegate(Scene scene) - { - scene.ForEachClient(delegate(IClientAPI client) - { - if (client is IStatsCollector) - { - report = report + client.FirstName + - " " + client.LastName; + IStatsCollector stats = (IStatsCollector)client; + + report.AppendLine(stats.Report()); + } + }); + }); - IStatsCollector stats = - (IStatsCollector) client; - - report = report + string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}\n", - "Send", - "In", - "Out", - "Resend", - "Land", - "Wind", - "Cloud", - "Task", - "Texture", - "Asset"); - report = report + stats.Report() + - "\n"; - } - }); - }); - - return report; + return report.ToString(); } /// diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index ca5a7bdc4b..1812c08d2a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -246,11 +246,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP throw new NotImplementedException(); } + /// + /// Return statistics information about client packet queues. + /// + /// + /// FIXME: This should really be done in a more sensible manner rather than sending back a formatted string. + /// + /// public string GetStats() { - // TODO: ??? - return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + return string.Format( + "{0,9} {1,10} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7} {9,7}", + PacketsSent, + PacketsReceived, + m_throttleCategories[(int)ThrottleOutPacketType.Resend].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Land].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Wind].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Cloud].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Task].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Texture].Content, + m_throttleCategories[(int)ThrottleOutPacketType.Asset].Content, + m_throttleCategories[(int)ThrottleOutPacketType.State].Content); } public void SendPacketStats() From c4f3175e173b399f533fc42be36631d97b696a5a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 17 Nov 2010 19:58:27 +0000 Subject: [PATCH 3/7] add "Unacked bytes" column to "show queues" This should show the number of bytes sent to the client that it has not yet acknowledged. --- OpenSim/Region/Application/OpenSim.cs | 18 +++++++++++------- .../ClientStack/LindenUDP/LLUDPClient.cs | 3 ++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index c20a4e81a4..a90ce33650 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -306,7 +306,9 @@ namespace OpenSim m_console.Commands.AddCommand("region", false, "show queues", "show queues", - "Show queue data", HandleShow); + "Show queue data for each client", + HandleShow); + m_console.Commands.AddCommand("region", false, "show ratings", "show ratings", "Show rating data", HandleShow); @@ -994,7 +996,7 @@ namespace OpenSim int columnPadding = 2; int maxNameLength = 18; int maxRegionNameLength = 14; - int maxTypeLength = 5; + int maxTypeLength = 4; int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding; report.AppendFormat("{0,-" + maxNameLength + "}{1,-" + columnPadding + "}", "User", ""); @@ -1002,7 +1004,7 @@ namespace OpenSim report.AppendFormat("{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", "Type", ""); report.AppendFormat( - "{0,9} {1,10} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7} {9,7}\n", + "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n", "Packets", "Packets", "Bytes", @@ -1012,13 +1014,15 @@ namespace OpenSim "Bytes", "Bytes", "Bytes", + "Bytes", "Bytes"); report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); report.AppendFormat( - "{0,9} {1,10} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7} {9,7}\n", - "Sent", - "Received", + "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n", + "Out", + "In", + "Unacked", "Resend", "Land", "Wind", @@ -1047,7 +1051,7 @@ namespace OpenSim regionName.Length > maxRegionNameLength ? regionName.Substring(0, maxRegionNameLength) : regionName, ""); report.AppendFormat( "{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", - scene.PresenceChildStatus(client.AgentId) ? "Child" : "Root", ""); + scene.PresenceChildStatus(client.AgentId) ? "Cd" : "Rt", ""); IStatsCollector stats = (IStatsCollector)client; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 1812c08d2a..c4db5da2da 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -256,9 +256,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public string GetStats() { return string.Format( - "{0,9} {1,10} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7} {9,7}", + "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}", PacketsSent, PacketsReceived, + UnackedBytes, m_throttleCategories[(int)ThrottleOutPacketType.Resend].Content, m_throttleCategories[(int)ThrottleOutPacketType.Land].Content, m_throttleCategories[(int)ThrottleOutPacketType.Wind].Content, From af0deff7e9b052e4843bc8d4816ebd7aa80f48f4 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 17 Nov 2010 20:09:18 +0000 Subject: [PATCH 4/7] Make "show queues [full]" behave like "show users [full]" Now, "show queues" only shows root agents. "show queues full" will show child agents as well --- OpenSim/Region/Application/OpenSim.cs | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index a90ce33650..2c920f6e0a 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -286,16 +286,15 @@ namespace OpenSim m_console.Commands.AddCommand("region", false, "show users", "show users [full]", - "Show user data", HandleShow); + "Show user data for users currently on the region", + "Without the 'full' option, only users actually on the region are shown." + + " With the 'full' option child agents of users in neighbouring regions are also shown.", + HandleShow); m_console.Commands.AddCommand("region", false, "show connections", "show connections", "Show connection data", HandleShow); - m_console.Commands.AddCommand("region", false, "show users full", - "show users full", - String.Empty, HandleShow); - m_console.Commands.AddCommand("region", false, "show modules", "show modules", "Show module data", HandleShow); @@ -305,8 +304,10 @@ namespace OpenSim "Show region data", HandleShow); m_console.Commands.AddCommand("region", false, "show queues", - "show queues", + "show queues [full]", "Show queue data for each client", + "Without the 'full' option, only users actually on the region are shown." + + " With the 'full' option child agents of users in neighbouring regions are also shown.", HandleShow); m_console.Commands.AddCommand("region", false, "show ratings", @@ -879,7 +880,7 @@ namespace OpenSim { agents = m_sceneManager.GetCurrentSceneAvatars(); } - + MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count)); MainConsole.Instance.Output( @@ -956,7 +957,7 @@ namespace OpenSim break; case "queues": - Notice(GetQueuesReport()); + Notice(GetQueuesReport(showParams)); break; case "ratings": @@ -986,11 +987,17 @@ namespace OpenSim } /// - /// print UDP Queue data for each client + /// Generate UDP Queue data report for each client /// + /// /// - private string GetQueuesReport() + private string GetQueuesReport(string[] showParams) { + bool showChildren = false; + + if (showParams.Length > 1 && showParams[1] == "full") + showChildren = true; + StringBuilder report = new StringBuilder(); int columnPadding = 2; @@ -1040,6 +1047,10 @@ namespace OpenSim { if (client is IStatsCollector) { + bool isChild = scene.PresenceChildStatus(client.AgentId); + if (isChild && !showChildren) + return; + string name = client.Name; string regionName = scene.RegionInfo.RegionName; @@ -1051,7 +1062,7 @@ namespace OpenSim regionName.Length > maxRegionNameLength ? regionName.Substring(0, maxRegionNameLength) : regionName, ""); report.AppendFormat( "{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", - scene.PresenceChildStatus(client.AgentId) ? "Cd" : "Rt", ""); + isChild ? "Cd" : "Rt", ""); IStatsCollector stats = (IStatsCollector)client; From c072a9cfb3e74d58ec89fccf56cd67be97b99df9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 17 Nov 2010 23:34:39 +0000 Subject: [PATCH 5/7] save all lines to history, not just those which turn out to be valid comands. does not store passwords also, blank lines are not stored to history this makes it easier to go back and correct a command which was simply mistyped rather than having to type it out again --- OpenSim/Framework/Console/LocalConsole.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index 5f2f4041b5..6966211457 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -473,9 +473,11 @@ namespace OpenSim.Framework.Console y = -1; } + string commandLine = cmdline.ToString(); + if (isCommand) { - string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString())); + string[] cmd = Commands.Resolve(Parser.Parse(commandLine)); if (cmd.Length != 0) { @@ -491,7 +493,10 @@ namespace OpenSim.Framework.Console } } - //AddToHistory(cmdline.ToString()); + // If we're not echoing to screen (e.g. a password) then we probably don't want it in history + if (echo && commandLine != "") + AddToHistory(commandLine); + return cmdline.ToString(); default: break; From 859234f963115eb4307b09dc888adfaeed9537b8 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 17 Nov 2010 23:50:23 +0000 Subject: [PATCH 6/7] small refactor: reuse existing commandLine string rather than calling cmdline.ToString() again --- OpenSim/Framework/Console/LocalConsole.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index 6966211457..eda41b8d5a 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -497,7 +497,7 @@ namespace OpenSim.Framework.Console if (echo && commandLine != "") AddToHistory(commandLine); - return cmdline.ToString(); + return commandLine; default: break; } From 8f1a79420be062ea59b3c04aacb439fb57713ac7 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Thu, 18 Nov 2010 10:01:10 -0800 Subject: [PATCH 7/7] Fixed appearance send for avatars with only default textures. This should fix some of the appearance problems on osgrid. Also added a transaction lock on SetAppearance. This won't prevent concurrent access to Appearance but it will at least make sure each update completes. Signed-off-by: Melanie --- .../AvatarFactory/AvatarFactoryModule.cs | 131 ++++++++++-------- 1 file changed, 76 insertions(+), 55 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 2dd444d523..0df4585eec 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -55,6 +55,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private Dictionary m_savequeue = new Dictionary(); private Dictionary m_sendqueue = new Dictionary(); + private object m_setAppearanceLock = new object(); + #region RegionModule Members public void Initialise(Scene scene, IConfigSource config) @@ -69,6 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); + // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); } } @@ -117,26 +120,28 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}", client.AgentId); + m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId); return false; } - bool cached = true; + bool defonly = true; // are we only using default textures // Process the texture entry 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 (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - if (! CheckBakedTextureAsset(client,face.TextureID,idx)) - { - sp.Appearance.Texture.FaceTextures[idx] = null; - cached = false; - } + if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + continue; + + defonly = false; // found a non-default texture reference + + if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + return false; } - return cached; + // If we only found default textures, then the appearance is not cached + return (defonly ? false : true); } /// @@ -146,44 +151,59 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) { -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance for {0}",client.AgentId); - ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}",client.AgentId); + m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId); return; } + // m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId); + bool changed = false; - // Process the texture entry - if (textureEntry != null) + // Process the texture entry transactionally, this doesn't guarantee that Appearance is + // going to be handled correctly but it does serialize the updates to the appearance + lock (m_setAppearanceLock) { - changed = sp.Appearance.SetTextureEntries(textureEntry); - - for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) + if (textureEntry != null) { - int idx = AvatarAppearance.BAKE_INDICES[i]; - Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; - if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - Util.FireAndForget(delegate(object o) { - if (! CheckBakedTextureAsset(client,face.TextureID,idx)) - client.SendRebakeAvatarTextures(face.TextureID); - }); - } - } + changed = sp.Appearance.SetTextureEntries(textureEntry); - // Process the visual params, this may change height as well - if (visualParams != null) - { - if (sp.Appearance.SetVisualParams(visualParams)) - { - changed = true; - if (sp.Appearance.AvatarHeight > 0) - sp.SetHeight(sp.Appearance.AvatarHeight); + // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId); + + 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 (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + Util.FireAndForget(delegate(object o) { + if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + client.SendRebakeAvatarTextures(face.TextureID); + }); + } + + // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); } + + // Process the visual params, this may change height as well + if (visualParams != null) + { + if (sp.Appearance.SetVisualParams(visualParams)) + { + changed = true; + if (sp.Appearance.AvatarHeight > 0) + sp.SetHeight(sp.Appearance.AvatarHeight); + } + } + + // Send the appearance back to the avatar, not clear that this is needed + sp.ControllingClient.SendAvatarDataImmediate(sp); + // AvatarAppearance avp = sp.Appearance; + // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); + } + // If something changed in the appearance then queue an appearance save if (changed) @@ -192,10 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // And always queue up an appearance update to send out QueueAppearanceSend(client.AgentId); - // Send the appearance back to the avatar - // AvatarAppearance avp = sp.Appearance; - // sp.ControllingClient.SendAvatarDataImmediate(sp); - // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); + // m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); } /// @@ -209,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { if (m_scene.AssetService.Get(textureID.ToString()) == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: Missing baked texture {0} ({1}) for avatar {2}", + m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}", textureID, idx, client.Name); return false; } @@ -220,10 +237,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void QueueAppearanceSend(UUID agentid) { -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance send for {0}", agentid); + // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); - // 100 nanoseconds (ticks) we should wait - long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000); + // 10000 ticks per millisecond, 1000 milliseconds per second + long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); lock (m_sendqueue) { m_sendqueue[agentid] = timestamp; @@ -233,10 +250,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void QueueAppearanceSave(UUID agentid) { -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance save for {0}", agentid); + // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); - // 100 nanoseconds (ticks) we should wait - long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000); + // 10000 ticks per millisecond, 1000 milliseconds per second + long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); lock (m_savequeue) { m_savequeue[agentid] = timestamp; @@ -249,15 +266,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); + m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); return; } -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Handle appearance send for {0}", agentid); + // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid); // Send the appearance to everyone in the scene sp.SendAppearanceToAllOtherAgents(); - sp.ControllingClient.SendAvatarDataImmediate(sp); + // sp.ControllingClient.SendAvatarDataImmediate(sp); // Send the appearance back to the avatar // AvatarAppearance avp = sp.Appearance; @@ -279,10 +296,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); + m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); return; } + // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); + m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); } @@ -330,11 +349,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: SendWearables unable to find presence for {0}", client.AgentId); + m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId); return; } -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Received request for wearables of {0}", client.AgentId); + // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId); client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); } @@ -349,11 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing unable to find presence for {0}", client.AgentId); + m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId); return; } -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing called for {0}", client.AgentId); + // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); @@ -368,6 +387,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // This could take awhile since it needs to pull inventory SetAppearanceAssets(sp.UUID, ref avatAppearance); + // could get fancier with the locks here, but in the spirit of "last write wins" + // this should work correctly sp.Appearance = avatAppearance; m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); } @@ -398,7 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory else { m_log.ErrorFormat( - "[AVATAR FACTORY MODULE]: Can't find inventory item {0} for {1}, setting to default", + "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", appearance.Wearables[i][j].ItemID, (WearableType)i); appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); @@ -408,7 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } else { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: user {0} has no inventory, appearance isn't going to work", userID); + m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); } } }