From 180be7de07014aa33bc6066f12a0819b731c1c9d Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Tue, 10 Feb 2009 13:10:57 +0000 Subject: this is step 2 of 2 of the OpenSim.Region.Environment refactor. NOTHING has been deleted or moved off to forge at this point. what has happened is that OpenSim.Region.Environment.Modules has been split in two: - OpenSim.Region.CoreModules: all those modules that are either directly or indirectly referenced from other OpenSim packages, or that provide functionality that the OpenSim developer community considers core functionality: CoreModules/Agent/AssetTransaction CoreModules/Agent/Capabilities CoreModules/Agent/TextureDownload CoreModules/Agent/TextureSender CoreModules/Agent/TextureSender/Tests CoreModules/Agent/Xfer CoreModules/Avatar/AvatarFactory CoreModules/Avatar/Chat/ChatModule CoreModules/Avatar/Combat CoreModules/Avatar/Currency/SampleMoney CoreModules/Avatar/Dialog CoreModules/Avatar/Friends CoreModules/Avatar/Gestures CoreModules/Avatar/Groups CoreModules/Avatar/InstantMessage CoreModules/Avatar/Inventory CoreModules/Avatar/Inventory/Archiver CoreModules/Avatar/Inventory/Transfer CoreModules/Avatar/Lure CoreModules/Avatar/ObjectCaps CoreModules/Avatar/Profiles CoreModules/Communications/Local CoreModules/Communications/REST CoreModules/Framework/EventQueue CoreModules/Framework/InterfaceCommander CoreModules/Hypergrid CoreModules/InterGrid CoreModules/Scripting/DynamicTexture CoreModules/Scripting/EMailModules CoreModules/Scripting/HttpRequest CoreModules/Scripting/LoadImageURL CoreModules/Scripting/VectorRender CoreModules/Scripting/WorldComm CoreModules/Scripting/XMLRPC CoreModules/World/Archiver CoreModules/World/Archiver/Tests CoreModules/World/Estate CoreModules/World/Land CoreModules/World/Permissions CoreModules/World/Serialiser CoreModules/World/Sound CoreModules/World/Sun CoreModules/World/Terrain CoreModules/World/Terrain/DefaultEffects CoreModules/World/Terrain/DefaultEffects/bin CoreModules/World/Terrain/DefaultEffects/bin/Debug CoreModules/World/Terrain/Effects CoreModules/World/Terrain/FileLoaders CoreModules/World/Terrain/FloodBrushes CoreModules/World/Terrain/PaintBrushes CoreModules/World/Terrain/Tests CoreModules/World/Vegetation CoreModules/World/Wind CoreModules/World/WorldMap - OpenSim.Region.OptionalModules: all those modules that are not core modules: OptionalModules/Avatar/Chat/IRC-stuff OptionalModules/Avatar/Concierge OptionalModules/Avatar/Voice/AsterixVoice OptionalModules/Avatar/Voice/SIPVoice OptionalModules/ContentManagementSystem OptionalModules/Grid/Interregion OptionalModules/Python OptionalModules/SvnSerialiser OptionalModules/World/NPC OptionalModules/World/TreePopulator --- .../OptionalModules/Avatar/Chat/ChannelState.cs | 628 +++++++++++++++ .../OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 219 +++++ .../OptionalModules/Avatar/Chat/IRCConnector.cs | 887 +++++++++++++++++++++ .../OptionalModules/Avatar/Chat/RegionState.cs | 424 ++++++++++ .../Avatar/Concierge/ConciergeModule.cs | 604 ++++++++++++++ .../Avatar/Concierge/ConciergeServer.py | 130 +++ .../Voice/AsterixVoice/AsteriskVoiceModule.cs | 292 +++++++ .../Avatar/Voice/SIPVoice/SIPVoiceModule.cs | 202 +++++ 8 files changed, 3386 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs create mode 100755 OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeServer.py create mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs new file mode 100644 index 0000000..167f0cc --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -0,0 +1,628 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text.RegularExpressions; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Chat +{ + + // An instance of this class exists for each unique combination of + // IRC chat interface characteristics, as determined by the supplied + // configuration file. + + internal class ChannelState + { + + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static Regex arg = new Regex(@"\[[^\[\]]*\]"); + private static int _idk_ = 0; + private static int DEBUG_CHANNEL = 2147483647; + + // These are the IRC Connector configurable parameters with hard-wired + // default values (retained for compatability). + + internal string Server = null; + internal string Password = null; + internal string IrcChannel = null; + internal string BaseNickname = "OSimBot"; + internal uint Port = 6667; + internal string User = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot"; + + internal bool ClientReporting = true; + internal bool RelayChat = true; + internal bool RelayPrivateChannels = false; + internal int RelayChannel = 1; + internal List ValidInWorldChannels = new List(); + + // Connector agnostic parameters. These values are NOT shared with the + // connector and do not differentiate at an IRC level + + internal string PrivateMessageFormat = "PRIVMSG {0} :<{2}> {1} {3}"; + internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; + internal int RelayChannelOut = -1; + internal bool RandomizeNickname = true; + internal bool CommandsEnabled = false; + internal int CommandChannel = -1; + internal int ConnectDelay = 10; + internal int PingDelay = 15; + internal string DefaultZone = "Sim"; + + internal string _accessPassword = String.Empty; + internal Regex AccessPasswordRegex = null; + internal string AccessPassword + { + get { return _accessPassword; } + set + { + _accessPassword = value; + AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?[^,]+),\s*(?.+)$", _accessPassword), + RegexOptions.Compiled); + } + } + + + + // IRC connector reference + + internal IRCConnector irc = null; + + internal int idn = _idk_++; + + // List of regions dependent upon this connection + + internal List clientregions = new List(); + + // Needed by OpenChannel + + internal ChannelState() + { + } + + // This constructor is used by the Update* methods. A copy of the + // existing channel state is created, and distinguishing characteristics + // are copied across. + + internal ChannelState(ChannelState model) + { + Server = model.Server; + Password = model.Password; + IrcChannel = model.IrcChannel; + Port = model.Port; + BaseNickname = model.BaseNickname; + RandomizeNickname = model.RandomizeNickname; + User = model.User; + CommandsEnabled = model.CommandsEnabled; + CommandChannel = model.CommandChannel; + RelayChat = model.RelayChat; + RelayPrivateChannels = model.RelayPrivateChannels; + RelayChannelOut = model.RelayChannelOut; + RelayChannel = model.RelayChannel; + ValidInWorldChannels = model.ValidInWorldChannels; + PrivateMessageFormat = model.PrivateMessageFormat; + NoticeMessageFormat = model.NoticeMessageFormat; + ClientReporting = model.ClientReporting; + AccessPassword = model.AccessPassword; + DefaultZone = model.DefaultZone; + ConnectDelay = model.ConnectDelay; + PingDelay = model.PingDelay; + } + + // Read the configuration file, performing variable substitution and any + // necessary aliasing. See accompanying documentation for how this works. + // If you don't need variables, then this works exactly as before. + // If either channel or server are not specified, the request fails. + + internal static void OpenChannel(RegionState rs, IConfig config) + { + + // Create a new instance of a channel. This may not actually + // get used if an equivalent channel already exists. + + ChannelState cs = new ChannelState(); + + // Read in the configuration file and filter everything for variable + // subsititution. + + m_log.DebugFormat("[IRC-Channel-{0}] Initial request by Region {1} to connect to IRC", cs.idn, rs.Region); + + cs.Server = Substitute(rs, config.GetString("server", null)); + m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); + cs.Password = Substitute(rs, config.GetString("password", null)); + // probably not a good idea to put a password in the log file + cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); + m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); + cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); + m_log.DebugFormat("[IRC-Channel-{0}] Port : <{1}>", cs.idn, cs.Port); + cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); + m_log.DebugFormat("[IRC-Channel-{0}] BaseNickname : <{1}>", cs.idn, cs.BaseNickname); + cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); + m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); + cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); + m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); + cs.User = Substitute(rs, config.GetString("username", cs.User)); + m_log.DebugFormat("[IRC-Channel-{0}] User : <{1}>", cs.idn, cs.User); + cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); + m_log.DebugFormat("[IRC-Channel-{0}] CommandsEnabled : <{1}>", cs.idn, cs.CommandsEnabled); + cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); + m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); + cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); + m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); + cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); + m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat); + cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); + m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); + cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); + m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); + cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); + m_log.DebugFormat("[IRC-Channel-{0}] RelayChannelOut : <{1}>", cs.idn, cs.RelayChannelOut); + cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); + m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); + cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); + m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); + cs.PrivateMessageFormat = Substitute(rs, config.GetString("msgformat", cs.PrivateMessageFormat)); + m_log.DebugFormat("[IRC-Channel-{0}] PrivateMessageFormat : <{1}>", cs.idn, cs.PrivateMessageFormat); + cs.NoticeMessageFormat = Substitute(rs, config.GetString("noticeformat", cs.NoticeMessageFormat)); + m_log.DebugFormat("[IRC-Channel-{0}] NoticeMessageFormat : <{1}>", cs.idn, cs.NoticeMessageFormat); + cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting?"1":"0"))) > 0; + m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); + cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); + m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); + cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); + m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); + cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); + m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); + cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); + m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); + cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); + m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); + + + // Fail if fundamental information is still missing + + if (cs.Server == null || cs.IrcChannel == null || cs.BaseNickname == null || cs.User == null) + throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}", cs.idn, rs.Region)); + + m_log.InfoFormat("[IRC-Channel-{0}] Configuration for Region {1} is valid", cs.idn, rs.Region); + m_log.InfoFormat("[IRC-Channel-{0}] Server = {1}", cs.idn, cs.Server); + m_log.InfoFormat("[IRC-Channel-{0}] Channel = {1}", cs.idn, cs.IrcChannel); + m_log.InfoFormat("[IRC-Channel-{0}] Port = {1}", cs.idn, cs.Port); + m_log.InfoFormat("[IRC-Channel-{0}] Nickname = {1}", cs.idn, cs.BaseNickname); + m_log.InfoFormat("[IRC-Channel-{0}] User = {1}", cs.idn, cs.User); + + // Set the channel state for this region + + if (cs.RelayChat) + { + cs.ValidInWorldChannels.Add(0); + cs.ValidInWorldChannels.Add(DEBUG_CHANNEL); + } + + if (cs.RelayPrivateChannels) + cs.ValidInWorldChannels.Add(cs.RelayChannelOut); + + rs.cs = Integrate(rs, cs); + + } + + // An initialized channel state instance is passed in. If an identical + // channel state instance already exists, then the existing instance + // is used to replace the supplied value. + // If the instance matches with respect to IRC, then the underlying + // IRCConnector is assigned to the supplied channel state and the + // updated value is returned. + // If there is no match, then the supplied instance is completed by + // creating and assigning an instance of an IRC connector. + + private static ChannelState Integrate(RegionState rs, ChannelState p_cs) + { + + ChannelState cs = p_cs; + + // Check to see if we have an existing server/channel setup that can be used + // In the absence of variable substitution this will always resolve to the + // same ChannelState instance, and the table will only contains a single + // entry, so the performance considerations for the existing behavior are + // zero. Only the IRC connector is shared, the ChannelState still contains + // values that, while independent of the IRC connetion, do still distinguish + // this region's behavior. + + lock (IRCBridgeModule.m_channels) + { + + foreach (ChannelState xcs in IRCBridgeModule.m_channels) + { + if (cs.IsAPerfectMatchFor(xcs)) + { + m_log.DebugFormat("[IRC-Channel-{0}] Channel state matched", cs.idn); + cs = xcs; + break; + } + if (cs.IsAConnectionMatchFor(xcs)) + { + m_log.DebugFormat("[IRC-Channel-{0}] Channel matched", cs.idn); + cs.irc = xcs.irc; + break; + } + } + + } + + // No entry was found, so this is going to be a new entry. + + if (cs.irc == null) + { + + m_log.DebugFormat("[IRC-Channel-{0}] New channel required", cs.idn); + + if ((cs.irc = new IRCConnector(cs)) != null) + { + + IRCBridgeModule.m_channels.Add(cs); + + m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", + cs.idn, rs.Region, cs.DefaultZone, + cs.CommandsEnabled ? "enabled" : "not enabled", + cs.RelayPrivateChannels ? "relayed" : "not relayed"); + } + else + { + string txt = String.Format("[IRC-Channel-{0}] Region {1} failed to connect to channel {2} on server {3}:{4}", + cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); + m_log.Error(txt); + throw new Exception(txt); + } + } + else + { + m_log.InfoFormat("[IRC-Channel-{0}] Region {1} reusing existing connection to channel {2} on server {3}:{4}", + cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); + } + + m_log.InfoFormat("[IRC-Channel-{0}] Region {1} associated with channel {2} on server {3}:{4}", + cs.idn, rs.Region, cs.IrcChannel, cs.Server, cs.Port); + + // We're finally ready to commit ourselves + + + return cs; + + } + + // These routines allow differentiating changes to + // the underlying channel state. If necessary, a + // new channel state will be created. + + internal ChannelState UpdateServer(RegionState rs, string server) + { + RemoveRegion(rs); + ChannelState cs = new ChannelState(this); + cs.Server = server; + cs = Integrate(rs, cs); + cs.AddRegion(rs); + return cs; + } + + internal ChannelState UpdatePort(RegionState rs, string port) + { + RemoveRegion(rs); + ChannelState cs = new ChannelState(this); + cs.Port = Convert.ToUInt32(port); + cs = Integrate(rs, cs); + cs.AddRegion(rs); + return cs; + } + + internal ChannelState UpdateChannel(RegionState rs, string channel) + { + RemoveRegion(rs); + ChannelState cs = new ChannelState(this); + cs.IrcChannel = channel; + cs = Integrate(rs, cs); + cs.AddRegion(rs); + return cs; + } + + internal ChannelState UpdateNickname(RegionState rs, string nickname) + { + RemoveRegion(rs); + ChannelState cs = new ChannelState(this); + cs.BaseNickname = nickname; + cs = Integrate(rs, cs); + cs.AddRegion(rs); + return cs; + } + + internal ChannelState UpdateClientReporting(RegionState rs, string cr) + { + RemoveRegion(rs); + ChannelState cs = new ChannelState(this); + cs.ClientReporting = Convert.ToBoolean(cr); + cs = Integrate(rs, cs); + cs.AddRegion(rs); + return cs; + } + + internal ChannelState UpdateRelayIn(RegionState rs, string channel) + { + RemoveRegion(rs); + ChannelState cs = new ChannelState(this); + cs.RelayChannel = Convert.ToInt32(channel); + cs = Integrate(rs, cs); + cs.AddRegion(rs); + return cs; + } + + internal ChannelState UpdateRelayOut(RegionState rs, string channel) + { + RemoveRegion(rs); + ChannelState cs = new ChannelState(this); + cs.RelayChannelOut = Convert.ToInt32(channel); + cs = Integrate(rs, cs); + cs.AddRegion(rs); + return cs; + } + + // Determine whether or not this is a 'new' channel. Only those + // attributes that uniquely distinguish an IRC connection should + // be included here (and only those attributes should really be + // in the ChannelState structure) + + private bool IsAConnectionMatchFor(ChannelState cs) + { + return ( + Server == cs.Server && + IrcChannel == cs.IrcChannel && + Port == cs.Port && + BaseNickname == cs.BaseNickname && + User == cs.User + ); + } + + // This level of obsessive matching allows us to produce + // a minimal overhead int he case of a server which does + // need to differentiate IRC at a region level. + + private bool IsAPerfectMatchFor(ChannelState cs) + { + return ( IsAConnectionMatchFor(cs) && + RelayChannelOut == cs.RelayChannelOut && + PrivateMessageFormat == cs.PrivateMessageFormat && + NoticeMessageFormat == cs.NoticeMessageFormat && + RandomizeNickname == cs.RandomizeNickname && + AccessPassword == cs.AccessPassword && + CommandsEnabled == cs.CommandsEnabled && + CommandChannel == cs.CommandChannel && + DefaultZone == cs.DefaultZone && + RelayPrivateChannels == cs.RelayPrivateChannels && + RelayChannel == cs.RelayChannel && + RelayChat == cs.RelayChat && + ClientReporting == cs.ClientReporting + ); + } + + // This function implements the variable substitution mechanism + // for the configuration values. Each string read from the + // configuration file is scanned for '[...]' enclosures. Each + // one that is found is replaced by either a runtime variable + // (%xxx) or an existing configuration key. When no further + // substitution is possible, the remaining string is returned + // to the caller. This allows for arbitrarily nested + // enclosures. + + private static string Substitute(RegionState rs, string instr) + { + + string result = instr; + + if (result == null || result.Length == 0) + return result; + + // Repeatedly scan the string until all possible + // substitutions have been performed. + + // m_log.DebugFormat("[IRC-Channel] Parse[1]: {0}", result); + + while (arg.IsMatch(result)) + { + + string vvar = arg.Match(result).ToString(); + string var = vvar.Substring(1,vvar.Length-2).Trim(); + + switch (var.ToLower()) + { + case "%region" : + result = result.Replace(vvar, rs.Region); + break; + case "%host" : + result = result.Replace(vvar, rs.Host); + break; + case "%master1" : + result = result.Replace(vvar, rs.MA1); + break; + case "%master2" : + result = result.Replace(vvar, rs.MA2); + break; + case "%locx" : + result = result.Replace(vvar, rs.LocX); + break; + case "%locy" : + result = result.Replace(vvar, rs.LocY); + break; + case "%k" : + result = result.Replace(vvar, rs.IDK); + break; + default : + result = result.Replace(vvar, rs.config.GetString(var,var)); + break; + } + // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); + } + + // m_log.DebugFormat("[IRC-Channel] Parse[3]: {0}", result); + return result; + + } + + public void Close() + { + m_log.InfoFormat("[IRC-Channel-{0}] Closing channel <{1}> to server <{2}:{3}>", + idn, IrcChannel, Server, Port); + m_log.InfoFormat("[IRC-Channel-{0}] There are {1} active clients", + idn, clientregions.Count); + irc.Close(); + } + + public void Open() + { + m_log.InfoFormat("[IRC-Channel-{0}] Opening channel <{1}> to server <{2}:{3}>", + idn, IrcChannel, Server, Port); + + irc.Open(); + + } + + // These are called by each region that attaches to this channel. The call affects + // only the relationship of the region with the channel. Not the channel to IRC + // relationship (unless it is closed and we want it open). + + public void Open(RegionState rs) + { + AddRegion(rs); + Open(); + } + + // Close is called to ensure that the IRC session is terminated if this is the + // only client. + + public void Close(RegionState rs) + { + RemoveRegion(rs); + lock (IRCBridgeModule.m_channels) + { + if (clientregions.Count == 0) + { + Close(); + IRCBridgeModule.m_channels.Remove(this); + m_log.InfoFormat("[IRC-Channel-{0}] Region {1} is last user of channel <{2}> to server <{3}:{4}>", + idn, rs.Region, IrcChannel, Server, Port); + m_log.InfoFormat("[IRC-Channel-{0}] Removed", idn); + } + } + } + + // Add a client region to this channel if it is not already known + + public void AddRegion(RegionState rs) + { + m_log.InfoFormat("[IRC-Channel-{0}] Adding region {1} to channel <{2}> to server <{3}:{4}>", + idn, rs.Region, IrcChannel, Server, Port); + if (!clientregions.Contains(rs)) + { + clientregions.Add(rs); + lock (irc) irc.depends++; + } + } + + // Remove a client region from the channel. If this is the last + // region, then clean up the channel. The connector will clean itself + // up if it finds itself about to be GC'd. + + public void RemoveRegion(RegionState rs) + { + + m_log.InfoFormat("[IRC-Channel-{0}] Removing region {1} from channel <{2} to server <{3}:{4}>", + idn, rs.Region, IrcChannel, Server, Port); + + if (clientregions.Contains(rs)) + { + clientregions.Remove(rs); + lock (irc) irc.depends--; + } + + } + + // This function is lifted from the IRCConnector because it + // contains information that is not differentiating from an + // IRC point-of-view. + + public static void OSChat(IRCConnector p_irc, OSChatMessage c, bool cmsg) + { + + // m_log.DebugFormat("[IRC-OSCHAT] from {0}:{1}", p_irc.Server, p_irc.IrcChannel); + + try + { + + // Scan through the set of unique channel configuration for those + // that belong to this connector. And then forward the message to + // all regions known to those channels. + // Note that this code is responsible for completing some of the + // settings for the inbound OSChatMessage + + lock (IRCBridgeModule.m_channels) + { + foreach (ChannelState cs in IRCBridgeModule.m_channels) + { + if ( p_irc == cs.irc) + { + + // This non-IRC differentiator moved to here + + if (cmsg && !cs.ClientReporting) + continue; + + // This non-IRC differentiator moved to here + + c.Channel = (cs.RelayPrivateChannels ? cs.RelayChannel : 0); + + foreach (RegionState region in cs.clientregions) + { + region.OSChat(cs.irc, c); + } + + } + } + } + } + catch (Exception ex) + { + m_log.ErrorFormat("[IRC-OSCHAT]: BroadcastSim Exception: {0}", ex.Message); + m_log.Debug(ex); + } + } + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs new file mode 100644 index 0000000..0facc14 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -0,0 +1,219 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Chat +{ + public class IRCBridgeModule : IRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + internal static bool configured = false; + internal static bool enabled = false; + internal static IConfig m_config = null; + + internal static List m_channels = new List(); + internal static List m_regions = new List(); + + internal static string password = String.Empty; + + internal RegionState region = null; + + #region IRegionModule Members + + public string Name + { + get { return "IRCBridgeModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + + public void Initialise(Scene scene, IConfigSource config) + { + // Do a once-only scan of the configuration file to make + // sure it's basically intact. + + if (!configured) + { + configured = true; + + try + { + if ((m_config = config.Configs["IRC"]) == null) + { + m_log.InfoFormat("[IRC-Bridge] module not configured"); + return; + } + + if (!m_config.GetBoolean("enabled", false)) + { + m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); + return; + } + } + catch (Exception e) + { + m_log.ErrorFormat("[IRC-Bridge] configuration failed : {0}", e.Message); + return; + } + + enabled = true; + + if (config.Configs["RemoteAdmin"] != null) + { + password = config.Configs["RemoteAdmin"].GetString("access_password", password); + scene.CommsManager.HttpServer.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); + } + } + + // Iff the IRC bridge is enabled, then each new region may be + // connected to IRC. But it should NOT be obligatory (and it + // is not). + // We have to do ALL of the startup here because PostInitialize + // is not called when a region gets created in-flight from the + // command line. + + if (enabled) + { + try + { + m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); + region = new RegionState(scene, m_config); + lock (m_regions) m_regions.Add(region); + region.Open(); + } + catch (Exception e) + { + m_log.WarnFormat("[IRC-Bridge] Region {0} not connected to IRC : {1}", scene.RegionInfo.RegionName, e.Message); + m_log.Debug(e); + } + } + else + { + m_log.WarnFormat("[IRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName); + } + } + + // This module can be called in-flight in which case PostInitialize + // is not called following Initialize. So no use is made of this + // call. + + public void PostInitialise() + { + } + + // Called immediately before the region module is unloaded. Cleanup + // the region. + + public void Close() + { + if (!enabled) + return; + + region.Close(); + lock (m_regions) m_regions.Remove(region); + } + + #endregion + + public static XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request) + { + m_log.Info("[IRC-Bridge]: XML RPC Admin Entry"); + + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + + try + { + Hashtable requestData = (Hashtable)request.Params[0]; + bool found = false; + string region = String.Empty; + + if (password != String.Empty) + { + if (!requestData.ContainsKey("password")) + throw new Exception("Invalid request"); + if ((string)requestData["password"] != password) + throw new Exception("Invalid request"); + } + + if (!requestData.ContainsKey("region")) + throw new Exception("No region name specified"); + region = (string)requestData["region"]; + + foreach (RegionState rs in m_regions) + { + if (rs.Region == region) + { + responseData["server"] = rs.cs.Server; + responseData["port"] = (int)rs.cs.Port; + responseData["user"] = rs.cs.User; + responseData["channel"] = rs.cs.IrcChannel; + responseData["enabled"] = rs.cs.irc.Enabled; + responseData["connected"] = rs.cs.irc.Connected; + responseData["nickname"] = rs.cs.irc.Nick; + found = true; + break; + } + } + + if (!found) throw new Exception(String.Format("Region <{0}> not found", region)); + + responseData["success"] = true; + } + catch (Exception e) + { + m_log.InfoFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); + + responseData["success"] = "false"; + responseData["error"] = e.Message; + } + finally + { + response.Value = responseData; + } + + m_log.Debug("[IRC-Bridge]: XML RPC Admin Exit"); + + return response; + } + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs new file mode 100644 index 0000000..f5c324d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -0,0 +1,887 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Timers; +using System.Collections.Generic; +using System.IO; +using System.Net.Sockets; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Threading; +using OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Chat +{ + public class IRCConnector + { + + #region Global (static) state + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // Local constants + + private static readonly Vector3 CenterOfRegion = new Vector3(128, 128, 20); + private static readonly char[] CS_SPACE = { ' ' }; + + private const int WD_INTERVAL = 1000; // base watchdog interval + private static int PING_PERIOD = 15; // WD intervals per PING + private static int ICCD_PERIOD = 10; // WD intervals between Connects + private static int L_TIMEOUT = 25; // Login time out interval + + private static int _idk_ = 0; // core connector identifier + private static int _pdk_ = 0; // ping interval counter + private static int _icc_ = 0; // IRC connect counter + + // List of configured connectors + + private static List m_connectors = new List(); + + // Watchdog state + + private static System.Timers.Timer m_watchdog = null; + + static IRCConnector() + { + m_log.DebugFormat("[IRC-Connector]: Static initialization started"); + m_watchdog = new System.Timers.Timer(WD_INTERVAL); + m_watchdog.Elapsed += new ElapsedEventHandler(WatchdogHandler); + m_watchdog.AutoReset = true; + m_watchdog.Start(); + m_log.DebugFormat("[IRC-Connector]: Static initialization complete"); + } + + #endregion + + #region Instance state + + // Connector identity + + internal int idn = _idk_++; + + // How many regions depend upon this connection + // This count is updated by the ChannelState object and reflects the sum + // of the region clients associated with the set of associated channel + // state instances. That's why it cannot be managed here. + + internal int depends = 0; + + // Working threads + + private Thread m_listener = null; + + private Object msyncConnect = new Object(); + + internal bool m_randomizeNick = true; // add random suffix + internal string m_baseNick = null; // base name for randomizing + internal string m_nick = null; // effective nickname + + public string Nick // Public property + { + get { return m_nick; } + set { m_nick = value; } + } + + private bool m_enabled = false; // connector enablement + public bool Enabled + { + get { return m_enabled; } + } + + private bool m_connected = false; // connection status + private bool m_pending = false; // login disposition + private int m_timeout = L_TIMEOUT; // login timeout counter + public bool Connected + { + get { return m_connected; } + } + + private string m_ircChannel; // associated channel id + public string IrcChannel + { + get { return m_ircChannel; } + set { m_ircChannel = value; } + } + + private uint m_port = 6667; // session port + public uint Port + { + get { return m_port; } + set { m_port = value; } + } + + private string m_server = null; // IRC server name + public string Server + { + get { return m_server; } + set { m_server = value; } + } + private string m_password = null; + public string Password + { + get { return m_password; } + set { m_password = value; } + } + + private string m_user = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot"; + public string User + { + get { return m_user; } + } + + // Network interface + + private TcpClient m_tcp; + private NetworkStream m_stream = null; + private StreamReader m_reader; + private StreamWriter m_writer; + + // Channel characteristic info (if available) + + internal string usermod = String.Empty; + internal string chanmod = String.Empty; + internal string version = String.Empty; + internal bool motd = false; + + #endregion + + #region connector instance management + + internal IRCConnector(ChannelState cs) + { + + // Prepare network interface + + m_tcp = null; + m_writer = null; + m_reader = null; + + // Setup IRC session parameters + + m_server = cs.Server; + m_password = cs.Password; + m_baseNick = cs.BaseNickname; + m_randomizeNick = cs.RandomizeNickname; + m_ircChannel = cs.IrcChannel; + m_port = cs.Port; + m_user = cs.User; + + if (m_watchdog == null) + { + // Non-differentiating + + ICCD_PERIOD = cs.ConnectDelay; + PING_PERIOD = cs.PingDelay; + + // Smaller values are not reasonable + + if (ICCD_PERIOD < 5) + ICCD_PERIOD = 5; + + if (PING_PERIOD < 5) + PING_PERIOD = 5; + + _icc_ = ICCD_PERIOD; // get started right away! + + } + + // The last line of defense + + if (m_server == null || m_baseNick == null || m_ircChannel == null || m_user == null) + throw new Exception("Invalid connector configuration"); + + // Generate an initial nickname if randomizing is enabled + + if (m_randomizeNick) + { + m_nick = m_baseNick + Util.RandomClass.Next(1, 99); + } + + // Add the newly created connector to the known connectors list + + m_connectors.Add(this); + + m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); + + } + + ~IRCConnector() + { + m_watchdog.Stop(); + Close(); + } + + // Mark the connector as connectable. Harmless if already enabled. + + public void Open() + { + if (!m_enabled) + { + + m_connectors.Add(this); + m_enabled = true; + + if (!Connected) + { + Connect(); + } + + } + } + + // Only close the connector if the dependency count is zero. + + public void Close() + { + + m_log.InfoFormat("[IRC-Connector-{0}] Closing", idn); + + lock (msyncConnect) + { + + if ((depends == 0) && Enabled) + { + + m_enabled = false; + + if (Connected) + { + m_log.DebugFormat("[IRC-Connector-{0}] Closing interface", idn); + + // Cleanup the IRC session + + try + { + m_writer.WriteLine(String.Format("QUIT :{0} to {1} wormhole to {2} closing", + m_nick, m_ircChannel, m_server)); + m_writer.Flush(); + } + catch (Exception) {} + + + m_connected = false; + + try { m_writer.Close(); } catch (Exception) {} + try { m_reader.Close(); } catch (Exception) {} + try { m_stream.Close(); } catch (Exception) {} + try { m_tcp.Close(); } catch (Exception) {} + + } + + m_connectors.Remove(this); + + } + } + + m_log.InfoFormat("[IRC-Connector-{0}] Closed", idn); + + } + + #endregion + + #region session management + + // Connect to the IRC server. A connector should always be connected, once enabled + + public void Connect() + { + + if (!m_enabled) + return; + + // Delay until next WD cycle if this is too close to the last start attempt + + while (_icc_ < ICCD_PERIOD) + return; + + m_log.DebugFormat("[IRC-Connector-{0}]: Connection request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel); + + lock (msyncConnect) + { + + _icc_ = 0; + + try + { + if (m_connected) return; + + m_connected = true; + m_pending = true; + m_timeout = L_TIMEOUT; + + m_tcp = new TcpClient(m_server, (int)m_port); + m_stream = m_tcp.GetStream(); + m_reader = new StreamReader(m_stream); + m_writer = new StreamWriter(m_stream); + + m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); + + m_listener = new Thread(new ThreadStart(ListenerRun)); + m_listener.Name = "IRCConnectorListenerThread"; + m_listener.IsBackground = true; + m_listener.Start(); + ThreadTracker.Add(m_listener); + + // This is the message order recommended by RFC 2812 + if (m_password != null) + m_writer.WriteLine(String.Format("PASS {0}", m_password)); + m_writer.WriteLine(String.Format("NICK {0}", m_nick)); + m_writer.Flush(); + m_writer.WriteLine(m_user); + m_writer.Flush(); + m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); + m_writer.Flush(); + + m_log.InfoFormat("[IRC-Connector-{0}]: {1} has asked to join {2}", idn, m_nick, m_ircChannel); + + } + catch (Exception e) + { + m_log.ErrorFormat("[IRC-Connector-{0}] cannot connect {1} to {2}:{3}: {4}", + idn, m_nick, m_server, m_port, e.Message); + m_connected = false; + m_pending = false; + } + + } + + return; + + } + + // Reconnect is used to force a re-cycle of the IRC connection. Should generally + // be a transparent event + + public void Reconnect() + { + m_log.DebugFormat("[IRC-Connector-{0}]: Reconnect request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel); + + // Don't do this if a Connect is in progress... + + lock (msyncConnect) + { + + if (m_connected) + { + m_log.InfoFormat("[IRC-Connector-{0}] Resetting connector", idn); + + // Mark as disconnected. This will allow the listener thread + // to exit if still in-flight. + + + // The listener thread is not aborted - it *might* actually be + // the thread that is running the Reconnect! Instead just close + // the socket and it will disappear of its own accord, once this + // processing is completed. + + try { m_writer.Close(); } catch (Exception) {} + try { m_reader.Close(); } catch (Exception) {} + try { m_tcp.Close(); } catch (Exception) {} + + m_connected = false; + m_pending = false; + + } + + } + + Connect(); + + } + + #endregion + + #region Outbound (to-IRC) message handlers + + public void PrivMsg(string pattern, string from, string region, string msg) + { + + m_log.DebugFormat("[IRC-Connector-{0}] PrivMsg to IRC from {1}: <{2}>", idn, from, + String.Format(pattern, m_ircChannel, from, region, msg)); + + // One message to the IRC server + + try + { + m_writer.WriteLine(pattern, m_ircChannel, from, region, msg); + m_writer.Flush(); + m_log.DebugFormat("[IRC-Connector-{0}]: PrivMsg from {1} in {2}: {3}", idn, from, region, msg); + } + catch (IOException) + { + m_log.ErrorFormat("[IRC-Connector-{0}]: PrivMsg I/O Error: disconnected from IRC server", idn); + Reconnect(); + } + catch (Exception ex) + { + m_log.ErrorFormat("[IRC-Connector-{0}]: PrivMsg exception : {1}", idn, ex.Message); + m_log.Debug(ex); + } + + } + + public void Send(string msg) + { + + m_log.DebugFormat("[IRC-Connector-{0}] Send to IRC : <{1}>", idn, msg); + + try + { + m_writer.WriteLine(msg); + m_writer.Flush(); + m_log.DebugFormat("[IRC-Connector-{0}] Sent command string: {1}", idn, msg); + } + catch (IOException) + { + m_log.ErrorFormat("[IRC-Connector-{0}] Disconnected from IRC server.(Send)", idn); + Reconnect(); + } + catch (Exception ex) + { + m_log.ErrorFormat("[IRC-Connector-{0}] Send exception trap: {0}", idn, ex.Message); + m_log.Debug(ex); + } + + } + + #endregion + + public void ListenerRun() + { + string inputLine; + + try + { + while (m_enabled && m_connected) + { + + if ((inputLine = m_reader.ReadLine()) == null) + throw new Exception("Listener input socket closed"); + + // m_log.Info("[IRCConnector]: " + inputLine); + + if (inputLine.Contains("PRIVMSG")) + { + + Dictionary data = ExtractMsg(inputLine); + + // Any chat ??? + if (data != null) + { + + OSChatMessage c = new OSChatMessage(); + c.Message = data["msg"]; + c.Type = ChatTypeEnum.Region; + c.Position = CenterOfRegion; + c.From = data["nick"]; + c.Sender = null; + c.SenderUUID = UUID.Zero; + + // Is message "\001ACTION foo bar\001"? + // Then change to: "/me foo bar" + + if ((1 == c.Message[0]) && c.Message.Substring(1).StartsWith("ACTION")) + c.Message = String.Format("/me {0}", c.Message.Substring(8, c.Message.Length - 9)); + + ChannelState.OSChat(this, c, false); + + } + + } + else + { + ProcessIRCCommand(inputLine); + } + } + } + catch (Exception /*e*/) + { + // m_log.ErrorFormat("[IRC-Connector-{0}]: ListenerRun exception trap: {1}", idn, e.Message); + // m_log.Debug(e); + } + + // This is potentially circular, but harmless if so. + // The connection is marked as not connected the first time + // through reconnect. + + if (m_enabled) Reconnect(); + + } + + private Regex RE = new Regex(@":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)", + RegexOptions.Multiline); + + private Dictionary ExtractMsg(string input) + { + //examines IRC commands and extracts any private messages + // which will then be reboadcast in the Sim + + // m_log.InfoFormat("[IRC-Connector-{0}]: ExtractMsg: {1}", idn, input); + + Dictionary result = null; + MatchCollection matches = RE.Matches(input); + + // Get some direct matches $1 $4 is a + if ((matches.Count == 0) || (matches.Count != 1) || (matches[0].Groups.Count != 5)) + { + // m_log.Info("[IRCConnector]: Number of matches: " + matches.Count); + // if (matches.Count > 0) + // { + // m_log.Info("[IRCConnector]: Number of groups: " + matches[0].Groups.Count); + // } + return null; + } + + result = new Dictionary(); + result.Add("nick", matches[0].Groups[1].Value); + result.Add("user", matches[0].Groups[2].Value); + result.Add("channel", matches[0].Groups[3].Value); + result.Add("msg", matches[0].Groups[4].Value); + + return result; + } + + public void BroadcastSim(string sender, string format, params string[] args) + { + try + { + OSChatMessage c = new OSChatMessage(); + c.From = sender; + c.Message = String.Format(format, args); + c.Type = ChatTypeEnum.Region; // ChatTypeEnum.Say; + c.Position = CenterOfRegion; + c.Sender = null; + c.SenderUUID = UUID.Zero; + + ChannelState.OSChat(this, c, true); + + } + catch (Exception ex) // IRC gate should not crash Sim + { + m_log.ErrorFormat("[IRC-Connector-{0}]: BroadcastSim Exception Trap: {1}\n{2}", idn, ex.Message, ex.StackTrace); + } + } + + #region IRC Command Handlers + + public void ProcessIRCCommand(string command) + { + + string[] commArgs; + string c_server = m_server; + + string pfx = String.Empty; + string cmd = String.Empty; + string parms = String.Empty; + + // ":" indicates that a prefix is present + // There are NEVER more than 17 real + // fields. A parameter that starts with + // ":" indicates that the remainder of the + // line is a single parameter value. + + commArgs = command.Split(CS_SPACE,2); + + if (commArgs[0].StartsWith(":")) + { + pfx = commArgs[0].Substring(1); + commArgs = commArgs[1].Split(CS_SPACE,2); + } + + cmd = commArgs[0]; + parms = commArgs[1]; + + // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd); + + switch (cmd) + { + + // Messages 001-004 are always sent + // following signon. + + case "001" : // Welcome ... + case "002" : // Server information + case "003" : // Welcome ... + break; + case "004" : // Server information + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + commArgs = parms.Split(CS_SPACE); + c_server = commArgs[1]; + m_server = c_server; + version = commArgs[2]; + usermod = commArgs[3]; + chanmod = commArgs[4]; + break; + case "005" : // Server information + break; + case "042" : + case "250" : + case "251" : + case "252" : + case "254" : + case "255" : + case "265" : + case "266" : + case "332" : // Subject + case "333" : // Subject owner (?) + case "353" : // Name list + case "366" : // End-of-Name list marker + case "372" : // MOTD body + case "375" : // MOTD start + m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + break; + case "376" : // MOTD end + m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + motd = true; + break; + case "451" : // Not registered + break; + case "433" : // Nickname in use + // Gen a new name + m_nick = m_baseNick + Util.RandomClass.Next(1, 99); + m_log.ErrorFormat("[IRC-Connector-{0}]: [{1}] IRC SERVER reports NicknameInUse, trying {2}", idn, cmd, m_nick); + // Retry + m_writer.WriteLine(String.Format("NICK {0}", m_nick)); + m_writer.Flush(); + m_writer.WriteLine(m_user); + m_writer.Flush(); + m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); + m_writer.Flush(); + break; + case "479" : // Bad channel name, etc. This will never work, so disable the connection + m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] Connector disabled", idn, cmd); + m_enabled = false; + m_connected = false; + m_pending = false; + break; + case "NOTICE" : + m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + break; + case "ERROR" : + m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + if (parms.Contains("reconnect too fast")) + ICCD_PERIOD++; + m_pending = false; + Reconnect(); + break; + case "PING" : + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + m_writer.WriteLine(String.Format("PONG {0}", parms)); + m_writer.Flush(); + break; + case "PONG" : + break; + case "JOIN": + if (m_pending) + { + m_log.InfoFormat("[IRC-Connector-{0}] [{1}] Connected", idn, cmd); + m_pending = false; + } + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + eventIrcJoin(pfx, cmd, parms); + break; + case "PART": + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + eventIrcPart(pfx, cmd, parms); + break; + case "MODE": + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + eventIrcMode(pfx, cmd, parms); + break; + case "NICK": + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + eventIrcNickChange(pfx, cmd, parms); + break; + case "KICK": + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + eventIrcKick(pfx, cmd, parms); + break; + case "QUIT": + m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); + eventIrcQuit(pfx, cmd, parms); + break; + default : + m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms); + break; + } + + // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd); + + } + + public void eventIrcJoin(string prefix, string command, string parms) + { + string[] args = parms.Split(CS_SPACE,2); + string IrcUser = prefix.Split('!')[0]; + string IrcChannel = args[0]; + + if (IrcChannel.StartsWith(":")) + IrcChannel = IrcChannel.Substring(1); + + m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCJoin {1}:{2}", idn, m_server, m_ircChannel); + BroadcastSim(IrcUser, "/me joins {0}", IrcChannel); + } + + public void eventIrcPart(string prefix, string command, string parms) + { + string[] args = parms.Split(CS_SPACE,2); + string IrcUser = prefix.Split('!')[0]; + string IrcChannel = args[0]; + + m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel); + BroadcastSim(IrcUser, "/me parts {0}", IrcChannel); + } + + public void eventIrcMode(string prefix, string command, string parms) + { + string[] args = parms.Split(CS_SPACE,2); + string UserMode = args[1]; + + m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel); + if (UserMode.Substring(0, 1) == ":") + { + UserMode = UserMode.Remove(0, 1); + } + } + + public void eventIrcNickChange(string prefix, string command, string parms) + { + string[] args = parms.Split(CS_SPACE,2); + string UserOldNick = prefix.Split('!')[0]; + string UserNewNick = args[0].Remove(0, 1); + + m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCNickChange {1}:{2}", idn, m_server, m_ircChannel); + BroadcastSim(UserOldNick, "/me is now known as {0}", UserNewNick); + } + + public void eventIrcKick(string prefix, string command, string parms) + { + string[] args = parms.Split(CS_SPACE,3); + string UserKicker = prefix.Split('!')[0]; + string IrcChannel = args[0]; + string UserKicked = args[1]; + string KickMessage = args[2]; + + m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel); + BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage); + + if (UserKicked == m_nick) + { + BroadcastSim(m_nick, "Hey, that was me!!!"); + } + + } + + public void eventIrcQuit(string prefix, string command, string parms) + { + string IrcUser = prefix.Split('!')[0]; + string QuitMessage = parms; + + m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel); + BroadcastSim(IrcUser, "/me quits saying \"{0}\"", QuitMessage); + } + + #endregion + + #region Connector Watch Dog + + // A single watch dog monitors extant connectors and makes sure that they + // are re-connected as necessary. If a connector IS connected, then it is + // pinged, but only if a PING period has elapsed. + + protected static void WatchdogHandler(Object source, ElapsedEventArgs args) + { + + // m_log.InfoFormat("[IRC-Watchdog] Status scan"); + + _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger + _icc_++; // increment the inter-consecutive-connect-delay counter + + foreach (IRCConnector connector in m_connectors) + { + if (connector.Enabled) + { + if (!connector.Connected) + { + try + { + // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); + connector.Connect(); + } + catch (Exception e) + { + m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message); + } + } + else + { + + if (connector.m_pending) + { + if (connector.m_timeout == 0) + { + m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); + connector.Reconnect(); + } + else + connector.m_timeout--; + } + + if (_pdk_ == 0) + { + try + { + connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); + connector.m_writer.Flush(); + } + catch (Exception /*e*/) + { + // m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); + // m_log.Debug(e); + connector.Reconnect(); + } + } + + } + } + } + + // m_log.InfoFormat("[IRC-Watchdog] Status scan completed"); + + } + + #endregion + + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs new file mode 100644 index 0000000..6733120 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -0,0 +1,424 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text.RegularExpressions; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Chat +{ + // An instance of this class exists for every active region + + internal class RegionState + { + + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(128, 128, 20); + private const int DEBUG_CHANNEL = 2147483647; + + private static int _idk_ = 0; + + // Runtime variables; these values are assigned when the + // IrcState is created and remain constant thereafter. + + internal string Region = String.Empty; + internal string Host = String.Empty; + internal string LocX = String.Empty; + internal string LocY = String.Empty; + internal string MA1 = String.Empty; + internal string MA2 = String.Empty; + internal string IDK = String.Empty; + + // System values - used only be the IRC classes themselves + + internal ChannelState cs = null; // associated IRC configuration + internal Scene scene = null; // associated scene + internal IConfig config = null; // configuration file reference + internal bool enabled = true; + + // This list is used to keep track of who is here, and by + // implication, who is not. + + internal List clients = new List(); + + // Setup runtime variable values + + public RegionState(Scene p_scene, IConfig p_config) + { + + scene = p_scene; + config = p_config; + + Region = scene.RegionInfo.RegionName; + Host = scene.RegionInfo.ExternalHostName; + LocX = Convert.ToString(scene.RegionInfo.RegionLocX); + LocY = Convert.ToString(scene.RegionInfo.RegionLocY); + MA1 = scene.RegionInfo.MasterAvatarFirstName; + MA2 = scene.RegionInfo.MasterAvatarLastName; + IDK = Convert.ToString(_idk_++); + + // OpenChannel conditionally establishes a connection to the + // IRC server. The request will either succeed, or it will + // throw an exception. + + ChannelState.OpenChannel(this, config); + + // Connect channel to world events + + scene.EventManager.OnChatFromWorld += OnSimChat; + scene.EventManager.OnChatFromClient += OnSimChat; + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; + scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; + + m_log.InfoFormat("[IRC-Region {0}] Initialization complete", Region); + + } + + // Auto cleanup when abandoned + + ~RegionState() + { + if (cs != null) + cs.RemoveRegion(this); + } + + // Called by PostInitialize after all regions have been created + + public void Open() + { + cs.Open(this); + enabled = true; + } + + // Called by IRCBridgeModule.Close immediately prior to unload + // of the module for this region. This happens when the region + // is being removed or the server is terminating. The IRC + // BridgeModule will remove the region from the region list + // when control returns. + + public void Close() + { + enabled = false; + cs.Close(this); + } + + // The agent has disconnected, cleanup associated resources + + private void OnClientLoggedOut(IClientAPI client) + { + try + { + if (clients.Contains(client)) + { + if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) + { + m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name); + cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); + } + client.OnLogout -= OnClientLoggedOut; + client.OnConnectionClosed -= OnClientLoggedOut; + clients.Remove(client); + } + } + catch (Exception ex) + { + m_log.ErrorFormat("[IRC-Region {0}]: ClientLoggedOut exception: {1}", Region, ex.Message); + m_log.Debug(ex); + } + } + + // This event indicates that the agent has left the building. We should treat that the same + // as if the agent has logged out (we don't want cross-region noise - or do we?) + + private void OnMakeChildAgent(ScenePresence presence) + { + + IClientAPI client = presence.ControllingClient; + + try + { + if (clients.Contains(client)) + { + if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) + { + string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); + m_log.DebugFormat("[IRC-Region {0}] {1} has left", Region, clientName); + cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", clientName)); + } + client.OnLogout -= OnClientLoggedOut; + client.OnConnectionClosed -= OnClientLoggedOut; + clients.Remove(client); + } + } + catch (Exception ex) + { + m_log.ErrorFormat("[IRC-Region {0}]: MakeChildAgent exception: {1}", Region, ex.Message); + m_log.Debug(ex); + } + + } + + // An agent has entered the region (from another region). Add the client to the locally + // known clients list + + private void OnMakeRootAgent(ScenePresence presence) + { + + IClientAPI client = presence.ControllingClient; + + try + { + if (!clients.Contains(client)) + { + client.OnLogout += OnClientLoggedOut; + client.OnConnectionClosed += OnClientLoggedOut; + clients.Add(client); + if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) + { + string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); + m_log.DebugFormat("[IRC-Region {0}] {1} has arrived", Region, clientName); + cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has arrived", clientName)); + } + } + } + catch (Exception ex) + { + m_log.ErrorFormat("[IRC-Region {0}]: MakeRootAgent exception: {1}", Region, ex.Message); + m_log.Debug(ex); + } + + } + + // This handler detects chat events int he virtual world. + + public void OnSimChat(Object sender, OSChatMessage msg) + { + + // early return if this comes from the IRC forwarder + + if (cs.irc.Equals(sender)) return; + + // early return if nothing to forward + + if (msg.Message.Length == 0) return; + + // check for commands coming from avatars or in-world + // object (if commands are enabled) + + if (cs.CommandsEnabled && msg.Channel == cs.CommandChannel) + { + + m_log.DebugFormat("[IRC-Region {0}] command on channel {1}: {2}", Region, msg.Channel, msg.Message); + + string[] messages = msg.Message.Split(' '); + string command = messages[0].ToLower(); + + try + { + switch (command) + { + + // These commands potentially require a change in the + // underlying ChannelState. + + case "server": + cs.Close(this); + cs = cs.UpdateServer(this, messages[1]); + cs.Open(this); + break; + case "port": + cs.Close(this); + cs = cs.UpdatePort(this, messages[1]); + cs.Open(this); + break; + case "channel": + cs.Close(this); + cs = cs.UpdateChannel(this, messages[1]); + cs.Open(this); + break; + case "nick": + cs.Close(this); + cs = cs.UpdateNickname(this, messages[1]); + cs.Open(this); + break; + + // These may also (but are less likely) to require a + // change in ChannelState. + + case "client-reporting": + cs = cs.UpdateClientReporting(this, messages[1]); + break; + case "in-channel": + cs = cs.UpdateRelayIn(this, messages[1]); + break; + case "out-channel": + cs = cs.UpdateRelayOut(this, messages[1]); + break; + + // These are all taken to be temporary changes in state + // so the underlying connector remains intact. But note + // that with regions sharing a connector, there could + // be interference. + + case "close": + enabled = false; + cs.Close(this); + break; + + case "connect": + enabled = true; + cs.Open(this); + break; + + case "reconnect": + enabled = true; + cs.Close(this); + cs.Open(this); + break; + + // This one is harmless as far as we can judge from here. + // If it is not, then the complaints will eventually make + // that evident. + + default: + m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", + Region, msg.Message); + cs.irc.Send(msg.Message); + break; + } + } + catch (Exception ex) + { + m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}", + Region, ex.Message); + m_log.Debug(ex); + } + + return; + + } + + // The command channel remains enabled, even if we have otherwise disabled the IRC + // interface. + + if (!enabled) + return; + + // drop messages unless they are on a valid in-world + // channel as configured in the ChannelState + + if (!cs.ValidInWorldChannels.Contains(msg.Channel)) + { + m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel); + return; + } + + ScenePresence avatar = null; + string fromName = msg.From; + + if (msg.Sender != null) + { + avatar = scene.GetScenePresence(msg.Sender.AgentId); + if (avatar != null) fromName = avatar.Name; + } + + if (!cs.irc.Connected) + { + m_log.WarnFormat("[IRC-Region {0}] IRCConnector not connected: dropping message from {1}", Region, fromName); + return; + } + + m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); + + if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) + { + string txt = msg.Message; + if (txt.StartsWith("/me ")) + txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4)); + + cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt); + return; + } + + if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && + msg.Channel == cs.RelayChannelOut) + { + Match m = cs.AccessPasswordRegex.Match(msg.Message); + if (null != m) + { + m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), + m.Groups["message"].ToString()); + cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(), + scene.RegionInfo.RegionName, m.Groups["message"].ToString()); + } + } + } + + // This method gives the region an opportunity to interfere with + // message delivery. For now we just enforce the enable/disable + // flag. + + internal void OSChat(Object irc, OSChatMessage msg) + { + if (enabled) + { + // m_log.DebugFormat("[IRC-OSCHAT] Region {0} being sent message", region.Region); + msg.Scene = scene; + scene.EventManager.TriggerOnChatBroadcast(irc, msg); + } + } + + // This supports any local message traffic that might be needed in + // support of command processing. At present there is none. + + internal void LocalChat(string msg) + { + if (enabled) + { + OSChatMessage osm = new OSChatMessage(); + osm.From = "IRC Agent"; + osm.Message = msg; + osm.Type = ChatTypeEnum.Region; + osm.Position = CenterOfRegion; + osm.Sender = null; + osm.SenderUUID = OpenMetaverse.UUID.Zero; // Hmph! Still? + osm.Channel = 0; + OSChat(this, osm); + } + } + + } + +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs new file mode 100644 index 0000000..bb46b11 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -0,0 +1,604 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.CoreModules.Avatar.Chat; + +namespace OpenSim.Region.OptionalModules.Avatar.Concierge +{ + public class ConciergeModule : ChatModule, IRegionModule + { + private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private const int DEBUG_CHANNEL = 2147483647; + + private List _scenes = new List(); + private List _conciergedScenes = new List(); + private Dictionary> _sceneAttendees = + new Dictionary>(); + private Dictionary _attendeeNames = + new Dictionary(); + + private bool _replacingChatModule = false; + + private IConfig _config; + + private string _whoami = "conferencier"; + private Regex _regions = null; + private string _welcomes = null; + private int _conciergeChannel = 42; + private string _announceEntering = "{0} enters {1} (now {2} visitors in this region)"; + private string _announceLeaving = "{0} leaves {1} (back to {2} visitors in this region)"; + private string _xmlRpcPassword = String.Empty; + private string _brokerURI = String.Empty; + + internal object _syncy = new object(); + + #region IRegionModule Members + public override void Initialise(Scene scene, IConfigSource config) + { + try + { + if ((_config = config.Configs["Concierge"]) == null) + { + //_log.InfoFormat("[Concierge]: no configuration section [Concierge] in OpenSim.ini: module not configured"); + return; + } + + if (!_config.GetBoolean("enabled", false)) + { + //_log.InfoFormat("[Concierge]: module disabled by OpenSim.ini configuration"); + return; + } + } + catch (Exception) + { + _log.Info("[Concierge]: module not configured"); + return; + } + + // check whether ChatModule has been disabled: if yes, + // then we'll "stand in" + try + { + if (config.Configs["Chat"] == null) + { + _replacingChatModule = false; + } + else + { + _replacingChatModule = !config.Configs["Chat"].GetBoolean("enabled", true); + } + } + catch (Exception) + { + _replacingChatModule = false; + } + _log.InfoFormat("[Concierge] {0} ChatModule", _replacingChatModule ? "replacing" : "not replacing"); + + + // take note of concierge channel and of identity + _conciergeChannel = config.Configs["Concierge"].GetInt("concierge_channel", _conciergeChannel); + _whoami = _config.GetString("whoami", "conferencier"); + _welcomes = _config.GetString("welcomes", _welcomes); + _announceEntering = _config.GetString("announce_entering", _announceEntering); + _announceLeaving = _config.GetString("announce_leaving", _announceLeaving); + _xmlRpcPassword = _config.GetString("password", _xmlRpcPassword); + _brokerURI = _config.GetString("broker", _brokerURI); + + _log.InfoFormat("[Concierge] reporting as \"{0}\" to our users", _whoami); + + // calculate regions Regex + if (_regions == null) + { + string regions = _config.GetString("regions", String.Empty); + if (!String.IsNullOrEmpty(regions)) + { + _regions = new Regex(@regions, RegexOptions.Compiled | RegexOptions.IgnoreCase); + } + } + + scene.CommsManager.HttpServer.AddXmlRPCHandler("concierge_update_welcome", XmlRpcUpdateWelcomeMethod, false); + + lock (_syncy) + { + if (!_scenes.Contains(scene)) + { + _scenes.Add(scene); + + if (_regions == null || _regions.IsMatch(scene.RegionInfo.RegionName)) + _conciergedScenes.Add(scene); + + // subscribe to NewClient events + scene.EventManager.OnNewClient += OnNewClient; + + // subscribe to *Chat events + scene.EventManager.OnChatFromWorld += OnChatFromWorld; + if (!_replacingChatModule) + scene.EventManager.OnChatFromClient += OnChatFromClient; + scene.EventManager.OnChatBroadcast += OnChatBroadcast; + + // subscribe to agent change events + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; + scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; + } + } + _log.InfoFormat("[Concierge]: initialized for {0}", scene.RegionInfo.RegionName); + } + + public override void PostInitialise() + { + } + + public override void Close() + { + } + + public override string Name + { + get { return "ConciergeModule"; } + } + + public override bool IsSharedModule + { + get { return true; } + } + + #endregion + + #region ISimChat Members + public override void OnChatBroadcast(Object sender, OSChatMessage c) + { + if (_replacingChatModule) + { + // distribute chat message to each and every avatar in + // the region + base.OnChatBroadcast(sender, c); + } + + // TODO: capture logic + return; + } + + public override void OnChatFromClient(Object sender, OSChatMessage c) + { + if (_replacingChatModule) + { + // replacing ChatModule: need to redistribute + // ChatFromClient to interested subscribers + c = FixPositionOfChatMessage(c); + + Scene scene = (Scene)c.Scene; + scene.EventManager.TriggerOnChatFromClient(sender, c); + + if (_conciergedScenes.Contains(c.Scene)) + { + // when we are replacing ChatModule, we treat + // OnChatFromClient like OnChatBroadcast for + // concierged regions, effectively extending the + // range of chat to cover the whole + // region. however, we don't do this for whisper + // (got to have some privacy) + if (c.Type != ChatTypeEnum.Whisper) + { + base.OnChatBroadcast(sender, c); + return; + } + } + + // redistribution will be done by base class + base.OnChatFromClient(sender, c); + } + + // TODO: capture chat + return; + } + + public override void OnChatFromWorld(Object sender, OSChatMessage c) + { + if (_replacingChatModule) + { + if (_conciergedScenes.Contains(c.Scene)) + { + // when we are replacing ChatModule, we treat + // OnChatFromClient like OnChatBroadcast for + // concierged regions, effectively extending the + // range of chat to cover the whole + // region. however, we don't do this for whisper + // (got to have some privacy) + if (c.Type != ChatTypeEnum.Whisper) + { + base.OnChatBroadcast(sender, c); + return; + } + } + + base.OnChatFromWorld(sender, c); + } + return; + } + #endregion + + + public override void OnNewClient(IClientAPI client) + { + client.OnLogout += OnClientLoggedOut; + + if (_replacingChatModule) + client.OnChatFromClient += OnChatFromClient; + } + + + + public void OnClientLoggedOut(IClientAPI client) + { + client.OnLogout -= OnClientLoggedOut; + client.OnConnectionClosed -= OnClientLoggedOut; + + if (_conciergedScenes.Contains(client.Scene)) + { + _log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, client.Scene.RegionInfo.RegionName); + RemoveFromAttendeeList(client.AgentId, client.Name, client.Scene); + AnnounceToAgentsRegion(client.Scene, String.Format(_announceLeaving, client.Name, client.Scene.RegionInfo.RegionName, + _sceneAttendees[client.Scene].Count)); + UpdateBroker(client.Scene); + } + } + + + public void OnMakeRootAgent(ScenePresence agent) + { + if (_conciergedScenes.Contains(agent.Scene)) + { + _log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, agent.Scene.RegionInfo.RegionName); + AddToAttendeeList(agent.UUID, agent.Name, agent.Scene); + WelcomeAvatar(agent, agent.Scene); + AnnounceToAgentsRegion(agent.Scene, String.Format(_announceEntering, agent.Name, agent.Scene.RegionInfo.RegionName, + _sceneAttendees[agent.Scene].Count)); + UpdateBroker(agent.Scene); + } + } + + + public void OnMakeChildAgent(ScenePresence agent) + { + if (_conciergedScenes.Contains(agent.Scene)) + { + _log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, agent.Scene.RegionInfo.RegionName); + RemoveFromAttendeeList(agent.UUID, agent.Name, agent.Scene); + AnnounceToAgentsRegion(agent.Scene, String.Format(_announceLeaving, agent.Name, agent.Scene.RegionInfo.RegionName, + _sceneAttendees[agent.Scene].Count)); + UpdateBroker(agent.Scene); + } + } + + protected void AddToAttendeeList(UUID agentID, string name, Scene scene) + { + lock (_sceneAttendees) + { + if (!_sceneAttendees.ContainsKey(scene)) + _sceneAttendees[scene] = new List(); + + List attendees = _sceneAttendees[scene]; + if (!attendees.Contains(agentID)) + { + attendees.Add(agentID); + _attendeeNames[agentID] = name; + } + } + } + + protected void RemoveFromAttendeeList(UUID agentID, String name, IScene scene) + { + lock (_sceneAttendees) + { + if (!_sceneAttendees.ContainsKey(scene)) + { + _log.WarnFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); + return; + } + + List attendees = _sceneAttendees[scene]; + if (!attendees.Contains(agentID)) + { + _log.WarnFormat("[Concierge]: avatar {0} must have sneaked in to region {1} earlier", + name, scene.RegionInfo.RegionName); + return; + } + + attendees.Remove(agentID); + _attendeeNames.Remove(agentID); + } + } + + protected void UpdateBroker(IScene scene) + { + if (String.IsNullOrEmpty(_brokerURI)) + return; + + string uri = String.Format(_brokerURI, scene.RegionInfo.RegionName, scene.RegionInfo.RegionID); + + // get attendee list for the scene + List attendees; + lock (_sceneAttendees) + { + if (!_sceneAttendees.ContainsKey(scene)) + { + _log.DebugFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); + return; + } + + attendees = _sceneAttendees[scene]; + } + + // create XML sniplet + StringBuilder list = new StringBuilder(); + if (0 == attendees.Count) + { + list.Append(String.Format("", + scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, + DateTime.UtcNow.ToString("s"))); + } + else + { + list.Append(String.Format("\n", + attendees.Count, scene.RegionInfo.RegionName, + scene.RegionInfo.RegionID, + DateTime.UtcNow.ToString("s"))); + foreach (UUID uuid in attendees) + { + string name = _attendeeNames[uuid]; + list.Append(String.Format(" \n", name, uuid)); + } + list.Append(""); + } + string payload = list.ToString(); + + // post via REST to broker + HttpWebRequest updatePost = WebRequest.Create(uri) as HttpWebRequest; + updatePost.Method = "POST"; + updatePost.ContentType = "text/xml"; + updatePost.ContentLength = payload.Length; + updatePost.UserAgent = "OpenSim.Concierge"; + + try + { + StreamWriter payloadStream = new StreamWriter(updatePost.GetRequestStream()); + payloadStream.Write(payload); + payloadStream.Close(); + + updatePost.BeginGetResponse(UpdateBrokerDone, updatePost); + _log.DebugFormat("[Concierge] async broker POST to {0} started", uri); + } + catch (WebException we) + { + _log.ErrorFormat("[Concierge] async broker POST to {0} failed: {1}", uri, we.Status); + } + } + + private void UpdateBrokerDone(IAsyncResult result) + { + HttpWebRequest updatePost = null; + try + { + updatePost = result.AsyncState as HttpWebRequest; + using (HttpWebResponse response = updatePost.EndGetResponse(result) as HttpWebResponse) + { + _log.DebugFormat("[Concierge] broker update: status {0}", response.StatusCode); + } + } + catch (WebException we) + { + string uri = updatePost.RequestUri.OriginalString; + _log.ErrorFormat("[Concierge] broker update to {0} failed with status {1}", uri, we.Status); + if (null != we.Response) + { + using (HttpWebResponse resp = we.Response as HttpWebResponse) + { + _log.ErrorFormat("[Concierge] response from {0} status code: {1}", uri, resp.StatusCode); + _log.ErrorFormat("[Concierge] response from {0} status desc: {1}", uri, resp.StatusDescription); + _log.ErrorFormat("[Concierge] response from {0} server: {1}", uri, resp.Server); + + if (resp.ContentLength > 0) + { + StreamReader content = new StreamReader(resp.GetResponseStream()); + _log.ErrorFormat("[Concierge] response from {0} content: {1}", uri, content.ReadToEnd()); + content.Close(); + } + } + } + } + } + + protected void WelcomeAvatar(ScenePresence agent, Scene scene) + { + // welcome mechanics: check whether we have a welcomes + // directory set and wether there is a region specific + // welcome file there: if yes, send it to the agent + if (!String.IsNullOrEmpty(_welcomes)) + { + string[] welcomes = new string[] { + Path.Combine(_welcomes, agent.Scene.RegionInfo.RegionName), + Path.Combine(_welcomes, "DEFAULT")}; + foreach (string welcome in welcomes) + { + if (File.Exists(welcome)) + { + try + { + string[] welcomeLines = File.ReadAllLines(welcome); + foreach (string l in welcomeLines) + { + AnnounceToAgent(agent, String.Format(l, agent.Name, scene.RegionInfo.RegionName, _whoami)); + } + } + catch (IOException ioe) + { + _log.ErrorFormat("[Concierge]: run into trouble reading welcome file {0} for region {1} for avatar {2}: {3}", + welcome, scene.RegionInfo.RegionName, agent.Name, ioe); + } + catch (FormatException fe) + { + _log.ErrorFormat("[Concierge]: welcome file {0} is malformed: {1}", welcome, fe); + } + } + return; + } + _log.DebugFormat("[Concierge]: no welcome message for region {0}", scene.RegionInfo.RegionName); + } + } + + static private Vector3 PosOfGod = new Vector3(128, 128, 9999); + + // protected void AnnounceToAgentsRegion(Scene scene, string msg) + // { + // ScenePresence agent = null; + // if ((client.Scene is Scene) && (client.Scene as Scene).TryGetAvatar(client.AgentId, out agent)) + // AnnounceToAgentsRegion(agent, msg); + // else + // _log.DebugFormat("[Concierge]: could not find an agent for client {0}", client.Name); + // } + + protected void AnnounceToAgentsRegion(IScene scene, string msg) + { + OSChatMessage c = new OSChatMessage(); + c.Message = msg; + c.Type = ChatTypeEnum.Say; + c.Channel = 0; + c.Position = PosOfGod; + c.From = _whoami; + c.Sender = null; + c.SenderUUID = UUID.Zero; + c.Scene = scene; + + if (scene is Scene) + (scene as Scene).EventManager.TriggerOnChatBroadcast(this, c); + } + + protected void AnnounceToAgent(ScenePresence agent, string msg) + { + OSChatMessage c = new OSChatMessage(); + c.Message = msg; + c.Type = ChatTypeEnum.Say; + c.Channel = 0; + c.Position = PosOfGod; + c.From = _whoami; + c.Sender = null; + c.SenderUUID = UUID.Zero; + c.Scene = agent.Scene; + + agent.ControllingClient.SendChatMessage(msg, (byte) ChatTypeEnum.Say, PosOfGod, _whoami, UUID.Zero, + (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); + } + + private static void checkStringParameters(XmlRpcRequest request, string[] param) + { + Hashtable requestData = (Hashtable) request.Params[0]; + foreach (string p in param) + { + if (!requestData.Contains(p)) + throw new Exception(String.Format("missing string parameter {0}", p)); + if (String.IsNullOrEmpty((string)requestData[p])) + throw new Exception(String.Format("parameter {0} is empty", p)); + } + } + + public XmlRpcResponse XmlRpcUpdateWelcomeMethod(XmlRpcRequest request) + { + _log.Info("[Concierge]: processing UpdateWelcome request"); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + + try + { + Hashtable requestData = (Hashtable)request.Params[0]; + checkStringParameters(request, new string[] { "password", "region", "welcome" }); + + // check password + if (!String.IsNullOrEmpty(_xmlRpcPassword) && + (string)requestData["password"] != _xmlRpcPassword) throw new Exception("wrong password"); + + if (String.IsNullOrEmpty(_welcomes)) + throw new Exception("welcome templates are not enabled, ask your OpenSim operator to set the \"welcomes\" option in the [Concierge] section of OpenSim.ini"); + + string msg = (string)requestData["welcome"]; + if (String.IsNullOrEmpty(msg)) + throw new Exception("empty parameter \"welcome\""); + + string regionName = (string)requestData["region"]; + IScene scene = _scenes.Find(delegate(IScene s) { return s.RegionInfo.RegionName == regionName; }); + if (scene == null) + throw new Exception(String.Format("unknown region \"{0}\"", regionName)); + + if (!_conciergedScenes.Contains(scene)) + throw new Exception(String.Format("region \"{0}\" is not a concierged region.", regionName)); + + string welcome = Path.Combine(_welcomes, regionName); + if (File.Exists(welcome)) + { + _log.InfoFormat("[Concierge]: UpdateWelcome: updating existing template \"{0}\"", welcome); + string welcomeBackup = String.Format("{0}~", welcome); + if (File.Exists(welcomeBackup)) + File.Delete(welcomeBackup); + File.Move(welcome, welcomeBackup); + } + File.WriteAllText(welcome, msg); + + responseData["success"] = "true"; + response.Value = responseData; + } + catch (Exception e) + { + _log.InfoFormat("[Concierge]: UpdateWelcome failed: {0}", e.Message); + + responseData["success"] = "false"; + responseData["error"] = e.Message; + + response.Value = responseData; + } + _log.Debug("[Concierge]: done processing UpdateWelcome request"); + return response; + } + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeServer.py b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeServer.py new file mode 100755 index 0000000..1c088fb --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeServer.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# +# 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 OpenSim 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. +# + +import logging +import BaseHTTPServer +import optparse +import xml.etree.ElementTree as ET +import xml.parsers.expat + + +# enable debug level logging +logging.basicConfig(level = logging.DEBUG, + format='%(asctime)s %(levelname)s %(message)s') + +options = None + +# subclassed HTTPRequestHandler +class ConciergeHandler(BaseHTTPServer.BaseHTTPRequestHandler): + def logRequest(self): + logging.info('[ConciergeHandler] %(command)s request: %(host)s:%(port)d --- %(path)s', + dict(command = self.command, + host = self.client_address[0], + port = self.client_address[1], + path = self.path)) + + def logResponse(self, status): + logging.info('[ConciergeHandler] %(command)s returned %(status)d', + dict(command = self.command, + status = status)) + + + def do_HEAD(self): + self.logRequest() + + self.send_response(200) + self.send_header('Content-type', 'text/html') + self.end_headers() + + self.logResponse(200) + + def dumpXml(self, xml): + logging.debug('[ConciergeHandler] %s', xml.tag) + for attr in xml.attrib: + logging.debug('[ConciergeHandler] %s [%s] %s', xml.tag, attr, xml.attrib[attr]) + for kid in xml.getchildren(): + self.dumpXml(kid) + + def do_POST(self): + self.logRequest() + hdrs = {} + for hdr in self.headers.headers: + logging.debug('[ConciergeHandler] POST: header: %s', hdr.rstrip()) + + length = int(self.headers.getheader('Content-Length')) + content = self.rfile.read(length) + self.rfile.close() + + logging.debug('[ConciergeHandler] POST: content: %s', content) + try: + postXml = ET.fromstring(content) + self.dumpXml(postXml) + except xml.parsers.expat.ExpatError, xmlError: + logging.error('[ConciergeHandler] POST illformed:%s', xmlError) + self.send_response(500) + return + + if not options.fail: + self.send_response(200) + self.send_header('Content-Type', 'text/html') + self.send_header('Content-Length', len('')) + self.end_headers() + self.logResponse(200) + self.wfile.write('') + self.wfile.close() + else: + self.send_response(500) + self.send_header('Content-Type', 'text/html') + self.send_header('Content-Length', len('gotcha!')) + self.end_headers() + self.wfile.write('gotcha!') + self.wfile.close() + + self.logResponse(500) + + def log_request(code, size): + pass + +if __name__ == '__main__': + + logging.info('[ConciergeServer] Concierge Broker Test Server starting') + + parser = optparse.OptionParser() + parser.add_option('-p', '--port', dest = 'port', help = 'port to listen on', metavar = 'PORT') + parser.add_option('-f', '--fail', dest = 'fail', action = 'store_true', help = 'always fail POST requests') + + (options, args) = parser.parse_args() + + httpServer = BaseHTTPServer.HTTPServer(('', 8080), ConciergeHandler) + try: + httpServer.serve_forever() + except KeyboardInterrupt: + logging.info('[ConciergeServer] terminating') + + httpServer.server_close() diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs new file mode 100644 index 0000000..c827214 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs @@ -0,0 +1,292 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Reflection; +using OpenMetaverse; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Communications.Capabilities; +using OpenSim.Framework.Servers; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps=OpenSim.Framework.Communications.Capabilities.Caps; + +namespace OpenSim.Region.OptionalModules.Avatar.Voice.AsterixVoice +{ + public class AsteriskVoiceModule : IRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; + private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; + + private string m_asterisk; + private string m_asterisk_password; + private string m_asterisk_salt; + private int m_asterisk_timeout; + private string m_confDomain; + private IConfig m_config; + private Scene m_scene; + private string m_sipDomain; + + #region IRegionModule Members + + public void Initialise(Scene scene, IConfigSource config) + { + m_scene = scene; + m_config = config.Configs["AsteriskVoice"]; + + if (null == m_config) + { + m_log.Info("[ASTERISKVOICE] no config found, plugin disabled"); + return; + } + + if (!m_config.GetBoolean("enabled", false)) + { + m_log.Info("[ASTERISKVOICE] plugin disabled by configuration"); + return; + } + m_log.Info("[ASTERISKVOICE] plugin enabled"); + + try + { + m_sipDomain = m_config.GetString("sip_domain", String.Empty); + m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain); + + m_confDomain = m_config.GetString("conf_domain", String.Empty); + m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain); + + m_asterisk = m_config.GetString("asterisk_frontend", String.Empty); + m_asterisk_password = m_config.GetString("asterisk_password", String.Empty); + m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000); + m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff"); + if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter"); + if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter"); + m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk); + + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + } + catch (Exception e) + { + m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message); + m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString()); + return; + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "AsteriskVoiceModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + + #endregion + + public void OnRegisterCaps(UUID agentID, Caps caps) + { + m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + string capsBase = "/CAPS/" + caps.CapsObjectPath; + caps.RegisterHandler("ParcelVoiceInfoRequest", + new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ParcelVoiceInfoRequest(request, path, param, + agentID, caps); + })); + caps.RegisterHandler("ProvisionVoiceAccountRequest", + new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ProvisionVoiceAccountRequest(request, path, param, + agentID, caps); + })); + } + + /// + /// Callback for a client request for ParcelVoiceInfo + /// + /// + /// + /// + /// + /// + /// + public string ParcelVoiceInfoRequest(string request, string path, string param, + UUID agentID, Caps caps) + { + // we need to do: + // - send channel_uri: as "sip:regionID@m_sipDomain" + try + { + m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", + request, path, param); + + + // setup response to client + Hashtable creds = new Hashtable(); + creds["channel_uri"] = String.Format("sip:{0}@{1}", + m_scene.RegionInfo.RegionID, m_sipDomain); + + string regionName = m_scene.RegionInfo.RegionName; + ScenePresence avatar = m_scene.GetScenePresence(agentID); + if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); + LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + + LLSDParcelVoiceInfoResponse parcelVoiceInfo = + new LLSDParcelVoiceInfoResponse(regionName, land.LocalID, creds); + + string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); + + + // update region on asterisk-opensim frontend + Hashtable requestData = new Hashtable(); + requestData["admin_password"] = m_asterisk_password; + requestData["region"] = m_scene.RegionInfo.RegionID.ToString(); + if (!String.IsNullOrEmpty(m_confDomain)) + { + requestData["region"] += String.Format("@{0}", m_confDomain); + } + + ArrayList SendParams = new ArrayList(); + SendParams.Add(requestData); + XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams); + XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); + Hashtable responseData = (Hashtable) updateAccountResponse.Value; + + if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed"); + + bool success = Convert.ToBoolean((string) responseData["success"]); + if (!success) throw new Exception("region_update failed"); + + + m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r); + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message); + m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString()); + + return "undef"; + } + } + + /// + /// Callback for a client request for Voice Account Details + /// + /// + /// + /// + /// + /// + /// + public string ProvisionVoiceAccountRequest(string request, string path, string param, + UUID agentID, Caps caps) + { + // we need to + // - get user data from UserProfileCacheService + // - generate nonce for user voice account password + // - issue XmlRpc request to asterisk opensim front end: + // + user: base 64 encoded user name (otherwise SL + // client is unhappy) + // + password: nonce + // - the XmlRpc call to asteris-opensim was successful: + // send account details back to client + try + { + m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", + request, path, param); + + // get user data & prepare voice account response + string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); + voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); + + CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); + if (null == userInfo) throw new Exception("cannot get user details"); + + // we generate a nonce everytime + string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt); + LLSDVoiceAccountResponse voiceAccountResponse = + new LLSDVoiceAccountResponse(voiceUser, voicePassword); + string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); + m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); + + + // update user account on asterisk frontend + Hashtable requestData = new Hashtable(); + requestData["admin_password"] = m_asterisk_password; + requestData["username"] = voiceUser; + if (!String.IsNullOrEmpty(m_sipDomain)) + { + requestData["username"] += String.Format("@{0}", m_sipDomain); + } + requestData["password"] = voicePassword; + + ArrayList SendParams = new ArrayList(); + SendParams.Add(requestData); + XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams); + XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); + Hashtable responseData = (Hashtable) updateAccountResponse.Value; + + if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed"); + + bool success = Convert.ToBoolean((string) responseData["success"]); + if (!success) throw new Exception("account_update failed"); + + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); + m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString()); + + return "undef"; + } + } + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs new file mode 100644 index 0000000..3e8a433 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs @@ -0,0 +1,202 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Reflection; +using OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Communications.Capabilities; +using OpenSim.Framework.Servers; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps=OpenSim.Framework.Communications.Capabilities.Caps; + +namespace OpenSim.Region.OptionalModules.Avatar.Voice.SIPVoice +{ + public class SIPVoiceModule : IRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; + private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; + private IConfig m_config; + private Scene m_scene; + private string m_sipDomain; + + #region IRegionModule Members + + public void Initialise(Scene scene, IConfigSource config) + { + m_scene = scene; + m_config = config.Configs["Voice"]; + + if (null == m_config || !m_config.GetBoolean("enabled", false)) + { + m_log.Info("[VOICE] plugin disabled"); + return; + } + m_log.Info("[VOICE] plugin enabled"); + + m_sipDomain = m_config.GetString("sip_domain", String.Empty); + if (String.IsNullOrEmpty(m_sipDomain)) + { + m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration"); + m_log.Info("[VOICE] plugin disabled"); + return; + } + m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain); + + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "VoiceModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + + #endregion + + public void OnRegisterCaps(UUID agentID, Caps caps) + { + m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + string capsBase = "/CAPS/" + caps.CapsObjectPath; + caps.RegisterHandler("ParcelVoiceInfoRequest", + new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ParcelVoiceInfoRequest(request, path, param, + agentID, caps); + })); + caps.RegisterHandler("ProvisionVoiceAccountRequest", + new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ProvisionVoiceAccountRequest(request, path, param, + agentID, caps); + })); + } + + /// + /// Callback for a client request for ParcelVoiceInfo + /// + /// + /// + /// + /// + /// + /// + public string ParcelVoiceInfoRequest(string request, string path, string param, + UUID agentID, Caps caps) + { + try + { + m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); + + // FIXME: get the creds from region file or from config + Hashtable creds = new Hashtable(); + + creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain); + + string regionName = m_scene.RegionInfo.RegionName; + ScenePresence avatar = m_scene.GetScenePresence(agentID); + if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); + LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + + LLSDParcelVoiceInfoResponse parcelVoiceInfo = + new LLSDParcelVoiceInfoResponse(regionName, land.LocalID, creds); + + string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); + m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r); + + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString()); + } + + return null; + } + + /// + /// Callback for a client request for Voice Account Details + /// + /// + /// + /// + /// + /// + /// + public string ProvisionVoiceAccountRequest(string request, string path, string param, + UUID agentID, Caps caps) + { + try + { + m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", + request, path, param); + + string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); + voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); + + CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); + if (null == userInfo) throw new Exception("cannot get user details"); + + LLSDVoiceAccountResponse voiceAccountResponse = + new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash); + string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); + m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); + } + + return null; + } + } +} -- cgit v1.1 From a99285ecc6c4326e05b2e4f60882d16935f9b30e Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Tue, 10 Feb 2009 14:32:23 +0000 Subject: fixing ConciergeModule to follow coding conventions --- .../Avatar/Concierge/ConciergeModule.cs | 212 ++++++++++----------- 1 file changed, 106 insertions(+), 106 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index bb46b11..3f99562 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -49,44 +49,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { public class ConciergeModule : ChatModule, IRegionModule { - private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private const int DEBUG_CHANNEL = 2147483647; - private List _scenes = new List(); - private List _conciergedScenes = new List(); - private Dictionary> _sceneAttendees = + private List m_scenes = new List(); + private List m_conciergedScenes = new List(); + private Dictionary> m_sceneAttendees = new Dictionary>(); - private Dictionary _attendeeNames = + private Dictionary m_attendeeNames = new Dictionary(); - private bool _replacingChatModule = false; + private bool m_replacingChatModule = false; - private IConfig _config; + private IConfig m_config; - private string _whoami = "conferencier"; - private Regex _regions = null; - private string _welcomes = null; - private int _conciergeChannel = 42; - private string _announceEntering = "{0} enters {1} (now {2} visitors in this region)"; - private string _announceLeaving = "{0} leaves {1} (back to {2} visitors in this region)"; - private string _xmlRpcPassword = String.Empty; - private string _brokerURI = String.Empty; + private string m_whoami = "conferencier"; + private Regex m_regions = null; + private string m_welcomes = null; + private int m_conciergeChannel = 42; + private string m_announceEntering = "{0} enters {1} (now {2} visitors in this region)"; + private string m_announceLeaving = "{0} leaves {1} (back to {2} visitors in this region)"; + private string m_xmlRpcPassword = String.Empty; + private string m_brokerURI = String.Empty; - internal object _syncy = new object(); + internal object m_syncy = new object(); #region IRegionModule Members public override void Initialise(Scene scene, IConfigSource config) { try { - if ((_config = config.Configs["Concierge"]) == null) + if ((m_config = config.Configs["Concierge"]) == null) { //_log.InfoFormat("[Concierge]: no configuration section [Concierge] in OpenSim.ini: module not configured"); return; } - if (!_config.GetBoolean("enabled", false)) + if (!m_config.GetBoolean("enabled", false)) { //_log.InfoFormat("[Concierge]: module disabled by OpenSim.ini configuration"); return; @@ -94,7 +94,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } catch (Exception) { - _log.Info("[Concierge]: module not configured"); + m_log.Info("[Concierge]: module not configured"); return; } @@ -104,58 +104,58 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { if (config.Configs["Chat"] == null) { - _replacingChatModule = false; + m_replacingChatModule = false; } else { - _replacingChatModule = !config.Configs["Chat"].GetBoolean("enabled", true); + m_replacingChatModule = !config.Configs["Chat"].GetBoolean("enabled", true); } } catch (Exception) { - _replacingChatModule = false; + m_replacingChatModule = false; } - _log.InfoFormat("[Concierge] {0} ChatModule", _replacingChatModule ? "replacing" : "not replacing"); + m_log.InfoFormat("[Concierge] {0} ChatModule", m_replacingChatModule ? "replacing" : "not replacing"); // take note of concierge channel and of identity - _conciergeChannel = config.Configs["Concierge"].GetInt("concierge_channel", _conciergeChannel); - _whoami = _config.GetString("whoami", "conferencier"); - _welcomes = _config.GetString("welcomes", _welcomes); - _announceEntering = _config.GetString("announce_entering", _announceEntering); - _announceLeaving = _config.GetString("announce_leaving", _announceLeaving); - _xmlRpcPassword = _config.GetString("password", _xmlRpcPassword); - _brokerURI = _config.GetString("broker", _brokerURI); + m_conciergeChannel = config.Configs["Concierge"].GetInt("concierge_channel", m_conciergeChannel); + m_whoami = m_config.GetString("whoami", "conferencier"); + m_welcomes = m_config.GetString("welcomes", m_welcomes); + m_announceEntering = m_config.GetString("announce_entering", m_announceEntering); + m_announceLeaving = m_config.GetString("announce_leaving", m_announceLeaving); + m_xmlRpcPassword = m_config.GetString("password", m_xmlRpcPassword); + m_brokerURI = m_config.GetString("broker", m_brokerURI); - _log.InfoFormat("[Concierge] reporting as \"{0}\" to our users", _whoami); + m_log.InfoFormat("[Concierge] reporting as \"{0}\" to our users", m_whoami); // calculate regions Regex - if (_regions == null) + if (m_regions == null) { - string regions = _config.GetString("regions", String.Empty); + string regions = m_config.GetString("regions", String.Empty); if (!String.IsNullOrEmpty(regions)) { - _regions = new Regex(@regions, RegexOptions.Compiled | RegexOptions.IgnoreCase); + m_regions = new Regex(@regions, RegexOptions.Compiled | RegexOptions.IgnoreCase); } } scene.CommsManager.HttpServer.AddXmlRPCHandler("concierge_update_welcome", XmlRpcUpdateWelcomeMethod, false); - lock (_syncy) + lock (m_syncy) { - if (!_scenes.Contains(scene)) + if (!m_scenes.Contains(scene)) { - _scenes.Add(scene); + m_scenes.Add(scene); - if (_regions == null || _regions.IsMatch(scene.RegionInfo.RegionName)) - _conciergedScenes.Add(scene); + if (m_regions == null || m_regions.IsMatch(scene.RegionInfo.RegionName)) + m_conciergedScenes.Add(scene); // subscribe to NewClient events scene.EventManager.OnNewClient += OnNewClient; // subscribe to *Chat events scene.EventManager.OnChatFromWorld += OnChatFromWorld; - if (!_replacingChatModule) + if (!m_replacingChatModule) scene.EventManager.OnChatFromClient += OnChatFromClient; scene.EventManager.OnChatBroadcast += OnChatBroadcast; @@ -164,7 +164,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; } } - _log.InfoFormat("[Concierge]: initialized for {0}", scene.RegionInfo.RegionName); + m_log.InfoFormat("[Concierge]: initialized for {0}", scene.RegionInfo.RegionName); } public override void PostInitialise() @@ -190,7 +190,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge #region ISimChat Members public override void OnChatBroadcast(Object sender, OSChatMessage c) { - if (_replacingChatModule) + if (m_replacingChatModule) { // distribute chat message to each and every avatar in // the region @@ -203,7 +203,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge public override void OnChatFromClient(Object sender, OSChatMessage c) { - if (_replacingChatModule) + if (m_replacingChatModule) { // replacing ChatModule: need to redistribute // ChatFromClient to interested subscribers @@ -212,7 +212,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge Scene scene = (Scene)c.Scene; scene.EventManager.TriggerOnChatFromClient(sender, c); - if (_conciergedScenes.Contains(c.Scene)) + if (m_conciergedScenes.Contains(c.Scene)) { // when we are replacing ChatModule, we treat // OnChatFromClient like OnChatBroadcast for @@ -237,9 +237,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge public override void OnChatFromWorld(Object sender, OSChatMessage c) { - if (_replacingChatModule) + if (m_replacingChatModule) { - if (_conciergedScenes.Contains(c.Scene)) + if (m_conciergedScenes.Contains(c.Scene)) { // when we are replacing ChatModule, we treat // OnChatFromClient like OnChatBroadcast for @@ -265,7 +265,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { client.OnLogout += OnClientLoggedOut; - if (_replacingChatModule) + if (m_replacingChatModule) client.OnChatFromClient += OnChatFromClient; } @@ -276,12 +276,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge client.OnLogout -= OnClientLoggedOut; client.OnConnectionClosed -= OnClientLoggedOut; - if (_conciergedScenes.Contains(client.Scene)) + if (m_conciergedScenes.Contains(client.Scene)) { - _log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, client.Scene.RegionInfo.RegionName); + m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, client.Scene.RegionInfo.RegionName); RemoveFromAttendeeList(client.AgentId, client.Name, client.Scene); - AnnounceToAgentsRegion(client.Scene, String.Format(_announceLeaving, client.Name, client.Scene.RegionInfo.RegionName, - _sceneAttendees[client.Scene].Count)); + AnnounceToAgentsRegion(client.Scene, String.Format(m_announceLeaving, client.Name, client.Scene.RegionInfo.RegionName, + m_sceneAttendees[client.Scene].Count)); UpdateBroker(client.Scene); } } @@ -289,13 +289,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge public void OnMakeRootAgent(ScenePresence agent) { - if (_conciergedScenes.Contains(agent.Scene)) + if (m_conciergedScenes.Contains(agent.Scene)) { - _log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, agent.Scene.RegionInfo.RegionName); + m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, agent.Scene.RegionInfo.RegionName); AddToAttendeeList(agent.UUID, agent.Name, agent.Scene); WelcomeAvatar(agent, agent.Scene); - AnnounceToAgentsRegion(agent.Scene, String.Format(_announceEntering, agent.Name, agent.Scene.RegionInfo.RegionName, - _sceneAttendees[agent.Scene].Count)); + AnnounceToAgentsRegion(agent.Scene, String.Format(m_announceEntering, agent.Name, agent.Scene.RegionInfo.RegionName, + m_sceneAttendees[agent.Scene].Count)); UpdateBroker(agent.Scene); } } @@ -303,73 +303,73 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge public void OnMakeChildAgent(ScenePresence agent) { - if (_conciergedScenes.Contains(agent.Scene)) + if (m_conciergedScenes.Contains(agent.Scene)) { - _log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, agent.Scene.RegionInfo.RegionName); + m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, agent.Scene.RegionInfo.RegionName); RemoveFromAttendeeList(agent.UUID, agent.Name, agent.Scene); - AnnounceToAgentsRegion(agent.Scene, String.Format(_announceLeaving, agent.Name, agent.Scene.RegionInfo.RegionName, - _sceneAttendees[agent.Scene].Count)); + AnnounceToAgentsRegion(agent.Scene, String.Format(m_announceLeaving, agent.Name, agent.Scene.RegionInfo.RegionName, + m_sceneAttendees[agent.Scene].Count)); UpdateBroker(agent.Scene); } } protected void AddToAttendeeList(UUID agentID, string name, Scene scene) { - lock (_sceneAttendees) + lock (m_sceneAttendees) { - if (!_sceneAttendees.ContainsKey(scene)) - _sceneAttendees[scene] = new List(); + if (!m_sceneAttendees.ContainsKey(scene)) + m_sceneAttendees[scene] = new List(); - List attendees = _sceneAttendees[scene]; + List attendees = m_sceneAttendees[scene]; if (!attendees.Contains(agentID)) { attendees.Add(agentID); - _attendeeNames[agentID] = name; + m_attendeeNames[agentID] = name; } } } protected void RemoveFromAttendeeList(UUID agentID, String name, IScene scene) { - lock (_sceneAttendees) + lock (m_sceneAttendees) { - if (!_sceneAttendees.ContainsKey(scene)) + if (!m_sceneAttendees.ContainsKey(scene)) { - _log.WarnFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); + m_log.WarnFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); return; } - List attendees = _sceneAttendees[scene]; + List attendees = m_sceneAttendees[scene]; if (!attendees.Contains(agentID)) { - _log.WarnFormat("[Concierge]: avatar {0} must have sneaked in to region {1} earlier", + m_log.WarnFormat("[Concierge]: avatar {0} must have sneaked in to region {1} earlier", name, scene.RegionInfo.RegionName); return; } attendees.Remove(agentID); - _attendeeNames.Remove(agentID); + m_attendeeNames.Remove(agentID); } } protected void UpdateBroker(IScene scene) { - if (String.IsNullOrEmpty(_brokerURI)) + if (String.IsNullOrEmpty(m_brokerURI)) return; - string uri = String.Format(_brokerURI, scene.RegionInfo.RegionName, scene.RegionInfo.RegionID); + string uri = String.Format(m_brokerURI, scene.RegionInfo.RegionName, scene.RegionInfo.RegionID); // get attendee list for the scene List attendees; - lock (_sceneAttendees) + lock (m_sceneAttendees) { - if (!_sceneAttendees.ContainsKey(scene)) + if (!m_sceneAttendees.ContainsKey(scene)) { - _log.DebugFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); + m_log.DebugFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); return; } - attendees = _sceneAttendees[scene]; + attendees = m_sceneAttendees[scene]; } // create XML sniplet @@ -388,7 +388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge DateTime.UtcNow.ToString("s"))); foreach (UUID uuid in attendees) { - string name = _attendeeNames[uuid]; + string name = m_attendeeNames[uuid]; list.Append(String.Format(" \n", name, uuid)); } list.Append(""); @@ -409,11 +409,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge payloadStream.Close(); updatePost.BeginGetResponse(UpdateBrokerDone, updatePost); - _log.DebugFormat("[Concierge] async broker POST to {0} started", uri); + m_log.DebugFormat("[Concierge] async broker POST to {0} started", uri); } catch (WebException we) { - _log.ErrorFormat("[Concierge] async broker POST to {0} failed: {1}", uri, we.Status); + m_log.ErrorFormat("[Concierge] async broker POST to {0} failed: {1}", uri, we.Status); } } @@ -425,25 +425,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge updatePost = result.AsyncState as HttpWebRequest; using (HttpWebResponse response = updatePost.EndGetResponse(result) as HttpWebResponse) { - _log.DebugFormat("[Concierge] broker update: status {0}", response.StatusCode); + m_log.DebugFormat("[Concierge] broker update: status {0}", response.StatusCode); } } catch (WebException we) { string uri = updatePost.RequestUri.OriginalString; - _log.ErrorFormat("[Concierge] broker update to {0} failed with status {1}", uri, we.Status); + m_log.ErrorFormat("[Concierge] broker update to {0} failed with status {1}", uri, we.Status); if (null != we.Response) { using (HttpWebResponse resp = we.Response as HttpWebResponse) { - _log.ErrorFormat("[Concierge] response from {0} status code: {1}", uri, resp.StatusCode); - _log.ErrorFormat("[Concierge] response from {0} status desc: {1}", uri, resp.StatusDescription); - _log.ErrorFormat("[Concierge] response from {0} server: {1}", uri, resp.Server); + m_log.ErrorFormat("[Concierge] response from {0} status code: {1}", uri, resp.StatusCode); + m_log.ErrorFormat("[Concierge] response from {0} status desc: {1}", uri, resp.StatusDescription); + m_log.ErrorFormat("[Concierge] response from {0} server: {1}", uri, resp.Server); if (resp.ContentLength > 0) { StreamReader content = new StreamReader(resp.GetResponseStream()); - _log.ErrorFormat("[Concierge] response from {0} content: {1}", uri, content.ReadToEnd()); + m_log.ErrorFormat("[Concierge] response from {0} content: {1}", uri, content.ReadToEnd()); content.Close(); } } @@ -456,11 +456,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge // welcome mechanics: check whether we have a welcomes // directory set and wether there is a region specific // welcome file there: if yes, send it to the agent - if (!String.IsNullOrEmpty(_welcomes)) + if (!String.IsNullOrEmpty(m_welcomes)) { string[] welcomes = new string[] { - Path.Combine(_welcomes, agent.Scene.RegionInfo.RegionName), - Path.Combine(_welcomes, "DEFAULT")}; + Path.Combine(m_welcomes, agent.Scene.RegionInfo.RegionName), + Path.Combine(m_welcomes, "DEFAULT")}; foreach (string welcome in welcomes) { if (File.Exists(welcome)) @@ -470,22 +470,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge string[] welcomeLines = File.ReadAllLines(welcome); foreach (string l in welcomeLines) { - AnnounceToAgent(agent, String.Format(l, agent.Name, scene.RegionInfo.RegionName, _whoami)); + AnnounceToAgent(agent, String.Format(l, agent.Name, scene.RegionInfo.RegionName, m_whoami)); } } catch (IOException ioe) { - _log.ErrorFormat("[Concierge]: run into trouble reading welcome file {0} for region {1} for avatar {2}: {3}", + m_log.ErrorFormat("[Concierge]: run into trouble reading welcome file {0} for region {1} for avatar {2}: {3}", welcome, scene.RegionInfo.RegionName, agent.Name, ioe); } catch (FormatException fe) { - _log.ErrorFormat("[Concierge]: welcome file {0} is malformed: {1}", welcome, fe); + m_log.ErrorFormat("[Concierge]: welcome file {0} is malformed: {1}", welcome, fe); } } return; } - _log.DebugFormat("[Concierge]: no welcome message for region {0}", scene.RegionInfo.RegionName); + m_log.DebugFormat("[Concierge]: no welcome message for region {0}", scene.RegionInfo.RegionName); } } @@ -497,7 +497,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge // if ((client.Scene is Scene) && (client.Scene as Scene).TryGetAvatar(client.AgentId, out agent)) // AnnounceToAgentsRegion(agent, msg); // else - // _log.DebugFormat("[Concierge]: could not find an agent for client {0}", client.Name); + // m_log.DebugFormat("[Concierge]: could not find an agent for client {0}", client.Name); // } protected void AnnounceToAgentsRegion(IScene scene, string msg) @@ -507,7 +507,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge c.Type = ChatTypeEnum.Say; c.Channel = 0; c.Position = PosOfGod; - c.From = _whoami; + c.From = m_whoami; c.Sender = null; c.SenderUUID = UUID.Zero; c.Scene = scene; @@ -523,12 +523,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge c.Type = ChatTypeEnum.Say; c.Channel = 0; c.Position = PosOfGod; - c.From = _whoami; + c.From = m_whoami; c.Sender = null; c.SenderUUID = UUID.Zero; c.Scene = agent.Scene; - agent.ControllingClient.SendChatMessage(msg, (byte) ChatTypeEnum.Say, PosOfGod, _whoami, UUID.Zero, + agent.ControllingClient.SendChatMessage(msg, (byte) ChatTypeEnum.Say, PosOfGod, m_whoami, UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); } @@ -546,7 +546,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge public XmlRpcResponse XmlRpcUpdateWelcomeMethod(XmlRpcRequest request) { - _log.Info("[Concierge]: processing UpdateWelcome request"); + m_log.Info("[Concierge]: processing UpdateWelcome request"); XmlRpcResponse response = new XmlRpcResponse(); Hashtable responseData = new Hashtable(); @@ -556,10 +556,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge checkStringParameters(request, new string[] { "password", "region", "welcome" }); // check password - if (!String.IsNullOrEmpty(_xmlRpcPassword) && - (string)requestData["password"] != _xmlRpcPassword) throw new Exception("wrong password"); + if (!String.IsNullOrEmpty(m_xmlRpcPassword) && + (string)requestData["password"] != m_xmlRpcPassword) throw new Exception("wrong password"); - if (String.IsNullOrEmpty(_welcomes)) + if (String.IsNullOrEmpty(m_welcomes)) throw new Exception("welcome templates are not enabled, ask your OpenSim operator to set the \"welcomes\" option in the [Concierge] section of OpenSim.ini"); string msg = (string)requestData["welcome"]; @@ -567,17 +567,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge throw new Exception("empty parameter \"welcome\""); string regionName = (string)requestData["region"]; - IScene scene = _scenes.Find(delegate(IScene s) { return s.RegionInfo.RegionName == regionName; }); + IScene scene = m_scenes.Find(delegate(IScene s) { return s.RegionInfo.RegionName == regionName; }); if (scene == null) throw new Exception(String.Format("unknown region \"{0}\"", regionName)); - if (!_conciergedScenes.Contains(scene)) + if (!m_conciergedScenes.Contains(scene)) throw new Exception(String.Format("region \"{0}\" is not a concierged region.", regionName)); - string welcome = Path.Combine(_welcomes, regionName); + string welcome = Path.Combine(m_welcomes, regionName); if (File.Exists(welcome)) { - _log.InfoFormat("[Concierge]: UpdateWelcome: updating existing template \"{0}\"", welcome); + m_log.InfoFormat("[Concierge]: UpdateWelcome: updating existing template \"{0}\"", welcome); string welcomeBackup = String.Format("{0}~", welcome); if (File.Exists(welcomeBackup)) File.Delete(welcomeBackup); @@ -590,14 +590,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } catch (Exception e) { - _log.InfoFormat("[Concierge]: UpdateWelcome failed: {0}", e.Message); + m_log.InfoFormat("[Concierge]: UpdateWelcome failed: {0}", e.Message); responseData["success"] = "false"; responseData["error"] = e.Message; response.Value = responseData; } - _log.Debug("[Concierge]: done processing UpdateWelcome request"); + m_log.Debug("[Concierge]: done processing UpdateWelcome request"); return response; } } -- cgit v1.1 From 6600a7a9bc8781f5ccc51abed464c5b32c65a5c3 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 13 Feb 2009 16:11:52 +0000 Subject: fixing crash due to make-child and make-root stepping on each other's toes --- .../Avatar/Concierge/ConciergeModule.cs | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 3f99562..83c3c34 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -280,9 +280,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, client.Scene.RegionInfo.RegionName); RemoveFromAttendeeList(client.AgentId, client.Name, client.Scene); - AnnounceToAgentsRegion(client.Scene, String.Format(m_announceLeaving, client.Name, client.Scene.RegionInfo.RegionName, - m_sceneAttendees[client.Scene].Count)); - UpdateBroker(client.Scene); + lock(m_sceneAttendees) + { + AnnounceToAgentsRegion(client.Scene, String.Format(m_announceLeaving, client.Name, client.Scene.RegionInfo.RegionName, + m_sceneAttendees[client.Scene].Count)); + UpdateBroker(client.Scene); + m_attendeeNames.Remove(client.AgentId); + } } } @@ -348,7 +352,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } attendees.Remove(agentID); - m_attendeeNames.Remove(agentID); } } @@ -386,10 +389,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge attendees.Count, scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); - foreach (UUID uuid in attendees) + lock(m_sceneAttendees) { - string name = m_attendeeNames[uuid]; - list.Append(String.Format(" \n", name, uuid)); + foreach (UUID uuid in attendees) + { + if (m_attendeeNames.ContainsKey(uuid)) + { + string name = m_attendeeNames[uuid]; + list.Append(String.Format(" \n", name, uuid)); + } + } } list.Append(""); } -- cgit v1.1 From 6fbc1f2b23a2b75c87fe901a47845958af990368 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Tue, 17 Feb 2009 18:27:01 +0000 Subject: - additional code to get ConciergeModule to do truly async broker updates - adding watchdog timer async web request - making broker update timeout configurable --- .../Avatar/Concierge/ConciergeModule.cs | 76 ++++++++++++++++++---- 1 file changed, 63 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 83c3c34..51aa8f8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -72,6 +72,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge private string m_announceLeaving = "{0} leaves {1} (back to {2} visitors in this region)"; private string m_xmlRpcPassword = String.Empty; private string m_brokerURI = String.Empty; + private int m_brokerUpdateTimeout = 300; internal object m_syncy = new object(); @@ -126,6 +127,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge m_announceLeaving = m_config.GetString("announce_leaving", m_announceLeaving); m_xmlRpcPassword = m_config.GetString("password", m_xmlRpcPassword); m_brokerURI = m_config.GetString("broker", m_brokerURI); + m_brokerUpdateTimeout = m_config.GetInt("broker_timeout", m_brokerUpdateTimeout); m_log.InfoFormat("[Concierge] reporting as \"{0}\" to our users", m_whoami); @@ -355,6 +357,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } } + internal class BrokerState + { + public string Uri; + public string Payload; + public HttpWebRequest Poster; + public Timer Timer; + + public BrokerState(string uri, string payload, HttpWebRequest poster) + { + Uri = uri; + Payload = payload; + Poster = poster; + } + } + protected void UpdateBroker(IScene scene) { if (String.IsNullOrEmpty(m_brokerURI)) @@ -411,13 +428,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge updatePost.ContentLength = payload.Length; updatePost.UserAgent = "OpenSim.Concierge"; + + BrokerState bs = new BrokerState(uri, payload, updatePost); + bs.Timer = new Timer(delegate(object state) + { + BrokerState b = state as BrokerState; + b.Poster.Abort(); + b.Timer.Dispose(); + m_log.Debug("[Concierge]: async broker POST abort due to timeout"); + }, bs, m_brokerUpdateTimeout * 1000, Timeout.Infinite); + try { - StreamWriter payloadStream = new StreamWriter(updatePost.GetRequestStream()); - payloadStream.Write(payload); - payloadStream.Close(); - - updatePost.BeginGetResponse(UpdateBrokerDone, updatePost); + updatePost.BeginGetRequestStream(UpdateBrokerSend, bs); m_log.DebugFormat("[Concierge] async broker POST to {0} started", uri); } catch (WebException we) @@ -426,33 +449,60 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } } + private void UpdateBrokerSend(IAsyncResult result) + { + BrokerState bs = null; + try + { + bs = result.AsyncState as BrokerState; + string payload = bs.Payload; + HttpWebRequest updatePost = bs.Poster; + + using(StreamWriter payloadStream = new StreamWriter(updatePost.EndGetRequestStream(result))) + { + payloadStream.Write(payload); + payloadStream.Close(); + } + updatePost.BeginGetResponse(UpdateBrokerDone, bs); + } + catch (WebException we) + { + m_log.DebugFormat("[Concierge]: async broker POST to {0} failed: {1}", bs.Uri, we.Status); + } + catch (Exception) + { + m_log.DebugFormat("[Concierge]: async broker POST to {0} failed", bs.Uri); + } + } + private void UpdateBrokerDone(IAsyncResult result) { - HttpWebRequest updatePost = null; + BrokerState bs = null; try { - updatePost = result.AsyncState as HttpWebRequest; + bs = result.AsyncState as BrokerState; + HttpWebRequest updatePost = bs.Poster; using (HttpWebResponse response = updatePost.EndGetResponse(result) as HttpWebResponse) { m_log.DebugFormat("[Concierge] broker update: status {0}", response.StatusCode); } + bs.Timer.Dispose(); } catch (WebException we) { - string uri = updatePost.RequestUri.OriginalString; - m_log.ErrorFormat("[Concierge] broker update to {0} failed with status {1}", uri, we.Status); + m_log.ErrorFormat("[Concierge] broker update to {0} failed with status {1}", bs.Uri, we.Status); if (null != we.Response) { using (HttpWebResponse resp = we.Response as HttpWebResponse) { - m_log.ErrorFormat("[Concierge] response from {0} status code: {1}", uri, resp.StatusCode); - m_log.ErrorFormat("[Concierge] response from {0} status desc: {1}", uri, resp.StatusDescription); - m_log.ErrorFormat("[Concierge] response from {0} server: {1}", uri, resp.Server); + m_log.ErrorFormat("[Concierge] response from {0} status code: {1}", bs.Uri, resp.StatusCode); + m_log.ErrorFormat("[Concierge] response from {0} status desc: {1}", bs.Uri, resp.StatusDescription); + m_log.ErrorFormat("[Concierge] response from {0} server: {1}", bs.Uri, resp.Server); if (resp.ContentLength > 0) { StreamReader content = new StreamReader(resp.GetResponseStream()); - m_log.ErrorFormat("[Concierge] response from {0} content: {1}", uri, content.ReadToEnd()); + m_log.ErrorFormat("[Concierge] response from {0} content: {1}", bs.Uri, content.ReadToEnd()); content.Close(); } } -- cgit v1.1 From 7d4846462bf5f3c7fe862c7466d0461b6c5d228f Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Fri, 20 Feb 2009 02:33:54 +0000 Subject: Update svn properties, add copyright headers, minor formatting cleanup. --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 51aa8f8..604b21d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -282,7 +282,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, client.Scene.RegionInfo.RegionName); RemoveFromAttendeeList(client.AgentId, client.Name, client.Scene); - lock(m_sceneAttendees) + lock (m_sceneAttendees) { AnnounceToAgentsRegion(client.Scene, String.Format(m_announceLeaving, client.Name, client.Scene.RegionInfo.RegionName, m_sceneAttendees[client.Scene].Count)); @@ -406,7 +406,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge attendees.Count, scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); - lock(m_sceneAttendees) + lock (m_sceneAttendees) { foreach (UUID uuid in attendees) { @@ -458,7 +458,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge string payload = bs.Payload; HttpWebRequest updatePost = bs.Poster; - using(StreamWriter payloadStream = new StreamWriter(updatePost.EndGetRequestStream(result))) + using (StreamWriter payloadStream = new StreamWriter(updatePost.EndGetRequestStream(result))) { payloadStream.Write(payload); payloadStream.Close(); -- cgit v1.1 From 1caf1c5d96dfa6863f524f57247befc9359e7259 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Thu, 19 Mar 2009 08:42:59 +0000 Subject: adding missing ChatSessionRequest voice capability for direct AV-AV calls. --- .../Avatar/Voice/SIPVoice/SIPVoiceModule.cs | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs index 3e8a433..d00a256 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs @@ -48,6 +48,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.SIPVoice private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; + private static readonly string m_chatSessionRequestPath = "0009/"; private IConfig m_config; private Scene m_scene; private string m_sipDomain; @@ -118,6 +119,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.SIPVoice return ProvisionVoiceAccountRequest(request, path, param, agentID, caps); })); + caps.RegisterHandler("ChatSessionRequest", + new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ChatSessionRequest(request, path, param, + agentID, caps); + })); + } /// @@ -198,5 +208,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.SIPVoice return null; } + + /// + /// Callback for a client request for ParcelVoiceInfo + /// + /// current scene object of the client + /// + /// + /// + /// + /// + /// + public string ChatSessionRequest(string request, string path, string param, + UUID agentID, Caps caps) + { + ScenePresence avatar = m_scene.GetScenePresence(agentID); + string avatarName = avatar.Name; + + m_log.DebugFormat("[CAPS][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", + avatarName, request, path, param); + return "true"; + } + } } -- cgit v1.1 From a1fe54baa0d3610da5e4c2821b48d0a4c9390bd5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 1 Apr 2009 12:28:46 +0000 Subject: Add a "user" config option to the IRC module config. Like all other IRC config options, this has NO default, if you use the IRC module, you MUST add this setting to your ini file. --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 167f0cc..2f3de69 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -60,7 +60,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal string IrcChannel = null; internal string BaseNickname = "OSimBot"; internal uint Port = 6667; - internal string User = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot"; + internal string User = null; internal bool ClientReporting = true; internal bool RelayChat = true; @@ -163,6 +163,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); cs.Password = Substitute(rs, config.GetString("password", null)); // probably not a good idea to put a password in the log file + cs.User = Substitute(rs, config.GetString("user", null)); cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); -- cgit v1.1 From e540b66a8660ab2f3d3a9be153e8cf8aaa641714 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Tue, 7 Apr 2009 16:53:41 +0000 Subject: From: Alan Webb Fix null reference exception during close down of IRC module if the region was not actually initialized. --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 0facc14..13874fa 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -148,8 +148,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (!enabled) return; + if (region == null) + return; + region.Close(); - lock (m_regions) m_regions.Remove(region); + + if(m_regions.Contains(region)) + { + lock (m_regions) m_regions.Remove(region); + } + } #endregion -- cgit v1.1 From cad0aab7934bf0f81634c44fc03876f4b252eaa8 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Tue, 14 Apr 2009 11:38:33 +0000 Subject: Formatting cleanup. --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 13874fa..fdc2bd9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat region.Close(); - if(m_regions.Contains(region)) + if (m_regions.Contains(region)) { lock (m_regions) m_regions.Remove(region); } -- cgit v1.1 From 91bd87add1c03aef5141d468889a4965da5f6eba Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 17 Apr 2009 16:00:02 +0000 Subject: - disabling logging of non-system IRC messages --- .../Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index f5c324d..5123ef5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -426,8 +426,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void PrivMsg(string pattern, string from, string region, string msg) { - m_log.DebugFormat("[IRC-Connector-{0}] PrivMsg to IRC from {1}: <{2}>", idn, from, - String.Format(pattern, m_ircChannel, from, region, msg)); + // m_log.DebugFormat("[IRC-Connector-{0}] PrivMsg to IRC from {1}: <{2}>", idn, from, + // String.Format(pattern, m_ircChannel, from, region, msg)); // One message to the IRC server @@ -435,7 +435,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { m_writer.WriteLine(pattern, m_ircChannel, from, region, msg); m_writer.Flush(); - m_log.DebugFormat("[IRC-Connector-{0}]: PrivMsg from {1} in {2}: {3}", idn, from, region, msg); + // m_log.DebugFormat("[IRC-Connector-{0}]: PrivMsg from {1} in {2}: {3}", idn, from, region, msg); } catch (IOException) { @@ -453,13 +453,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void Send(string msg) { - m_log.DebugFormat("[IRC-Connector-{0}] Send to IRC : <{1}>", idn, msg); + // m_log.DebugFormat("[IRC-Connector-{0}] Send to IRC : <{1}>", idn, msg); try { m_writer.WriteLine(msg); m_writer.Flush(); - m_log.DebugFormat("[IRC-Connector-{0}] Sent command string: {1}", idn, msg); + // m_log.DebugFormat("[IRC-Connector-{0}] Sent command string: {1}", idn, msg); } catch (IOException) { @@ -658,10 +658,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat case "366" : // End-of-Name list marker case "372" : // MOTD body case "375" : // MOTD start - m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); break; case "376" : // MOTD end - m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); motd = true; break; case "451" : // Not registered @@ -686,7 +686,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_pending = false; break; case "NOTICE" : - m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + // m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); break; case "ERROR" : m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); -- cgit v1.1 From 7f30be17d0ee841961262ee9e9b8fab27ccf6d83 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Fri, 17 Apr 2009 20:00:30 +0000 Subject: experimental freeswitch code, imported from Rob Smart's tree --- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 88 ++++ .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 335 ++++++++++++ .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 571 +++++++++++++++++++++ 3 files changed, 994 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs new file mode 100644 index 0000000..2a2b4a3 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -0,0 +1,88 @@ +/* + * 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 OpenSim 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 log4net; +using System.Reflection; +using System.Collections; + +namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice +{ + public class FreeSwitchDialplan + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + + public Hashtable HandleDialplanRequest(Hashtable request) + { + m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString()); + + Hashtable response = new Hashtable(); + + foreach(DictionaryEntry item in request) + { + m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); + } + + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"]=200; + response["str_response_string"] = @" + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
"; + + return response; + } + } + +} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs new file mode 100644 index 0000000..9959d11 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -0,0 +1,335 @@ +/* + * 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 OpenSim 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 log4net; +using System; +using System.Reflection; +using System.Text; +using System.Collections; + +namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice +{ + public class FreeSwitchDirectory + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public Hashtable HandleDirectoryRequest(Hashtable request) + { + m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); + + Hashtable response = new Hashtable(); + + // information in the request we might be interested in + + // Request 1 sip_auth for users account + + //Event-Calling-Function=sofia_reg_parse_auth + //Event-Calling-Line-Number=1494 + //action=sip_auth + //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41) + //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_auth_realm=9.20.151.43 + //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers + //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //sip_to_host=9.20.151.43 + //sip_auth_method=REGISTER + //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //domain=9.20.151.43 + //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup + + foreach(DictionaryEntry item in request) + { + m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); + } + + string eventCallingFunction = (string) request["Event-Calling-Function"]; + + + if(eventCallingFunction=="sofia_reg_parse_auth") + { + string sipAuthMethod = (string)request["sip_auth_method"]; + + if(sipAuthMethod=="REGISTER") + { + response = HandleRegister(request); + } + else if(sipAuthMethod=="INVITE") + { + response = HandleInvite(request); + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); + response["int_response_code"]=404; + } + } + else if(eventCallingFunction=="switch_xml_locate_user") + { + response = HandleLocateUser(request); + } + else if(eventCallingFunction=="user_data_function") // gets called when an avatar to avatar call is made + { + response = HandleLocateUser(request); + } + else if(eventCallingFunction=="user_outgoing_channel") + { + response = HandleRegister(request); + } + else if(eventCallingFunction=="config_sofia") // happens once on freeswitch startup + { + response = HandleConfigSofia(request); + } + else if(eventCallingFunction=="switch_load_network_lists") + { + //response = HandleLoadNetworkLists(request); + response["int_response_code"]=404; + response["keepalive"] = false; + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); + response["int_response_code"]=404; + response["keepalive"] = false; + } + + + + return response; + } + + private Hashtable HandleRegister(Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleRegister called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string password = "1234"; + string domain = (string) request["domain"]; + string user = (string) request["user"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"]=200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + ""+ + "\r\n" + + "\r\n" + + "\r\n" + + "
\r\n" + + "
\r\n" + , domain , user, password); + + return response; + + } + + private Hashtable HandleInvite(Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleInvite called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string password = "1234"; + string domain = (string) request["domain"]; + string user = (string) request["user"]; + string sipRequestUser = (string) request["sip_request_user"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"]=200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + ""+ + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + ""+ + "\r\n" + + "\r\n" + + "\r\n" + + "
\r\n" + + "
\r\n" + , domain , user, password,sipRequestUser); + + return response; + } + + + private Hashtable HandleLocateUser(Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string domain = (string) request["domain"]; + string user = (string) request["user"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"]=200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n"+ + "\r\n"+ + ""+ + "\r\n"+ + "\r\n" + + "\r\n" + + "
\r\n" + + "
\r\n" + , domain , user); + + + + return response; + } + + private Hashtable HandleConfigSofia(Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string domain = (string) request["domain"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"]=200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + ""+ + "\r\n" + + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n" + + "
\r\n" + + "
\r\n" + , domain); + + + return response; + } + + private Hashtable HandleLoadNetworkLists(Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string domain = (string) request["domain"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"]=200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n" + + "
\r\n" + + "
\r\n" + , domain); + + + return response; + } + + } + +} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs new file mode 100644 index 0000000..a8f9de6 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -0,0 +1,571 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Net; +using System.Web; +using System.Text; +using System.Xml; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using OpenMetaverse; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Communications.Capabilities; +using OpenSim.Framework.Servers; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; + +namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice +{ + public class FreeSwitchVoiceModule : IRegionModule + { + + // Infrastructure + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly bool DUMP = true; + + // Capability string prefixes + private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; + private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; + private static readonly string m_chatSessionRequestPath = "0009/"; + + // Control info + private static bool m_WOF = true; + private static bool m_pluginEnabled = false; + + // FreeSwitch server is going to contact us and ask us all + // sorts of things. + private static string m_freeSwitchServerUser; + private static string m_freeSwitchServerPass; + + // SLVoice client will do a GET on this prefix + private static string m_freeSwitchAPIPrefix; + + // We need to return some information to SLVoice + // figured those out via curl + // http://vd1.vivox.com/api2/viv_get_prelogin.php + // + // need to figure out whether we do need to return ALL of + // these... + private static string m_freeSwitchRealm; + private static string m_freeSwitchSIPProxy; + private static bool m_freeSwitchAttemptUseSTUN; + private static string m_freeSwitchSTUNServer; + private static string m_freeSwitchEchoServer; + private static int m_freeSwitchEchoPort; + private static string m_freeSwitchDefaultWellKnownIP; + private static int m_freeSwitchDefaultTimeout; + private static int m_freeSwitchSubscribeRetry; + private static string m_freeSwitchUrlResetPassword; + private static IPEndPoint m_FreeSwitchServiceIP; + + private FreeSwitchDirectory m_FreeSwitchDirectory; + private FreeSwitchDialplan m_FreeSwitchDialplan; + + private IConfig m_config; + + public void Initialise(Scene scene, IConfigSource config) + { + + m_config = config.Configs["FreeSwitchVoice"]; + + if (null == m_config) + { + m_log.Info("[FreeSwitchVoice] no config found, plugin disabled"); + return; + } + + if (!m_config.GetBoolean("enabled", false)) + { + m_log.Info("[FreeSwitchVoice] plugin disabled by configuration"); + return; + } + + // This is only done the FIRST time this method is invoked. + if (m_WOF) + { + m_pluginEnabled = true; + m_WOF = false; + + try + { + m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty); + m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty); + m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty); + + // XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server) + + string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty); + int servicePort = m_config.GetInt("freeswitch_service_port", 80); + IPAddress serviceIPAddress = IPAddress.Parse(serviceIP); + m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort); + + m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty); + m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm); + m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true); + m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm); + m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm); + m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505); + m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm); + m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); + m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); + m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); + + + + + if (String.IsNullOrEmpty(m_freeSwitchServerUser) || + String.IsNullOrEmpty(m_freeSwitchServerPass) || + String.IsNullOrEmpty(m_freeSwitchRealm) || + String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) + { + m_log.Error("[FreeSwitchVoice] plugin mis-configured"); + m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration"); + return; + } + + // set up http request handlers for + // - prelogin: viv_get_prelogin.php + // - signin: viv_signin.php + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceGetPreloginHTTPHandler); + + // RestStreamHandler h = new RestStreamHandler("GET", String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); + // scene.CommsManager.HttpServer.AddStreamHandler(h); + + + + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceSigninHTTPHandler); + + // set up http request handlers to provide + // on-demand FreeSwitch configuration to + // FreeSwitch's mod_curl_xml + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), + FreeSwitchConfigHTTPHandler); + + m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); + + m_FreeSwitchDirectory = new FreeSwitchDirectory(); + m_FreeSwitchDialplan = new FreeSwitchDialplan(); + + m_pluginEnabled = true; + m_WOF = false; + + m_log.Info("[FreeSwitchVoice] plugin enabled"); + } + catch (Exception e) + { + m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message); + m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString()); + return; + } + } + + if (m_pluginEnabled) + { + // we need to capture scene in an anonymous method + // here as we need it later in the callbacks + scene.EventManager.OnRegisterCaps += delegate(UUID agentID, Caps caps) + { + OnRegisterCaps(scene, agentID, caps); + }; + + + + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "FreeSwitchVoiceModule"; } + } + + public bool IsSharedModule + { + get { return true; } + } + + + // + // OnRegisterCaps is invoked via the scene.EventManager + // everytime OpenSim hands out capabilities to a client + // (login, region crossing). We contribute two capabilities to + // the set of capabilities handed back to the client: + // ProvisionVoiceAccountRequest and ParcelVoiceInfoRequest. + // + // ProvisionVoiceAccountRequest allows the client to obtain + // the voice account credentials for the avatar it is + // controlling (e.g., user name, password, etc). + // + // ParcelVoiceInfoRequest is invoked whenever the client + // changes from one region or parcel to another. + // + // Note that OnRegisterCaps is called here via a closure + // delegate containing the scene of the respective region (see + // Initialise()). + // + public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps) + { + m_log.DebugFormat("[FreeSwitchVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + + string capsBase = "/CAPS/" + caps.CapsObjectPath; + caps.RegisterHandler("ProvisionVoiceAccountRequest", + new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ProvisionVoiceAccountRequest(scene, request, path, param, + agentID, caps); + })); + caps.RegisterHandler("ParcelVoiceInfoRequest", + new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ParcelVoiceInfoRequest(scene, request, path, param, + agentID, caps); + })); + caps.RegisterHandler("ChatSessionRequest", + new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ChatSessionRequest(scene, request, path, param, + agentID, caps); + })); + } + + /// + /// Callback for a client request for Voice Account Details + /// + /// current scene object of the client + /// + /// + /// + /// + /// + /// + public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, + UUID agentID, Caps caps) + { + ScenePresence avatar = scene.GetScenePresence(agentID); + string avatarName = avatar.Name; + + try + { + m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", + request, path, param); + + //XmlElement resp; + string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); + string password = "1234";//temp hack//new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16); + + // XXX: we need to cache the voice credentials, as + // FreeSwitch is later going to come and ask us for + // those + + agentname = agentname.Replace('+', '-').Replace('/', '_'); + + // LLSDVoiceAccountResponse voiceAccountResponse = + // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); + LLSDVoiceAccountResponse voiceAccountResponse = + new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, + String.Format("http://{0}/{1}/", m_FreeSwitchServiceIP, + m_freeSwitchAPIPrefix)); + + string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); + + m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); + + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}, retry later", avatarName, e.Message); + m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1} failed", avatarName, e.ToString()); + + return "undef"; + } + } + + /// + /// Callback for a client request for ParcelVoiceInfo + /// + /// current scene object of the client + /// + /// + /// + /// + /// + /// + public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param, + UUID agentID, Caps caps) + { + ScenePresence avatar = scene.GetScenePresence(agentID); + string avatarName = avatar.Name; + + // - check whether we have a region channel in our cache + // - if not: + // create it and cache it + // - send it to the client + // - send channel_uri: as "sip:regionID@m_sipDomain" + try + { + LLSDParcelVoiceInfoResponse parcelVoiceInfo; + string channelUri; + + if (null == scene.LandChannel) + throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available", + scene.RegionInfo.RegionName, avatarName)); + + + + // get channel_uri: check first whether estate + // settings allow voice, then whether parcel allows + // voice, if all do retrieve or obtain the parcel + // voice channel + LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + + m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", + scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); + + // TODO: EstateSettings don't seem to get propagated... + // if (!scene.RegionInfo.EstateSettings.AllowVoice) + // { + // m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings", + // scene.RegionInfo.RegionName); + // channel_uri = String.Empty; + // } + // else + + if ((land.Flags & (uint)Parcel.ParcelFlags.AllowVoiceChat) == 0) + { + m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", + scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); + channelUri = String.Empty; + } + else + { + channelUri = ChannelUri(scene, land); + } + + // fill in our response to the client + Hashtable creds = new Hashtable(); + creds["channel_uri"] = channelUri; + + parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); + string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); + + m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", + scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later", + scene.RegionInfo.RegionName, avatarName, e.Message); + m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed", + scene.RegionInfo.RegionName, avatarName, e.ToString()); + + return "undef"; + } + } + + + /// + /// Callback for a client request for ChatSessionRequest + /// + /// current scene object of the client + /// + /// + /// + /// + /// + /// + public string ChatSessionRequest(Scene scene, string request, string path, string param, + UUID agentID, Caps caps) + { + ScenePresence avatar = scene.GetScenePresence(agentID); + string avatarName = avatar.Name; + + m_log.DebugFormat("[FreeSwitchVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", + avatarName, request, path, param); + return "true"; + } + + + public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) + { + m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler called"); + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n"+ + "{0}\r\n" + + "{1}\r\n"+ + "{2}\r\n"+ + "{3}\r\n"+ + "{4}\r\n"+ + "{5}\r\n"+ + "{6}\r\n"+ + "{7}\r\n"+ + "{8}\r\n"+ + "\r\n"+ + "false\r\n"+ + "" + , + m_freeSwitchRealm,m_freeSwitchSIPProxy,m_freeSwitchAttemptUseSTUN, + m_freeSwitchSTUNServer,m_freeSwitchEchoServer,m_freeSwitchEchoPort, + m_freeSwitchDefaultWellKnownIP,m_freeSwitchDefaultTimeout,m_freeSwitchUrlResetPassword,""); + + response["int_response_code"] = 200; + + m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler return {0}",response["str_response_string"]); + return response; + } + + public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) + { + m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called"); + + Hashtable response = new Hashtable(); + response["str_response_string"] = @" + + OK + + 200 + auth successful + + + "; + response["int_response_code"] = 200; + return response; + } + + + public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request) + { + m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}",request.ToString()); + + Hashtable response = new Hashtable(); + + // all the params come as NVPs in the request body + Hashtable requestBody = parseRequestBody((string) request["body"]); + + // is this a dialplan or directory request + string section = (string) requestBody["section"]; + + if(section=="directory") + response = m_FreeSwitchDirectory.HandleDirectoryRequest(requestBody); + else if (section=="dialplan") + response = m_FreeSwitchDialplan.HandleDialplanRequest(requestBody); + + // XXX: re-generate dialplan: + // - conf == region UUID + // - conf number = region port + // -> TODO Initialise(): keep track of regions via events + // re-generate accounts for all avatars + // -> TODO Initialise(): keep track of avatars via events + m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",response["str_response_string"]); + return response; + } + + public Hashtable parseRequestBody(string body) + { + Hashtable bodyParams = new Hashtable(); + // split string + string [] nvps = body.Split(new Char [] {'&'}); + + foreach (string s in nvps) { + + if (s.Trim() != "") + { + string [] nvp = s.Split(new Char [] {'='}); + bodyParams.Add(HttpUtility.UrlDecode(nvp[0]),HttpUtility.UrlDecode(nvp[1])); + } + } + + return bodyParams; + + } + + private string ChannelUri(Scene scene, LandData land) + { + + string channelUri = null; + + string landUUID; + string landName; + + // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same + // as the directory ID. Otherwise, it reflects the parcel's ID. + + if (land.LocalID != 1 && (land.Flags & (uint)Parcel.ParcelFlags.UseEstateVoiceChan) == 0) + { + landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); + landUUID = land.GlobalID.ToString(); + m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", + landName, land.LocalID, landUUID); + } + else + { + landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, scene.RegionInfo.RegionName); + landUUID = scene.RegionInfo.RegionID.ToString(); + m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", + landName, land.LocalID, landUUID); + } + System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); + channelUri = String.Format("sip:confctl-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); + + //channelUri="sip:confctl-3001@9.20.151.43"; + //channelUri="sip:opensimconf-3001@9.20.151.43"; + + return channelUri; + } + } +} -- cgit v1.1 From 659b55905dc7e006ae73f3d569efdf52276aa825 Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Sat, 18 Apr 2009 21:33:48 +0000 Subject: Thank you kindly, MCortez, for a patch that: Added is a patch that adds a rough Groups implementation. This patch allows the creation, adding and maintaining Groups, Roles and Members. Work has begun on a very naive implementation of messaging, and minimal support for notifications {no attachments yet}. Proposals are not yet supported, but are on the to-do list. This implementation is not active by default, and must be configured in OpenSim.ini to become active. --- .../Avatar/XmlRpcGroups/IGroupDataProvider.cs | 85 ++ .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 1017 +++++++++++++++++++ .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 423 ++++++++ .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 1039 ++++++++++++++++++++ 4 files changed, 2564 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs new file mode 100644 index 0000000..6e9105d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs @@ -0,0 +1,85 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; + +using OpenMetaverse; + +using OpenSim.Framework; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + interface IGroupDataProvider + { + UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(UUID GroupID, string GroupName); + List FindGroups(string search); + List GetGroupMembers(UUID GroupID); + + void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(UUID groupID, UUID roleID); + List GetGroupRoles(UUID GroupID); + List GetGroupRoleMembers(UUID GroupID); + + void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(UUID AgentID, UUID GroupID); + + void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(UUID inviteID); + void RemoveAgentToGroupInvite(UUID inviteID); + + + void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(UUID AgentID, UUID GroupID); + + void SetAgentActiveGroup(UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(UUID AgentID); + + void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + + GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(UUID AgentID); + + void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(UUID noticeID); + List GetGroupNotices(UUID GroupID); + } + + public class GroupInviteInfo + { + public UUID GroupID = UUID.Zero; + public UUID RoleID = UUID.Zero; + public UUID AgentID = UUID.Zero; + public UUID InviteID = UUID.Zero; + } + +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs new file mode 100644 index 0000000..343bd6d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -0,0 +1,1017 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +//using System.Text; + +using Nwc.XmlRpc; + +using log4net; +// using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +//using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + + public class XmlRpcGroupDataProvider : IGroupDataProvider + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serviceURL = "http://osflotsam.org/xmlrpc.php"; + + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | GroupPowers.AllowVoiceChat | GroupPowers.ReceiveNotices | GroupPowers.StartProposal | GroupPowers.VoteOnProposal; + + public XmlRpcGroupDataProvider(string serviceURL) + { + m_serviceURL = serviceURL; + } + + /// + /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. + /// + public UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) + { + UUID GroupID = UUID.Random(); + UUID OwnerRoleID = UUID.Random(); + + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + param["Name"] = name; + param["Charter"] = charter; + param["ShowInList"] = showInList == true ? 1 : 0; + param["InsigniaID"] = insigniaID.ToString(); + param["MembershipFee"] = 0; + param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; + param["AllowPublish"] = allowPublish == true ? 1 : 0; + param["MaturePublish"] = maturePublish == true ? 1 : 0; + param["FounderID"] = founderID.ToString(); + param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); + param["OwnerRoleID"] = OwnerRoleID.ToString(); + + // Would this be cleaner as (GroupPowers)ulong.MaxValue; + GroupPowers OwnerPowers = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); + + + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.createGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + + return UUID.Parse((string)respData["GroupID"]); + } + + public void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["Charter"] = charter; + param["ShowInList"] = showInList == true ? 1 : 0; + param["InsigniaID"] = insigniaID.ToString(); + param["MembershipFee"] = membershipFee; + param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; + param["AllowPublish"] = allowPublish == true ? 1 : 0; + param["MaturePublish"] = maturePublish == true ? 1 : 0; + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.updateGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + param["Name"] = name; + param["Description"] = description; + param["Title"] = title; + param["Powers"] = powers.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addRoleToGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void RemoveGroupRole(UUID groupID, UUID roleID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeRoleFromGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + if (name != null) + { + param["Name"] = name; + } + if (description != null) + { + param["Description"] = description; + } + if (title != null) + { + param["Title"] = title; + } + param["Powers"] = powers.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.updateGroupRole", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) + { + Hashtable param = new Hashtable(); + if ((GroupID != null) && (GroupID != UUID.Zero)) + { + param["GroupID"] = GroupID.ToString(); + } + if ((GroupName != null) && (GroupName != string.Empty)) + { + param["Name"] = GroupName.ToString(); + } + + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "Group Not Found") + { + LogRespDataToConsoleError(respData); + } + return null; + } + + return GroupProfileHashtableToGroupRecord(respData); + + } + + public GroupProfileData GetMemberGroupProfile(UUID GroupID, UUID AgentID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "Group Not Found") + { + LogRespDataToConsoleError(respData); + } + return new GroupProfileData(); + } + + GroupMembershipData MemberInfo = GetAgentGroupMembership(AgentID, GroupID); + GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); + + MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; + MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; + + return MemberGroupProfile; + + } + + private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) + { + GroupProfileData group = new GroupProfileData(); + group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); + group.Name = (string)groupProfile["Name"]; + + if (groupProfile["Charter"] != null) + { + group.Charter = (string)groupProfile["Charter"]; + } + + group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; + group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); + group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); + group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; + group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; + group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; + group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); + group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); + + group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); + group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); + + return group; + } + + private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) + { + + GroupRecord group = new GroupRecord(); + m_log.Debug("GroupID"); + group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); + + m_log.Debug("Name"); + group.GroupName = groupProfile["Name"].ToString(); + + m_log.Debug("Charter"); + if (groupProfile["Charter"] != null) + { + group.Charter = (string)groupProfile["Charter"]; + } + + m_log.Debug("ShowInList"); + group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; + + m_log.Debug("InsigniaID"); + group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); + + m_log.Debug("MembershipFee"); + group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); + + m_log.Debug("OpenEnrollment"); + group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; + + m_log.Debug("AllowPublish"); + group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; + + m_log.Debug("MaturePublish"); + group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; + + m_log.Debug("FounderID"); + group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); + + m_log.Debug("OwnerRoleID"); + group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); + + return group; + } + + + public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.setAgentActiveGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + + } + + public void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["SelectedRoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + + } + + public void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["AcceptNotices"] = AcceptNotices ? "1" : "0"; + param["ListInProfile"] = ListInProfile ? "1" : "0"; + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + param["AgentID"] = agentID.ToString(); + param["RoleID"] = roleID.ToString(); + param["GroupID"] = groupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupInvite", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if (respData["error"] != "Duplicate group invite requested") + { + LogRespDataToConsoleError(respData); + } + } + + + } + + public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentToGroupInvite", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + + return null; + } + + GroupInviteInfo inviteInfo = new GroupInviteInfo(); + inviteInfo.InviteID = inviteID; + inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); + inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); + inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); + + return inviteInfo; + } + + public void RemoveAgentToGroupInvite(UUID inviteID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentToGroupInvite", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void RemoveAgentFromGroup(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupRole", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroupRole", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + + public List FindGroups(string search) + { + Hashtable param = new Hashtable(); + param["Search"] = search; + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.findGroups", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List findings = new List(); + + if (respData.Contains("error")) + { + if (respData["error"].ToString() != "No groups found.") + { + LogRespDataToConsoleError(respData); + } + } + else + { + Hashtable results = (Hashtable)respData["results"]; + foreach (Hashtable groupFind in results.Values) + { + DirGroupsReplyData data = new DirGroupsReplyData(); + data.groupID = new UUID((string)groupFind["GroupID"]); ; + data.groupName = (string)groupFind["Name"]; + data.members = int.Parse((string)groupFind["Members"]); + // data.searchOrder = order; + + findings.Add(data); + } + } + + return findings; + } + + public GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMembership", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "None Found") + { + LogRespDataToConsoleError(respData); + } + return null; + } + + GroupMembershipData data = HashTableToGroupMembershipData(respData); + + return data; + } + + public GroupMembershipData GetAgentActiveMembership(UUID AgentID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentActiveMembership", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if (respData["error"].ToString() == "No Active Group Specified") + { + return null; + } + LogRespDataToConsoleError(respData); + return null; + } + + try + { + GroupMembershipData data = HashTableToGroupMembershipData(respData); + return data; + } + catch (System.Exception e) + { + LogRespDataToConsoleError(respData); + throw e; + } + } + + private void LogRespDataToConsoleError(Hashtable respData) + { + m_log.Error("[GROUPDATA] Error:"); + + foreach (string key in respData.Keys) + { + m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); + + object o = respData[key]; + + string[] lines = respData[key].ToString().Split(new char[] { '\n' }); + foreach (string line in lines) + { + m_log.ErrorFormat("[GROUPDATA] {0}", line); + } + + } + } + + public List GetAgentGroupMemberships(UUID AgentID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMemberships", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List memberships = new List(); + + if (respData.Contains("error")) + { + if (respData["error"].ToString() != "No Memberships") + { + LogRespDataToConsoleError(respData); + } + } + else + { + foreach (object membership in respData.Values) + { + memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); + } + } + return memberships; + } + + public List GetAgentGroupRoles(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentRoles", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List Roles = new List(); + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "None found") + { + LogRespDataToConsoleError(respData); + } + return Roles; + } + + foreach (Hashtable role in respData.Values) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = new UUID((string)role["RoleID"]); + data.Name = (string)role["Name"]; + data.Description = (string)role["Description"]; + data.Powers = ulong.Parse((string)role["Powers"]); + data.Title = (string)role["Title"]; + + Roles.Add(data); + } + + return Roles; + + + } + + public List GetGroupRoles(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoles", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + return null; + } + + List Roles = new List(); + foreach (Hashtable role in respData.Values) + { + GroupRolesData data = new GroupRolesData(); + data.Description = (string)role["Description"]; + data.Members = int.Parse((string)role["Members"]); + data.Name = (string)role["Name"]; + data.Powers = ulong.Parse((string)role["Powers"]); + data.RoleID = new UUID((string)role["RoleID"]); + data.Title = (string)role["Title"]; + + Roles.Add(data); + } + + return Roles; + + } + + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) + { + GroupMembershipData data = new GroupMembershipData(); + data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); + data.Contribution = int.Parse((string)respData["Contribution"]); + data.ListInProfile = ((string)respData["ListInProfile"] == "1"); + + data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); + data.GroupTitle = (string)respData["Title"]; + + data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); + + // Is this group the agent's active group + + data.GroupID = new UUID((string)respData["GroupID"]); + + UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); + data.Active = data.GroupID.Equals(ActiveGroup); + + data.AllowPublish = ((string)respData["AllowPublish"] == "1"); + data.Charter = (string)respData["Charter"]; + data.FounderID = new UUID((string)respData["FounderID"]); + data.GroupID = new UUID((string)respData["GroupID"]); + data.GroupName = (string)respData["GroupName"]; + data.GroupPicture = new UUID((string)respData["InsigniaID"]); + data.MaturePublish = ((string)respData["MaturePublish"] == "1"); + data.MembershipFee = int.Parse((string)respData["MembershipFee"]); + data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); + data.ShowInList = ((string)respData["ShowInList"] == "1"); + return data; + } + + public List GetGroupMembers(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupMembers", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + return null; + } + + List members = new List(); + foreach (Hashtable membership in respData.Values) + { + GroupMembersData data = new GroupMembersData(); + + data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; + data.AgentID = new UUID((string)membership["AgentID"]); + data.Contribution = int.Parse((string)membership["Contribution"]); + data.IsOwner = ((string)membership["IsOwner"]) == "1"; + data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; + data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); + data.Title = (string)membership["Title"]; + + members.Add(data); + } + + return members; + + } + + public List GetGroupRoleMembers(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoleMembers", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + return null; + } + + List members = new List(); + foreach (Hashtable membership in respData.Values) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = new UUID((string)membership["AgentID"]); + data.RoleID = new UUID((string)membership["RoleID"]); + + members.Add(data); + } + + return members; + } + + public List GetGroupNotices(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotices", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List values = new List(); + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "No Notices") + { + LogRespDataToConsoleError(respData); + } + } + else + { + foreach (Hashtable value in respData.Values) + { + GroupNoticeData data = new GroupNoticeData(); + data.NoticeID = UUID.Parse((string)value["NoticeID"]); + data.Timestamp = uint.Parse((string)value["Timestamp"]); + data.FromName = (string)value["FromName"]; + data.Subject = (string)value["Subject"]; + data.HasAttachment = false; + data.AssetType = 0; + + values.Add(data); + } + } + return values; + + } + public GroupNoticeInfo GetGroupNotice(UUID noticeID) + { + Hashtable param = new Hashtable(); + param["NoticeID"] = noticeID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotice", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "Group Notice Not Found") + { + LogRespDataToConsoleError(respData); + return null; + } + } + + GroupNoticeInfo data = new GroupNoticeInfo(); + data.GroupID = UUID.Parse((string)respData["GroupID"]); + data.Message = (string)respData["Message"]; + data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); + data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); + data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); + data.noticeData.FromName = (string)respData["FromName"]; + data.noticeData.Subject = (string)respData["Subject"]; + data.noticeData.HasAttachment = false; + data.noticeData.AssetType = 0; + + if (data.Message == null) + { + data.Message = string.Empty; + } + + return data; + } + public void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + { + string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); + + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["NoticeID"] = noticeID.ToString(); + param["FromName"] = fromName; + param["Subject"] = subject; + param["Message"] = message; + param["BinaryBucket"] = binBucket; + param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addGroupNotice", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List values = new List(); + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + + } + + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs new file mode 100644 index 0000000..d14d135 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -0,0 +1,423 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +//using System.Collections; +using System.Collections.Generic; +using System.Reflection; + + +using log4net; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Framework.EventQueue; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + + +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + public class XmlRpcGroupsMessaging : INonSharedRegionModule + { + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_SceneList = new List(); + + // must be NonShared for this to work, otherewise we may actually get multiple active clients + private Dictionary m_ActiveClients = new Dictionary(); + + private IMessageTransferModule m_MsgTransferModule = null; + + private IGroupsModule m_GroupsModule = null; + + // Config Options + private bool m_GroupMessagingEnabled = true; + private bool m_debugEnabled = true; + + #region IRegionModule Members + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); + + if (groupsConfig == null) + { + // Do not run this module by default. + m_log.Info("[GROUPS-MESSAGING]: No config found in OpenSim.ini -- not enabling XmlRpcGroupsMessaging"); + return; + } + else + { + if (!groupsConfig.GetBoolean("Enabled", false)) + { + m_log.Info("[GROUPS-MESSAGING]: Groups disabled in configuration"); + return; + } + + if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + { + m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); + + return; + } + + m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); + + if (!m_GroupMessagingEnabled) + { + m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); + return; + } + + m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + + } + + m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up"); + + } + + public void AddRegion(Scene scene) + { + } + public void RegionLoaded(Scene scene) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + if (!m_GroupMessagingEnabled) + return; + + + m_GroupsModule = scene.RequestModuleInterface(); + + // No groups module, no groups messaging + if (m_GroupsModule == null) + { + m_GroupMessagingEnabled = false; + m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); + Close(); + return; + } + + m_MsgTransferModule = scene.RequestModuleInterface(); + + // No message transfer module, no groups messaging + if (m_MsgTransferModule == null) + { + m_GroupMessagingEnabled = false; + m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); + Close(); + return; + } + + + m_SceneList.Add(scene); + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += OnClientClosed; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + + } + + public void RemoveRegion(Scene scene) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_SceneList.Remove(scene); + } + + + public void Close() + { + m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); + + + foreach (Scene scene in m_SceneList) + { + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnClientClosed -= OnClientClosed; + scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + } + + m_SceneList.Clear(); + + m_GroupsModule = null; + m_MsgTransferModule = null; + } + + public string Name + { + get { return "XmlRpcGroupsMessaging"; } + } + + #endregion + + #region SimGridEventHandlers + + private void OnNewClient(IClientAPI client) + { + RegisterClientAgent(client); + } + private void OnClientClosed(UUID AgentId) + { + UnregisterClientAgent(AgentId); + } + + private void OnGridInstantMessage(GridInstantMessage msg) + { + m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + DebugGridInstantMessage(msg); + + // Incoming message from a group + if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true)) + { + if (m_ActiveClients.ContainsKey(msg.toAgentID)) + { + UUID GroupID = new UUID(msg.fromAgentID); + // SendMessageToGroup(im); + + GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); + if (GroupInfo != null) + { + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); + + // Force? open the group session dialog??? + IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface(); + eq.ChatterboxInvitation( + GroupID + , GroupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message, new UUID(msg.toAgentID) + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline==1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(GroupInfo.GroupName) + ); + + eq.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) + , new UUID(msg.fromAgentID) + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + + } + } + } + + } + + #endregion + + #region ClientEvents + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + DebugGridInstantMessage(im); + + // Start group IM session + if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) + { + UUID GroupID = new UUID(im.toAgentID); + + GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); + if (GroupInfo != null) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName); + + // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0])); + + ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID); + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + queue.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) + , new UUID(im.fromAgentID) + , new UUID(im.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + } + } + + // Send a message to a group + if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) + { + UUID GroupID = new UUID(im.toAgentID); + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID); + + SendMessageToGroup(im, GroupID); + } + + // Incoming message from a group + if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true)) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID); + } + } + #endregion + + private void RegisterClientAgent(IClientAPI client) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + lock (m_ActiveClients) + { + if (!m_ActiveClients.ContainsKey(client.AgentId.Guid)) + { + client.OnInstantMessage += OnInstantMessage; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); + + m_ActiveClients.Add(client.AgentId.Guid, client); + } + else + { + // Remove old client connection for this agent + UnregisterClientAgent(client.AgentId); + + // Add new client connection + RegisterClientAgent(client); + } + } + } + private void UnregisterClientAgent(UUID agentID) + { + lock (m_ActiveClients) + { + if (m_ActiveClients.ContainsKey(agentID.Guid)) + { + IClientAPI client = m_ActiveClients[agentID.Guid]; + client.OnInstantMessage -= OnInstantMessage; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name); + + m_ActiveClients.Remove(agentID.Guid); + } + else + { + m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here."); + } + } + } + + private void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = im.imSessionID; + msg.fromAgentID = im.imSessionID; // GroupID + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = new byte[1] { 0 }; + + foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID)) + { + msg.toAgentID = member.AgentID.Guid; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + } + + void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap moderatedMap = new OSDMap(4); + moderatedMap.Add("voice", OSD.FromBoolean(false)); + + OSDMap sessionMap = new OSDMap(4); + sessionMap.Add("moderated_mode", moderatedMap); + sessionMap.Add("session_name", OSD.FromString(groupName)); + sessionMap.Add("type", OSD.FromInteger(0)); + sessionMap.Add("voice_enabled", OSD.FromBoolean(false)); + + + OSDMap bodyMap = new OSDMap(4); + bodyMap.Add("session_id", OSD.FromUUID(groupID)); + bodyMap.Add("temp_session_id", OSD.FromUUID(groupID)); + bodyMap.Add("success", OSD.FromBoolean(true)); + bodyMap.Add("session_info", sessionMap); + + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + + if (queue != null) + { + queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); + } + + } + + + private void DebugGridInstantMessage(GridInstantMessage im) + { + if (m_debugEnabled) + { + m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromGroup({0})", im.fromGroup ? "True" : "False"); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentID({0})", im.fromAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentName({0})", im.fromAgentName.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: imSessionID({0})", im.imSessionID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: message({0})", im.message.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: offline({0})", im.offline.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: toAgentID({0})", im.toAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); + } + } + + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs new file mode 100644 index 0000000..ca08fe2 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -0,0 +1,1039 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; + +using System.Collections; +//using Nwc.XmlRpc; + +using log4net; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Framework.EventQueue; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; +using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; + + + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + public class XmlRpcGroupsModule : INonSharedRegionModule, IGroupsModule + { + /// + /// To use this module, you must specify the following in your OpenSim.ini + /// [GROUPS] + /// Enabled = true + /// Module = XmlRpcGroups + /// XmlRpcMessagingEnabled = true + /// XmlRpcNoticesEnabled = true + /// XmlRpcDebugEnabled = true + /// + /// + + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_SceneList = new List(); + + // This only works when running as non-Shared, in shared, there may be multiple IClientAPIs for a single client + private Dictionary m_ActiveClients = new Dictionary(); + + private IMessageTransferModule m_MsgTransferModule = null; + + private IGroupDataProvider m_groupData = null; + + // Configuration settings + private const string m_defaultXmlRpcServiceURL = "http://osflotsam.org/xmlrpc.php"; + private bool m_GroupsEnabled = false; + private bool m_GroupNoticesEnabled = true; + private bool m_debugEnabled = true; + + #region IRegionModule Members + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + m_log.Info("[GROUPS]: Initializing XmlRpcGroups"); + + if (groupsConfig == null) + { + // Do not run this module by default. + m_log.Info("[GROUPS]: No config found in OpenSim.ini -- not enabling XmlRpcGroups"); + return; + } + else + { + m_GroupsEnabled = groupsConfig.GetBoolean("Enabled", false); + if (!m_GroupsEnabled) + { + m_log.Info("[GROUPS]: Groups disabled in configuration"); + return; + } + + if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + { + m_log.Info("[GROUPS]: Config Groups Module not set to XmlRpcGroups"); + + return; + } + + string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); + m_groupData = new XmlRpcGroupDataProvider(ServiceURL); + m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL); + + m_GroupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); + m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + + } + } + + public void AddRegion(Scene scene) + { + scene.RegisterModuleInterface(this); + } + public void RegionLoaded(Scene scene) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + if (!m_GroupsEnabled) + return; + + + m_MsgTransferModule = scene.RequestModuleInterface(); + + // No message transfer module, no notices, group invites, rejects, ejects, etc + if (m_MsgTransferModule == null) + { + m_GroupsEnabled = false; + m_log.Info("[GROUPS]: Could not get MessageTransferModule"); + Close(); + return; + } + + + m_SceneList.Add(scene); + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += OnClientClosed; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + + } + + public void RemoveRegion(Scene scene) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_SceneList.Remove(scene); + } + + public void Close() + { + m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); + } + + public string Name + { + get { return "XmlRpcGroupsModule"; } + } + + #endregion + + private void UpdateAllClientsWithGroupInfo() + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + foreach (IClientAPI client in m_ActiveClients.Values) + { + UpdateClientWithGroupInfo(client); + } + } + + private void UpdateClientWithGroupInfo(IClientAPI client) + { + m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); + OnAgentDataUpdateRequest(client, client.AgentId, UUID.Zero); + + + // Need to send a group membership update to the client + // UDP version doesn't seem to behave nicely + // client.SendGroupMembership(GetMembershipData(client.AgentId)); + + GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(client.AgentId).ToArray(); + + SendGroupMembershipInfoViaCaps(client, membershipData); + client.SendAvatarGroupsReply(client.AgentId, membershipData); + + } + + #region EventHandlers + private void OnNewClient(IClientAPI client) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + lock (m_ActiveClients) + { + if (!m_ActiveClients.ContainsKey(client.AgentId)) + { + client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; + client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; + client.OnDirFindQuery += OnDirFindQuery; + client.OnInstantMessage += OnInstantMessage; + + m_ActiveClients.Add(client.AgentId, client); + } + } + + UpdateClientWithGroupInfo(client); + } + private void OnClientClosed(UUID AgentId) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + lock (m_ActiveClients) + { + if (m_ActiveClients.ContainsKey(AgentId)) + { + IClientAPI client = m_ActiveClients[AgentId]; + client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; + client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; + client.OnDirFindQuery -= OnDirFindQuery; + client.OnInstantMessage -= OnInstantMessage; + + m_ActiveClients.Remove(AgentId); + } + else + { + m_log.InfoFormat("[GROUPS] Client closed that wasn't registered here."); + } + + + } + + } + + + void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) + { + if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) + { + m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); + } + + } + + private void OnAgentDataUpdateRequest(IClientAPI remoteClient, + UUID AgentID, UUID SessionID) + { + m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, SessionID); + + + UUID ActiveGroupID = UUID.Zero; + string ActiveGroupTitle = string.Empty; + string ActiveGroupName = string.Empty; + ulong ActiveGroupPowers = (ulong)GroupPowers.None; + + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(AgentID); + if (membership != null) + { + ActiveGroupID = membership.GroupID; + ActiveGroupTitle = membership.GroupTitle; + ActiveGroupPowers = membership.GroupPowers; + } + + string firstname, lastname; + IClientAPI agent; + if( m_ActiveClients.TryGetValue(AgentID, out agent) ) + { + firstname = agent.FirstName; + lastname = agent.LastName; + } else { + firstname = "Unknown"; + lastname = "Unknown"; + } + + UpdateScenePresenceWithTitle(AgentID, ActiveGroupTitle); + + remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, + lastname, ActiveGroupPowers, ActiveGroupName, + ActiveGroupTitle); + } + + private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + string GroupName; + + GroupRecord group = m_groupData.GetGroupRecord(GroupID, null); + if (group != null) + { + GroupName = group.GroupName; + } + else + { + GroupName = "Unknown"; + } + + + remote_client.SendGroupNameReply(GroupID, GroupName); + } + + + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + // Group invitations + if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) + { + m_log.WarnFormat("[GROUPS] Received an IIM for {0}.", ((InstantMessageDialog)im.dialog).ToString()); + + + UUID inviteID = new UUID(im.imSessionID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); + + m_log.WarnFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); + + UUID fromAgentID = new UUID(im.fromAgentID); + if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) + { + + // Accept + if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) + { + m_log.WarnFormat("[GROUPS] Received an accept invite notice."); + + // and the sessionid is the role + m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + + if (m_MsgTransferModule != null) + { + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = UUID.Zero.Guid; + msg.toAgentID = inviteInfo.AgentID.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Groups"; + msg.message = string.Format("You have been added to the group."); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = new byte[0]; + + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + + UpdateAllClientsWithGroupInfo(); + + m_groupData.RemoveAgentToGroupInvite(inviteID); + } + + // Reject + if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) + { + m_log.WarnFormat("[GROUPS] Received a reject invite notice."); + m_groupData.RemoveAgentToGroupInvite(inviteID); + + } + + + } + } + + // Group notices + if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) + { + if (!m_GroupNoticesEnabled) + { + return; + } + + UUID GroupID = new UUID(im.toAgentID); + if( m_groupData.GetGroupRecord(GroupID, null) != null) + { + UUID NoticeID = UUID.Random(); + string Subject = im.message.Substring(0, im.message.IndexOf('|')); + string Message = im.message.Substring(Subject.Length + 1); + + byte[] bucket; + + if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) + { + bucket = new byte[19]; + bucket[0] = 0; //dunno + bucket[1] = 0; //dunno + GroupID.ToBytes(bucket, 2); + bucket[18] = 0; //dunno + } + else + { + string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); + binBucket = binBucket.Remove(0, 14).Trim(); + m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); + + OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + + foreach (string key in binBucketOSD.Keys) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } + + // treat as if no attachment + bucket = new byte[19]; + bucket[0] = 0; //dunno + bucket[1] = 0; //dunno + GroupID.ToBytes(bucket, 2); + bucket[18] = 0; //dunno + } + + + m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + if (OnNewGroupNotice != null) + { + OnNewGroupNotice(GroupID, NoticeID); + } + + // Build notice IIM + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + + // Send notice out to everyone that wants notices + foreach( GroupMembersData member in m_groupData.GetGroupMembers(GroupID) ) + { + if( member.AcceptNotices ) + { + msg.toAgentID = member.AgentID.Guid; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + + } + } + + + + } + } + + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presense server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue + if ((im.dialog == 210)) + { + // This is sent from the region that the ejectee was ejected from + // if it's being delivered here, then the ejectee is here + // so we need to send local updates to the agent. + + + if (m_MsgTransferModule != null) + { + im.dialog = (byte)InstantMessageDialog.MessageFromAgent; + m_MsgTransferModule.SendInstantMessage(im, delegate(bool success) { }); + } + + UUID ejecteeID = new UUID(im.toAgentID); + UUID groupID = new UUID(im.toAgentID); + if (m_ActiveClients.ContainsKey(ejecteeID)) + { + m_ActiveClients[ejecteeID].SendAgentDropGroup(groupID); + } + + } + + + + } + + private void OnGridInstantMessage(GridInstantMessage msg) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Trigger the above event handler + OnInstantMessage(null, msg); + } + + + #endregion + + + private void UpdateScenePresenceWithTitle(UUID AgentID, string Title) + { + m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title); + ScenePresence presence = null; + lock (m_SceneList) + { + foreach (Scene scene in m_SceneList) + { + presence = scene.GetScenePresence(AgentID); + if (presence != null) + { + presence.Grouptitle = Title; + + // FixMe: Ter suggests a "Schedule" method that I can't find. + presence.SendFullUpdateToAllClients(); + } + } + } + } + + + #region IGroupsModule Members + + public event NewGroupNotice OnNewGroupNotice; + + public GroupRecord GetGroupRecord(UUID GroupID) + { + return m_groupData.GetGroupRecord(GroupID, null); + } + + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); + + // UpdateClientWithGroupInfo(remoteClient); + UpdateAllClientsWithGroupInfo(); + } + + /// + /// Get the Role Titles for an Agent, for a specific group + /// + public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); + + List titles = new List(); + foreach (GroupRolesData role in agentRoles) + { + GroupTitlesData title = new GroupTitlesData(); + title.Name = role.Name; + title.Selected = agentMembership.ActiveRole == role.RoleID; + title.UUID = role.RoleID; + } + + return titles; + } + + public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupMembers(groupID); + + foreach (GroupMembersData member in data) + { + m_log.InfoFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); + } + + return data; + + } + + public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupRoles(groupID); + + foreach (GroupRolesData member in data) + { + m_log.InfoFormat("[GROUPS] {0} {1}", member.Title, member.Members); + } + + return data; + + } + + public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupRoleMembers(groupID); + + foreach (GroupRoleMembersData member in data) + { + m_log.InfoFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); + } + + return data; + + + } + + public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupProfileData profile = new GroupProfileData(); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); + if (groupInfo != null) + { + profile.AllowPublish = groupInfo.AllowPublish; + profile.Charter = groupInfo.Charter; + profile.FounderID = groupInfo.FounderID; + profile.GroupID = groupID; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(groupID).Count; + profile.InsigniaID = groupInfo.GroupPicture; + profile.MaturePublish = groupInfo.MaturePublish; + profile.MembershipFee = groupInfo.MembershipFee; + profile.Money = 0; // TODO: Get this from the currency server? + profile.Name = groupInfo.GroupName; + profile.OpenEnrollment = groupInfo.OpenEnrollment; + profile.OwnerRole = groupInfo.OwnerRoleID; + profile.ShowInList = groupInfo.ShowInList; + } + + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); + if (memberInfo != null) + { + profile.MemberTitle = memberInfo.GroupTitle; + profile.PowersMask = memberInfo.GroupPowers; + } + + return profile; + } + + public GroupMembershipData[] GetMembershipData(UUID UserID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + return m_groupData.GetAgentGroupMemberships(UserID).ToArray(); + } + + public GroupMembershipData GetMembershipData(UUID GroupID, UUID UserID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + return m_groupData.GetAgentGroupMembership(UserID, GroupID); + } + + public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security Check? + + m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + } + + public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) + { + // TODO: Security Check? + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); + } + + public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + if( m_groupData.GetGroupRecord(UUID.Zero, name) != null ) + { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); + return UUID.Zero; + } + + UUID GroupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + + remoteClient.SendCreateGroupReply(GroupID, true, "Group created successfullly"); + + UpdateClientWithGroupInfo(remoteClient); + + return GroupID; + } + + public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // ToDo: check if agent is a member of group and is allowed to see notices? + + return m_groupData.GetGroupNotices(GroupID).ToArray(); + } + + /// + /// Get the title of the agent's current role. + /// + public string GetGroupTitle(UUID avatarID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); + if (membership != null) + { + return membership.GroupTitle; + } + return string.Empty; + } + + /// + /// Change the current Active Group Role for Agent + /// + public void GroupTitleUpdate(IClientAPI remoteClient, UUID GroupID, UUID TitleRoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, GroupID, TitleRoleID); + + UpdateAllClientsWithGroupInfo(); + } + + + public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security Checks? + + switch ((OpenMetaverse.GroupRoleUpdate)updateType) + { + case OpenMetaverse.GroupRoleUpdate.Create: + m_groupData.AddGroupRole(groupID, UUID.Random(), name, description, title, powers); + break; + + case OpenMetaverse.GroupRoleUpdate.Delete: + m_groupData.RemoveGroupRole(groupID, roleID); + break; + + case OpenMetaverse.GroupRoleUpdate.UpdateAll: + case OpenMetaverse.GroupRoleUpdate.UpdateData: + case OpenMetaverse.GroupRoleUpdate.UpdatePowers: + m_groupData.UpdateGroupRole(groupID, roleID, name, description, title, powers); + break; + + case OpenMetaverse.GroupRoleUpdate.NoUpdate: + default: + // No Op + break; + + } + + UpdateClientWithGroupInfo(remoteClient); + } + + public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // Todo: Security check + + switch (changes) + { + case 0: + // Add + m_groupData.AddAgentToGroupRole(memberID, groupID, roleID); + + break; + case 1: + // Remove + m_groupData.RemoveAgentFromGroupRole(memberID, groupID, roleID); + + break; + default: + m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); + break; + } + UpdateClientWithGroupInfo(remoteClient); + } + + public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); + + if (data != null) + { + if (m_MsgTransferModule != null) + { + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = data.GroupID.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Group Notice From"; + msg.message = data.noticeData.Subject + "|" + data.Message; + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = data.BinaryBucket; + + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + } + + } + + public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) + { + m_log.WarnFormat("[GROUPS] {0} is probably not properly implemented", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.toAgentID = agentID.Guid; + msg.dialog = dialog; + // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + + GroupNoticeInfo info = m_groupData.GetGroupNotice(groupNoticeID); + if (info != null) + { + msg.fromAgentID = info.GroupID.Guid; + msg.timestamp = info.noticeData.Timestamp; + msg.fromAgentName = info.noticeData.FromName; + msg.message = info.noticeData.Subject + "|" + info.Message; + msg.binaryBucket = info.BinaryBucket; + } + + return msg; + } + + public void SendAgentGroupDataUpdate(IClientAPI remoteClient) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UpdateClientWithGroupInfo(remoteClient); + } + + public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Should check to see if OpenEnrollment, or if there's an outstanding invitation + m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); + + remoteClient.SendJoinGroupReply(groupID, true); + + UpdateClientWithGroupInfo(remoteClient); + } + + public void LeaveGroupRequest(IClientAPI remoteClient, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, GroupID); + + remoteClient.SendLeaveGroupReply(GroupID, true); + + remoteClient.SendAgentDropGroup(GroupID); + + UpdateClientWithGroupInfo(remoteClient); + } + + public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID GroupID, UUID EjecteeID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Todo: Security check? + m_groupData.RemoveAgentFromGroup(EjecteeID, GroupID); + + remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, GroupID, true); + + if (m_MsgTransferModule != null) + { + GroupRecord groupInfo = m_groupData.GetGroupRecord(GroupID, null); + UserProfileData userProfile = m_SceneList[0].CommsManager.UserService.GetUserProfile(EjecteeID); + + if ((groupInfo == null) || (userProfile == null)) + { + return; + } + + + // Send Message to Ejectee + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = info.GroupID; + msg.toAgentID = EjecteeID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); + + + // Message to ejector + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presense server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue + + msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + if (userProfile != null) + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); + } + else + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); + } + msg.dialog = (byte)210; //interop + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success, ToString()); }); + + + + } + + + UpdateAllClientsWithGroupInfo(); + } + + public void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InvitedAgentID, UUID RoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", GroupID, InvitedAgentID, RoleID); + + // Todo: Security check, probably also want to send some kind of notification + UUID InviteID = UUID.Random(); + m_log.WarnFormat("[GROUPS] Invite ID: {0}", InviteID); + m_groupData.AddAgentToGroupInvite(InviteID, GroupID, RoleID, InvitedAgentID); + + if (m_MsgTransferModule != null) + { + Guid inviteUUID = InviteID.Guid; + + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = inviteUUID; + + // msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GroupID.Guid; + msg.toAgentID = InvitedAgentID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[20]; + + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); + } + } + + #endregion + + void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, GroupMembershipData[] data) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDArray AgentData = new OSDArray(1); + OSDMap AgentDataMap = new OSDMap(1); + AgentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId)); + AgentData.Add(AgentDataMap); + + + OSDArray GroupData = new OSDArray(data.Length); + OSDArray NewGroupData = new OSDArray(data.Length); + + foreach (GroupMembershipData membership in data) + { + OSDMap GroupDataMap = new OSDMap(6); + OSDMap NewGroupDataMap = new OSDMap(1); + + GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); + GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); + GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); + GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); + GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); + GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); + NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); + + GroupData.Add(GroupDataMap); + NewGroupData.Add(NewGroupDataMap); + } + + OSDMap llDataStruct = new OSDMap(3); + llDataStruct.Add("AgentData", AgentData); + llDataStruct.Add("GroupData", GroupData); + llDataStruct.Add("NewGroupData", NewGroupData); + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + + if (queue != null) + { + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); + } + + } + } + +} -- cgit v1.1 From 5ae8ad55cda56b023be0efced1a41387d4889783 Mon Sep 17 00:00:00 2001 From: diva Date: Sat, 18 Apr 2009 22:31:38 +0000 Subject: Little bug fix on the Groups module to get over an exception upon login. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index ca08fe2..6252d56 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -123,8 +123,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - scene.RegisterModuleInterface(this); + if (m_GroupsEnabled) + scene.RegisterModuleInterface(this); } + public void RegionLoaded(Scene scene) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From a416e75ddba9de7448c00ecb88cb2f1a1949dac2 Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Sun, 19 Apr 2009 00:11:14 +0000 Subject: Thank you kindly, MCortez, for a patch that: This hooks up the LandManagementModule to handle the DeedParcelToGroup packet. Now people can start testing land assigned to and owned by groups. Also fixes a viewer crash issue when searching for and then joining a group with an agent that is not already being tracked by groups server. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 6252d56..5ebab65 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -552,7 +552,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { GroupTitlesData title = new GroupTitlesData(); title.Name = role.Name; - title.Selected = agentMembership.ActiveRole == role.RoleID; + if (agentMembership != null) + { + title.Selected = agentMembership.ActiveRole == role.RoleID; + } title.UUID = role.RoleID; } -- cgit v1.1 From 088ed685625f64762461c38704ea17b20bb8a2df Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Sun, 19 Apr 2009 16:22:26 +0000 Subject: Fixes Mantis#3489. Thank you kindly, MCortez for a patch that: Group profile page is showing an empty dropdown for titles and this patch fixes this. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 5ebab65..7ae3b90 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -557,6 +557,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups title.Selected = agentMembership.ActiveRole == role.RoleID; } title.UUID = role.RoleID; + + titles.Add(title); } return titles; -- cgit v1.1 From 489758f68abe15e55f73d660225e7af1851b0882 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 20 Apr 2009 13:39:41 +0000 Subject: Make sure that the groups module is really disabled when it's not configured. Fixes an issue where the presence of any groups section will make XmlRpcGroups think it should hook client events. --- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 7ae3b90..6a3aa06 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -107,6 +107,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") { m_log.Info("[GROUPS]: Config Groups Module not set to XmlRpcGroups"); + m_GroupsEnabled = false; return; } @@ -129,11 +130,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void RegionLoaded(Scene scene) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - if (!m_GroupsEnabled) return; + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_MsgTransferModule = scene.RequestModuleInterface(); @@ -157,6 +157,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void RemoveRegion(Scene scene) { + if (!m_GroupsEnabled) + return; + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_SceneList.Remove(scene); @@ -164,6 +167,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { + if (!m_GroupsEnabled) + return; m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); } -- cgit v1.1 From 334021732003c2ff7ce69db84f7719c2586dff59 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 20 Apr 2009 13:59:18 +0000 Subject: Also make GroupsMessaging quit trying to run and reduce it's debug spamming somewhat --- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index d14d135..5990fa6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -90,6 +90,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") { m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); + m_GroupMessagingEnabled = false; return; } @@ -115,11 +116,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } public void RegionLoaded(Scene scene) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - if (!m_GroupMessagingEnabled) return; + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + m_GroupsModule = scene.RequestModuleInterface(); @@ -154,6 +155,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void RemoveRegion(Scene scene) { + if (!m_GroupMessagingEnabled) + return; + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_SceneList.Remove(scene); @@ -162,6 +166,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { + if (!m_GroupMessagingEnabled) + return; + m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); -- cgit v1.1 From f31a60bad7133f877fe50570d811b320905280ab Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Tue, 21 Apr 2009 13:17:34 +0000 Subject: From: Alan Webb Fixes IRC reconnect problem When a session fails to establish, the login attempt eventually times out and the login is retried. This should occur once every 25 seconds (to give the server plenty of time to respond). In fact the interval was typically only 10 seconds, this was being caused by a second reset that was being scheduled when the failed listener thread was terminated. Because the second reset occurred inside the ICC timeout, it eventually gets scheduled after only 10 seconds. In addition to this, the connector was being added to the monitoring twice. This was harmless, but entirely redundant. Both of these problems have been fixed and tested. Each connector now maintains a count of how often it has been reset. The listener thread records this value on entry and checks for a change on exit. If the counts are the same, then the listener is exiting and can potentially reschedule the connection. --- .../OptionalModules/Avatar/Chat/IRCConnector.cs | 25 ++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index 5123ef5..ca85817 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -96,6 +96,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal int depends = 0; + // This variable counts the number of resets that have been performed + // on the connector. When a listener thread terminates, it checks to + // see of the reset count has changed before it schedules another + // reset. + + internal int m_resetk = 0; + // Working threads private Thread m_listener = null; @@ -229,7 +236,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Add the newly created connector to the known connectors list - m_connectors.Add(this); + // m_connectors.Add(this); m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); @@ -393,6 +400,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (m_connected) { + m_log.InfoFormat("[IRC-Connector-{0}] Resetting connector", idn); // Mark as disconnected. This will allow the listener thread @@ -410,6 +418,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_connected = false; m_pending = false; + m_resetk++; } @@ -478,7 +487,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void ListenerRun() { + string inputLine; + int resetk = m_resetk; try { @@ -534,7 +545,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // The connection is marked as not connected the first time // through reconnect. - if (m_enabled) Reconnect(); + if (m_enabled && (m_resetk == resetk)) + Reconnect(); } @@ -830,6 +842,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat foreach (IRCConnector connector in m_connectors) { + // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); if (connector.Enabled) { if (!connector.Connected) @@ -851,7 +864,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { if (connector.m_timeout == 0) { - m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); + // m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); connector.Reconnect(); } else @@ -865,10 +878,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); connector.m_writer.Flush(); } - catch (Exception /*e*/) + catch (Exception e) { - // m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); - // m_log.Debug(e); + m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); + m_log.Debug(e); connector.Reconnect(); } } -- cgit v1.1 From 13f5dd5f353c5ea5e86944af3dbaa739c8be1a8a Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Tue, 21 Apr 2009 15:30:03 +0000 Subject: Update svn properties. --- .../Avatar/XmlRpcGroups/IGroupDataProvider.cs | 170 +- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 2034 +++++++++---------- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 860 ++++---- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 2102 ++++++++++---------- 4 files changed, 2583 insertions(+), 2583 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs index 6e9105d..3fd6116 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs @@ -1,85 +1,85 @@ -/* - * 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 OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; - -using OpenMetaverse; - -using OpenSim.Framework; - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - interface IGroupDataProvider - { - UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(UUID GroupID, string GroupName); - List FindGroups(string search); - List GetGroupMembers(UUID GroupID); - - void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(UUID groupID, UUID roleID); - List GetGroupRoles(UUID GroupID); - List GetGroupRoleMembers(UUID GroupID); - - void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(UUID AgentID, UUID GroupID); - - void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(UUID inviteID); - void RemoveAgentToGroupInvite(UUID inviteID); - - - void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(UUID AgentID, UUID GroupID); - - void SetAgentActiveGroup(UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(UUID AgentID); - - void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - - GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(UUID AgentID); - - void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(UUID noticeID); - List GetGroupNotices(UUID GroupID); - } - - public class GroupInviteInfo - { - public UUID GroupID = UUID.Zero; - public UUID RoleID = UUID.Zero; - public UUID AgentID = UUID.Zero; - public UUID InviteID = UUID.Zero; - } - -} +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; + +using OpenMetaverse; + +using OpenSim.Framework; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + interface IGroupDataProvider + { + UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(UUID GroupID, string GroupName); + List FindGroups(string search); + List GetGroupMembers(UUID GroupID); + + void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(UUID groupID, UUID roleID); + List GetGroupRoles(UUID GroupID); + List GetGroupRoleMembers(UUID GroupID); + + void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(UUID AgentID, UUID GroupID); + + void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(UUID inviteID); + void RemoveAgentToGroupInvite(UUID inviteID); + + + void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(UUID AgentID, UUID GroupID); + + void SetAgentActiveGroup(UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(UUID AgentID); + + void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + + GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(UUID AgentID); + + void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(UUID noticeID); + List GetGroupNotices(UUID GroupID); + } + + public class GroupInviteInfo + { + public UUID GroupID = UUID.Zero; + public UUID RoleID = UUID.Zero; + public UUID AgentID = UUID.Zero; + public UUID InviteID = UUID.Zero; + } + +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 343bd6d..eff76cf 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -1,1017 +1,1017 @@ -/* - * 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 OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -//using System.Text; - -using Nwc.XmlRpc; - -using log4net; -// using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -//using OpenSim.Region.Framework.Interfaces; - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - - public class XmlRpcGroupDataProvider : IGroupDataProvider - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private string m_serviceURL = "http://osflotsam.org/xmlrpc.php"; - - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | GroupPowers.AllowVoiceChat | GroupPowers.ReceiveNotices | GroupPowers.StartProposal | GroupPowers.VoteOnProposal; - - public XmlRpcGroupDataProvider(string serviceURL) - { - m_serviceURL = serviceURL; - } - - /// - /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. - /// - public UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) - { - UUID GroupID = UUID.Random(); - UUID OwnerRoleID = UUID.Random(); - - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - param["Name"] = name; - param["Charter"] = charter; - param["ShowInList"] = showInList == true ? 1 : 0; - param["InsigniaID"] = insigniaID.ToString(); - param["MembershipFee"] = 0; - param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; - param["AllowPublish"] = allowPublish == true ? 1 : 0; - param["MaturePublish"] = maturePublish == true ? 1 : 0; - param["FounderID"] = founderID.ToString(); - param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); - param["OwnerRoleID"] = OwnerRoleID.ToString(); - - // Would this be cleaner as (GroupPowers)ulong.MaxValue; - GroupPowers OwnerPowers = GroupPowers.Accountable - | GroupPowers.AllowEditLand - | GroupPowers.AllowFly - | GroupPowers.AllowLandmark - | GroupPowers.AllowRez - | GroupPowers.AllowSetHome - | GroupPowers.AllowVoiceChat - | GroupPowers.AssignMember - | GroupPowers.AssignMemberLimited - | GroupPowers.ChangeActions - | GroupPowers.ChangeIdentity - | GroupPowers.ChangeMedia - | GroupPowers.ChangeOptions - | GroupPowers.CreateRole - | GroupPowers.DeedObject - | GroupPowers.DeleteRole - | GroupPowers.Eject - | GroupPowers.FindPlaces - | GroupPowers.Invite - | GroupPowers.JoinChat - | GroupPowers.LandChangeIdentity - | GroupPowers.LandDeed - | GroupPowers.LandDivideJoin - | GroupPowers.LandEdit - | GroupPowers.LandEjectAndFreeze - | GroupPowers.LandGardening - | GroupPowers.LandManageAllowed - | GroupPowers.LandManageBanned - | GroupPowers.LandManagePasses - | GroupPowers.LandOptions - | GroupPowers.LandRelease - | GroupPowers.LandSetSale - | GroupPowers.ModerateChat - | GroupPowers.ObjectManipulate - | GroupPowers.ObjectSetForSale - | GroupPowers.ReceiveNotices - | GroupPowers.RemoveMember - | GroupPowers.ReturnGroupOwned - | GroupPowers.ReturnGroupSet - | GroupPowers.ReturnNonGroup - | GroupPowers.RoleProperties - | GroupPowers.SendNotices - | GroupPowers.SetLandingPoint - | GroupPowers.StartProposal - | GroupPowers.VoteOnProposal; - param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); - - - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.createGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - - return UUID.Parse((string)respData["GroupID"]); - } - - public void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["Charter"] = charter; - param["ShowInList"] = showInList == true ? 1 : 0; - param["InsigniaID"] = insigniaID.ToString(); - param["MembershipFee"] = membershipFee; - param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; - param["AllowPublish"] = allowPublish == true ? 1 : 0; - param["MaturePublish"] = maturePublish == true ? 1 : 0; - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.updateGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["RoleID"] = roleID.ToString(); - param["Name"] = name; - param["Description"] = description; - param["Title"] = title; - param["Powers"] = powers.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addRoleToGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void RemoveGroupRole(UUID groupID, UUID roleID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["RoleID"] = roleID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeRoleFromGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["RoleID"] = roleID.ToString(); - if (name != null) - { - param["Name"] = name; - } - if (description != null) - { - param["Description"] = description; - } - if (title != null) - { - param["Title"] = title; - } - param["Powers"] = powers.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.updateGroupRole", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) - { - Hashtable param = new Hashtable(); - if ((GroupID != null) && (GroupID != UUID.Zero)) - { - param["GroupID"] = GroupID.ToString(); - } - if ((GroupName != null) && (GroupName != string.Empty)) - { - param["Name"] = GroupName.ToString(); - } - - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - if ((string)respData["error"] != "Group Not Found") - { - LogRespDataToConsoleError(respData); - } - return null; - } - - return GroupProfileHashtableToGroupRecord(respData); - - } - - public GroupProfileData GetMemberGroupProfile(UUID GroupID, UUID AgentID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - if ((string)respData["error"] != "Group Not Found") - { - LogRespDataToConsoleError(respData); - } - return new GroupProfileData(); - } - - GroupMembershipData MemberInfo = GetAgentGroupMembership(AgentID, GroupID); - GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); - - MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; - MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; - - return MemberGroupProfile; - - } - - private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) - { - GroupProfileData group = new GroupProfileData(); - group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); - group.Name = (string)groupProfile["Name"]; - - if (groupProfile["Charter"] != null) - { - group.Charter = (string)groupProfile["Charter"]; - } - - group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; - group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); - group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); - group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; - group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; - group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; - group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); - group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); - - group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); - group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); - - return group; - } - - private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) - { - - GroupRecord group = new GroupRecord(); - m_log.Debug("GroupID"); - group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); - - m_log.Debug("Name"); - group.GroupName = groupProfile["Name"].ToString(); - - m_log.Debug("Charter"); - if (groupProfile["Charter"] != null) - { - group.Charter = (string)groupProfile["Charter"]; - } - - m_log.Debug("ShowInList"); - group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; - - m_log.Debug("InsigniaID"); - group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); - - m_log.Debug("MembershipFee"); - group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); - - m_log.Debug("OpenEnrollment"); - group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; - - m_log.Debug("AllowPublish"); - group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; - - m_log.Debug("MaturePublish"); - group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; - - m_log.Debug("FounderID"); - group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); - - m_log.Debug("OwnerRoleID"); - group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); - - return group; - } - - - public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.setAgentActiveGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - - } - - public void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["SelectedRoleID"] = RoleID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - - } - - public void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["AcceptNotices"] = AcceptNotices ? "1" : "0"; - param["ListInProfile"] = ListInProfile ? "1" : "0"; - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) - { - Hashtable param = new Hashtable(); - param["InviteID"] = inviteID.ToString(); - param["AgentID"] = agentID.ToString(); - param["RoleID"] = roleID.ToString(); - param["GroupID"] = groupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupInvite", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - if (respData["error"] != "Duplicate group invite requested") - { - LogRespDataToConsoleError(respData); - } - } - - - } - - public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) - { - Hashtable param = new Hashtable(); - param["InviteID"] = inviteID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentToGroupInvite", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - - return null; - } - - GroupInviteInfo inviteInfo = new GroupInviteInfo(); - inviteInfo.InviteID = inviteID; - inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); - inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); - inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); - - return inviteInfo; - } - - public void RemoveAgentToGroupInvite(UUID inviteID) - { - Hashtable param = new Hashtable(); - param["InviteID"] = inviteID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentToGroupInvite", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["RoleID"] = RoleID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void RemoveAgentFromGroup(UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["RoleID"] = RoleID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupRole", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - public void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["RoleID"] = RoleID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroupRole", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - - public List FindGroups(string search) - { - Hashtable param = new Hashtable(); - param["Search"] = search; - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.findGroups", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - List findings = new List(); - - if (respData.Contains("error")) - { - if (respData["error"].ToString() != "No groups found.") - { - LogRespDataToConsoleError(respData); - } - } - else - { - Hashtable results = (Hashtable)respData["results"]; - foreach (Hashtable groupFind in results.Values) - { - DirGroupsReplyData data = new DirGroupsReplyData(); - data.groupID = new UUID((string)groupFind["GroupID"]); ; - data.groupName = (string)groupFind["Name"]; - data.members = int.Parse((string)groupFind["Members"]); - // data.searchOrder = order; - - findings.Add(data); - } - } - - return findings; - } - - public GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMembership", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - if ((string)respData["error"] != "None Found") - { - LogRespDataToConsoleError(respData); - } - return null; - } - - GroupMembershipData data = HashTableToGroupMembershipData(respData); - - return data; - } - - public GroupMembershipData GetAgentActiveMembership(UUID AgentID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentActiveMembership", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - if (respData["error"].ToString() == "No Active Group Specified") - { - return null; - } - LogRespDataToConsoleError(respData); - return null; - } - - try - { - GroupMembershipData data = HashTableToGroupMembershipData(respData); - return data; - } - catch (System.Exception e) - { - LogRespDataToConsoleError(respData); - throw e; - } - } - - private void LogRespDataToConsoleError(Hashtable respData) - { - m_log.Error("[GROUPDATA] Error:"); - - foreach (string key in respData.Keys) - { - m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); - - object o = respData[key]; - - string[] lines = respData[key].ToString().Split(new char[] { '\n' }); - foreach (string line in lines) - { - m_log.ErrorFormat("[GROUPDATA] {0}", line); - } - - } - } - - public List GetAgentGroupMemberships(UUID AgentID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMemberships", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - List memberships = new List(); - - if (respData.Contains("error")) - { - if (respData["error"].ToString() != "No Memberships") - { - LogRespDataToConsoleError(respData); - } - } - else - { - foreach (object membership in respData.Values) - { - memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); - } - } - return memberships; - } - - public List GetAgentGroupRoles(UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentRoles", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - List Roles = new List(); - - if (respData.Contains("error")) - { - if ((string)respData["error"] != "None found") - { - LogRespDataToConsoleError(respData); - } - return Roles; - } - - foreach (Hashtable role in respData.Values) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = new UUID((string)role["RoleID"]); - data.Name = (string)role["Name"]; - data.Description = (string)role["Description"]; - data.Powers = ulong.Parse((string)role["Powers"]); - data.Title = (string)role["Title"]; - - Roles.Add(data); - } - - return Roles; - - - } - - public List GetGroupRoles(UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoles", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - return null; - } - - List Roles = new List(); - foreach (Hashtable role in respData.Values) - { - GroupRolesData data = new GroupRolesData(); - data.Description = (string)role["Description"]; - data.Members = int.Parse((string)role["Members"]); - data.Name = (string)role["Name"]; - data.Powers = ulong.Parse((string)role["Powers"]); - data.RoleID = new UUID((string)role["RoleID"]); - data.Title = (string)role["Title"]; - - Roles.Add(data); - } - - return Roles; - - } - - private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) - { - GroupMembershipData data = new GroupMembershipData(); - data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); - data.Contribution = int.Parse((string)respData["Contribution"]); - data.ListInProfile = ((string)respData["ListInProfile"] == "1"); - - data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); - data.GroupTitle = (string)respData["Title"]; - - data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); - - // Is this group the agent's active group - - data.GroupID = new UUID((string)respData["GroupID"]); - - UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); - data.Active = data.GroupID.Equals(ActiveGroup); - - data.AllowPublish = ((string)respData["AllowPublish"] == "1"); - data.Charter = (string)respData["Charter"]; - data.FounderID = new UUID((string)respData["FounderID"]); - data.GroupID = new UUID((string)respData["GroupID"]); - data.GroupName = (string)respData["GroupName"]; - data.GroupPicture = new UUID((string)respData["InsigniaID"]); - data.MaturePublish = ((string)respData["MaturePublish"] == "1"); - data.MembershipFee = int.Parse((string)respData["MembershipFee"]); - data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); - data.ShowInList = ((string)respData["ShowInList"] == "1"); - return data; - } - - public List GetGroupMembers(UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupMembers", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - return null; - } - - List members = new List(); - foreach (Hashtable membership in respData.Values) - { - GroupMembersData data = new GroupMembersData(); - - data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; - data.AgentID = new UUID((string)membership["AgentID"]); - data.Contribution = int.Parse((string)membership["Contribution"]); - data.IsOwner = ((string)membership["IsOwner"]) == "1"; - data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; - data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); - data.Title = (string)membership["Title"]; - - members.Add(data); - } - - return members; - - } - - public List GetGroupRoleMembers(UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoleMembers", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - return null; - } - - List members = new List(); - foreach (Hashtable membership in respData.Values) - { - GroupRoleMembersData data = new GroupRoleMembersData(); - - data.MemberID = new UUID((string)membership["AgentID"]); - data.RoleID = new UUID((string)membership["RoleID"]); - - members.Add(data); - } - - return members; - } - - public List GetGroupNotices(UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotices", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - List values = new List(); - - if (respData.Contains("error")) - { - if ((string)respData["error"] != "No Notices") - { - LogRespDataToConsoleError(respData); - } - } - else - { - foreach (Hashtable value in respData.Values) - { - GroupNoticeData data = new GroupNoticeData(); - data.NoticeID = UUID.Parse((string)value["NoticeID"]); - data.Timestamp = uint.Parse((string)value["Timestamp"]); - data.FromName = (string)value["FromName"]; - data.Subject = (string)value["Subject"]; - data.HasAttachment = false; - data.AssetType = 0; - - values.Add(data); - } - } - return values; - - } - public GroupNoticeInfo GetGroupNotice(UUID noticeID) - { - Hashtable param = new Hashtable(); - param["NoticeID"] = noticeID.ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotice", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - - - if (respData.Contains("error")) - { - if ((string)respData["error"] != "Group Notice Not Found") - { - LogRespDataToConsoleError(respData); - return null; - } - } - - GroupNoticeInfo data = new GroupNoticeInfo(); - data.GroupID = UUID.Parse((string)respData["GroupID"]); - data.Message = (string)respData["Message"]; - data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); - data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); - data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); - data.noticeData.FromName = (string)respData["FromName"]; - data.noticeData.Subject = (string)respData["Subject"]; - data.noticeData.HasAttachment = false; - data.noticeData.AssetType = 0; - - if (data.Message == null) - { - data.Message = string.Empty; - } - - return data; - } - public void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) - { - string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); - - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["NoticeID"] = noticeID.ToString(); - param["FromName"] = fromName; - param["Subject"] = subject; - param["Message"] = message; - param["BinaryBucket"] = binBucket; - param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addGroupNotice", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - List values = new List(); - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - } - - - } - - public class GroupNoticeInfo - { - public GroupNoticeData noticeData = new GroupNoticeData(); - public UUID GroupID = UUID.Zero; - public string Message = string.Empty; - public byte[] BinaryBucket = new byte[0]; - } -} +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +//using System.Text; + +using Nwc.XmlRpc; + +using log4net; +// using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +//using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + + public class XmlRpcGroupDataProvider : IGroupDataProvider + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serviceURL = "http://osflotsam.org/xmlrpc.php"; + + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | GroupPowers.AllowVoiceChat | GroupPowers.ReceiveNotices | GroupPowers.StartProposal | GroupPowers.VoteOnProposal; + + public XmlRpcGroupDataProvider(string serviceURL) + { + m_serviceURL = serviceURL; + } + + /// + /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. + /// + public UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) + { + UUID GroupID = UUID.Random(); + UUID OwnerRoleID = UUID.Random(); + + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + param["Name"] = name; + param["Charter"] = charter; + param["ShowInList"] = showInList == true ? 1 : 0; + param["InsigniaID"] = insigniaID.ToString(); + param["MembershipFee"] = 0; + param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; + param["AllowPublish"] = allowPublish == true ? 1 : 0; + param["MaturePublish"] = maturePublish == true ? 1 : 0; + param["FounderID"] = founderID.ToString(); + param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); + param["OwnerRoleID"] = OwnerRoleID.ToString(); + + // Would this be cleaner as (GroupPowers)ulong.MaxValue; + GroupPowers OwnerPowers = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); + + + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.createGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + + return UUID.Parse((string)respData["GroupID"]); + } + + public void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["Charter"] = charter; + param["ShowInList"] = showInList == true ? 1 : 0; + param["InsigniaID"] = insigniaID.ToString(); + param["MembershipFee"] = membershipFee; + param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; + param["AllowPublish"] = allowPublish == true ? 1 : 0; + param["MaturePublish"] = maturePublish == true ? 1 : 0; + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.updateGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + param["Name"] = name; + param["Description"] = description; + param["Title"] = title; + param["Powers"] = powers.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addRoleToGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void RemoveGroupRole(UUID groupID, UUID roleID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeRoleFromGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + if (name != null) + { + param["Name"] = name; + } + if (description != null) + { + param["Description"] = description; + } + if (title != null) + { + param["Title"] = title; + } + param["Powers"] = powers.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.updateGroupRole", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) + { + Hashtable param = new Hashtable(); + if ((GroupID != null) && (GroupID != UUID.Zero)) + { + param["GroupID"] = GroupID.ToString(); + } + if ((GroupName != null) && (GroupName != string.Empty)) + { + param["Name"] = GroupName.ToString(); + } + + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "Group Not Found") + { + LogRespDataToConsoleError(respData); + } + return null; + } + + return GroupProfileHashtableToGroupRecord(respData); + + } + + public GroupProfileData GetMemberGroupProfile(UUID GroupID, UUID AgentID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "Group Not Found") + { + LogRespDataToConsoleError(respData); + } + return new GroupProfileData(); + } + + GroupMembershipData MemberInfo = GetAgentGroupMembership(AgentID, GroupID); + GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); + + MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; + MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; + + return MemberGroupProfile; + + } + + private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) + { + GroupProfileData group = new GroupProfileData(); + group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); + group.Name = (string)groupProfile["Name"]; + + if (groupProfile["Charter"] != null) + { + group.Charter = (string)groupProfile["Charter"]; + } + + group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; + group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); + group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); + group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; + group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; + group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; + group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); + group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); + + group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); + group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); + + return group; + } + + private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) + { + + GroupRecord group = new GroupRecord(); + m_log.Debug("GroupID"); + group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); + + m_log.Debug("Name"); + group.GroupName = groupProfile["Name"].ToString(); + + m_log.Debug("Charter"); + if (groupProfile["Charter"] != null) + { + group.Charter = (string)groupProfile["Charter"]; + } + + m_log.Debug("ShowInList"); + group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; + + m_log.Debug("InsigniaID"); + group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); + + m_log.Debug("MembershipFee"); + group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); + + m_log.Debug("OpenEnrollment"); + group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; + + m_log.Debug("AllowPublish"); + group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; + + m_log.Debug("MaturePublish"); + group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; + + m_log.Debug("FounderID"); + group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); + + m_log.Debug("OwnerRoleID"); + group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); + + return group; + } + + + public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.setAgentActiveGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + + } + + public void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["SelectedRoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + + } + + public void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["AcceptNotices"] = AcceptNotices ? "1" : "0"; + param["ListInProfile"] = ListInProfile ? "1" : "0"; + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + param["AgentID"] = agentID.ToString(); + param["RoleID"] = roleID.ToString(); + param["GroupID"] = groupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupInvite", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if (respData["error"] != "Duplicate group invite requested") + { + LogRespDataToConsoleError(respData); + } + } + + + } + + public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentToGroupInvite", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + + return null; + } + + GroupInviteInfo inviteInfo = new GroupInviteInfo(); + inviteInfo.InviteID = inviteID; + inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); + inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); + inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); + + return inviteInfo; + } + + public void RemoveAgentToGroupInvite(UUID inviteID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentToGroupInvite", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void RemoveAgentFromGroup(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroup", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupRole", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + public void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroupRole", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + + public List FindGroups(string search) + { + Hashtable param = new Hashtable(); + param["Search"] = search; + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.findGroups", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List findings = new List(); + + if (respData.Contains("error")) + { + if (respData["error"].ToString() != "No groups found.") + { + LogRespDataToConsoleError(respData); + } + } + else + { + Hashtable results = (Hashtable)respData["results"]; + foreach (Hashtable groupFind in results.Values) + { + DirGroupsReplyData data = new DirGroupsReplyData(); + data.groupID = new UUID((string)groupFind["GroupID"]); ; + data.groupName = (string)groupFind["Name"]; + data.members = int.Parse((string)groupFind["Members"]); + // data.searchOrder = order; + + findings.Add(data); + } + } + + return findings; + } + + public GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMembership", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "None Found") + { + LogRespDataToConsoleError(respData); + } + return null; + } + + GroupMembershipData data = HashTableToGroupMembershipData(respData); + + return data; + } + + public GroupMembershipData GetAgentActiveMembership(UUID AgentID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentActiveMembership", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + if (respData["error"].ToString() == "No Active Group Specified") + { + return null; + } + LogRespDataToConsoleError(respData); + return null; + } + + try + { + GroupMembershipData data = HashTableToGroupMembershipData(respData); + return data; + } + catch (System.Exception e) + { + LogRespDataToConsoleError(respData); + throw e; + } + } + + private void LogRespDataToConsoleError(Hashtable respData) + { + m_log.Error("[GROUPDATA] Error:"); + + foreach (string key in respData.Keys) + { + m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); + + object o = respData[key]; + + string[] lines = respData[key].ToString().Split(new char[] { '\n' }); + foreach (string line in lines) + { + m_log.ErrorFormat("[GROUPDATA] {0}", line); + } + + } + } + + public List GetAgentGroupMemberships(UUID AgentID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMemberships", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List memberships = new List(); + + if (respData.Contains("error")) + { + if (respData["error"].ToString() != "No Memberships") + { + LogRespDataToConsoleError(respData); + } + } + else + { + foreach (object membership in respData.Values) + { + memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); + } + } + return memberships; + } + + public List GetAgentGroupRoles(UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getAgentRoles", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List Roles = new List(); + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "None found") + { + LogRespDataToConsoleError(respData); + } + return Roles; + } + + foreach (Hashtable role in respData.Values) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = new UUID((string)role["RoleID"]); + data.Name = (string)role["Name"]; + data.Description = (string)role["Description"]; + data.Powers = ulong.Parse((string)role["Powers"]); + data.Title = (string)role["Title"]; + + Roles.Add(data); + } + + return Roles; + + + } + + public List GetGroupRoles(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoles", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + return null; + } + + List Roles = new List(); + foreach (Hashtable role in respData.Values) + { + GroupRolesData data = new GroupRolesData(); + data.Description = (string)role["Description"]; + data.Members = int.Parse((string)role["Members"]); + data.Name = (string)role["Name"]; + data.Powers = ulong.Parse((string)role["Powers"]); + data.RoleID = new UUID((string)role["RoleID"]); + data.Title = (string)role["Title"]; + + Roles.Add(data); + } + + return Roles; + + } + + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) + { + GroupMembershipData data = new GroupMembershipData(); + data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); + data.Contribution = int.Parse((string)respData["Contribution"]); + data.ListInProfile = ((string)respData["ListInProfile"] == "1"); + + data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); + data.GroupTitle = (string)respData["Title"]; + + data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); + + // Is this group the agent's active group + + data.GroupID = new UUID((string)respData["GroupID"]); + + UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); + data.Active = data.GroupID.Equals(ActiveGroup); + + data.AllowPublish = ((string)respData["AllowPublish"] == "1"); + data.Charter = (string)respData["Charter"]; + data.FounderID = new UUID((string)respData["FounderID"]); + data.GroupID = new UUID((string)respData["GroupID"]); + data.GroupName = (string)respData["GroupName"]; + data.GroupPicture = new UUID((string)respData["InsigniaID"]); + data.MaturePublish = ((string)respData["MaturePublish"] == "1"); + data.MembershipFee = int.Parse((string)respData["MembershipFee"]); + data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); + data.ShowInList = ((string)respData["ShowInList"] == "1"); + return data; + } + + public List GetGroupMembers(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupMembers", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + return null; + } + + List members = new List(); + foreach (Hashtable membership in respData.Values) + { + GroupMembersData data = new GroupMembersData(); + + data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; + data.AgentID = new UUID((string)membership["AgentID"]); + data.Contribution = int.Parse((string)membership["Contribution"]); + data.IsOwner = ((string)membership["IsOwner"]) == "1"; + data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; + data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); + data.Title = (string)membership["Title"]; + + members.Add(data); + } + + return members; + + } + + public List GetGroupRoleMembers(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoleMembers", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + return null; + } + + List members = new List(); + foreach (Hashtable membership in respData.Values) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = new UUID((string)membership["AgentID"]); + data.RoleID = new UUID((string)membership["RoleID"]); + + members.Add(data); + } + + return members; + } + + public List GetGroupNotices(UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotices", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List values = new List(); + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "No Notices") + { + LogRespDataToConsoleError(respData); + } + } + else + { + foreach (Hashtable value in respData.Values) + { + GroupNoticeData data = new GroupNoticeData(); + data.NoticeID = UUID.Parse((string)value["NoticeID"]); + data.Timestamp = uint.Parse((string)value["Timestamp"]); + data.FromName = (string)value["FromName"]; + data.Subject = (string)value["Subject"]; + data.HasAttachment = false; + data.AssetType = 0; + + values.Add(data); + } + } + return values; + + } + public GroupNoticeInfo GetGroupNotice(UUID noticeID) + { + Hashtable param = new Hashtable(); + param["NoticeID"] = noticeID.ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotice", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + + + if (respData.Contains("error")) + { + if ((string)respData["error"] != "Group Notice Not Found") + { + LogRespDataToConsoleError(respData); + return null; + } + } + + GroupNoticeInfo data = new GroupNoticeInfo(); + data.GroupID = UUID.Parse((string)respData["GroupID"]); + data.Message = (string)respData["Message"]; + data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); + data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); + data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); + data.noticeData.FromName = (string)respData["FromName"]; + data.noticeData.Subject = (string)respData["Subject"]; + data.noticeData.HasAttachment = false; + data.noticeData.AssetType = 0; + + if (data.Message == null) + { + data.Message = string.Empty; + } + + return data; + } + public void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + { + string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); + + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["NoticeID"] = noticeID.ToString(); + param["FromName"] = fromName; + param["Subject"] = subject; + param["Message"] = message; + param["BinaryBucket"] = binBucket; + param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); + + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("groups.addGroupNotice", parameters); + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + Hashtable respData = (Hashtable)resp.Value; + + List values = new List(); + + if (respData.Contains("error")) + { + LogRespDataToConsoleError(respData); + } + } + + + } + + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 5990fa6..10561a6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -1,430 +1,430 @@ -/* - * 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 OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -//using System.Collections; -using System.Collections.Generic; -using System.Reflection; - - -using log4net; -using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - - -using Caps = OpenSim.Framework.Communications.Capabilities.Caps; - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - public class XmlRpcGroupsMessaging : INonSharedRegionModule - { - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private List m_SceneList = new List(); - - // must be NonShared for this to work, otherewise we may actually get multiple active clients - private Dictionary m_ActiveClients = new Dictionary(); - - private IMessageTransferModule m_MsgTransferModule = null; - - private IGroupsModule m_GroupsModule = null; - - // Config Options - private bool m_GroupMessagingEnabled = true; - private bool m_debugEnabled = true; - - #region IRegionModule Members - - public void Initialise(IConfigSource config) - { - IConfig groupsConfig = config.Configs["Groups"]; - - m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); - - if (groupsConfig == null) - { - // Do not run this module by default. - m_log.Info("[GROUPS-MESSAGING]: No config found in OpenSim.ini -- not enabling XmlRpcGroupsMessaging"); - return; - } - else - { - if (!groupsConfig.GetBoolean("Enabled", false)) - { - m_log.Info("[GROUPS-MESSAGING]: Groups disabled in configuration"); - return; - } - - if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") - { - m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); - m_GroupMessagingEnabled = false; - - return; - } - - m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); - - if (!m_GroupMessagingEnabled) - { - m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); - return; - } - - m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); - - } - - m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up"); - - } - - public void AddRegion(Scene scene) - { - } - public void RegionLoaded(Scene scene) - { - if (!m_GroupMessagingEnabled) - return; - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - - m_GroupsModule = scene.RequestModuleInterface(); - - // No groups module, no groups messaging - if (m_GroupsModule == null) - { - m_GroupMessagingEnabled = false; - m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); - Close(); - return; - } - - m_MsgTransferModule = scene.RequestModuleInterface(); - - // No message transfer module, no groups messaging - if (m_MsgTransferModule == null) - { - m_GroupMessagingEnabled = false; - m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); - Close(); - return; - } - - - m_SceneList.Add(scene); - - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnClientClosed += OnClientClosed; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - - } - - public void RemoveRegion(Scene scene) - { - if (!m_GroupMessagingEnabled) - return; - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_SceneList.Remove(scene); - } - - - public void Close() - { - if (!m_GroupMessagingEnabled) - return; - - m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); - - - foreach (Scene scene in m_SceneList) - { - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnClientClosed -= OnClientClosed; - scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; - } - - m_SceneList.Clear(); - - m_GroupsModule = null; - m_MsgTransferModule = null; - } - - public string Name - { - get { return "XmlRpcGroupsMessaging"; } - } - - #endregion - - #region SimGridEventHandlers - - private void OnNewClient(IClientAPI client) - { - RegisterClientAgent(client); - } - private void OnClientClosed(UUID AgentId) - { - UnregisterClientAgent(AgentId); - } - - private void OnGridInstantMessage(GridInstantMessage msg) - { - m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - DebugGridInstantMessage(msg); - - // Incoming message from a group - if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true)) - { - if (m_ActiveClients.ContainsKey(msg.toAgentID)) - { - UUID GroupID = new UUID(msg.fromAgentID); - // SendMessageToGroup(im); - - GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); - if (GroupInfo != null) - { - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); - - // Force? open the group session dialog??? - IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( - GroupID - , GroupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp - , msg.offline==1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , Utils.StringToBytes(GroupInfo.GroupName) - ); - - eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - - } - } - } - - } - - #endregion - - #region ClientEvents - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - DebugGridInstantMessage(im); - - // Start group IM session - if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) - { - UUID GroupID = new UUID(im.toAgentID); - - GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); - if (GroupInfo != null) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName); - - // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0])); - - ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID); - - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - queue.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(im.fromAgentID) - , new UUID(im.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - } - } - - // Send a message to a group - if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) - { - UUID GroupID = new UUID(im.toAgentID); - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID); - - SendMessageToGroup(im, GroupID); - } - - // Incoming message from a group - if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true)) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID); - } - } - #endregion - - private void RegisterClientAgent(IClientAPI client) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - lock (m_ActiveClients) - { - if (!m_ActiveClients.ContainsKey(client.AgentId.Guid)) - { - client.OnInstantMessage += OnInstantMessage; - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); - - m_ActiveClients.Add(client.AgentId.Guid, client); - } - else - { - // Remove old client connection for this agent - UnregisterClientAgent(client.AgentId); - - // Add new client connection - RegisterClientAgent(client); - } - } - } - private void UnregisterClientAgent(UUID agentID) - { - lock (m_ActiveClients) - { - if (m_ActiveClients.ContainsKey(agentID.Guid)) - { - IClientAPI client = m_ActiveClients[agentID.Guid]; - client.OnInstantMessage -= OnInstantMessage; - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name); - - m_ActiveClients.Remove(agentID.Guid); - } - else - { - m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here."); - } - } - } - - private void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; - msg.fromAgentID = im.imSessionID; // GroupID - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = new byte[1] { 0 }; - - foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID)) - { - msg.toAgentID = member.AgentID.Guid; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - } - - void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap moderatedMap = new OSDMap(4); - moderatedMap.Add("voice", OSD.FromBoolean(false)); - - OSDMap sessionMap = new OSDMap(4); - sessionMap.Add("moderated_mode", moderatedMap); - sessionMap.Add("session_name", OSD.FromString(groupName)); - sessionMap.Add("type", OSD.FromInteger(0)); - sessionMap.Add("voice_enabled", OSD.FromBoolean(false)); - - - OSDMap bodyMap = new OSDMap(4); - bodyMap.Add("session_id", OSD.FromUUID(groupID)); - bodyMap.Add("temp_session_id", OSD.FromUUID(groupID)); - bodyMap.Add("success", OSD.FromBoolean(true)); - bodyMap.Add("session_info", sessionMap); - - - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - - if (queue != null) - { - queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); - } - - } - - - private void DebugGridInstantMessage(GridInstantMessage im) - { - if (m_debugEnabled) - { - m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromGroup({0})", im.fromGroup ? "True" : "False"); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentID({0})", im.fromAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentName({0})", im.fromAgentName.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: imSessionID({0})", im.imSessionID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: message({0})", im.message.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: offline({0})", im.offline.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: toAgentID({0})", im.toAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); - } - } - - } -} +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +//using System.Collections; +using System.Collections.Generic; +using System.Reflection; + + +using log4net; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Framework.EventQueue; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + + +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + public class XmlRpcGroupsMessaging : INonSharedRegionModule + { + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_SceneList = new List(); + + // must be NonShared for this to work, otherewise we may actually get multiple active clients + private Dictionary m_ActiveClients = new Dictionary(); + + private IMessageTransferModule m_MsgTransferModule = null; + + private IGroupsModule m_GroupsModule = null; + + // Config Options + private bool m_GroupMessagingEnabled = true; + private bool m_debugEnabled = true; + + #region IRegionModule Members + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); + + if (groupsConfig == null) + { + // Do not run this module by default. + m_log.Info("[GROUPS-MESSAGING]: No config found in OpenSim.ini -- not enabling XmlRpcGroupsMessaging"); + return; + } + else + { + if (!groupsConfig.GetBoolean("Enabled", false)) + { + m_log.Info("[GROUPS-MESSAGING]: Groups disabled in configuration"); + return; + } + + if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + { + m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); + m_GroupMessagingEnabled = false; + + return; + } + + m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); + + if (!m_GroupMessagingEnabled) + { + m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); + return; + } + + m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + + } + + m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up"); + + } + + public void AddRegion(Scene scene) + { + } + public void RegionLoaded(Scene scene) + { + if (!m_GroupMessagingEnabled) + return; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + m_GroupsModule = scene.RequestModuleInterface(); + + // No groups module, no groups messaging + if (m_GroupsModule == null) + { + m_GroupMessagingEnabled = false; + m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); + Close(); + return; + } + + m_MsgTransferModule = scene.RequestModuleInterface(); + + // No message transfer module, no groups messaging + if (m_MsgTransferModule == null) + { + m_GroupMessagingEnabled = false; + m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); + Close(); + return; + } + + + m_SceneList.Add(scene); + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += OnClientClosed; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + + } + + public void RemoveRegion(Scene scene) + { + if (!m_GroupMessagingEnabled) + return; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_SceneList.Remove(scene); + } + + + public void Close() + { + if (!m_GroupMessagingEnabled) + return; + + m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); + + + foreach (Scene scene in m_SceneList) + { + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnClientClosed -= OnClientClosed; + scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + } + + m_SceneList.Clear(); + + m_GroupsModule = null; + m_MsgTransferModule = null; + } + + public string Name + { + get { return "XmlRpcGroupsMessaging"; } + } + + #endregion + + #region SimGridEventHandlers + + private void OnNewClient(IClientAPI client) + { + RegisterClientAgent(client); + } + private void OnClientClosed(UUID AgentId) + { + UnregisterClientAgent(AgentId); + } + + private void OnGridInstantMessage(GridInstantMessage msg) + { + m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + DebugGridInstantMessage(msg); + + // Incoming message from a group + if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true)) + { + if (m_ActiveClients.ContainsKey(msg.toAgentID)) + { + UUID GroupID = new UUID(msg.fromAgentID); + // SendMessageToGroup(im); + + GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); + if (GroupInfo != null) + { + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); + + // Force? open the group session dialog??? + IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface(); + eq.ChatterboxInvitation( + GroupID + , GroupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message, new UUID(msg.toAgentID) + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline==1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(GroupInfo.GroupName) + ); + + eq.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) + , new UUID(msg.fromAgentID) + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + + } + } + } + + } + + #endregion + + #region ClientEvents + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + DebugGridInstantMessage(im); + + // Start group IM session + if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) + { + UUID GroupID = new UUID(im.toAgentID); + + GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); + if (GroupInfo != null) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName); + + // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0])); + + ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID); + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + queue.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) + , new UUID(im.fromAgentID) + , new UUID(im.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + } + } + + // Send a message to a group + if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) + { + UUID GroupID = new UUID(im.toAgentID); + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID); + + SendMessageToGroup(im, GroupID); + } + + // Incoming message from a group + if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true)) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID); + } + } + #endregion + + private void RegisterClientAgent(IClientAPI client) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + lock (m_ActiveClients) + { + if (!m_ActiveClients.ContainsKey(client.AgentId.Guid)) + { + client.OnInstantMessage += OnInstantMessage; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); + + m_ActiveClients.Add(client.AgentId.Guid, client); + } + else + { + // Remove old client connection for this agent + UnregisterClientAgent(client.AgentId); + + // Add new client connection + RegisterClientAgent(client); + } + } + } + private void UnregisterClientAgent(UUID agentID) + { + lock (m_ActiveClients) + { + if (m_ActiveClients.ContainsKey(agentID.Guid)) + { + IClientAPI client = m_ActiveClients[agentID.Guid]; + client.OnInstantMessage -= OnInstantMessage; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name); + + m_ActiveClients.Remove(agentID.Guid); + } + else + { + m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here."); + } + } + } + + private void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = im.imSessionID; + msg.fromAgentID = im.imSessionID; // GroupID + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = new byte[1] { 0 }; + + foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID)) + { + msg.toAgentID = member.AgentID.Guid; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + } + + void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap moderatedMap = new OSDMap(4); + moderatedMap.Add("voice", OSD.FromBoolean(false)); + + OSDMap sessionMap = new OSDMap(4); + sessionMap.Add("moderated_mode", moderatedMap); + sessionMap.Add("session_name", OSD.FromString(groupName)); + sessionMap.Add("type", OSD.FromInteger(0)); + sessionMap.Add("voice_enabled", OSD.FromBoolean(false)); + + + OSDMap bodyMap = new OSDMap(4); + bodyMap.Add("session_id", OSD.FromUUID(groupID)); + bodyMap.Add("temp_session_id", OSD.FromUUID(groupID)); + bodyMap.Add("success", OSD.FromBoolean(true)); + bodyMap.Add("session_info", sessionMap); + + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + + if (queue != null) + { + queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); + } + + } + + + private void DebugGridInstantMessage(GridInstantMessage im) + { + if (m_debugEnabled) + { + m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromGroup({0})", im.fromGroup ? "True" : "False"); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentID({0})", im.fromAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentName({0})", im.fromAgentName.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: imSessionID({0})", im.imSessionID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: message({0})", im.message.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: offline({0})", im.offline.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: toAgentID({0})", im.toAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); + } + } + + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 6a3aa06..a6f9ea1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -1,1051 +1,1051 @@ -/* - * 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 OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; - -using System.Collections; -//using Nwc.XmlRpc; - -using log4net; -using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -using Caps = OpenSim.Framework.Communications.Capabilities.Caps; -using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; - - - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - public class XmlRpcGroupsModule : INonSharedRegionModule, IGroupsModule - { - /// - /// To use this module, you must specify the following in your OpenSim.ini - /// [GROUPS] - /// Enabled = true - /// Module = XmlRpcGroups - /// XmlRpcMessagingEnabled = true - /// XmlRpcNoticesEnabled = true - /// XmlRpcDebugEnabled = true - /// - /// - - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private List m_SceneList = new List(); - - // This only works when running as non-Shared, in shared, there may be multiple IClientAPIs for a single client - private Dictionary m_ActiveClients = new Dictionary(); - - private IMessageTransferModule m_MsgTransferModule = null; - - private IGroupDataProvider m_groupData = null; - - // Configuration settings - private const string m_defaultXmlRpcServiceURL = "http://osflotsam.org/xmlrpc.php"; - private bool m_GroupsEnabled = false; - private bool m_GroupNoticesEnabled = true; - private bool m_debugEnabled = true; - - #region IRegionModule Members - - public void Initialise(IConfigSource config) - { - IConfig groupsConfig = config.Configs["Groups"]; - - m_log.Info("[GROUPS]: Initializing XmlRpcGroups"); - - if (groupsConfig == null) - { - // Do not run this module by default. - m_log.Info("[GROUPS]: No config found in OpenSim.ini -- not enabling XmlRpcGroups"); - return; - } - else - { - m_GroupsEnabled = groupsConfig.GetBoolean("Enabled", false); - if (!m_GroupsEnabled) - { - m_log.Info("[GROUPS]: Groups disabled in configuration"); - return; - } - - if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") - { - m_log.Info("[GROUPS]: Config Groups Module not set to XmlRpcGroups"); - m_GroupsEnabled = false; - - return; - } - - string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); - m_groupData = new XmlRpcGroupDataProvider(ServiceURL); - m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL); - - m_GroupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); - m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); - - } - } - - public void AddRegion(Scene scene) - { - if (m_GroupsEnabled) - scene.RegisterModuleInterface(this); - } - - public void RegionLoaded(Scene scene) - { - if (!m_GroupsEnabled) - return; - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_MsgTransferModule = scene.RequestModuleInterface(); - - // No message transfer module, no notices, group invites, rejects, ejects, etc - if (m_MsgTransferModule == null) - { - m_GroupsEnabled = false; - m_log.Info("[GROUPS]: Could not get MessageTransferModule"); - Close(); - return; - } - - - m_SceneList.Add(scene); - - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnClientClosed += OnClientClosed; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - - } - - public void RemoveRegion(Scene scene) - { - if (!m_GroupsEnabled) - return; - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_SceneList.Remove(scene); - } - - public void Close() - { - if (!m_GroupsEnabled) - return; - m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); - } - - public string Name - { - get { return "XmlRpcGroupsModule"; } - } - - #endregion - - private void UpdateAllClientsWithGroupInfo() - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - foreach (IClientAPI client in m_ActiveClients.Values) - { - UpdateClientWithGroupInfo(client); - } - } - - private void UpdateClientWithGroupInfo(IClientAPI client) - { - m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); - OnAgentDataUpdateRequest(client, client.AgentId, UUID.Zero); - - - // Need to send a group membership update to the client - // UDP version doesn't seem to behave nicely - // client.SendGroupMembership(GetMembershipData(client.AgentId)); - - GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(client.AgentId).ToArray(); - - SendGroupMembershipInfoViaCaps(client, membershipData); - client.SendAvatarGroupsReply(client.AgentId, membershipData); - - } - - #region EventHandlers - private void OnNewClient(IClientAPI client) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - - lock (m_ActiveClients) - { - if (!m_ActiveClients.ContainsKey(client.AgentId)) - { - client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; - client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; - client.OnDirFindQuery += OnDirFindQuery; - client.OnInstantMessage += OnInstantMessage; - - m_ActiveClients.Add(client.AgentId, client); - } - } - - UpdateClientWithGroupInfo(client); - } - private void OnClientClosed(UUID AgentId) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - lock (m_ActiveClients) - { - if (m_ActiveClients.ContainsKey(AgentId)) - { - IClientAPI client = m_ActiveClients[AgentId]; - client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; - client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; - client.OnDirFindQuery -= OnDirFindQuery; - client.OnInstantMessage -= OnInstantMessage; - - m_ActiveClients.Remove(AgentId); - } - else - { - m_log.InfoFormat("[GROUPS] Client closed that wasn't registered here."); - } - - - } - - } - - - void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) - { - if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) - { - m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); - - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); - } - - } - - private void OnAgentDataUpdateRequest(IClientAPI remoteClient, - UUID AgentID, UUID SessionID) - { - m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, SessionID); - - - UUID ActiveGroupID = UUID.Zero; - string ActiveGroupTitle = string.Empty; - string ActiveGroupName = string.Empty; - ulong ActiveGroupPowers = (ulong)GroupPowers.None; - - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(AgentID); - if (membership != null) - { - ActiveGroupID = membership.GroupID; - ActiveGroupTitle = membership.GroupTitle; - ActiveGroupPowers = membership.GroupPowers; - } - - string firstname, lastname; - IClientAPI agent; - if( m_ActiveClients.TryGetValue(AgentID, out agent) ) - { - firstname = agent.FirstName; - lastname = agent.LastName; - } else { - firstname = "Unknown"; - lastname = "Unknown"; - } - - UpdateScenePresenceWithTitle(AgentID, ActiveGroupTitle); - - remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, - lastname, ActiveGroupPowers, ActiveGroupName, - ActiveGroupTitle); - } - - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - string GroupName; - - GroupRecord group = m_groupData.GetGroupRecord(GroupID, null); - if (group != null) - { - GroupName = group.GroupName; - } - else - { - GroupName = "Unknown"; - } - - - remote_client.SendGroupNameReply(GroupID, GroupName); - } - - - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - - // Group invitations - if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) - { - m_log.WarnFormat("[GROUPS] Received an IIM for {0}.", ((InstantMessageDialog)im.dialog).ToString()); - - - UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); - - m_log.WarnFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); - - UUID fromAgentID = new UUID(im.fromAgentID); - if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) - { - - // Accept - if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) - { - m_log.WarnFormat("[GROUPS] Received an accept invite notice."); - - // and the sessionid is the role - m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); - - if (m_MsgTransferModule != null) - { - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = UUID.Zero.Guid; - msg.toAgentID = inviteInfo.AgentID.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Groups"; - msg.message = string.Format("You have been added to the group."); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = new byte[0]; - - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - - UpdateAllClientsWithGroupInfo(); - - m_groupData.RemoveAgentToGroupInvite(inviteID); - } - - // Reject - if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) - { - m_log.WarnFormat("[GROUPS] Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(inviteID); - - } - - - } - } - - // Group notices - if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) - { - if (!m_GroupNoticesEnabled) - { - return; - } - - UUID GroupID = new UUID(im.toAgentID); - if( m_groupData.GetGroupRecord(GroupID, null) != null) - { - UUID NoticeID = UUID.Random(); - string Subject = im.message.Substring(0, im.message.IndexOf('|')); - string Message = im.message.Substring(Subject.Length + 1); - - byte[] bucket; - - if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) - { - bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno - } - else - { - string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); - binBucket = binBucket.Remove(0, 14).Trim(); - m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); - - OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); - - foreach (string key in binBucketOSD.Keys) - { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); - } - - // treat as if no attachment - bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno - } - - - m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); - if (OnNewGroupNotice != null) - { - OnNewGroupNotice(GroupID, NoticeID); - } - - // Build notice IIM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); - - // Send notice out to everyone that wants notices - foreach( GroupMembersData member in m_groupData.GetGroupMembers(GroupID) ) - { - if( member.AcceptNotices ) - { - msg.toAgentID = member.AgentID.Guid; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - - } - } - - - - } - } - - // Interop, received special 210 code for ejecting a group member - // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the - // client actually is, and try contacting that region directly to notify them, - // or provide the notification via xmlrpc update queue - if ((im.dialog == 210)) - { - // This is sent from the region that the ejectee was ejected from - // if it's being delivered here, then the ejectee is here - // so we need to send local updates to the agent. - - - if (m_MsgTransferModule != null) - { - im.dialog = (byte)InstantMessageDialog.MessageFromAgent; - m_MsgTransferModule.SendInstantMessage(im, delegate(bool success) { }); - } - - UUID ejecteeID = new UUID(im.toAgentID); - UUID groupID = new UUID(im.toAgentID); - if (m_ActiveClients.ContainsKey(ejecteeID)) - { - m_ActiveClients[ejecteeID].SendAgentDropGroup(groupID); - } - - } - - - - } - - private void OnGridInstantMessage(GridInstantMessage msg) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Trigger the above event handler - OnInstantMessage(null, msg); - } - - - #endregion - - - private void UpdateScenePresenceWithTitle(UUID AgentID, string Title) - { - m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title); - ScenePresence presence = null; - lock (m_SceneList) - { - foreach (Scene scene in m_SceneList) - { - presence = scene.GetScenePresence(AgentID); - if (presence != null) - { - presence.Grouptitle = Title; - - // FixMe: Ter suggests a "Schedule" method that I can't find. - presence.SendFullUpdateToAllClients(); - } - } - } - } - - - #region IGroupsModule Members - - public event NewGroupNotice OnNewGroupNotice; - - public GroupRecord GetGroupRecord(UUID GroupID) - { - return m_groupData.GetGroupRecord(GroupID, null); - } - - public void ActivateGroup(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); - - // UpdateClientWithGroupInfo(remoteClient); - UpdateAllClientsWithGroupInfo(); - } - - /// - /// Get the Role Titles for an Agent, for a specific group - /// - public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); - - List titles = new List(); - foreach (GroupRolesData role in agentRoles) - { - GroupTitlesData title = new GroupTitlesData(); - title.Name = role.Name; - if (agentMembership != null) - { - title.Selected = agentMembership.ActiveRole == role.RoleID; - } - title.UUID = role.RoleID; - - titles.Add(title); - } - - return titles; - } - - public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupMembers(groupID); - - foreach (GroupMembersData member in data) - { - m_log.InfoFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); - } - - return data; - - } - - public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupRoles(groupID); - - foreach (GroupRolesData member in data) - { - m_log.InfoFormat("[GROUPS] {0} {1}", member.Title, member.Members); - } - - return data; - - } - - public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupRoleMembers(groupID); - - foreach (GroupRoleMembersData member in data) - { - m_log.InfoFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); - } - - return data; - - - } - - public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupProfileData profile = new GroupProfileData(); - - GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); - if (groupInfo != null) - { - profile.AllowPublish = groupInfo.AllowPublish; - profile.Charter = groupInfo.Charter; - profile.FounderID = groupInfo.FounderID; - profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(groupID).Count; - profile.InsigniaID = groupInfo.GroupPicture; - profile.MaturePublish = groupInfo.MaturePublish; - profile.MembershipFee = groupInfo.MembershipFee; - profile.Money = 0; // TODO: Get this from the currency server? - profile.Name = groupInfo.GroupName; - profile.OpenEnrollment = groupInfo.OpenEnrollment; - profile.OwnerRole = groupInfo.OwnerRoleID; - profile.ShowInList = groupInfo.ShowInList; - } - - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); - if (memberInfo != null) - { - profile.MemberTitle = memberInfo.GroupTitle; - profile.PowersMask = memberInfo.GroupPowers; - } - - return profile; - } - - public GroupMembershipData[] GetMembershipData(UUID UserID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - return m_groupData.GetAgentGroupMemberships(UserID).ToArray(); - } - - public GroupMembershipData GetMembershipData(UUID GroupID, UUID UserID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - return m_groupData.GetAgentGroupMembership(UserID, GroupID); - } - - public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Security Check? - - m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); - } - - public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) - { - // TODO: Security Check? - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); - } - - public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - if( m_groupData.GetGroupRecord(UUID.Zero, name) != null ) - { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); - return UUID.Zero; - } - - UUID GroupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); - - remoteClient.SendCreateGroupReply(GroupID, true, "Group created successfullly"); - - UpdateClientWithGroupInfo(remoteClient); - - return GroupID; - } - - public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID GroupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // ToDo: check if agent is a member of group and is allowed to see notices? - - return m_groupData.GetGroupNotices(GroupID).ToArray(); - } - - /// - /// Get the title of the agent's current role. - /// - public string GetGroupTitle(UUID avatarID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); - if (membership != null) - { - return membership.GroupTitle; - } - return string.Empty; - } - - /// - /// Change the current Active Group Role for Agent - /// - public void GroupTitleUpdate(IClientAPI remoteClient, UUID GroupID, UUID TitleRoleID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, GroupID, TitleRoleID); - - UpdateAllClientsWithGroupInfo(); - } - - - public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Security Checks? - - switch ((OpenMetaverse.GroupRoleUpdate)updateType) - { - case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(groupID, UUID.Random(), name, description, title, powers); - break; - - case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(groupID, roleID); - break; - - case OpenMetaverse.GroupRoleUpdate.UpdateAll: - case OpenMetaverse.GroupRoleUpdate.UpdateData: - case OpenMetaverse.GroupRoleUpdate.UpdatePowers: - m_groupData.UpdateGroupRole(groupID, roleID, name, description, title, powers); - break; - - case OpenMetaverse.GroupRoleUpdate.NoUpdate: - default: - // No Op - break; - - } - - UpdateClientWithGroupInfo(remoteClient); - } - - public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // Todo: Security check - - switch (changes) - { - case 0: - // Add - m_groupData.AddAgentToGroupRole(memberID, groupID, roleID); - - break; - case 1: - // Remove - m_groupData.RemoveAgentFromGroupRole(memberID, groupID, roleID); - - break; - default: - m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); - break; - } - UpdateClientWithGroupInfo(remoteClient); - } - - public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - - GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); - - if (data != null) - { - if (m_MsgTransferModule != null) - { - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Group Notice From"; - msg.message = data.noticeData.Subject + "|" + data.Message; - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = data.BinaryBucket; - - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - } - - } - - public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) - { - m_log.WarnFormat("[GROUPS] {0} is probably not properly implemented", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.toAgentID = agentID.Guid; - msg.dialog = dialog; - // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - - GroupNoticeInfo info = m_groupData.GetGroupNotice(groupNoticeID); - if (info != null) - { - msg.fromAgentID = info.GroupID.Guid; - msg.timestamp = info.noticeData.Timestamp; - msg.fromAgentName = info.noticeData.FromName; - msg.message = info.noticeData.Subject + "|" + info.Message; - msg.binaryBucket = info.BinaryBucket; - } - - return msg; - } - - public void SendAgentGroupDataUpdate(IClientAPI remoteClient) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - UpdateClientWithGroupInfo(remoteClient); - } - - public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); - - remoteClient.SendJoinGroupReply(groupID, true); - - UpdateClientWithGroupInfo(remoteClient); - } - - public void LeaveGroupRequest(IClientAPI remoteClient, UUID GroupID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, GroupID); - - remoteClient.SendLeaveGroupReply(GroupID, true); - - remoteClient.SendAgentDropGroup(GroupID); - - UpdateClientWithGroupInfo(remoteClient); - } - - public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID GroupID, UUID EjecteeID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Todo: Security check? - m_groupData.RemoveAgentFromGroup(EjecteeID, GroupID); - - remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, GroupID, true); - - if (m_MsgTransferModule != null) - { - GroupRecord groupInfo = m_groupData.GetGroupRecord(GroupID, null); - UserProfileData userProfile = m_SceneList[0].CommsManager.UserService.GetUserProfile(EjecteeID); - - if ((groupInfo == null) || (userProfile == null)) - { - return; - } - - - // Send Message to Ejectee - GridInstantMessage msg = new GridInstantMessage(); - - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - // msg.fromAgentID = info.GroupID; - msg.toAgentID = EjecteeID.Guid; - //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[0]; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); - - - // Message to ejector - // Interop, received special 210 code for ejecting a group member - // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the - // client actually is, and try contacting that region directly to notify them, - // or provide the notification via xmlrpc update queue - - msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - if (userProfile != null) - { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); - } - else - { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); - } - msg.dialog = (byte)210; //interop - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[0]; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success, ToString()); }); - - - - } - - - UpdateAllClientsWithGroupInfo(); - } - - public void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InvitedAgentID, UUID RoleID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", GroupID, InvitedAgentID, RoleID); - - // Todo: Security check, probably also want to send some kind of notification - UUID InviteID = UUID.Random(); - m_log.WarnFormat("[GROUPS] Invite ID: {0}", InviteID); - m_groupData.AddAgentToGroupInvite(InviteID, GroupID, RoleID, InvitedAgentID); - - if (m_MsgTransferModule != null) - { - Guid inviteUUID = InviteID.Guid; - - GridInstantMessage msg = new GridInstantMessage(); - - msg.imSessionID = inviteUUID; - - // msg.fromAgentID = remoteClient.AgentId.Guid; - msg.fromAgentID = GroupID.Guid; - msg.toAgentID = InvitedAgentID.Guid; - //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[20]; - - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); - } - } - - #endregion - - void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, GroupMembershipData[] data) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDArray AgentData = new OSDArray(1); - OSDMap AgentDataMap = new OSDMap(1); - AgentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId)); - AgentData.Add(AgentDataMap); - - - OSDArray GroupData = new OSDArray(data.Length); - OSDArray NewGroupData = new OSDArray(data.Length); - - foreach (GroupMembershipData membership in data) - { - OSDMap GroupDataMap = new OSDMap(6); - OSDMap NewGroupDataMap = new OSDMap(1); - - GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); - GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); - GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); - GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); - GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); - GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); - NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); - - GroupData.Add(GroupDataMap); - NewGroupData.Add(NewGroupDataMap); - } - - OSDMap llDataStruct = new OSDMap(3); - llDataStruct.Add("AgentData", AgentData); - llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); - - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - - if (queue != null) - { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); - } - - } - } - -} +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; + +using System.Collections; +//using Nwc.XmlRpc; + +using log4net; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Framework.EventQueue; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; +using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; + + + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + public class XmlRpcGroupsModule : INonSharedRegionModule, IGroupsModule + { + /// + /// To use this module, you must specify the following in your OpenSim.ini + /// [GROUPS] + /// Enabled = true + /// Module = XmlRpcGroups + /// XmlRpcMessagingEnabled = true + /// XmlRpcNoticesEnabled = true + /// XmlRpcDebugEnabled = true + /// + /// + + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_SceneList = new List(); + + // This only works when running as non-Shared, in shared, there may be multiple IClientAPIs for a single client + private Dictionary m_ActiveClients = new Dictionary(); + + private IMessageTransferModule m_MsgTransferModule = null; + + private IGroupDataProvider m_groupData = null; + + // Configuration settings + private const string m_defaultXmlRpcServiceURL = "http://osflotsam.org/xmlrpc.php"; + private bool m_GroupsEnabled = false; + private bool m_GroupNoticesEnabled = true; + private bool m_debugEnabled = true; + + #region IRegionModule Members + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + m_log.Info("[GROUPS]: Initializing XmlRpcGroups"); + + if (groupsConfig == null) + { + // Do not run this module by default. + m_log.Info("[GROUPS]: No config found in OpenSim.ini -- not enabling XmlRpcGroups"); + return; + } + else + { + m_GroupsEnabled = groupsConfig.GetBoolean("Enabled", false); + if (!m_GroupsEnabled) + { + m_log.Info("[GROUPS]: Groups disabled in configuration"); + return; + } + + if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + { + m_log.Info("[GROUPS]: Config Groups Module not set to XmlRpcGroups"); + m_GroupsEnabled = false; + + return; + } + + string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); + m_groupData = new XmlRpcGroupDataProvider(ServiceURL); + m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL); + + m_GroupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); + m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + + } + } + + public void AddRegion(Scene scene) + { + if (m_GroupsEnabled) + scene.RegisterModuleInterface(this); + } + + public void RegionLoaded(Scene scene) + { + if (!m_GroupsEnabled) + return; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_MsgTransferModule = scene.RequestModuleInterface(); + + // No message transfer module, no notices, group invites, rejects, ejects, etc + if (m_MsgTransferModule == null) + { + m_GroupsEnabled = false; + m_log.Info("[GROUPS]: Could not get MessageTransferModule"); + Close(); + return; + } + + + m_SceneList.Add(scene); + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += OnClientClosed; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + + } + + public void RemoveRegion(Scene scene) + { + if (!m_GroupsEnabled) + return; + + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_SceneList.Remove(scene); + } + + public void Close() + { + if (!m_GroupsEnabled) + return; + m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); + } + + public string Name + { + get { return "XmlRpcGroupsModule"; } + } + + #endregion + + private void UpdateAllClientsWithGroupInfo() + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + foreach (IClientAPI client in m_ActiveClients.Values) + { + UpdateClientWithGroupInfo(client); + } + } + + private void UpdateClientWithGroupInfo(IClientAPI client) + { + m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); + OnAgentDataUpdateRequest(client, client.AgentId, UUID.Zero); + + + // Need to send a group membership update to the client + // UDP version doesn't seem to behave nicely + // client.SendGroupMembership(GetMembershipData(client.AgentId)); + + GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(client.AgentId).ToArray(); + + SendGroupMembershipInfoViaCaps(client, membershipData); + client.SendAvatarGroupsReply(client.AgentId, membershipData); + + } + + #region EventHandlers + private void OnNewClient(IClientAPI client) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + lock (m_ActiveClients) + { + if (!m_ActiveClients.ContainsKey(client.AgentId)) + { + client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; + client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; + client.OnDirFindQuery += OnDirFindQuery; + client.OnInstantMessage += OnInstantMessage; + + m_ActiveClients.Add(client.AgentId, client); + } + } + + UpdateClientWithGroupInfo(client); + } + private void OnClientClosed(UUID AgentId) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + lock (m_ActiveClients) + { + if (m_ActiveClients.ContainsKey(AgentId)) + { + IClientAPI client = m_ActiveClients[AgentId]; + client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; + client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; + client.OnDirFindQuery -= OnDirFindQuery; + client.OnInstantMessage -= OnInstantMessage; + + m_ActiveClients.Remove(AgentId); + } + else + { + m_log.InfoFormat("[GROUPS] Client closed that wasn't registered here."); + } + + + } + + } + + + void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) + { + if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) + { + m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); + } + + } + + private void OnAgentDataUpdateRequest(IClientAPI remoteClient, + UUID AgentID, UUID SessionID) + { + m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, SessionID); + + + UUID ActiveGroupID = UUID.Zero; + string ActiveGroupTitle = string.Empty; + string ActiveGroupName = string.Empty; + ulong ActiveGroupPowers = (ulong)GroupPowers.None; + + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(AgentID); + if (membership != null) + { + ActiveGroupID = membership.GroupID; + ActiveGroupTitle = membership.GroupTitle; + ActiveGroupPowers = membership.GroupPowers; + } + + string firstname, lastname; + IClientAPI agent; + if( m_ActiveClients.TryGetValue(AgentID, out agent) ) + { + firstname = agent.FirstName; + lastname = agent.LastName; + } else { + firstname = "Unknown"; + lastname = "Unknown"; + } + + UpdateScenePresenceWithTitle(AgentID, ActiveGroupTitle); + + remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, + lastname, ActiveGroupPowers, ActiveGroupName, + ActiveGroupTitle); + } + + private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + string GroupName; + + GroupRecord group = m_groupData.GetGroupRecord(GroupID, null); + if (group != null) + { + GroupName = group.GroupName; + } + else + { + GroupName = "Unknown"; + } + + + remote_client.SendGroupNameReply(GroupID, GroupName); + } + + + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + // Group invitations + if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) + { + m_log.WarnFormat("[GROUPS] Received an IIM for {0}.", ((InstantMessageDialog)im.dialog).ToString()); + + + UUID inviteID = new UUID(im.imSessionID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); + + m_log.WarnFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); + + UUID fromAgentID = new UUID(im.fromAgentID); + if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) + { + + // Accept + if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) + { + m_log.WarnFormat("[GROUPS] Received an accept invite notice."); + + // and the sessionid is the role + m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + + if (m_MsgTransferModule != null) + { + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = UUID.Zero.Guid; + msg.toAgentID = inviteInfo.AgentID.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Groups"; + msg.message = string.Format("You have been added to the group."); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = new byte[0]; + + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + + UpdateAllClientsWithGroupInfo(); + + m_groupData.RemoveAgentToGroupInvite(inviteID); + } + + // Reject + if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) + { + m_log.WarnFormat("[GROUPS] Received a reject invite notice."); + m_groupData.RemoveAgentToGroupInvite(inviteID); + + } + + + } + } + + // Group notices + if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) + { + if (!m_GroupNoticesEnabled) + { + return; + } + + UUID GroupID = new UUID(im.toAgentID); + if( m_groupData.GetGroupRecord(GroupID, null) != null) + { + UUID NoticeID = UUID.Random(); + string Subject = im.message.Substring(0, im.message.IndexOf('|')); + string Message = im.message.Substring(Subject.Length + 1); + + byte[] bucket; + + if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) + { + bucket = new byte[19]; + bucket[0] = 0; //dunno + bucket[1] = 0; //dunno + GroupID.ToBytes(bucket, 2); + bucket[18] = 0; //dunno + } + else + { + string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); + binBucket = binBucket.Remove(0, 14).Trim(); + m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); + + OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + + foreach (string key in binBucketOSD.Keys) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } + + // treat as if no attachment + bucket = new byte[19]; + bucket[0] = 0; //dunno + bucket[1] = 0; //dunno + GroupID.ToBytes(bucket, 2); + bucket[18] = 0; //dunno + } + + + m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + if (OnNewGroupNotice != null) + { + OnNewGroupNotice(GroupID, NoticeID); + } + + // Build notice IIM + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + + // Send notice out to everyone that wants notices + foreach( GroupMembersData member in m_groupData.GetGroupMembers(GroupID) ) + { + if( member.AcceptNotices ) + { + msg.toAgentID = member.AgentID.Guid; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + + } + } + + + + } + } + + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presense server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue + if ((im.dialog == 210)) + { + // This is sent from the region that the ejectee was ejected from + // if it's being delivered here, then the ejectee is here + // so we need to send local updates to the agent. + + + if (m_MsgTransferModule != null) + { + im.dialog = (byte)InstantMessageDialog.MessageFromAgent; + m_MsgTransferModule.SendInstantMessage(im, delegate(bool success) { }); + } + + UUID ejecteeID = new UUID(im.toAgentID); + UUID groupID = new UUID(im.toAgentID); + if (m_ActiveClients.ContainsKey(ejecteeID)) + { + m_ActiveClients[ejecteeID].SendAgentDropGroup(groupID); + } + + } + + + + } + + private void OnGridInstantMessage(GridInstantMessage msg) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Trigger the above event handler + OnInstantMessage(null, msg); + } + + + #endregion + + + private void UpdateScenePresenceWithTitle(UUID AgentID, string Title) + { + m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title); + ScenePresence presence = null; + lock (m_SceneList) + { + foreach (Scene scene in m_SceneList) + { + presence = scene.GetScenePresence(AgentID); + if (presence != null) + { + presence.Grouptitle = Title; + + // FixMe: Ter suggests a "Schedule" method that I can't find. + presence.SendFullUpdateToAllClients(); + } + } + } + } + + + #region IGroupsModule Members + + public event NewGroupNotice OnNewGroupNotice; + + public GroupRecord GetGroupRecord(UUID GroupID) + { + return m_groupData.GetGroupRecord(GroupID, null); + } + + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); + + // UpdateClientWithGroupInfo(remoteClient); + UpdateAllClientsWithGroupInfo(); + } + + /// + /// Get the Role Titles for an Agent, for a specific group + /// + public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); + + List titles = new List(); + foreach (GroupRolesData role in agentRoles) + { + GroupTitlesData title = new GroupTitlesData(); + title.Name = role.Name; + if (agentMembership != null) + { + title.Selected = agentMembership.ActiveRole == role.RoleID; + } + title.UUID = role.RoleID; + + titles.Add(title); + } + + return titles; + } + + public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupMembers(groupID); + + foreach (GroupMembersData member in data) + { + m_log.InfoFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); + } + + return data; + + } + + public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupRoles(groupID); + + foreach (GroupRolesData member in data) + { + m_log.InfoFormat("[GROUPS] {0} {1}", member.Title, member.Members); + } + + return data; + + } + + public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupRoleMembers(groupID); + + foreach (GroupRoleMembersData member in data) + { + m_log.InfoFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); + } + + return data; + + + } + + public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupProfileData profile = new GroupProfileData(); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); + if (groupInfo != null) + { + profile.AllowPublish = groupInfo.AllowPublish; + profile.Charter = groupInfo.Charter; + profile.FounderID = groupInfo.FounderID; + profile.GroupID = groupID; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(groupID).Count; + profile.InsigniaID = groupInfo.GroupPicture; + profile.MaturePublish = groupInfo.MaturePublish; + profile.MembershipFee = groupInfo.MembershipFee; + profile.Money = 0; // TODO: Get this from the currency server? + profile.Name = groupInfo.GroupName; + profile.OpenEnrollment = groupInfo.OpenEnrollment; + profile.OwnerRole = groupInfo.OwnerRoleID; + profile.ShowInList = groupInfo.ShowInList; + } + + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); + if (memberInfo != null) + { + profile.MemberTitle = memberInfo.GroupTitle; + profile.PowersMask = memberInfo.GroupPowers; + } + + return profile; + } + + public GroupMembershipData[] GetMembershipData(UUID UserID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + return m_groupData.GetAgentGroupMemberships(UserID).ToArray(); + } + + public GroupMembershipData GetMembershipData(UUID GroupID, UUID UserID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + return m_groupData.GetAgentGroupMembership(UserID, GroupID); + } + + public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security Check? + + m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + } + + public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) + { + // TODO: Security Check? + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); + } + + public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + if( m_groupData.GetGroupRecord(UUID.Zero, name) != null ) + { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); + return UUID.Zero; + } + + UUID GroupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + + remoteClient.SendCreateGroupReply(GroupID, true, "Group created successfullly"); + + UpdateClientWithGroupInfo(remoteClient); + + return GroupID; + } + + public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // ToDo: check if agent is a member of group and is allowed to see notices? + + return m_groupData.GetGroupNotices(GroupID).ToArray(); + } + + /// + /// Get the title of the agent's current role. + /// + public string GetGroupTitle(UUID avatarID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); + if (membership != null) + { + return membership.GroupTitle; + } + return string.Empty; + } + + /// + /// Change the current Active Group Role for Agent + /// + public void GroupTitleUpdate(IClientAPI remoteClient, UUID GroupID, UUID TitleRoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, GroupID, TitleRoleID); + + UpdateAllClientsWithGroupInfo(); + } + + + public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security Checks? + + switch ((OpenMetaverse.GroupRoleUpdate)updateType) + { + case OpenMetaverse.GroupRoleUpdate.Create: + m_groupData.AddGroupRole(groupID, UUID.Random(), name, description, title, powers); + break; + + case OpenMetaverse.GroupRoleUpdate.Delete: + m_groupData.RemoveGroupRole(groupID, roleID); + break; + + case OpenMetaverse.GroupRoleUpdate.UpdateAll: + case OpenMetaverse.GroupRoleUpdate.UpdateData: + case OpenMetaverse.GroupRoleUpdate.UpdatePowers: + m_groupData.UpdateGroupRole(groupID, roleID, name, description, title, powers); + break; + + case OpenMetaverse.GroupRoleUpdate.NoUpdate: + default: + // No Op + break; + + } + + UpdateClientWithGroupInfo(remoteClient); + } + + public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // Todo: Security check + + switch (changes) + { + case 0: + // Add + m_groupData.AddAgentToGroupRole(memberID, groupID, roleID); + + break; + case 1: + // Remove + m_groupData.RemoveAgentFromGroupRole(memberID, groupID, roleID); + + break; + default: + m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); + break; + } + UpdateClientWithGroupInfo(remoteClient); + } + + public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); + + if (data != null) + { + if (m_MsgTransferModule != null) + { + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = data.GroupID.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Group Notice From"; + msg.message = data.noticeData.Subject + "|" + data.Message; + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = data.BinaryBucket; + + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + } + + } + + public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) + { + m_log.WarnFormat("[GROUPS] {0} is probably not properly implemented", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.toAgentID = agentID.Guid; + msg.dialog = dialog; + // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + + GroupNoticeInfo info = m_groupData.GetGroupNotice(groupNoticeID); + if (info != null) + { + msg.fromAgentID = info.GroupID.Guid; + msg.timestamp = info.noticeData.Timestamp; + msg.fromAgentName = info.noticeData.FromName; + msg.message = info.noticeData.Subject + "|" + info.Message; + msg.binaryBucket = info.BinaryBucket; + } + + return msg; + } + + public void SendAgentGroupDataUpdate(IClientAPI remoteClient) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UpdateClientWithGroupInfo(remoteClient); + } + + public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Should check to see if OpenEnrollment, or if there's an outstanding invitation + m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); + + remoteClient.SendJoinGroupReply(groupID, true); + + UpdateClientWithGroupInfo(remoteClient); + } + + public void LeaveGroupRequest(IClientAPI remoteClient, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, GroupID); + + remoteClient.SendLeaveGroupReply(GroupID, true); + + remoteClient.SendAgentDropGroup(GroupID); + + UpdateClientWithGroupInfo(remoteClient); + } + + public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID GroupID, UUID EjecteeID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Todo: Security check? + m_groupData.RemoveAgentFromGroup(EjecteeID, GroupID); + + remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, GroupID, true); + + if (m_MsgTransferModule != null) + { + GroupRecord groupInfo = m_groupData.GetGroupRecord(GroupID, null); + UserProfileData userProfile = m_SceneList[0].CommsManager.UserService.GetUserProfile(EjecteeID); + + if ((groupInfo == null) || (userProfile == null)) + { + return; + } + + + // Send Message to Ejectee + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = info.GroupID; + msg.toAgentID = EjecteeID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); + + + // Message to ejector + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presense server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue + + msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + if (userProfile != null) + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); + } + else + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); + } + msg.dialog = (byte)210; //interop + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success, ToString()); }); + + + + } + + + UpdateAllClientsWithGroupInfo(); + } + + public void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InvitedAgentID, UUID RoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", GroupID, InvitedAgentID, RoleID); + + // Todo: Security check, probably also want to send some kind of notification + UUID InviteID = UUID.Random(); + m_log.WarnFormat("[GROUPS] Invite ID: {0}", InviteID); + m_groupData.AddAgentToGroupInvite(InviteID, GroupID, RoleID, InvitedAgentID); + + if (m_MsgTransferModule != null) + { + Guid inviteUUID = InviteID.Guid; + + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = inviteUUID; + + // msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GroupID.Guid; + msg.toAgentID = InvitedAgentID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[20]; + + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); + } + } + + #endregion + + void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, GroupMembershipData[] data) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDArray AgentData = new OSDArray(1); + OSDMap AgentDataMap = new OSDMap(1); + AgentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId)); + AgentData.Add(AgentDataMap); + + + OSDArray GroupData = new OSDArray(data.Length); + OSDArray NewGroupData = new OSDArray(data.Length); + + foreach (GroupMembershipData membership in data) + { + OSDMap GroupDataMap = new OSDMap(6); + OSDMap NewGroupDataMap = new OSDMap(1); + + GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); + GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); + GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); + GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); + GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); + GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); + NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); + + GroupData.Add(GroupDataMap); + NewGroupData.Add(NewGroupDataMap); + } + + OSDMap llDataStruct = new OSDMap(3); + llDataStruct.Add("AgentData", AgentData); + llDataStruct.Add("GroupData", GroupData); + llDataStruct.Add("NewGroupData", NewGroupData); + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + + if (queue != null) + { + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); + } + + } + } + +} -- cgit v1.1 From 4a8313f14c0aeffc87d37bd1f6c633a61c0a0fca Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Tue, 21 Apr 2009 16:06:16 +0000 Subject: culling AsteriskVoiceModule and SIPVoiceModule, now that we have working FreeSwitchVoiceModule and soon will have a fully working VivoxVoiceModule. --- .../Voice/AsterixVoice/AsteriskVoiceModule.cs | 292 --------------------- .../Avatar/Voice/SIPVoice/SIPVoiceModule.cs | 234 ----------------- 2 files changed, 526 deletions(-) delete mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs delete mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs deleted file mode 100644 index c827214..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs +++ /dev/null @@ -1,292 +0,0 @@ -/* - * 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 OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Reflection; -using OpenMetaverse; -using log4net; -using Nini.Config; -using Nwc.XmlRpc; -using OpenSim.Framework; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Communications.Capabilities; -using OpenSim.Framework.Servers; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using Caps=OpenSim.Framework.Communications.Capabilities.Caps; - -namespace OpenSim.Region.OptionalModules.Avatar.Voice.AsterixVoice -{ - public class AsteriskVoiceModule : IRegionModule - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; - private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; - - private string m_asterisk; - private string m_asterisk_password; - private string m_asterisk_salt; - private int m_asterisk_timeout; - private string m_confDomain; - private IConfig m_config; - private Scene m_scene; - private string m_sipDomain; - - #region IRegionModule Members - - public void Initialise(Scene scene, IConfigSource config) - { - m_scene = scene; - m_config = config.Configs["AsteriskVoice"]; - - if (null == m_config) - { - m_log.Info("[ASTERISKVOICE] no config found, plugin disabled"); - return; - } - - if (!m_config.GetBoolean("enabled", false)) - { - m_log.Info("[ASTERISKVOICE] plugin disabled by configuration"); - return; - } - m_log.Info("[ASTERISKVOICE] plugin enabled"); - - try - { - m_sipDomain = m_config.GetString("sip_domain", String.Empty); - m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain); - - m_confDomain = m_config.GetString("conf_domain", String.Empty); - m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain); - - m_asterisk = m_config.GetString("asterisk_frontend", String.Empty); - m_asterisk_password = m_config.GetString("asterisk_password", String.Empty); - m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000); - m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff"); - if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter"); - if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter"); - m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk); - - scene.EventManager.OnRegisterCaps += OnRegisterCaps; - } - catch (Exception e) - { - m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message); - m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString()); - return; - } - } - - public void PostInitialise() - { - } - - public void Close() - { - } - - public string Name - { - get { return "AsteriskVoiceModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - - #endregion - - public void OnRegisterCaps(UUID agentID, Caps caps) - { - m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); - string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("ParcelVoiceInfoRequest", - new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, - delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return ParcelVoiceInfoRequest(request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ProvisionVoiceAccountRequest", - new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, - delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return ProvisionVoiceAccountRequest(request, path, param, - agentID, caps); - })); - } - - /// - /// Callback for a client request for ParcelVoiceInfo - /// - /// - /// - /// - /// - /// - /// - public string ParcelVoiceInfoRequest(string request, string path, string param, - UUID agentID, Caps caps) - { - // we need to do: - // - send channel_uri: as "sip:regionID@m_sipDomain" - try - { - m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", - request, path, param); - - - // setup response to client - Hashtable creds = new Hashtable(); - creds["channel_uri"] = String.Format("sip:{0}@{1}", - m_scene.RegionInfo.RegionID, m_sipDomain); - - string regionName = m_scene.RegionInfo.RegionName; - ScenePresence avatar = m_scene.GetScenePresence(agentID); - if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); - LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - - LLSDParcelVoiceInfoResponse parcelVoiceInfo = - new LLSDParcelVoiceInfoResponse(regionName, land.LocalID, creds); - - string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); - - - // update region on asterisk-opensim frontend - Hashtable requestData = new Hashtable(); - requestData["admin_password"] = m_asterisk_password; - requestData["region"] = m_scene.RegionInfo.RegionID.ToString(); - if (!String.IsNullOrEmpty(m_confDomain)) - { - requestData["region"] += String.Format("@{0}", m_confDomain); - } - - ArrayList SendParams = new ArrayList(); - SendParams.Add(requestData); - XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams); - XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); - Hashtable responseData = (Hashtable) updateAccountResponse.Value; - - if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed"); - - bool success = Convert.ToBoolean((string) responseData["success"]); - if (!success) throw new Exception("region_update failed"); - - - m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r); - return r; - } - catch (Exception e) - { - m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message); - m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString()); - - return "undef"; - } - } - - /// - /// Callback for a client request for Voice Account Details - /// - /// - /// - /// - /// - /// - /// - public string ProvisionVoiceAccountRequest(string request, string path, string param, - UUID agentID, Caps caps) - { - // we need to - // - get user data from UserProfileCacheService - // - generate nonce for user voice account password - // - issue XmlRpc request to asterisk opensim front end: - // + user: base 64 encoded user name (otherwise SL - // client is unhappy) - // + password: nonce - // - the XmlRpc call to asteris-opensim was successful: - // send account details back to client - try - { - m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", - request, path, param); - - // get user data & prepare voice account response - string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); - voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); - - CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); - if (null == userInfo) throw new Exception("cannot get user details"); - - // we generate a nonce everytime - string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt); - LLSDVoiceAccountResponse voiceAccountResponse = - new LLSDVoiceAccountResponse(voiceUser, voicePassword); - string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); - m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); - - - // update user account on asterisk frontend - Hashtable requestData = new Hashtable(); - requestData["admin_password"] = m_asterisk_password; - requestData["username"] = voiceUser; - if (!String.IsNullOrEmpty(m_sipDomain)) - { - requestData["username"] += String.Format("@{0}", m_sipDomain); - } - requestData["password"] = voicePassword; - - ArrayList SendParams = new ArrayList(); - SendParams.Add(requestData); - XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams); - XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); - Hashtable responseData = (Hashtable) updateAccountResponse.Value; - - if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed"); - - bool success = Convert.ToBoolean((string) responseData["success"]); - if (!success) throw new Exception("account_update failed"); - - return r; - } - catch (Exception e) - { - m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); - m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString()); - - return "undef"; - } - } - } -} diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs deleted file mode 100644 index d00a256..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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 OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Reflection; -using OpenMetaverse; -using log4net; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Communications.Capabilities; -using OpenSim.Framework.Servers; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using Caps=OpenSim.Framework.Communications.Capabilities.Caps; - -namespace OpenSim.Region.OptionalModules.Avatar.Voice.SIPVoice -{ - public class SIPVoiceModule : IRegionModule - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; - private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; - private static readonly string m_chatSessionRequestPath = "0009/"; - private IConfig m_config; - private Scene m_scene; - private string m_sipDomain; - - #region IRegionModule Members - - public void Initialise(Scene scene, IConfigSource config) - { - m_scene = scene; - m_config = config.Configs["Voice"]; - - if (null == m_config || !m_config.GetBoolean("enabled", false)) - { - m_log.Info("[VOICE] plugin disabled"); - return; - } - m_log.Info("[VOICE] plugin enabled"); - - m_sipDomain = m_config.GetString("sip_domain", String.Empty); - if (String.IsNullOrEmpty(m_sipDomain)) - { - m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration"); - m_log.Info("[VOICE] plugin disabled"); - return; - } - m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain); - - scene.EventManager.OnRegisterCaps += OnRegisterCaps; - } - - public void PostInitialise() - { - } - - public void Close() - { - } - - public string Name - { - get { return "VoiceModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - - #endregion - - public void OnRegisterCaps(UUID agentID, Caps caps) - { - m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); - string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("ParcelVoiceInfoRequest", - new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, - delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return ParcelVoiceInfoRequest(request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ProvisionVoiceAccountRequest", - new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, - delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return ProvisionVoiceAccountRequest(request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ChatSessionRequest", - new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, - delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return ChatSessionRequest(request, path, param, - agentID, caps); - })); - - } - - /// - /// Callback for a client request for ParcelVoiceInfo - /// - /// - /// - /// - /// - /// - /// - public string ParcelVoiceInfoRequest(string request, string path, string param, - UUID agentID, Caps caps) - { - try - { - m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); - - // FIXME: get the creds from region file or from config - Hashtable creds = new Hashtable(); - - creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain); - - string regionName = m_scene.RegionInfo.RegionName; - ScenePresence avatar = m_scene.GetScenePresence(agentID); - if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); - LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - - LLSDParcelVoiceInfoResponse parcelVoiceInfo = - new LLSDParcelVoiceInfoResponse(regionName, land.LocalID, creds); - - string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); - m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r); - - return r; - } - catch (Exception e) - { - m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString()); - } - - return null; - } - - /// - /// Callback for a client request for Voice Account Details - /// - /// - /// - /// - /// - /// - /// - public string ProvisionVoiceAccountRequest(string request, string path, string param, - UUID agentID, Caps caps) - { - try - { - m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", - request, path, param); - - string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); - voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); - - CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); - if (null == userInfo) throw new Exception("cannot get user details"); - - LLSDVoiceAccountResponse voiceAccountResponse = - new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash); - string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); - m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); - return r; - } - catch (Exception e) - { - m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); - } - - return null; - } - - /// - /// Callback for a client request for ParcelVoiceInfo - /// - /// current scene object of the client - /// - /// - /// - /// - /// - /// - public string ChatSessionRequest(string request, string path, string param, - UUID agentID, Caps caps) - { - ScenePresence avatar = m_scene.GetScenePresence(agentID); - string avatarName = avatar.Name; - - m_log.DebugFormat("[CAPS][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", - avatarName, request, path, param); - return "true"; - } - - } -} -- cgit v1.1 From 5ea4faa6f209fd5c6a48cc704c595fb029b790f2 Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Tue, 21 Apr 2009 20:44:17 +0000 Subject: Thank you kindly, MCortez, for a patch that: * Refactors the xmlrpc calls to a single location to make it easier to debug and include alternative xmlrpc call mechanisms * Includes an alternative xmlrpc call mechanism that sets HTTP Keep-Alive to false which solves nearly all System.Net exceptions on some windows environments --- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 513 ++++++++------------- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 3 + .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 31 +- 3 files changed, 217 insertions(+), 330 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index eff76cf..3a728da 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -50,13 +50,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private string m_serviceURL = "http://osflotsam.org/xmlrpc.php"; + private string m_serviceURL = string.Empty; public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | GroupPowers.AllowVoiceChat | GroupPowers.ReceiveNotices | GroupPowers.StartProposal | GroupPowers.VoteOnProposal; - public XmlRpcGroupDataProvider(string serviceURL) + private bool m_disableKeepAlive = false; + + public XmlRpcGroupDataProvider(string serviceURL, bool disableKeepAlive) { - m_serviceURL = serviceURL; + m_serviceURL = serviceURL.Trim().ToLower(); + m_disableKeepAlive = disableKeepAlive; + + if ((serviceURL == null) + || (serviceURL == string.Empty) + ) + { + throw new Exception("Please specify a valid ServiceURL for XmlRpcGroupDataProvider in OpenSim.ini, [Groups], XmlRpcServiceURL"); + } + } /// @@ -131,15 +142,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.createGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; + + Hashtable respData = XmlRpcCall("groups.createGroup", param); if (respData.Contains("error")) { - LogRespDataToConsoleError(respData); + // UUID is not nullable + + return UUID.Zero; } return UUID.Parse((string)respData["GroupID"]); @@ -157,16 +167,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.updateGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } + XmlRpcCall("groups.updateGroup", param); } public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) @@ -179,16 +180,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Title"] = title; param["Powers"] = powers.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addRoleToGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } + XmlRpcCall("groups.addRoleToGroup", param); } public void RemoveGroupRole(UUID groupID, UUID roleID) @@ -197,16 +189,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = groupID.ToString(); param["RoleID"] = roleID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeRoleFromGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; + XmlRpcCall("groups.removeRoleFromGroup", param); - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } } public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) @@ -228,16 +212,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } param["Powers"] = powers.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.updateGroupRole", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } + XmlRpcCall("groups.updateGroupRole", param); } public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) @@ -253,18 +228,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) { - if ((string)respData["error"] != "Group Not Found") - { - LogRespDataToConsoleError(respData); - } return null; } @@ -278,18 +245,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) { - if ((string)respData["error"] != "Group Not Found") - { - LogRespDataToConsoleError(respData); - } + // GroupProfileData is not nullable return new GroupProfileData(); } @@ -333,40 +293,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { GroupRecord group = new GroupRecord(); - m_log.Debug("GroupID"); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); - - m_log.Debug("Name"); group.GroupName = groupProfile["Name"].ToString(); - - m_log.Debug("Charter"); if (groupProfile["Charter"] != null) { group.Charter = (string)groupProfile["Charter"]; } - - m_log.Debug("ShowInList"); group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; - - m_log.Debug("InsigniaID"); group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); - - m_log.Debug("MembershipFee"); group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); - - m_log.Debug("OpenEnrollment"); group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; - - m_log.Debug("AllowPublish"); group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; - - m_log.Debug("MaturePublish"); group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; - - m_log.Debug("FounderID"); group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); - - m_log.Debug("OwnerRoleID"); group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); return group; @@ -379,17 +318,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.setAgentActiveGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - + XmlRpcCall("groups.setAgentActiveGroup", param); } public void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) @@ -399,17 +328,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); param["SelectedRoleID"] = RoleID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } - + XmlRpcCall("groups.setAgentGroupInfo", param); } public void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) @@ -420,16 +339,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AcceptNotices"] = AcceptNotices ? "1" : "0"; param["ListInProfile"] = ListInProfile ? "1" : "0"; - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; + XmlRpcCall("groups.setAgentGroupInfo", param); - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } } public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) @@ -440,20 +351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); param["GroupID"] = groupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupInvite", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - if (respData["error"] != "Duplicate group invite requested") - { - LogRespDataToConsoleError(respData); - } - } - + XmlRpcCall("groups.addAgentToGroupInvite", param); } @@ -462,17 +360,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentToGroupInvite", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - + Hashtable respData = XmlRpcCall("groups.getAgentToGroupInvite", param); if (respData.Contains("error")) { - LogRespDataToConsoleError(respData); - return null; } @@ -490,16 +381,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentToGroupInvite", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } + XmlRpcCall("groups.removeAgentToGroupInvite", param); } public void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID) @@ -509,16 +391,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } + XmlRpcCall("groups.addAgentToGroup", param); } public void RemoveAgentFromGroup(UUID AgentID, UUID GroupID) @@ -527,16 +400,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroup", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; + XmlRpcCall("groups.removeAgentFromGroup", param); - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } } public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) @@ -546,16 +411,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupRole", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } + XmlRpcCall("groups.addAgentToGroupRole", param); } public void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) @@ -565,16 +421,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroupRole", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 3000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - } + XmlRpcCall("groups.removeAgentFromGroupRole", param); } @@ -583,22 +430,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["Search"] = search; - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.findGroups", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.findGroups", param); List findings = new List(); - if (respData.Contains("error")) - { - if (respData["error"].ToString() != "No groups found.") - { - LogRespDataToConsoleError(respData); - } - } - else + if (!respData.Contains("error")) { Hashtable results = (Hashtable)respData["results"]; foreach (Hashtable groupFind in results.Values) @@ -622,18 +458,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMembership", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getAgentGroupMembership", param); if (respData.Contains("error")) { - if ((string)respData["error"] != "None Found") - { - LogRespDataToConsoleError(respData); - } return null; } @@ -647,74 +475,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentActiveMembership", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getAgentActiveMembership", param); if (respData.Contains("error")) { - if (respData["error"].ToString() == "No Active Group Specified") - { return null; } - LogRespDataToConsoleError(respData); - return null; - } - try - { - GroupMembershipData data = HashTableToGroupMembershipData(respData); - return data; - } - catch (System.Exception e) - { - LogRespDataToConsoleError(respData); - throw e; - } - } - - private void LogRespDataToConsoleError(Hashtable respData) - { - m_log.Error("[GROUPDATA] Error:"); - - foreach (string key in respData.Keys) - { - m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); - - object o = respData[key]; - - string[] lines = respData[key].ToString().Split(new char[] { '\n' }); - foreach (string line in lines) - { - m_log.ErrorFormat("[GROUPDATA] {0}", line); + return HashTableToGroupMembershipData(respData); } - } - } public List GetAgentGroupMemberships(UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMemberships", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getAgentGroupMemberships", param); List memberships = new List(); - if (respData.Contains("error")) - { - if (respData["error"].ToString() != "No Memberships") - { - LogRespDataToConsoleError(respData); - } - } - else + if (!respData.Contains("error")) { foreach (object membership in respData.Values) { @@ -730,20 +511,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getAgentRoles", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getAgentRoles", param); List Roles = new List(); if (respData.Contains("error")) { - if ((string)respData["error"] != "None found") - { - LogRespDataToConsoleError(respData); - } return Roles; } @@ -769,19 +542,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoles", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getGroupRoles", param); + + List Roles = new List(); if (respData.Contains("error")) { - LogRespDataToConsoleError(respData); - return null; + return Roles; } - List Roles = new List(); foreach (Hashtable role in respData.Values) { GroupRolesData data = new GroupRolesData(); @@ -819,7 +588,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.Active = data.GroupID.Equals(ActiveGroup); data.AllowPublish = ((string)respData["AllowPublish"] == "1"); + if (respData["Charter"] != null) + { data.Charter = (string)respData["Charter"]; + } data.FounderID = new UUID((string)respData["FounderID"]); data.GroupID = new UUID((string)respData["GroupID"]); data.GroupName = (string)respData["GroupName"]; @@ -836,19 +608,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupMembers", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getGroupMembers", param); + + List members = new List(); if (respData.Contains("error")) { - LogRespDataToConsoleError(respData); - return null; + return members; } - List members = new List(); foreach (Hashtable membership in respData.Values) { GroupMembersData data = new GroupMembersData(); @@ -873,19 +641,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoleMembers", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - - if (respData.Contains("error")) - { - LogRespDataToConsoleError(respData); - return null; - } + Hashtable respData = XmlRpcCall("groups.getGroupRoleMembers", param); List members = new List(); + + if (!respData.Contains("error")) + { foreach (Hashtable membership in respData.Values) { GroupRoleMembersData data = new GroupRoleMembersData(); @@ -895,7 +656,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups members.Add(data); } - + } return members; } @@ -904,22 +665,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotices", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; + Hashtable respData = XmlRpcCall("groups.getGroupNotices", param); List values = new List(); - if (respData.Contains("error")) - { - if ((string)respData["error"] != "No Notices") - { - LogRespDataToConsoleError(respData); - } - } - else + if (!respData.Contains("error")) { foreach (Hashtable value in respData.Values) { @@ -942,22 +692,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); - IList parameters = new ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotice", parameters); - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - + Hashtable respData = XmlRpcCall("groups.getGroupNotice", param); - if (respData.Contains("error")) + if (!respData.Contains("error")) { - if ((string)respData["error"] != "Group Notice Not Found") - { - LogRespDataToConsoleError(respData); return null; } - } GroupNoticeInfo data = new GroupNoticeInfo(); data.GroupID = UUID.Parse((string)respData["GroupID"]); @@ -990,20 +731,78 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["BinaryBucket"] = binBucket; param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); + XmlRpcCall("groups.addGroupNotice", param); + } + + private Hashtable XmlRpcCall(string function, Hashtable param) + { IList parameters = new ArrayList(); parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest("groups.addGroupNotice", parameters); + + XmlRpcRequest req; + if (!m_disableKeepAlive) + { + req = new XmlRpcRequest(function, parameters); + } + else + { + // This seems to solve a major problem on some windows servers + req = new NoKeepAliveXmlRpcRequest(function, parameters); + } + XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - Hashtable respData = (Hashtable)resp.Value; - List values = new List(); + if( resp.Value is Hashtable ) + { + Hashtable respData = (Hashtable)resp.Value; + if (respData.Contains("error") && !respData.Contains("succeed")) + { + LogRespDataToConsoleError(respData); + } - if (respData.Contains("error")) + return respData; + } + + m_log.ErrorFormat("[XmlRpcGroupData] The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + + if (resp.Value is ArrayList) { - LogRespDataToConsoleError(respData); + ArrayList al = (ArrayList)resp.Value; + m_log.ErrorFormat("[XmlRpcGroupData] Contains {0} elements", al.Count); + + foreach (object o in al) + { + m_log.ErrorFormat("[XmlRpcGroupData] {0} :: {1}", o.GetType().ToString(), o.ToString()); + } } + else + { + m_log.ErrorFormat("[XmlRpcGroupData] Function returned: {0}", resp.Value.ToString()); + } + + Hashtable error = new Hashtable(); + error.Add("error", "invalid return value"); + return error; + } + + private void LogRespDataToConsoleError(Hashtable respData) + { + m_log.Error("[GROUPDATA] Error:"); + + foreach (string key in respData.Keys) + { + m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); + + object o = respData[key]; + + string[] lines = respData[key].ToString().Split(new char[] { '\n' }); + foreach (string line in lines) + { + m_log.ErrorFormat("[GROUPDATA] {0}", line); } + } + } } @@ -1015,3 +814,61 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public byte[] BinaryBucket = new byte[0]; } } + +namespace Nwc.XmlRpc +{ + using System; + using System.Collections; + using System.IO; + using System.Xml; + using System.Net; + using System.Text; + using System.Reflection; + + /// Class supporting the request side of an XML-RPC transaction. + public class NoKeepAliveXmlRpcRequest : XmlRpcRequest + { + private Encoding _encoding = new ASCIIEncoding(); + private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); + private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); + + /// Instantiate an XmlRpcRequest for a specified method and parameters. + /// String designating the object.method on the server the request + /// should be directed to. + /// ArrayList of XML-RPC type parameters to invoke the request with. + public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) + { + MethodName = methodName; + _params = parameters; + } + + /// Send the request to the server. + /// String The url of the XML-RPC server. + /// XmlRpcResponse The response generated. + public XmlRpcResponse Send(String url) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + if (request == null) + throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR, + XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url); + request.Method = "POST"; + request.ContentType = "text/xml"; + request.AllowWriteStreamBuffering = true; + request.KeepAlive = false; + + Stream stream = request.GetRequestStream(); + XmlTextWriter xml = new XmlTextWriter(stream, _encoding); + _serializer.Serialize(xml, this); + xml.Flush(); + xml.Close(); + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + StreamReader input = new StreamReader(response.GetResponseStream()); + + XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); + input.Close(); + response.Close(); + return resp; + } + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 10561a6..34af325 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -212,6 +212,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Incoming message from a group if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true)) { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnGridInstantMessage from group session {0} going to agent {1}", msg.fromAgentID, msg.toAgentID); + if (m_ActiveClients.ContainsKey(msg.toAgentID)) { UUID GroupID = new UUID(msg.fromAgentID); @@ -220,6 +222,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); if (GroupInfo != null) { + // TODO: Check to see if already a member of session, if so, do not send chatterbox, just forward message if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index a6f9ea1..ec26dff 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -53,14 +53,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public class XmlRpcGroupsModule : INonSharedRegionModule, IGroupsModule { /// - /// To use this module, you must specify the following in your OpenSim.ini + /// ; To use this module, you must specify the following in your OpenSim.ini /// [GROUPS] /// Enabled = true /// Module = XmlRpcGroups + /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php /// XmlRpcMessagingEnabled = true /// XmlRpcNoticesEnabled = true /// XmlRpcDebugEnabled = true /// + /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for + /// ; a problem discovered on some Windows based region servers. Only disable + /// ; if you see a large number (dozens) of the following Exceptions: + /// ; System.Net.WebException: The request was aborted: The request was canceled. + /// + /// XmlRpcDisableKeepAlive = false /// private static readonly ILog m_log = @@ -113,7 +120,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); - m_groupData = new XmlRpcGroupDataProvider(ServiceURL); + bool DisableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); + + m_groupData = new XmlRpcGroupDataProvider(ServiceURL, DisableKeepAlive); m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL); m_GroupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); @@ -496,6 +505,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Trigger the above event handler OnInstantMessage(null, msg); + + + // If a message from a group arrives here, it may need to be forwarded to a local client + if (msg.fromGroup == true) + { + switch( msg.dialog ) + { + case (byte)InstantMessageDialog.GroupInvitation: + case (byte)InstantMessageDialog.GroupNotice: + UUID toAgentID = new UUID(msg.toAgentID); + if (m_ActiveClients.ContainsKey(toAgentID)) + { + m_ActiveClients[toAgentID].SendInstantMessage(msg); + } + break; + } + } + } -- cgit v1.1 From 6aa5d3904d71c4be21e5991d9ba82dff3c1cf51f Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Wed, 22 Apr 2009 00:48:56 +0000 Subject: Add copyright headers. Formatting cleanup. --- .../OptionalModules/Avatar/Chat/IRCConnector.cs | 3 +- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 60 ++++++++-------- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 84 +++++++++++----------- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 2 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 10 +-- 5 files changed, 79 insertions(+), 80 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index ca85817..c621fd3 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -546,8 +546,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // through reconnect. if (m_enabled && (m_resetk == resetk)) - Reconnect(); - + Reconnect(); } private Regex RE = new Regex(@":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)", diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index 2a2b4a3..d8fce67 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -43,7 +43,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable response = new Hashtable(); - foreach(DictionaryEntry item in request) + foreach (DictionaryEntry item in request) { m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); } @@ -52,37 +52,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["keepalive"] = false; response["int_response_code"]=200; response["str_response_string"] = @" - -
- - - - - - - - - - - - - - - - - - - - - - - - -
-
"; + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
"; return response; } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 9959d11..4113976 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice //domain=9.20.151.43 //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup - foreach(DictionaryEntry item in request) + foreach (DictionaryEntry item in request) { m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); } @@ -71,41 +71,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string eventCallingFunction = (string) request["Event-Calling-Function"]; - if(eventCallingFunction=="sofia_reg_parse_auth") + if (eventCallingFunction=="sofia_reg_parse_auth") { string sipAuthMethod = (string)request["sip_auth_method"]; - - if(sipAuthMethod=="REGISTER") - { - response = HandleRegister(request); - } - else if(sipAuthMethod=="INVITE") - { - response = HandleInvite(request); - } - else - { - m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); - response["int_response_code"]=404; - } + + if (sipAuthMethod=="REGISTER") + { + response = HandleRegister(request); + } + else if (sipAuthMethod=="INVITE") + { + response = HandleInvite(request); + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); + response["int_response_code"]=404; + } } - else if(eventCallingFunction=="switch_xml_locate_user") - { - response = HandleLocateUser(request); + else if (eventCallingFunction=="switch_xml_locate_user") + { + response = HandleLocateUser(request); } - else if(eventCallingFunction=="user_data_function") // gets called when an avatar to avatar call is made + else if (eventCallingFunction=="user_data_function") // gets called when an avatar to avatar call is made { response = HandleLocateUser(request); } - else if(eventCallingFunction=="user_outgoing_channel") + else if (eventCallingFunction=="user_outgoing_channel") { response = HandleRegister(request); } - else if(eventCallingFunction=="config_sofia") // happens once on freeswitch startup + else if (eventCallingFunction=="config_sofia") // happens once on freeswitch startup { response = HandleConfigSofia(request); } - else if(eventCallingFunction=="switch_load_network_lists") + else if (eventCallingFunction=="switch_load_network_lists") { //response = HandleLoadNetworkLists(request); response["int_response_code"]=404; @@ -266,24 +266,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n"+ "\r\n"+ "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "
\r\n"+ ""+ "\r\n" + "\r\n"+ @@ -332,4 +332,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } -} \ No newline at end of file +} diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index a8f9de6..fcb1c97 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -500,7 +500,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // is this a dialplan or directory request string section = (string) requestBody["section"]; - if(section=="directory") + if (section=="directory") response = m_FreeSwitchDirectory.HandleDirectoryRequest(requestBody); else if (section=="dialplan") response = m_FreeSwitchDialplan.HandleDialplanRequest(requestBody); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index ec26dff..9f45fd0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -294,7 +294,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string firstname, lastname; IClientAPI agent; - if( m_ActiveClients.TryGetValue(AgentID, out agent) ) + if (m_ActiveClients.TryGetValue(AgentID, out agent)) { firstname = agent.FirstName; lastname = agent.LastName; @@ -405,7 +405,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } UUID GroupID = new UUID(im.toAgentID); - if( m_groupData.GetGroupRecord(GroupID, null) != null) + if (m_groupData.GetGroupRecord(GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); @@ -453,9 +453,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); // Send notice out to everyone that wants notices - foreach( GroupMembersData member in m_groupData.GetGroupMembers(GroupID) ) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GroupID)) { - if( member.AcceptNotices ) + if (member.AcceptNotices) { msg.toAgentID = member.AgentID.Guid; m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); @@ -712,7 +712,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - if( m_groupData.GetGroupRecord(UUID.Zero, name) != null ) + if (m_groupData.GetGroupRecord(UUID.Zero, name) != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; -- cgit v1.1 From c397f05be74487d18eb2e60d52dadffc496aa19e Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Wed, 22 Apr 2009 06:07:39 +0000 Subject: * Some tweaks to the FreeSwitchModule to allow a well known hostname and avoid a double // in a path which causes account verification to fail * The change shouldn't affect anyone who has it working currently and makes it a ton easier for everyone else to get it working. * Handle a case when there's no Event-Calling-Function but it's obviously a REGISTER method --- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 14 +++++++++++++- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 21 +++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 4113976..24f114d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -69,7 +69,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } string eventCallingFunction = (string) request["Event-Calling-Function"]; - + if (eventCallingFunction == null) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } + + if (eventCallingFunction.Length == 0) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } if (eventCallingFunction=="sofia_reg_parse_auth") { @@ -110,12 +118,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice //response = HandleLoadNetworkLists(request); response["int_response_code"]=404; response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; } else { m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); response["int_response_code"]=404; response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index fcb1c97..6fb2c53 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -90,6 +90,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static int m_freeSwitchSubscribeRetry; private static string m_freeSwitchUrlResetPassword; private static IPEndPoint m_FreeSwitchServiceIP; + private int m_freeSwitchServicePort; + private string m_openSimWellKnownHTTPAddress; private FreeSwitchDirectory m_FreeSwitchDirectory; private FreeSwitchDialplan m_FreeSwitchDialplan; @@ -131,7 +133,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice int servicePort = m_config.GetInt("freeswitch_service_port", 80); IPAddress serviceIPAddress = IPAddress.Parse(serviceIP); m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort); - + m_freeSwitchServicePort = servicePort; m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty); m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm); m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true); @@ -139,6 +141,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm); m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505); m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm); + m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString()); m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); @@ -306,12 +309,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // those agentname = agentname.Replace('+', '-').Replace('/', '_'); - + // LLSDVoiceAccountResponse voiceAccountResponse = // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); LLSDVoiceAccountResponse voiceAccountResponse = new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, - String.Format("http://{0}/{1}/", m_FreeSwitchServiceIP, + String.Format("http://{0}:{1}{2}/", m_openSimWellKnownHTTPAddress, m_freeSwitchServicePort, m_freeSwitchAPIPrefix)); string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); @@ -490,20 +493,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request) { - m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}",request.ToString()); + m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]); Hashtable response = new Hashtable(); // all the params come as NVPs in the request body Hashtable requestBody = parseRequestBody((string) request["body"]); - + // is this a dialplan or directory request string section = (string) requestBody["section"]; - - if (section=="directory") + + if (section == "directory") response = m_FreeSwitchDirectory.HandleDirectoryRequest(requestBody); - else if (section=="dialplan") + else if (section == "dialplan") response = m_FreeSwitchDialplan.HandleDialplanRequest(requestBody); + else + m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); // XXX: re-generate dialplan: // - conf == region UUID -- cgit v1.1 From 458f7eb9b38609d02980afe5a6ee88d19c7dd7f8 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Wed, 22 Apr 2009 09:42:44 +0000 Subject: cleaning up, fixing warnings --- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 2 +- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 63 ++++++++++------------ .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 42 +++++++-------- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 4 +- 4 files changed, 48 insertions(+), 63 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index d8fce67..039cc2f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"]=200; + response["int_response_code"] = 200; response["str_response_string"] = @"
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 24f114d..fd384e4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -65,7 +65,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice foreach (DictionaryEntry item in request) { - m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); + m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); } string eventCallingFunction = (string) request["Event-Calling-Function"]; @@ -79,44 +79,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice eventCallingFunction = "sofia_reg_parse_auth"; } - if (eventCallingFunction=="sofia_reg_parse_auth") + if (eventCallingFunction == "sofia_reg_parse_auth") { string sipAuthMethod = (string)request["sip_auth_method"]; - if (sipAuthMethod=="REGISTER") + if (sipAuthMethod == "REGISTER") { response = HandleRegister(request); } - else if (sipAuthMethod=="INVITE") + else if (sipAuthMethod == "INVITE") { response = HandleInvite(request); } else { m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); - response["int_response_code"]=404; + response["int_response_code"] = 404; } } - else if (eventCallingFunction=="switch_xml_locate_user") + else if (eventCallingFunction == "switch_xml_locate_user") { response = HandleLocateUser(request); } - else if (eventCallingFunction=="user_data_function") // gets called when an avatar to avatar call is made + else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made { response = HandleLocateUser(request); } - else if (eventCallingFunction=="user_outgoing_channel") + else if (eventCallingFunction == "user_outgoing_channel") { response = HandleRegister(request); } - else if (eventCallingFunction=="config_sofia") // happens once on freeswitch startup + else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup { response = HandleConfigSofia(request); } - else if (eventCallingFunction=="switch_load_network_lists") + else if (eventCallingFunction == "switch_load_network_lists") { //response = HandleLoadNetworkLists(request); - response["int_response_code"]=404; + response["int_response_code"] = 404; response["keepalive"] = false; response["content_type"] = "text/xml"; response["str_response_string"] = ""; @@ -124,14 +124,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice else { m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); - response["int_response_code"]=404; + response["int_response_code"] = 404; response["keepalive"] = false; response["content_type"] = "text/xml"; response["str_response_string"] = ""; } - - - return response; } @@ -147,7 +144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable response = new Hashtable(); response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"]=200; + response["int_response_code"] = 200; response["str_response_string"] = String.Format( "\r\n" + "\r\n" + @@ -165,11 +162,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "
\r\n" + - "
\r\n" - , domain , user, password); + "\r\n", + domain , user, password); return response; - } private Hashtable HandleInvite(Hashtable request) @@ -185,7 +181,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable response = new Hashtable(); response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"]=200; + response["int_response_code"] = 200; response["str_response_string"] = String.Format( "\r\n" + "\r\n" + @@ -213,8 +209,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" - , domain , user, password,sipRequestUser); + "\r\n", + domain , user, password,sipRequestUser); return response; } @@ -231,7 +227,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable response = new Hashtable(); response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"]=200; + response["int_response_code"] = 200; response["str_response_string"] = String.Format( "\r\n" + "\r\n" + @@ -248,10 +244,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" - , domain , user); - - + "\r\n", + domain , user); return response; } @@ -266,7 +260,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable response = new Hashtable(); response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"]=200; + response["int_response_code"] = 200; response["str_response_string"] = String.Format( "\r\n" + "\r\n" + @@ -303,9 +297,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "
\r\n"+ "\r\n" + "\r\n" + - "\r\n" - , domain); - + "\r\n", + domain); return response; } @@ -320,7 +313,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable response = new Hashtable(); response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"]=200; + response["int_response_code"] = 200; response["str_response_string"] = String.Format( "\r\n" + "\r\n" + @@ -335,13 +328,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n"+ "\r\n" + "\r\n" + - "\r\n" - , domain); + "\r\n", + domain); return response; } - } - } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 6fb2c53..358f1cd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -54,7 +54,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // Infrastructure private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static readonly bool DUMP = true; // Capability string prefixes private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; @@ -87,9 +86,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static int m_freeSwitchEchoPort; private static string m_freeSwitchDefaultWellKnownIP; private static int m_freeSwitchDefaultTimeout; - private static int m_freeSwitchSubscribeRetry; + // private static int m_freeSwitchSubscribeRetry; private static string m_freeSwitchUrlResetPassword; - private static IPEndPoint m_FreeSwitchServiceIP; + // private static IPEndPoint m_FreeSwitchServiceIP; private int m_freeSwitchServicePort; private string m_openSimWellKnownHTTPAddress; @@ -132,7 +131,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty); int servicePort = m_config.GetInt("freeswitch_service_port", 80); IPAddress serviceIPAddress = IPAddress.Parse(serviceIP); - m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort); + // m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort); m_freeSwitchServicePort = servicePort; m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty); m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm); @@ -143,12 +142,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm); m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString()); m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); - m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); + // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); - - - if (String.IsNullOrEmpty(m_freeSwitchServerUser) || String.IsNullOrEmpty(m_freeSwitchServerPass) || String.IsNullOrEmpty(m_freeSwitchRealm) || @@ -163,12 +159,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // - prelogin: viv_get_prelogin.php // - signin: viv_signin.php scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceGetPreloginHTTPHandler); + FreeSwitchSLVoiceGetPreloginHTTPHandler); - // RestStreamHandler h = new RestStreamHandler("GET", String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); + // RestStreamHandler h = new + // RestStreamHandler("GET", + // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); // scene.CommsManager.HttpServer.AddStreamHandler(h); - - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceSigninHTTPHandler); @@ -307,15 +303,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // XXX: we need to cache the voice credentials, as // FreeSwitch is later going to come and ask us for // those - agentname = agentname.Replace('+', '-').Replace('/', '_'); // LLSDVoiceAccountResponse voiceAccountResponse = // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); LLSDVoiceAccountResponse voiceAccountResponse = - new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, - String.Format("http://{0}:{1}{2}/", m_openSimWellKnownHTTPAddress, m_freeSwitchServicePort, - m_freeSwitchAPIPrefix)); + new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, + String.Format("http://{0}:{1}{2}/", m_openSimWellKnownHTTPAddress, + m_freeSwitchServicePort, m_freeSwitchAPIPrefix)); string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); @@ -346,7 +341,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice UUID agentID, Caps caps) { ScenePresence avatar = scene.GetScenePresence(agentID); - string avatarName = avatar.Name; + string avatarName = avatar.Name; // - check whether we have a region channel in our cache // - if not: @@ -460,11 +455,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "{8}\r\n"+ "\r\n"+ "false\r\n"+ - "" - , - m_freeSwitchRealm,m_freeSwitchSIPProxy,m_freeSwitchAttemptUseSTUN, - m_freeSwitchSTUNServer,m_freeSwitchEchoServer,m_freeSwitchEchoPort, - m_freeSwitchDefaultWellKnownIP,m_freeSwitchDefaultTimeout,m_freeSwitchUrlResetPassword,""); + "", + m_freeSwitchRealm, m_freeSwitchSIPProxy, m_freeSwitchAttemptUseSTUN, + m_freeSwitchSTUNServer, m_freeSwitchEchoServer, m_freeSwitchEchoPort, + m_freeSwitchDefaultWellKnownIP, m_freeSwitchDefaultTimeout, + m_freeSwitchUrlResetPassword, ""); response["int_response_code"] = 200; @@ -531,12 +526,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice if (s.Trim() != "") { string [] nvp = s.Split(new Char [] {'='}); - bodyParams.Add(HttpUtility.UrlDecode(nvp[0]),HttpUtility.UrlDecode(nvp[1])); + bodyParams.Add(HttpUtility.UrlDecode(nvp[0]), HttpUtility.UrlDecode(nvp[1])); } } return bodyParams; - } private string ChannelUri(Scene scene, LandData land) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 3a728da..ada6cfd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -218,7 +218,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); - if ((GroupID != null) && (GroupID != UUID.Zero)) + if (GroupID != UUID.Zero) { param["GroupID"] = GroupID.ToString(); } @@ -793,7 +793,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); - object o = respData[key]; + // object o = respData[key]; string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) -- cgit v1.1 From 956be49238541502dab3319d09a225357a0946ee Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Wed, 22 Apr 2009 10:03:38 +0000 Subject: further cleanup (lower casing non-public vars and local vars) --- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 352 ++++++++++----------- 1 file changed, 173 insertions(+), 179 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 9f45fd0..3d9477f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -73,19 +73,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private List m_SceneList = new List(); + private List m_sceneList = new List(); // This only works when running as non-Shared, in shared, there may be multiple IClientAPIs for a single client - private Dictionary m_ActiveClients = new Dictionary(); + private Dictionary m_activeClients = new Dictionary(); - private IMessageTransferModule m_MsgTransferModule = null; + private IMessageTransferModule m_msgTransferModule = null; private IGroupDataProvider m_groupData = null; // Configuration settings private const string m_defaultXmlRpcServiceURL = "http://osflotsam.org/xmlrpc.php"; - private bool m_GroupsEnabled = false; - private bool m_GroupNoticesEnabled = true; + private bool m_groupsEnabled = false; + private bool m_groupNoticesEnabled = true; private bool m_debugEnabled = true; #region IRegionModule Members @@ -104,8 +104,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } else { - m_GroupsEnabled = groupsConfig.GetBoolean("Enabled", false); - if (!m_GroupsEnabled) + m_groupsEnabled = groupsConfig.GetBoolean("Enabled", false); + if (!m_groupsEnabled) { m_log.Info("[GROUPS]: Groups disabled in configuration"); return; @@ -114,7 +114,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") { m_log.Info("[GROUPS]: Config Groups Module not set to XmlRpcGroups"); - m_GroupsEnabled = false; + m_groupsEnabled = false; return; } @@ -125,7 +125,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupData = new XmlRpcGroupDataProvider(ServiceURL, DisableKeepAlive); m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL); - m_GroupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); + m_groupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); } @@ -133,30 +133,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - if (m_GroupsEnabled) + if (m_groupsEnabled) scene.RegisterModuleInterface(this); } public void RegionLoaded(Scene scene) { - if (!m_GroupsEnabled) + if (!m_groupsEnabled) return; if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_MsgTransferModule = scene.RequestModuleInterface(); + m_msgTransferModule = scene.RequestModuleInterface(); // No message transfer module, no notices, group invites, rejects, ejects, etc - if (m_MsgTransferModule == null) + if (m_msgTransferModule == null) { - m_GroupsEnabled = false; + m_groupsEnabled = false; m_log.Info("[GROUPS]: Could not get MessageTransferModule"); Close(); return; } - m_SceneList.Add(scene); + m_sceneList.Add(scene); scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnClientClosed += OnClientClosed; @@ -166,17 +166,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void RemoveRegion(Scene scene) { - if (!m_GroupsEnabled) + if (!m_groupsEnabled) return; if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_SceneList.Remove(scene); + m_sceneList.Remove(scene); } public void Close() { - if (!m_GroupsEnabled) + if (!m_groupsEnabled) return; m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); } @@ -185,13 +185,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { get { return "XmlRpcGroupsModule"; } } - #endregion private void UpdateAllClientsWithGroupInfo() { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - foreach (IClientAPI client in m_ActiveClients.Values) + foreach (IClientAPI client in m_activeClients.Values) { UpdateClientWithGroupInfo(client); } @@ -220,45 +219,43 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - lock (m_ActiveClients) + lock (m_activeClients) { - if (!m_ActiveClients.ContainsKey(client.AgentId)) + if (!m_activeClients.ContainsKey(client.AgentId)) { client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnDirFindQuery += OnDirFindQuery; client.OnInstantMessage += OnInstantMessage; - m_ActiveClients.Add(client.AgentId, client); + m_activeClients.Add(client.AgentId, client); } } UpdateClientWithGroupInfo(client); } - private void OnClientClosed(UUID AgentId) + + private void OnClientClosed(UUID agentId) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - lock (m_ActiveClients) + lock (m_activeClients) { - if (m_ActiveClients.ContainsKey(AgentId)) + if (m_activeClients.ContainsKey(agentId)) { - IClientAPI client = m_ActiveClients[AgentId]; + IClientAPI client = m_activeClients[agentId]; client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; client.OnDirFindQuery -= OnDirFindQuery; client.OnInstantMessage -= OnInstantMessage; - m_ActiveClients.Remove(AgentId); + m_activeClients.Remove(agentId); } else { m_log.InfoFormat("[GROUPS] Client closed that wasn't registered here."); } - - } - } @@ -266,35 +263,33 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { - m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", + System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); } - } - private void OnAgentDataUpdateRequest(IClientAPI remoteClient, - UUID AgentID, UUID SessionID) + private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID agentID, UUID sessionID) { - m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, SessionID); - + m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, sessionID); - UUID ActiveGroupID = UUID.Zero; - string ActiveGroupTitle = string.Empty; - string ActiveGroupName = string.Empty; - ulong ActiveGroupPowers = (ulong)GroupPowers.None; + UUID activeGroupID = UUID.Zero; + string activeGroupTitle = string.Empty; + string activeGroupName = string.Empty; + ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(AgentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID); if (membership != null) { - ActiveGroupID = membership.GroupID; - ActiveGroupTitle = membership.GroupTitle; - ActiveGroupPowers = membership.GroupPowers; + activeGroupID = membership.GroupID; + activeGroupTitle = membership.GroupTitle; + activeGroupPowers = membership.GroupPowers; } string firstname, lastname; IClientAPI agent; - if (m_ActiveClients.TryGetValue(AgentID, out agent)) + if (m_activeClients.TryGetValue(agentID, out agent)) { firstname = agent.FirstName; lastname = agent.LastName; @@ -303,31 +298,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups lastname = "Unknown"; } - UpdateScenePresenceWithTitle(AgentID, ActiveGroupTitle); + UpdateScenePresenceWithTitle(agentID, activeGroupTitle); - remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, - lastname, ActiveGroupPowers, ActiveGroupName, - ActiveGroupTitle); + remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname, + lastname, activeGroupPowers, activeGroupName, + activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) + private void HandleUUIDGroupNameRequest(UUID groupID, IClientAPI remoteClient) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - string GroupName; + string groupName; - GroupRecord group = m_groupData.GetGroupRecord(GroupID, null); + GroupRecord group = m_groupData.GetGroupRecord(groupID, null); if (group != null) { - GroupName = group.GroupName; + groupName = group.GroupName; } else { - GroupName = "Unknown"; + groupName = "Unknown"; } - - remote_client.SendGroupNameReply(GroupID, GroupName); + remoteClient.SendGroupNameReply(groupID, groupName); } @@ -337,11 +331,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Group invitations - if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) + if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || + (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { m_log.WarnFormat("[GROUPS] Received an IIM for {0}.", ((InstantMessageDialog)im.dialog).ToString()); - UUID inviteID = new UUID(im.imSessionID); GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); @@ -359,7 +353,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // and the sessionid is the role m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); - if (m_MsgTransferModule != null) + if (m_msgTransferModule != null) { GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -376,7 +370,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = new byte[0]; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); } UpdateAllClientsWithGroupInfo(); @@ -391,25 +385,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupData.RemoveAgentToGroupInvite(inviteID); } - - } } // Group notices if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) { - if (!m_GroupNoticesEnabled) + if (!m_groupNoticesEnabled) { return; } - UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GroupID, null) != null) + UUID groupID = new UUID(im.toAgentID); + if (m_groupData.GetGroupRecord(groupID, null) != null) { - UUID NoticeID = UUID.Random(); - string Subject = im.message.Substring(0, im.message.IndexOf('|')); - string Message = im.message.Substring(Subject.Length + 1); + UUID noticeID = UUID.Random(); + string subject = im.message.Substring(0, im.message.IndexOf('|')); + string message = im.message.Substring(subject.Length + 1); byte[] bucket; @@ -418,7 +410,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket = new byte[19]; bucket[0] = 0; //dunno bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); + groupID.ToBytes(bucket, 2); bucket[18] = 0; //dunno } else @@ -438,33 +430,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket = new byte[19]; bucket[0] = 0; //dunno bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); + groupID.ToBytes(bucket, 2); bucket[18] = 0; //dunno } - m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + m_groupData.AddGroupNotice(groupID, noticeID, im.fromAgentName, subject, message, bucket); if (OnNewGroupNotice != null) { - OnNewGroupNotice(GroupID, NoticeID); + OnNewGroupNotice(groupID, noticeID); } // Build notice IIM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, noticeID, + (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GroupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(groupID)) { if (member.AcceptNotices) { msg.toAgentID = member.AgentID.Guid; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) {}); } } - - - } } @@ -473,30 +462,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO:FIXME: Use a presense server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue - if ((im.dialog == 210)) + if (im.dialog == 210) { // This is sent from the region that the ejectee was ejected from // if it's being delivered here, then the ejectee is here // so we need to send local updates to the agent. - - - if (m_MsgTransferModule != null) + if (m_msgTransferModule != null) { im.dialog = (byte)InstantMessageDialog.MessageFromAgent; - m_MsgTransferModule.SendInstantMessage(im, delegate(bool success) { }); + m_msgTransferModule.SendInstantMessage(im, delegate(bool success) {}); } UUID ejecteeID = new UUID(im.toAgentID); UUID groupID = new UUID(im.toAgentID); - if (m_ActiveClients.ContainsKey(ejecteeID)) + if (m_activeClients.ContainsKey(ejecteeID)) { - m_ActiveClients[ejecteeID].SendAgentDropGroup(groupID); + m_activeClients[ejecteeID].SendAgentDropGroup(groupID); } - } - - - } private void OnGridInstantMessage(GridInstantMessage msg) @@ -506,7 +489,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Trigger the above event handler OnInstantMessage(null, msg); - // If a message from a group arrives here, it may need to be forwarded to a local client if (msg.fromGroup == true) { @@ -515,32 +497,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case (byte)InstantMessageDialog.GroupInvitation: case (byte)InstantMessageDialog.GroupNotice: UUID toAgentID = new UUID(msg.toAgentID); - if (m_ActiveClients.ContainsKey(toAgentID)) + if (m_activeClients.ContainsKey(toAgentID)) { - m_ActiveClients[toAgentID].SendInstantMessage(msg); + m_activeClients[toAgentID].SendInstantMessage(msg); } break; } } } - - #endregion - - private void UpdateScenePresenceWithTitle(UUID AgentID, string Title) + private void UpdateScenePresenceWithTitle(UUID agentID, string title) { - m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title); + m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", agentID, title); + ScenePresence presence = null; - lock (m_SceneList) + lock (m_sceneList) { - foreach (Scene scene in m_SceneList) + foreach (Scene scene in m_sceneList) { - presence = scene.GetScenePresence(AgentID); + presence = scene.GetScenePresence(agentID); if (presence != null) { - presence.Grouptitle = Title; + presence.Grouptitle = title; // FixMe: Ter suggests a "Schedule" method that I can't find. presence.SendFullUpdateToAllClients(); @@ -554,9 +534,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public event NewGroupNotice OnNewGroupNotice; - public GroupRecord GetGroupRecord(UUID GroupID) + public GroupRecord GetGroupRecord(UUID groupID) { - return m_groupData.GetGroupRecord(GroupID, null); + return m_groupData.GetGroupRecord(groupID, null); } public void ActivateGroup(IClientAPI remoteClient, UUID groupID) @@ -608,7 +588,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return data; - } public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) @@ -623,7 +602,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return data; - } public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) @@ -638,8 +616,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return data; - - } public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) @@ -677,27 +653,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return profile; } - public GroupMembershipData[] GetMembershipData(UUID UserID) + public GroupMembershipData[] GetMembershipData(UUID userID) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(UserID).ToArray(); + return m_groupData.GetAgentGroupMemberships(userID).ToArray(); } - public GroupMembershipData GetMembershipData(UUID GroupID, UUID UserID) + public GroupMembershipData GetMembershipData(UUID groupID, UUID userID) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMembership(UserID, GroupID); + return m_groupData.GetAgentGroupMembership(userID, groupID); } - public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, + bool showInList, UUID insigniaID, int membershipFee, + bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: Security Check? - m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, + openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) @@ -708,7 +687,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); } - public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, + bool showInList, UUID insigniaID, int membershipFee, + bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -718,22 +699,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Zero; } - UUID GroupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + UUID groupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, + openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); - remoteClient.SendCreateGroupReply(GroupID, true, "Group created successfullly"); + remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); UpdateClientWithGroupInfo(remoteClient); - return GroupID; + return groupID; } - public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID GroupID) + public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // ToDo: check if agent is a member of group and is allowed to see notices? - return m_groupData.GetGroupNotices(GroupID).ToArray(); + return m_groupData.GetGroupNotices(groupID).ToArray(); } /// @@ -754,17 +736,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Change the current Active Group Role for Agent /// - public void GroupTitleUpdate(IClientAPI remoteClient, UUID GroupID, UUID TitleRoleID) + public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, GroupID, TitleRoleID); + m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, groupID, titleRoleID); UpdateAllClientsWithGroupInfo(); } - public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) + public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, + string name, string description, string title, ulong powers, byte updateType) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -829,7 +812,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (data != null) { - if (m_MsgTransferModule != null) + if (m_msgTransferModule != null) { GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -846,7 +829,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = data.BinaryBucket; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); } } @@ -899,32 +882,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UpdateClientWithGroupInfo(remoteClient); } - public void LeaveGroupRequest(IClientAPI remoteClient, UUID GroupID) + public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, GroupID); + m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, groupID); - remoteClient.SendLeaveGroupReply(GroupID, true); + remoteClient.SendLeaveGroupReply(groupID, true); - remoteClient.SendAgentDropGroup(GroupID); + remoteClient.SendAgentDropGroup(groupID); UpdateClientWithGroupInfo(remoteClient); } - public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID GroupID, UUID EjecteeID) + public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check? - m_groupData.RemoveAgentFromGroup(EjecteeID, GroupID); + m_groupData.RemoveAgentFromGroup(ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, GroupID, true); + remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); - if (m_MsgTransferModule != null) + if (m_msgTransferModule != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(GroupID, null); - UserProfileData userProfile = m_SceneList[0].CommsManager.UserService.GetUserProfile(EjecteeID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); if ((groupInfo == null) || (userProfile == null)) { @@ -938,7 +921,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = UUID.Zero.Guid; msg.fromAgentID = remoteClient.AgentId.Guid; // msg.fromAgentID = info.GroupID; - msg.toAgentID = EjecteeID.Guid; + msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; @@ -950,7 +933,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) + { + m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", + success,ToString()); + }); // Message to ejector @@ -968,11 +955,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.fromAgentName = remoteClient.Name; if (userProfile != null) { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", + remoteClient.Name, groupInfo.GroupName, userProfile.Name); } else { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", + remoteClient.Name, groupInfo.GroupName, "Unknown member"); } msg.dialog = (byte)210; //interop msg.fromGroup = false; @@ -981,41 +970,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success, ToString()); }); - - - + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) + { + m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", + success, ToString()); + }); } - UpdateAllClientsWithGroupInfo(); } - public void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InvitedAgentID, UUID RoleID) + public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", GroupID, InvitedAgentID, RoleID); + m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", groupID, invitedAgentID, roleID); // Todo: Security check, probably also want to send some kind of notification - UUID InviteID = UUID.Random(); - m_log.WarnFormat("[GROUPS] Invite ID: {0}", InviteID); - m_groupData.AddAgentToGroupInvite(InviteID, GroupID, RoleID, InvitedAgentID); + UUID inviteID = UUID.Random(); + m_log.WarnFormat("[GROUPS] Invite ID: {0}", inviteID); + m_groupData.AddAgentToGroupInvite(inviteID, groupID, roleID, invitedAgentID); - if (m_MsgTransferModule != null) + if (m_msgTransferModule != null) { - Guid inviteUUID = InviteID.Guid; + Guid inviteUUID = inviteID.Guid; GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = inviteUUID; // msg.fromAgentID = remoteClient.AgentId.Guid; - msg.fromAgentID = GroupID.Guid; - msg.toAgentID = InvitedAgentID.Guid; + msg.fromAgentID = groupID.Guid; + msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", + remoteClient.Name); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; msg.fromGroup = true; msg.offline = (byte)0; @@ -1024,7 +1014,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[20]; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); }); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) + { + m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); + }); } } @@ -1034,42 +1027,43 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - OSDArray AgentData = new OSDArray(1); - OSDMap AgentDataMap = new OSDMap(1); - AgentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId)); - AgentData.Add(AgentDataMap); + OSDArray agentData = new OSDArray(1); + OSDMap agentDataMap = new OSDMap(1); + agentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId)); + agentData.Add(agentDataMap); - OSDArray GroupData = new OSDArray(data.Length); - OSDArray NewGroupData = new OSDArray(data.Length); + OSDArray groupData = new OSDArray(data.Length); + OSDArray newGroupData = new OSDArray(data.Length); foreach (GroupMembershipData membership in data) { - OSDMap GroupDataMap = new OSDMap(6); - OSDMap NewGroupDataMap = new OSDMap(1); - - GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); - GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); - GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); - GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); - GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); - GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); - NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); - - GroupData.Add(GroupDataMap); - NewGroupData.Add(NewGroupDataMap); + OSDMap groupDataMap = new OSDMap(6); + OSDMap newGroupDataMap = new OSDMap(1); + + groupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); + groupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); + groupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); + groupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); + groupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); + groupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); + newGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); + + groupData.Add(groupDataMap); + newGroupData.Add(newGroupDataMap); } OSDMap llDataStruct = new OSDMap(3); - llDataStruct.Add("AgentData", AgentData); - llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); + llDataStruct.Add("AgentData", agentData); + llDataStruct.Add("GroupData", groupData); + llDataStruct.Add("NewGroupData", newGroupData); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), + remoteClient.AgentId); } } -- cgit v1.1 From d455d579d03523b98e9f0161716942889b7913c3 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Wed, 22 Apr 2009 18:00:59 +0000 Subject: more cleanup --- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 61 +++++++++++---------- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 63 ++++++++++------------ .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 2 - 3 files changed, 60 insertions(+), 66 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index ada6cfd..30839cc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -52,7 +52,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_serviceURL = string.Empty; - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | GroupPowers.AllowVoiceChat | GroupPowers.ReceiveNotices | GroupPowers.StartProposal | GroupPowers.VoteOnProposal; + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | + GroupPowers.VoteOnProposal; private bool m_disableKeepAlive = false; @@ -73,7 +79,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) + public UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, + int membershipFee, bool openEnrollment, bool allowPublish, + bool maturePublish, UUID founderID) { UUID GroupID = UUID.Random(); UUID OwnerRoleID = UUID.Random(); @@ -140,9 +148,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | GroupPowers.VoteOnProposal; param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); - - - Hashtable respData = XmlRpcCall("groups.createGroup", param); if (respData.Contains("error")) @@ -155,7 +160,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + public void UpdateGroup(UUID groupID, string charter, bool showInList, + UUID insigniaID, int membershipFee, bool openEnrollment, + bool allowPublish, bool maturePublish) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); @@ -170,7 +177,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall("groups.updateGroup", param); } - public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) + public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); @@ -193,7 +201,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers) + public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); @@ -479,11 +488,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (respData.Contains("error")) { - return null; - } + return null; + } return HashTableToGroupMembershipData(respData); - } + } public List GetAgentGroupMemberships(UUID AgentID) @@ -533,8 +542,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - - } public List GetGroupRoles(UUID GroupID) @@ -565,7 +572,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - } private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) @@ -633,7 +639,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return members; - } public List GetGroupRoleMembers(UUID GroupID) @@ -647,15 +652,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!respData.Contains("error")) { - foreach (Hashtable membership in respData.Values) - { - GroupRoleMembersData data = new GroupRoleMembersData(); - - data.MemberID = new UUID((string)membership["AgentID"]); - data.RoleID = new UUID((string)membership["RoleID"]); - - members.Add(data); - } + foreach (Hashtable membership in respData.Values) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = new UUID((string)membership["AgentID"]); + data.RoleID = new UUID((string)membership["RoleID"]); + + members.Add(data); + } } return members; } @@ -697,8 +702,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!respData.Contains("error")) { - return null; - } + return null; + } GroupNoticeInfo data = new GroupNoticeInfo(); data.GroupID = UUID.Parse((string)respData["GroupID"]); @@ -799,11 +804,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (string line in lines) { m_log.ErrorFormat("[GROUPDATA] {0}", line); - } - + } } } - } public class GroupNoticeInfo diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 34af325..b1b25aa 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -229,31 +229,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Force? open the group session dialog??? IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface(); eq.ChatterboxInvitation( - GroupID - , GroupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp - , msg.offline==1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , Utils.StringToBytes(GroupInfo.GroupName) - ); + GroupID, + GroupInfo.GroupName, + new UUID(msg.fromAgentID), + msg.message, new UUID(msg.toAgentID), + msg.fromAgentName, + msg.dialog, + msg.timestamp, + msg.offline == 1, + (int)msg.ParentEstateID, + msg.Position, + 1, + new UUID(msg.imSessionID), + msg.fromGroup, + Utils.StringToBytes(GroupInfo.GroupName)); eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - + new UUID(GroupID), + new UUID(msg.fromAgentID), + new UUID(msg.toAgentID), + false, //canVoiceChat + false, //isModerator + false); //text mute } } } @@ -285,13 +282,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); queue.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(im.fromAgentID) - , new UUID(im.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); + new UUID(GroupID), + new UUID(im.fromAgentID), + new UUID(im.toAgentID), + false, //canVoiceChat + false, //isModerator + false); //text mute } } @@ -373,12 +369,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.ParentEstateID = im.ParentEstateID; msg.Position = im.Position; msg.RegionID = im.RegionID; - msg.binaryBucket = new byte[1] { 0 }; + msg.binaryBucket = new byte[1]{0}; foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID)) { msg.toAgentID = member.AgentID.Guid; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) {}); } } @@ -402,14 +398,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bodyMap.Add("success", OSD.FromBoolean(true)); bodyMap.Add("session_info", sessionMap); - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); } - } @@ -428,6 +422,5 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); } } - } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 3d9477f..9ba78c5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -155,13 +155,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_sceneList.Add(scene); scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnClientClosed += OnClientClosed; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - } public void RemoveRegion(Scene scene) -- cgit v1.1 From c25ceb009e644579c56811faffded540658cd4dd Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Wed, 22 Apr 2009 19:43:58 +0000 Subject: * minor: remove some compiler warnings --- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 62 +++++++++++----------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index fd384e4..c131a7f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -303,36 +303,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - private Hashtable HandleLoadNetworkLists(Hashtable request) - { - m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called"); - - // TODO the password we return needs to match that sent in the request, this is hard coded for now - string domain = (string) request["domain"]; - - Hashtable response = new Hashtable(); - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = String.Format( - "\r\n" + - "\r\n" + - "
\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n" + - "
\r\n" + - "
\r\n", - domain); - - - return response; - } +// private Hashtable HandleLoadNetworkLists(Hashtable request) +// { +// m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called"); +// +// // TODO the password we return needs to match that sent in the request, this is hard coded for now +// string domain = (string) request["domain"]; +// +// Hashtable response = new Hashtable(); +// response["content_type"] = "text/xml"; +// response["keepalive"] = false; +// response["int_response_code"] = 200; +// response["str_response_string"] = String.Format( +// "\r\n" + +// "\r\n" + +// "
\r\n" + +// "\r\n" + +// "\r\n" + +// "\r\n" + +// "\r\n" + +// "\r\n" + +// "\r\n"+ +// "\r\n"+ +// "\r\n"+ +// "\r\n" + +// "
\r\n" + +// "
\r\n", +// domain); +// +// +// return response; +// } } } -- cgit v1.1 From dc640465a834c3ddb586d6a7850fd1805ea2e48f Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Thu, 23 Apr 2009 05:22:02 +0000 Subject: * Tweaking the dialstring so the sip_contact_user variable is set to the dialed user. This stops the client from complaining and might be useful later. Resolves the 'unable to parse id from mod_sofia@ip:port' message. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 11 ++++++----- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index c131a7f..11797f6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + "\r\n" + "\r\n" + "\r\n" + @@ -190,7 +190,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + "\r\n" + "\r\n" + "\r\n" + @@ -200,7 +200,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + "\r\n" + "\r\n" + "\r\n" + @@ -234,7 +234,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "
\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + "\r\n" + "\r\n" + "\r\n"+ @@ -267,7 +267,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "
\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + "\r\n" + "\r\n"+ "\r\n"+ @@ -302,6 +302,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } + // private Hashtable HandleLoadNetworkLists(Hashtable request) // { diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 358f1cd..58f1b3a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -45,6 +45,7 @@ using OpenSim.Framework.Servers; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps = OpenSim.Framework.Communications.Capabilities.Caps; +using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { @@ -511,7 +512,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // -> TODO Initialise(): keep track of regions via events // re-generate accounts for all avatars // -> TODO Initialise(): keep track of avatars via events - m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",response["str_response_string"]); + Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); + + m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",normalizeEndLines.Replace(((string)response["str_response_string"]), "")); return response; } -- cgit v1.1 From 77bd7da9ccce7d572c7565b8fdda8e6711ca2643 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Thu, 23 Apr 2009 06:31:32 +0000 Subject: * Fix another crash bug in the FreeSwitchVoiceModule --- .../OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 2 ++ .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 11797f6..377a824 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -95,6 +95,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); response["int_response_code"] = 404; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; } } else if (eventCallingFunction == "switch_xml_locate_user") diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 58f1b3a..abe7594 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -492,7 +492,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]); Hashtable response = new Hashtable(); - + response["str_response_string"] = string.Empty; // all the params come as NVPs in the request body Hashtable requestBody = parseRequestBody((string) request["body"]); -- cgit v1.1 From 4b7a2085592c67d86a57305465208adc482a2203 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Thu, 23 Apr 2009 09:06:36 +0000 Subject: From: Alan M Webb Some other IRC timing wrinkles showed up: [1] If connect processing blocked in socket activation, then the watch dog saw the session as connected, and eventually tried to ping, but because the socket create was still blocked, it barfed on a null reference. This then drove reconnect. Changed the watchdog handler so that it only tries to ping connections that are connected and not pending. [2] If the socket creation actually fails, then the connect and pending flags were reset. This resulted in the connection being retried at the earliest possible opportunity. The longer login-timeout is preferrable, so the status flags are not reset, and the failed login is eventually timed out. [3] The Inter-connection interval is primed so that the first session can connect without delay. --- .../OptionalModules/Avatar/Chat/IRCConnector.cs | 41 ++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index c621fd3..eb6634d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private static int _idk_ = 0; // core connector identifier private static int _pdk_ = 0; // ping interval counter - private static int _icc_ = 0; // IRC connect counter + private static int _icc_ = ICCD_PERIOD; // IRC connect counter // List of configured connectors @@ -71,6 +71,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private static System.Timers.Timer m_watchdog = null; + // The watch-dog gets started as soon as the class is instantiated, and + // ticks once every second (WD_INTERVAL) + static IRCConnector() { m_log.DebugFormat("[IRC-Connector]: Static initialization started"); @@ -234,10 +237,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_nick = m_baseNick + Util.RandomClass.Next(1, 99); } - // Add the newly created connector to the known connectors list - - // m_connectors.Add(this); - m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); } @@ -255,14 +254,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (!m_enabled) { - m_connectors.Add(this); - m_enabled = true; - if (!Connected) { Connect(); } + lock(m_connectors) + m_connectors.Add(this); + + m_enabled = true; + } } @@ -305,7 +306,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } - m_connectors.Remove(this); + lock(m_connectors) + m_connectors.Remove(this); } } @@ -340,6 +342,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat try { + if (m_connected) return; m_connected = true; @@ -376,8 +379,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { m_log.ErrorFormat("[IRC-Connector-{0}] cannot connect {1} to {2}:{3}: {4}", idn, m_nick, m_server, m_port, e.Message); - m_connected = false; - m_pending = false; + // It might seem reasonable to reset connected and pending status here + // Seeing as we know that the login has failed, but if we do that, then + // connection will be retried each time the interconnection interval + // expires. By leaving them as they are, the connection will be retried + // when the login timeout expires. Which is preferred. } } @@ -834,14 +840,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat protected static void WatchdogHandler(Object source, ElapsedEventArgs args) { - // m_log.InfoFormat("[IRC-Watchdog] Status scan"); + // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_); _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger _icc_++; // increment the inter-consecutive-connect-delay counter + lock(m_connectors) foreach (IRCConnector connector in m_connectors) { + // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); + if (connector.Enabled) { if (!connector.Connected) @@ -863,14 +872,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { if (connector.m_timeout == 0) { - // m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); + m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); connector.Reconnect(); } else connector.m_timeout--; } - if (_pdk_ == 0) + // Being marked connected is not enough to ping. Socket establishment can sometimes take a long + // time, in which case the watch dog might try to ping the server before the socket has been + // set up, with nasty side-effects. + + else if (_pdk_ == 0) { try { -- cgit v1.1 From 8afeee9ff6905781824237e0ddd4235b4d921ef8 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Fri, 24 Apr 2009 00:58:48 +0000 Subject: Update svn properties, add copyright headers, formatting cleanup. --- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 19 +++---------------- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 2 +- 2 files changed, 4 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 30839cc..2a5a319 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -67,13 +67,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_serviceURL = serviceURL.Trim().ToLower(); m_disableKeepAlive = disableKeepAlive; - if ((serviceURL == null) - || (serviceURL == string.Empty) - ) + if ((serviceURL == null) || + (serviceURL == string.Empty)) { throw new Exception("Please specify a valid ServiceURL for XmlRpcGroupDataProvider in OpenSim.ini, [Groups], XmlRpcServiceURL"); } - } /// @@ -153,7 +151,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (respData.Contains("error")) { // UUID is not nullable - return UUID.Zero; } @@ -236,7 +233,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -253,7 +249,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -269,7 +264,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; - } private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) @@ -300,7 +294,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) { - GroupRecord group = new GroupRecord(); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); group.GroupName = groupProfile["Name"].ToString(); @@ -320,7 +313,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } - public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); @@ -349,7 +341,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["ListInProfile"] = ListInProfile ? "1" : "0"; XmlRpcCall("groups.setAgentGroupInfo", param); - } public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) @@ -361,7 +352,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = groupID.ToString(); XmlRpcCall("groups.addAgentToGroupInvite", param); - } public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) @@ -410,7 +400,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); XmlRpcCall("groups.removeAgentFromGroup", param); - } public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) @@ -433,7 +422,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall("groups.removeAgentFromGroupRole", param); } - public List FindGroups(string search) { Hashtable param = new Hashtable(); @@ -494,7 +482,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - public List GetAgentGroupMemberships(UUID AgentID) { Hashtable param = new Hashtable(); @@ -757,7 +744,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcResponse resp = req.Send(m_serviceURL, 10000); - if( resp.Value is Hashtable ) + if (resp.Value is Hashtable) { Hashtable respData = (Hashtable)resp.Value; if (respData.Contains("error") && !respData.Contains("succeed")) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 9ba78c5..69c7258 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -490,7 +490,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // If a message from a group arrives here, it may need to be forwarded to a local client if (msg.fromGroup == true) { - switch( msg.dialog ) + switch (msg.dialog) { case (byte)InstantMessageDialog.GroupInvitation: case (byte)InstantMessageDialog.GroupNotice: -- cgit v1.1 From 917849eaac7fa8a93079d2279781ce819fa04bd1 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sat, 25 Apr 2009 01:15:34 +0000 Subject: * More debug warning message removal in the FreeSwitchVoiceModule --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 296 +++++++++++++++++++-- 1 file changed, 275 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index abe7594..513d169 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -28,7 +28,9 @@ using System; using System.IO; using System.Net; +using System.Net.Security; using System.Web; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Xml; using System.Collections; @@ -47,6 +49,7 @@ using OpenSim.Region.Framework.Scenes; using Caps = OpenSim.Framework.Communications.Capabilities.Caps; using System.Text.RegularExpressions; + namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { public class FreeSwitchVoiceModule : IRegionModule @@ -56,6 +59,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private const bool UseProxy = false; + // Capability string prefixes private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; @@ -95,7 +100,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private FreeSwitchDirectory m_FreeSwitchDirectory; private FreeSwitchDialplan m_FreeSwitchDialplan; + + private readonly Dictionary m_UUIDName = new Dictionary(); + private IConfig m_config; public void Initialise(Scene scene, IConfigSource config) @@ -159,22 +167,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // set up http request handlers for // - prelogin: viv_get_prelogin.php // - signin: viv_signin.php - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceGetPreloginHTTPHandler); - - // RestStreamHandler h = new - // RestStreamHandler("GET", - // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); - // scene.CommsManager.HttpServer.AddStreamHandler(h); + // - buddies: viv_buddy.php + // - ???: viv_watcher.php + // - signout: viv_signout.php + if (UseProxy) + { + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix), + ForwardProxyRequest); + } + else + { + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceGetPreloginHTTPHandler); + + // RestStreamHandler h = new + // RestStreamHandler("GET", + // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); + // scene.CommsManager.HttpServer.AddStreamHandler(h); + + + + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceSigninHTTPHandler); + + // set up http request handlers to provide + // on-demand FreeSwitch configuration to + // FreeSwitch's mod_curl_xml + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), + FreeSwitchConfigHTTPHandler); + + scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceBuddyHTTPHandler); + } - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceSigninHTTPHandler); - - // set up http request handlers to provide - // on-demand FreeSwitch configuration to - // FreeSwitch's mod_curl_xml - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), - FreeSwitchConfigHTTPHandler); + + + m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); @@ -203,7 +231,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice OnRegisterCaps(scene, agentID, caps); }; - + try + { + ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation; + } + catch (NotImplementedException) + { + try + { +#pragma warning disable 0612, 0618 + // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this! + ServicePointManager.CertificatePolicy = new MonoCert(); +#pragma warning restore 0612, 0618 + } + catch (Exception) + { + m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); + } + } } } @@ -290,6 +335,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice UUID agentID, Caps caps) { ScenePresence avatar = scene.GetScenePresence(agentID); + if (avatar == null) + { + System.Threading.Thread.Sleep(2000); + avatar = scene.GetScenePresence(agentID); + + if (avatar == null) + return "undef"; + } string avatarName = avatar.Name; try @@ -305,8 +358,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // FreeSwitch is later going to come and ask us for // those agentname = agentname.Replace('+', '-').Replace('/', '_'); - - // LLSDVoiceAccountResponse voiceAccountResponse = + + lock (m_UUIDName) + { + if (m_UUIDName.ContainsKey(agentname)) + { + m_UUIDName[agentname] = avatarName; + } + else + { + m_UUIDName.Add(agentname, avatarName); + } + } + + // LLSDVoiceAccountResponse voiceAccountResponse = // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); LLSDVoiceAccountResponse voiceAccountResponse = new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, @@ -433,6 +498,57 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return "true"; } + public Hashtable ForwardProxyRequest(Hashtable request) + { + m_log.Debug("[PROXYING]: -------------------------------proxying request"); + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + response["int_response_code"] = 200; + + string forwardaddress = "https://www.bhr.vivox.com/api2/"; + string body = (string)request["body"]; + string method = (string) request["http-method"]; + string contenttype = (string) request["content-type"]; + string uri = (string) request["uri"]; + uri = uri.Replace("/api/", ""); + forwardaddress += uri; + + + string fwdresponsestr = ""; + int fwdresponsecode = 200; + string fwdresponsecontenttype = "text/xml"; + + + HttpWebRequest forwardreq = (HttpWebRequest)WebRequest.Create(forwardaddress); + forwardreq.Method = method; + forwardreq.ContentType = contenttype; + forwardreq.KeepAlive = false; + + if (method == "POST") + { + byte[] contentreq = Encoding.UTF8.GetBytes(body); + forwardreq.ContentLength = contentreq.Length; + Stream reqStream = forwardreq.GetRequestStream(); + reqStream.Write(contentreq, 0, contentreq.Length); + reqStream.Close(); + } + + HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse(); + Encoding encoding = Encoding.UTF8; + StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding); + fwdresponsestr = fwdresponsestream.ReadToEnd(); + fwdresponsecontenttype = fwdrsp.ContentType; + fwdresponsecode = (int)fwdrsp.StatusCode; + fwdresponsestream.Close(); + + response["content_type"] = fwdresponsecontenttype; + response["str_response_string"] = fwdresponsestr; + response["int_response_code"] = fwdresponsecode; + + return response; + } + public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) { @@ -468,22 +584,139 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } + public Hashtable FreeSwitchSLVoiceBuddyHTTPHandler(Hashtable request) + { + Hashtable response = new Hashtable(); + response["int_response_code"] = 200; + response["str_response_string"] = string.Empty; + response["content-type"] = "text/xml"; + + Hashtable requestBody = parseRequestBody((string)request["body"]); + + if (!requestBody.ContainsKey("auth_token")) + return response; + + string auth_token = (string)requestBody["auth_token"]; + string[] auth_tokenvals = auth_token.Split(':'); + string username = auth_tokenvals[0]; + int strcount = 0; + + string[] ids = new string[strcount]; + + int iter = -1; + lock (m_UUIDName) + { + strcount = m_UUIDName.Count; + ids = new string[strcount]; + foreach (string s in m_UUIDName.Keys) + { + iter++; + ids[iter] = s; + } + } + StringBuilder resp = new StringBuilder(); + resp.Append(""); + + resp.Append(string.Format(@" + OK + lib_session + {0} + {0} + + ",auth_token)); + /* + lib_session + {0}:{1}:9303959503950:: + {0}:{1}:9303959503950:: + */ + for (int i=0;i + {1} + + sip:{0}@{2} + {0} + {0} + {2} + A + {3} + + ", ids[i],i,m_freeSwitchRealm,dt)); + } + + + + resp.Append(""); + + response["str_response_string"] = resp.ToString(); + Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); + + m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); + return response; + } + public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) { m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called"); - + string requestbody = (string)request["body"]; + string uri = (string)request["uri"]; + string contenttype = (string)request["content-type"]; + + Hashtable requestBody = parseRequestBody((string)request["body"]); + + string pwd = (string) requestBody["pwd"]; + string userid = (string) requestBody["userid"]; + + string avatarName = string.Empty; + int pos = -1; + lock (m_UUIDName) + { + if (m_UUIDName.ContainsKey(userid)) + { + avatarName = m_UUIDName[userid]; + foreach (string s in m_UUIDName.Keys) + { + pos++; + if (s == userid) + break; + + } + } + } + + m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype, + requestbody); Hashtable response = new Hashtable(); - response["str_response_string"] = @" + response["str_response_string"] = string.Format(@" OK 200 + lib_session + {0}:{1}:9303959503950:: + {0}:{1}:9303959503950:: + 1 + {1} + {2} auth successful - "; + ", userid, pos, avatarName); + response["int_response_code"] = 200; return response; + /* + + OKOklib_session + * xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592:: + * xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592:: + * 1 + * 7449 + * Teravus Ousley + */ } @@ -569,5 +802,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return channelUri; } + + private static bool CustomCertificateValidation(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) + { + //if (cert.Subject == "E=root@lindenlab.com, CN=*.vaak.lindenlab.com, O=\"Linden Lab, Inc.\", L=San Francisco, S=California, C=US") + //{ + return true; + //} + + //return false; + } + } + public class MonoCert : ICertificatePolicy + { + #region ICertificatePolicy Members + + public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) + { + return true; + } + + #endregion } } -- cgit v1.1 From c17a12544561de8103e1631c1a23dd225bd39698 Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Sat, 25 Apr 2009 18:58:18 +0000 Subject: Thank you kindly, MCortez for a patch that: The attached patch fixes a few problems that people were having with the Messaging provided by the XmlRpcGroups optional module, namely: * Fixes 2x echo in group messaging * Fixes problems with cross instance, non-neighbor, messaging --- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 36 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 423 +++++++---- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 841 ++++++++++++--------- 3 files changed, 795 insertions(+), 505 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 2a5a319..27cffd6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -146,11 +146,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | GroupPowers.VoteOnProposal; param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); + + + Hashtable respData = XmlRpcCall("groups.createGroup", param); if (respData.Contains("error")) { // UUID is not nullable + return UUID.Zero; } @@ -224,7 +228,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); - if (GroupID != UUID.Zero) + if ((GroupID != null) && (GroupID != UUID.Zero)) { param["GroupID"] = GroupID.ToString(); } @@ -233,6 +237,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } + Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -249,6 +254,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); + Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -264,6 +270,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; + } private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) @@ -294,6 +301,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) { + GroupRecord group = new GroupRecord(); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); group.GroupName = groupProfile["Name"].ToString(); @@ -313,6 +321,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } + public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); @@ -341,6 +350,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["ListInProfile"] = ListInProfile ? "1" : "0"; XmlRpcCall("groups.setAgentGroupInfo", param); + } public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) @@ -352,6 +362,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = groupID.ToString(); XmlRpcCall("groups.addAgentToGroupInvite", param); + } public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) @@ -400,6 +411,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); XmlRpcCall("groups.removeAgentFromGroup", param); + } public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) @@ -422,6 +434,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall("groups.removeAgentFromGroupRole", param); } + public List FindGroups(string search) { Hashtable param = new Hashtable(); @@ -482,6 +495,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } + public List GetAgentGroupMemberships(UUID AgentID) { Hashtable param = new Hashtable(); @@ -529,6 +543,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; + + } public List GetGroupRoles(UUID GroupID) @@ -559,6 +575,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; + } private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) @@ -583,7 +600,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.AllowPublish = ((string)respData["AllowPublish"] == "1"); if (respData["Charter"] != null) { - data.Charter = (string)respData["Charter"]; + data.Charter = (string)respData["Charter"]; } data.FounderID = new UUID((string)respData["FounderID"]); data.GroupID = new UUID((string)respData["GroupID"]); @@ -626,6 +643,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return members; + } public List GetGroupRoleMembers(UUID GroupID) @@ -642,10 +660,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (Hashtable membership in respData.Values) { GroupRoleMembersData data = new GroupRoleMembersData(); - + data.MemberID = new UUID((string)membership["AgentID"]); data.RoleID = new UUID((string)membership["RoleID"]); - + members.Add(data); } } @@ -685,9 +703,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["NoticeID"] = noticeID.ToString(); Hashtable respData = XmlRpcCall("groups.getGroupNotice", param); - - if (!respData.Contains("error")) + + if (respData.Contains("error")) { return null; } @@ -775,7 +793,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable error = new Hashtable(); error.Add("error", "invalid return value"); return error; - } + } private void LogRespDataToConsoleError(Hashtable respData) { @@ -785,15 +803,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); - // object o = respData[key]; - string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) { m_log.ErrorFormat("[GROUPDATA] {0}", line); } + } } + } public class GroupNoticeInfo diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index b1b25aa..b1322ab 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -26,7 +26,6 @@ */ using System; -//using System.Collections; using System.Collections.Generic; using System.Reflection; @@ -47,25 +46,27 @@ using Caps = OpenSim.Framework.Communications.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - public class XmlRpcGroupsMessaging : INonSharedRegionModule + public class XmlRpcGroupsMessaging : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private List m_SceneList = new List(); + private List m_sceneList = new List(); - // must be NonShared for this to work, otherewise we may actually get multiple active clients - private Dictionary m_ActiveClients = new Dictionary(); + private IMessageTransferModule m_msgTransferModule = null; - private IMessageTransferModule m_MsgTransferModule = null; + private IGroupsModule m_groupsModule = null; + + // TODO: Move this off to the xmlrpc server + public Dictionary> m_agentsInGroupSession = new Dictionary>(); + public Dictionary> m_agentsDroppedSession = new Dictionary>(); - private IGroupsModule m_GroupsModule = null; // Config Options - private bool m_GroupMessagingEnabled = true; + private bool m_groupMessagingEnabled = true; private bool m_debugEnabled = true; - #region IRegionModule Members + #region IRegionModuleBase Members public void Initialise(IConfigSource config) { @@ -90,14 +91,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") { m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); - m_GroupMessagingEnabled = false; + m_groupMessagingEnabled = false; return; } - m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); + m_groupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); - if (!m_GroupMessagingEnabled) + if (!m_groupMessagingEnabled) { m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); return; @@ -113,76 +114,74 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { + // NoOp } public void RegionLoaded(Scene scene) { - if (!m_GroupMessagingEnabled) + if (!m_groupMessagingEnabled) return; - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_GroupsModule = scene.RequestModuleInterface(); + m_groupsModule = scene.RequestModuleInterface(); // No groups module, no groups messaging - if (m_GroupsModule == null) + if (m_groupsModule == null) { - m_GroupMessagingEnabled = false; - m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); + m_groupMessagingEnabled = false; + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); Close(); return; } - m_MsgTransferModule = scene.RequestModuleInterface(); + m_msgTransferModule = scene.RequestModuleInterface(); // No message transfer module, no groups messaging - if (m_MsgTransferModule == null) + if (m_msgTransferModule == null) { - m_GroupMessagingEnabled = false; - m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); + m_groupMessagingEnabled = false; + m_log.Error("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); Close(); return; } - m_SceneList.Add(scene); + m_sceneList.Add(scene); scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnClientClosed += OnClientClosed; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; } public void RemoveRegion(Scene scene) { - if (!m_GroupMessagingEnabled) + if (!m_groupMessagingEnabled) return; - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_SceneList.Remove(scene); + m_sceneList.Remove(scene); } public void Close() { - if (!m_GroupMessagingEnabled) + if (!m_groupMessagingEnabled) return; - m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); - + if(m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); - foreach (Scene scene in m_SceneList) + foreach (Scene scene in m_sceneList) { scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnClientClosed -= OnClientClosed; scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; } - m_SceneList.Clear(); + m_sceneList.Clear(); - m_GroupsModule = null; - m_MsgTransferModule = null; + m_groupsModule = null; + m_msgTransferModule = null; } public string Name @@ -192,195 +191,293 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - #region SimGridEventHandlers + #region ISharedRegionModule Members - private void OnNewClient(IClientAPI client) + public void PostInitialise() { - RegisterClientAgent(client); + // NoOp } - private void OnClientClosed(UUID AgentId) + + #endregion + + #region SimGridEventHandlers + + private void OnNewClient(IClientAPI client) { - UnregisterClientAgent(AgentId); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); + + client.OnInstantMessage += OnInstantMessage; } private void OnGridInstantMessage(GridInstantMessage msg) { - m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // The instant message module will only deliver messages of dialog types: + // MessageFromAgent, StartTyping, StopTyping, MessageFromObject + // + // Any other message type will not be delivered to a client by the + // Instant Message Module + + + if (m_debugEnabled) + { + m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); DebugGridInstantMessage(msg); + } // Incoming message from a group - if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true)) + if ((msg.fromGroup == true) && + ( (msg.dialog == (byte)InstantMessageDialog.SessionSend) + || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) + || (msg.dialog == (byte)InstantMessageDialog.SessionDrop) + )) + { + ProcessMessageFromGroupSession(msg); + } + + } + + private void ProcessMessageFromGroupSession(GridInstantMessage msg) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + + switch (msg.dialog) + { + case (byte)InstantMessageDialog.SessionAdd: + AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); + break; + + case (byte)InstantMessageDialog.SessionDrop: + RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); + break; + + case (byte)InstantMessageDialog.SessionSend: + if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) + && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnGridInstantMessage from group session {0} going to agent {1}", msg.fromAgentID, msg.toAgentID); + // Agent not in session and hasn't dropped from session + // Add them to the session for now, and Invite them + AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); - if (m_ActiveClients.ContainsKey(msg.toAgentID)) + UUID toAgentID = new UUID(msg.toAgentID); + IClientAPI activeClient = GetActiveClient(toAgentID); + if (activeClient != null) { - UUID GroupID = new UUID(msg.fromAgentID); - // SendMessageToGroup(im); + UUID groupID = new UUID(msg.fromAgentID); - GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); - if (GroupInfo != null) + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + if (groupInfo != null) { - // TODO: Check to see if already a member of session, if so, do not send chatterbox, just forward message - - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); // Force? open the group session dialog??? - IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface(); + IEventQueue eq = activeClient.Scene.RequestModuleInterface(); eq.ChatterboxInvitation( - GroupID, - GroupInfo.GroupName, - new UUID(msg.fromAgentID), - msg.message, new UUID(msg.toAgentID), - msg.fromAgentName, - msg.dialog, - msg.timestamp, - msg.offline == 1, - (int)msg.ParentEstateID, - msg.Position, - 1, - new UUID(msg.imSessionID), - msg.fromGroup, - Utils.StringToBytes(GroupInfo.GroupName)); + groupID + , groupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message, new UUID(msg.toAgentID) + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline == 1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(groupInfo.GroupName) + ); eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID), - new UUID(msg.fromAgentID), - new UUID(msg.toAgentID), - false, //canVoiceChat - false, //isModerator - false); //text mute + new UUID(groupID) + , new UUID(msg.fromAgentID) + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + } } } + else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + { + // User hasn't dropped, so they're in the session, + // maybe we should deliver it. + IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); + if (client != null) + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} locally", client.Name); + client.SendInstantMessage(msg); + } + else + { + m_log.WarnFormat("[GROUPS-MESSAGING] Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); + } + } + break; + default: + m_log.WarnFormat("[GROUPS-MESSAGING] I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); + break; + } } + + #endregion #region ClientEvents - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - DebugGridInstantMessage(im); - // Start group IM session - if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) + private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) + { + if( m_agentsInGroupSession.ContainsKey(sessionID) ) { - UUID GroupID = new UUID(im.toAgentID); - - GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); - if (GroupInfo != null) + // If in session remove + if( m_agentsInGroupSession[sessionID].Contains(agentID) ) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName); - - // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0])); - - ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID); + m_agentsInGroupSession[sessionID].Remove(agentID); + } - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - queue.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID), - new UUID(im.fromAgentID), - new UUID(im.toAgentID), - false, //canVoiceChat - false, //isModerator - false); //text mute + // If not in dropped list, add + if( !m_agentsDroppedSession[sessionID].Contains(agentID) ) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Dropped {1} from session {0}", sessionID, agentID); + m_agentsDroppedSession[sessionID].Add(agentID); } } + } - // Send a message to a group - if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) - { - UUID GroupID = new UUID(im.toAgentID); + private void AddAgentToGroupSession(Guid agentID, Guid sessionID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupSessionTracking(sessionID); - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID); + // If nessesary, remove from dropped list + if( m_agentsDroppedSession[sessionID].Contains(agentID) ) + { + m_agentsDroppedSession[sessionID].Remove(agentID); + } - SendMessageToGroup(im, GroupID); + // If nessesary, add to in session list + if( !m_agentsInGroupSession[sessionID].Contains(agentID) ) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Added {1} to session {0}", sessionID, agentID); + m_agentsInGroupSession[sessionID].Add(agentID); } + } - // Incoming message from a group - if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true)) + private void CreateGroupSessionTracking(Guid sessionID) + { + if (!m_agentsInGroupSession.ContainsKey(sessionID)) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Creating session tracking for : {0}", sessionID); + m_agentsInGroupSession.Add(sessionID, new List()); + m_agentsDroppedSession.Add(sessionID, new List()); } } - #endregion - private void RegisterClientAgent(IClientAPI client) + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + { + m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - lock (m_ActiveClients) + DebugGridInstantMessage(im); + } + + // Start group IM session + if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { - if (!m_ActiveClients.ContainsKey(client.AgentId.Guid)) + UUID groupID = new UUID(im.toAgentID); + + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + if (groupInfo != null) { - client.OnInstantMessage += OnInstantMessage; + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Start Group Session for {0}", groupInfo.GroupName); - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); + AddAgentToGroupSession(im.fromAgentID, im.imSessionID); - m_ActiveClients.Add(client.AgentId.Guid, client); - } - else - { - // Remove old client connection for this agent - UnregisterClientAgent(client.AgentId); + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); - // Add new client connection - RegisterClientAgent(client); + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + queue.ChatterBoxSessionAgentListUpdates( + new UUID(groupID) + , new UUID(im.fromAgentID) + , new UUID(im.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); } } - } - private void UnregisterClientAgent(UUID agentID) - { - lock (m_ActiveClients) + + // Send a message from locally connected client to a group + if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) { - if (m_ActiveClients.ContainsKey(agentID.Guid)) - { - IClientAPI client = m_ActiveClients[agentID.Guid]; - client.OnInstantMessage -= OnInstantMessage; + UUID groupID = new UUID(im.toAgentID); - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); - m_ActiveClients.Remove(agentID.Guid); - } - else - { - m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here."); - } + SendMessageToGroup(im, groupID); } } + #endregion private void SendMessageToGroup(GridInstantMessage im, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) + { + if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + { + // Don't deliver messages to people who have dropped this session + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} has dropped session, not delivering to them", member.AgentID); + continue; + } + + // Copy Message GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = im.imSessionID; - msg.fromAgentID = im.imSessionID; // GroupID - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = im.fromAgentName; msg.message = im.message; msg.dialog = im.dialog; - msg.fromGroup = true; - msg.offline = (byte)0; + msg.offline = im.offline; msg.ParentEstateID = im.ParentEstateID; msg.Position = im.Position; msg.RegionID = im.RegionID; - msg.binaryBucket = new byte[1]{0}; + msg.binaryBucket = im.binaryBucket; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + + // Updat Pertinate fields to make it a "group message" + msg.fromAgentID = groupID.Guid; + msg.fromGroup = true; - foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID)) - { msg.toAgentID = member.AgentID.Guid; - m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) {}); + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg); + } } } void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); OSDMap moderatedMap = new OSDMap(4); moderatedMap.Add("voice", OSD.FromBoolean(false)); @@ -398,12 +495,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bodyMap.Add("success", OSD.FromBoolean(true)); bodyMap.Add("session_info", sessionMap); + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); } + } @@ -422,5 +521,39 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); } } + + #region Client Tools + + /// + /// Try to find an active IClientAPI reference for agentID giving preference to root connections + /// + private IClientAPI GetActiveClient(UUID agentID) + { + IClientAPI child = null; + + // Try root avatar first + foreach (Scene scene in m_sceneList) + { + if (scene.Entities.ContainsKey(agentID) && + scene.Entities[agentID] is ScenePresence) + { + ScenePresence user = (ScenePresence)scene.Entities[agentID]; + if (!user.IsChildAgent) + { + return user.ControllingClient; + } + else + { + child = user.ControllingClient; + } + } + } + + // If we didn't find a root, then just return whichever child we found, or null if none + return child; + } + + #endregion } + } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 69c7258..d5cd7e2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Reflection; using System.Collections; -//using Nwc.XmlRpc; using log4net; using Nini.Config; @@ -39,6 +38,7 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; +using OpenSim.Framework.Communications; using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -50,7 +50,7 @@ using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - public class XmlRpcGroupsModule : INonSharedRegionModule, IGroupsModule + public class XmlRpcGroupsModule : ISharedRegionModule, IGroupsModule { /// /// ; To use this module, you must specify the following in your OpenSim.ini @@ -75,11 +75,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private List m_sceneList = new List(); - // This only works when running as non-Shared, in shared, there may be multiple IClientAPIs for a single client - private Dictionary m_activeClients = new Dictionary(); - private IMessageTransferModule m_msgTransferModule = null; - + private IGroupDataProvider m_groupData = null; // Configuration settings @@ -88,7 +85,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_groupNoticesEnabled = true; private bool m_debugEnabled = true; - #region IRegionModule Members + #region IRegionModuleBase Members public void Initialise(IConfigSource config) { @@ -142,24 +139,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupsEnabled) return; - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_msgTransferModule = scene.RequestModuleInterface(); - - // No message transfer module, no notices, group invites, rejects, ejects, etc if (m_msgTransferModule == null) { - m_groupsEnabled = false; - m_log.Info("[GROUPS]: Could not get MessageTransferModule"); - Close(); - return; + m_msgTransferModule = scene.RequestModuleInterface(); + + // No message transfer module, no notices, group invites, rejects, ejects, etc + if (m_msgTransferModule == null) + { + m_groupsEnabled = false; + m_log.Error("[GROUPS]: Could not get MessageTransferModule"); + Close(); + return; + } } - m_sceneList.Add(scene); + lock (m_sceneList) + { + m_sceneList.Add(scene); + } scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnClientClosed += OnClientClosed; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + + // The InstantMessageModule itself doesn't do this, + // so lets see if things explode if we don't do it + // scene.EventManager.OnClientClosed += OnClientClosed; + } public void RemoveRegion(Scene scene) @@ -167,117 +174,117 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupsEnabled) return; - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_sceneList.Remove(scene); + lock (m_sceneList) + { + m_sceneList.Remove(scene); + } } public void Close() { if (!m_groupsEnabled) return; - m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); + + if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); } public string Name { get { return "XmlRpcGroupsModule"; } } + #endregion - private void UpdateAllClientsWithGroupInfo() - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - foreach (IClientAPI client in m_activeClients.Values) - { - UpdateClientWithGroupInfo(client); - } - } + #region ISharedRegionModule Members - private void UpdateClientWithGroupInfo(IClientAPI client) + public void PostInitialise() { - m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); - OnAgentDataUpdateRequest(client, client.AgentId, UUID.Zero); - - - // Need to send a group membership update to the client - // UDP version doesn't seem to behave nicely - // client.SendGroupMembership(GetMembershipData(client.AgentId)); - - GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(client.AgentId).ToArray(); - - SendGroupMembershipInfoViaCaps(client, membershipData); - client.SendAvatarGroupsReply(client.AgentId, membershipData); - + // NoOp } + #endregion + #region EventHandlers private void OnNewClient(IClientAPI client) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - lock (m_activeClients) - { - if (!m_activeClients.ContainsKey(client.AgentId)) - { - client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; - client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; - client.OnDirFindQuery += OnDirFindQuery; - client.OnInstantMessage += OnInstantMessage; + client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; + client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; + client.OnDirFindQuery += OnDirFindQuery; + client.OnRequestAvatarProperties += OnRequestAvatarProperties; - m_activeClients.Add(client.AgentId, client); - } - } + // Used for Notices and Group Invites/Accept/Reject + client.OnInstantMessage += OnInstantMessage; + + SendAgentGroupDataUpdate(client, client.AgentId); + } - UpdateClientWithGroupInfo(client); + private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) + { + GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(avatarID).ToArray(); + remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } - private void OnClientClosed(UUID agentId) + /* + * This becomes very problematic in a shared module. In a shared module you may have more then one + * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections. + * The OnClientClosed event does not provide anything to indicate which one of those should be closed + * nor does it provide what scene it was from so that the specific reference can be looked up. + * The InstantMessageModule.cs does not currently worry about unregistering the handles, + * and it should be an issue, since it's the client that references us not the other way around + * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed + private void OnClientClosed(UUID AgentId) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - lock (m_activeClients) + lock (m_ActiveClients) { - if (m_activeClients.ContainsKey(agentId)) + if (m_ActiveClients.ContainsKey(AgentId)) { - IClientAPI client = m_activeClients[agentId]; + IClientAPI client = m_ActiveClients[AgentId]; client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; client.OnDirFindQuery -= OnDirFindQuery; client.OnInstantMessage -= OnInstantMessage; - m_activeClients.Remove(agentId); + m_ActiveClients.Remove(AgentId); } else { - m_log.InfoFormat("[GROUPS] Client closed that wasn't registered here."); + if (m_debugEnabled) m_log.WarnFormat("[GROUPS] Client closed that wasn't registered here."); } + + } } + */ void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) { if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { - m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", - System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + // TODO: This currently ignores pretty much all the query flags including Mature and sort order remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); } + } - private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID agentID, UUID sessionID) + private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) { - m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, sessionID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); UUID activeGroupID = UUID.Zero; string activeGroupTitle = string.Empty; string activeGroupName = string.Empty; ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(dataForAgentID); if (membership != null) { activeGroupID = membership.GroupID; @@ -285,59 +292,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups activeGroupPowers = membership.GroupPowers; } - string firstname, lastname; - IClientAPI agent; - if (m_activeClients.TryGetValue(agentID, out agent)) - { - firstname = agent.FirstName; - lastname = agent.LastName; - } else { - firstname = "Unknown"; - lastname = "Unknown"; - } - - UpdateScenePresenceWithTitle(agentID, activeGroupTitle); + SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle); - remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname, - lastname, activeGroupPowers, activeGroupName, - activeGroupTitle); + SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID groupID, IClientAPI remoteClient) + private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - string groupName; + string GroupName; - GroupRecord group = m_groupData.GetGroupRecord(groupID, null); + GroupRecord group = m_groupData.GetGroupRecord(GroupID, null); if (group != null) { - groupName = group.GroupName; + GroupName = group.GroupName; } else { - groupName = "Unknown"; + GroupName = "Unknown"; } - remoteClient.SendGroupNameReply(groupID, groupName); + + remote_client.SendGroupNameReply(GroupID, GroupName); } private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Group invitations - if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || - (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) + if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { - m_log.WarnFormat("[GROUPS] Received an IIM for {0}.", ((InstantMessageDialog)im.dialog).ToString()); - UUID inviteID = new UUID(im.imSessionID); GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); - m_log.WarnFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); UUID fromAgentID = new UUID(im.fromAgentID); if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) @@ -346,32 +338,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Accept if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) { - m_log.WarnFormat("[GROUPS] Received an accept invite notice."); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Received an accept invite notice."); // and the sessionid is the role m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); - if (m_msgTransferModule != null) - { - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = UUID.Zero.Guid; - msg.toAgentID = inviteInfo.AgentID.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Groups"; - msg.message = string.Format("You have been added to the group."); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = new byte[0]; - - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = UUID.Zero.Guid; + msg.toAgentID = inviteInfo.AgentID.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Groups"; + msg.message = string.Format("You have been added to the group."); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = new byte[0]; + + OutgoingInstantMessage(msg, inviteInfo.AgentID); - UpdateAllClientsWithGroupInfo(); + UpdateAllClientsWithGroupInfo(inviteInfo.AgentID); + + // TODO: If the inviter is still online, they need an agent dataupdate + // and maybe group membership updates for the invitee m_groupData.RemoveAgentToGroupInvite(inviteID); } @@ -379,10 +371,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { - m_log.WarnFormat("[GROUPS] Received a reject invite notice."); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Received a reject invite notice."); m_groupData.RemoveAgentToGroupInvite(inviteID); } + + } } @@ -394,12 +388,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - UUID groupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(groupID, null) != null) + UUID GroupID = new UUID(im.toAgentID); + if (m_groupData.GetGroupRecord(GroupID, null) != null) { - UUID noticeID = UUID.Random(); - string subject = im.message.Substring(0, im.message.IndexOf('|')); - string message = im.message.Substring(subject.Length + 1); + UUID NoticeID = UUID.Random(); + string Subject = im.message.Substring(0, im.message.IndexOf('|')); + string Message = im.message.Substring(Subject.Length + 1); byte[] bucket; @@ -408,50 +402,56 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket = new byte[19]; bucket[0] = 0; //dunno bucket[1] = 0; //dunno - groupID.ToBytes(bucket, 2); + GroupID.ToBytes(bucket, 2); bucket[18] = 0; //dunno } else { string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); binBucket = binBucket.Remove(0, 14).Trim(); - m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); - - OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); - - foreach (string key in binBucketOSD.Keys) + if (m_debugEnabled) { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); - } + m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); + + OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + + foreach (string key in binBucketOSD.Keys) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } + } // treat as if no attachment bucket = new byte[19]; bucket[0] = 0; //dunno bucket[1] = 0; //dunno - groupID.ToBytes(bucket, 2); + GroupID.ToBytes(bucket, 2); bucket[18] = 0; //dunno } - m_groupData.AddGroupNotice(groupID, noticeID, im.fromAgentName, subject, message, bucket); + m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { - OnNewGroupNotice(groupID, noticeID); + OnNewGroupNotice(GroupID, NoticeID); } // Build notice IIM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, noticeID, - (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(groupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GroupID)) { if (member.AcceptNotices) { msg.toAgentID = member.AgentID.Guid; - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) {}); + OutgoingInstantMessage(msg, member.AgentID); + } } + + + } } @@ -460,24 +460,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO:FIXME: Use a presense server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue - if (im.dialog == 210) + if ((im.dialog == 210)) { // This is sent from the region that the ejectee was ejected from // if it's being delivered here, then the ejectee is here // so we need to send local updates to the agent. - if (m_msgTransferModule != null) - { - im.dialog = (byte)InstantMessageDialog.MessageFromAgent; - m_msgTransferModule.SendInstantMessage(im, delegate(bool success) {}); - } UUID ejecteeID = new UUID(im.toAgentID); - UUID groupID = new UUID(im.toAgentID); - if (m_activeClients.ContainsKey(ejecteeID)) + + im.dialog = (byte)InstantMessageDialog.MessageFromAgent; + OutgoingInstantMessage(im, ejecteeID); + + IClientAPI ejectee = GetActiveClient(ejecteeID); + if (ejectee != null) { - m_activeClients[ejecteeID].SendAgentDropGroup(groupID); + UUID groupID = new UUID(im.fromAgentID); + ejectee.SendAgentDropGroup(groupID); } + } + + + } private void OnGridInstantMessage(GridInstantMessage msg) @@ -487,6 +491,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Trigger the above event handler OnInstantMessage(null, msg); + // If a message from a group arrives here, it may need to be forwarded to a local client if (msg.fromGroup == true) { @@ -495,56 +500,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case (byte)InstantMessageDialog.GroupInvitation: case (byte)InstantMessageDialog.GroupNotice: UUID toAgentID = new UUID(msg.toAgentID); - if (m_activeClients.ContainsKey(toAgentID)) + IClientAPI localClient = GetActiveClient(toAgentID); + if( localClient != null ) { - m_activeClients[toAgentID].SendInstantMessage(msg); + localClient.SendInstantMessage(msg); } break; } } } - #endregion - private void UpdateScenePresenceWithTitle(UUID agentID, string title) - { - m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", agentID, title); - - ScenePresence presence = null; - lock (m_sceneList) - { - foreach (Scene scene in m_sceneList) - { - presence = scene.GetScenePresence(agentID); - if (presence != null) - { - presence.Grouptitle = title; - - // FixMe: Ter suggests a "Schedule" method that I can't find. - presence.SendFullUpdateToAllClients(); - } - } - } - } + #endregion #region IGroupsModule Members public event NewGroupNotice OnNewGroupNotice; - public GroupRecord GetGroupRecord(UUID groupID) + public GroupRecord GetGroupRecord(UUID GroupID) { - return m_groupData.GetGroupRecord(groupID, null); + return m_groupData.GetGroupRecord(GroupID, null); } public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); - // UpdateClientWithGroupInfo(remoteClient); - UpdateAllClientsWithGroupInfo(); + // Changing active group changes title, active powers, all kinds of things + // anyone who is in any region that can see this client, should probably be + // updated with new group info. At a minimum, they should get ScenePresence + // updated with new title. + UpdateAllClientsWithGroupInfo(remoteClient.AgentId); } /// @@ -552,7 +541,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); @@ -576,49 +565,61 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupMembers(groupID); - - foreach (GroupMembersData member in data) + if (m_debugEnabled) { - m_log.InfoFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); + } } return data; + } public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupRoles(groupID); - foreach (GroupRolesData member in data) + if (m_debugEnabled) { - m_log.InfoFormat("[GROUPS] {0} {1}", member.Title, member.Members); + foreach (GroupRolesData member in data) + { + m_log.DebugFormat("[GROUPS] {0} {1}", member.Title, member.Members); + } } return data; + } public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupRoleMembers(groupID); - foreach (GroupRoleMembersData member in data) + if (m_debugEnabled) { - m_log.InfoFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); + } } - + return data; + + } public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupProfileData profile = new GroupProfileData(); @@ -651,45 +652,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return profile; } - public GroupMembershipData[] GetMembershipData(UUID userID) + public GroupMembershipData[] GetMembershipData(UUID agentID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(userID).ToArray(); + return m_groupData.GetAgentGroupMemberships(agentID).ToArray(); } - public GroupMembershipData GetMembershipData(UUID groupID, UUID userID) + public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMembership(userID, groupID); + return m_groupData.GetAgentGroupMembership(agentID, groupID); } - public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, - bool showInList, UUID insigniaID, int membershipFee, - bool openEnrollment, bool allowPublish, bool maturePublish) + public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: Security Check? - m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, - openEnrollment, allowPublish, maturePublish); + m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) { // TODO: Security Check? - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); } - public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, - bool showInList, UUID insigniaID, int membershipFee, - bool openEnrollment, bool allowPublish, bool maturePublish) + public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_groupData.GetGroupRecord(UUID.Zero, name) != null) { @@ -697,19 +693,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Zero; } - UUID groupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, - openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + UUID groupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); - UpdateClientWithGroupInfo(remoteClient); + // Update the founder with new group information. + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); return groupID; } public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // ToDo: check if agent is a member of group and is allowed to see notices? @@ -721,7 +717,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// public string GetGroupTitle(UUID avatarID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); if (membership != null) @@ -736,18 +732,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, groupID, titleRoleID); - UpdateAllClientsWithGroupInfo(); + // TODO: Not sure what all is needed here, but if the active group role change is for the group + // the client currently has set active, then we need to do a scene presence update too + // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) + + UpdateAllClientsWithGroupInfo(remoteClient.AgentId); } - public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, - string name, string description, string title, ulong powers, byte updateType) + public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: Security Checks? @@ -774,12 +773,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - UpdateClientWithGroupInfo(remoteClient); + // TODO: This update really should send out updates for everyone in the role that just got changed. + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check switch (changes) @@ -798,44 +798,45 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); break; } - UpdateClientWithGroupInfo(remoteClient); + + // TODO: This update really should send out updates for everyone in the role that just got changed. + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); if (data != null) { - if (m_msgTransferModule != null) - { - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Group Notice From"; - msg.message = data.noticeData.Subject + "|" + data.Message; - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = data.BinaryBucket; - - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } + GroupRecord groupInfo = m_groupData.GetGroupRecord(data.GroupID, null); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = data.GroupID.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; + msg.message = data.noticeData.Subject + "|" + data.Message; + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = data.BinaryBucket; + + OutgoingInstantMessage(msg, remoteClient.AgentId); } } public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) { - m_log.WarnFormat("[GROUPS] {0} is probably not properly implemented", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -857,32 +858,43 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.message = info.noticeData.Subject + "|" + info.Message; msg.binaryBucket = info.BinaryBucket; } + else + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Group Notice {0} not found, composing empty message.", groupNoticeID); + msg.fromAgentID = UUID.Zero.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; + msg.fromAgentName = string.Empty; + msg.message = string.Empty; + msg.binaryBucket = new byte[0]; + } return msg; } public void SendAgentGroupDataUpdate(IClientAPI remoteClient) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - UpdateClientWithGroupInfo(remoteClient); + // Send agent information about his groups + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); remoteClient.SendJoinGroupReply(groupID, true); - UpdateClientWithGroupInfo(remoteClient); + // Should this send updates to everyone in the group? + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, groupID); @@ -890,107 +902,97 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendAgentDropGroup(groupID); - UpdateClientWithGroupInfo(remoteClient); + // SL sends out notifcations to the group messaging session that the person has left + // Should this also update everyone who is in the group? + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check? m_groupData.RemoveAgentFromGroup(ejecteeID, groupID); remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); - if (m_msgTransferModule != null) - { - GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); - if ((groupInfo == null) || (userProfile == null)) - { - return; - } - + if ((groupInfo == null) || (userProfile == null)) + { + return; + } + - // Send Message to Ejectee - GridInstantMessage msg = new GridInstantMessage(); - - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - // msg.fromAgentID = info.GroupID; - msg.toAgentID = ejecteeID.Guid; - //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[0]; - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) - { - m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", - success,ToString()); - }); + // Send Message to Ejectee + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = info.GroupID; + msg.toAgentID = ejecteeID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + OutgoingInstantMessage(msg, ejecteeID); - // Message to ejector - // Interop, received special 210 code for ejecting a group member - // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the - // client actually is, and try contacting that region directly to notify them, - // or provide the notification via xmlrpc update queue + // Message to ejector + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presense server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue - msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - if (userProfile != null) - { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", - remoteClient.Name, groupInfo.GroupName, userProfile.Name); - } - else - { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", - remoteClient.Name, groupInfo.GroupName, "Unknown member"); - } - msg.dialog = (byte)210; //interop - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[0]; - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) - { - m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", - success, ToString()); - }); + msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + if (userProfile != null) + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); } + else + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); + } + msg.dialog = (byte)210; //interop + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + OutgoingInstantMessage(msg, remoteClient.AgentId); - UpdateAllClientsWithGroupInfo(); + + // SL sends out messages to everyone in the group + // Who all should receive updates and what should they be updated with? + UpdateAllClientsWithGroupInfo(ejecteeID); } public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", groupID, invitedAgentID, roleID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check, probably also want to send some kind of notification - UUID inviteID = UUID.Random(); - m_log.WarnFormat("[GROUPS] Invite ID: {0}", inviteID); - m_groupData.AddAgentToGroupInvite(inviteID, groupID, roleID, invitedAgentID); + UUID InviteID = UUID.Random(); + m_groupData.AddAgentToGroupInvite(InviteID, groupID, roleID, invitedAgentID); if (m_msgTransferModule != null) { - Guid inviteUUID = inviteID.Guid; + Guid inviteUUID = InviteID.Guid; GridInstantMessage msg = new GridInstantMessage(); @@ -1002,8 +1004,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", - remoteClient.Name); + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; msg.fromGroup = true; msg.offline = (byte)0; @@ -1011,60 +1012,198 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[20]; - - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) - { - m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); - }); + + OutgoingInstantMessage(msg, invitedAgentID); } } #endregion - void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, GroupMembershipData[] data) + #region Client/Update Tools + + /// + /// Try to find an active IClientAPI reference for agentID giving preference to root connections + /// + private IClientAPI GetActiveClient(UUID agentID) + { + IClientAPI child = null; + + // Try root avatar first + foreach (Scene scene in m_sceneList) + { + if (scene.Entities.ContainsKey(agentID) && + scene.Entities[agentID] is ScenePresence) + { + ScenePresence user = (ScenePresence)scene.Entities[agentID]; + if (!user.IsChildAgent) + { + return user.ControllingClient; + } + else + { + child = user.ControllingClient; + } + } + } + + // If we didn't find a root, then just return whichever child we found, or null if none + return child; + } + + /// + /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. + /// + private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - OSDArray agentData = new OSDArray(1); - OSDMap agentDataMap = new OSDMap(1); - agentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId)); - agentData.Add(agentDataMap); + OSDArray AgentData = new OSDArray(1); + OSDMap AgentDataMap = new OSDMap(1); + AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); + AgentData.Add(AgentDataMap); - OSDArray groupData = new OSDArray(data.Length); - OSDArray newGroupData = new OSDArray(data.Length); + OSDArray GroupData = new OSDArray(data.Length); + OSDArray NewGroupData = new OSDArray(data.Length); foreach (GroupMembershipData membership in data) { - OSDMap groupDataMap = new OSDMap(6); - OSDMap newGroupDataMap = new OSDMap(1); - - groupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); - groupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); - groupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); - groupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); - groupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); - groupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); - newGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); - - groupData.Add(groupDataMap); - newGroupData.Add(newGroupDataMap); + OSDMap GroupDataMap = new OSDMap(6); + OSDMap NewGroupDataMap = new OSDMap(1); + + GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); + GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); + GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); + GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); + GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); + GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); + NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); + + GroupData.Add(GroupDataMap); + NewGroupData.Add(NewGroupDataMap); } OSDMap llDataStruct = new OSDMap(3); - llDataStruct.Add("AgentData", agentData); - llDataStruct.Add("GroupData", groupData); - llDataStruct.Add("NewGroupData", newGroupData); + llDataStruct.Add("AgentData", AgentData); + llDataStruct.Add("GroupData", GroupData); + llDataStruct.Add("NewGroupData", NewGroupData); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), - remoteClient.AgentId); + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); } } + + private void SendScenePresenceUpdate(UUID AgentID, string Title) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title); + + ScenePresence presence = null; + lock (m_sceneList) + { + foreach (Scene scene in m_sceneList) + { + presence = scene.GetScenePresence(AgentID); + if (presence != null) + { + presence.Grouptitle = Title; + + // FixMe: Ter suggests a "Schedule" method that I can't find. + presence.SendFullUpdateToAllClients(); + } + } + } + } + + /// + /// Send updates to all clients who might be interested in groups data for dataForClientID + /// + private void UpdateAllClientsWithGroupInfo(UUID dataForClientID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Probably isn't nessesary to update every client in every scene. + // Need to examine client updates and do only what's nessesary. + lock (m_sceneList) + { + foreach (Scene scene in m_sceneList) + { + scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); }); + } + } + } + + /// + /// Update remoteClient with group information about dataForAgentID + /// + private void SendAgentGroupDataUpdate(IClientAPI client, UUID dataForAgentID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); + + // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff + + OnAgentDataUpdateRequest(client, dataForAgentID, UUID.Zero); + + + // Need to send a group membership update to the client + // UDP version doesn't seem to behave nicely + // client.SendGroupMembership(GetMembershipData(client.AgentId)); + + GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(dataForAgentID).ToArray(); + + SendGroupMembershipInfoViaCaps(client, dataForAgentID, membershipData); + client.SendAvatarGroupsReply(dataForAgentID, membershipData); + + } + + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); + string firstname, lastname; + if (userProfile != null) + { + firstname = userProfile.FirstName; + lastname = userProfile.SurName; + } + else + { + firstname = "Unknown"; + lastname = "Unknown"; + } + + remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, + lastname, activeGroupPowers, activeGroupName, + activeGroupTitle); + } + + #endregion + + #region IM Backed Processes + + private void OutgoingInstantMessage(GridInstantMessage msg, UUID msgTo) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + IClientAPI localClient = GetActiveClient(msgTo); + if (localClient != null) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] MsgTo ({0}) is local, delivering directly", localClient.Name); + localClient.SendInstantMessage(msg); + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS] MsgTo ({0}) is not local, delivering via TransferModule", msgTo); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Message Sent: {0}", success?"Succeeded":"Failed"); }); + } + } + + #endregion } } -- cgit v1.1 From 647368f53f58dcda9885a9d4ac656fcf0fc3b99e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 26 Apr 2009 18:19:14 +0000 Subject: Thank you, mcortez, for a patch to fix group notice delivery --- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index d5cd7e2..eb9f804 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -436,14 +436,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OnNewGroupNotice(GroupID, NoticeID); } - // Build notice IIM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); - // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GroupID)) { if (member.AcceptNotices) { + // Build notice IIM + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + msg.toAgentID = member.AgentID.Guid; OutgoingInstantMessage(msg, member.AgentID); -- cgit v1.1 From ac3154e6b7b83a8f1f5e27ac561af6105bb2c238 Mon Sep 17 00:00:00 2001 From: Homer Horwitz Date: Sun, 26 Apr 2009 18:26:01 +0000 Subject: - Setting groups-messaging module to by disabled by default (groups module already is). - Make sure it really is Close()d when the configuration isn't sane. --- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index b1322ab..2dbe237 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Config Options - private bool m_groupMessagingEnabled = true; + private bool m_groupMessagingEnabled = false; private bool m_debugEnabled = true; #region IRegionModuleBase Members @@ -129,9 +129,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // No groups module, no groups messaging if (m_groupsModule == null) { - m_groupMessagingEnabled = false; m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); Close(); + m_groupMessagingEnabled = false; return; } @@ -140,9 +140,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // No message transfer module, no groups messaging if (m_msgTransferModule == null) { - m_groupMessagingEnabled = false; m_log.Error("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); Close(); + m_groupMessagingEnabled = false; return; } -- cgit v1.1 From 8dbcfc70bf87d503edd4239bd974339a130de153 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Mon, 27 Apr 2009 05:22:44 +0000 Subject: Add copyright headers. Formatting cleanup. --- .../OptionalModules/Avatar/Chat/IRCConnector.cs | 8 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 143 ++++++++++----------- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 61 +++------ 3 files changed, 90 insertions(+), 122 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index eb6634d..ce8917b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -259,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat Connect(); } - lock(m_connectors) + lock (m_connectors) m_connectors.Add(this); m_enabled = true; @@ -306,8 +306,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } - lock(m_connectors) - m_connectors.Remove(this); + lock (m_connectors) + m_connectors.Remove(this); } } @@ -845,7 +845,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger _icc_++; // increment the inter-consecutive-connect-delay counter - lock(m_connectors) + lock (m_connectors) foreach (IRCConnector connector in m_connectors) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 2dbe237..16dd0b6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -105,7 +105,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); - } m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up"); @@ -123,7 +122,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupsModule = scene.RequestModuleInterface(); // No groups module, no groups messaging @@ -164,13 +162,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_sceneList.Remove(scene); } - public void Close() { if (!m_groupMessagingEnabled) return; - if(m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); + if (m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); foreach (Scene scene in m_sceneList) { @@ -222,19 +219,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - DebugGridInstantMessage(msg); + DebugGridInstantMessage(msg); } // Incoming message from a group if ((msg.fromGroup == true) && - ( (msg.dialog == (byte)InstantMessageDialog.SessionSend) - || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) - || (msg.dialog == (byte)InstantMessageDialog.SessionDrop) - )) + ((msg.dialog == (byte)InstantMessageDialog.SessionSend) + || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) + || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) { ProcessMessageFromGroupSession(msg); } - } private void ProcessMessageFromGroupSession(GridInstantMessage msg) @@ -254,53 +249,52 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case (byte)InstantMessageDialog.SessionSend: if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) - { + { // Agent not in session and hasn't dropped from session // Add them to the session for now, and Invite them AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); - UUID toAgentID = new UUID(msg.toAgentID); - IClientAPI activeClient = GetActiveClient(toAgentID); - if (activeClient != null) - { - UUID groupID = new UUID(msg.fromAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); - if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); - - // Force? open the group session dialog??? - IEventQueue eq = activeClient.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( - groupID - , groupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp + UUID toAgentID = new UUID(msg.toAgentID); + IClientAPI activeClient = GetActiveClient(toAgentID); + if (activeClient != null) + { + UUID groupID = new UUID(msg.fromAgentID); + + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + if (groupInfo != null) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); + + // Force? open the group session dialog??? + IEventQueue eq = activeClient.Scene.RequestModuleInterface(); + eq.ChatterboxInvitation( + groupID + , groupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message, new UUID(msg.toAgentID) + , msg.fromAgentName + , msg.dialog + , msg.timestamp , msg.offline == 1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , Utils.StringToBytes(groupInfo.GroupName) - ); - - eq.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(groupInfo.GroupName) + ); + + eq.ChatterBoxSessionAgentListUpdates( + new UUID(groupID) + , new UUID(msg.fromAgentID) + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + } + } } - } - } else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) { // User hasn't dropped, so they're in the session, @@ -322,10 +316,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups default: m_log.WarnFormat("[GROUPS-MESSAGING] I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); break; + } } - } - - #endregion @@ -333,16 +325,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) { - if( m_agentsInGroupSession.ContainsKey(sessionID) ) + if (m_agentsInGroupSession.ContainsKey(sessionID)) { // If in session remove - if( m_agentsInGroupSession[sessionID].Contains(agentID) ) + if (m_agentsInGroupSession[sessionID].Contains(agentID)) { m_agentsInGroupSession[sessionID].Remove(agentID); } // If not in dropped list, add - if( !m_agentsDroppedSession[sessionID].Contains(agentID) ) + if (!m_agentsDroppedSession[sessionID].Contains(agentID)) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Dropped {1} from session {0}", sessionID, agentID); m_agentsDroppedSession[sessionID].Add(agentID); @@ -356,13 +348,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups CreateGroupSessionTracking(sessionID); // If nessesary, remove from dropped list - if( m_agentsDroppedSession[sessionID].Contains(agentID) ) + if (m_agentsDroppedSession[sessionID].Contains(agentID)) { m_agentsDroppedSession[sessionID].Remove(agentID); } // If nessesary, add to in session list - if( !m_agentsInGroupSession[sessionID].Contains(agentID) ) + if (!m_agentsInGroupSession[sessionID].Contains(agentID)) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Added {1} to session {0}", sessionID, agentID); m_agentsInGroupSession[sessionID].Add(agentID); @@ -385,7 +377,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - DebugGridInstantMessage(im); + DebugGridInstantMessage(im); } // Start group IM session @@ -424,13 +416,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendMessageToGroup(im, groupID); } } + #endregion private void SendMessageToGroup(GridInstantMessage im, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) { if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) @@ -441,15 +433,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = im.imSessionID; + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; msg.binaryBucket = im.binaryBucket; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -464,8 +456,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { // If they're not local, forward across the grid if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } else { // Deliver locally, directly @@ -488,24 +480,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups sessionMap.Add("type", OSD.FromInteger(0)); sessionMap.Add("voice_enabled", OSD.FromBoolean(false)); - OSDMap bodyMap = new OSDMap(4); bodyMap.Add("session_id", OSD.FromUUID(groupID)); bodyMap.Add("temp_session_id", OSD.FromUUID(groupID)); bodyMap.Add("success", OSD.FromBoolean(true)); bodyMap.Add("session_info", sessionMap); - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); } - } - private void DebugGridInstantMessage(GridInstantMessage im) { if (m_debugEnabled) @@ -535,7 +523,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (Scene scene in m_sceneList) { if (scene.Entities.ContainsKey(agentID) && - scene.Entities[agentID] is ScenePresence) + scene.Entities[agentID] is ScenePresence) { ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) @@ -546,7 +534,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { child = user.ControllingClient; } - } + } } // If we didn't find a root, then just return whichever child we found, or null if none @@ -555,5 +543,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion } - } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index eb9f804..a2d506c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -143,13 +143,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_msgTransferModule == null) { - m_msgTransferModule = scene.RequestModuleInterface(); + m_msgTransferModule = scene.RequestModuleInterface(); // No message transfer module, no notices, group invites, rejects, ejects, etc - if (m_msgTransferModule == null) + if (m_msgTransferModule == null) { - m_groupsEnabled = false; - m_log.Error("[GROUPS]: Could not get MessageTransferModule"); + m_groupsEnabled = false; + m_log.Error("[GROUPS]: Could not get MessageTransferModule"); Close(); return; } @@ -157,7 +157,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups lock (m_sceneList) { - m_sceneList.Add(scene); + m_sceneList.Add(scene); } scene.EventManager.OnNewClient += OnNewClient; @@ -178,7 +178,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups lock (m_sceneList) { - m_sceneList.Remove(scene); + m_sceneList.Remove(scene); } } @@ -313,16 +313,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupName = "Unknown"; } - remote_client.SendGroupNameReply(GroupID, GroupName); } - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // Group invitations if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { @@ -334,7 +331,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID fromAgentID = new UUID(im.fromAgentID); if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) { - // Accept if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) { @@ -373,10 +369,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Received a reject invite notice."); m_groupData.RemoveAgentToGroupInvite(inviteID); - } - - } } @@ -411,14 +404,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups binBucket = binBucket.Remove(0, 14).Trim(); if (m_debugEnabled) { - m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); - - OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); - - foreach (string key in binBucketOSD.Keys) - { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); - } + m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); + + OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + + foreach (string key in binBucketOSD.Keys) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } } // treat as if no attachment @@ -429,7 +422,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket[18] = 0; //dunno } - m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { @@ -446,12 +438,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.toAgentID = member.AgentID.Guid; OutgoingInstantMessage(msg, member.AgentID); - } } - - - } } @@ -477,11 +465,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID groupID = new UUID(im.fromAgentID); ejectee.SendAgentDropGroup(groupID); } - } - - - } private void OnGridInstantMessage(GridInstantMessage msg) @@ -491,7 +475,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Trigger the above event handler OnInstantMessage(null, msg); - // If a message from a group arrives here, it may need to be forwarded to a local client if (msg.fromGroup == true) { @@ -501,17 +484,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case (byte)InstantMessageDialog.GroupNotice: UUID toAgentID = new UUID(msg.toAgentID); IClientAPI localClient = GetActiveClient(toAgentID); - if( localClient != null ) + if (localClient != null) { localClient.SendInstantMessage(msg); } break; } } - } - #endregion #region IGroupsModule Members @@ -570,8 +551,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupMembers(groupID); if (m_debugEnabled) { - foreach (GroupMembersData member in data) - { + foreach (GroupMembersData member in data) + { m_log.DebugFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); } } @@ -588,8 +569,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) { - foreach (GroupRolesData member in data) - { + foreach (GroupRolesData member in data) + { m_log.DebugFormat("[GROUPS] {0} {1}", member.Title, member.Members); } } @@ -606,8 +587,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) { - foreach (GroupRoleMembersData member in data) - { + foreach (GroupRoleMembersData member in data) + { m_log.DebugFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); } } -- cgit v1.1 From c320dca2db5c841976f5a36dab47cd3a8250c825 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Wed, 29 Apr 2009 18:11:41 +0000 Subject: * minor: remove some mono compiler warnings --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 513d169..f7001ef 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private const bool UseProxy = false; + private bool UseProxy = false; // Capability string prefixes private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; @@ -598,7 +598,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string auth_token = (string)requestBody["auth_token"]; string[] auth_tokenvals = auth_token.Split(':'); - string username = auth_tokenvals[0]; + //string username = auth_tokenvals[0]; int strcount = 0; string[] ids = new string[strcount]; @@ -667,7 +667,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable requestBody = parseRequestBody((string)request["body"]); - string pwd = (string) requestBody["pwd"]; + //string pwd = (string) requestBody["pwd"]; string userid = (string) requestBody["userid"]; string avatarName = string.Empty; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 27cffd6..23dd52d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -228,7 +228,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); - if ((GroupID != null) && (GroupID != UUID.Zero)) + if (GroupID != UUID.Zero) { param["GroupID"] = GroupID.ToString(); } -- cgit v1.1 From 978f98fe7e21a2c540bf75aebc98fe6c3d4e2d19 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Wed, 29 Apr 2009 18:14:34 +0000 Subject: * Apply http://opensimulator.org/mantis/view.php?id=3554 * Stop converting serviceURL to all lower case. * Thanks mcortez --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 23dd52d..c380232 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public XmlRpcGroupDataProvider(string serviceURL, bool disableKeepAlive) { - m_serviceURL = serviceURL.Trim().ToLower(); + m_serviceURL = serviceURL.Trim(); m_disableKeepAlive = disableKeepAlive; if ((serviceURL == null) || -- cgit v1.1 From 517a454086281b31be7ca0f4303ab2eef5b0cd5a Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Wed, 29 Apr 2009 18:22:49 +0000 Subject: * Apply http://opensimulator.org/mantis/view.php?id=3557 * Stops XmlRpcGroups crashing client sessions if there is an XMLRPC failure * Thanks mcortez --- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index c380232..e913543 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -760,7 +760,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups req = new NoKeepAliveXmlRpcRequest(function, parameters); } - XmlRpcResponse resp = req.Send(m_serviceURL, 10000); + XmlRpcResponse resp = null; + + try + { + req.Send(m_serviceURL, 10000); + } + catch (Exception e) + { + m_log.Error("[GROUPS] An error has occured while attempting to access the XmlRpcGroups server"); + m_log.ErrorFormat("[GROUPS] {0} ", e.ToString()); + + foreach (KeyValuePair kvp in param) + { + m_log.WarnFormat("[GROUPS] {0} :: {1}", kvp.Key.ToString(), kvp.Value.ToString()); + } + Hashtable respData = (Hashtable)resp.Value; + respData.Add("error", e.ToString()); + return respData; + } if (resp.Value is Hashtable) { -- cgit v1.1 From 1bf0bc8bb3c3d78f2616397b7a4f048ae5ea1ac3 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Wed, 29 Apr 2009 18:52:10 +0000 Subject: * Apply further groups xmlrpc to stop an exception in the exception handler * Thanks mcortez --- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 47 ++++++++-------------- 1 file changed, 17 insertions(+), 30 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index e913543..25ce093 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -146,9 +146,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | GroupPowers.VoteOnProposal; param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); - - - Hashtable respData = XmlRpcCall("groups.createGroup", param); if (respData.Contains("error")) @@ -237,7 +234,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -246,7 +242,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return GroupProfileHashtableToGroupRecord(respData); - } public GroupProfileData GetMemberGroupProfile(UUID GroupID, UUID AgentID) @@ -254,7 +249,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -270,7 +264,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; - } private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) @@ -350,7 +343,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["ListInProfile"] = ListInProfile ? "1" : "0"; XmlRpcCall("groups.setAgentGroupInfo", param); - } public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) @@ -362,7 +354,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = groupID.ToString(); XmlRpcCall("groups.addAgentToGroupInvite", param); - } public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) @@ -434,7 +425,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall("groups.removeAgentFromGroupRole", param); } - public List FindGroups(string search) { Hashtable param = new Hashtable(); @@ -495,7 +485,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - public List GetAgentGroupMemberships(UUID AgentID) { Hashtable param = new Hashtable(); @@ -543,8 +532,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - - } public List GetGroupRoles(UUID GroupID) @@ -575,7 +562,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - } private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) @@ -643,7 +629,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return members; - } public List GetGroupRoleMembers(UUID GroupID) @@ -667,6 +652,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups members.Add(data); } } + return members; } @@ -694,9 +680,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups values.Add(data); } } + return values; - } + public GroupNoticeInfo GetGroupNotice(UUID noticeID) { Hashtable param = new Hashtable(); @@ -704,7 +691,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable respData = XmlRpcCall("groups.getGroupNotice", param); - if (respData.Contains("error")) { return null; @@ -728,6 +714,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } + public void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -768,14 +755,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } catch (Exception e) { - m_log.Error("[GROUPS] An error has occured while attempting to access the XmlRpcGroups server"); - m_log.ErrorFormat("[GROUPS] {0} ", e.ToString()); + m_log.ErrorFormat("[GROUPS]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); + m_log.ErrorFormat("[GROUPS]: {0} ", e.ToString()); foreach (KeyValuePair kvp in param) { - m_log.WarnFormat("[GROUPS] {0} :: {1}", kvp.Key.ToString(), kvp.Value.ToString()); + m_log.WarnFormat("[GROUPS]: {0} :: {1}", kvp.Key.ToString(), kvp.Value.ToString()); } - Hashtable respData = (Hashtable)resp.Value; + + + Hashtable respData = new Hashtable(); respData.Add("error", e.ToString()); return respData; } @@ -791,21 +780,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return respData; } - m_log.ErrorFormat("[XmlRpcGroupData] The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + m_log.ErrorFormat("[GROUPS]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); if (resp.Value is ArrayList) { ArrayList al = (ArrayList)resp.Value; - m_log.ErrorFormat("[XmlRpcGroupData] Contains {0} elements", al.Count); + m_log.ErrorFormat("[GROUPS]: Contains {0} elements", al.Count); foreach (object o in al) { - m_log.ErrorFormat("[XmlRpcGroupData] {0} :: {1}", o.GetType().ToString(), o.ToString()); + m_log.ErrorFormat("[GROUPS]: {0} :: {1}", o.GetType().ToString(), o.ToString()); } } else { - m_log.ErrorFormat("[XmlRpcGroupData] Function returned: {0}", resp.Value.ToString()); + m_log.ErrorFormat("[GROUPS]: Function returned: {0}", resp.Value.ToString()); } Hashtable error = new Hashtable(); @@ -815,21 +804,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void LogRespDataToConsoleError(Hashtable respData) { - m_log.Error("[GROUPDATA] Error:"); + m_log.Error("[GROUPS]: Error:"); foreach (string key in respData.Keys) { - m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); + m_log.ErrorFormat("[GROUPS]: Key: {0}", key); string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) { - m_log.ErrorFormat("[GROUPDATA] {0}", line); + m_log.ErrorFormat("[GROUPS]: {0}", line); } - } } - } public class GroupNoticeInfo -- cgit v1.1 From 40c2e2e84f50e9a75f26b326a798a280d36687e9 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Wed, 29 Apr 2009 19:31:48 +0000 Subject: * Add test to check temp profile creation on iar load --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index f7001ef..e04b1ba 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -54,10 +54,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { public class FreeSwitchVoiceModule : IRegionModule { - - // Infrastructure - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private bool UseProxy = false; -- cgit v1.1 From 10415c579b3c67e0314eb0aac5d4cdd7870d9e6a Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Wed, 29 Apr 2009 19:38:20 +0000 Subject: * Correct log message format * Fix XmlRpcGroupData.XmlRpcCall() to correctly handle response --- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 32 +++---- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 58 ++++++------ .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 100 ++++++++++----------- 3 files changed, 95 insertions(+), 95 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 25ce093..d941118 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -44,7 +44,6 @@ using OpenSim.Framework; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - public class XmlRpcGroupDataProvider : IGroupDataProvider { private static readonly ILog m_log = @@ -196,7 +195,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); XmlRpcCall("groups.removeRoleFromGroup", param); - } public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, @@ -234,6 +232,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } + Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -249,6 +248,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); + Hashtable respData = XmlRpcCall("groups.getGroup", param); if (respData.Contains("error")) @@ -314,7 +314,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } - public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); @@ -402,7 +401,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["GroupID"] = GroupID.ToString(); XmlRpcCall("groups.removeAgentFromGroup", param); - } public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) @@ -501,6 +499,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); } } + return memberships; } @@ -691,6 +690,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable respData = XmlRpcCall("groups.getGroupNotice", param); + if (respData.Contains("error")) { return null; @@ -751,19 +751,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups try { - req.Send(m_serviceURL, 10000); + resp = req.Send(m_serviceURL, 10000); } catch (Exception e) { - m_log.ErrorFormat("[GROUPS]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[GROUPS]: {0} ", e.ToString()); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); foreach (KeyValuePair kvp in param) { - m_log.WarnFormat("[GROUPS]: {0} :: {1}", kvp.Key.ToString(), kvp.Value.ToString()); + m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", kvp.Key.ToString(), kvp.Value.ToString()); } - Hashtable respData = new Hashtable(); respData.Add("error", e.ToString()); return respData; @@ -780,21 +779,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return respData; } - m_log.ErrorFormat("[GROUPS]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); if (resp.Value is ArrayList) { ArrayList al = (ArrayList)resp.Value; - m_log.ErrorFormat("[GROUPS]: Contains {0} elements", al.Count); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); foreach (object o in al) { - m_log.ErrorFormat("[GROUPS]: {0} :: {1}", o.GetType().ToString(), o.ToString()); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); } } else { - m_log.ErrorFormat("[GROUPS]: Function returned: {0}", resp.Value.ToString()); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); } Hashtable error = new Hashtable(); @@ -804,17 +803,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void LogRespDataToConsoleError(Hashtable respData) { - m_log.Error("[GROUPS]: Error:"); + m_log.Error("[XMLRPCGROUPDATA]: Error:"); foreach (string key in respData.Keys) { - m_log.ErrorFormat("[GROUPS]: Key: {0}", key); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) { - m_log.ErrorFormat("[GROUPS]: {0}", line); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); } + } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 16dd0b6..a613ec2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -120,7 +120,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupMessagingEnabled) return; - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupsModule = scene.RequestModuleInterface(); @@ -157,7 +157,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupMessagingEnabled) return; - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_sceneList.Remove(scene); } @@ -201,7 +201,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnNewClient(IClientAPI client) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); client.OnInstantMessage += OnInstantMessage; } @@ -217,7 +217,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) { - m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); DebugGridInstantMessage(msg); } @@ -234,7 +234,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void ProcessMessageFromGroupSession(GridInstantMessage msg) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); switch (msg.dialog) { @@ -263,7 +263,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); if (groupInfo != null) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); // Force? open the group session dialog??? IEventQueue eq = activeClient.Scene.RequestModuleInterface(); @@ -303,18 +303,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (client != null) { // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} locally", client.Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); client.SendInstantMessage(msg); } else { - m_log.WarnFormat("[GROUPS-MESSAGING] Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); + m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); } } break; default: - m_log.WarnFormat("[GROUPS-MESSAGING] I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); break; } } @@ -336,7 +336,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // If not in dropped list, add if (!m_agentsDroppedSession[sessionID].Contains(agentID)) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Dropped {1} from session {0}", sessionID, agentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); m_agentsDroppedSession[sessionID].Add(agentID); } } @@ -356,7 +356,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // If nessesary, add to in session list if (!m_agentsInGroupSession[sessionID].Contains(agentID)) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Added {1} to session {0}", sessionID, agentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); m_agentsInGroupSession[sessionID].Add(agentID); } } @@ -365,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (!m_agentsInGroupSession.ContainsKey(sessionID)) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Creating session tracking for : {0}", sessionID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); m_agentsInGroupSession.Add(sessionID, new List()); m_agentsDroppedSession.Add(sessionID, new List()); } @@ -375,7 +375,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) { - m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); DebugGridInstantMessage(im); } @@ -388,7 +388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); if (groupInfo != null) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Start Group Session for {0}", groupInfo.GroupName); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); AddAgentToGroupSession(im.fromAgentID, im.imSessionID); @@ -411,7 +411,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { UUID groupID = new UUID(im.toAgentID); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); SendMessageToGroup(im, groupID); } @@ -421,14 +421,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void SendMessageToGroup(GridInstantMessage im, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) { if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) { // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} has dropped session, not delivering to them", member.AgentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); continue; } @@ -455,13 +455,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (client == null) { // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} via Grid", member.AgentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); } else { // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); ProcessMessageFromGroupSession(msg); } } @@ -469,7 +469,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); OSDMap moderatedMap = new OSDMap(4); moderatedMap.Add("voice", OSD.FromBoolean(false)); @@ -498,15 +498,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) { - m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromGroup({0})", im.fromGroup ? "True" : "False"); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentID({0})", im.fromAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentName({0})", im.fromAgentName.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: imSessionID({0})", im.imSessionID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: message({0})", im.message.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: offline({0})", im.offline.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: toAgentID({0})", im.toAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index a2d506c..3337ccd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -139,7 +139,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupsEnabled) return; - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_msgTransferModule == null) { @@ -174,7 +174,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupsEnabled) return; - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); lock (m_sceneList) { @@ -209,7 +209,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #region EventHandlers private void OnNewClient(IClientAPI client) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; @@ -238,7 +238,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed private void OnClientClosed(UUID AgentId) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); lock (m_ActiveClients) { @@ -254,7 +254,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } else { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS] Client closed that wasn't registered here."); + if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Client closed that wasn't registered here."); } @@ -267,7 +267,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); // TODO: This currently ignores pretty much all the query flags including Mature and sort order remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); @@ -277,7 +277,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); UUID activeGroupID = UUID.Zero; string activeGroupTitle = string.Empty; @@ -299,7 +299,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); string GroupName; @@ -318,7 +318,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Group invitations if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) @@ -326,7 +326,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID inviteID = new UUID(im.imSessionID); GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); UUID fromAgentID = new UUID(im.fromAgentID); if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) @@ -334,7 +334,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Accept if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Received an accept invite notice."); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); @@ -367,7 +367,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Received a reject invite notice."); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); m_groupData.RemoveAgentToGroupInvite(inviteID); } } @@ -470,7 +470,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnGridInstantMessage(GridInstantMessage msg) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Trigger the above event handler OnInstantMessage(null, msg); @@ -506,7 +506,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); @@ -522,7 +522,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ///
public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); @@ -546,14 +546,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupMembers(groupID); if (m_debugEnabled) { foreach (GroupMembersData member in data) { - m_log.DebugFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); + m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title); } } @@ -563,7 +563,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupRoles(groupID); @@ -571,7 +571,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { foreach (GroupRolesData member in data) { - m_log.DebugFormat("[GROUPS] {0} {1}", member.Title, member.Members); + m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members); } } @@ -581,7 +581,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupRoleMembers(groupID); @@ -589,7 +589,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { foreach (GroupRoleMembersData member in data) { - m_log.DebugFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); + m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID); } } @@ -600,7 +600,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupProfileData profile = new GroupProfileData(); @@ -635,21 +635,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupMembershipData[] GetMembershipData(UUID agentID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); return m_groupData.GetAgentGroupMemberships(agentID).ToArray(); } public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); return m_groupData.GetAgentGroupMembership(agentID, groupID); } public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: Security Check? @@ -659,14 +659,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) { // TODO: Security Check? - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); } public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_groupData.GetGroupRecord(UUID.Zero, name) != null) { @@ -686,7 +686,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // ToDo: check if agent is a member of group and is allowed to see notices? @@ -698,7 +698,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ///
public string GetGroupTitle(UUID avatarID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); if (membership != null) @@ -713,7 +713,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ///
public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, groupID, titleRoleID); @@ -727,7 +727,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: Security Checks? @@ -760,7 +760,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check switch (changes) @@ -776,7 +776,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups break; default: - m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); + m_log.ErrorFormat("[GROUPS]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); break; } @@ -786,7 +786,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); @@ -817,7 +817,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -841,7 +841,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } else { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Group Notice {0} not found, composing empty message.", groupNoticeID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); msg.fromAgentID = UUID.Zero.Guid; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; msg.fromAgentName = string.Empty; @@ -854,7 +854,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendAgentGroupDataUpdate(IClientAPI remoteClient) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Send agent information about his groups SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); @@ -862,7 +862,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); @@ -875,7 +875,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, groupID); @@ -890,7 +890,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check? m_groupData.RemoveAgentFromGroup(ejecteeID, groupID); @@ -965,7 +965,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); @@ -1036,7 +1036,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); OSDArray AgentData = new OSDArray(1); OSDMap AgentDataMap = new OSDMap(1); @@ -1080,7 +1080,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void SendScenePresenceUpdate(UUID AgentID, string Title) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); ScenePresence presence = null; lock (m_sceneList) @@ -1104,7 +1104,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private void UpdateAllClientsWithGroupInfo(UUID dataForClientID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: Probably isn't nessesary to update every client in every scene. // Need to examine client updates and do only what's nessesary. @@ -1122,7 +1122,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private void SendAgentGroupDataUpdate(IClientAPI client, UUID dataForAgentID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff @@ -1142,7 +1142,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); @@ -1169,18 +1169,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OutgoingInstantMessage(GridInstantMessage msg, UUID msgTo) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); IClientAPI localClient = GetActiveClient(msgTo); if (localClient != null) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] MsgTo ({0}) is local, delivering directly", localClient.Name); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); localClient.SendInstantMessage(msg); } else { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS] MsgTo ({0}) is not local, delivering via TransferModule", msgTo); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Message Sent: {0}", success?"Succeeded":"Failed"); }); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is not local, delivering via TransferModule", msgTo); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Message Sent: {0}", success?"Succeeded":"Failed"); }); } } -- cgit v1.1 From 8944ab910cc8f62dc6ce567046a92e50b1e2813f Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Wed, 29 Apr 2009 22:31:00 +0000 Subject: Thank you kindly, MCortez for a patch that: The attached patch provides the necessary infrastructure to support security and authentication features of the xmlrpc server. * Read/Write keys for accessing a Group's xmlrpc service. * Requiring user session verification for write operations. --- .../Avatar/XmlRpcGroups/IGroupDataProvider.cs | 60 +++--- .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 163 +++++++++------- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 213 +++++++++++++++------ 3 files changed, 280 insertions(+), 156 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs index 3fd6116..43cccf4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs @@ -36,42 +36,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { interface IGroupDataProvider { - UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(UUID GroupID, string GroupName); - List FindGroups(string search); - List GetGroupMembers(UUID GroupID); + UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); + List FindGroups(GroupRequestID requestID, string search); + List GetGroupMembers(GroupRequestID requestID, UUID GroupID); - void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(UUID groupID, UUID roleID); - List GetGroupRoles(UUID GroupID); - List GetGroupRoleMembers(UUID GroupID); + void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); + List GetGroupRoles(GroupRequestID requestID, UUID GroupID); + List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); - void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(UUID AgentID, UUID GroupID); + void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(UUID inviteID); - void RemoveAgentToGroupInvite(UUID inviteID); + void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(UUID AgentID, UUID GroupID); + void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); - void SetAgentActiveGroup(UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(UUID AgentID); + void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); - void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(UUID AgentID); + GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); - void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(UUID noticeID); - List GetGroupNotices(UUID GroupID); + void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); + List GetGroupNotices(GroupRequestID requestID, UUID GroupID); } public class GroupInviteInfo @@ -82,4 +82,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public UUID InviteID = UUID.Zero; } + public class GroupRequestID + { + public UUID AgentID = UUID.Zero; + public string UserServiceURL = string.Empty; + public UUID SessionID = UUID.Zero; + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index d941118..a7ef40a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -61,7 +61,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_disableKeepAlive = false; - public XmlRpcGroupDataProvider(string serviceURL, bool disableKeepAlive) + private string m_groupReadKey = string.Empty; + private string m_groupWriteKey = string.Empty; + + public XmlRpcGroupDataProvider(string serviceURL, bool disableKeepAlive, string groupReadKey, string groupWriteKey) { m_serviceURL = serviceURL.Trim(); m_disableKeepAlive = disableKeepAlive; @@ -71,12 +74,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { throw new Exception("Please specify a valid ServiceURL for XmlRpcGroupDataProvider in OpenSim.ini, [Groups], XmlRpcServiceURL"); } + + m_groupReadKey = groupReadKey; + m_groupWriteKey = groupWriteKey; } /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, + public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) { @@ -145,7 +151,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | GroupPowers.VoteOnProposal; param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); - Hashtable respData = XmlRpcCall("groups.createGroup", param); + + + + Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); if (respData.Contains("error")) { @@ -157,7 +166,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(UUID groupID, string charter, bool showInList, + public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { @@ -171,10 +180,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; - XmlRpcCall("groups.updateGroup", param); + XmlRpcCall(requestID, "groups.updateGroup", param); } - public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, + public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -185,19 +194,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Title"] = title; param["Powers"] = powers.ToString(); - XmlRpcCall("groups.addRoleToGroup", param); + XmlRpcCall(requestID, "groups.addRoleToGroup", param); } - public void RemoveGroupRole(UUID groupID, UUID roleID) + public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); param["RoleID"] = roleID.ToString(); - XmlRpcCall("groups.removeRoleFromGroup", param); + XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); } - public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, + public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -217,10 +226,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } param["Powers"] = powers.ToString(); - XmlRpcCall("groups.updateGroupRole", param); + XmlRpcCall(requestID, "groups.updateGroupRole", param); } - public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) + public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); if (GroupID != UUID.Zero) @@ -232,8 +241,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - - Hashtable respData = XmlRpcCall("groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -241,15 +249,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return GroupProfileHashtableToGroupRecord(respData); + } - public GroupProfileData GetMemberGroupProfile(UUID GroupID, UUID AgentID) + public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall("groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -257,13 +265,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return new GroupProfileData(); } - GroupMembershipData MemberInfo = GetAgentGroupMembership(AgentID, GroupID); + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; + } private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) @@ -314,26 +323,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } - public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) + public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall("groups.setAgentActiveGroup", param); + XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); } - public void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["SelectedRoleID"] = RoleID.ToString(); - XmlRpcCall("groups.setAgentGroupInfo", param); + XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); } - public void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); @@ -341,10 +350,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AcceptNotices"] = AcceptNotices ? "1" : "0"; param["ListInProfile"] = ListInProfile ? "1" : "0"; - XmlRpcCall("groups.setAgentGroupInfo", param); + XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + } - public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); @@ -352,15 +362,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); param["GroupID"] = groupID.ToString(); - XmlRpcCall("groups.addAgentToGroupInvite", param); + XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); + } - public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) + public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - Hashtable respData = XmlRpcCall("groups.getAgentToGroupInvite", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); if (respData.Contains("error")) { @@ -376,59 +387,60 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return inviteInfo; } - public void RemoveAgentToGroupInvite(UUID inviteID) + public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - XmlRpcCall("groups.removeAgentToGroupInvite", param); + XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); } - public void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall("groups.addAgentToGroup", param); + XmlRpcCall(requestID, "groups.addAgentToGroup", param); } - public void RemoveAgentFromGroup(UUID AgentID, UUID GroupID) + public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall("groups.removeAgentFromGroup", param); + XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); } - public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall("groups.addAgentToGroupRole", param); + XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); } - public void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) + public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall("groups.removeAgentFromGroupRole", param); + XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); } - public List FindGroups(string search) + + public List FindGroups(GroupRequestID requestID, string search) { Hashtable param = new Hashtable(); param["Search"] = search; - Hashtable respData = XmlRpcCall("groups.findGroups", param); + Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); List findings = new List(); @@ -450,13 +462,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return findings; } - public GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID) + public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getAgentGroupMembership", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); if (respData.Contains("error")) { @@ -468,12 +480,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public GroupMembershipData GetAgentActiveMembership(UUID AgentID) + public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall("groups.getAgentActiveMembership", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); if (respData.Contains("error")) { @@ -483,12 +495,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - public List GetAgentGroupMemberships(UUID AgentID) + + public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall("groups.getAgentGroupMemberships", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); List memberships = new List(); @@ -503,13 +516,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return memberships; } - public List GetAgentGroupRoles(UUID AgentID, UUID GroupID) + public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getAgentRoles", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); List Roles = new List(); @@ -531,14 +544,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; + + } - public List GetGroupRoles(UUID GroupID) + public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getGroupRoles", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); List Roles = new List(); @@ -561,6 +576,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; + } private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) @@ -598,12 +614,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public List GetGroupMembers(UUID GroupID) + public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getGroupMembers", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); List members = new List(); @@ -628,14 +644,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return members; + } - public List GetGroupRoleMembers(UUID GroupID) + public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getGroupRoleMembers", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); List members = new List(); @@ -651,16 +668,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups members.Add(data); } } - return members; } - public List GetGroupNotices(UUID GroupID) + public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall("groups.getGroupNotices", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); List values = new List(); @@ -679,16 +695,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups values.Add(data); } } - return values; + } - - public GroupNoticeInfo GetGroupNotice(UUID noticeID) + public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) { Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); - Hashtable respData = XmlRpcCall("groups.getGroupNotice", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); if (respData.Contains("error")) @@ -714,8 +729,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - - public void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -728,11 +742,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["BinaryBucket"] = binBucket; param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - XmlRpcCall("groups.addGroupNotice", param); + XmlRpcCall(requestID, "groups.addGroupNotice", param); } - private Hashtable XmlRpcCall(string function, Hashtable param) + private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) { + if (requestID == null) + { + requestID = new GroupRequestID(); + } + param.Add("RequestingAgentID", requestID.AgentID.ToString()); + param.Add("RequestingAgentUserService", requestID.UserServiceURL); + param.Add("RequestingSessionID", requestID.SessionID.ToString()); + + + param.Add("ReadKey", m_groupReadKey); + param.Add("WriteKey", m_groupWriteKey); + + IList parameters = new ArrayList(); parameters.Add(param); @@ -758,9 +785,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - foreach (KeyValuePair kvp in param) + + foreach (string key in param.Keys) { - m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", kvp.Key.ToString(), kvp.Value.ToString()); + m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); } Hashtable respData = new Hashtable(); @@ -817,6 +845,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } + } public class GroupNoticeInfo diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 3337ccd..5ba7eff 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -28,8 +28,7 @@ using System; using System.Collections.Generic; using System.Reflection; - -using System.Collections; +using System.Timers; using log4net; using Nini.Config; @@ -61,6 +60,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// XmlRpcMessagingEnabled = true /// XmlRpcNoticesEnabled = true /// XmlRpcDebugEnabled = true + /// XmlRpcServiceReadKey = 1234 + /// XmlRpcServiceWriteKey = 1234 /// /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for /// ; a problem discovered on some Windows based region servers. Only disable @@ -79,6 +80,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupDataProvider m_groupData = null; + class GroupRequestIDInfo + { + public GroupRequestID RequestID = new GroupRequestID(); + public DateTime LastUsedTMStamp = DateTime.MinValue; + } + private Dictionary m_clientRequestIDInfo = new Dictionary(); + private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes + private Timer m_clientRequestIDFlushTimer = new Timer(); + + // Configuration settings private const string m_defaultXmlRpcServiceURL = "http://osflotsam.org/xmlrpc.php"; private bool m_groupsEnabled = false; @@ -119,12 +130,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); bool DisableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); - m_groupData = new XmlRpcGroupDataProvider(ServiceURL, DisableKeepAlive); + string ServiceReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); + string ServiceWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); + + m_groupData = new XmlRpcGroupDataProvider(ServiceURL, DisableKeepAlive, ServiceReadKey, ServiceWriteKey); m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL); m_groupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; + m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; + m_clientRequestIDFlushTimer.Start(); + } + } + + void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) + { + lock (m_clientRequestIDInfo) + { + TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); + UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; + foreach (UUID key in CurrentKeys) + { + if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + { + m_clientRequestIDInfo.Remove(key); + } + } } } @@ -188,6 +221,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); + + m_clientRequestIDFlushTimer.Stop(); } public string Name @@ -218,13 +253,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - + + lock (m_clientRequestIDInfo) + { + if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) + { + // flush any old RequestID information + m_clientRequestIDInfo.Remove(client.AgentId); + } + } SendAgentGroupDataUpdate(client, client.AgentId); } private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) { - GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(avatarID).ToArray(); + GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -270,7 +313,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); } } @@ -284,7 +327,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string activeGroupName = string.Empty; ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(dataForAgentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); if (membership != null) { activeGroupID = membership.GroupID; @@ -297,13 +340,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) + private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); string GroupName; - - GroupRecord group = m_groupData.GetGroupRecord(GroupID, null); + + GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); if (group != null) { GroupName = group.GroupName; @@ -313,7 +356,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupName = "Unknown"; } - remote_client.SendGroupNameReply(GroupID, GroupName); + remoteClient.SendGroupNameReply(GroupID, GroupName); } private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) @@ -324,7 +367,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); @@ -337,7 +380,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role - m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -361,14 +404,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: If the inviter is still online, they need an agent dataupdate // and maybe group membership updates for the invitee - m_groupData.RemoveAgentToGroupInvite(inviteID); + m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(inviteID); + m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); } } } @@ -382,7 +425,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GroupID, null) != null) + if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); @@ -422,14 +465,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket[18] = 0; //dunno } - m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { OnNewGroupNotice(GroupID, NoticeID); } // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GroupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) { if (member.AcceptNotices) { @@ -501,14 +544,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID) { - return m_groupData.GetGroupRecord(GroupID, null); + return m_groupData.GetGroupRecord(null, GroupID, null); } public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); + m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); // Changing active group changes title, active powers, all kinds of things // anyone who is in any region that can see this client, should probably be @@ -524,8 +567,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); List titles = new List(); foreach (GroupRolesData role in agentRoles) @@ -548,7 +593,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupMembers(groupID); + List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); if (m_debugEnabled) { foreach (GroupMembersData member in data) @@ -565,7 +610,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoles(groupID); + List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); if (m_debugEnabled) { @@ -583,7 +628,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(groupID); + List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); if (m_debugEnabled) { @@ -604,15 +649,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupProfileData profile = new GroupProfileData(); - GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); if (groupInfo != null) { profile.AllowPublish = groupInfo.AllowPublish; profile.Charter = groupInfo.Charter; profile.FounderID = groupInfo.FounderID; profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(groupID).Count; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; profile.InsigniaID = groupInfo.GroupPicture; profile.MaturePublish = groupInfo.MaturePublish; profile.MembershipFee = groupInfo.MembershipFee; @@ -623,7 +670,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups profile.ShowInList = groupInfo.ShowInList; } - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); if (memberInfo != null) { profile.MemberTitle = memberInfo.GroupTitle; @@ -637,14 +684,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(agentID).ToArray(); + return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); } public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMembership(agentID, groupID); + return m_groupData.GetAgentGroupMembership(null, agentID, groupID); } public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) @@ -653,7 +700,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: Security Check? - m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) @@ -661,20 +708,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: Security Check? if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); + m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); } public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - if (m_groupData.GetGroupRecord(UUID.Zero, name) != null) + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } - UUID groupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); @@ -689,8 +738,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // ToDo: check if agent is a member of group and is allowed to see notices? - - return m_groupData.GetGroupNotices(groupID).ToArray(); + + return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); } /// @@ -700,7 +749,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); if (membership != null) { return membership.GroupTitle; @@ -715,7 +764,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, groupID, titleRoleID); + m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); // TODO: Not sure what all is needed here, but if the active group role change is for the group // the client currently has set active, then we need to do a scene presence update too @@ -731,20 +780,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: Security Checks? + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + switch ((OpenMetaverse.GroupRoleUpdate)updateType) { case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(groupID, UUID.Random(), name, description, title, powers); + m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(groupID, roleID); + m_groupData.RemoveGroupRole(grID, groupID, roleID); break; case OpenMetaverse.GroupRoleUpdate.UpdateAll: case OpenMetaverse.GroupRoleUpdate.UpdateData: case OpenMetaverse.GroupRoleUpdate.UpdatePowers: - m_groupData.UpdateGroupRole(groupID, roleID, name, description, title, powers); + m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.NoUpdate: @@ -763,16 +814,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + switch (changes) { case 0: // Add - m_groupData.AddAgentToGroupRole(memberID, groupID, roleID); + m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); break; case 1: // Remove - m_groupData.RemoveAgentFromGroupRole(memberID, groupID, roleID); + m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); break; default: @@ -788,12 +841,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(data.GroupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -825,12 +879,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.dialog = dialog; // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; msg.fromGroup = true; - msg.offline = (byte)0; + msg.offline = (byte)1; // Allow this message to be stored for offline use msg.ParentEstateID = 0; msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; - GroupNoticeInfo info = m_groupData.GetGroupNotice(groupNoticeID); + GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); if (info != null) { msg.fromAgentID = info.GroupID.Guid; @@ -865,7 +919,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); + m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); remoteClient.SendJoinGroupReply(groupID, true); @@ -877,7 +931,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, groupID); + m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); remoteClient.SendLeaveGroupReply(groupID, true); @@ -892,12 +946,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + // Todo: Security check? - m_groupData.RemoveAgentFromGroup(ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); - GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); if ((groupInfo == null) || (userProfile == null)) @@ -969,7 +1025,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - m_groupData.AddAgentToGroupInvite(InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(GetClientGroupRequestID(remoteClient), InviteID, groupID, roleID, invitedAgentID); if (m_msgTransferModule != null) { @@ -1031,6 +1087,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return child; } + private GroupRequestID GetClientGroupRequestID(IClientAPI client) + { + lock (m_clientRequestIDInfo) + { + if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) + { + GroupRequestIDInfo info = new GroupRequestIDInfo(); + info.RequestID.AgentID = client.AgentId; + info.RequestID.SessionID = client.SessionId; + + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); + if (userProfile is ForeignUserProfileData) + { + // They aren't from around here + ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; + info.RequestID.UserServiceURL = fupd.UserServerURI; + } + else + { + // They're a local user, use this: + info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + } + + m_clientRequestIDInfo.Add(client.AgentId, info); + } + + m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; + } + return m_clientRequestIDInfo[client.AgentId].RequestID; + } + /// /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. /// @@ -1120,23 +1207,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Update remoteClient with group information about dataForAgentID /// - private void SendAgentGroupDataUpdate(IClientAPI client, UUID dataForAgentID) + private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - OnAgentDataUpdateRequest(client, dataForAgentID, UUID.Zero); + OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); // Need to send a group membership update to the client - // UDP version doesn't seem to behave nicely - // client.SendGroupMembership(GetMembershipData(client.AgentId)); + // UDP version doesn't seem to behave nicely. But we're going to send it out here + // with an empty group membership to hopefully remove groups being displayed due + // to the core Groups Stub + remoteClient.SendGroupMembership( new GroupMembershipData[0] ); - GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(dataForAgentID).ToArray(); + GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); - SendGroupMembershipInfoViaCaps(client, dataForAgentID, membershipData); - client.SendAvatarGroupsReply(dataForAgentID, membershipData); + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); + remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); } -- cgit v1.1 From 47640aca22dc567d92f54c08cc29ea8bfa373ffd Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Sat, 2 May 2009 16:16:27 +0000 Subject: Thank you kindly, MCortez for a patch that solves: Different people using Hippo 0.5.1 report that trying to send group instant messages crashes the viewer (Hippo 0.5.1). This is the case even for empty groups or if all group members are online. --- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 5ba7eff..3476cdb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -1089,6 +1089,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRequestID GetClientGroupRequestID(IClientAPI client) { + if (client == null) + { + return new GroupRequestID(); + } + lock (m_clientRequestIDInfo) { if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) @@ -1098,7 +1103,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups info.RequestID.SessionID = client.SessionId; UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); - if (userProfile is ForeignUserProfileData) + if (userProfile == null) + { + // This should be impossible. If I've been passed a reference to a client + // that client should be registered with the UserService. So something + // is horribly wrong somewhere. + + m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); + + // Default to local user service and hope for the best? + info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + + } + else if (userProfile is ForeignUserProfileData) { // They aren't from around here ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; -- cgit v1.1 From 257fc5515ac9cb36032c2f44f040c3620ed2f328 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Mon, 4 May 2009 15:38:36 +0000 Subject: * minor: remove some mono compiler warnings, minor cleanup --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index e04b1ba..ddd0c12 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -594,7 +594,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; string auth_token = (string)requestBody["auth_token"]; - string[] auth_tokenvals = auth_token.Split(':'); + //string[] auth_tokenvals = auth_token.Split(':'); //string username = auth_tokenvals[0]; int strcount = 0; @@ -643,9 +643,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice ", ids[i],i,m_freeSwitchRealm,dt)); } - - - + resp.Append(""); response["str_response_string"] = resp.ToString(); @@ -716,7 +714,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice */ } - public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request) { m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]); -- cgit v1.1 From acfb5051cd328ab21aba5bfc2878ce84d496a7f1 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 4 May 2009 20:15:39 +0000 Subject: Intermediate commit. WILL NOT COMPILE! --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index ddd0c12..4723a93 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -44,6 +44,7 @@ using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Communications.Capabilities; using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps = OpenSim.Framework.Communications.Capabilities.Caps; -- cgit v1.1 From 93d54d7652176350ce3dc517972e81adb6a7f1ac Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 9 May 2009 17:02:03 +0000 Subject: Prevent normal (Text) IM from being logged by the group message module in debug mode. Fixes Mantis #3609 --- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index a613ec2..da7aa6b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -496,7 +496,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void DebugGridInstantMessage(GridInstantMessage im) { - if (m_debugEnabled) + // Don't log any normal IMs (privacy!) + if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent) { m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); -- cgit v1.1 From 1b7d0a6c93eb4a056d39b9cc708283086f8e8bf8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 12 May 2009 14:59:11 +0000 Subject: Paving the way for syncing group permissions across a grid --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 3476cdb..2a3df8c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -541,6 +541,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #region IGroupsModule Members public event NewGroupNotice OnNewGroupNotice; + public event GroupChange OnGroupChange; public GroupRecord GetGroupRecord(UUID GroupID) { -- cgit v1.1 From fca73f3ae488de578c4c6e093c9d1185ec6d4ba3 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 12 May 2009 15:52:28 +0000 Subject: Add more group notify glue --- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 2a3df8c..3b12722 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -1291,6 +1291,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } + public void NotifyChange(UUID groupID) + { + // Notify all group members of a chnge in group roles and/or + // permissions + // + } + #endregion } -- cgit v1.1 From 9248300596831fd5a562cd2443a87f37bd1d4ff1 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 14 May 2009 21:28:02 +0000 Subject: Remove a misleading event that was only used internally --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 3b12722..88f8038 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -541,7 +541,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #region IGroupsModule Members public event NewGroupNotice OnNewGroupNotice; - public event GroupChange OnGroupChange; public GroupRecord GetGroupRecord(UUID GroupID) { -- cgit v1.1 From 786ff98f6decce315e8cdf160b806237b00cc4ed Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 14 May 2009 21:38:17 +0000 Subject: Remove all messages from the groups module that would be output when it is NOT enabled. --- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 8 ++------ .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 7 ++----- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index da7aa6b..24d539f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -72,25 +72,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { IConfig groupsConfig = config.Configs["Groups"]; - m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); - if (groupsConfig == null) { // Do not run this module by default. - m_log.Info("[GROUPS-MESSAGING]: No config found in OpenSim.ini -- not enabling XmlRpcGroupsMessaging"); return; } else { if (!groupsConfig.GetBoolean("Enabled", false)) { - m_log.Info("[GROUPS-MESSAGING]: Groups disabled in configuration"); return; } if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") { - m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); m_groupMessagingEnabled = false; return; @@ -100,10 +95,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupMessagingEnabled) { - m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); return; } + m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); + m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 88f8038..40481a8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -102,12 +102,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { IConfig groupsConfig = config.Configs["Groups"]; - m_log.Info("[GROUPS]: Initializing XmlRpcGroups"); - if (groupsConfig == null) { // Do not run this module by default. - m_log.Info("[GROUPS]: No config found in OpenSim.ini -- not enabling XmlRpcGroups"); return; } else @@ -115,18 +112,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupsEnabled = groupsConfig.GetBoolean("Enabled", false); if (!m_groupsEnabled) { - m_log.Info("[GROUPS]: Groups disabled in configuration"); return; } if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") { - m_log.Info("[GROUPS]: Config Groups Module not set to XmlRpcGroups"); m_groupsEnabled = false; return; } + m_log.Info("[GROUPS]: Initializing XmlRpcGroups"); + string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); bool DisableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); -- cgit v1.1 From 37726764be2beb71bfd6844482a26b7648b34435 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 22 May 2009 11:37:26 +0000 Subject: changing IRCBridgeModule to new region module scheme --- .../OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 121 ++++++++------------- 1 file changed, 47 insertions(+), 74 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index fdc2bd9..5ebbd7b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -38,87 +38,61 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Avatar.Chat { - public class IRCBridgeModule : IRegionModule + public class IRCBridgeModule : INonSharedRegionModule { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - internal static bool configured = false; - internal static bool enabled = false; - internal static IConfig m_config = null; + internal static bool m_pluginEnabled = false; + internal static IConfig m_config = null; internal static List m_channels = new List(); internal static List m_regions = new List(); - internal static string password = String.Empty; + internal static string m_password = String.Empty; + internal RegionState m_region = null; - internal RegionState region = null; - - #region IRegionModule Members + #region INonSharedRegionModule Members public string Name { get { return "IRCBridgeModule"; } } - public bool IsSharedModule + public void Initialise(IConfigSource config) { - get { return false; } - } - - public void Initialise(Scene scene, IConfigSource config) - { - // Do a once-only scan of the configuration file to make - // sure it's basically intact. - - if (!configured) + m_config = config.Configs["IRC"]; + if (m_config == null) { - configured = true; - - try - { - if ((m_config = config.Configs["IRC"]) == null) - { - m_log.InfoFormat("[IRC-Bridge] module not configured"); - return; - } - - if (!m_config.GetBoolean("enabled", false)) - { - m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); - return; - } - } - catch (Exception e) - { - m_log.ErrorFormat("[IRC-Bridge] configuration failed : {0}", e.Message); - return; - } + m_log.InfoFormat("[IRC-Bridge] module not configured"); + return; + } - enabled = true; + if (!m_config.GetBoolean("enabled", false)) + { + m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); + return; + } - if (config.Configs["RemoteAdmin"] != null) - { - password = config.Configs["RemoteAdmin"].GetString("access_password", password); - scene.CommsManager.HttpServer.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); - } + if (config.Configs["RemoteAdmin"] != null) + { + m_password = config.Configs["RemoteAdmin"].GetString("access_password", m_password); } - // Iff the IRC bridge is enabled, then each new region may be - // connected to IRC. But it should NOT be obligatory (and it - // is not). - // We have to do ALL of the startup here because PostInitialize - // is not called when a region gets created in-flight from the - // command line. - - if (enabled) + m_pluginEnabled = true; + } + + public void AddRegion(Scene scene) + { + if (m_pluginEnabled) { try { m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); - region = new RegionState(scene, m_config); - lock (m_regions) m_regions.Add(region); - region.Open(); + if (!String.IsNullOrEmpty(m_password)) + scene.CommsManager.HttpServer.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); + m_region = new RegionState(scene, m_config); + lock (m_regions) m_regions.Add(m_region); + m_region.Open(); } catch (Exception e) { @@ -132,34 +106,33 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } } - // This module can be called in-flight in which case PostInitialize - // is not called following Initialize. So no use is made of this - // call. - public void PostInitialise() + public void RegionLoaded(Scene scene) { } - // Called immediately before the region module is unloaded. Cleanup - // the region. - - public void Close() + public void RemoveRegion(Scene scene) { - if (!enabled) + if (!m_pluginEnabled) return; - if (region == null) + if (m_region == null) return; - region.Close(); + if (!String.IsNullOrEmpty(m_password)) + scene.CommsManager.HttpServer.RemoveXmlRPCHandler("irc_admin"); + + m_region.Close(); - if (m_regions.Contains(region)) + if (m_regions.Contains(m_region)) { - lock (m_regions) m_regions.Remove(region); + lock (m_regions) m_regions.Remove(m_region); } - } + public void Close() + { + } #endregion public static XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request) @@ -175,11 +148,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat bool found = false; string region = String.Empty; - if (password != String.Empty) + if (m_password != String.Empty) { if (!requestData.ContainsKey("password")) throw new Exception("Invalid request"); - if ((string)requestData["password"] != password) + if ((string)requestData["password"] != m_password) throw new Exception("Invalid request"); } -- cgit v1.1 From 912be7a2acee6f49eeee2f06879d9fff7ca183ab Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 22 May 2009 14:25:50 +0000 Subject: converting Chat module and Concierge module to new style region modules --- .../Avatar/Concierge/ConciergeModule.cs | 78 +++++++++++++++------- 1 file changed, 55 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 604b21d..687b2da 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -47,7 +47,7 @@ using OpenSim.Region.CoreModules.Avatar.Chat; namespace OpenSim.Region.OptionalModules.Avatar.Concierge { - public class ConciergeModule : ChatModule, IRegionModule + public class ConciergeModule : ChatModule, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -76,28 +76,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge internal object m_syncy = new object(); - #region IRegionModule Members - public override void Initialise(Scene scene, IConfigSource config) + internal bool m_enabled = false; + + #region ISharedRegionModule Members + public override void Initialise(IConfigSource config) { - try - { - if ((m_config = config.Configs["Concierge"]) == null) - { - //_log.InfoFormat("[Concierge]: no configuration section [Concierge] in OpenSim.ini: module not configured"); - return; - } + m_config = config.Configs["Concierge"]; - if (!m_config.GetBoolean("enabled", false)) - { - //_log.InfoFormat("[Concierge]: module disabled by OpenSim.ini configuration"); - return; - } + if (null == m_config) + { + m_log.Info("[Concierge]: no config found, plugin disabled"); + return; } - catch (Exception) + + if (!m_config.GetBoolean("enabled", false)) { - m_log.Info("[Concierge]: module not configured"); + m_log.Info("[Concierge]: plugin disabled by configuration"); return; } + m_enabled = true; + // check whether ChatModule has been disabled: if yes, // then we'll "stand in" @@ -140,6 +138,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge m_regions = new Regex(@regions, RegexOptions.Compiled | RegexOptions.IgnoreCase); } } + } + + + public override void AddRegion(Scene scene) + { + if (!m_enabled) return; scene.CommsManager.HttpServer.AddXmlRPCHandler("concierge_update_welcome", XmlRpcUpdateWelcomeMethod, false); @@ -169,6 +173,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge m_log.InfoFormat("[Concierge]: initialized for {0}", scene.RegionInfo.RegionName); } + public override void RemoveRegion(Scene scene) + { + if (!m_enabled) return; + + scene.CommsManager.HttpServer.RemoveXmlRPCHandler("concierge_update_welcome"); + + lock (m_syncy) + { + // unsubscribe from NewClient events + scene.EventManager.OnNewClient -= OnNewClient; + + // unsubscribe from *Chat events + scene.EventManager.OnChatFromWorld -= OnChatFromWorld; + if (!m_replacingChatModule) + scene.EventManager.OnChatFromClient -= OnChatFromClient; + scene.EventManager.OnChatBroadcast -= OnChatBroadcast; + + // unsubscribe from agent change events + scene.EventManager.OnMakeRootAgent -= OnMakeRootAgent; + scene.EventManager.OnMakeChildAgent -= OnMakeChildAgent; + + if (m_scenes.Contains(scene)) + { + m_scenes.Remove(scene); + } + + if (m_conciergedScenes.Contains(scene)) + { + m_conciergedScenes.Remove(scene); + } + } + m_log.InfoFormat("[Concierge]: removed {0}", scene.RegionInfo.RegionName); + } + public override void PostInitialise() { } @@ -181,12 +219,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { get { return "ConciergeModule"; } } - - public override bool IsSharedModule - { - get { return true; } - } - #endregion #region ISimChat Members -- cgit v1.1 From 31baeef469d72a9dc13cf4f56392b9f740f71cba Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sat, 23 May 2009 06:05:20 +0000 Subject: * Pipes requestors IP address through all XmlRpcRequest delegates. This is needed to be able to 'NAT-wrap' the login sequence. * If you have something using XmlRpc that isn't in core, change your method signature from: (XmlRpcRequest request) to: (XmlRpcRequest request, IPEndPoint remoteClient) --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 3 ++- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 5ebbd7b..61fac94 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Net; using System.Reflection; using log4net; using Nini.Config; @@ -135,7 +136,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } #endregion - public static XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request) + public static XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request, IPEndPoint remoteClient) { m_log.Info("[IRC-Bridge]: XML RPC Admin Entry"); diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 687b2da..df3402d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -635,7 +635,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } } - public XmlRpcResponse XmlRpcUpdateWelcomeMethod(XmlRpcRequest request) + public XmlRpcResponse XmlRpcUpdateWelcomeMethod(XmlRpcRequest request, IPEndPoint remoteClient) { m_log.Info("[Concierge]: processing UpdateWelcome request"); XmlRpcResponse response = new XmlRpcResponse(); -- cgit v1.1 From b8405356220b81f81aa13295c878f7fc469ea757 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Mon, 25 May 2009 09:32:44 +0000 Subject: dropping attendee list keeping from Concierge, relying on Scene.GetAvatars() instead now. [test #487] --- .../Avatar/Concierge/ConciergeModule.cs | 113 +++++---------------- 1 file changed, 26 insertions(+), 87 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index df3402d..4aee66d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -55,10 +55,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge private List m_scenes = new List(); private List m_conciergedScenes = new List(); - private Dictionary> m_sceneAttendees = - new Dictionary>(); - private Dictionary m_attendeeNames = - new Dictionary(); private bool m_replacingChatModule = false; @@ -103,6 +99,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { if (config.Configs["Chat"] == null) { + // if Chat module has not been configured it's + // enabled by default, so we are not going to + // replace it. m_replacingChatModule = false; } else @@ -312,15 +311,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge if (m_conciergedScenes.Contains(client.Scene)) { - m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, client.Scene.RegionInfo.RegionName); - RemoveFromAttendeeList(client.AgentId, client.Name, client.Scene); - lock (m_sceneAttendees) - { - AnnounceToAgentsRegion(client.Scene, String.Format(m_announceLeaving, client.Name, client.Scene.RegionInfo.RegionName, - m_sceneAttendees[client.Scene].Count)); - UpdateBroker(client.Scene); - m_attendeeNames.Remove(client.AgentId); - } + Scene scene = client.Scene as Scene; + m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, scene.RegionInfo.RegionName); + List avs = scene.GetAvatars(); + AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, client.Name, scene.RegionInfo.RegionName, avs.Count)); + UpdateBroker(scene, avs); } } @@ -329,12 +324,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { if (m_conciergedScenes.Contains(agent.Scene)) { - m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, agent.Scene.RegionInfo.RegionName); - AddToAttendeeList(agent.UUID, agent.Name, agent.Scene); - WelcomeAvatar(agent, agent.Scene); - AnnounceToAgentsRegion(agent.Scene, String.Format(m_announceEntering, agent.Name, agent.Scene.RegionInfo.RegionName, - m_sceneAttendees[agent.Scene].Count)); - UpdateBroker(agent.Scene); + Scene scene = agent.Scene; + m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, scene.RegionInfo.RegionName); + List avs = scene.GetAvatars(); + WelcomeAvatar(agent, scene); + AnnounceToAgentsRegion(scene, String.Format(m_announceEntering, agent.Name, + scene.RegionInfo.RegionName, avs.Count)); + UpdateBroker(scene, avs); } } @@ -343,49 +339,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { if (m_conciergedScenes.Contains(agent.Scene)) { - m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, agent.Scene.RegionInfo.RegionName); - RemoveFromAttendeeList(agent.UUID, agent.Name, agent.Scene); - AnnounceToAgentsRegion(agent.Scene, String.Format(m_announceLeaving, agent.Name, agent.Scene.RegionInfo.RegionName, - m_sceneAttendees[agent.Scene].Count)); - UpdateBroker(agent.Scene); - } - } - - protected void AddToAttendeeList(UUID agentID, string name, Scene scene) - { - lock (m_sceneAttendees) - { - if (!m_sceneAttendees.ContainsKey(scene)) - m_sceneAttendees[scene] = new List(); - - List attendees = m_sceneAttendees[scene]; - if (!attendees.Contains(agentID)) - { - attendees.Add(agentID); - m_attendeeNames[agentID] = name; - } - } - } - - protected void RemoveFromAttendeeList(UUID agentID, String name, IScene scene) - { - lock (m_sceneAttendees) - { - if (!m_sceneAttendees.ContainsKey(scene)) - { - m_log.WarnFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); - return; - } - - List attendees = m_sceneAttendees[scene]; - if (!attendees.Contains(agentID)) - { - m_log.WarnFormat("[Concierge]: avatar {0} must have sneaked in to region {1} earlier", - name, scene.RegionInfo.RegionName); - return; - } - - attendees.Remove(agentID); + Scene scene = agent.Scene; + m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, scene.RegionInfo.RegionName); + List avs = scene.GetAvatars(); + AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, agent.Name, + scene.RegionInfo.RegionName, avs.Count)); + UpdateBroker(scene, avs); } } @@ -404,29 +363,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } } - protected void UpdateBroker(IScene scene) + protected void UpdateBroker(IScene scene, List avatars) { if (String.IsNullOrEmpty(m_brokerURI)) return; string uri = String.Format(m_brokerURI, scene.RegionInfo.RegionName, scene.RegionInfo.RegionID); - // get attendee list for the scene - List attendees; - lock (m_sceneAttendees) - { - if (!m_sceneAttendees.ContainsKey(scene)) - { - m_log.DebugFormat("[Concierge]: attendee list missing for region {0}", scene.RegionInfo.RegionName); - return; - } - - attendees = m_sceneAttendees[scene]; - } - // create XML sniplet StringBuilder list = new StringBuilder(); - if (0 == attendees.Count) + if (0 == avatars.Count) { list.Append(String.Format("", scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, @@ -435,19 +381,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge else { list.Append(String.Format("\n", - attendees.Count, scene.RegionInfo.RegionName, + avatars.Count, scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); - lock (m_sceneAttendees) + foreach (ScenePresence av in avatars) { - foreach (UUID uuid in attendees) - { - if (m_attendeeNames.ContainsKey(uuid)) - { - string name = m_attendeeNames[uuid]; - list.Append(String.Format(" \n", name, uuid)); - } - } + list.Append(String.Format(" \n", av.Name, av.UUID)); } list.Append(""); } -- cgit v1.1 From 840de6c036570d559ec6924cd8405d3f34a99fdd Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Mon, 1 Jun 2009 06:37:14 +0000 Subject: Minor: Change OpenSim to OpenSimulator in older copyright headers and LICENSE.txt. --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- .../OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 2 +- .../OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 2 +- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 2 +- .../Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 2 +- .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 2 +- .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 2f3de69..89eecf8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 61fac94..b17a7e1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index ce8917b..2f1dbc1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index 6733120..ba3f3e5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 4aee66d..6ef30c4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index 039cc2f..89071cd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 377a824..eee122b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 4723a93..84d7c4c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs index 43cccf4..302be4a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index a7ef40a..1d4cde5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 24d539f..31295f8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 40481a8..5d8760f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -9,7 +9,7 @@ * * 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 OpenSim Project nor the + * * 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. * -- cgit v1.1 From a23d64dec1cbf88abc3c7e84664a683dee534e4a Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Wed, 10 Jun 2009 04:28:56 +0000 Subject: Formatting cleanup. --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 6 +++--- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 10 +++++----- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 2 +- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 89eecf8..f03e5fc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -404,7 +404,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private bool IsAConnectionMatchFor(ChannelState cs) { - return ( + return ( Server == cs.Server && IrcChannel == cs.IrcChannel && Port == cs.Port && @@ -419,7 +419,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private bool IsAPerfectMatchFor(ChannelState cs) { - return ( IsAConnectionMatchFor(cs) && + return (IsAConnectionMatchFor(cs) && RelayChannelOut == cs.RelayChannelOut && PrivateMessageFormat == cs.PrivateMessageFormat && NoticeMessageFormat == cs.NoticeMessageFormat && @@ -598,7 +598,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { foreach (ChannelState cs in IRCBridgeModule.m_channels) { - if ( p_irc == cs.irc) + if (p_irc == cs.irc) { // This non-IRC differentiator moved to here diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index eee122b..caec43d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -147,7 +147,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - response["str_response_string"] = String.Format( + response["str_response_string"] = String.Format( "\r\n" + "\r\n" + "
\r\n" + @@ -184,7 +184,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - response["str_response_string"] = String.Format( + response["str_response_string"] = String.Format( "\r\n" + "\r\n" + "
\r\n" + @@ -230,7 +230,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - response["str_response_string"] = String.Format( + response["str_response_string"] = String.Format( "\r\n" + "\r\n" + "
\r\n" + @@ -263,7 +263,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - response["str_response_string"] = String.Format( + response["str_response_string"] = String.Format( "\r\n" + "\r\n" + "
\r\n" + @@ -317,7 +317,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // response["content_type"] = "text/xml"; // response["keepalive"] = false; // response["int_response_code"] = 200; -// response["str_response_string"] = String.Format( +// response["str_response_string"] = String.Format( // "\r\n" + // "\r\n" + // "
\r\n" + diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 84d7c4c..de78f5f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -556,7 +556,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; - response["str_response_string"] = String.Format( + response["str_response_string"] = String.Format( "\r\n" + "\r\n"+ "{0}\r\n" + diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 5d8760f..bc421c2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -1234,7 +1234,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // UDP version doesn't seem to behave nicely. But we're going to send it out here // with an empty group membership to hopefully remove groups being displayed due // to the core Groups Stub - remoteClient.SendGroupMembership( new GroupMembershipData[0] ); + remoteClient.SendGroupMembership(new GroupMembershipData[0]); GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); -- cgit v1.1 From f243dddc04a16a175e52e88fb34d38fb6fb643e5 Mon Sep 17 00:00:00 2001 From: Arthur Valadares Date: Thu, 18 Jun 2009 14:33:35 +0000 Subject: * Corrected CAPS namespaces * "luke, use the sed" --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 4 ++-- .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 2 +- .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index de78f5f..ce68522 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -42,12 +42,12 @@ using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Communications.Capabilities; +using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Communications.Capabilities.Caps; +using Caps = OpenSim.Framework.Capabilities.Caps; using System.Text.RegularExpressions; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 31295f8..9625342 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -42,7 +42,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Communications.Capabilities.Caps; +using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index bc421c2..da45177 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -42,7 +42,7 @@ using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Communications.Capabilities.Caps; +using Caps = OpenSim.Framework.Capabilities.Caps; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; -- cgit v1.1 From dfd4e78fc0d8ea9210563d4d374e3459436b5c39 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Fri, 19 Jun 2009 12:21:33 +0000 Subject: From: Rob Smart Makes an avatars personal voice indicator work with Freeswitch (though not other avatars indicators) --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 7 +++++++ .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 14 ++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index 89071cd..ad2b7e4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -70,6 +70,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice + + + + + + + diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index ce68522..469ac2f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -790,22 +790,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice landName, land.LocalID, landUUID); } System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); - channelUri = String.Format("sip:confctl-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); - //channelUri="sip:confctl-3001@9.20.151.43"; - //channelUri="sip:opensimconf-3001@9.20.151.43"; + // slvoice handles the sip address differently if it begins with confctl, hiding it from the user in the friends list. however it also disables + // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator. + channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); + return channelUri; } private static bool CustomCertificateValidation(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { - //if (cert.Subject == "E=root@lindenlab.com, CN=*.vaak.lindenlab.com, O=\"Linden Lab, Inc.\", L=San Francisco, S=California, C=US") - //{ + return true; - //} - - //return false; + } } public class MonoCert : ICertificatePolicy -- cgit v1.1 From c310fb11f492419de60b4bf8e5bb234e4589b336 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 10 Jul 2009 02:22:26 +0000 Subject: Remove all references to HttpServer from CommsManager (all incarnations) Change all uses of the HttpServer properties to use the new singleton --- .../Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 4 ++-- .../OptionalModules/Avatar/Concierge/ConciergeModule.cs | 4 ++-- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index b17a7e1..0c696e3 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -90,7 +90,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); if (!String.IsNullOrEmpty(m_password)) - scene.CommsManager.HttpServer.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); + MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); m_region = new RegionState(scene, m_config); lock (m_regions) m_regions.Add(m_region); m_region.Open(); @@ -121,7 +121,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat return; if (!String.IsNullOrEmpty(m_password)) - scene.CommsManager.HttpServer.RemoveXmlRPCHandler("irc_admin"); + MainServer.Instance.RemoveXmlRPCHandler("irc_admin"); m_region.Close(); diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 6ef30c4..96b6888 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -144,7 +144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { if (!m_enabled) return; - scene.CommsManager.HttpServer.AddXmlRPCHandler("concierge_update_welcome", XmlRpcUpdateWelcomeMethod, false); + MainServer.Instance.AddXmlRPCHandler("concierge_update_welcome", XmlRpcUpdateWelcomeMethod, false); lock (m_syncy) { @@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { if (!m_enabled) return; - scene.CommsManager.HttpServer.RemoveXmlRPCHandler("concierge_update_welcome"); + MainServer.Instance.RemoveXmlRPCHandler("concierge_update_welcome"); lock (m_syncy) { diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 469ac2f..5c562ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -170,31 +170,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // - signout: viv_signout.php if (UseProxy) { - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix), + MainServer.Instance.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix), ForwardProxyRequest); } else { - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); // RestStreamHandler h = new // RestStreamHandler("GET", // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); - // scene.CommsManager.HttpServer.AddStreamHandler(h); + // MainServer.Instance.AddStreamHandler(h); - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceSigninHTTPHandler); // set up http request handlers to provide // on-demand FreeSwitch configuration to // FreeSwitch's mod_curl_xml - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), + MainServer.Instance.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), FreeSwitchConfigHTTPHandler); - scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceBuddyHTTPHandler); } -- cgit v1.1 From 8ecfc9a717c259fd238312888f6178b3f86c008a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 10 Jul 2009 20:17:13 +0000 Subject: Committing the interface change and the addition to the modules to get the ball rolling on replacable modules. No user functionality yet --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 5 +++++ OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 5 +++++ .../OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 5 +++++ .../Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 5 +++++ 4 files changed, 20 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 0c696e3..d7e7a56 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -54,6 +54,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat #region INonSharedRegionModule Members + public Type ReplacableInterface + { + get { return null; } + } + public string Name { get { return "IRCBridgeModule"; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 96b6888..21c0ab1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -214,6 +214,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { } + public Type ReplacableInterface + { + get { return null; } + } + public override string Name { get { return "ConciergeModule"; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index 9625342..4095041 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs @@ -177,6 +177,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_msgTransferModule = null; } + public Type ReplacableInterface + { + get { return null; } + } + public string Name { get { return "XmlRpcGroupsMessaging"; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index da45177..b43a6ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -222,6 +222,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_clientRequestIDFlushTimer.Stop(); } + public Type ReplacableInterface + { + get { return null; } + } + public string Name { get { return "XmlRpcGroupsModule"; } -- cgit v1.1 From 16b4e38f6822e8242db9cf0f527bfbe4037283fc Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Sat, 11 Jul 2009 08:10:54 +0000 Subject: fixing warning re ReplacableInterface() --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 21c0ab1..bf6d5e7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -214,7 +214,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { } - public Type ReplacableInterface + new public Type ReplacableInterface { get { return null; } } -- cgit v1.1 From 7a4abf0def0b2d9a89bec354ad175c342e7f2106 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Sat, 11 Jul 2009 08:16:47 +0000 Subject: From: Dr Scofield & Alan Webb this commit finally adds the VivoxVoiceModule: it supports positional as well as conference call type voice (currently only per region server), region and parcel voice, speaker indication (LL client family), direct avtar-to-avatar voice chat. NOTE: you need to obtain an customer admin account from Vivox to be able to use this module --- DON'T ask me about how to about an admin account, i've NO clue, we just wrote this code. --- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 1301 ++++++++++++++++++++ 1 file changed, 1301 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs new file mode 100644 index 0000000..12ad9b8 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -0,0 +1,1301 @@ +/* + * 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 OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Net; +using System.Text; +using System.Xml; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using OpenMetaverse; +using log4net; +using Nini.Config; +using Nwc.XmlRpc; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Communications.Capabilities; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; + +namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice +{ + public class VivoxVoiceModule : ISharedRegionModule + { + + // channel distance model values + public const int CHAN_DIST_NONE = 0; // no attenuation + public const int CHAN_DIST_INVERSE = 1; // inverse distance attenuation + public const int CHAN_DIST_LINEAR = 2; // linear attenuation + public const int CHAN_DIST_EXPONENT = 3; // exponential attenuation + public const int CHAN_DIST_DEFAULT = CHAN_DIST_LINEAR; + + // channel type values + public static readonly string CHAN_TYPE_POSITIONAL = "positional"; + public static readonly string CHAN_TYPE_CHANNEL = "channel"; + public static readonly string CHAN_TYPE_DEFAULT = CHAN_TYPE_POSITIONAL; + + // channel mode values + public static readonly string CHAN_MODE_OPEN = "open"; + public static readonly string CHAN_MODE_LECTURE = "lecture"; + public static readonly string CHAN_MODE_PRESENTATION = "presentation"; + public static readonly string CHAN_MODE_AUDITORIUM = "auditorium"; + public static readonly string CHAN_MODE_DEFAULT = CHAN_MODE_OPEN; + + // unconstrained default values + public const double CHAN_ROLL_OFF_DEFAULT = 2.0; // rate of attenuation + public const double CHAN_ROLL_OFF_MIN = 1.0; + public const double CHAN_ROLL_OFF_MAX = 4.0; + public const int CHAN_MAX_RANGE_DEFAULT = 80; // distance at which channel is silent + public const int CHAN_MAX_RANGE_MIN = 0; + public const int CHAN_MAX_RANGE_MAX = 160; + public const int CHAN_CLAMPING_DISTANCE_DEFAULT = 10; // distance before attenuation applies + public const int CHAN_CLAMPING_DISTANCE_MIN = 0; + public const int CHAN_CLAMPING_DISTANCE_MAX = 160; + + // Infrastructure + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly Object vlock = new Object(); + + // Capability strings + private static readonly string m_parcelVoiceInfoRequestPath = "0107/"; + private static readonly string m_provisionVoiceAccountRequestPath = "0108/"; + private static readonly string m_chatSessionRequestPath = "0109/"; + + // Control info, e.g. vivox server, admin user, admin password + private static bool m_pluginEnabled = false; + private static bool m_adminConnected = false; + + private static string m_vivoxServer; + private static string m_vivoxSipUri; + private static string m_vivoxVoiceAccountApi; + private static string m_vivoxAdminUser; + private static string m_vivoxAdminPassword; + private static string m_authToken = String.Empty; + + private static int m_vivoxChannelDistanceModel; + private static double m_vivoxChannelRollOff; + private static int m_vivoxChannelMaximumRange; + private static string m_vivoxChannelMode; + private static string m_vivoxChannelType; + private static int m_vivoxChannelClampingDistance; + + private static Dictionary m_parents = new Dictionary(); + private static bool m_dumpXml; + + private IConfig m_config; + + public void Initialise(IConfigSource config) + { + + m_config = config.Configs["VivoxVoice"]; + + if (null == m_config) + { + m_log.Info("[VivoxVoice] no config found, plugin disabled"); + return; + } + + if (!m_config.GetBoolean("enabled", false)) + { + m_log.Info("[VivoxVoice] plugin disabled by configuration"); + return; + } + + try + { + // retrieve configuration variables + m_vivoxServer = m_config.GetString("vivox_server", String.Empty); + m_vivoxSipUri = m_config.GetString("vivox_sip_uri", String.Empty); + m_vivoxAdminUser = m_config.GetString("vivox_admin_user", String.Empty); + m_vivoxAdminPassword = m_config.GetString("vivox_admin_password", String.Empty); + + m_vivoxChannelDistanceModel = m_config.GetInt("vivox_channel_distance_model", CHAN_DIST_DEFAULT); + m_vivoxChannelRollOff = m_config.GetDouble("vivox_channel_roll_off", CHAN_ROLL_OFF_DEFAULT); + m_vivoxChannelMaximumRange = m_config.GetInt("vivox_channel_max_range", CHAN_MAX_RANGE_DEFAULT); + m_vivoxChannelMode = m_config.GetString("vivox_channel_mode", CHAN_MODE_DEFAULT).ToLower(); + m_vivoxChannelType = m_config.GetString("vivox_channel_type", CHAN_TYPE_DEFAULT).ToLower(); + m_vivoxChannelClampingDistance = m_config.GetInt("vivox_channel_clamping_distance", + CHAN_CLAMPING_DISTANCE_DEFAULT); + m_dumpXml = m_config.GetBoolean("dump_xml", false); + + // Validate against constraints and default if necessary + if (m_vivoxChannelRollOff < CHAN_ROLL_OFF_MIN || m_vivoxChannelRollOff > CHAN_ROLL_OFF_MAX) + { + m_log.WarnFormat("[VivoxVoice] Invalid value for roll off ({0}), reset to {1}.", + m_vivoxChannelRollOff, CHAN_ROLL_OFF_DEFAULT); + m_vivoxChannelRollOff = CHAN_ROLL_OFF_DEFAULT; + } + + if (m_vivoxChannelMaximumRange < CHAN_MAX_RANGE_MIN || m_vivoxChannelMaximumRange > CHAN_MAX_RANGE_MAX) + { + m_log.WarnFormat("[VivoxVoice] Invalid value for maximum range ({0}), reset to {1}.", + m_vivoxChannelMaximumRange, CHAN_MAX_RANGE_DEFAULT); + m_vivoxChannelMaximumRange = CHAN_MAX_RANGE_DEFAULT; + } + + if (m_vivoxChannelClampingDistance < CHAN_CLAMPING_DISTANCE_MIN || + m_vivoxChannelClampingDistance > CHAN_CLAMPING_DISTANCE_MAX) + { + m_log.WarnFormat("[VivoxVoice] Invalid value for clamping distance ({0}), reset to {1}.", + m_vivoxChannelClampingDistance, CHAN_CLAMPING_DISTANCE_DEFAULT); + m_vivoxChannelClampingDistance = CHAN_CLAMPING_DISTANCE_DEFAULT; + } + + switch (m_vivoxChannelMode) + { + case "open" : break; + case "lecture" : break; + case "presentation" : break; + case "auditorium" : break; + default : + m_log.WarnFormat("[VivoxVoice] Invalid value for channel mode ({0}), reset to {1}.", + m_vivoxChannelMode, CHAN_MODE_DEFAULT); + m_vivoxChannelMode = CHAN_MODE_DEFAULT; + break; + } + + switch (m_vivoxChannelType) + { + case "positional" : break; + case "channel" : break; + default : + m_log.WarnFormat("[VivoxVoice] Invalid value for channel type ({0}), reset to {1}.", + m_vivoxChannelType, CHAN_TYPE_DEFAULT); + m_vivoxChannelType = CHAN_TYPE_DEFAULT; + break; + } + + m_vivoxVoiceAccountApi = String.Format("http://{0}/api2", m_vivoxServer); + + // Admin interface required values + if (String.IsNullOrEmpty(m_vivoxServer) || + String.IsNullOrEmpty(m_vivoxSipUri) || + String.IsNullOrEmpty(m_vivoxAdminUser) || + String.IsNullOrEmpty(m_vivoxAdminPassword)) + { + m_log.Error("[VivoxVoice] plugin mis-configured"); + m_log.Info("[VivoxVoice] plugin disabled: incomplete configuration"); + return; + } + + m_log.InfoFormat("[VivoxVoice] using vivox server {0}", m_vivoxServer); + + // Get admin rights and cleanup any residual channel definition + + DoAdminLogin(); + + m_pluginEnabled = true; + + m_log.Info("[VivoxVoice] plugin enabled"); + + } + catch (Exception e) + { + m_log.ErrorFormat("[VivoxVoice] plugin initialization failed: {0}", e.Message); + m_log.DebugFormat("[VivoxVoice] plugin initialization failed: {0}", e.ToString()); + return; + } + } + + + // Called to indicate that the module has been added to the region + public void AddRegion(Scene scene) + { + + if (m_pluginEnabled) + { + lock (vlock) + { + + string channelId; + + string sceneUUID = scene.RegionInfo.RegionID.ToString(); + string sceneName = scene.RegionInfo.RegionName; + + // Make sure that all local channels are deleted. + // So we have to search for the children, and then do an + // iteration over the set of chidren identified. + // This assumes that there is just one directory per + // region. + + if (VivoxTryGetDirectory(sceneUUID + "D", out channelId)) + { + m_log.DebugFormat("[VivoxVoice]: region {0}: uuid {1}: located directory id {2}", + sceneName, sceneUUID, channelId); + + XmlElement children = VivoxListChildren(channelId); + string count; + + if (XmlFind(children, "response.level0.channel-search.count", out count)) + { + int cnum = Convert.ToInt32(count); + for (int i = 0; i < cnum; i++) + { + string id; + if (XmlFind(children, "response.level0.channel-search.channels.channels.level4.id", i, out id)) + { + if (!IsOK(VivoxDeleteChannel(channelId, id))) + m_log.WarnFormat("[VivoxVoice] Channel delete failed {0}:{1}:{2}", i, channelId, id); + } + } + } + } + else + { + if (!VivoxTryCreateDirectory(sceneUUID + "D", sceneName, out channelId)) + { + m_log.WarnFormat("[VivoxVoice] Create failed <{0}:{1}:{2}>", + "*", sceneUUID, sceneName); + channelId = String.Empty; + } + } + + + // Create a dictionary entry unconditionally. This eliminates the + // need to check for a parent in the core code. The end result is + // the same, if the parent table entry is an empty string, then + // region channels will be created as first-level channels. + + lock (m_parents) + if (m_parents.ContainsKey(sceneUUID)) + { + RemoveRegion(scene); + m_parents.Add(sceneUUID, channelId); + } + else + { + m_parents.Add(sceneUUID, channelId); + } + + } + + // we need to capture scene in an anonymous method + // here as we need it later in the callbacks + scene.EventManager.OnRegisterCaps += delegate(UUID agentID, Caps caps) + { + OnRegisterCaps(scene, agentID, caps); + }; + + } + + } + + // Called to indicate that all loadable modules have now been added + public void RegionLoaded(Scene scene) + { + // Do nothing. + } + + // Called to indicate that the region is going away. + public void RemoveRegion(Scene scene) + { + + if (m_pluginEnabled) + { + lock (vlock) + { + + string channelId; + + string sceneUUID = scene.RegionInfo.RegionID.ToString(); + string sceneName = scene.RegionInfo.RegionName; + + // Make sure that all local channels are deleted. + // So we have to search for the children, and then do an + // iteration over the set of chidren identified. + // This assumes that there is just one directory per + // region. + + if (VivoxTryGetDirectory(sceneUUID + "D", out channelId)) + { + + m_log.DebugFormat("[VivoxVoice]: region {0}: uuid {1}: located directory id {2}", + sceneName, sceneUUID, channelId); + + XmlElement children = VivoxListChildren(channelId); + string count; + + if (XmlFind(children, "response.level0.channel-search.count", out count)) + { + int cnum = Convert.ToInt32(count); + for (int i = 0; i < cnum; i++) + { + string id; + if (XmlFind(children, "response.level0.channel-search.channels.channels.level4.id", i, out id)) + { + if (!IsOK(VivoxDeleteChannel(channelId, id))) + m_log.WarnFormat("[VivoxVoice] Channel delete failed {0}:{1}:{2}", i, channelId, id); + } + } + } + } + + if (!IsOK(VivoxDeleteChannel(null, channelId))) + m_log.WarnFormat("[VivoxVoice] Parent channel delete failed {0}:{1}:{2}", sceneName, sceneUUID, channelId); + + // Remove the channel umbrella entry + + lock (m_parents) + { + if (m_parents.ContainsKey(sceneUUID)) + { + m_parents.Remove(sceneUUID); + } + } + } + } + } + + public void PostInitialise() + { + // Do nothing. + } + + public void Close() + { + if (m_pluginEnabled) + VivoxLogout(); + } + + public string Name + { + get { return "VivoxVoiceModule"; } + } + + public bool IsSharedModule + { + get { return true; } + } + + // + // OnRegisterCaps is invoked via the scene.EventManager + // everytime OpenSim hands out capabilities to a client + // (login, region crossing). We contribute two capabilities to + // the set of capabilities handed back to the client: + // ProvisionVoiceAccountRequest and ParcelVoiceInfoRequest. + // + // ProvisionVoiceAccountRequest allows the client to obtain + // the voice account credentials for the avatar it is + // controlling (e.g., user name, password, etc). + // + // ParcelVoiceInfoRequest is invoked whenever the client + // changes from one region or parcel to another. + // + // Note that OnRegisterCaps is called here via a closure + // delegate containing the scene of the respective region (see + // Initialise()). + // + public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps) + { + m_log.DebugFormat("[VivoxVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + + string capsBase = "/CAPS/" + caps.CapsObjectPath; + caps.RegisterHandler("ProvisionVoiceAccountRequest", + new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ProvisionVoiceAccountRequest(scene, request, path, param, + agentID, caps); + })); + caps.RegisterHandler("ParcelVoiceInfoRequest", + new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ParcelVoiceInfoRequest(scene, request, path, param, + agentID, caps); + })); + caps.RegisterHandler("ChatSessionRequest", + new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ChatSessionRequest(scene, request, path, param, + agentID, caps); + })); + } + + /// + /// Callback for a client request for Voice Account Details + /// + /// current scene object of the client + /// + /// + /// + /// + /// + /// + public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, + UUID agentID, Caps caps) + { + try + { + + ScenePresence avatar = null; + string avatarName = null; + + if (scene == null) throw new Exception("[VivoxVoice][PROVISIONVOICE] Invalid scene"); + + avatar = scene.GetScenePresence(agentID); + while (avatar == null) + { + Thread.Sleep(100); + avatar = scene.GetScenePresence(agentID); + } + + avatarName = avatar.Name; + + m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID); + m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", + request, path, param); + + XmlElement resp; + bool retry = false; + string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); + string password = new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16); + string code = String.Empty; + + agentname = agentname.Replace('+', '-').Replace('/', '_'); + + do + { + resp = VivoxGetAccountInfo(agentname); + + if (XmlFind(resp, "response.level0.status", out code)) + { + if (code != "OK") + { + if (XmlFind(resp, "response.level0.body.code", out code)) + { + // If the request was recognized, then this should be set to something + switch (code) + { + case "201" : // Account expired + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : expired credentials", + avatarName); + m_adminConnected = false; + retry = DoAdminLogin(); + break; + + case "202" : // Missing credentials + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : missing credentials", + avatarName); + break; + + case "212" : // Not authorized + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : not authorized", + avatarName); + break; + + case "300" : // Required parameter missing + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : parameter missing", + avatarName); + break; + + case "403" : // Account does not exist + resp = VivoxCreateAccount(agentname,password); + // Note: This REALLY MUST BE status. Create Account does not return code. + if (XmlFind(resp, "response.level0.status", out code)) + { + switch (code) + { + case "201" : // Account expired + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : expired credentials", + avatarName); + m_adminConnected = false; + retry = DoAdminLogin(); + break; + + case "202" : // Missing credentials + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : missing credentials", + avatarName); + break; + + case "212" : // Not authorized + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : not authorized", + avatarName); + break; + + case "300" : // Required parameter missing + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : parameter missing", + avatarName); + break; + + case "400" : // Create failed + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : create failed", + avatarName); + break; + } + } + break; + + case "404" : // Failed to retrieve account + m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : retrieve failed"); + // [AMW] Sleep and retry for a fixed period? Or just abandon? + break; + } + } + } + } + } while (retry); + + if (code != "OK") + { + m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: Get Account Request failed for \"{0}\"", avatarName); + throw new Exception("Unable to execute request"); + } + + // Unconditionally change the password on each request + VivoxPassword(agentname, password); + + LLSDVoiceAccountResponse voiceAccountResponse = + new LLSDVoiceAccountResponse(agentname, password, m_vivoxSipUri, m_vivoxVoiceAccountApi); + + string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); + + m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); + + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[VivoxVoice][PROVISIONVOICE]: : {0}, retry later", e.Message); + m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: : {0} failed", e.ToString()); + return ""; + } + } + + /// + /// Callback for a client request for ParcelVoiceInfo + /// + /// current scene object of the client + /// + /// + /// + /// + /// + /// + public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param, + UUID agentID, Caps caps) + { + ScenePresence avatar = scene.GetScenePresence(agentID); + string avatarName = avatar.Name; + + // - check whether we have a region channel in our cache + // - if not: + // create it and cache it + // - send it to the client + // - send channel_uri: as "sip:regionID@m_sipDomain" + try + { + LLSDParcelVoiceInfoResponse parcelVoiceInfo; + string channel_uri; + + if (null == scene.LandChannel) + throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available", + scene.RegionInfo.RegionName, avatarName)); + + // get channel_uri: check first whether estate + // settings allow voice, then whether parcel allows + // voice, if all do retrieve or obtain the parcel + // voice channel + LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + + m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", + scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); + // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}", + // avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); + + // TODO: EstateSettings don't seem to get propagated... + if (!scene.RegionInfo.EstateSettings.AllowVoice) + { + m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings", + scene.RegionInfo.RegionName); + channel_uri = String.Empty; + } + + if ((land.Flags & (uint)Parcel.ParcelFlags.AllowVoiceChat) == 0) + { + m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", + scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); + channel_uri = String.Empty; + } + else + { + channel_uri = RegionGetOrCreateChannel(scene, land); + } + + // fill in our response to the client + Hashtable creds = new Hashtable(); + creds["channel_uri"] = channel_uri; + + parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); + string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); + + m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", + scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); + return r; + } + catch (Exception e) + { + m_log.ErrorFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later", + scene.RegionInfo.RegionName, avatarName, e.Message); + m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed", + scene.RegionInfo.RegionName, avatarName, e.ToString()); + + return ""; + } + } + + + /// + /// Callback for a client request for a private chat channel + /// + /// current scene object of the client + /// + /// + /// + /// + /// + /// + public string ChatSessionRequest(Scene scene, string request, string path, string param, + UUID agentID, Caps caps) + { + ScenePresence avatar = scene.GetScenePresence(agentID); + string avatarName = avatar.Name; + + m_log.DebugFormat("[VivoxVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", + avatarName, request, path, param); + return "true"; + } + + + private string RegionGetOrCreateChannel(Scene scene, LandData land) + { + + string channelUri = null; + string channelId = null; + + string landUUID; + string landName; + string parentId; + + lock (m_parents) parentId = m_parents[scene.RegionInfo.RegionID.ToString()]; + + // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same + // as the directory ID. Otherwise, it reflects the parcel's ID. + + if (land.LocalID != 1 && (land.Flags & (uint)Parcel.ParcelFlags.UseEstateVoiceChan) == 0) + { + landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); + landUUID = land.GlobalID.ToString(); + m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", + landName, land.LocalID, landUUID); + } + else + { + landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, scene.RegionInfo.RegionName); + landUUID = scene.RegionInfo.RegionID.ToString(); + m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", + landName, land.LocalID, landUUID); + } + + lock (vlock) + { + if (!VivoxTryGetChannel(parentId, landUUID, out channelId, out channelUri) && + !VivoxTryCreateChannel(parentId, landUUID, landName, out channelUri)) + throw new Exception("vivox channel uri not available"); + + m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parent channel id {1}: retrieved parcel channel_uri {2} ", + landName, parentId, channelUri); + + + } + + return channelUri; + } + + + private static readonly string m_vivoxLoginPath = "http://{0}/api2/viv_signin.php?userid={1}&pwd={2}"; + + /// + /// Perform administrative login for Vivox. + /// Returns a hash table containing values returned from the request. + /// + private XmlElement VivoxLogin(string name, string password) + { + string requrl = String.Format(m_vivoxLoginPath, m_vivoxServer, name, password); + return VivoxCall(requrl, false); + } + + + private static readonly string m_vivoxLogoutPath = "http://{0}/api2/viv_signout.php?auth_token={1}"; + + /// + /// Perform administrative logout for Vivox. + /// + private XmlElement VivoxLogout() + { + string requrl = String.Format(m_vivoxLogoutPath, m_vivoxServer, m_authToken); + return VivoxCall(requrl, false); + } + + + private static readonly string m_vivoxGetAccountPath = "http://{0}/api2/viv_get_acct.php?auth_token={1}&user_name={2}"; + + /// + /// Retrieve account information for the specified user. + /// Returns a hash table containing values returned from the request. + /// + private XmlElement VivoxGetAccountInfo(string user) + { + string requrl = String.Format(m_vivoxGetAccountPath, m_vivoxServer, m_authToken, user); + return VivoxCall(requrl, true); + } + + + private static readonly string m_vivoxNewAccountPath = "http://{0}/api2/viv_adm_acct_new.php?username={1}&pwd={2}&auth_token={3}"; + + /// + /// Creates a new account. + /// For now we supply the minimum set of values, which + /// is user name and password. We *can* supply a lot more + /// demographic data. + /// + private XmlElement VivoxCreateAccount(string user, string password) + { + string requrl = String.Format(m_vivoxNewAccountPath, m_vivoxServer, user, password, m_authToken); + return VivoxCall(requrl, true); + } + + + private static readonly string m_vivoxPasswordPath = "http://{0}/api2/viv_adm_password.php?user_name={1}&new_pwd={2}&auth_token={3}"; + + /// + /// Change the user's password. + /// + private XmlElement VivoxPassword(string user, string password) + { + string requrl = String.Format(m_vivoxPasswordPath, m_vivoxServer, user, password, m_authToken); + return VivoxCall(requrl, true); + } + + + private static readonly string m_vivoxChannelPath = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_name={2}&auth_token={3}"; + + /// + /// Create a channel. + /// Once again, there a multitude of options possible. In the simplest case + /// we specify only the name and get a non-persistent cannel in return. Non + /// persistent means that the channel gets deleted if no-one uses it for + /// 5 hours. To accomodate future requirements, it may be a good idea to + /// initially create channels under the umbrella of a parent ID based upon + /// the region name. That way we have a context for side channels, if those + /// are required in a later phase. + /// + /// In this case the call handles parent and description as optional values. + /// + + private bool VivoxTryCreateChannel(string parent, string channelId, string description, out string channelUri) + { + string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", channelId, m_authToken); + + if (parent != null && parent != String.Empty) + { + requrl = String.Format("{0}&chan_parent={1}", requrl, parent); + } + if (description != null && description != String.Empty) + { + requrl = String.Format("{0}&chan_desc={1}", requrl, description); + } + + requrl = String.Format("{0}&chan_type={1}", requrl, m_vivoxChannelType); + requrl = String.Format("{0}&chan_mode={1}", requrl, m_vivoxChannelMode); + requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff); + requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel); + requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange); + requrl = String.Format("{0}&chan_ckamping_distance={1}", requrl, m_vivoxChannelClampingDistance); + + XmlElement resp = VivoxCall(requrl, true); + if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri)) + return true; + + channelUri = String.Empty; + return false; + } + + /// + /// Create a directory. + /// Create a channel with an unconditional type of "dir" (indicating directory). + /// This is used to create an arbitrary name tree for partitioning of the + /// channel name space. + /// The parent and description are optional values. + /// + + private bool VivoxTryCreateDirectory(string dirId, string description, out string channelId) + { + string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", dirId, m_authToken); + + // if (parent != null && parent != String.Empty) + // { + // requrl = String.Format("{0}&chan_parent={1}", requrl, parent); + // } + + if (description != null && description != String.Empty) + { + requrl = String.Format("{0}&chan_desc={1}", requrl, description); + } + requrl = String.Format("{0}&chan_type={1}", requrl, "dir"); + + XmlElement resp = VivoxCall(requrl, true); + if (IsOK(resp) && XmlFind(resp, "response.level0.body.chan_id", out channelId)) + return true; + + channelId = String.Empty; + return false; + } + + private static readonly string m_vivoxChannelSearchPath = "http://{0}/api2/viv_chan_search.php?cond_channame={1}&auth_token={2}"; + + /// + /// Retrieve a channel. + /// Once again, there a multitude of options possible. In the simplest case + /// we specify only the name and get a non-persistent cannel in return. Non + /// persistent means that the channel gets deleted if no-one uses it for + /// 5 hours. To accomodate future requirements, it may be a good idea to + /// initially create channels under the umbrella of a parent ID based upon + /// the region name. That way we have a context for side channels, if those + /// are required in a later phase. + /// In this case the call handles parent and description as optional values. + /// + + private bool VivoxTryGetChannel(string channelParent, string channelName, + out string channelId, out string channelUri) + { + string count; + + string requrl = String.Format(m_vivoxChannelSearchPath, m_vivoxServer, channelName, m_authToken); + XmlElement resp = VivoxCall(requrl, true); + + if (XmlFind(resp, "response.level0.channel-search.count", out count)) + { + int channels = Convert.ToInt32(count); + for (int i = 0; i < channels; i++) + { + string name; + string id; + string type; + string uri; + string parent; + + // skip if not a channel + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.type", i, out type) || + (type != "channel" && type != "positional_M")) + continue; + + // skip if not the name we are looking for + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.name", i, out name) || + name != channelName) + continue; + + // skip if parent does not match + if (channelParent != null && !XmlFind(resp, "response.level0.channel-search.channels.channels.level4.parent", i, out parent)) + continue; + + // skip if no channel id available + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.id", i, out id)) + continue; + + // skip if no channel uri available + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.uri", i, out uri)) + continue; + + channelId = id; + channelUri = uri; + + return true; + } + } + + channelId = String.Empty; + channelUri = String.Empty; + return false; + } + + private bool VivoxTryGetDirectory(string directoryName, out string directoryId) + { + string count; + + string requrl = String.Format(m_vivoxChannelSearchPath, m_vivoxServer, directoryName, m_authToken); + XmlElement resp = VivoxCall(requrl, true); + + if (XmlFind(resp, "response.level0.channel-search.count", out count)) + { + int channels = Convert.ToInt32(count); + for (int i = 0; i < channels; i++) + { + string name; + string id; + string type; + + // skip if not a directory + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.type", i, out type) || + type != "dir") + continue; + + // skip if not the name we are looking for + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.name", i, out name) || + name != directoryName) + continue; + + // skip if no channel id available + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.id", i, out id)) + continue; + + directoryId = id; + return true; + } + } + + directoryId = String.Empty; + return false; + } + + // private static readonly string m_vivoxChannelById = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}"; + + // private XmlElement VivoxGetChannelById(string parent, string channelid) + // { + // string requrl = String.Format(m_vivoxChannelById, m_vivoxServer, "get", channelid, m_authToken); + + // if (parent != null && parent != String.Empty) + // return VivoxGetChild(parent, channelid); + // else + // return VivoxCall(requrl, true); + // } + + /// + /// Delete a channel. + /// Once again, there a multitude of options possible. In the simplest case + /// we specify only the name and get a non-persistent cannel in return. Non + /// persistent means that the channel gets deleted if no-one uses it for + /// 5 hours. To accomodate future requirements, it may be a good idea to + /// initially create channels under the umbrella of a parent ID based upon + /// the region name. That way we have a context for side channels, if those + /// are required in a later phase. + /// In this case the call handles parent and description as optional values. + /// + + private static readonly string m_vivoxChannelDel = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}"; + + private XmlElement VivoxDeleteChannel(string parent, string channelid) + { + string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken); + if (parent != null && parent != String.Empty) + { + requrl = String.Format("{0}&chan_parent={1}", requrl, parent); + } + return VivoxCall(requrl, true); + } + + /// + /// Return information on channels in the given directory + /// + + private static readonly string m_vivoxChannelSearch = "http://{0}/api2/viv_chan_search.php?&cond_chanparent={1}&auth_token={2}"; + + private XmlElement VivoxListChildren(string channelid) + { + string requrl = String.Format(m_vivoxChannelSearch, m_vivoxServer, channelid, m_authToken); + return VivoxCall(requrl, true); + } + + // private XmlElement VivoxGetChild(string parent, string child) + // { + + // XmlElement children = VivoxListChildren(parent); + // string count; + + // if (XmlFind(children, "response.level0.channel-search.count", out count)) + // { + // int cnum = Convert.ToInt32(count); + // for (int i = 0; i < cnum; i++) + // { + // string name; + // string id; + // if (XmlFind(children, "response.level0.channel-search.channels.channels.level4.name", i, out name)) + // { + // if (name == child) + // { + // if (XmlFind(children, "response.level0.channel-search.channels.channels.level4.id", i, out id)) + // { + // return VivoxGetChannelById(null, id); + // } + // } + // } + // } + // } + + // // One we *know* does not exist. + // return VivoxGetChannel(null, Guid.NewGuid().ToString()); + + // } + + /// + /// This method handles the WEB side of making a request over the + /// Vivox interface. The returned values are tansferred to a has + /// table which is returned as the result. + /// The outcome of the call can be determined by examining the + /// status value in the hash table. + /// + + private XmlElement VivoxCall(string requrl, bool admin) + { + + XmlDocument doc = null; + + // If this is an admin call, and admin is not connected, + // and the admin id cannot be connected, then fail. + if (admin && !m_adminConnected && !DoAdminLogin()) + return null; + + doc = new XmlDocument(); + + try + { + // Otherwise prepare the request + m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); + + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); + HttpWebResponse rsp = null; + + // We are sending just parameters, no content + req.ContentLength = 0; + + // Send request and retrieve the response + rsp = (HttpWebResponse)req.GetResponse(); + + XmlTextReader rdr = new XmlTextReader(rsp.GetResponseStream()); + doc.Load(rdr); + rdr.Close(); + } + catch (Exception e) + { + m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message); + } + + // If we're debugging server responses, dump the whole + // load now + if (m_dumpXml) XmlScanl(doc.DocumentElement,0); + + return doc.DocumentElement; + } + + /// + /// Just say if it worked. + /// + + private bool IsOK(XmlElement resp) + { + string status; + XmlFind(resp, "response.level0.status", out status); + return (status == "OK"); + } + + /// + /// Login has been factored in this way because it gets called + /// from several places in the module, and we want it to work + /// the same way each time. + /// + private bool DoAdminLogin() + { + m_log.Debug("[VivoxVoice] Establishing admin connection"); + + lock (vlock) + { + if (!m_adminConnected) + { + string status = "Unknown"; + XmlElement resp = null; + + resp = VivoxLogin(m_vivoxAdminUser, m_vivoxAdminPassword); + + if (XmlFind(resp, "response.level0.body.status", out status)) + { + if (status == "Ok") + { + m_log.Info("[VivoxVoice] Admin connection established"); + if (XmlFind(resp, "response.level0.body.auth_token", out m_authToken)) + { + if (m_dumpXml) m_log.DebugFormat("[VivoxVoice] Auth Token <{0}>", + m_authToken); + m_adminConnected = true; + } + } + else + { + m_log.WarnFormat("[VivoxVoice] Admin connection failed, status = {0}", + status); + } + } + } + } + + return m_adminConnected; + } + + /// + /// The XmlScan routine is provided to aid in the + /// reverse engineering of incompletely + /// documented packets returned by the Vivox + /// voice server. It is only called if the + /// m_dumpXml switch is set. + /// + private void XmlScanl(XmlElement e, int index) + { + if (e.HasChildNodes) + { + m_log.DebugFormat("<{0}>".PadLeft(index+5), e.Name); + XmlNodeList children = e.ChildNodes; + foreach (XmlNode node in children) + switch (node.NodeType) + { + case XmlNodeType.Element : + XmlScanl((XmlElement)node, index+1); + break; + case XmlNodeType.Text : + m_log.DebugFormat("\"{0}\"".PadLeft(index+5), node.Value); + break; + default : + break; + } + m_log.DebugFormat("".PadLeft(index+6), e.Name); + } + else + { + m_log.DebugFormat("<{0}/>".PadLeft(index+6), e.Name); + } + } + + private static readonly char[] C_POINT = {'.'}; + + /// + /// The Find method is passed an element whose + /// inner text is scanned in an attempt to match + /// the name hierarchy passed in the 'tag' parameter. + /// If the whole hierarchy is resolved, the InnerText + /// value at that point is returned. Note that this + /// may itself be a subhierarchy of the entire + /// document. The function returns a boolean indicator + /// of the search's success. The search is performed + /// by the recursive Search method. + /// + private bool XmlFind(XmlElement root, string tag, int nth, out string result) + { + if (root == null || tag == null || tag == String.Empty) + { + result = String.Empty; + return false; + } + return XmlSearch(root,tag.Split(C_POINT),0, ref nth, out result); + } + + private bool XmlFind(XmlElement root, string tag, out string result) + { + int nth = 0; + if (root == null || tag == null || tag == String.Empty) + { + result = String.Empty; + return false; + } + return XmlSearch(root,tag.Split(C_POINT),0, ref nth, out result); + } + + /// + /// XmlSearch is initially called by XmlFind, and then + /// recursively called by itself until the document + /// supplied to XmlFind is either exhausted or the name hierarchy + /// is matched. + /// + /// If the hierarchy is matched, the value is returned in + /// result, and true returned as the function's + /// value. Otherwise the result is set to the empty string and + /// false is returned. + /// + private bool XmlSearch(XmlElement e, string[] tags, int index, ref int nth, out string result) + { + if (index == tags.Length || e.Name != tags[index]) + { + result = String.Empty; + return false; + } + + if (tags.Length-index == 1) + { + if (nth == 0) + { + result = e.InnerText; + return true; + } + else + { + nth--; + result = String.Empty; + return false; + } + } + + if (e.HasChildNodes) + { + XmlNodeList children = e.ChildNodes; + foreach (XmlNode node in children) + { + switch (node.NodeType) + { + case XmlNodeType.Element : + if (XmlSearch((XmlElement)node, tags, index+1, ref nth, out result)) + return true; + break; + + default : + break; + } + } + } + + result = String.Empty; + return false; + } + } +} -- cgit v1.1 From d123c74e37b8018d82db6eb8afbe3747e22731ad Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Sat, 11 Jul 2009 08:16:59 +0000 Subject: fixing missing ReplacableInterface --- .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 12ad9b8..773edc0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -40,12 +40,12 @@ using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Communications.Capabilities; +using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Communications.Capabilities.Caps; +using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice { @@ -388,6 +388,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice VivoxLogout(); } + public Type ReplacableInterface + { + get { return null; } + } + public string Name { get { return "VivoxVoiceModule"; } -- cgit v1.1 From 199984cbea45478e850cce39bff8fbec1695ea75 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sun, 12 Jul 2009 01:04:32 +0000 Subject: * Added some noisy debug information to VivoxModule to try debug why GetChannel fails on LBSA/Zaius Plaza. --- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 773edc0..5070ecc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -739,8 +739,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice lock (vlock) { - if (!VivoxTryGetChannel(parentId, landUUID, out channelId, out channelUri) && - !VivoxTryCreateChannel(parentId, landUUID, landName, out channelUri)) + // Added by Adam to help debug channel not availible errors. + if (VivoxTryGetChannel(parentId, landUUID, out channelId, out channelUri)) + m_log.DebugFormat("[VivoxVoice] Found existing channel at " + channelUri); + else if (VivoxTryCreateChannel(parentId, landUUID, landName, out channelUri)) + m_log.DebugFormat("[VivoxVoice] Created new channel at " + channelUri); + else throw new Exception("vivox channel uri not available"); m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parent channel id {1}: retrieved parcel channel_uri {2} ", @@ -956,6 +960,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice channelId = String.Empty; channelUri = String.Empty; + + m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + resp); + return false; } -- cgit v1.1 From c20a4032e2d4253fe0d8a4c79a6e89ef89d4f131 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sun, 12 Jul 2009 01:23:49 +0000 Subject: * More VivoxModule debugging. --- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 5070ecc..d5f3b4a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -930,26 +930,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice string parent; // skip if not a channel - if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.type", i, out type) || + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.type", i, out type) || (type != "channel" && type != "positional_M")) + { + m_log.Debug("[VivoxVoice] Skipping Channel " + i + " as it's not a channel."); continue; + } // skip if not the name we are looking for if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.name", i, out name) || name != channelName) + { + m_log.Debug("[VivoxVoice] Skipping Channel " + i + " as it has no name."); continue; + } // skip if parent does not match if (channelParent != null && !XmlFind(resp, "response.level0.channel-search.channels.channels.level4.parent", i, out parent)) + { + m_log.Debug("[VivoxVoice] Skipping Channel " + i + "/" + name + " as it's parent doesnt match"); continue; + } // skip if no channel id available if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.id", i, out id)) + { + m_log.Debug("[VivoxVoice] Skipping Channel " + i + "/" + name + " as it has no channel ID"); continue; + } // skip if no channel uri available if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.uri", i, out uri)) + { + m_log.Debug("[VivoxVoice] Skipping Channel " + i + "/" + name + " as it has no channel URI"); continue; + } channelId = id; channelUri = uri; @@ -961,7 +976,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice channelId = String.Empty; channelUri = String.Empty; - m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + resp); + XmlDocument tmpDoc = new XmlDocument(); + tmpDoc.AppendChild(resp); + + m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + tmpDoc.InnerText); return false; } -- cgit v1.1 From a8b40d47d69979763c63c98ab00aa012514ee36b Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sun, 12 Jul 2009 01:31:33 +0000 Subject: * Patch for previous revision. --- .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index d5f3b4a..7c1d2c8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -976,10 +976,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice channelId = String.Empty; channelUri = String.Empty; - XmlDocument tmpDoc = new XmlDocument(); - tmpDoc.AppendChild(resp); - - m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + tmpDoc.InnerText); + m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + resp.InnerText); return false; } -- cgit v1.1 From 50ccf914ca6bd542e8698cd24feb2832681a466c Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sun, 12 Jul 2009 01:56:38 +0000 Subject: * More Vivox Fiddling --- .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 7c1d2c8..98c39cc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -972,11 +972,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return true; } } + else + { + m_log.Debug("[VivoxVoice] No channels registered."); + } channelId = String.Empty; channelUri = String.Empty; - m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + resp.InnerText); + m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + resp.InnerXml); return false; } -- cgit v1.1 From 71ab7a1e2d4b613c1d897e26b518c0316b723f95 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sun, 12 Jul 2009 02:16:49 +0000 Subject: * Workaround for a bug in Vivox Server r2978, whereby channel-search.channels.count returns 0 instead of the actual channel count. Should not affect more recent versions of Vivox where this issue has been fixed. --- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 98c39cc..f9d6bd2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -921,6 +921,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice if (XmlFind(resp, "response.level0.channel-search.count", out count)) { int channels = Convert.ToInt32(count); + + // Bug in Vivox Server r2978 where count returns 0 + // Found by Adam + if(channels == 0) + { + for(int j=0;j<100;j++) + { + string tmpId; + if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.id", j, out tmpId)) + break; + + channels = j + 1; + } + } + for (int i = 0; i < channels; i++) { string name; @@ -974,13 +989,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice } else { - m_log.Debug("[VivoxVoice] No channels registered."); + m_log.Debug("[VivoxVoice] No count element?"); } channelId = String.Empty; channelUri = String.Empty; - m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + resp.InnerXml); + // Useful incase something goes wrong. + //m_log.Debug("[VivoxVoice] Could not find channel in XMLRESP: " + resp.InnerXml); return false; } -- cgit v1.1 From eb1a6e9b87ab7fedc035127b8224147deba2d5ab Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Fri, 17 Jul 2009 21:06:28 +0000 Subject: * Patch from otakup0pe to help freeswitch play nice with complex existing freeswitch configurations. * Thanks! fixes mantis #3899 --- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 91 +++++----- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 201 +++++++++++---------- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 8 +- 3 files changed, 160 insertions(+), 140 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index ad2b7e4..d34b6f1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -26,18 +26,20 @@ */ using log4net; +using System; using System.Reflection; +using System.Text; using System.Collections; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { public class FreeSwitchDialplan { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public Hashtable HandleDialplanRequest(Hashtable request) + public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request) { m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString()); @@ -47,48 +49,55 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); } - + + string requestcontext = (string) request["Hunt-Context"]; response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - response["str_response_string"] = @" - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
"; + if ( Context != requestcontext ) + { + m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); + response["str_response_string"] = ""; + } else { + response["str_response_string"] = String.Format(@" + +
+ " + + +/* + + + + + + */ + + @" + + + + + + + + + + + + + + + + + + + + +
+
", Context, Realm); + } - return response; + return response; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index caec43d..af5692c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -38,103 +38,111 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public Hashtable HandleDirectoryRequest(Hashtable request) + public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request) { - m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); + Hashtable response = new Hashtable(); + string domain = (string) request["domain"]; + if ( domain != Realm ) { + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + response["str_response_string"] = ""; + } else { + m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); - Hashtable response = new Hashtable(); - // information in the request we might be interested in + // information in the request we might be interested in - // Request 1 sip_auth for users account + // Request 1 sip_auth for users account - //Event-Calling-Function=sofia_reg_parse_auth - //Event-Calling-Line-Number=1494 - //action=sip_auth - //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41) - //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) - //sip_auth_realm=9.20.151.43 - //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) - //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers - //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D - //sip_to_host=9.20.151.43 - //sip_auth_method=REGISTER - //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D - //domain=9.20.151.43 - //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup + //Event-Calling-Function=sofia_reg_parse_auth + //Event-Calling-Line-Number=1494 + //action=sip_auth + //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41) + //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_auth_realm=9.20.151.43 + //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers + //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //sip_to_host=9.20.151.43 + //sip_auth_method=REGISTER + //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //domain=9.20.151.43 + //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup - foreach (DictionaryEntry item in request) - { - m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); - } + foreach (DictionaryEntry item in request) + { + m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); + } - string eventCallingFunction = (string) request["Event-Calling-Function"]; - if (eventCallingFunction == null) - { - eventCallingFunction = "sofia_reg_parse_auth"; - } + string eventCallingFunction = (string) request["Event-Calling-Function"]; + if (eventCallingFunction == null) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } - if (eventCallingFunction.Length == 0) - { - eventCallingFunction = "sofia_reg_parse_auth"; - } + if (eventCallingFunction.Length == 0) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } - if (eventCallingFunction == "sofia_reg_parse_auth") - { - string sipAuthMethod = (string)request["sip_auth_method"]; + if (eventCallingFunction == "sofia_reg_parse_auth") + { + string sipAuthMethod = (string)request["sip_auth_method"]; - if (sipAuthMethod == "REGISTER") - { - response = HandleRegister(request); - } - else if (sipAuthMethod == "INVITE") - { - response = HandleInvite(request); - } - else - { - m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); - response["int_response_code"] = 404; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - } - else if (eventCallingFunction == "switch_xml_locate_user") - { - response = HandleLocateUser(request); - } - else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made - { - response = HandleLocateUser(request); - } - else if (eventCallingFunction == "user_outgoing_channel") - { - response = HandleRegister(request); - } - else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup - { - response = HandleConfigSofia(request); - } - else if (eventCallingFunction == "switch_load_network_lists") - { - //response = HandleLoadNetworkLists(request); - response["int_response_code"] = 404; - response["keepalive"] = false; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - else - { - m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); - response["int_response_code"] = 404; - response["keepalive"] = false; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - return response; + if (sipAuthMethod == "REGISTER") + { + response = HandleRegister(Context, Realm, request); + } + else if (sipAuthMethod == "INVITE") + { + response = HandleInvite(Context, Realm, request); + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); + response["int_response_code"] = 404; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + } + else if (eventCallingFunction == "switch_xml_locate_user") + { + response = HandleLocateUser(Realm, request); + } + else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made + { + response = HandleLocateUser(Realm, request); + } + else if (eventCallingFunction == "user_outgoing_channel") + { + response = HandleRegister(Context, Realm, request); + } + else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup + { + response = HandleConfigSofia(Context, Realm, request); + } + else if (eventCallingFunction == "switch_load_network_lists") + { + //response = HandleLoadNetworkLists(request); + response["int_response_code"] = 404; + response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); + response["int_response_code"] = 404; + response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + } + return response; } - private Hashtable HandleRegister(Hashtable request) + private Hashtable HandleRegister(string Context, string Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleRegister called"); @@ -147,7 +155,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - response["str_response_string"] = String.Format( + + response["str_response_string"] = String.Format( "\r\n" + "\r\n" + "
\r\n" + @@ -158,19 +167,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + "\r\n" + "
\r\n" + "
\r\n", - domain , user, password); + domain , user, password, Context); return response; } - private Hashtable HandleInvite(Hashtable request) + private Hashtable HandleInvite(string Context, string Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleInvite called"); @@ -195,7 +204,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + @@ -205,20 +214,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + "\r\n" + "
\r\n" + "
\r\n", - domain , user, password,sipRequestUser); + domain , user, password,sipRequestUser, Context); return response; } - private Hashtable HandleLocateUser(Hashtable request) + private Hashtable HandleLocateUser(String Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); @@ -252,7 +261,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - private Hashtable HandleConfigSofia(Hashtable request) + private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called"); @@ -285,7 +294,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n"+ "\r\n"+ "\r\n"+ - "\r\n"+ + "\r\n"+ "\r\n"+ "\r\n"+ "\r\n"+ @@ -300,7 +309,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "
\r\n" + "
\r\n", - domain); + domain, Context); return response; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 5c562ac..3659299 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -95,6 +95,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // private static IPEndPoint m_FreeSwitchServiceIP; private int m_freeSwitchServicePort; private string m_openSimWellKnownHTTPAddress; + private string m_freeSwitchContext; private FreeSwitchDirectory m_FreeSwitchDirectory; private FreeSwitchDialplan m_FreeSwitchDialplan; @@ -151,6 +152,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); + m_freeSwitchContext = m_config.GetString("freeswitch_context", "public"); if (String.IsNullOrEmpty(m_freeSwitchServerUser) || String.IsNullOrEmpty(m_freeSwitchServerPass) || @@ -572,7 +574,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "false\r\n"+ "", m_freeSwitchRealm, m_freeSwitchSIPProxy, m_freeSwitchAttemptUseSTUN, - m_freeSwitchSTUNServer, m_freeSwitchEchoServer, m_freeSwitchEchoPort, + m_freeSwitchEchoServer, m_freeSwitchEchoPort, m_freeSwitchDefaultWellKnownIP, m_freeSwitchDefaultTimeout, m_freeSwitchUrlResetPassword, ""); @@ -728,9 +730,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string section = (string) requestBody["section"]; if (section == "directory") - response = m_FreeSwitchDirectory.HandleDirectoryRequest(requestBody); + response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); else if (section == "dialplan") - response = m_FreeSwitchDialplan.HandleDialplanRequest(requestBody); + response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); else m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); -- cgit v1.1 From 7c747035ff6940a165de5c74105cfbd20d18a566 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 21 Jul 2009 23:57:56 +0000 Subject: Thank you, MarcelEdward, for a patch to add paying group join fees. Applied with changes (original patch would not compile) Whitespace changes removed Fixes Mantis #3926 --- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index b43a6ac..4a46949 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -724,7 +724,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } - + // is there is a money module present ? + IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); + if (money != null) + { + // do the transaction, that is if the agent has got sufficient funds + if (!money.GroupCreationCovered(remoteClient)) { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); + return UUID.Zero; + } + money.ApplyGroupCreationCharge(remoteClient.AgentId); + } UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); @@ -733,6 +743,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); return groupID; + } public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) -- cgit v1.1 From a133e83f3ab38ad7abf0b3c591421d3eac418c0c Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Thu, 23 Jul 2009 15:32:11 +0000 Subject: Formatting cleanup. --- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 78 ++++----- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 192 ++++++++++----------- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 4 +- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 4 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 19 +- 5 files changed, 147 insertions(+), 150 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index d34b6f1..bb3dca5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -36,7 +36,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public class FreeSwitchDialplan { private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request) @@ -54,50 +54,50 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - if ( Context != requestcontext ) - { - m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); - response["str_response_string"] = ""; - } else { - response["str_response_string"] = String.Format(@" - -
- " + + if (Context != requestcontext) + { + m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); + response["str_response_string"] = ""; + } else { + response["str_response_string"] = String.Format(@" + +
+ " + -/* - - - - - - */ +/* + + + + + + */ - @" - - - - - + @" + + + + + - - - - - - + + + + + + - - - - - + + + + + - -
-
", Context, Realm); - } +
+
+
", Context, Realm); + } - return response; + return response; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index af5692c..5d90a8f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -40,109 +40,108 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request) { - Hashtable response = new Hashtable(); - string domain = (string) request["domain"]; - if ( domain != Realm ) { - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = ""; - } else { - m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); - - - // information in the request we might be interested in + Hashtable response = new Hashtable(); + string domain = (string) request["domain"]; + if (domain != Realm) { + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + response["str_response_string"] = ""; + } else { + m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); + + // information in the request we might be interested in - // Request 1 sip_auth for users account + // Request 1 sip_auth for users account - //Event-Calling-Function=sofia_reg_parse_auth - //Event-Calling-Line-Number=1494 - //action=sip_auth - //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41) - //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) - //sip_auth_realm=9.20.151.43 - //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) - //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers - //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D - //sip_to_host=9.20.151.43 - //sip_auth_method=REGISTER - //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D - //domain=9.20.151.43 - //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup + //Event-Calling-Function=sofia_reg_parse_auth + //Event-Calling-Line-Number=1494 + //action=sip_auth + //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41) + //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_auth_realm=9.20.151.43 + //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers + //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //sip_to_host=9.20.151.43 + //sip_auth_method=REGISTER + //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //domain=9.20.151.43 + //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup - foreach (DictionaryEntry item in request) - { - m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); - } + foreach (DictionaryEntry item in request) + { + m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); + } - string eventCallingFunction = (string) request["Event-Calling-Function"]; - if (eventCallingFunction == null) - { - eventCallingFunction = "sofia_reg_parse_auth"; - } + string eventCallingFunction = (string) request["Event-Calling-Function"]; + if (eventCallingFunction == null) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } - if (eventCallingFunction.Length == 0) - { - eventCallingFunction = "sofia_reg_parse_auth"; - } + if (eventCallingFunction.Length == 0) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } - if (eventCallingFunction == "sofia_reg_parse_auth") - { - string sipAuthMethod = (string)request["sip_auth_method"]; + if (eventCallingFunction == "sofia_reg_parse_auth") + { + string sipAuthMethod = (string)request["sip_auth_method"]; - if (sipAuthMethod == "REGISTER") - { - response = HandleRegister(Context, Realm, request); - } - else if (sipAuthMethod == "INVITE") - { - response = HandleInvite(Context, Realm, request); - } - else - { - m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); - response["int_response_code"] = 404; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - } - else if (eventCallingFunction == "switch_xml_locate_user") - { - response = HandleLocateUser(Realm, request); - } - else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made - { - response = HandleLocateUser(Realm, request); - } - else if (eventCallingFunction == "user_outgoing_channel") - { - response = HandleRegister(Context, Realm, request); - } - else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup - { - response = HandleConfigSofia(Context, Realm, request); - } - else if (eventCallingFunction == "switch_load_network_lists") - { - //response = HandleLoadNetworkLists(request); - response["int_response_code"] = 404; - response["keepalive"] = false; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - else - { - m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); - response["int_response_code"] = 404; - response["keepalive"] = false; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - } - return response; + if (sipAuthMethod == "REGISTER") + { + response = HandleRegister(Context, Realm, request); + } + else if (sipAuthMethod == "INVITE") + { + response = HandleInvite(Context, Realm, request); + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); + response["int_response_code"] = 404; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + } + else if (eventCallingFunction == "switch_xml_locate_user") + { + response = HandleLocateUser(Realm, request); + } + else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made + { + response = HandleLocateUser(Realm, request); + } + else if (eventCallingFunction == "user_outgoing_channel") + { + response = HandleRegister(Context, Realm, request); + } + else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup + { + response = HandleConfigSofia(Context, Realm, request); + } + else if (eventCallingFunction == "switch_load_network_lists") + { + //response = HandleLoadNetworkLists(request); + response["int_response_code"] = 404; + response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); + response["int_response_code"] = 404; + response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + } + return response; } - private Hashtable HandleRegister(string Context, string Realm, Hashtable request) + private Hashtable HandleRegister(string Context, string Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleRegister called"); @@ -156,7 +155,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["keepalive"] = false; response["int_response_code"] = 200; - response["str_response_string"] = String.Format( + response["str_response_string"] = String.Format( "\r\n" + "\r\n" + "
\r\n" + @@ -225,8 +224,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - - + private Hashtable HandleLocateUser(String Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 3659299..de12b0a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -95,7 +95,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // private static IPEndPoint m_FreeSwitchServiceIP; private int m_freeSwitchServicePort; private string m_openSimWellKnownHTTPAddress; - private string m_freeSwitchContext; + private string m_freeSwitchContext; private FreeSwitchDirectory m_FreeSwitchDirectory; private FreeSwitchDialplan m_FreeSwitchDialplan; @@ -152,7 +152,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); - m_freeSwitchContext = m_config.GetString("freeswitch_context", "public"); + m_freeSwitchContext = m_config.GetString("freeswitch_context", "public"); if (String.IsNullOrEmpty(m_freeSwitchServerUser) || String.IsNullOrEmpty(m_freeSwitchServerPass) || diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index f9d6bd2..47309d0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -924,9 +924,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // Bug in Vivox Server r2978 where count returns 0 // Found by Adam - if(channels == 0) + if (channels == 0) { - for(int j=0;j<100;j++) + for (int j=0;j<100;j++) { string tmpId; if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.id", j, out tmpId)) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 4a46949..fc19785 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -724,17 +724,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } - // is there is a money module present ? - IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); + // is there is a money module present ? + IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); if (money != null) { - // do the transaction, that is if the agent has got sufficient funds - if (!money.GroupCreationCovered(remoteClient)) { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); - return UUID.Zero; - } - money.ApplyGroupCreationCharge(remoteClient.AgentId); - } + // do the transaction, that is if the agent has got sufficient funds + if (!money.GroupCreationCovered(remoteClient)) { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); + return UUID.Zero; + } + money.ApplyGroupCreationCharge(remoteClient.AgentId); + } UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); @@ -743,7 +743,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); return groupID; - } public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) -- cgit v1.1 From a7c894829262f99d726c28b2b3438aa937f93446 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Fri, 24 Jul 2009 20:08:26 +0000 Subject: * Apply http://opensimulator.org/mantis/view.php?id=3855 * Prevent session crashes when something goes wrong with group invite. * Thanks mcortez. --- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 64 ++++++++++++++-------- 1 file changed, 40 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index fc19785..2cbc571 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.Info("[GROUPS]: Initializing XmlRpcGroups"); + m_log.InfoFormat("[GROUPS]: Initializing {0}", this.Name); string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); bool DisableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); @@ -138,6 +138,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; + m_clientRequestIDFlushTimer.AutoReset = true; m_clientRequestIDFlushTimer.Start(); } } @@ -371,6 +372,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID inviteID = new UUID(im.imSessionID); GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + if (inviteInfo == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Received an Invite IM for an invite that does not exist {0}.", inviteID); + return; + } + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); UUID fromAgentID = new UUID(im.fromAgentID); @@ -1037,32 +1044,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - m_groupData.AddAgentToGroupInvite(GetClientGroupRequestID(remoteClient), InviteID, groupID, roleID, invitedAgentID); + GroupRequestID grid = GetClientGroupRequestID(remoteClient); - if (m_msgTransferModule != null) - { - Guid inviteUUID = InviteID.Guid; + m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); - GridInstantMessage msg = new GridInstantMessage(); - - msg.imSessionID = inviteUUID; - - // msg.fromAgentID = remoteClient.AgentId.Guid; - msg.fromAgentID = groupID.Guid; - msg.toAgentID = invitedAgentID.Guid; - //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[20]; + // Check to see if the invite went through, if it did not then it's possible + // the remoteClient did not validate or did not have permission to invite. + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); - OutgoingInstantMessage(msg, invitedAgentID); + if (inviteInfo != null) + { + if (m_msgTransferModule != null) + { + Guid inviteUUID = InviteID.Guid; + + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = inviteUUID; + + // msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = groupID.Guid; + msg.toAgentID = invitedAgentID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[20]; + + OutgoingInstantMessage(msg, invitedAgentID); + } } } -- cgit v1.1 From 64bd9a335444379ebe1cad8e34d5b5953a76f671 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sat, 25 Jul 2009 15:49:10 +0000 Subject: * Updates libOMV to version 0.7.0 * Uses mantis #3811 as a base (thanks jhuliman) with changes. * E-mail regarding interface changes sent to the opensim-dev list * Archive: https://lists.berlios.de/pipermail/opensim-dev/2009-July/007219.html --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 4 ++-- .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index de12b0a..5fa7efd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -443,7 +443,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // } // else - if ((land.Flags & (uint)Parcel.ParcelFlags.AllowVoiceChat) == 0) + if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) { m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); @@ -777,7 +777,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same // as the directory ID. Otherwise, it reflects the parcel's ID. - if (land.LocalID != 1 && (land.Flags & (uint)Parcel.ParcelFlags.UseEstateVoiceChan) == 0) + if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) { landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); landUUID = land.GlobalID.ToString(); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 47309d0..5465678 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -651,7 +651,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice channel_uri = String.Empty; } - if ((land.Flags & (uint)Parcel.ParcelFlags.AllowVoiceChat) == 0) + if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) { m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); @@ -722,7 +722,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same // as the directory ID. Otherwise, it reflects the parcel's ID. - if (land.LocalID != 1 && (land.Flags & (uint)Parcel.ParcelFlags.UseEstateVoiceChan) == 0) + if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) { landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); landUUID = land.GlobalID.ToString(); -- cgit v1.1 From fa20a2685bc7bb94ef0f963cae0ebee38cdc9724 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 4 Aug 2009 00:38:20 +0100 Subject: Output the Freeswitch context received and the context set up in the debugging message so a mismatch can be corrected more easily --- .../OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index bb3dca5..703c1e7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -56,7 +56,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["int_response_code"] = 200; if (Context != requestcontext) { - m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); + m_log.DebugFormat("[FreeSwitchDirectory] returning empty as it's for context {0} and we are using {1}", requestcontext, Context); response["str_response_string"] = ""; } else { response["str_response_string"] = String.Format(@" -- cgit v1.1 From 1f90d2a2c6872ff1c6349f86b68de79b17b9de36 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 4 Aug 2009 00:43:49 +0100 Subject: If the FreeSwitch context is unset or "public", then accept any context. This restores the "out of the box" functionality. --- .../OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index 703c1e7..94f29ea 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - if (Context != requestcontext) + if (Context != requestcontext && Context != "public") { m_log.DebugFormat("[FreeSwitchDirectory] returning empty as it's for context {0} and we are using {1}", requestcontext, Context); response["str_response_string"] = ""; -- cgit v1.1 From c3dd98b016c8770c61525bd4d6ca898c635358ed Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 4 Aug 2009 05:03:32 +0100 Subject: Revert the #3899 patch and it's two follow ups --- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 25 ++++------- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 48 ++++++++++------------ .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 8 ++-- 3 files changed, 32 insertions(+), 49 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index 94f29ea..c05d598 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -26,9 +26,7 @@ */ using log4net; -using System; using System.Reflection; -using System.Text; using System.Collections; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice @@ -39,7 +37,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request) + public Hashtable HandleDialplanRequest(Hashtable request) { m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString()); @@ -50,32 +48,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); } - string requestcontext = (string) request["Hunt-Context"]; response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; - if (Context != requestcontext && Context != "public") - { - m_log.DebugFormat("[FreeSwitchDirectory] returning empty as it's for context {0} and we are using {1}", requestcontext, Context); - response["str_response_string"] = ""; - } else { - response["str_response_string"] = String.Format(@" + response["str_response_string"] = @"
- " + + -/* + - */ + - @" + - + @@ -94,8 +86,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
-
", Context, Realm); - } + "; return response; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 5d90a8f..0a9f69d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -38,18 +38,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request) + public Hashtable HandleDirectoryRequest(Hashtable request) { - Hashtable response = new Hashtable(); - string domain = (string) request["domain"]; - if (domain != Realm) { - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = ""; - } else { m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); + Hashtable response = new Hashtable(); + // information in the request we might be interested in // Request 1 sip_auth for users account @@ -91,11 +85,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice if (sipAuthMethod == "REGISTER") { - response = HandleRegister(Context, Realm, request); + response = HandleRegister(request); } else if (sipAuthMethod == "INVITE") { - response = HandleInvite(Context, Realm, request); + response = HandleInvite(request); } else { @@ -107,19 +101,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } else if (eventCallingFunction == "switch_xml_locate_user") { - response = HandleLocateUser(Realm, request); + response = HandleLocateUser(request); } else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made { - response = HandleLocateUser(Realm, request); + response = HandleLocateUser(request); } else if (eventCallingFunction == "user_outgoing_channel") { - response = HandleRegister(Context, Realm, request); + response = HandleRegister(request); } else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup { - response = HandleConfigSofia(Context, Realm, request); + response = HandleConfigSofia(request); } else if (eventCallingFunction == "switch_load_network_lists") { @@ -137,11 +131,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["str_response_string"] = ""; } - } return response; } - private Hashtable HandleRegister(string Context, string Realm, Hashtable request) + private Hashtable HandleRegister(Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleRegister called"); @@ -166,19 +159,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + "\r\n" + "
\r\n" + "
\r\n", - domain , user, password, Context); + domain , user, password); return response; } - private Hashtable HandleInvite(string Context, string Realm, Hashtable request) + private Hashtable HandleInvite(Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleInvite called"); @@ -203,7 +196,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + @@ -213,19 +206,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + "\r\n" + "
\r\n" + "
\r\n", - domain , user, password,sipRequestUser, Context); + domain , user, password,sipRequestUser); return response; } - private Hashtable HandleLocateUser(String Realm, Hashtable request) + + private Hashtable HandleLocateUser(Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); @@ -259,7 +253,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request) + private Hashtable HandleConfigSofia(Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called"); @@ -292,7 +286,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n"+ "\r\n"+ "\r\n"+ - "\r\n"+ + "\r\n"+ "\r\n"+ "\r\n"+ "\r\n"+ @@ -307,7 +301,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "
\r\n" + "
\r\n", - domain, Context); + domain); return response; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 5fa7efd..f9cb1c4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -95,7 +95,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // private static IPEndPoint m_FreeSwitchServiceIP; private int m_freeSwitchServicePort; private string m_openSimWellKnownHTTPAddress; - private string m_freeSwitchContext; private FreeSwitchDirectory m_FreeSwitchDirectory; private FreeSwitchDialplan m_FreeSwitchDialplan; @@ -152,7 +151,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); - m_freeSwitchContext = m_config.GetString("freeswitch_context", "public"); if (String.IsNullOrEmpty(m_freeSwitchServerUser) || String.IsNullOrEmpty(m_freeSwitchServerPass) || @@ -574,7 +572,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "false\r\n"+ "", m_freeSwitchRealm, m_freeSwitchSIPProxy, m_freeSwitchAttemptUseSTUN, - m_freeSwitchEchoServer, m_freeSwitchEchoPort, + m_freeSwitchSTUNServer, m_freeSwitchEchoServer, m_freeSwitchEchoPort, m_freeSwitchDefaultWellKnownIP, m_freeSwitchDefaultTimeout, m_freeSwitchUrlResetPassword, ""); @@ -730,9 +728,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string section = (string) requestBody["section"]; if (section == "directory") - response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); + response = m_FreeSwitchDirectory.HandleDirectoryRequest(requestBody); else if (section == "dialplan") - response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); + response = m_FreeSwitchDialplan.HandleDialplanRequest(requestBody); else m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); -- cgit v1.1 From 989517725d02d8a2d216e599856eb2625b454e25 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 5 Aug 2009 11:15:53 -0700 Subject: Begin refactoring XmlRpcGroups to a more generic Groups module that allows for replaceable Groups Service Connectors. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 548 ++++++++ .../Avatar/XmlRpcGroups/GroupsModule.cs | 1335 ++++++++++++++++++++ .../Avatar/XmlRpcGroups/IGroupDataProvider.cs | 91 -- .../XmlRpcGroups/IGroupsServicesConnector.cs | 91 ++ .../Avatar/XmlRpcGroups/XmlRpcGroupData.cs | 916 -------------- .../Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | 548 -------- .../Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | 1331 ------------------- .../XmlRpcGroupsServicesConnectorModule.cs | 1007 +++++++++++++++ 8 files changed, 2981 insertions(+), 2886 deletions(-) create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs delete mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs delete mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs delete mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs delete mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs new file mode 100644 index 0000000..8fbda28 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -0,0 +1,548 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; + + +using log4net; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Framework.EventQueue; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + + +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + public class GroupsMessagingModule : ISharedRegionModule + { + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_sceneList = new List(); + + private IMessageTransferModule m_msgTransferModule = null; + + private IGroupsModule m_groupsModule = null; + + // TODO: Move this off to the xmlrpc server + public Dictionary> m_agentsInGroupSession = new Dictionary>(); + public Dictionary> m_agentsDroppedSession = new Dictionary>(); + + + // Config Options + private bool m_groupMessagingEnabled = false; + private bool m_debugEnabled = true; + + #region IRegionModuleBase Members + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + if (groupsConfig == null) + { + // Do not run this module by default. + return; + } + else + { + if (!groupsConfig.GetBoolean("Enabled", false)) + { + return; + } + + if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + { + m_groupMessagingEnabled = false; + + return; + } + + m_groupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); + + if (!m_groupMessagingEnabled) + { + return; + } + + m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); + + m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + } + + m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up"); + + } + + public void AddRegion(Scene scene) + { + // NoOp + } + public void RegionLoaded(Scene scene) + { + if (!m_groupMessagingEnabled) + return; + + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupsModule = scene.RequestModuleInterface(); + + // No groups module, no groups messaging + if (m_groupsModule == null) + { + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); + Close(); + m_groupMessagingEnabled = false; + return; + } + + m_msgTransferModule = scene.RequestModuleInterface(); + + // No message transfer module, no groups messaging + if (m_msgTransferModule == null) + { + m_log.Error("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); + Close(); + m_groupMessagingEnabled = false; + return; + } + + + m_sceneList.Add(scene); + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + + } + + public void RemoveRegion(Scene scene) + { + if (!m_groupMessagingEnabled) + return; + + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_sceneList.Remove(scene); + } + + public void Close() + { + if (!m_groupMessagingEnabled) + return; + + if (m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); + + foreach (Scene scene in m_sceneList) + { + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + } + + m_sceneList.Clear(); + + m_groupsModule = null; + m_msgTransferModule = null; + } + + public Type ReplacableInterface + { + get { return null; } + } + + public string Name + { + get { return "XmlRpcGroupsMessaging"; } + } + + #endregion + + #region ISharedRegionModule Members + + public void PostInitialise() + { + // NoOp + } + + #endregion + + #region SimGridEventHandlers + + private void OnNewClient(IClientAPI client) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); + + client.OnInstantMessage += OnInstantMessage; + } + + private void OnGridInstantMessage(GridInstantMessage msg) + { + // The instant message module will only deliver messages of dialog types: + // MessageFromAgent, StartTyping, StopTyping, MessageFromObject + // + // Any other message type will not be delivered to a client by the + // Instant Message Module + + + if (m_debugEnabled) + { + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + DebugGridInstantMessage(msg); + } + + // Incoming message from a group + if ((msg.fromGroup == true) && + ((msg.dialog == (byte)InstantMessageDialog.SessionSend) + || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) + || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) + { + ProcessMessageFromGroupSession(msg); + } + } + + private void ProcessMessageFromGroupSession(GridInstantMessage msg) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + + switch (msg.dialog) + { + case (byte)InstantMessageDialog.SessionAdd: + AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); + break; + + case (byte)InstantMessageDialog.SessionDrop: + RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); + break; + + case (byte)InstantMessageDialog.SessionSend: + if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) + && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + { + // Agent not in session and hasn't dropped from session + // Add them to the session for now, and Invite them + AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); + + UUID toAgentID = new UUID(msg.toAgentID); + IClientAPI activeClient = GetActiveClient(toAgentID); + if (activeClient != null) + { + UUID groupID = new UUID(msg.fromAgentID); + + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + if (groupInfo != null) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); + + // Force? open the group session dialog??? + IEventQueue eq = activeClient.Scene.RequestModuleInterface(); + eq.ChatterboxInvitation( + groupID + , groupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message, new UUID(msg.toAgentID) + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline == 1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(groupInfo.GroupName) + ); + + eq.ChatterBoxSessionAgentListUpdates( + new UUID(groupID) + , new UUID(msg.fromAgentID) + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + } + } + } + else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + { + // User hasn't dropped, so they're in the session, + // maybe we should deliver it. + IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); + if (client != null) + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); + client.SendInstantMessage(msg); + } + else + { + m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); + } + } + break; + + default: + m_log.WarnFormat("[GROUPS-MESSAGING]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); + break; + } + } + + #endregion + + #region ClientEvents + + private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) + { + if (m_agentsInGroupSession.ContainsKey(sessionID)) + { + // If in session remove + if (m_agentsInGroupSession[sessionID].Contains(agentID)) + { + m_agentsInGroupSession[sessionID].Remove(agentID); + } + + // If not in dropped list, add + if (!m_agentsDroppedSession[sessionID].Contains(agentID)) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); + m_agentsDroppedSession[sessionID].Add(agentID); + } + } + } + + private void AddAgentToGroupSession(Guid agentID, Guid sessionID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupSessionTracking(sessionID); + + // If nessesary, remove from dropped list + if (m_agentsDroppedSession[sessionID].Contains(agentID)) + { + m_agentsDroppedSession[sessionID].Remove(agentID); + } + + // If nessesary, add to in session list + if (!m_agentsInGroupSession[sessionID].Contains(agentID)) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); + m_agentsInGroupSession[sessionID].Add(agentID); + } + } + + private void CreateGroupSessionTracking(Guid sessionID) + { + if (!m_agentsInGroupSession.ContainsKey(sessionID)) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); + m_agentsInGroupSession.Add(sessionID, new List()); + m_agentsDroppedSession.Add(sessionID, new List()); + } + } + + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) + { + if (m_debugEnabled) + { + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + DebugGridInstantMessage(im); + } + + // Start group IM session + if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) + { + UUID groupID = new UUID(im.toAgentID); + + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + if (groupInfo != null) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); + + AddAgentToGroupSession(im.fromAgentID, im.imSessionID); + + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + queue.ChatterBoxSessionAgentListUpdates( + new UUID(groupID) + , new UUID(im.fromAgentID) + , new UUID(im.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + } + } + + // Send a message from locally connected client to a group + if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) + { + UUID groupID = new UUID(im.toAgentID); + + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + + SendMessageToGroup(im, groupID); + } + } + + #endregion + + private void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) + { + if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + { + // Don't deliver messages to people who have dropped this session + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; + } + + // Copy Message + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = im.imSessionID; + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.offline = im.offline; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = im.binaryBucket; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + + // Updat Pertinate fields to make it a "group message" + msg.fromAgentID = groupID.Guid; + msg.fromGroup = true; + + msg.toAgentID = member.AgentID.Guid; + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg); + } + } + } + + void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap moderatedMap = new OSDMap(4); + moderatedMap.Add("voice", OSD.FromBoolean(false)); + + OSDMap sessionMap = new OSDMap(4); + sessionMap.Add("moderated_mode", moderatedMap); + sessionMap.Add("session_name", OSD.FromString(groupName)); + sessionMap.Add("type", OSD.FromInteger(0)); + sessionMap.Add("voice_enabled", OSD.FromBoolean(false)); + + OSDMap bodyMap = new OSDMap(4); + bodyMap.Add("session_id", OSD.FromUUID(groupID)); + bodyMap.Add("temp_session_id", OSD.FromUUID(groupID)); + bodyMap.Add("success", OSD.FromBoolean(true)); + bodyMap.Add("session_info", sessionMap); + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + + if (queue != null) + { + queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); + } + } + + private void DebugGridInstantMessage(GridInstantMessage im) + { + // Don't log any normal IMs (privacy!) + if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent) + { + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); + } + } + + #region Client Tools + + /// + /// Try to find an active IClientAPI reference for agentID giving preference to root connections + /// + private IClientAPI GetActiveClient(UUID agentID) + { + IClientAPI child = null; + + // Try root avatar first + foreach (Scene scene in m_sceneList) + { + if (scene.Entities.ContainsKey(agentID) && + scene.Entities[agentID] is ScenePresence) + { + ScenePresence user = (ScenePresence)scene.Entities[agentID]; + if (!user.IsChildAgent) + { + return user.ControllingClient; + } + else + { + child = user.ControllingClient; + } + } + } + + // If we didn't find a root, then just return whichever child we found, or null if none + return child; + } + + #endregion + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs new file mode 100644 index 0000000..f0e386b --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -0,0 +1,1335 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Timers; + +using log4net; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Framework.EventQueue; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +using Caps = OpenSim.Framework.Capabilities.Caps; +using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; + + + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + public class GroupsModule : ISharedRegionModule, IGroupsModule + { + /// + /// ; To use this module, you must specify the following in your OpenSim.ini + /// [GROUPS] + /// Enabled = true + /// Module = XmlRpcGroups + /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php + /// XmlRpcMessagingEnabled = true + /// XmlRpcNoticesEnabled = true + /// XmlRpcDebugEnabled = true + /// XmlRpcServiceReadKey = 1234 + /// XmlRpcServiceWriteKey = 1234 + /// + /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for + /// ; a problem discovered on some Windows based region servers. Only disable + /// ; if you see a large number (dozens) of the following Exceptions: + /// ; System.Net.WebException: The request was aborted: The request was canceled. + /// + /// XmlRpcDisableKeepAlive = false + /// + + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_sceneList = new List(); + + private IMessageTransferModule m_msgTransferModule = null; + + private IGroupsServicesConnector m_groupData = null; + + class GroupRequestIDInfo + { + public GroupRequestID RequestID = new GroupRequestID(); + public DateTime LastUsedTMStamp = DateTime.MinValue; + } + private Dictionary m_clientRequestIDInfo = new Dictionary(); + private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes + private Timer m_clientRequestIDFlushTimer = new Timer(); + + + // Configuration settings + private bool m_groupsEnabled = false; + private bool m_groupNoticesEnabled = true; + private bool m_debugEnabled = true; + + #region IRegionModuleBase Members + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + if (groupsConfig == null) + { + // Do not run this module by default. + return; + } + else + { + m_groupsEnabled = groupsConfig.GetBoolean("Enabled", false); + if (!m_groupsEnabled) + { + return; + } + + if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + { + m_groupsEnabled = false; + + return; + } + + m_log.InfoFormat("[GROUPS]: Initializing {0}", this.Name); + + m_groupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); + m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + + m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; + m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; + m_clientRequestIDFlushTimer.AutoReset = true; + m_clientRequestIDFlushTimer.Start(); + } + } + + void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) + { + lock (m_clientRequestIDInfo) + { + TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); + UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; + foreach (UUID key in CurrentKeys) + { + if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + { + m_clientRequestIDInfo.Remove(key); + } + } + } + } + + public void AddRegion(Scene scene) + { + if (m_groupsEnabled) + scene.RegisterModuleInterface(this); + } + + public void RegionLoaded(Scene scene) + { + if (!m_groupsEnabled) + return; + + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + if (m_groupData == null) + { + m_groupData = scene.RequestModuleInterface(); + + // No Groups Service Connector, then nothing works... + if (m_groupData == null) + { + m_groupsEnabled = false; + m_log.Error("[GROUPS]: Could not get IGroupsServicesConnector"); + Close(); + return; + } + } + + if (m_msgTransferModule == null) + { + m_msgTransferModule = scene.RequestModuleInterface(); + + // No message transfer module, no notices, group invites, rejects, ejects, etc + if (m_msgTransferModule == null) + { + m_groupsEnabled = false; + m_log.Error("[GROUPS]: Could not get MessageTransferModule"); + Close(); + return; + } + } + + lock (m_sceneList) + { + m_sceneList.Add(scene); + } + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + + // The InstantMessageModule itself doesn't do this, + // so lets see if things explode if we don't do it + // scene.EventManager.OnClientClosed += OnClientClosed; + + } + + public void RemoveRegion(Scene scene) + { + if (!m_groupsEnabled) + return; + + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + lock (m_sceneList) + { + m_sceneList.Remove(scene); + } + } + + public void Close() + { + if (!m_groupsEnabled) + return; + + if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); + + m_clientRequestIDFlushTimer.Stop(); + } + + public Type ReplacableInterface + { + get { return null; } + } + + public string Name + { + get { return "XmlRpcGroupsModule"; } + } + + #endregion + + #region ISharedRegionModule Members + + public void PostInitialise() + { + // NoOp + } + + #endregion + + #region EventHandlers + private void OnNewClient(IClientAPI client) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; + client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; + client.OnDirFindQuery += OnDirFindQuery; + client.OnRequestAvatarProperties += OnRequestAvatarProperties; + + // Used for Notices and Group Invites/Accept/Reject + client.OnInstantMessage += OnInstantMessage; + + lock (m_clientRequestIDInfo) + { + if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) + { + // flush any old RequestID information + m_clientRequestIDInfo.Remove(client.AgentId); + } + } + SendAgentGroupDataUpdate(client, client.AgentId); + } + + private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) + { + GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); + } + + /* + * This becomes very problematic in a shared module. In a shared module you may have more then one + * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections. + * The OnClientClosed event does not provide anything to indicate which one of those should be closed + * nor does it provide what scene it was from so that the specific reference can be looked up. + * The InstantMessageModule.cs does not currently worry about unregistering the handles, + * and it should be an issue, since it's the client that references us not the other way around + * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed + private void OnClientClosed(UUID AgentId) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + lock (m_ActiveClients) + { + if (m_ActiveClients.ContainsKey(AgentId)) + { + IClientAPI client = m_ActiveClients[AgentId]; + client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; + client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; + client.OnDirFindQuery -= OnDirFindQuery; + client.OnInstantMessage -= OnInstantMessage; + + m_ActiveClients.Remove(AgentId); + } + else + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Client closed that wasn't registered here."); + } + + + } + } + */ + + + void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) + { + if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + + // TODO: This currently ignores pretty much all the query flags including Mature and sort order + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); + } + + } + + private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID activeGroupID = UUID.Zero; + string activeGroupTitle = string.Empty; + string activeGroupName = string.Empty; + ulong activeGroupPowers = (ulong)GroupPowers.None; + + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); + if (membership != null) + { + activeGroupID = membership.GroupID; + activeGroupTitle = membership.GroupTitle; + activeGroupPowers = membership.GroupPowers; + } + + SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle); + + SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); + } + + private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + string GroupName; + + GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); + if (group != null) + { + GroupName = group.GroupName; + } + else + { + GroupName = "Unknown"; + } + + remoteClient.SendGroupNameReply(GroupID, GroupName); + } + + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Group invitations + if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) + { + UUID inviteID = new UUID(im.imSessionID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + + if (inviteInfo == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Received an Invite IM for an invite that does not exist {0}.", inviteID); + return; + } + + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); + + UUID fromAgentID = new UUID(im.fromAgentID); + if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) + { + // Accept + if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); + + // and the sessionid is the role + m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = UUID.Zero.Guid; + msg.toAgentID = inviteInfo.AgentID.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Groups"; + msg.message = string.Format("You have been added to the group."); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = new byte[0]; + + OutgoingInstantMessage(msg, inviteInfo.AgentID); + + UpdateAllClientsWithGroupInfo(inviteInfo.AgentID); + + // TODO: If the inviter is still online, they need an agent dataupdate + // and maybe group membership updates for the invitee + + m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + } + + // Reject + if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); + m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + } + } + } + + // Group notices + if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) + { + if (!m_groupNoticesEnabled) + { + return; + } + + UUID GroupID = new UUID(im.toAgentID); + if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) + { + UUID NoticeID = UUID.Random(); + string Subject = im.message.Substring(0, im.message.IndexOf('|')); + string Message = im.message.Substring(Subject.Length + 1); + + byte[] bucket; + + if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) + { + bucket = new byte[19]; + bucket[0] = 0; //dunno + bucket[1] = 0; //dunno + GroupID.ToBytes(bucket, 2); + bucket[18] = 0; //dunno + } + else + { + string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); + binBucket = binBucket.Remove(0, 14).Trim(); + if (m_debugEnabled) + { + m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); + + OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + + foreach (string key in binBucketOSD.Keys) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } + } + + // treat as if no attachment + bucket = new byte[19]; + bucket[0] = 0; //dunno + bucket[1] = 0; //dunno + GroupID.ToBytes(bucket, 2); + bucket[18] = 0; //dunno + } + + m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + if (OnNewGroupNotice != null) + { + OnNewGroupNotice(GroupID, NoticeID); + } + + // Send notice out to everyone that wants notices + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) + { + if (member.AcceptNotices) + { + // Build notice IIM + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + + msg.toAgentID = member.AgentID.Guid; + OutgoingInstantMessage(msg, member.AgentID); + } + } + } + } + + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presense server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue + if ((im.dialog == 210)) + { + // This is sent from the region that the ejectee was ejected from + // if it's being delivered here, then the ejectee is here + // so we need to send local updates to the agent. + + UUID ejecteeID = new UUID(im.toAgentID); + + im.dialog = (byte)InstantMessageDialog.MessageFromAgent; + OutgoingInstantMessage(im, ejecteeID); + + IClientAPI ejectee = GetActiveClient(ejecteeID); + if (ejectee != null) + { + UUID groupID = new UUID(im.fromAgentID); + ejectee.SendAgentDropGroup(groupID); + } + } + } + + private void OnGridInstantMessage(GridInstantMessage msg) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Trigger the above event handler + OnInstantMessage(null, msg); + + // If a message from a group arrives here, it may need to be forwarded to a local client + if (msg.fromGroup == true) + { + switch (msg.dialog) + { + case (byte)InstantMessageDialog.GroupInvitation: + case (byte)InstantMessageDialog.GroupNotice: + UUID toAgentID = new UUID(msg.toAgentID); + IClientAPI localClient = GetActiveClient(toAgentID); + if (localClient != null) + { + localClient.SendInstantMessage(msg); + } + break; + } + } + } + + #endregion + + #region IGroupsModule Members + + public event NewGroupNotice OnNewGroupNotice; + + public GroupRecord GetGroupRecord(UUID GroupID) + { + return m_groupData.GetGroupRecord(null, GroupID, null); + } + + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + + // Changing active group changes title, active powers, all kinds of things + // anyone who is in any region that can see this client, should probably be + // updated with new group info. At a minimum, they should get ScenePresence + // updated with new title. + UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + } + + /// + /// Get the Role Titles for an Agent, for a specific group + /// + public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + + List titles = new List(); + foreach (GroupRolesData role in agentRoles) + { + GroupTitlesData title = new GroupTitlesData(); + title.Name = role.Name; + if (agentMembership != null) + { + title.Selected = agentMembership.ActiveRole == role.RoleID; + } + title.UUID = role.RoleID; + + titles.Add(title); + } + + return titles; + } + + public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title); + } + } + + return data; + + } + + public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupRolesData member in data) + { + m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members); + } + } + + return data; + + } + + public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID); + } + } + + return data; + + + } + + public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupProfileData profile = new GroupProfileData(); + + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); + if (groupInfo != null) + { + profile.AllowPublish = groupInfo.AllowPublish; + profile.Charter = groupInfo.Charter; + profile.FounderID = groupInfo.FounderID; + profile.GroupID = groupID; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; + profile.InsigniaID = groupInfo.GroupPicture; + profile.MaturePublish = groupInfo.MaturePublish; + profile.MembershipFee = groupInfo.MembershipFee; + profile.Money = 0; // TODO: Get this from the currency server? + profile.Name = groupInfo.GroupName; + profile.OpenEnrollment = groupInfo.OpenEnrollment; + profile.OwnerRole = groupInfo.OwnerRoleID; + profile.ShowInList = groupInfo.ShowInList; + } + + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + if (memberInfo != null) + { + profile.MemberTitle = memberInfo.GroupTitle; + profile.PowersMask = memberInfo.GroupPowers; + } + + return profile; + } + + public GroupMembershipData[] GetMembershipData(UUID agentID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); + } + + public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + return m_groupData.GetAgentGroupMembership(null, agentID, groupID); + } + + public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security Check? + + m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + } + + public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) + { + // TODO: Security Check? + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); + } + + public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) + { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); + return UUID.Zero; + } + // is there is a money module present ? + IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); + if (money != null) + { + // do the transaction, that is if the agent has got sufficient funds + if (!money.GroupCreationCovered(remoteClient)) { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); + return UUID.Zero; + } + money.ApplyGroupCreationCharge(remoteClient.AgentId); + } + UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + + remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); + + // Update the founder with new group information. + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + + return groupID; + } + + public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // ToDo: check if agent is a member of group and is allowed to see notices? + + return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); + } + + /// + /// Get the title of the agent's current role. + /// + public string GetGroupTitle(UUID avatarID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); + if (membership != null) + { + return membership.GroupTitle; + } + return string.Empty; + } + + /// + /// Change the current Active Group Role for Agent + /// + public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); + + // TODO: Not sure what all is needed here, but if the active group role change is for the group + // the client currently has set active, then we need to do a scene presence update too + // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) + + UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + } + + + public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security Checks? + + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + switch ((OpenMetaverse.GroupRoleUpdate)updateType) + { + case OpenMetaverse.GroupRoleUpdate.Create: + m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); + break; + + case OpenMetaverse.GroupRoleUpdate.Delete: + m_groupData.RemoveGroupRole(grID, groupID, roleID); + break; + + case OpenMetaverse.GroupRoleUpdate.UpdateAll: + case OpenMetaverse.GroupRoleUpdate.UpdateData: + case OpenMetaverse.GroupRoleUpdate.UpdatePowers: + m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); + break; + + case OpenMetaverse.GroupRoleUpdate.NoUpdate: + default: + // No Op + break; + + } + + // TODO: This update really should send out updates for everyone in the role that just got changed. + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + } + + public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // Todo: Security check + + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + switch (changes) + { + case 0: + // Add + m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); + + break; + case 1: + // Remove + m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); + + break; + default: + m_log.ErrorFormat("[GROUPS]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); + break; + } + + // TODO: This update really should send out updates for everyone in the role that just got changed. + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + } + + public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); + + if (data != null) + { + GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = data.GroupID.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; + msg.message = data.noticeData.Subject + "|" + data.Message; + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + msg.binaryBucket = data.BinaryBucket; + + OutgoingInstantMessage(msg, remoteClient.AgentId); + } + + } + + public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.toAgentID = agentID.Guid; + msg.dialog = dialog; + // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; + msg.fromGroup = true; + msg.offline = (byte)1; // Allow this message to be stored for offline use + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = UUID.Zero.Guid; + + GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); + if (info != null) + { + msg.fromAgentID = info.GroupID.Guid; + msg.timestamp = info.noticeData.Timestamp; + msg.fromAgentName = info.noticeData.FromName; + msg.message = info.noticeData.Subject + "|" + info.Message; + msg.binaryBucket = info.BinaryBucket; + } + else + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); + msg.fromAgentID = UUID.Zero.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; + msg.fromAgentName = string.Empty; + msg.message = string.Empty; + msg.binaryBucket = new byte[0]; + } + + return msg; + } + + public void SendAgentGroupDataUpdate(IClientAPI remoteClient) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Send agent information about his groups + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + } + + public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Should check to see if OpenEnrollment, or if there's an outstanding invitation + m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); + + remoteClient.SendJoinGroupReply(groupID, true); + + // Should this send updates to everyone in the group? + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + } + + public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + + remoteClient.SendLeaveGroupReply(groupID, true); + + remoteClient.SendAgentDropGroup(groupID); + + // SL sends out notifcations to the group messaging session that the person has left + // Should this also update everyone who is in the group? + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + } + + public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + // Todo: Security check? + m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); + + remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); + + if ((groupInfo == null) || (userProfile == null)) + { + return; + } + + + // Send Message to Ejectee + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = info.GroupID; + msg.toAgentID = ejecteeID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + OutgoingInstantMessage(msg, ejecteeID); + + + // Message to ejector + // Interop, received special 210 code for ejecting a group member + // this only works within the comms servers domain, and won't work hypergrid + // TODO:FIXME: Use a presense server of some kind to find out where the + // client actually is, and try contacting that region directly to notify them, + // or provide the notification via xmlrpc update queue + + msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + if (userProfile != null) + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); + } + else + { + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); + } + msg.dialog = (byte)210; //interop + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[0]; + OutgoingInstantMessage(msg, remoteClient.AgentId); + + + // SL sends out messages to everyone in the group + // Who all should receive updates and what should they be updated with? + UpdateAllClientsWithGroupInfo(ejecteeID); + } + + public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Todo: Security check, probably also want to send some kind of notification + UUID InviteID = UUID.Random(); + GroupRequestID grid = GetClientGroupRequestID(remoteClient); + + m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); + + // Check to see if the invite went through, if it did not then it's possible + // the remoteClient did not validate or did not have permission to invite. + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); + + if (inviteInfo != null) + { + if (m_msgTransferModule != null) + { + Guid inviteUUID = InviteID.Guid; + + GridInstantMessage msg = new GridInstantMessage(); + + msg.imSessionID = inviteUUID; + + // msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = groupID.Guid; + msg.toAgentID = invitedAgentID.Guid; + //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.timestamp = 0; + msg.fromAgentName = remoteClient.Name; + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); + msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; + msg.fromGroup = true; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.binaryBucket = new byte[20]; + + OutgoingInstantMessage(msg, invitedAgentID); + } + } + } + + #endregion + + #region Client/Update Tools + + /// + /// Try to find an active IClientAPI reference for agentID giving preference to root connections + /// + private IClientAPI GetActiveClient(UUID agentID) + { + IClientAPI child = null; + + // Try root avatar first + foreach (Scene scene in m_sceneList) + { + if (scene.Entities.ContainsKey(agentID) && + scene.Entities[agentID] is ScenePresence) + { + ScenePresence user = (ScenePresence)scene.Entities[agentID]; + if (!user.IsChildAgent) + { + return user.ControllingClient; + } + else + { + child = user.ControllingClient; + } + } + } + + // If we didn't find a root, then just return whichever child we found, or null if none + return child; + } + + private GroupRequestID GetClientGroupRequestID(IClientAPI client) + { + if (client == null) + { + return new GroupRequestID(); + } + + lock (m_clientRequestIDInfo) + { + if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) + { + GroupRequestIDInfo info = new GroupRequestIDInfo(); + info.RequestID.AgentID = client.AgentId; + info.RequestID.SessionID = client.SessionId; + + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); + if (userProfile == null) + { + // This should be impossible. If I've been passed a reference to a client + // that client should be registered with the UserService. So something + // is horribly wrong somewhere. + + m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); + + // Default to local user service and hope for the best? + info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + + } + else if (userProfile is ForeignUserProfileData) + { + // They aren't from around here + ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; + info.RequestID.UserServiceURL = fupd.UserServerURI; + } + else + { + // They're a local user, use this: + info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + } + + m_clientRequestIDInfo.Add(client.AgentId, info); + } + + m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; + } + return m_clientRequestIDInfo[client.AgentId].RequestID; + } + + /// + /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. + /// + private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDArray AgentData = new OSDArray(1); + OSDMap AgentDataMap = new OSDMap(1); + AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); + AgentData.Add(AgentDataMap); + + + OSDArray GroupData = new OSDArray(data.Length); + OSDArray NewGroupData = new OSDArray(data.Length); + + foreach (GroupMembershipData membership in data) + { + OSDMap GroupDataMap = new OSDMap(6); + OSDMap NewGroupDataMap = new OSDMap(1); + + GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); + GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); + GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); + GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); + GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); + GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); + NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); + + GroupData.Add(GroupDataMap); + NewGroupData.Add(NewGroupDataMap); + } + + OSDMap llDataStruct = new OSDMap(3); + llDataStruct.Add("AgentData", AgentData); + llDataStruct.Add("GroupData", GroupData); + llDataStruct.Add("NewGroupData", NewGroupData); + + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); + + if (queue != null) + { + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); + } + + } + + private void SendScenePresenceUpdate(UUID AgentID, string Title) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); + + ScenePresence presence = null; + lock (m_sceneList) + { + foreach (Scene scene in m_sceneList) + { + presence = scene.GetScenePresence(AgentID); + if (presence != null) + { + presence.Grouptitle = Title; + + // FixMe: Ter suggests a "Schedule" method that I can't find. + presence.SendFullUpdateToAllClients(); + } + } + } + } + + /// + /// Send updates to all clients who might be interested in groups data for dataForClientID + /// + private void UpdateAllClientsWithGroupInfo(UUID dataForClientID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Probably isn't nessesary to update every client in every scene. + // Need to examine client updates and do only what's nessesary. + lock (m_sceneList) + { + foreach (Scene scene in m_sceneList) + { + scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); }); + } + } + } + + /// + /// Update remoteClient with group information about dataForAgentID + /// + private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); + + // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff + + OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); + + + // Need to send a group membership update to the client + // UDP version doesn't seem to behave nicely. But we're going to send it out here + // with an empty group membership to hopefully remove groups being displayed due + // to the core Groups Stub + remoteClient.SendGroupMembership(new GroupMembershipData[0]); + + GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); + + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); + remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); + + } + + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); + string firstname, lastname; + if (userProfile != null) + { + firstname = userProfile.FirstName; + lastname = userProfile.SurName; + } + else + { + firstname = "Unknown"; + lastname = "Unknown"; + } + + remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, + lastname, activeGroupPowers, activeGroupName, + activeGroupTitle); + } + + #endregion + + #region IM Backed Processes + + private void OutgoingInstantMessage(GridInstantMessage msg, UUID msgTo) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + IClientAPI localClient = GetActiveClient(msgTo); + if (localClient != null) + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); + localClient.SendInstantMessage(msg); + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is not local, delivering via TransferModule", msgTo); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Message Sent: {0}", success?"Succeeded":"Failed"); }); + } + } + + public void NotifyChange(UUID groupID) + { + // Notify all group members of a chnge in group roles and/or + // permissions + // + } + + #endregion + } + +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs deleted file mode 100644 index 302be4a..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; - -using OpenMetaverse; - -using OpenSim.Framework; - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - interface IGroupDataProvider - { - UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); - List FindGroups(GroupRequestID requestID, string search); - List GetGroupMembers(GroupRequestID requestID, UUID GroupID); - - void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); - List GetGroupRoles(GroupRequestID requestID, UUID GroupID); - List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); - - void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - - void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - - - void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); - - void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); - - void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - - GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); - - void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); - List GetGroupNotices(GroupRequestID requestID, UUID GroupID); - } - - public class GroupInviteInfo - { - public UUID GroupID = UUID.Zero; - public UUID RoleID = UUID.Zero; - public UUID AgentID = UUID.Zero; - public UUID InviteID = UUID.Zero; - } - - public class GroupRequestID - { - public UUID AgentID = UUID.Zero; - public string UserServiceURL = string.Empty; - public UUID SessionID = UUID.Zero; - } -} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs new file mode 100644 index 0000000..9e0fa2d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -0,0 +1,91 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; + +using OpenMetaverse; + +using OpenSim.Framework; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + interface IGroupsServicesConnector + { + UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); + List FindGroups(GroupRequestID requestID, string search); + List GetGroupMembers(GroupRequestID requestID, UUID GroupID); + + void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); + List GetGroupRoles(GroupRequestID requestID, UUID GroupID); + List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); + + void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + + void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + + + void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); + + void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); + + void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + + GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); + + void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); + List GetGroupNotices(GroupRequestID requestID, UUID GroupID); + } + + public class GroupInviteInfo + { + public UUID GroupID = UUID.Zero; + public UUID RoleID = UUID.Zero; + public UUID AgentID = UUID.Zero; + public UUID InviteID = UUID.Zero; + } + + public class GroupRequestID + { + public UUID AgentID = UUID.Zero; + public string UserServiceURL = string.Empty; + public UUID SessionID = UUID.Zero; + } +} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs deleted file mode 100644 index 1d4cde5..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ /dev/null @@ -1,916 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -//using System.Text; - -using Nwc.XmlRpc; - -using log4net; -// using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -//using OpenSim.Region.Framework.Interfaces; - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - public class XmlRpcGroupDataProvider : IGroupDataProvider - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private string m_serviceURL = string.Empty; - - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | - GroupPowers.Accountable | - GroupPowers.JoinChat | - GroupPowers.AllowVoiceChat | - GroupPowers.ReceiveNotices | - GroupPowers.StartProposal | - GroupPowers.VoteOnProposal; - - private bool m_disableKeepAlive = false; - - private string m_groupReadKey = string.Empty; - private string m_groupWriteKey = string.Empty; - - public XmlRpcGroupDataProvider(string serviceURL, bool disableKeepAlive, string groupReadKey, string groupWriteKey) - { - m_serviceURL = serviceURL.Trim(); - m_disableKeepAlive = disableKeepAlive; - - if ((serviceURL == null) || - (serviceURL == string.Empty)) - { - throw new Exception("Please specify a valid ServiceURL for XmlRpcGroupDataProvider in OpenSim.ini, [Groups], XmlRpcServiceURL"); - } - - m_groupReadKey = groupReadKey; - m_groupWriteKey = groupWriteKey; - } - - /// - /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. - /// - public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, - int membershipFee, bool openEnrollment, bool allowPublish, - bool maturePublish, UUID founderID) - { - UUID GroupID = UUID.Random(); - UUID OwnerRoleID = UUID.Random(); - - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - param["Name"] = name; - param["Charter"] = charter; - param["ShowInList"] = showInList == true ? 1 : 0; - param["InsigniaID"] = insigniaID.ToString(); - param["MembershipFee"] = 0; - param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; - param["AllowPublish"] = allowPublish == true ? 1 : 0; - param["MaturePublish"] = maturePublish == true ? 1 : 0; - param["FounderID"] = founderID.ToString(); - param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); - param["OwnerRoleID"] = OwnerRoleID.ToString(); - - // Would this be cleaner as (GroupPowers)ulong.MaxValue; - GroupPowers OwnerPowers = GroupPowers.Accountable - | GroupPowers.AllowEditLand - | GroupPowers.AllowFly - | GroupPowers.AllowLandmark - | GroupPowers.AllowRez - | GroupPowers.AllowSetHome - | GroupPowers.AllowVoiceChat - | GroupPowers.AssignMember - | GroupPowers.AssignMemberLimited - | GroupPowers.ChangeActions - | GroupPowers.ChangeIdentity - | GroupPowers.ChangeMedia - | GroupPowers.ChangeOptions - | GroupPowers.CreateRole - | GroupPowers.DeedObject - | GroupPowers.DeleteRole - | GroupPowers.Eject - | GroupPowers.FindPlaces - | GroupPowers.Invite - | GroupPowers.JoinChat - | GroupPowers.LandChangeIdentity - | GroupPowers.LandDeed - | GroupPowers.LandDivideJoin - | GroupPowers.LandEdit - | GroupPowers.LandEjectAndFreeze - | GroupPowers.LandGardening - | GroupPowers.LandManageAllowed - | GroupPowers.LandManageBanned - | GroupPowers.LandManagePasses - | GroupPowers.LandOptions - | GroupPowers.LandRelease - | GroupPowers.LandSetSale - | GroupPowers.ModerateChat - | GroupPowers.ObjectManipulate - | GroupPowers.ObjectSetForSale - | GroupPowers.ReceiveNotices - | GroupPowers.RemoveMember - | GroupPowers.ReturnGroupOwned - | GroupPowers.ReturnGroupSet - | GroupPowers.ReturnNonGroup - | GroupPowers.RoleProperties - | GroupPowers.SendNotices - | GroupPowers.SetLandingPoint - | GroupPowers.StartProposal - | GroupPowers.VoteOnProposal; - param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); - - - - - Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); - - if (respData.Contains("error")) - { - // UUID is not nullable - - return UUID.Zero; - } - - return UUID.Parse((string)respData["GroupID"]); - } - - public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, - UUID insigniaID, int membershipFee, bool openEnrollment, - bool allowPublish, bool maturePublish) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["Charter"] = charter; - param["ShowInList"] = showInList == true ? 1 : 0; - param["InsigniaID"] = insigniaID.ToString(); - param["MembershipFee"] = membershipFee; - param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; - param["AllowPublish"] = allowPublish == true ? 1 : 0; - param["MaturePublish"] = maturePublish == true ? 1 : 0; - - XmlRpcCall(requestID, "groups.updateGroup", param); - } - - public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, - string title, ulong powers) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["RoleID"] = roleID.ToString(); - param["Name"] = name; - param["Description"] = description; - param["Title"] = title; - param["Powers"] = powers.ToString(); - - XmlRpcCall(requestID, "groups.addRoleToGroup", param); - } - - public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["RoleID"] = roleID.ToString(); - - XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); - } - - public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, - string title, ulong powers) - { - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["RoleID"] = roleID.ToString(); - if (name != null) - { - param["Name"] = name; - } - if (description != null) - { - param["Description"] = description; - } - if (title != null) - { - param["Title"] = title; - } - param["Powers"] = powers.ToString(); - - XmlRpcCall(requestID, "groups.updateGroupRole", param); - } - - public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) - { - Hashtable param = new Hashtable(); - if (GroupID != UUID.Zero) - { - param["GroupID"] = GroupID.ToString(); - } - if ((GroupName != null) && (GroupName != string.Empty)) - { - param["Name"] = GroupName.ToString(); - } - - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); - - if (respData.Contains("error")) - { - return null; - } - - return GroupProfileHashtableToGroupRecord(respData); - - } - - public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); - - if (respData.Contains("error")) - { - // GroupProfileData is not nullable - return new GroupProfileData(); - } - - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); - GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); - - MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; - MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; - - return MemberGroupProfile; - - } - - private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) - { - GroupProfileData group = new GroupProfileData(); - group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); - group.Name = (string)groupProfile["Name"]; - - if (groupProfile["Charter"] != null) - { - group.Charter = (string)groupProfile["Charter"]; - } - - group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; - group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); - group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); - group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; - group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; - group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; - group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); - group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); - - group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); - group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); - - return group; - } - - private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) - { - - GroupRecord group = new GroupRecord(); - group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); - group.GroupName = groupProfile["Name"].ToString(); - if (groupProfile["Charter"] != null) - { - group.Charter = (string)groupProfile["Charter"]; - } - group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; - group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); - group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); - group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; - group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; - group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; - group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); - group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); - - return group; - } - - public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); - } - - public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["SelectedRoleID"] = RoleID.ToString(); - - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); - } - - public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["AcceptNotices"] = AcceptNotices ? "1" : "0"; - param["ListInProfile"] = ListInProfile ? "1" : "0"; - - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); - - } - - public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) - { - Hashtable param = new Hashtable(); - param["InviteID"] = inviteID.ToString(); - param["AgentID"] = agentID.ToString(); - param["RoleID"] = roleID.ToString(); - param["GroupID"] = groupID.ToString(); - - XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); - - } - - public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) - { - Hashtable param = new Hashtable(); - param["InviteID"] = inviteID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); - - if (respData.Contains("error")) - { - return null; - } - - GroupInviteInfo inviteInfo = new GroupInviteInfo(); - inviteInfo.InviteID = inviteID; - inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); - inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); - inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); - - return inviteInfo; - } - - public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) - { - Hashtable param = new Hashtable(); - param["InviteID"] = inviteID.ToString(); - - XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); - } - - public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["RoleID"] = RoleID.ToString(); - - XmlRpcCall(requestID, "groups.addAgentToGroup", param); - } - - public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); - } - - public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["RoleID"] = RoleID.ToString(); - - XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); - } - - public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - param["RoleID"] = RoleID.ToString(); - - XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); - } - - - public List FindGroups(GroupRequestID requestID, string search) - { - Hashtable param = new Hashtable(); - param["Search"] = search; - - Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); - - List findings = new List(); - - if (!respData.Contains("error")) - { - Hashtable results = (Hashtable)respData["results"]; - foreach (Hashtable groupFind in results.Values) - { - DirGroupsReplyData data = new DirGroupsReplyData(); - data.groupID = new UUID((string)groupFind["GroupID"]); ; - data.groupName = (string)groupFind["Name"]; - data.members = int.Parse((string)groupFind["Members"]); - // data.searchOrder = order; - - findings.Add(data); - } - } - - return findings; - } - - public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); - - if (respData.Contains("error")) - { - return null; - } - - GroupMembershipData data = HashTableToGroupMembershipData(respData); - - return data; - } - - public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); - - if (respData.Contains("error")) - { - return null; - } - - return HashTableToGroupMembershipData(respData); - } - - - public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); - - List memberships = new List(); - - if (!respData.Contains("error")) - { - foreach (object membership in respData.Values) - { - memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); - } - } - - return memberships; - } - - public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["AgentID"] = AgentID.ToString(); - param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); - - List Roles = new List(); - - if (respData.Contains("error")) - { - return Roles; - } - - foreach (Hashtable role in respData.Values) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = new UUID((string)role["RoleID"]); - data.Name = (string)role["Name"]; - data.Description = (string)role["Description"]; - data.Powers = ulong.Parse((string)role["Powers"]); - data.Title = (string)role["Title"]; - - Roles.Add(data); - } - - return Roles; - - - } - - public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); - - List Roles = new List(); - - if (respData.Contains("error")) - { - return Roles; - } - - foreach (Hashtable role in respData.Values) - { - GroupRolesData data = new GroupRolesData(); - data.Description = (string)role["Description"]; - data.Members = int.Parse((string)role["Members"]); - data.Name = (string)role["Name"]; - data.Powers = ulong.Parse((string)role["Powers"]); - data.RoleID = new UUID((string)role["RoleID"]); - data.Title = (string)role["Title"]; - - Roles.Add(data); - } - - return Roles; - - } - - private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) - { - GroupMembershipData data = new GroupMembershipData(); - data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); - data.Contribution = int.Parse((string)respData["Contribution"]); - data.ListInProfile = ((string)respData["ListInProfile"] == "1"); - - data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); - data.GroupTitle = (string)respData["Title"]; - - data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); - - // Is this group the agent's active group - - data.GroupID = new UUID((string)respData["GroupID"]); - - UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); - data.Active = data.GroupID.Equals(ActiveGroup); - - data.AllowPublish = ((string)respData["AllowPublish"] == "1"); - if (respData["Charter"] != null) - { - data.Charter = (string)respData["Charter"]; - } - data.FounderID = new UUID((string)respData["FounderID"]); - data.GroupID = new UUID((string)respData["GroupID"]); - data.GroupName = (string)respData["GroupName"]; - data.GroupPicture = new UUID((string)respData["InsigniaID"]); - data.MaturePublish = ((string)respData["MaturePublish"] == "1"); - data.MembershipFee = int.Parse((string)respData["MembershipFee"]); - data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); - data.ShowInList = ((string)respData["ShowInList"] == "1"); - return data; - } - - public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); - - List members = new List(); - - if (respData.Contains("error")) - { - return members; - } - - foreach (Hashtable membership in respData.Values) - { - GroupMembersData data = new GroupMembersData(); - - data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; - data.AgentID = new UUID((string)membership["AgentID"]); - data.Contribution = int.Parse((string)membership["Contribution"]); - data.IsOwner = ((string)membership["IsOwner"]) == "1"; - data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; - data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); - data.Title = (string)membership["Title"]; - - members.Add(data); - } - - return members; - - } - - public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); - - List members = new List(); - - if (!respData.Contains("error")) - { - foreach (Hashtable membership in respData.Values) - { - GroupRoleMembersData data = new GroupRoleMembersData(); - - data.MemberID = new UUID((string)membership["AgentID"]); - data.RoleID = new UUID((string)membership["RoleID"]); - - members.Add(data); - } - } - return members; - } - - public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) - { - Hashtable param = new Hashtable(); - param["GroupID"] = GroupID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); - - List values = new List(); - - if (!respData.Contains("error")) - { - foreach (Hashtable value in respData.Values) - { - GroupNoticeData data = new GroupNoticeData(); - data.NoticeID = UUID.Parse((string)value["NoticeID"]); - data.Timestamp = uint.Parse((string)value["Timestamp"]); - data.FromName = (string)value["FromName"]; - data.Subject = (string)value["Subject"]; - data.HasAttachment = false; - data.AssetType = 0; - - values.Add(data); - } - } - return values; - - } - public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) - { - Hashtable param = new Hashtable(); - param["NoticeID"] = noticeID.ToString(); - - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); - - - if (respData.Contains("error")) - { - return null; - } - - GroupNoticeInfo data = new GroupNoticeInfo(); - data.GroupID = UUID.Parse((string)respData["GroupID"]); - data.Message = (string)respData["Message"]; - data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); - data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); - data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); - data.noticeData.FromName = (string)respData["FromName"]; - data.noticeData.Subject = (string)respData["Subject"]; - data.noticeData.HasAttachment = false; - data.noticeData.AssetType = 0; - - if (data.Message == null) - { - data.Message = string.Empty; - } - - return data; - } - public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) - { - string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); - - Hashtable param = new Hashtable(); - param["GroupID"] = groupID.ToString(); - param["NoticeID"] = noticeID.ToString(); - param["FromName"] = fromName; - param["Subject"] = subject; - param["Message"] = message; - param["BinaryBucket"] = binBucket; - param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - - XmlRpcCall(requestID, "groups.addGroupNotice", param); - } - - private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) - { - if (requestID == null) - { - requestID = new GroupRequestID(); - } - param.Add("RequestingAgentID", requestID.AgentID.ToString()); - param.Add("RequestingAgentUserService", requestID.UserServiceURL); - param.Add("RequestingSessionID", requestID.SessionID.ToString()); - - - param.Add("ReadKey", m_groupReadKey); - param.Add("WriteKey", m_groupWriteKey); - - - IList parameters = new ArrayList(); - parameters.Add(param); - - XmlRpcRequest req; - if (!m_disableKeepAlive) - { - req = new XmlRpcRequest(function, parameters); - } - else - { - // This seems to solve a major problem on some windows servers - req = new NoKeepAliveXmlRpcRequest(function, parameters); - } - - XmlRpcResponse resp = null; - - try - { - resp = req.Send(m_serviceURL, 10000); - } - catch (Exception e) - { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - - - foreach (string key in param.Keys) - { - m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); - } - - Hashtable respData = new Hashtable(); - respData.Add("error", e.ToString()); - return respData; - } - - if (resp.Value is Hashtable) - { - Hashtable respData = (Hashtable)resp.Value; - if (respData.Contains("error") && !respData.Contains("succeed")) - { - LogRespDataToConsoleError(respData); - } - - return respData; - } - - m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); - - if (resp.Value is ArrayList) - { - ArrayList al = (ArrayList)resp.Value; - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); - - foreach (object o in al) - { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); - } - } - else - { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); - } - - Hashtable error = new Hashtable(); - error.Add("error", "invalid return value"); - return error; - } - - private void LogRespDataToConsoleError(Hashtable respData) - { - m_log.Error("[XMLRPCGROUPDATA]: Error:"); - - foreach (string key in respData.Keys) - { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); - - string[] lines = respData[key].ToString().Split(new char[] { '\n' }); - foreach (string line in lines) - { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); - } - - } - } - - } - - public class GroupNoticeInfo - { - public GroupNoticeData noticeData = new GroupNoticeData(); - public UUID GroupID = UUID.Zero; - public string Message = string.Empty; - public byte[] BinaryBucket = new byte[0]; - } -} - -namespace Nwc.XmlRpc -{ - using System; - using System.Collections; - using System.IO; - using System.Xml; - using System.Net; - using System.Text; - using System.Reflection; - - /// Class supporting the request side of an XML-RPC transaction. - public class NoKeepAliveXmlRpcRequest : XmlRpcRequest - { - private Encoding _encoding = new ASCIIEncoding(); - private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); - private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); - - /// Instantiate an XmlRpcRequest for a specified method and parameters. - /// String designating the object.method on the server the request - /// should be directed to. - /// ArrayList of XML-RPC type parameters to invoke the request with. - public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) - { - MethodName = methodName; - _params = parameters; - } - - /// Send the request to the server. - /// String The url of the XML-RPC server. - /// XmlRpcResponse The response generated. - public XmlRpcResponse Send(String url) - { - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); - if (request == null) - throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR, - XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url); - request.Method = "POST"; - request.ContentType = "text/xml"; - request.AllowWriteStreamBuffering = true; - request.KeepAlive = false; - - Stream stream = request.GetRequestStream(); - XmlTextWriter xml = new XmlTextWriter(stream, _encoding); - _serializer.Serialize(xml, this); - xml.Flush(); - xml.Close(); - - HttpWebResponse response = (HttpWebResponse)request.GetResponse(); - StreamReader input = new StreamReader(response.GetResponseStream()); - - XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); - input.Close(); - response.Close(); - return resp; - } - } -} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs deleted file mode 100644 index 4095041..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; - - -using log4net; -using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - - -using Caps = OpenSim.Framework.Capabilities.Caps; - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - public class XmlRpcGroupsMessaging : ISharedRegionModule - { - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private List m_sceneList = new List(); - - private IMessageTransferModule m_msgTransferModule = null; - - private IGroupsModule m_groupsModule = null; - - // TODO: Move this off to the xmlrpc server - public Dictionary> m_agentsInGroupSession = new Dictionary>(); - public Dictionary> m_agentsDroppedSession = new Dictionary>(); - - - // Config Options - private bool m_groupMessagingEnabled = false; - private bool m_debugEnabled = true; - - #region IRegionModuleBase Members - - public void Initialise(IConfigSource config) - { - IConfig groupsConfig = config.Configs["Groups"]; - - if (groupsConfig == null) - { - // Do not run this module by default. - return; - } - else - { - if (!groupsConfig.GetBoolean("Enabled", false)) - { - return; - } - - if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") - { - m_groupMessagingEnabled = false; - - return; - } - - m_groupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); - - if (!m_groupMessagingEnabled) - { - return; - } - - m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); - - m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); - } - - m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up"); - - } - - public void AddRegion(Scene scene) - { - // NoOp - } - public void RegionLoaded(Scene scene) - { - if (!m_groupMessagingEnabled) - return; - - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupsModule = scene.RequestModuleInterface(); - - // No groups module, no groups messaging - if (m_groupsModule == null) - { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); - Close(); - m_groupMessagingEnabled = false; - return; - } - - m_msgTransferModule = scene.RequestModuleInterface(); - - // No message transfer module, no groups messaging - if (m_msgTransferModule == null) - { - m_log.Error("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); - Close(); - m_groupMessagingEnabled = false; - return; - } - - - m_sceneList.Add(scene); - - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - - } - - public void RemoveRegion(Scene scene) - { - if (!m_groupMessagingEnabled) - return; - - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_sceneList.Remove(scene); - } - - public void Close() - { - if (!m_groupMessagingEnabled) - return; - - if (m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); - - foreach (Scene scene in m_sceneList) - { - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; - } - - m_sceneList.Clear(); - - m_groupsModule = null; - m_msgTransferModule = null; - } - - public Type ReplacableInterface - { - get { return null; } - } - - public string Name - { - get { return "XmlRpcGroupsMessaging"; } - } - - #endregion - - #region ISharedRegionModule Members - - public void PostInitialise() - { - // NoOp - } - - #endregion - - #region SimGridEventHandlers - - private void OnNewClient(IClientAPI client) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); - - client.OnInstantMessage += OnInstantMessage; - } - - private void OnGridInstantMessage(GridInstantMessage msg) - { - // The instant message module will only deliver messages of dialog types: - // MessageFromAgent, StartTyping, StopTyping, MessageFromObject - // - // Any other message type will not be delivered to a client by the - // Instant Message Module - - - if (m_debugEnabled) - { - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - DebugGridInstantMessage(msg); - } - - // Incoming message from a group - if ((msg.fromGroup == true) && - ((msg.dialog == (byte)InstantMessageDialog.SessionSend) - || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) - || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) - { - ProcessMessageFromGroupSession(msg); - } - } - - private void ProcessMessageFromGroupSession(GridInstantMessage msg) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); - - switch (msg.dialog) - { - case (byte)InstantMessageDialog.SessionAdd: - AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); - break; - - case (byte)InstantMessageDialog.SessionDrop: - RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); - break; - - case (byte)InstantMessageDialog.SessionSend: - if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) - && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) - { - // Agent not in session and hasn't dropped from session - // Add them to the session for now, and Invite them - AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); - - UUID toAgentID = new UUID(msg.toAgentID); - IClientAPI activeClient = GetActiveClient(toAgentID); - if (activeClient != null) - { - UUID groupID = new UUID(msg.fromAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); - if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); - - // Force? open the group session dialog??? - IEventQueue eq = activeClient.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( - groupID - , groupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp - , msg.offline == 1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , Utils.StringToBytes(groupInfo.GroupName) - ); - - eq.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - } - } - } - else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) - { - // User hasn't dropped, so they're in the session, - // maybe we should deliver it. - IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); - if (client != null) - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); - client.SendInstantMessage(msg); - } - else - { - m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); - } - } - break; - - default: - m_log.WarnFormat("[GROUPS-MESSAGING]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); - break; - } - } - - #endregion - - #region ClientEvents - - private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) - { - if (m_agentsInGroupSession.ContainsKey(sessionID)) - { - // If in session remove - if (m_agentsInGroupSession[sessionID].Contains(agentID)) - { - m_agentsInGroupSession[sessionID].Remove(agentID); - } - - // If not in dropped list, add - if (!m_agentsDroppedSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); - m_agentsDroppedSession[sessionID].Add(agentID); - } - } - } - - private void AddAgentToGroupSession(Guid agentID, Guid sessionID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupSessionTracking(sessionID); - - // If nessesary, remove from dropped list - if (m_agentsDroppedSession[sessionID].Contains(agentID)) - { - m_agentsDroppedSession[sessionID].Remove(agentID); - } - - // If nessesary, add to in session list - if (!m_agentsInGroupSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); - m_agentsInGroupSession[sessionID].Add(agentID); - } - } - - private void CreateGroupSessionTracking(Guid sessionID) - { - if (!m_agentsInGroupSession.ContainsKey(sessionID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); - m_agentsInGroupSession.Add(sessionID, new List()); - m_agentsDroppedSession.Add(sessionID, new List()); - } - } - - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) - { - if (m_debugEnabled) - { - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - DebugGridInstantMessage(im); - } - - // Start group IM session - if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) - { - UUID groupID = new UUID(im.toAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); - if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); - - AddAgentToGroupSession(im.fromAgentID, im.imSessionID); - - ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); - - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - queue.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(im.fromAgentID) - , new UUID(im.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - } - } - - // Send a message from locally connected client to a group - if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) - { - UUID groupID = new UUID(im.toAgentID); - - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); - - SendMessageToGroup(im, groupID); - } - } - - #endregion - - private void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) - { - if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) - { - // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); - continue; - } - - // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = im.binaryBucket; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - - // Updat Pertinate fields to make it a "group message" - msg.fromAgentID = groupID.Guid; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; - - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) - { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - else - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); - } - } - } - - void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap moderatedMap = new OSDMap(4); - moderatedMap.Add("voice", OSD.FromBoolean(false)); - - OSDMap sessionMap = new OSDMap(4); - sessionMap.Add("moderated_mode", moderatedMap); - sessionMap.Add("session_name", OSD.FromString(groupName)); - sessionMap.Add("type", OSD.FromInteger(0)); - sessionMap.Add("voice_enabled", OSD.FromBoolean(false)); - - OSDMap bodyMap = new OSDMap(4); - bodyMap.Add("session_id", OSD.FromUUID(groupID)); - bodyMap.Add("temp_session_id", OSD.FromUUID(groupID)); - bodyMap.Add("success", OSD.FromBoolean(true)); - bodyMap.Add("session_info", sessionMap); - - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - - if (queue != null) - { - queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); - } - } - - private void DebugGridInstantMessage(GridInstantMessage im) - { - // Don't log any normal IMs (privacy!) - if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent) - { - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); - } - } - - #region Client Tools - - /// - /// Try to find an active IClientAPI reference for agentID giving preference to root connections - /// - private IClientAPI GetActiveClient(UUID agentID) - { - IClientAPI child = null; - - // Try root avatar first - foreach (Scene scene in m_sceneList) - { - if (scene.Entities.ContainsKey(agentID) && - scene.Entities[agentID] is ScenePresence) - { - ScenePresence user = (ScenePresence)scene.Entities[agentID]; - if (!user.IsChildAgent) - { - return user.ControllingClient; - } - else - { - child = user.ControllingClient; - } - } - } - - // If we didn't find a root, then just return whichever child we found, or null if none - return child; - } - - #endregion - } -} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs deleted file mode 100644 index 2cbc571..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ /dev/null @@ -1,1331 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Timers; - -using log4net; -using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Framework.EventQueue; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -using Caps = OpenSim.Framework.Capabilities.Caps; -using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; - - - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - public class XmlRpcGroupsModule : ISharedRegionModule, IGroupsModule - { - /// - /// ; To use this module, you must specify the following in your OpenSim.ini - /// [GROUPS] - /// Enabled = true - /// Module = XmlRpcGroups - /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php - /// XmlRpcMessagingEnabled = true - /// XmlRpcNoticesEnabled = true - /// XmlRpcDebugEnabled = true - /// XmlRpcServiceReadKey = 1234 - /// XmlRpcServiceWriteKey = 1234 - /// - /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for - /// ; a problem discovered on some Windows based region servers. Only disable - /// ; if you see a large number (dozens) of the following Exceptions: - /// ; System.Net.WebException: The request was aborted: The request was canceled. - /// - /// XmlRpcDisableKeepAlive = false - /// - - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private List m_sceneList = new List(); - - private IMessageTransferModule m_msgTransferModule = null; - - private IGroupDataProvider m_groupData = null; - - class GroupRequestIDInfo - { - public GroupRequestID RequestID = new GroupRequestID(); - public DateTime LastUsedTMStamp = DateTime.MinValue; - } - private Dictionary m_clientRequestIDInfo = new Dictionary(); - private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes - private Timer m_clientRequestIDFlushTimer = new Timer(); - - - // Configuration settings - private const string m_defaultXmlRpcServiceURL = "http://osflotsam.org/xmlrpc.php"; - private bool m_groupsEnabled = false; - private bool m_groupNoticesEnabled = true; - private bool m_debugEnabled = true; - - #region IRegionModuleBase Members - - public void Initialise(IConfigSource config) - { - IConfig groupsConfig = config.Configs["Groups"]; - - if (groupsConfig == null) - { - // Do not run this module by default. - return; - } - else - { - m_groupsEnabled = groupsConfig.GetBoolean("Enabled", false); - if (!m_groupsEnabled) - { - return; - } - - if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") - { - m_groupsEnabled = false; - - return; - } - - m_log.InfoFormat("[GROUPS]: Initializing {0}", this.Name); - - string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL); - bool DisableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); - - string ServiceReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); - string ServiceWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); - - m_groupData = new XmlRpcGroupDataProvider(ServiceURL, DisableKeepAlive, ServiceReadKey, ServiceWriteKey); - m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL); - - m_groupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); - m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); - - m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; - m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; - m_clientRequestIDFlushTimer.AutoReset = true; - m_clientRequestIDFlushTimer.Start(); - } - } - - void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) - { - lock (m_clientRequestIDInfo) - { - TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); - UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; - foreach (UUID key in CurrentKeys) - { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) - { - m_clientRequestIDInfo.Remove(key); - } - } - } - } - - public void AddRegion(Scene scene) - { - if (m_groupsEnabled) - scene.RegisterModuleInterface(this); - } - - public void RegionLoaded(Scene scene) - { - if (!m_groupsEnabled) - return; - - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - if (m_msgTransferModule == null) - { - m_msgTransferModule = scene.RequestModuleInterface(); - - // No message transfer module, no notices, group invites, rejects, ejects, etc - if (m_msgTransferModule == null) - { - m_groupsEnabled = false; - m_log.Error("[GROUPS]: Could not get MessageTransferModule"); - Close(); - return; - } - } - - lock (m_sceneList) - { - m_sceneList.Add(scene); - } - - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - - // The InstantMessageModule itself doesn't do this, - // so lets see if things explode if we don't do it - // scene.EventManager.OnClientClosed += OnClientClosed; - - } - - public void RemoveRegion(Scene scene) - { - if (!m_groupsEnabled) - return; - - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - lock (m_sceneList) - { - m_sceneList.Remove(scene); - } - } - - public void Close() - { - if (!m_groupsEnabled) - return; - - if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); - - m_clientRequestIDFlushTimer.Stop(); - } - - public Type ReplacableInterface - { - get { return null; } - } - - public string Name - { - get { return "XmlRpcGroupsModule"; } - } - - #endregion - - #region ISharedRegionModule Members - - public void PostInitialise() - { - // NoOp - } - - #endregion - - #region EventHandlers - private void OnNewClient(IClientAPI client) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; - client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; - client.OnDirFindQuery += OnDirFindQuery; - client.OnRequestAvatarProperties += OnRequestAvatarProperties; - - // Used for Notices and Group Invites/Accept/Reject - client.OnInstantMessage += OnInstantMessage; - - lock (m_clientRequestIDInfo) - { - if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - // flush any old RequestID information - m_clientRequestIDInfo.Remove(client.AgentId); - } - } - SendAgentGroupDataUpdate(client, client.AgentId); - } - - private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) - { - GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); - remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); - } - - /* - * This becomes very problematic in a shared module. In a shared module you may have more then one - * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections. - * The OnClientClosed event does not provide anything to indicate which one of those should be closed - * nor does it provide what scene it was from so that the specific reference can be looked up. - * The InstantMessageModule.cs does not currently worry about unregistering the handles, - * and it should be an issue, since it's the client that references us not the other way around - * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed - private void OnClientClosed(UUID AgentId) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - lock (m_ActiveClients) - { - if (m_ActiveClients.ContainsKey(AgentId)) - { - IClientAPI client = m_ActiveClients[AgentId]; - client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; - client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; - client.OnDirFindQuery -= OnDirFindQuery; - client.OnInstantMessage -= OnInstantMessage; - - m_ActiveClients.Remove(AgentId); - } - else - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Client closed that wasn't registered here."); - } - - - } - } - */ - - - void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) - { - if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); - - // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); - } - - } - - private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - UUID activeGroupID = UUID.Zero; - string activeGroupTitle = string.Empty; - string activeGroupName = string.Empty; - ulong activeGroupPowers = (ulong)GroupPowers.None; - - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); - if (membership != null) - { - activeGroupID = membership.GroupID; - activeGroupTitle = membership.GroupTitle; - activeGroupPowers = membership.GroupPowers; - } - - SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle); - - SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); - } - - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - string GroupName; - - GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); - if (group != null) - { - GroupName = group.GroupName; - } - else - { - GroupName = "Unknown"; - } - - remoteClient.SendGroupNameReply(GroupID, GroupName); - } - - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Group invitations - if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) - { - UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); - - if (inviteInfo == null) - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Received an Invite IM for an invite that does not exist {0}.", inviteID); - return; - } - - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); - - UUID fromAgentID = new UUID(im.fromAgentID); - if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) - { - // Accept - if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); - - // and the sessionid is the role - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); - - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = UUID.Zero.Guid; - msg.toAgentID = inviteInfo.AgentID.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Groups"; - msg.message = string.Format("You have been added to the group."); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = new byte[0]; - - OutgoingInstantMessage(msg, inviteInfo.AgentID); - - UpdateAllClientsWithGroupInfo(inviteInfo.AgentID); - - // TODO: If the inviter is still online, they need an agent dataupdate - // and maybe group membership updates for the invitee - - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); - } - - // Reject - if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); - } - } - } - - // Group notices - if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) - { - if (!m_groupNoticesEnabled) - { - return; - } - - UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) - { - UUID NoticeID = UUID.Random(); - string Subject = im.message.Substring(0, im.message.IndexOf('|')); - string Message = im.message.Substring(Subject.Length + 1); - - byte[] bucket; - - if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) - { - bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno - } - else - { - string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); - binBucket = binBucket.Remove(0, 14).Trim(); - if (m_debugEnabled) - { - m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); - - OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); - - foreach (string key in binBucketOSD.Keys) - { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); - } - } - - // treat as if no attachment - bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno - } - - m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); - if (OnNewGroupNotice != null) - { - OnNewGroupNotice(GroupID, NoticeID); - } - - // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) - { - if (member.AcceptNotices) - { - // Build notice IIM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); - - msg.toAgentID = member.AgentID.Guid; - OutgoingInstantMessage(msg, member.AgentID); - } - } - } - } - - // Interop, received special 210 code for ejecting a group member - // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the - // client actually is, and try contacting that region directly to notify them, - // or provide the notification via xmlrpc update queue - if ((im.dialog == 210)) - { - // This is sent from the region that the ejectee was ejected from - // if it's being delivered here, then the ejectee is here - // so we need to send local updates to the agent. - - UUID ejecteeID = new UUID(im.toAgentID); - - im.dialog = (byte)InstantMessageDialog.MessageFromAgent; - OutgoingInstantMessage(im, ejecteeID); - - IClientAPI ejectee = GetActiveClient(ejecteeID); - if (ejectee != null) - { - UUID groupID = new UUID(im.fromAgentID); - ejectee.SendAgentDropGroup(groupID); - } - } - } - - private void OnGridInstantMessage(GridInstantMessage msg) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Trigger the above event handler - OnInstantMessage(null, msg); - - // If a message from a group arrives here, it may need to be forwarded to a local client - if (msg.fromGroup == true) - { - switch (msg.dialog) - { - case (byte)InstantMessageDialog.GroupInvitation: - case (byte)InstantMessageDialog.GroupNotice: - UUID toAgentID = new UUID(msg.toAgentID); - IClientAPI localClient = GetActiveClient(toAgentID); - if (localClient != null) - { - localClient.SendInstantMessage(msg); - } - break; - } - } - } - - #endregion - - #region IGroupsModule Members - - public event NewGroupNotice OnNewGroupNotice; - - public GroupRecord GetGroupRecord(UUID GroupID) - { - return m_groupData.GetGroupRecord(null, GroupID, null); - } - - public void ActivateGroup(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); - - // Changing active group changes title, active powers, all kinds of things - // anyone who is in any region that can see this client, should probably be - // updated with new group info. At a minimum, they should get ScenePresence - // updated with new title. - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); - } - - /// - /// Get the Role Titles for an Agent, for a specific group - /// - public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); - - List titles = new List(); - foreach (GroupRolesData role in agentRoles) - { - GroupTitlesData title = new GroupTitlesData(); - title.Name = role.Name; - if (agentMembership != null) - { - title.Selected = agentMembership.ActiveRole == role.RoleID; - } - title.UUID = role.RoleID; - - titles.Add(title); - } - - return titles; - } - - public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title); - } - } - - return data; - - } - - public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupRolesData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members); - } - } - - return data; - - } - - public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID); - } - } - - return data; - - - } - - public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupProfileData profile = new GroupProfileData(); - - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); - if (groupInfo != null) - { - profile.AllowPublish = groupInfo.AllowPublish; - profile.Charter = groupInfo.Charter; - profile.FounderID = groupInfo.FounderID; - profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; - profile.InsigniaID = groupInfo.GroupPicture; - profile.MaturePublish = groupInfo.MaturePublish; - profile.MembershipFee = groupInfo.MembershipFee; - profile.Money = 0; // TODO: Get this from the currency server? - profile.Name = groupInfo.GroupName; - profile.OpenEnrollment = groupInfo.OpenEnrollment; - profile.OwnerRole = groupInfo.OwnerRoleID; - profile.ShowInList = groupInfo.ShowInList; - } - - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); - if (memberInfo != null) - { - profile.MemberTitle = memberInfo.GroupTitle; - profile.PowersMask = memberInfo.GroupPowers; - } - - return profile; - } - - public GroupMembershipData[] GetMembershipData(UUID agentID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); - } - - public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - return m_groupData.GetAgentGroupMembership(null, agentID, groupID); - } - - public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Security Check? - - m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); - } - - public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) - { - // TODO: Security Check? - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); - } - - public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) - { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); - return UUID.Zero; - } - // is there is a money module present ? - IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); - if (money != null) - { - // do the transaction, that is if the agent has got sufficient funds - if (!money.GroupCreationCovered(remoteClient)) { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); - return UUID.Zero; - } - money.ApplyGroupCreationCharge(remoteClient.AgentId); - } - UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); - - remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); - - // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); - - return groupID; - } - - public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // ToDo: check if agent is a member of group and is allowed to see notices? - - return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); - } - - /// - /// Get the title of the agent's current role. - /// - public string GetGroupTitle(UUID avatarID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); - if (membership != null) - { - return membership.GroupTitle; - } - return string.Empty; - } - - /// - /// Change the current Active Group Role for Agent - /// - public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); - - // TODO: Not sure what all is needed here, but if the active group role change is for the group - // the client currently has set active, then we need to do a scene presence update too - // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) - - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); - } - - - public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Security Checks? - - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - switch ((OpenMetaverse.GroupRoleUpdate)updateType) - { - case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); - break; - - case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(grID, groupID, roleID); - break; - - case OpenMetaverse.GroupRoleUpdate.UpdateAll: - case OpenMetaverse.GroupRoleUpdate.UpdateData: - case OpenMetaverse.GroupRoleUpdate.UpdatePowers: - m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); - break; - - case OpenMetaverse.GroupRoleUpdate.NoUpdate: - default: - // No Op - break; - - } - - // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); - } - - public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // Todo: Security check - - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - switch (changes) - { - case 0: - // Add - m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); - - break; - case 1: - // Remove - m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); - - break; - default: - m_log.ErrorFormat("[GROUPS]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); - break; - } - - // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); - } - - public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); - - if (data != null) - { - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); - - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; - msg.message = data.noticeData.Subject + "|" + data.Message; - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = data.BinaryBucket; - - OutgoingInstantMessage(msg, remoteClient.AgentId); - } - - } - - public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.toAgentID = agentID.Guid; - msg.dialog = dialog; - // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; - msg.fromGroup = true; - msg.offline = (byte)1; // Allow this message to be stored for offline use - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - - GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); - if (info != null) - { - msg.fromAgentID = info.GroupID.Guid; - msg.timestamp = info.noticeData.Timestamp; - msg.fromAgentName = info.noticeData.FromName; - msg.message = info.noticeData.Subject + "|" + info.Message; - msg.binaryBucket = info.BinaryBucket; - } - else - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); - msg.fromAgentID = UUID.Zero.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; - msg.fromAgentName = string.Empty; - msg.message = string.Empty; - msg.binaryBucket = new byte[0]; - } - - return msg; - } - - public void SendAgentGroupDataUpdate(IClientAPI remoteClient) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Send agent information about his groups - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); - } - - public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); - - remoteClient.SendJoinGroupReply(groupID, true); - - // Should this send updates to everyone in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); - } - - public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); - - remoteClient.SendLeaveGroupReply(groupID, true); - - remoteClient.SendAgentDropGroup(groupID); - - // SL sends out notifcations to the group messaging session that the person has left - // Should this also update everyone who is in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); - } - - public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - // Todo: Security check? - m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); - - remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); - - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); - - if ((groupInfo == null) || (userProfile == null)) - { - return; - } - - - // Send Message to Ejectee - GridInstantMessage msg = new GridInstantMessage(); - - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - // msg.fromAgentID = info.GroupID; - msg.toAgentID = ejecteeID.Guid; - //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, ejecteeID); - - - // Message to ejector - // Interop, received special 210 code for ejecting a group member - // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the - // client actually is, and try contacting that region directly to notify them, - // or provide the notification via xmlrpc update queue - - msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - if (userProfile != null) - { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); - } - else - { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); - } - msg.dialog = (byte)210; //interop - msg.fromGroup = false; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, remoteClient.AgentId); - - - // SL sends out messages to everyone in the group - // Who all should receive updates and what should they be updated with? - UpdateAllClientsWithGroupInfo(ejecteeID); - } - - public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Todo: Security check, probably also want to send some kind of notification - UUID InviteID = UUID.Random(); - GroupRequestID grid = GetClientGroupRequestID(remoteClient); - - m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); - - // Check to see if the invite went through, if it did not then it's possible - // the remoteClient did not validate or did not have permission to invite. - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); - - if (inviteInfo != null) - { - if (m_msgTransferModule != null) - { - Guid inviteUUID = InviteID.Guid; - - GridInstantMessage msg = new GridInstantMessage(); - - msg.imSessionID = inviteUUID; - - // msg.fromAgentID = remoteClient.AgentId.Guid; - msg.fromAgentID = groupID.Guid; - msg.toAgentID = invitedAgentID.Guid; - //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; - msg.binaryBucket = new byte[20]; - - OutgoingInstantMessage(msg, invitedAgentID); - } - } - } - - #endregion - - #region Client/Update Tools - - /// - /// Try to find an active IClientAPI reference for agentID giving preference to root connections - /// - private IClientAPI GetActiveClient(UUID agentID) - { - IClientAPI child = null; - - // Try root avatar first - foreach (Scene scene in m_sceneList) - { - if (scene.Entities.ContainsKey(agentID) && - scene.Entities[agentID] is ScenePresence) - { - ScenePresence user = (ScenePresence)scene.Entities[agentID]; - if (!user.IsChildAgent) - { - return user.ControllingClient; - } - else - { - child = user.ControllingClient; - } - } - } - - // If we didn't find a root, then just return whichever child we found, or null if none - return child; - } - - private GroupRequestID GetClientGroupRequestID(IClientAPI client) - { - if (client == null) - { - return new GroupRequestID(); - } - - lock (m_clientRequestIDInfo) - { - if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - GroupRequestIDInfo info = new GroupRequestIDInfo(); - info.RequestID.AgentID = client.AgentId; - info.RequestID.SessionID = client.SessionId; - - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); - if (userProfile == null) - { - // This should be impossible. If I've been passed a reference to a client - // that client should be registered with the UserService. So something - // is horribly wrong somewhere. - - m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); - - // Default to local user service and hope for the best? - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - - } - else if (userProfile is ForeignUserProfileData) - { - // They aren't from around here - ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; - info.RequestID.UserServiceURL = fupd.UserServerURI; - } - else - { - // They're a local user, use this: - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - } - - m_clientRequestIDInfo.Add(client.AgentId, info); - } - - m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; - } - return m_clientRequestIDInfo[client.AgentId].RequestID; - } - - /// - /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. - /// - private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDArray AgentData = new OSDArray(1); - OSDMap AgentDataMap = new OSDMap(1); - AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); - AgentData.Add(AgentDataMap); - - - OSDArray GroupData = new OSDArray(data.Length); - OSDArray NewGroupData = new OSDArray(data.Length); - - foreach (GroupMembershipData membership in data) - { - OSDMap GroupDataMap = new OSDMap(6); - OSDMap NewGroupDataMap = new OSDMap(1); - - GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); - GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); - GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); - GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); - GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); - GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); - NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); - - GroupData.Add(GroupDataMap); - NewGroupData.Add(NewGroupDataMap); - } - - OSDMap llDataStruct = new OSDMap(3); - llDataStruct.Add("AgentData", AgentData); - llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); - - IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - - if (queue != null) - { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); - } - - } - - private void SendScenePresenceUpdate(UUID AgentID, string Title) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); - - ScenePresence presence = null; - lock (m_sceneList) - { - foreach (Scene scene in m_sceneList) - { - presence = scene.GetScenePresence(AgentID); - if (presence != null) - { - presence.Grouptitle = Title; - - // FixMe: Ter suggests a "Schedule" method that I can't find. - presence.SendFullUpdateToAllClients(); - } - } - } - } - - /// - /// Send updates to all clients who might be interested in groups data for dataForClientID - /// - private void UpdateAllClientsWithGroupInfo(UUID dataForClientID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Probably isn't nessesary to update every client in every scene. - // Need to examine client updates and do only what's nessesary. - lock (m_sceneList) - { - foreach (Scene scene in m_sceneList) - { - scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); }); - } - } - } - - /// - /// Update remoteClient with group information about dataForAgentID - /// - private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); - - // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - - OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); - - - // Need to send a group membership update to the client - // UDP version doesn't seem to behave nicely. But we're going to send it out here - // with an empty group membership to hopefully remove groups being displayed due - // to the core Groups Stub - remoteClient.SendGroupMembership(new GroupMembershipData[0]); - - GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); - - SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); - remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); - - } - - private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); - string firstname, lastname; - if (userProfile != null) - { - firstname = userProfile.FirstName; - lastname = userProfile.SurName; - } - else - { - firstname = "Unknown"; - lastname = "Unknown"; - } - - remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, - lastname, activeGroupPowers, activeGroupName, - activeGroupTitle); - } - - #endregion - - #region IM Backed Processes - - private void OutgoingInstantMessage(GridInstantMessage msg, UUID msgTo) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - IClientAPI localClient = GetActiveClient(msgTo); - if (localClient != null) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); - localClient.SendInstantMessage(msg); - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is not local, delivering via TransferModule", msgTo); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Message Sent: {0}", success?"Succeeded":"Failed"); }); - } - } - - public void NotifyChange(UUID groupID) - { - // Notify all group members of a chnge in group roles and/or - // permissions - // - } - - #endregion - } - -} diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs new file mode 100644 index 0000000..03fe109 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -0,0 +1,1007 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; + +using Nwc.XmlRpc; + +using log4net; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | + GroupPowers.VoteOnProposal; + + private bool m_connectorEnabled = false; + + private string m_serviceURL = string.Empty; + + private bool m_disableKeepAlive = false; + + private string m_groupReadKey = string.Empty; + private string m_groupWriteKey = string.Empty; + + + #region IRegionModuleBase Members + + public string Name + { + get { return "XmlRpcGroupsServicesConnector"; } + } + + // this module is not intended to be replaced, but there should only be 1 of them. + public Type ReplacableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + if (groupsConfig == null) + { + // Do not run this module by default. + return; + } + else + { + // if groups aren't enabled, we're not needed. + // if we're not specified as the connector to use, then we're not wanted + if ( (groupsConfig.GetBoolean("Enabled", false) == false) + || (groupsConfig.GetString("GroupsServicesConnectorModule", "Default") != Name)) + { + m_connectorEnabled = false; + return; + } + + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + + m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); + if ((m_serviceURL == null) || + (m_serviceURL == string.Empty)) + { + m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_connectorEnabled = false; + return; + } + + m_disableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); + + m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); + m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); + + // If we got all the config options we need, lets start'er'up + m_connectorEnabled = true; + } + } + + public void Close() + { + m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + } + + public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (m_connectorEnabled) + scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (scene.RequestModuleInterface() == this) + scene.UnregisterModuleInterface(this); + } + + public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) + { + // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info + // scene.EventManager.OnNewClient += OnNewClient; + } + + #endregion + + #region ISharedRegionModule Members + + public void PostInitialise() + { + // NoOp + } + + #endregion + + + + #region IGroupsServicesConnector Members + + /// + /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. + /// + public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, + int membershipFee, bool openEnrollment, bool allowPublish, + bool maturePublish, UUID founderID) + { + UUID GroupID = UUID.Random(); + UUID OwnerRoleID = UUID.Random(); + + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + param["Name"] = name; + param["Charter"] = charter; + param["ShowInList"] = showInList == true ? 1 : 0; + param["InsigniaID"] = insigniaID.ToString(); + param["MembershipFee"] = 0; + param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; + param["AllowPublish"] = allowPublish == true ? 1 : 0; + param["MaturePublish"] = maturePublish == true ? 1 : 0; + param["FounderID"] = founderID.ToString(); + param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); + param["OwnerRoleID"] = OwnerRoleID.ToString(); + + // Would this be cleaner as (GroupPowers)ulong.MaxValue; + GroupPowers OwnerPowers = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); + + + + + Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); + + if (respData.Contains("error")) + { + // UUID is not nullable + + return UUID.Zero; + } + + return UUID.Parse((string)respData["GroupID"]); + } + + public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, + UUID insigniaID, int membershipFee, bool openEnrollment, + bool allowPublish, bool maturePublish) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["Charter"] = charter; + param["ShowInList"] = showInList == true ? 1 : 0; + param["InsigniaID"] = insigniaID.ToString(); + param["MembershipFee"] = membershipFee; + param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; + param["AllowPublish"] = allowPublish == true ? 1 : 0; + param["MaturePublish"] = maturePublish == true ? 1 : 0; + + XmlRpcCall(requestID, "groups.updateGroup", param); + } + + public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + param["Name"] = name; + param["Description"] = description; + param["Title"] = title; + param["Powers"] = powers.ToString(); + + XmlRpcCall(requestID, "groups.addRoleToGroup", param); + } + + public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + + XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); + } + + public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["RoleID"] = roleID.ToString(); + if (name != null) + { + param["Name"] = name; + } + if (description != null) + { + param["Description"] = description; + } + if (title != null) + { + param["Title"] = title; + } + param["Powers"] = powers.ToString(); + + XmlRpcCall(requestID, "groups.updateGroupRole", param); + } + + public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) + { + Hashtable param = new Hashtable(); + if (GroupID != UUID.Zero) + { + param["GroupID"] = GroupID.ToString(); + } + if ((GroupName != null) && (GroupName != string.Empty)) + { + param["Name"] = GroupName.ToString(); + } + + Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + + if (respData.Contains("error")) + { + return null; + } + + return GroupProfileHashtableToGroupRecord(respData); + + } + + public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + + if (respData.Contains("error")) + { + // GroupProfileData is not nullable + return new GroupProfileData(); + } + + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); + GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); + + MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; + MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; + + return MemberGroupProfile; + + } + + + + public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); + } + + public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["SelectedRoleID"] = RoleID.ToString(); + + XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + } + + public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["AcceptNotices"] = AcceptNotices ? "1" : "0"; + param["ListInProfile"] = ListInProfile ? "1" : "0"; + + XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + + } + + public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + param["AgentID"] = agentID.ToString(); + param["RoleID"] = roleID.ToString(); + param["GroupID"] = groupID.ToString(); + + XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); + + } + + public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); + + if (respData.Contains("error")) + { + return null; + } + + GroupInviteInfo inviteInfo = new GroupInviteInfo(); + inviteInfo.InviteID = inviteID; + inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); + inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); + inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); + + return inviteInfo; + } + + public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + { + Hashtable param = new Hashtable(); + param["InviteID"] = inviteID.ToString(); + + XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); + } + + public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + XmlRpcCall(requestID, "groups.addAgentToGroup", param); + } + + public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); + } + + public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); + } + + public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + param["RoleID"] = RoleID.ToString(); + + XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); + } + + + public List FindGroups(GroupRequestID requestID, string search) + { + Hashtable param = new Hashtable(); + param["Search"] = search; + + Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); + + List findings = new List(); + + if (!respData.Contains("error")) + { + Hashtable results = (Hashtable)respData["results"]; + foreach (Hashtable groupFind in results.Values) + { + DirGroupsReplyData data = new DirGroupsReplyData(); + data.groupID = new UUID((string)groupFind["GroupID"]); ; + data.groupName = (string)groupFind["Name"]; + data.members = int.Parse((string)groupFind["Members"]); + // data.searchOrder = order; + + findings.Add(data); + } + } + + return findings; + } + + public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); + + if (respData.Contains("error")) + { + return null; + } + + GroupMembershipData data = HashTableToGroupMembershipData(respData); + + return data; + } + + public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); + + if (respData.Contains("error")) + { + return null; + } + + return HashTableToGroupMembershipData(respData); + } + + + public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); + + List memberships = new List(); + + if (!respData.Contains("error")) + { + foreach (object membership in respData.Values) + { + memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); + } + } + + return memberships; + } + + public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["AgentID"] = AgentID.ToString(); + param["GroupID"] = GroupID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); + + List Roles = new List(); + + if (respData.Contains("error")) + { + return Roles; + } + + foreach (Hashtable role in respData.Values) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = new UUID((string)role["RoleID"]); + data.Name = (string)role["Name"]; + data.Description = (string)role["Description"]; + data.Powers = ulong.Parse((string)role["Powers"]); + data.Title = (string)role["Title"]; + + Roles.Add(data); + } + + return Roles; + + + } + + public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); + + List Roles = new List(); + + if (respData.Contains("error")) + { + return Roles; + } + + foreach (Hashtable role in respData.Values) + { + GroupRolesData data = new GroupRolesData(); + data.Description = (string)role["Description"]; + data.Members = int.Parse((string)role["Members"]); + data.Name = (string)role["Name"]; + data.Powers = ulong.Parse((string)role["Powers"]); + data.RoleID = new UUID((string)role["RoleID"]); + data.Title = (string)role["Title"]; + + Roles.Add(data); + } + + return Roles; + + } + + + + public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); + + List members = new List(); + + if (respData.Contains("error")) + { + return members; + } + + foreach (Hashtable membership in respData.Values) + { + GroupMembersData data = new GroupMembersData(); + + data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; + data.AgentID = new UUID((string)membership["AgentID"]); + data.Contribution = int.Parse((string)membership["Contribution"]); + data.IsOwner = ((string)membership["IsOwner"]) == "1"; + data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; + data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); + data.Title = (string)membership["Title"]; + + members.Add(data); + } + + return members; + + } + + public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); + + List members = new List(); + + if (!respData.Contains("error")) + { + foreach (Hashtable membership in respData.Values) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = new UUID((string)membership["AgentID"]); + data.RoleID = new UUID((string)membership["RoleID"]); + + members.Add(data); + } + } + return members; + } + + public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) + { + Hashtable param = new Hashtable(); + param["GroupID"] = GroupID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); + + List values = new List(); + + if (!respData.Contains("error")) + { + foreach (Hashtable value in respData.Values) + { + GroupNoticeData data = new GroupNoticeData(); + data.NoticeID = UUID.Parse((string)value["NoticeID"]); + data.Timestamp = uint.Parse((string)value["Timestamp"]); + data.FromName = (string)value["FromName"]; + data.Subject = (string)value["Subject"]; + data.HasAttachment = false; + data.AssetType = 0; + + values.Add(data); + } + } + return values; + + } + public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) + { + Hashtable param = new Hashtable(); + param["NoticeID"] = noticeID.ToString(); + + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); + + + if (respData.Contains("error")) + { + return null; + } + + GroupNoticeInfo data = new GroupNoticeInfo(); + data.GroupID = UUID.Parse((string)respData["GroupID"]); + data.Message = (string)respData["Message"]; + data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); + data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); + data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); + data.noticeData.FromName = (string)respData["FromName"]; + data.noticeData.Subject = (string)respData["Subject"]; + data.noticeData.HasAttachment = false; + data.noticeData.AssetType = 0; + + if (data.Message == null) + { + data.Message = string.Empty; + } + + return data; + } + public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + { + string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); + + Hashtable param = new Hashtable(); + param["GroupID"] = groupID.ToString(); + param["NoticeID"] = noticeID.ToString(); + param["FromName"] = fromName; + param["Subject"] = subject; + param["Message"] = message; + param["BinaryBucket"] = binBucket; + param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); + + XmlRpcCall(requestID, "groups.addGroupNotice", param); + } + #endregion + + #region XmlRpcHashtableMarshalling + private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) + { + GroupProfileData group = new GroupProfileData(); + group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); + group.Name = (string)groupProfile["Name"]; + + if (groupProfile["Charter"] != null) + { + group.Charter = (string)groupProfile["Charter"]; + } + + group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; + group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); + group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); + group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; + group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; + group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; + group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); + group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); + + group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); + group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); + + return group; + } + + private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) + { + + GroupRecord group = new GroupRecord(); + group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); + group.GroupName = groupProfile["Name"].ToString(); + if (groupProfile["Charter"] != null) + { + group.Charter = (string)groupProfile["Charter"]; + } + group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; + group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); + group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); + group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; + group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; + group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; + group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); + group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); + + return group; + } + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) + { + GroupMembershipData data = new GroupMembershipData(); + data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); + data.Contribution = int.Parse((string)respData["Contribution"]); + data.ListInProfile = ((string)respData["ListInProfile"] == "1"); + + data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); + data.GroupTitle = (string)respData["Title"]; + + data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); + + // Is this group the agent's active group + + data.GroupID = new UUID((string)respData["GroupID"]); + + UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); + data.Active = data.GroupID.Equals(ActiveGroup); + + data.AllowPublish = ((string)respData["AllowPublish"] == "1"); + if (respData["Charter"] != null) + { + data.Charter = (string)respData["Charter"]; + } + data.FounderID = new UUID((string)respData["FounderID"]); + data.GroupID = new UUID((string)respData["GroupID"]); + data.GroupName = (string)respData["GroupName"]; + data.GroupPicture = new UUID((string)respData["InsigniaID"]); + data.MaturePublish = ((string)respData["MaturePublish"] == "1"); + data.MembershipFee = int.Parse((string)respData["MembershipFee"]); + data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); + data.ShowInList = ((string)respData["ShowInList"] == "1"); + return data; + } + + #endregion + + /// + /// Encapsulate the XmlRpc call to standardize security and error handling. + /// + private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) + { + if (requestID == null) + { + requestID = new GroupRequestID(); + } + param.Add("RequestingAgentID", requestID.AgentID.ToString()); + param.Add("RequestingAgentUserService", requestID.UserServiceURL); + param.Add("RequestingSessionID", requestID.SessionID.ToString()); + + + param.Add("ReadKey", m_groupReadKey); + param.Add("WriteKey", m_groupWriteKey); + + + IList parameters = new ArrayList(); + parameters.Add(param); + + XmlRpcRequest req; + if (!m_disableKeepAlive) + { + req = new XmlRpcRequest(function, parameters); + } + else + { + // This seems to solve a major problem on some windows servers + req = new NoKeepAliveXmlRpcRequest(function, parameters); + } + + XmlRpcResponse resp = null; + + try + { + resp = req.Send(m_serviceURL, 10000); + } + catch (Exception e) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); + + + foreach (string key in param.Keys) + { + m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); + } + + Hashtable respData = new Hashtable(); + respData.Add("error", e.ToString()); + return respData; + } + + if (resp.Value is Hashtable) + { + Hashtable respData = (Hashtable)resp.Value; + if (respData.Contains("error") && !respData.Contains("succeed")) + { + LogRespDataToConsoleError(respData); + } + + return respData; + } + + m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + + if (resp.Value is ArrayList) + { + ArrayList al = (ArrayList)resp.Value; + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); + + foreach (object o in al) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); + } + } + else + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); + } + + Hashtable error = new Hashtable(); + error.Add("error", "invalid return value"); + return error; + } + + private void LogRespDataToConsoleError(Hashtable respData) + { + m_log.Error("[XMLRPCGROUPDATA]: Error:"); + + foreach (string key in respData.Keys) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); + + string[] lines = respData[key].ToString().Split(new char[] { '\n' }); + foreach (string line in lines) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); + } + + } + } + + + } + + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; + } +} + +namespace Nwc.XmlRpc +{ + using System; + using System.Collections; + using System.IO; + using System.Xml; + using System.Net; + using System.Text; + using System.Reflection; + + /// Class supporting the request side of an XML-RPC transaction. + public class NoKeepAliveXmlRpcRequest : XmlRpcRequest + { + private Encoding _encoding = new ASCIIEncoding(); + private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); + private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); + + /// Instantiate an XmlRpcRequest for a specified method and parameters. + /// String designating the object.method on the server the request + /// should be directed to. + /// ArrayList of XML-RPC type parameters to invoke the request with. + public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) + { + MethodName = methodName; + _params = parameters; + } + + /// Send the request to the server. + /// String The url of the XML-RPC server. + /// XmlRpcResponse The response generated. + public XmlRpcResponse Send(String url) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + if (request == null) + throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR, + XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url); + request.Method = "POST"; + request.ContentType = "text/xml"; + request.AllowWriteStreamBuffering = true; + request.KeepAlive = false; + + Stream stream = request.GetRequestStream(); + XmlTextWriter xml = new XmlTextWriter(stream, _encoding); + _serializer.Serialize(xml, this); + xml.Flush(); + xml.Close(); + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + StreamReader input = new StreamReader(response.GetResponseStream()); + + XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); + input.Close(); + response.Close(); + return resp; + } + } +} -- cgit v1.1 From 6c65b990a2b0a7766841e1776fe533a1f1e98203 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 5 Aug 2009 13:20:46 -0700 Subject: Fixes mono Add-In references for the OptionalModules add-in so that groups doesn't throw errors, and so that the add-in is correctly reported as "OptionalModules" rather then as "SampleMoney" --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 ++ OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 ++ .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 2 ++ 3 files changed, 6 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 8fbda28..f7883da 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -31,6 +31,7 @@ using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; @@ -46,6 +47,7 @@ using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GroupsMessagingModule : ISharedRegionModule { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index f0e386b..3fd2a85 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -31,6 +31,7 @@ using System.Reflection; using System.Timers; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; @@ -49,6 +50,7 @@ using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GroupsModule : ISharedRegionModule, IGroupsModule { /// diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 03fe109..80adb9e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -33,6 +33,7 @@ using System.Reflection; using Nwc.XmlRpc; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; @@ -43,6 +44,7 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { private static readonly ILog m_log = -- cgit v1.1 From c73a6ab7e01efd07f68798de8b402343bef12de4 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 5 Aug 2009 14:56:48 -0700 Subject: Continue with renaming of Groups module components --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 27 ++++++++++------------ .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 +++++++++++++--------- .../XmlRpcGroupsServicesConnectorModule.cs | 2 +- 3 files changed, 29 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index f7883da..0bfb8e7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupsModule m_groupsModule = null; - // TODO: Move this off to the xmlrpc server + // TODO: Move this off to the Groups Server public Dictionary> m_agentsInGroupSession = new Dictionary>(); public Dictionary> m_agentsDroppedSession = new Dictionary>(); @@ -81,31 +81,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } else { - if (!groupsConfig.GetBoolean("Enabled", false)) - { - return; - } - - if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + // if groups aren't enabled, we're not needed. + // if we're not specified as the connector to use, then we're not wanted + if ((groupsConfig.GetBoolean("Enabled", false) == false) + || (groupsConfig.GetString("MessagingModule", "Default") != Name)) { m_groupMessagingEnabled = false; - return; } - m_groupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); + m_groupMessagingEnabled = groupsConfig.GetBoolean("MessagingEnabled", true); if (!m_groupMessagingEnabled) { return; } - m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging"); + m_log.Info("[GROUPS-MESSAGING]: Initializing GroupsMessagingModule"); - m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); } - m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up"); + m_log.Info("[GROUPS-MESSAGING]: GroupsMessagingModule starting up"); } @@ -125,7 +122,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // No groups module, no groups messaging if (m_groupsModule == null) { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; return; @@ -165,7 +162,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupMessagingEnabled) return; - if (m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); + if (m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down GroupsMessagingModule module."); foreach (Scene scene in m_sceneList) { @@ -186,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public string Name { - get { return "XmlRpcGroupsMessaging"; } + get { return "GroupsMessagingModule"; } } #endregion diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 3fd2a85..5ec8de8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -57,14 +57,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// ; To use this module, you must specify the following in your OpenSim.ini /// [GROUPS] /// Enabled = true - /// Module = XmlRpcGroups - /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php - /// XmlRpcMessagingEnabled = true - /// XmlRpcNoticesEnabled = true - /// XmlRpcDebugEnabled = true - /// XmlRpcServiceReadKey = 1234 + /// + /// GroupsModule = GroupsModule + /// NoticesEnabled = true + /// DebugEnabled = true + /// + /// GroupsServicesConnectorModule = XmlRpcGroupsServicesConnector + /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php + /// XmlRpcServiceReadKey = 1234 /// XmlRpcServiceWriteKey = 1234 /// + /// GroupsMessagingModule = GroupsMessagingModule + /// GroupsMessagingEnabled = true + /// /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for /// ; a problem discovered on some Windows based region servers. Only disable /// ; if you see a large number (dozens) of the following Exceptions: @@ -116,7 +121,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") + if (groupsConfig.GetString("Module", "Default") != Name) { m_groupsEnabled = false; @@ -125,8 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS]: Initializing {0}", this.Name); - m_groupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true); - m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true); + m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; @@ -224,7 +229,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupsEnabled) return; - if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); + if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); m_clientRequestIDFlushTimer.Stop(); } @@ -236,7 +241,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public string Name { - get { return "XmlRpcGroupsModule"; } + get { return "GroupsModule"; } } #endregion diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 80adb9e..d77fe5b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -96,7 +96,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // if groups aren't enabled, we're not needed. // if we're not specified as the connector to use, then we're not wanted if ( (groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("GroupsServicesConnectorModule", "Default") != Name)) + || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) { m_connectorEnabled = false; return; -- cgit v1.1 From 6244b8c384790fbd846d6a9014d14096a1223c7b Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Thu, 6 Aug 2009 09:34:30 -0700 Subject: Fixing comments re: INI file. --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 5ec8de8..725c303 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// [GROUPS] /// Enabled = true /// - /// GroupsModule = GroupsModule + /// Module = GroupsModule /// NoticesEnabled = true /// DebugEnabled = true /// @@ -67,8 +67,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// XmlRpcServiceReadKey = 1234 /// XmlRpcServiceWriteKey = 1234 /// - /// GroupsMessagingModule = GroupsMessagingModule - /// GroupsMessagingEnabled = true + /// MessagingModule = GroupsMessagingModule + /// MessagingEnabled = true /// /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for /// ; a problem discovered on some Windows based region servers. Only disable -- cgit v1.1 From 2b990a61bfa88e13d5ad19602e6acef751ea473c Mon Sep 17 00:00:00 2001 From: Teravus Ovares (Dan Olivares) Date: Fri, 7 Aug 2009 20:31:48 -0400 Subject: This is the second part of the 'not crash on regionsize changes'. This lets you configure region sizes to be smaller without crashing the region. I remind you that regions are still square, must be a multiple of 4, and the Linden client doesn't like anything other then 256. If you set it bigger or smaller, the terrain doesn't load in the client, the map has issues, and god forbid you connect it to a grid that expects 256m regions. --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 4 ++-- OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index 2f1dbc1..9273fb5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -50,8 +50,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Local constants - - private static readonly Vector3 CenterOfRegion = new Vector3(128, 128, 20); + + private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); private static readonly char[] CS_SPACE = { ' ' }; private const int WD_INTERVAL = 1000; // base watchdog interval diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index ba3f3e5..203948e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -45,7 +45,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(128, 128, 20); + private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); private const int DEBUG_CHANNEL = 2147483647; private static int _idk_ = 0; -- cgit v1.1 From 7fc9358ec36b40c8226a0d76fd9cb5ae70151b5e Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 8 Aug 2009 03:29:00 +0100 Subject: Patch from otakup0pe: A better solution for making the FreeSwitch module cooperate with existing installations --- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 29 ++++++++----- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 48 ++++++++++++---------- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 8 ++-- 3 files changed, 51 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index c05d598..b1f93e9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -26,7 +26,9 @@ */ using log4net; +using System; using System.Reflection; +using System.Text; using System.Collections; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice @@ -37,7 +39,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public Hashtable HandleDialplanRequest(Hashtable request) + public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request) { m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString()); @@ -48,33 +50,39 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); } + string requestcontext = (string) request["Hunt-Context"]; response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = @" + response["int_response_code"] = 200; + if ( Context != String.Empty && Context != requestcontext) + { + m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); + response["str_response_string"] = ""; + } else { + response["str_response_string"] = String.Format(@"
- + " + - +/* - + */ - + @" - + - + @@ -86,7 +94,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
-
"; + ", Context, Realm); + } return response; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 0a9f69d..8afaeea 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -38,12 +38,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public Hashtable HandleDirectoryRequest(Hashtable request) + public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request) { + Hashtable response = new Hashtable(); + string domain = (string) request["domain"]; + if ( domain != Realm) { + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + response["str_response_string"] = ""; + } else { m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); - Hashtable response = new Hashtable(); - // information in the request we might be interested in // Request 1 sip_auth for users account @@ -85,11 +91,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice if (sipAuthMethod == "REGISTER") { - response = HandleRegister(request); + response = HandleRegister(Context, Realm, request); } else if (sipAuthMethod == "INVITE") { - response = HandleInvite(request); + response = HandleInvite(Context, Realm, request); } else { @@ -101,19 +107,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } else if (eventCallingFunction == "switch_xml_locate_user") { - response = HandleLocateUser(request); + response = HandleLocateUser(Realm, request); } else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made { - response = HandleLocateUser(request); + response = HandleLocateUser(Realm, request); } else if (eventCallingFunction == "user_outgoing_channel") { - response = HandleRegister(request); + response = HandleRegister(Context, Realm, request); } else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup { - response = HandleConfigSofia(request); + response = HandleConfigSofia(Context, Realm, request); } else if (eventCallingFunction == "switch_load_network_lists") { @@ -131,10 +137,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = "text/xml"; response["str_response_string"] = ""; } + } return response; } - private Hashtable HandleRegister(Hashtable request) + private Hashtable HandleRegister(string Context, string Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleRegister called"); @@ -159,19 +166,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + "\r\n" + "
\r\n" + "
\r\n", - domain , user, password); + domain , user, password, Context); return response; } - private Hashtable HandleInvite(Hashtable request) + private Hashtable HandleInvite(string Context, string Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleInvite called"); @@ -196,7 +203,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + @@ -206,20 +213,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n" + - "\r\n" + + "\r\n" + ""+ "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n", - domain , user, password,sipRequestUser); + domain , user, password,sipRequestUser, Context); return response; } - - private Hashtable HandleLocateUser(Hashtable request) + private Hashtable HandleLocateUser(String Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); @@ -253,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - private Hashtable HandleConfigSofia(Hashtable request) + private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request) { m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called"); @@ -286,7 +292,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n"+ "\r\n"+ "\r\n"+ - "\r\n"+ + "\r\n"+ "\r\n"+ "\r\n"+ "\r\n"+ @@ -301,7 +307,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n" + "\r\n" + "\r\n", - domain); + domain, Context); return response; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index f9cb1c4..faa0157 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -95,6 +95,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // private static IPEndPoint m_FreeSwitchServiceIP; private int m_freeSwitchServicePort; private string m_openSimWellKnownHTTPAddress; + private string m_freeSwitchContext; private FreeSwitchDirectory m_FreeSwitchDirectory; private FreeSwitchDialplan m_FreeSwitchDialplan; @@ -151,6 +152,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); + m_freeSwitchContext = m_config.GetString("freeswitch_context", "default"); if (String.IsNullOrEmpty(m_freeSwitchServerUser) || String.IsNullOrEmpty(m_freeSwitchServerPass) || @@ -572,7 +574,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "false\r\n"+ "", m_freeSwitchRealm, m_freeSwitchSIPProxy, m_freeSwitchAttemptUseSTUN, - m_freeSwitchSTUNServer, m_freeSwitchEchoServer, m_freeSwitchEchoPort, + m_freeSwitchEchoServer, m_freeSwitchEchoPort, m_freeSwitchDefaultWellKnownIP, m_freeSwitchDefaultTimeout, m_freeSwitchUrlResetPassword, ""); @@ -728,9 +730,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string section = (string) requestBody["section"]; if (section == "directory") - response = m_FreeSwitchDirectory.HandleDirectoryRequest(requestBody); + response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); else if (section == "dialplan") - response = m_FreeSwitchDialplan.HandleDialplanRequest(requestBody); + response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); else m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); -- cgit v1.1 From bc6ec3b56469f2d722ceee8fdb37059125878f66 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Sun, 9 Aug 2009 00:43:13 +0900 Subject: Formatting cleanup. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 4 ++-- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 2 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index b1f93e9..9ba09ed 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -53,8 +53,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string requestcontext = (string) request["Hunt-Context"]; response["content_type"] = "text/xml"; response["keepalive"] = false; - response["int_response_code"] = 200; - if ( Context != String.Empty && Context != requestcontext) + response["int_response_code"] = 200; + if (Context != String.Empty && Context != requestcontext) { m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); response["str_response_string"] = ""; diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 8afaeea..5d90a8f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { Hashtable response = new Hashtable(); string domain = (string) request["domain"]; - if ( domain != Realm) { + if (domain != Realm) { response["content_type"] = "text/xml"; response["keepalive"] = false; response["int_response_code"] = 200; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index d77fe5b..115660a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -95,8 +95,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { // if groups aren't enabled, we're not needed. // if we're not specified as the connector to use, then we're not wanted - if ( (groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) + if ((groupsConfig.GetBoolean("Enabled", false) == false) + || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) { m_connectorEnabled = false; return; -- cgit v1.1 From eba23048ca2d6dd1b934e11dc426093e5b2134c7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 10 Aug 2009 23:08:22 +0100 Subject: Replace the Replaceable modules name --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- .../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 2 +- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index d7e7a56..70e80bc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat #region INonSharedRegionModule Members - public Type ReplacableInterface + public Type ReplaceableInterface { get { return null; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index bf6d5e7..c864993 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -214,7 +214,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { } - new public Type ReplacableInterface + new public Type ReplaceableInterface { get { return null; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 5465678..febb491 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -388,7 +388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice VivoxLogout(); } - public Type ReplacableInterface + public Type ReplaceableInterface { get { return null; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 0bfb8e7..631d801 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_msgTransferModule = null; } - public Type ReplacableInterface + public Type ReplaceableInterface { get { return null; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 725c303..20f34b5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -234,7 +234,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_clientRequestIDFlushTimer.Stop(); } - public Type ReplacableInterface + public Type ReplaceableInterface { get { return null; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 115660a..b3eaa37 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -77,7 +77,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // this module is not intended to be replaced, but there should only be 1 of them. - public Type ReplacableInterface + public Type ReplaceableInterface { get { return null; } } -- cgit v1.1 From eb78ac343e68d36a84fdc7fec47797233699cccc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 17 Aug 2009 19:48:32 +0100 Subject: Apply http://opensimulator.org/mantis/view.php?id=3538 Add ability to silence IRC relay of region joins and quits from certain users This is useful for admins who wish to remain hidden, or service bots. Thanks RemedyTomm --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 10 ++++++++-- OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs | 12 ++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index f03e5fc..b61959f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -83,6 +83,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal string _accessPassword = String.Empty; internal Regex AccessPasswordRegex = null; + internal List ExcludeList = new List(); internal string AccessPassword { get { return _accessPassword; } @@ -210,8 +211,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); - - + string[] excludes = config.GetString("exclude_list", "").Trim().Split(new Char[] { ',' }); + cs.ExcludeList = new List(excludes.Length); + foreach(string name in excludes) + { + cs.ExcludeList.Add(name.Trim().ToLower()); + } + // Fail if fundamental information is still missing if (cs.Server == null || cs.IrcChannel == null || cs.BaseNickname == null || cs.User == null) diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index 203948e..c49d942 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -145,7 +145,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) { m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name); - cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); + //Check if this person is excluded from IRC + if (!cs.ExcludeList.Contains(client.Name.ToLower())) + { + cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); + } } client.OnLogout -= OnClientLoggedOut; client.OnConnectionClosed -= OnClientLoggedOut; @@ -209,7 +213,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); m_log.DebugFormat("[IRC-Region {0}] {1} has arrived", Region, clientName); - cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has arrived", clientName)); + //Check if this person is excluded from IRC + if (!cs.ExcludeList.Contains(clientName.ToLower())) + { + cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has arrived", clientName)); + } } } } -- cgit v1.1 From 158ad39df0de1c569d24d4ea28dc3952402df101 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Fri, 21 Aug 2009 15:42:36 +0900 Subject: Add copyright header. Formatting cleanup. --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index b61959f..3c5e8c9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -213,7 +213,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); string[] excludes = config.GetString("exclude_list", "").Trim().Split(new Char[] { ',' }); cs.ExcludeList = new List(excludes.Length); - foreach(string name in excludes) + foreach (string name in excludes) { cs.ExcludeList.Add(name.Trim().ToLower()); } -- cgit v1.1 From 05756e1fb96aa47f9ff111dd04499934c7077731 Mon Sep 17 00:00:00 2001 From: dr scofield (aka dirk husemann) Date: Wed, 2 Sep 2009 09:43:22 +0200 Subject: warnings safari. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index faa0157..65c5274 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -85,7 +85,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static string m_freeSwitchRealm; private static string m_freeSwitchSIPProxy; private static bool m_freeSwitchAttemptUseSTUN; - private static string m_freeSwitchSTUNServer; + // private static string m_freeSwitchSTUNServer; private static string m_freeSwitchEchoServer; private static int m_freeSwitchEchoPort; private static string m_freeSwitchDefaultWellKnownIP; @@ -144,7 +144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty); m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm); m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true); - m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm); + // m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm); m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm); m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505); m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm); -- cgit v1.1 From dc925416d7ca8aabbfb44376c366fc7cb990fa07 Mon Sep 17 00:00:00 2001 From: Teravus Ovares (Dan Olivares) Date: Mon, 14 Sep 2009 16:30:14 -0400 Subject: * fix missing lock on XMLRPC GroupsModule --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 20f34b5..37e1ed4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1170,8 +1170,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; + + return m_clientRequestIDInfo[client.AgentId].RequestID; } - return m_clientRequestIDInfo[client.AgentId].RequestID; + + return new GroupRequestID(); } /// -- cgit v1.1 From 69ef95693ae6451e2c754b22190557f3bf15777b Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 17 Sep 2009 15:38:17 +0100 Subject: Thank you, mcortez, for a patch to address showing users in group list Removed patch 0005, which was unrelated and likely accidental, and further didn't apply. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 102 +++++++++++++++------ .../XmlRpcGroupsServicesConnectorModule.cs | 42 ++++++--- 2 files changed, 100 insertions(+), 44 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 37e1ed4..d5cbfd4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -281,7 +281,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) { - GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -485,6 +488,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket[18] = 0; //dunno } + m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { @@ -494,7 +498,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) { - if (member.AcceptNotices) + if (m_debugEnabled) + { + UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID); + if (targetUserProfile != null) + { + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices); + } + else + { + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); + } + } + + if (member.AcceptNotices) { // Build notice IIM GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); @@ -614,13 +631,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title); - } - } return data; @@ -632,14 +642,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupRolesData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members); - } - } - return data; } @@ -650,14 +652,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID); - } - } - return data; @@ -808,7 +802,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Security Checks? + // Security Checks are handled in the Groups Service. GroupRequestID grID = GetClientGroupRequestID(remoteClient); @@ -825,6 +819,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case OpenMetaverse.GroupRoleUpdate.UpdateAll: case OpenMetaverse.GroupRoleUpdate.UpdateData: case OpenMetaverse.GroupRoleUpdate.UpdatePowers: + if (m_debugEnabled) + { + GroupPowers gp = (GroupPowers)powers; + m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); + } m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); break; @@ -1195,6 +1194,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembershipData membership in data) { + if (remoteClient.AgentId != dataForAgentID) + { + if (!membership.ListInProfile) + { + // If we're sending group info to remoteclient about another agent, + // filter out groups the other agent doesn't want to share. + continue; + } + } + OSDMap GroupDataMap = new OSDMap(6); OSDMap NewGroupDataMap = new OSDMap(1); @@ -1281,11 +1290,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // to the core Groups Stub remoteClient.SendGroupMembership(new GroupMembershipData[0]); - GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); + GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); + remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); - SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); - remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); + } + + /// + /// Get a list of groups memberships for the agent that are marked "ListInProfile" + /// + /// + /// + private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) + { + List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); + GroupMembershipData[] membershipArray; + + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); + foreach (GroupMembershipData membership in membershipArray) + { + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); + } + } + return membershipArray; } private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index b3eaa37..805c3d4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -855,16 +855,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IList parameters = new ArrayList(); parameters.Add(param); - XmlRpcRequest req; - if (!m_disableKeepAlive) - { - req = new XmlRpcRequest(function, parameters); - } - else - { - // This seems to solve a major problem on some windows servers - req = new NoKeepAliveXmlRpcRequest(function, parameters); - } + ConfigurableKeepAliveXmlRpcRequest req; + req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); XmlRpcResponse resp = null; @@ -874,10 +866,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } catch (Exception e) { + + m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - + foreach( string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); + } + foreach (string key in param.Keys) { m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); @@ -961,20 +959,24 @@ namespace Nwc.XmlRpc using System.Reflection; /// Class supporting the request side of an XML-RPC transaction. - public class NoKeepAliveXmlRpcRequest : XmlRpcRequest + public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest { private Encoding _encoding = new ASCIIEncoding(); private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); + private bool _disableKeepAlive = true; + + public string RequestResponse = String.Empty; /// Instantiate an XmlRpcRequest for a specified method and parameters. /// String designating the object.method on the server the request /// should be directed to. /// ArrayList of XML-RPC type parameters to invoke the request with. - public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) + public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive) { MethodName = methodName; _params = parameters; + _disableKeepAlive = disableKeepAlive; } /// Send the request to the server. @@ -989,7 +991,7 @@ namespace Nwc.XmlRpc request.Method = "POST"; request.ContentType = "text/xml"; request.AllowWriteStreamBuffering = true; - request.KeepAlive = false; + request.KeepAlive = !_disableKeepAlive; Stream stream = request.GetRequestStream(); XmlTextWriter xml = new XmlTextWriter(stream, _encoding); @@ -1000,7 +1002,17 @@ namespace Nwc.XmlRpc HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader input = new StreamReader(response.GetResponseStream()); - XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); + string inputXml = input.ReadToEnd(); + XmlRpcResponse resp; + try + { + resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); + } + catch (Exception e) + { + RequestResponse = inputXml; + throw e; + } input.Close(); response.Close(); return resp; -- cgit v1.1 From 4f3975f04e7bbaf7b7b8e286831714240ced5e6d Mon Sep 17 00:00:00 2001 From: Rob Smart Date: Fri, 18 Sep 2009 14:11:38 +0100 Subject: addition of a new script function osSetParcelSIPAddress(string SIPAddress), now including iVoiceModule This patch allows the land owner to dynamically set the SIP address of a particular land parcel from script. This allows predetermined SIP addresses to be used, making it easier to allow non OpenSim users to join a regions voice channel. Signed-off-by: dr scofield (aka dirk husemann) --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 55 ++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 65c5274..6b30959 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -53,7 +53,7 @@ using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { - public class FreeSwitchVoiceModule : IRegionModule + public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -101,13 +101,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private FreeSwitchDialplan m_FreeSwitchDialplan; private readonly Dictionary m_UUIDName = new Dictionary(); + private Dictionary m_ParcelAddress = new Dictionary(); + + private Scene m_scene; private IConfig m_config; public void Initialise(Scene scene, IConfigSource config) { - + m_scene = scene; m_config = config.Configs["FreeSwitchVoice"]; if (null == m_config) @@ -230,6 +233,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { OnRegisterCaps(scene, agentID, caps); }; + + try { @@ -255,6 +260,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public void PostInitialise() { + if(m_pluginEnabled) + { + m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); + + // register the voice interface for this module, so the script engine can call us + m_scene.RegisterModuleInterface(this); + } } public void Close() @@ -270,7 +282,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { get { return true; } } - + + // + // implementation of IVoiceModule, called by osSetParcelSIPAddress script function + // + public void setLandSIPAddress(string SIPAddress,UUID GlobalID) + { + m_log.DebugFormat("[FreeSwitchVoice]: setLandSIPAddress parcel id {0}: setting sip address {1}", + GlobalID, SIPAddress); + + lock (m_ParcelAddress) + { + if (m_ParcelAddress.ContainsKey(GlobalID.ToString())) + { + m_ParcelAddress[GlobalID.ToString()] = SIPAddress; + } + else + { + m_ParcelAddress.Add(GlobalID.ToString(), SIPAddress); + } + } + } // // OnRegisterCaps is invoked via the scene.EventManager @@ -776,6 +808,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same // as the directory ID. Otherwise, it reflects the parcel's ID. + + lock (m_ParcelAddress) + { + if (m_ParcelAddress.ContainsKey( land.GlobalID.ToString() )) + { + m_log.DebugFormat("[FreeSwitchVoice]: parcel id {0}: using sip address {1}", + land.GlobalID, m_ParcelAddress[land.GlobalID.ToString()]); + return m_ParcelAddress[land.GlobalID.ToString()]; + } + } if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) { @@ -797,6 +839,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator. channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); + lock (m_ParcelAddress) + { + if (!m_ParcelAddress.ContainsKey(land.GlobalID.ToString())) + { + m_ParcelAddress.Add(land.GlobalID.ToString(),channelUri); + } + } return channelUri; } -- cgit v1.1 From 0cb012aae5799ec746384c36d4bc99ca699edfe7 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Fri, 18 Sep 2009 12:06:33 -0700 Subject: Revert "Thank you, mcortez, for a patch to address showing users in group list" This reverts commit 69ef95693ae6451e2c754b22190557f3bf15777b. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 102 ++++++--------------- .../XmlRpcGroupsServicesConnectorModule.cs | 42 +++------ 2 files changed, 44 insertions(+), 100 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d5cbfd4..37e1ed4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -281,10 +281,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); - GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); + GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -488,7 +485,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket[18] = 0; //dunno } - m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { @@ -498,20 +494,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) { - if (m_debugEnabled) - { - UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID); - if (targetUserProfile != null) - { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices); - } - else - { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); - } - } - - if (member.AcceptNotices) + if (member.AcceptNotices) { // Build notice IIM GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); @@ -631,6 +614,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title); + } + } return data; @@ -642,6 +632,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupRolesData member in data) + { + m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members); + } + } + return data; } @@ -652,6 +650,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID); + } + } + return data; @@ -802,7 +808,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // Security Checks are handled in the Groups Service. + // TODO: Security Checks? GroupRequestID grID = GetClientGroupRequestID(remoteClient); @@ -819,11 +825,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case OpenMetaverse.GroupRoleUpdate.UpdateAll: case OpenMetaverse.GroupRoleUpdate.UpdateData: case OpenMetaverse.GroupRoleUpdate.UpdatePowers: - if (m_debugEnabled) - { - GroupPowers gp = (GroupPowers)powers; - m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); - } m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); break; @@ -1194,16 +1195,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembershipData membership in data) { - if (remoteClient.AgentId != dataForAgentID) - { - if (!membership.ListInProfile) - { - // If we're sending group info to remoteclient about another agent, - // filter out groups the other agent doesn't want to share. - continue; - } - } - OSDMap GroupDataMap = new OSDMap(6); OSDMap NewGroupDataMap = new OSDMap(1); @@ -1290,46 +1281,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // to the core Groups Stub remoteClient.SendGroupMembership(new GroupMembershipData[0]); - GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); - SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); - remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); + GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); - } - - /// - /// Get a list of groups memberships for the agent that are marked "ListInProfile" - /// - /// - /// - private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) - { - List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); - GroupMembershipData[] membershipArray; - - if (requestingClient.AgentId != dataForAgentID) - { - Predicate showInProfile = delegate(GroupMembershipData membership) - { - return membership.ListInProfile; - }; - - membershipArray = membershipData.FindAll(showInProfile).ToArray(); - } - else - { - membershipArray = membershipData.ToArray(); - } - - if (m_debugEnabled) - { - m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); - foreach (GroupMembershipData membership in membershipArray) - { - m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); - } - } + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); + remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); - return membershipArray; } private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 805c3d4..b3eaa37 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -855,8 +855,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IList parameters = new ArrayList(); parameters.Add(param); - ConfigurableKeepAliveXmlRpcRequest req; - req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); + XmlRpcRequest req; + if (!m_disableKeepAlive) + { + req = new XmlRpcRequest(function, parameters); + } + else + { + // This seems to solve a major problem on some windows servers + req = new NoKeepAliveXmlRpcRequest(function, parameters); + } XmlRpcResponse resp = null; @@ -866,16 +874,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } catch (Exception e) { - - m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - foreach( string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) - { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); - } - + foreach (string key in param.Keys) { m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); @@ -959,24 +961,20 @@ namespace Nwc.XmlRpc using System.Reflection; /// Class supporting the request side of an XML-RPC transaction. - public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest + public class NoKeepAliveXmlRpcRequest : XmlRpcRequest { private Encoding _encoding = new ASCIIEncoding(); private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); - private bool _disableKeepAlive = true; - - public string RequestResponse = String.Empty; /// Instantiate an XmlRpcRequest for a specified method and parameters. /// String designating the object.method on the server the request /// should be directed to. /// ArrayList of XML-RPC type parameters to invoke the request with. - public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive) + public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) { MethodName = methodName; _params = parameters; - _disableKeepAlive = disableKeepAlive; } /// Send the request to the server. @@ -991,7 +989,7 @@ namespace Nwc.XmlRpc request.Method = "POST"; request.ContentType = "text/xml"; request.AllowWriteStreamBuffering = true; - request.KeepAlive = !_disableKeepAlive; + request.KeepAlive = false; Stream stream = request.GetRequestStream(); XmlTextWriter xml = new XmlTextWriter(stream, _encoding); @@ -1002,17 +1000,7 @@ namespace Nwc.XmlRpc HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader input = new StreamReader(response.GetResponseStream()); - string inputXml = input.ReadToEnd(); - XmlRpcResponse resp; - try - { - resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); - } - catch (Exception e) - { - RequestResponse = inputXml; - throw e; - } + XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); input.Close(); response.Close(); return resp; -- cgit v1.1 From 61699275ed941565f3ede2a7ce6c00607fb70837 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 19 Aug 2009 07:37:39 -0700 Subject: Add additional debugging to help track down bug with notices not going to group owner/founder. --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 37e1ed4..daba7bc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -494,7 +494,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) { - if (member.AcceptNotices) + if (m_debugEnabled) + { + UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID); + if (targetUserProfile != null) + { + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices); + } + else + { + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); + } + } + + if (member.AcceptNotices) { // Build notice IIM GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); -- cgit v1.1 From 0e07a7ef1044f5987c0d8871972204bce3155a68 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 19 Aug 2009 08:17:29 -0700 Subject: Adding additional debug to output the group powers specified when updating a group role. This will be used to solve some issues with the Group Powers enum. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index daba7bc..fd74168 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -485,6 +485,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups bucket[18] = 0; //dunno } + m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { @@ -821,7 +822,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Security Checks? + // Security Checks are handled in the Groups Service. GroupRequestID grID = GetClientGroupRequestID(remoteClient); @@ -838,6 +839,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups case OpenMetaverse.GroupRoleUpdate.UpdateAll: case OpenMetaverse.GroupRoleUpdate.UpdateData: case OpenMetaverse.GroupRoleUpdate.UpdatePowers: + if (m_debugEnabled) + { + GroupPowers gp = (GroupPowers)powers; + m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); + } m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); break; -- cgit v1.1 From 841cd69af7020f663d040bb0b7e01c03712af322 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 19 Aug 2009 08:50:20 -0700 Subject: Remove debug messages from some areas that have been highly tested, and debug info is no longer nessesary. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 23 ---------------------- 1 file changed, 23 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index fd74168..36adfad 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -628,13 +628,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title); - } - } return data; @@ -646,14 +639,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupRolesData member in data) - { - m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members); - } - } - return data; } @@ -664,14 +649,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID); - } - } - return data; -- cgit v1.1 From 247fdd1a4df55315de7184081ca025ce32e7140d Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Thu, 20 Aug 2009 09:41:14 -0700 Subject: Add additional instrumentation so that when there is an xmlrpc call failure, the actual xml that was returned from the groups service can be logged. --- .../XmlRpcGroupsServicesConnectorModule.cs | 42 ++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index b3eaa37..805c3d4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -855,16 +855,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IList parameters = new ArrayList(); parameters.Add(param); - XmlRpcRequest req; - if (!m_disableKeepAlive) - { - req = new XmlRpcRequest(function, parameters); - } - else - { - // This seems to solve a major problem on some windows servers - req = new NoKeepAliveXmlRpcRequest(function, parameters); - } + ConfigurableKeepAliveXmlRpcRequest req; + req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); XmlRpcResponse resp = null; @@ -874,10 +866,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } catch (Exception e) { + + m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - + foreach( string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); + } + foreach (string key in param.Keys) { m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); @@ -961,20 +959,24 @@ namespace Nwc.XmlRpc using System.Reflection; /// Class supporting the request side of an XML-RPC transaction. - public class NoKeepAliveXmlRpcRequest : XmlRpcRequest + public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest { private Encoding _encoding = new ASCIIEncoding(); private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); + private bool _disableKeepAlive = true; + + public string RequestResponse = String.Empty; /// Instantiate an XmlRpcRequest for a specified method and parameters. /// String designating the object.method on the server the request /// should be directed to. /// ArrayList of XML-RPC type parameters to invoke the request with. - public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) + public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive) { MethodName = methodName; _params = parameters; + _disableKeepAlive = disableKeepAlive; } /// Send the request to the server. @@ -989,7 +991,7 @@ namespace Nwc.XmlRpc request.Method = "POST"; request.ContentType = "text/xml"; request.AllowWriteStreamBuffering = true; - request.KeepAlive = false; + request.KeepAlive = !_disableKeepAlive; Stream stream = request.GetRequestStream(); XmlTextWriter xml = new XmlTextWriter(stream, _encoding); @@ -1000,7 +1002,17 @@ namespace Nwc.XmlRpc HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader input = new StreamReader(response.GetResponseStream()); - XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); + string inputXml = input.ReadToEnd(); + XmlRpcResponse resp; + try + { + resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); + } + catch (Exception e) + { + RequestResponse = inputXml; + throw e; + } input.Close(); response.Close(); return resp; -- cgit v1.1 From 3b511d51388fa355c5ba4889cb7bc74c9c554b89 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 16 Sep 2009 15:39:52 -0700 Subject: Try to filter the groups list returns for User A, when sending to User B, based on User A's preferences for ShowInProfile. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 36adfad..79d7477 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1277,10 +1277,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // to the core Groups Stub remoteClient.SendGroupMembership(new GroupMembershipData[0]); - GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); + List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID); + GroupMembershipData[] membershipArray; - SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); - remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); + if (remoteClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } else { + membershipArray = membershipData.ToArray(); + } + + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); + remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); } -- cgit v1.1 From 65b9084c65f61e5ddb2d4e106aff6ce4f899f2b6 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 16 Sep 2009 16:12:23 -0700 Subject: Add a little debugging for filtered groups lists based on requester --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 79d7477..9d56ba8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1191,6 +1191,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembershipData membership in data) { + if (remoteClient.AgentId != dataForAgentID) + { + if (!membership.ListInProfile) + { + // If we're sending group info to remoteclient about another agent, + // filter out groups the other agent doesn't want to share. + continue; + } + } + OSDMap GroupDataMap = new OSDMap(6); OSDMap NewGroupDataMap = new OSDMap(1); @@ -1292,6 +1302,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups membershipArray = membershipData.ToArray(); } + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: Sending group membership information for {0} to {1}", dataForAgentID, remoteClient.AgentId); + foreach (GroupMembershipData membership in membershipArray) + { + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); + } + } + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); -- cgit v1.1 From 4eb07232e0e8ff36388c21c3b5522b81ee8ef156 Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Wed, 16 Sep 2009 16:51:22 -0700 Subject: Group Membership information is sent out from two different locations, refactored out the filtered membership list code and used it in both locations. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 32 ++++++++++++++++------ 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 9d56ba8..d5cbfd4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -281,7 +281,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) { - GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -1287,10 +1290,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // to the core Groups Stub remoteClient.SendGroupMembership(new GroupMembershipData[0]); - List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID); + GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); + SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); + remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); + + } + + /// + /// Get a list of groups memberships for the agent that are marked "ListInProfile" + /// + /// + /// + private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) + { + List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); GroupMembershipData[] membershipArray; - if (remoteClient.AgentId != dataForAgentID) + if (requestingClient.AgentId != dataForAgentID) { Predicate showInProfile = delegate(GroupMembershipData membership) { @@ -1298,22 +1314,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; membershipArray = membershipData.FindAll(showInProfile).ToArray(); - } else { + } + else + { membershipArray = membershipData.ToArray(); } if (m_debugEnabled) { - m_log.InfoFormat("[GROUPS]: Sending group membership information for {0} to {1}", dataForAgentID, remoteClient.AgentId); + m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); foreach (GroupMembershipData membership in membershipArray) { m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); } } - SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); - remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); - + return membershipArray; } private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) -- cgit v1.1 From f00126dc2dfc9e23aa50227f02ee9adbe1efdfa6 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Tue, 29 Sep 2009 08:32:59 +0900 Subject: Add copyright header. Formatting cleanup. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 12 ++++++------ .../XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 6b30959..c7bb56a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -260,12 +260,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public void PostInitialise() { - if(m_pluginEnabled) + if (m_pluginEnabled) { - m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); - - // register the voice interface for this module, so the script engine can call us - m_scene.RegisterModuleInterface(this); + m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); + + // register the voice interface for this module, so the script engine can call us + m_scene.RegisterModuleInterface(this); } } @@ -811,7 +811,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice lock (m_ParcelAddress) { - if (m_ParcelAddress.ContainsKey( land.GlobalID.ToString() )) + if (m_ParcelAddress.ContainsKey(land.GlobalID.ToString())) { m_log.DebugFormat("[FreeSwitchVoice]: parcel id {0}: using sip address {1}", land.GlobalID, m_ParcelAddress[land.GlobalID.ToString()]); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 805c3d4..964d0bb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -871,7 +871,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - foreach( string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) { m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); } -- cgit v1.1 From ee205e7e812e170f670e690a4e0fa9caa652f226 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Thu, 1 Oct 2009 01:00:09 +0900 Subject: Formatting cleanup. --- .../Region/OptionalModules/Avatar/Chat/RegionState.cs | 2 +- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 4 ++-- .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 18 +++++++++--------- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 4 ++-- .../Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index c49d942..773507c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -351,7 +351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel); return; - } + } ScenePresence avatar = null; string fromName = msg.From; diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs index 9ba09ed..46ad30f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs @@ -97,8 +97,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice ", Context, Realm); } - return response; - } + return response; + } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index 5d90a8f..df6e0e7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -138,7 +138,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["str_response_string"] = ""; } } - return response; + return response; } private Hashtable HandleRegister(string Context, string Realm, Hashtable request) @@ -309,17 +309,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "\r\n", domain, Context); - return response; - } + return response; + } // private Hashtable HandleLoadNetworkLists(Hashtable request) // { // m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called"); -// +// // // TODO the password we return needs to match that sent in the request, this is hard coded for now // string domain = (string) request["domain"]; -// +// // Hashtable response = new Hashtable(); // response["content_type"] = "text/xml"; // response["keepalive"] = false; @@ -340,9 +340,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // "\r\n" + // "\r\n", // domain); -// -// -// return response; -// } +// +// +// return response; +// } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index febb491..cb76200 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -226,7 +226,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice m_log.DebugFormat("[VivoxVoice] plugin initialization failed: {0}", e.ToString()); return; } - } + } // Called to indicate that the module has been added to the region @@ -1144,7 +1144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // Otherwise prepare the request m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); - HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); HttpWebResponse rsp = null; // We are sending just parameters, no content diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d5cbfd4..9ce4e1a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -477,7 +477,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (string key in binBucketOSD.Keys) { m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); - } + } } // treat as if no attachment -- cgit v1.1 From 606e831ff5337fb5e94dcebf9d6852bd4c434d4b Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Thu, 1 Oct 2009 09:38:36 +0900 Subject: Formatting cleanup. --- .../OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs index df6e0e7..17cdf74 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs @@ -93,7 +93,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { response = HandleRegister(Context, Realm, request); } - else if (sipAuthMethod == "INVITE") + else if (sipAuthMethod == "INVITE") { response = HandleInvite(Context, Realm, request); } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 9ce4e1a..2e89a24 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1261,7 +1261,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Probably isn't nessesary to update every client in every scene. + // TODO: Probably isn't nessesary to update every client in every scene. // Need to examine client updates and do only what's nessesary. lock (m_sceneList) { -- cgit v1.1 From 387e9f7a7faeb412054383080afc3507a1522746 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 2 Oct 2009 18:31:08 -0700 Subject: * Creates Util.UTF8 and switches some references of Encoding.UTF8 to Util.UTF8 (not all references were switched since not all OpenSim libraries reference OpenSim.Framework) * Shrinks the largest in-memory object, the LLRAW.HeightmapLookupValue struct (only used for exporting to LLRAW terrain files), to the minimum possible size. This seems to have the odd side effect of cutting the size of the two double[256,256] terrain objects in half. Possibly an alignment optimization? --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 65c5274..f9dfc0d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -527,7 +527,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice if (method == "POST") { - byte[] contentreq = Encoding.UTF8.GetBytes(body); + byte[] contentreq = Util.UTF8.GetBytes(body); forwardreq.ContentLength = contentreq.Length; Stream reqStream = forwardreq.GetRequestStream(); reqStream.Write(contentreq, 0, contentreq.Length); @@ -535,7 +535,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse(); - Encoding encoding = Encoding.UTF8; + Encoding encoding = Util.UTF8; StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding); fwdresponsestr = fwdresponsestream.ReadToEnd(); fwdresponsecontenttype = fwdrsp.ContentType; -- cgit v1.1 From 544675d0f0969ce19ca41d3e70b0b0d5c853210a Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Mon, 5 Oct 2009 11:59:33 -0700 Subject: Ensure the specified imSessionID exists in the DroppedSession collection before attempting to access it. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 631d801..00fe5df 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -425,7 +425,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) { - if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); -- cgit v1.1 From d4a6d9191a3ba4f19773213617843ddbb489c90c Mon Sep 17 00:00:00 2001 From: Michael Cortez Date: Mon, 5 Oct 2009 12:09:45 -0700 Subject: Make sure that keys exist in arrays before trying to access them. --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 2e89a24..b209199 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -148,9 +148,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; foreach (UUID key in CurrentKeys) { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + if (m_clientRequestIDInfo.ContainsKey(key)) { - m_clientRequestIDInfo.Remove(key); + if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + { + m_clientRequestIDInfo.Remove(key); + } } } } @@ -476,7 +479,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (string key in binBucketOSD.Keys) { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + if (binBucketOSD.ContainsKey(key)) + { + m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); + } } } -- cgit v1.1 From 2519f071f2c592aeea0414c8b2871e5df623271c Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 02:50:59 -0700 Subject: Fixing a few compile errors in the previous commit --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index 9273fb5..cd401a6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -360,7 +360,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_listener.Name = "IRCConnectorListenerThread"; m_listener.IsBackground = true; m_listener.Start(); - ThreadTracker.Add(m_listener); // This is the message order recommended by RFC 2812 if (m_password != null) -- cgit v1.1 From 8dd15fd5a590e059038d6438a305264cad3918b7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 21 Oct 2009 18:45:37 +0100 Subject: Patch by mcortez: Remove lock from scene presence updating in groups module --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b209199..b2544fa 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1244,18 +1244,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); ScenePresence presence = null; - lock (m_sceneList) + + foreach (Scene scene in m_sceneList) { - foreach (Scene scene in m_sceneList) + presence = scene.GetScenePresence(AgentID); + if (presence != null) { - presence = scene.GetScenePresence(AgentID); - if (presence != null) - { - presence.Grouptitle = Title; + presence.Grouptitle = Title; - // FixMe: Ter suggests a "Schedule" method that I can't find. - presence.SendFullUpdateToAllClients(); - } + // FixMe: Ter suggests a "Schedule" method that I can't find. + presence.SendFullUpdateToAllClients(); } } } -- cgit v1.1 From 2c34619aea074446e53dde80d397973075914bac Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 23 Oct 2009 14:22:21 -0700 Subject: * Changed various modules to not initialize timers unless the module is initialized. Ideally, the timers would not initialize unless the module was actually enabled, but Melanie's work on configuring module loading from a config file should make that unnecessary * Wrapped the Bitmap class used to generate the world map tile in a using statement to dispose of it after the JPEG2000 data is created --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b2544fa..f24869b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -94,7 +94,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } private Dictionary m_clientRequestIDInfo = new Dictionary(); private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes - private Timer m_clientRequestIDFlushTimer = new Timer(); + private Timer m_clientRequestIDFlushTimer; // Configuration settings @@ -133,6 +133,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); + m_clientRequestIDFlushTimer = new Timer(); m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; m_clientRequestIDFlushTimer.AutoReset = true; -- cgit v1.1 From de054bc5834eafab2add8ceb37787ad64f962ae8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 17 Nov 2009 15:21:29 +0000 Subject: minor: remove mono compiler warning due to unreachable code in GroupsModule --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index f24869b..8d32e66 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1179,8 +1179,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return m_clientRequestIDInfo[client.AgentId].RequestID; } - - return new GroupRequestID(); +// Unreachable code! +// return new GroupRequestID(); } /// -- cgit v1.1 From 1f71523a5ad4e21986d20a3012638991ea0d9e9c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Nov 2009 14:47:49 +0000 Subject: minor: make irc bridge logging less verbose if it isn't actually enabled --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 70e80bc..e664b44 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -69,13 +69,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_config = config.Configs["IRC"]; if (m_config == null) { - m_log.InfoFormat("[IRC-Bridge] module not configured"); +// m_log.InfoFormat("[IRC-Bridge] module not configured"); return; } if (!m_config.GetBoolean("enabled", false)) { - m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); +// m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); return; } @@ -85,6 +85,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } m_pluginEnabled = true; + m_log.InfoFormat("[IRC-Bridge]: Module enabled"); } public void AddRegion(Scene scene) @@ -143,7 +144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public static XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request, IPEndPoint remoteClient) { - m_log.Info("[IRC-Bridge]: XML RPC Admin Entry"); + m_log.Debug("[IRC-Bridge]: XML RPC Admin Entry"); XmlRpcResponse response = new XmlRpcResponse(); Hashtable responseData = new Hashtable(); @@ -188,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } catch (Exception e) { - m_log.InfoFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); + m_log.ErrorFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); responseData["success"] = "false"; responseData["error"] = e.Message; -- cgit v1.1 From b63405c1a796b44b58081857d01f726372467628 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 8 Jan 2010 10:43:34 -0800 Subject: Inching ahead... This compiles, but very likely does not run. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 41 +++++++++++----------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8d32e66..c8a10b5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -43,6 +43,8 @@ using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + using Caps = OpenSim.Framework.Capabilities.Caps; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; @@ -507,10 +509,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) { - UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID); - if (targetUserProfile != null) + UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); + if (targetUser != null) { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices); + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); } else { @@ -990,9 +992,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); - - if ((groupInfo == null) || (userProfile == null)) + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, ejecteeID); + if ((groupInfo == null) || (account == null)) { return; } @@ -1032,9 +1033,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.toAgentID = remoteClient.AgentId.Guid; msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; - if (userProfile != null) + if (account != null) { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, account.FirstName + " " + account.LastName); } else { @@ -1147,8 +1148,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups info.RequestID.AgentID = client.AgentId; info.RequestID.SessionID = client.SessionId; - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); - if (userProfile == null) + //UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); + if (account == null) { // This should be impossible. If I've been passed a reference to a client // that client should be registered with the UserService. So something @@ -1160,16 +1162,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; } - else if (userProfile is ForeignUserProfileData) - { - // They aren't from around here - ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; - info.RequestID.UserServiceURL = fupd.UserServerURI; - } else { + string domain = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + if (account.ServiceURLs["HomeURI"] != null) + domain = account.ServiceURLs["HomeURI"].ToString(); // They're a local user, use this: - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + info.RequestID.UserServiceURL = domain; } m_clientRequestIDInfo.Add(client.AgentId, info); @@ -1342,12 +1341,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); string firstname, lastname; - if (userProfile != null) + if (account != null) { - firstname = userProfile.FirstName; - lastname = userProfile.SurName; + firstname = account.FirstName; + lastname = account.LastName; } else { -- cgit v1.1 From 3c90d834eac382af5edf091e83aea1ffcce91792 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 10 Jan 2010 22:41:42 +0000 Subject: Remove all references to master avatar, replacing with estate owner where appropriate. This changes the behavior of the REST plugins and RemoteAdmin's region creation process. --- OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs | 4 ---- 1 file changed, 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index 773507c..53b103e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -57,8 +57,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal string Host = String.Empty; internal string LocX = String.Empty; internal string LocY = String.Empty; - internal string MA1 = String.Empty; - internal string MA2 = String.Empty; internal string IDK = String.Empty; // System values - used only be the IRC classes themselves @@ -85,8 +83,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat Host = scene.RegionInfo.ExternalHostName; LocX = Convert.ToString(scene.RegionInfo.RegionLocX); LocY = Convert.ToString(scene.RegionInfo.RegionLocY); - MA1 = scene.RegionInfo.MasterAvatarFirstName; - MA2 = scene.RegionInfo.MasterAvatarLastName; IDK = Convert.ToString(_idk_++); // OpenChannel conditionally establishes a connection to the -- cgit v1.1 From b5f1857d34a38e4217ec68e413ba9473f1af517a Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 10 Jan 2010 22:55:43 +0000 Subject: Remove a little bit more if master avatar --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 3c5e8c9..e11cbd7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -477,12 +477,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat case "%host" : result = result.Replace(vvar, rs.Host); break; - case "%master1" : - result = result.Replace(vvar, rs.MA1); - break; - case "%master2" : - result = result.Replace(vvar, rs.MA2); - break; case "%locx" : result = result.Replace(vvar, rs.LocX); break; -- cgit v1.1 From 751e70af788bf27fa0401c25d899f73186c8eafa Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 10 Jan 2010 21:37:36 -0800 Subject: NetworkServersInfo removed from CommsManager. --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index c8a10b5..68e6497 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1159,12 +1159,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); // Default to local user service and hope for the best? - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + // REFACTORING PROBLEM + //info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; } else { - string domain = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + string domain = string.Empty; //m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; if (account.ServiceURLs["HomeURI"] != null) domain = account.ServiceURLs["HomeURI"].ToString(); // They're a local user, use this: -- cgit v1.1 From c5ea783526611a968400a1936e4c6764ee1c7013 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 11 Jan 2010 07:51:33 -0800 Subject: OpenSim/Framework/Communications/Cache deleted. LibraryRootFolder deleted. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 2 +- .../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index b04b076..51341de 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -41,7 +41,7 @@ using log4net; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; -using OpenSim.Framework.Communications.Cache; + using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index cb76200..34d0e24 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -39,7 +39,7 @@ using log4net; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; -using OpenSim.Framework.Communications.Cache; + using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; -- cgit v1.1 From d86c0d406a3fcabae2fe2c70f76507796152eb74 Mon Sep 17 00:00:00 2001 From: dr scofield (aka dirk husemann) Date: Mon, 11 Jan 2010 17:15:49 +0100 Subject: more specific config error logging --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 3c5e8c9..b3fa07f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -220,8 +220,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Fail if fundamental information is still missing - if (cs.Server == null || cs.IrcChannel == null || cs.BaseNickname == null || cs.User == null) - throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}", cs.idn, rs.Region)); + if (cs.Server == null) + throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: server missing", cs.idn, rs.Region)); + else if (cs.IrcChannel == null) + throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: channel missing", cs.idn, rs.Region)); + else if (cs.BaseNickname == null) + throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: nick missing", cs.idn, rs.Region)); + else if (cs.User == null) + throw new Exception(String.Format("[IRC-Channel-{0}] Invalid configuration for region {1}: user missing", cs.idn, rs.Region)); m_log.InfoFormat("[IRC-Channel-{0}] Configuration for Region {1} is valid", cs.idn, rs.Region); m_log.InfoFormat("[IRC-Channel-{0}] Server = {1}", cs.idn, cs.Server); -- cgit v1.1 From ec3c31e61e5e540f822891110df9bc978655bbaf Mon Sep 17 00:00:00 2001 From: Revolution Date: Fri, 22 Jan 2010 18:09:33 -0600 Subject: Updates all IRegionModules to the new style region modules. Signed-off-by: Melanie --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 72 ++++++++++++++++------ 1 file changed, 52 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index b04b076..23ae307 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -38,6 +38,7 @@ using System.Collections.Generic; using System.Reflection; using OpenMetaverse; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; @@ -53,7 +54,8 @@ using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { - public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class FreeSwitchVoiceModule : ISharedRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -108,9 +110,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private IConfig m_config; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - m_scene = scene; m_config = config.Configs["FreeSwitchVoice"]; if (null == m_config) @@ -224,17 +225,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return; } } + } - if (m_pluginEnabled) + public void AddRegion(Scene scene) + { + m_scene = scene; + if (m_pluginEnabled) { // we need to capture scene in an anonymous method // here as we need it later in the callbacks scene.EventManager.OnRegisterCaps += delegate(UUID agentID, Caps caps) - { - OnRegisterCaps(scene, agentID, caps); - }; - - + { + OnRegisterCaps(scene, agentID, caps); + }; + + try { @@ -254,33 +259,60 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); } } - + } - } - - public void PostInitialise() - { if (m_pluginEnabled) { m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); - + // register the voice interface for this module, so the script engine can call us m_scene.RegisterModuleInterface(this); } } - public void Close() + public void RegionLoaded(Scene scene) { } - public string Name + public void RemoveRegion(Scene scene) + { + if (UseProxy) + { + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/", m_freeSwitchAPIPrefix)); + } + else + { + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix)); + + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix)); + + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix)); + + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix)); + } + scene.EventManager.OnRegisterCaps -= delegate(UUID agentID, Caps caps) + { + OnRegisterCaps(scene, agentID, caps); + }; + scene.UnregisterModuleInterface(this); + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void PostInitialise() { - get { return "FreeSwitchVoiceModule"; } } - public bool IsSharedModule + public void Close() { - get { return true; } + } + + public string Name + { + get { return "FreeSwitchVoiceModule"; } } // -- cgit v1.1 From a87a247f0548d39a8c39b1d28123d7da8db44598 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Jan 2010 07:20:13 +0000 Subject: Revert "Updates all IRegionModules to the new style region modules." This reverts commit ec3c31e61e5e540f822891110df9bc978655bbaf. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 72 ++++++---------------- 1 file changed, 20 insertions(+), 52 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 23ae307..b04b076 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -38,7 +38,6 @@ using System.Collections.Generic; using System.Reflection; using OpenMetaverse; using log4net; -using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; @@ -54,8 +53,7 @@ using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class FreeSwitchVoiceModule : ISharedRegionModule, IVoiceModule + public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -110,8 +108,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private IConfig m_config; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { + m_scene = scene; m_config = config.Configs["FreeSwitchVoice"]; if (null == m_config) @@ -225,21 +224,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return; } } - } - public void AddRegion(Scene scene) - { - m_scene = scene; - if (m_pluginEnabled) + if (m_pluginEnabled) { // we need to capture scene in an anonymous method // here as we need it later in the callbacks scene.EventManager.OnRegisterCaps += delegate(UUID agentID, Caps caps) - { - OnRegisterCaps(scene, agentID, caps); - }; - - + { + OnRegisterCaps(scene, agentID, caps); + }; + + try { @@ -259,53 +254,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); } } - + } + } + + public void PostInitialise() + { if (m_pluginEnabled) { m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); - + // register the voice interface for this module, so the script engine can call us m_scene.RegisterModuleInterface(this); } } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (UseProxy) - { - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/", m_freeSwitchAPIPrefix)); - } - else - { - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix)); - - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix)); - - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix)); - - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix)); - } - scene.EventManager.OnRegisterCaps -= delegate(UUID agentID, Caps caps) - { - OnRegisterCaps(scene, agentID, caps); - }; - scene.UnregisterModuleInterface(this); - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void PostInitialise() - { - } - public void Close() { } @@ -314,6 +277,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { get { return "FreeSwitchVoiceModule"; } } + + public bool IsSharedModule + { + get { return true; } + } // // implementation of IVoiceModule, called by osSetParcelSIPAddress script function -- cgit v1.1 From d1f2fae3481ea502630eaf2c4d1cdb776b165c05 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Sat, 20 Feb 2010 11:01:50 +0900 Subject: Formatting cleanup. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 123 +++++++++------------ 1 file changed, 54 insertions(+), 69 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index b04b076..35819a6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -50,7 +50,6 @@ using OpenSim.Region.Framework.Scenes; using Caps = OpenSim.Framework.Capabilities.Caps; using System.Text.RegularExpressions; - namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule @@ -76,7 +75,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // SLVoice client will do a GET on this prefix private static string m_freeSwitchAPIPrefix; - // We need to return some information to SLVoice + // We need to return some information to SLVoice // figured those out via curl // http://vd1.vivox.com/api2/viv_get_prelogin.php // @@ -102,9 +101,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private readonly Dictionary m_UUIDName = new Dictionary(); private Dictionary m_ParcelAddress = new Dictionary(); - + private Scene m_scene; - + private IConfig m_config; @@ -136,9 +135,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty); m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty); m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty); - + // XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server) - + string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty); int servicePort = m_config.GetInt("freeswitch_service_port", 80); IPAddress serviceIPAddress = IPAddress.Parse(serviceIP); @@ -156,7 +155,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); m_freeSwitchContext = m_config.GetString("freeswitch_context", "default"); - + if (String.IsNullOrEmpty(m_freeSwitchServerUser) || String.IsNullOrEmpty(m_freeSwitchServerPass) || String.IsNullOrEmpty(m_freeSwitchRealm) || @@ -182,9 +181,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); - + // RestStreamHandler h = new - // RestStreamHandler("GET", + // RestStreamHandler("GET", // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); // MainServer.Instance.AddStreamHandler(h); @@ -202,13 +201,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceBuddyHTTPHandler); } - - - - m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); - + m_FreeSwitchDirectory = new FreeSwitchDirectory(); m_FreeSwitchDialplan = new FreeSwitchDialplan(); @@ -225,7 +220,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } } - if (m_pluginEnabled) + if (m_pluginEnabled) { // we need to capture scene in an anonymous method // here as we need it later in the callbacks @@ -233,8 +228,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { OnRegisterCaps(scene, agentID, caps); }; - - try { @@ -254,16 +247,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); } } - } } - + public void PostInitialise() { if (m_pluginEnabled) { m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); - + // register the voice interface for this module, so the script engine can call us m_scene.RegisterModuleInterface(this); } @@ -282,15 +274,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { get { return true; } } - + // // implementation of IVoiceModule, called by osSetParcelSIPAddress script function // public void setLandSIPAddress(string SIPAddress,UUID GlobalID) { - m_log.DebugFormat("[FreeSwitchVoice]: setLandSIPAddress parcel id {0}: setting sip address {1}", + m_log.DebugFormat("[FreeSwitchVoice]: setLandSIPAddress parcel id {0}: setting sip address {1}", GlobalID, SIPAddress); - + lock (m_ParcelAddress) { if (m_ParcelAddress.ContainsKey(GlobalID.ToString())) @@ -303,18 +295,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } } } - + // // OnRegisterCaps is invoked via the scene.EventManager // everytime OpenSim hands out capabilities to a client // (login, region crossing). We contribute two capabilities to // the set of capabilities handed back to the client: // ProvisionVoiceAccountRequest and ParcelVoiceInfoRequest. - // + // // ProvisionVoiceAccountRequest allows the client to obtain // the voice account credentials for the avatar it is // controlling (e.g., user name, password, etc). - // + // // ParcelVoiceInfoRequest is invoked whenever the client // changes from one region or parcel to another. // @@ -371,7 +363,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { System.Threading.Thread.Sleep(2000); avatar = scene.GetScenePresence(agentID); - + if (avatar == null) return "undef"; } @@ -407,8 +399,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); LLSDVoiceAccountResponse voiceAccountResponse = new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, - String.Format("http://{0}:{1}{2}/", m_openSimWellKnownHTTPAddress, - m_freeSwitchServicePort, m_freeSwitchAPIPrefix)); + String.Format("http://{0}:{1}{2}/", m_openSimWellKnownHTTPAddress, + m_freeSwitchServicePort, m_freeSwitchAPIPrefix)); string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); @@ -442,7 +434,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string avatarName = avatar.Name; // - check whether we have a region channel in our cache - // - if not: + // - if not: // create it and cache it // - send it to the client // - send channel_uri: as "sip:regionID@m_sipDomain" @@ -451,12 +443,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice LLSDParcelVoiceInfoResponse parcelVoiceInfo; string channelUri; - if (null == scene.LandChannel) + if (null == scene.LandChannel) throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available", scene.RegionInfo.RegionName, avatarName)); - - // get channel_uri: check first whether estate // settings allow voice, then whether parcel allows // voice, if all do retrieve or obtain the parcel @@ -493,22 +483,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); - m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", + m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); return r; } catch (Exception e) { - m_log.ErrorFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later", + m_log.ErrorFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later", scene.RegionInfo.RegionName, avatarName, e.Message); - m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed", + m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed", scene.RegionInfo.RegionName, avatarName, e.ToString()); return "undef"; } } - /// /// Callback for a client request for ChatSessionRequest /// @@ -550,7 +539,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string fwdresponsestr = ""; int fwdresponsecode = 200; string fwdresponsecontenttype = "text/xml"; - HttpWebRequest forwardreq = (HttpWebRequest)WebRequest.Create(forwardaddress); forwardreq.Method = method; @@ -577,7 +565,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content_type"] = fwdresponsecontenttype; response["str_response_string"] = fwdresponsestr; response["int_response_code"] = fwdresponsecode; - + return response; } @@ -585,11 +573,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) { m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler called"); - + Hashtable response = new Hashtable(); response["content_type"] = "text/xml"; response["keepalive"] = false; - + response["str_response_string"] = String.Format( "\r\n" + "\r\n"+ @@ -607,9 +595,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "", m_freeSwitchRealm, m_freeSwitchSIPProxy, m_freeSwitchAttemptUseSTUN, m_freeSwitchEchoServer, m_freeSwitchEchoPort, - m_freeSwitchDefaultWellKnownIP, m_freeSwitchDefaultTimeout, + m_freeSwitchDefaultWellKnownIP, m_freeSwitchDefaultTimeout, m_freeSwitchUrlResetPassword, ""); - + response["int_response_code"] = 200; m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler return {0}",response["str_response_string"]); @@ -624,7 +612,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["content-type"] = "text/xml"; Hashtable requestBody = parseRequestBody((string)request["body"]); - + if (!requestBody.ContainsKey("auth_token")) return response; @@ -632,7 +620,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice //string[] auth_tokenvals = auth_token.Split(':'); //string username = auth_tokenvals[0]; int strcount = 0; - + string[] ids = new string[strcount]; int iter = -1; @@ -648,7 +636,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } StringBuilder resp = new StringBuilder(); resp.Append(""); - + resp.Append(string.Format(@" OK lib_session @@ -678,7 +666,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice ", ids[i],i,m_freeSwitchRealm,dt)); } - + resp.Append(""); response["str_response_string"] = resp.ToString(); @@ -694,7 +682,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string requestbody = (string)request["body"]; string uri = (string)request["uri"]; string contenttype = (string)request["content-type"]; - + Hashtable requestBody = parseRequestBody((string)request["body"]); //string pwd = (string) requestBody["pwd"]; @@ -712,7 +700,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice pos++; if (s == userid) break; - } } } @@ -735,7 +722,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice ", userid, pos, avatarName); - + response["int_response_code"] = 200; return response; /* @@ -752,13 +739,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request) { m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]); - + Hashtable response = new Hashtable(); response["str_response_string"] = string.Empty; // all the params come as NVPs in the request body Hashtable requestBody = parseRequestBody((string) request["body"]); - // is this a dialplan or directory request + // is this a dialplan or directory request string section = (string) requestBody["section"]; if (section == "directory") @@ -767,40 +754,39 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); else m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); - - // XXX: re-generate dialplan: + + // XXX: re-generate dialplan: // - conf == region UUID // - conf number = region port // -> TODO Initialise(): keep track of regions via events - // re-generate accounts for all avatars + // re-generate accounts for all avatars // -> TODO Initialise(): keep track of avatars via events Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",normalizeEndLines.Replace(((string)response["str_response_string"]), "")); return response; } - + public Hashtable parseRequestBody(string body) { Hashtable bodyParams = new Hashtable(); // split string string [] nvps = body.Split(new Char [] {'&'}); - foreach (string s in nvps) { - + foreach (string s in nvps) + { if (s.Trim() != "") { string [] nvp = s.Split(new Char [] {'='}); bodyParams.Add(HttpUtility.UrlDecode(nvp[0]), HttpUtility.UrlDecode(nvp[1])); } } - + return bodyParams; } private string ChannelUri(Scene scene, LandData land) { - string channelUri = null; string landUUID; @@ -808,12 +794,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same // as the directory ID. Otherwise, it reflects the parcel's ID. - + lock (m_ParcelAddress) { if (m_ParcelAddress.ContainsKey(land.GlobalID.ToString())) { - m_log.DebugFormat("[FreeSwitchVoice]: parcel id {0}: using sip address {1}", + m_log.DebugFormat("[FreeSwitchVoice]: parcel id {0}: using sip address {1}", land.GlobalID, m_ParcelAddress[land.GlobalID.ToString()]); return m_ParcelAddress[land.GlobalID.ToString()]; } @@ -823,22 +809,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); landUUID = land.GlobalID.ToString(); - m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", + m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", landName, land.LocalID, landUUID); } else { landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, scene.RegionInfo.RegionName); landUUID = scene.RegionInfo.RegionID.ToString(); - m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", + m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", landName, land.LocalID, landUUID); } System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); - + // slvoice handles the sip address differently if it begins with confctl, hiding it from the user in the friends list. however it also disables // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator. channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); - + lock (m_ParcelAddress) { if (!m_ParcelAddress.ContainsKey(land.GlobalID.ToString())) @@ -849,14 +835,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return channelUri; } - + private static bool CustomCertificateValidation(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { - return true; - } } + public class MonoCert : ICertificatePolicy { #region ICertificatePolicy Members -- cgit v1.1 From 859bc717a4fe4cd5810ad9889cfb9b1e7f5c2046 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Fri, 19 Mar 2010 05:51:16 -0700 Subject: Cleaned up access to scenepresences in scenegraph. GetScenePresences and GetAvatars have been removed to consolidate locking and iteration within SceneGraph. All callers which used these to then iterate over presences have been refactored to instead pass their delegates to Scene.ForEachScenePresence(Action). --- .../Avatar/Concierge/ConciergeModule.cs | 39 +++++++++------------- 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index c864993..b85bac6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -318,9 +318,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { Scene scene = client.Scene as Scene; m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, scene.RegionInfo.RegionName); - List avs = scene.GetAvatars(); - AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, client.Name, scene.RegionInfo.RegionName, avs.Count)); - UpdateBroker(scene, avs); + AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, client.Name, scene.RegionInfo.RegionName, scene.GetRootAgentCount())); + UpdateBroker(scene); } } @@ -331,11 +330,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { Scene scene = agent.Scene; m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, scene.RegionInfo.RegionName); - List avs = scene.GetAvatars(); WelcomeAvatar(agent, scene); AnnounceToAgentsRegion(scene, String.Format(m_announceEntering, agent.Name, - scene.RegionInfo.RegionName, avs.Count)); - UpdateBroker(scene, avs); + scene.RegionInfo.RegionName, scene.GetRootAgentCount())); + UpdateBroker(scene); } } @@ -346,10 +344,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { Scene scene = agent.Scene; m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, scene.RegionInfo.RegionName); - List avs = scene.GetAvatars(); AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, agent.Name, - scene.RegionInfo.RegionName, avs.Count)); - UpdateBroker(scene, avs); + scene.RegionInfo.RegionName, scene.GetRootAgentCount())); + UpdateBroker(scene); } } @@ -368,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge } } - protected void UpdateBroker(IScene scene, List avatars) + protected void UpdateBroker(Scene scene) { if (String.IsNullOrEmpty(m_brokerURI)) return; @@ -377,24 +374,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge // create XML sniplet StringBuilder list = new StringBuilder(); - if (0 == avatars.Count) - { - list.Append(String.Format("", - scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, + list.Append(String.Format("\n", + scene.GetRootAgentCount(), scene.RegionInfo.RegionName, + scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); - } - else + scene.ForEachScenePresence(delegate(ScenePresence sp) { - list.Append(String.Format("\n", - avatars.Count, scene.RegionInfo.RegionName, - scene.RegionInfo.RegionID, - DateTime.UtcNow.ToString("s"))); - foreach (ScenePresence av in avatars) + if (!sp.IsChildAgent) { - list.Append(String.Format(" \n", av.Name, av.UUID)); + list.Append(String.Format(" \n", sp.Name, sp.UUID)); + list.Append(""); } - list.Append(""); - } + }); string payload = list.ToString(); // post via REST to broker -- cgit v1.1 From 62e0b53ca4697a852ee1e36e86da6a32e93bd55e Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Fri, 19 Mar 2010 05:58:34 -0700 Subject: Renamed TryGetAvatar to TryGetScenePresence on SceneManager, SceneBase, Scene and SceneGraph. This was the only change in this patch to keep it isolated from other recent changes to the same set of files. --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index b85bac6..2fcc477 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -520,7 +520,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge // protected void AnnounceToAgentsRegion(Scene scene, string msg) // { // ScenePresence agent = null; - // if ((client.Scene is Scene) && (client.Scene as Scene).TryGetAvatar(client.AgentId, out agent)) + // if ((client.Scene is Scene) && (client.Scene as Scene).TryGetScenePresence(client.AgentId, out agent)) // AnnounceToAgentsRegion(agent, msg); // else // m_log.DebugFormat("[Concierge]: could not find an agent for client {0}", client.Name); -- cgit v1.1 From f0703cad2ce6894ef2ccbf6a9c3cc93fe3c960b6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 25 Mar 2010 22:47:52 +0000 Subject: add get group by name method to IGroupsModule --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 36 ++++++++++++++++------ .../XmlRpcGroupsServicesConnectorModule.cs | 1 - 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 68e6497..93c2d09 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -328,17 +328,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } */ - void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) { if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", + System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); - } - + remoteClient.SendDirGroupsReply( + queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); + } } private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) @@ -652,7 +654,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); return data; - } public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) @@ -662,8 +663,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); return data; - - } public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) @@ -746,7 +745,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Zero; } // is there is a money module present ? - IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); + IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); if (money != null) { // do the transaction, that is if the agent has got sufficient funds @@ -766,6 +765,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return groupID; } + public DirGroupsReplyData? GetGroup(string name) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List groups = m_groupData.FindGroups(null, name); + + DirGroupsReplyData? foundGroup = null; + + foreach (DirGroupsReplyData group in groups) + { + // We must have an exact match - I believe FindGroups will return partial matches + if (group.groupName == name) + foundGroup = group; + } + + return foundGroup; + } + public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 964d0bb..2115376 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -470,7 +470,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); } - public List FindGroups(GroupRequestID requestID, string search) { Hashtable param = new Hashtable(); -- cgit v1.1 From 857918d3b032df27e7ee1fe26cebc7421ec4ee0e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 25 Mar 2010 23:53:05 +0000 Subject: minor: some debugging information and spacing changes to group module --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 5 ++++- .../Avatar/XmlRpcGroups/IGroupsServicesConnector.cs | 1 - .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 8 +++----- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 93c2d09..8ea4b93 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -711,7 +711,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called with groupID={1}, agentID={2}", + System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); return m_groupData.GetAgentGroupMembership(null, agentID, groupID); } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 9e0fa2d..621ab28 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -55,7 +55,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 2115376..af1018f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -47,9 +47,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | @@ -530,7 +528,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) { Hashtable param = new Hashtable(); @@ -777,7 +774,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) { - GroupRecord group = new GroupRecord(); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); group.GroupName = groupProfile["Name"].ToString(); @@ -796,6 +792,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) { GroupMembershipData data = new GroupMembershipData(); @@ -828,6 +825,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.MembershipFee = int.Parse((string)respData["MembershipFee"]); data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); data.ShowInList = ((string)respData["ShowInList"] == "1"); + return data; } -- cgit v1.1 From 87fe96ae2c48216d006a02ef22392f0838fba17f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Mar 2010 00:10:29 +0000 Subject: replace recent IModule.GetGroup() with better GetGroupRecord(string name) --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 46 ++++++++++++---------- .../XmlRpcGroupsServicesConnectorModule.cs | 3 -- 2 files changed, 26 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8ea4b93..b011295 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -365,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) + private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -595,6 +595,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return m_groupData.GetGroupRecord(null, GroupID, null); } + public GroupRecord GetGroupRecord(string name) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // XXX: Two call implementation. This could be done in a single call if the server itself were to + // implement the code below. + + List groups = m_groupData.FindGroups(null, name); + + DirGroupsReplyData? foundGroup = null; + + foreach (DirGroupsReplyData group in groups) + { + // We must have an exact match - I believe FindGroups will return partial matches + if (group.groupName == name) + foundGroup = group; + } + + if (null == foundGroup) + return null; + + return GetGroupRecord(((DirGroupsReplyData)foundGroup).groupID); + } + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -768,25 +793,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return groupID; } - public DirGroupsReplyData? GetGroup(string name) - { - if (m_debugEnabled) - m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List groups = m_groupData.FindGroups(null, name); - - DirGroupsReplyData? foundGroup = null; - - foreach (DirGroupsReplyData group in groups) - { - // We must have an exact match - I believe FindGroups will return partial matches - if (group.groupName == name) - foundGroup = group; - } - - return foundGroup; - } - public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index af1018f..24ae4f7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -352,11 +352,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; - } - - public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); -- cgit v1.1 From 05123c6bd5442a7711660fcfb2eedd12c0b82efa Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 26 Mar 2010 12:39:22 -0700 Subject: * Fixed a dictionary value retrieval in GroupsModule --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b011295..eb630de 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1193,8 +1193,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups else { string domain = string.Empty; //m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - if (account.ServiceURLs["HomeURI"] != null) - domain = account.ServiceURLs["HomeURI"].ToString(); + object homeUriObj; + if (account.ServiceURLs.TryGetValue("HomeURI", out homeUriObj) && homeUriObj != null) + domain = homeUriObj.ToString(); // They're a local user, use this: info.RequestID.UserServiceURL = domain; } -- cgit v1.1 From e7e56e0143e8afce8a7aaa44cfe848b2017bd5e4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 29 Mar 2010 19:50:24 +0100 Subject: Remove a redundant method body --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index eb630de..6282272 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -597,27 +597,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(string name) { - if (m_debugEnabled) - m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // XXX: Two call implementation. This could be done in a single call if the server itself were to - // implement the code below. - - List groups = m_groupData.FindGroups(null, name); - - DirGroupsReplyData? foundGroup = null; - - foreach (DirGroupsReplyData group in groups) - { - // We must have an exact match - I believe FindGroups will return partial matches - if (group.groupName == name) - foundGroup = group; - } - - if (null == foundGroup) - return null; - - return GetGroupRecord(((DirGroupsReplyData)foundGroup).groupID); + return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); } public void ActivateGroup(IClientAPI remoteClient, UUID groupID) -- cgit v1.1 From 24fc4703d0b9885102bc59296eb334e7b6d89e0f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 29 Mar 2010 22:02:02 +0100 Subject: fix build break. First argument of GetGroupRecord is not a uuid --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6282272..61c51e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -597,7 +597,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(string name) { - return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); + return m_groupData.GetGroupRecord(null, UUID.Zero, name); } public void ActivateGroup(IClientAPI remoteClient, UUID groupID) -- cgit v1.1 From c33b1de9dfc238ca38a0f145160de2648189dd16 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Apr 2010 22:37:20 +0100 Subject: expose methods that allow region modules to send messages to groups --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 144 ++++++++++++--------- 1 file changed, 81 insertions(+), 63 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 00fe5df..e0840b1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -28,29 +28,23 @@ using System; using System.Collections.Generic; using System.Reflection; - - using log4net; using Mono.Addins; using Nini.Config; - using OpenMetaverse; using OpenMetaverse.StructuredData; - using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; - using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GroupsMessagingModule : ISharedRegionModule + public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_sceneList = new List(); @@ -108,8 +102,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - // NoOp + if (!m_groupMessagingEnabled) + return; + + scene.RegisterModuleInterface(this); } + public void RegionLoaded(Scene scene) { if (!m_groupMessagingEnabled) @@ -197,6 +195,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + public bool StartGroupChatSession(UUID agentID, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + + if (groupInfo != null) + return StartGroupChatSession(agentID.Guid, groupInfo); + else + return false; + } + + protected bool StartGroupChatSession(Guid agentID, GroupRecord groupInfo) + { + AddAgentToGroupSession(agentID, groupInfo.GroupID.Guid); + + return true; + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) + { + if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + { + // Don't deliver messages to people who have dropped this session + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; + } + + // Copy Message + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = im.imSessionID; + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.offline = im.offline; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = im.binaryBucket; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + + // Updat Pertinate fields to make it a "group message" + msg.fromAgentID = groupID.Guid; + msg.fromGroup = true; + + msg.toAgentID = member.AgentID.Guid; + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg); + } + } + } + #region SimGridEventHandlers private void OnNewClient(IClientAPI client) @@ -370,7 +437,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_agentsDroppedSession.Add(sessionID, new List()); } } - + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -384,13 +451,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { UUID groupID = new UUID(im.toAgentID); - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); - - AddAgentToGroupSession(im.fromAgentID, im.imSessionID); + { + StartGroupChatSession(im.fromAgentID, groupInfo); ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); @@ -411,7 +476,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { UUID groupID = new UUID(im.toAgentID); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); SendMessageToGroup(im, groupID); } @@ -419,54 +485,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - private void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) - { - if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) - { - // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); - continue; - } - - // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = im.binaryBucket; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - - // Updat Pertinate fields to make it a "group message" - msg.fromAgentID = groupID.Guid; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; - - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) - { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - else - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); - } - } - } - void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From 938905df1e04ca5ff2f09bb29b955ba7386daea4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 1 Apr 2010 22:45:01 +0100 Subject: oops, add file missing from last commit refactor out redundant method from GroupsMessagingModule --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index e0840b1..533815f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -203,16 +203,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); if (groupInfo != null) - return StartGroupChatSession(agentID.Guid, groupInfo); + { + AddAgentToGroupSession(agentID.Guid, groupID.Guid); + return true; + } else + { return false; - } - - protected bool StartGroupChatSession(Guid agentID, GroupRecord groupInfo) - { - AddAgentToGroupSession(agentID, groupInfo.GroupID.Guid); - - return true; + } } public void SendMessageToGroup(GridInstantMessage im, UUID groupID) @@ -455,7 +453,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (groupInfo != null) { - StartGroupChatSession(im.fromAgentID, groupInfo); + AddAgentToGroupSession(im.fromAgentID, groupInfo.GroupID.Guid); ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); -- cgit v1.1 From 4b98d0db92ed4cac695091426b6483b6366f090e Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 2 Apr 2010 14:53:10 +0100 Subject: Adding the groups update (Mantis #4646) Thanks, mcortez. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 301 ++--- .../XmlRpcGroups/IGroupsServicesConnector.cs | 61 +- .../SimianGroupsServicesConnectorModule.cs | 1278 ++++++++++++++++++++ .../XmlRpcGroupsServicesConnectorModule.cs | 197 +-- 4 files changed, 1543 insertions(+), 294 deletions(-) create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 61c51e0..6b942cb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -89,16 +89,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupsServicesConnector m_groupData = null; - class GroupRequestIDInfo - { - public GroupRequestID RequestID = new GroupRequestID(); - public DateTime LastUsedTMStamp = DateTime.MinValue; - } - private Dictionary m_clientRequestIDInfo = new Dictionary(); - private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes - private Timer m_clientRequestIDFlushTimer; - - // Configuration settings private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; @@ -135,30 +125,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); - m_clientRequestIDFlushTimer = new Timer(); - m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; - m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; - m_clientRequestIDFlushTimer.AutoReset = true; - m_clientRequestIDFlushTimer.Start(); - } - } - - void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) - { - lock (m_clientRequestIDInfo) - { - TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); - UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; - foreach (UUID key in CurrentKeys) - { - if (m_clientRequestIDInfo.ContainsKey(key)) - { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) - { - m_clientRequestIDInfo.Remove(key); - } - } - } } } @@ -236,8 +202,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); - - m_clientRequestIDFlushTimer.Stop(); } public Type ReplaceableInterface @@ -274,14 +238,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - lock (m_clientRequestIDInfo) - { - if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - // flush any old RequestID information - m_clientRequestIDInfo.Remove(client.AgentId); - } - } + // Send client thier groups information. SendAgentGroupDataUpdate(client, client.AgentId); } @@ -289,7 +246,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray(); GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -338,9 +295,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply( - queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); - } + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray()); + } + } private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) @@ -352,7 +309,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string activeGroupName = string.Empty; ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient), dataForAgentID); if (membership != null) { activeGroupID = membership.GroupID; @@ -371,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string GroupName; - GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); + GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null); if (group != null) { GroupName = group.GroupName; @@ -392,7 +349,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); if (inviteInfo == null) { @@ -411,7 +368,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -435,14 +392,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: If the inviter is still online, they need an agent dataupdate // and maybe group membership updates for the invitee - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } } } @@ -456,7 +413,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); @@ -500,14 +457,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { OnNewGroupNotice(GroupID, NoticeID); } // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) { if (m_debugEnabled) { @@ -592,25 +549,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID) { - return m_groupData.GetGroupRecord(null, GroupID, null); + return m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); } public GroupRecord GetGroupRecord(string name) { - return m_groupData.GetGroupRecord(null, UUID.Zero, name); + return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); } public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.SetAgentActiveGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); // Changing active group changes title, active powers, all kinds of things // anyone who is in any region that can see this client, should probably be // updated with new group info. At a minimum, they should get ScenePresence // updated with new title. - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } /// @@ -620,10 +577,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + List agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); List titles = new List(); foreach (GroupRolesData role in agentRoles) @@ -645,8 +601,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); + } + } return data; @@ -656,7 +619,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID); return data; } @@ -665,8 +628,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); - + List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); + } + } return data; } @@ -676,17 +646,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupProfileData profile = new GroupProfileData(); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); if (groupInfo != null) { profile.AllowPublish = groupInfo.AllowPublish; profile.Charter = groupInfo.Charter; profile.FounderID = groupInfo.FounderID; profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID).Count; profile.InsigniaID = groupInfo.GroupPicture; profile.MaturePublish = groupInfo.MaturePublish; profile.MembershipFee = groupInfo.MembershipFee; @@ -697,7 +666,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups profile.ShowInList = groupInfo.ShowInList; } - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); if (memberInfo != null) { profile.MemberTitle = memberInfo.GroupTitle; @@ -711,7 +680,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); + return m_groupData.GetAgentGroupMemberships(UUID.Zero, agentID).ToArray(); } public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) @@ -721,33 +690,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups "[GROUPS]: {0} called with groupID={1}, agentID={2}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); - return m_groupData.GetAgentGroupMembership(null, agentID, groupID); + return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID); } public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Security Check? - - m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + // Note: Permissions checking for modification rights is handled by the Groups Server/Service + m_groupData.UpdateGroup(GetRequestingAgentID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) { - // TODO: Security Check? + // Note: Permissions checking for modification rights is handled by the Groups Server/Service if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); + m_groupData.SetAgentGroupInfo(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, acceptNotices, listInProfile); } public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; @@ -761,14 +727,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); return UUID.Zero; } - money.ApplyGroupCreationCharge(remoteClient.AgentId); + money.ApplyGroupCreationCharge(GetRequestingAgentID(remoteClient)); } - UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); return groupID; } @@ -779,7 +745,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // ToDo: check if agent is a member of group and is allowed to see notices? - return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); + return m_groupData.GetGroupNotices(GetRequestingAgentID(remoteClient), groupID).ToArray(); } /// @@ -789,7 +755,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(UUID.Zero, avatarID); if (membership != null) { return membership.GroupTitle; @@ -804,13 +770,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); + m_groupData.SetAgentActiveGroupRole(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, titleRoleID); // TODO: Not sure what all is needed here, but if the active group role change is for the group // the client currently has set active, then we need to do a scene presence update too - // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) + // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } @@ -820,16 +786,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Security Checks are handled in the Groups Service. - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch ((OpenMetaverse.GroupRoleUpdate)updateType) { case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); + m_groupData.AddGroupRole(GetRequestingAgentID(remoteClient), groupID, UUID.Random(), name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(grID, groupID, roleID); + m_groupData.RemoveGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID); break; case OpenMetaverse.GroupRoleUpdate.UpdateAll: @@ -840,7 +804,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupPowers gp = (GroupPowers)powers; m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); } - m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); + m_groupData.UpdateGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID, name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.NoUpdate: @@ -851,7 +815,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) @@ -859,18 +823,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch (changes) { case 0: // Add - m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); + m_groupData.AddAgentToGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; case 1: // Remove - m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); + m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; default: @@ -879,25 +841,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); + GroupNoticeInfo data = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), groupNoticeID); if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; msg.message = data.noticeData.Subject + "|" + data.Message; @@ -909,7 +869,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = data.BinaryBucket; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); } } @@ -929,7 +889,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; - GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); + GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID, groupNoticeID); if (info != null) { msg.fromAgentID = info.GroupID.Guid; @@ -956,7 +916,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Send agent information about his groups - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) @@ -964,19 +924,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); remoteClient.SendJoinGroupReply(groupID, true); // Should this send updates to everyone in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); remoteClient.SendLeaveGroupReply(groupID, true); @@ -984,33 +944,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // SL sends out notifcations to the group messaging session that the person has left // Should this also update everyone who is in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); // Todo: Security check? - m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); + remoteClient.SendEjectGroupMemberReply(GetRequestingAgentID(remoteClient), groupID, true); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, ejecteeID); if ((groupInfo == null) || (account == null)) { return; - } - + } // Send Message to Ejectee GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1036,8 +995,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; if (account != null) @@ -1055,7 +1014,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); // SL sends out messages to everyone in the group @@ -1069,13 +1028,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - GroupRequestID grid = GetClientGroupRequestID(remoteClient); - m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID); // Check to see if the invite went through, if it did not then it's possible // the remoteClient did not validate or did not have permission to invite. - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID); if (inviteInfo != null) { @@ -1087,7 +1045,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = inviteUUID; - // msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1140,57 +1098,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return child; } - private GroupRequestID GetClientGroupRequestID(IClientAPI client) - { - if (client == null) - { - return new GroupRequestID(); - } - - lock (m_clientRequestIDInfo) - { - if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - GroupRequestIDInfo info = new GroupRequestIDInfo(); - info.RequestID.AgentID = client.AgentId; - info.RequestID.SessionID = client.SessionId; - - //UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); - UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); - if (account == null) - { - // This should be impossible. If I've been passed a reference to a client - // that client should be registered with the UserService. So something - // is horribly wrong somewhere. - - m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); - - // Default to local user service and hope for the best? - // REFACTORING PROBLEM - //info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - - } - else - { - string domain = string.Empty; //m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - object homeUriObj; - if (account.ServiceURLs.TryGetValue("HomeURI", out homeUriObj) && homeUriObj != null) - domain = homeUriObj.ToString(); - // They're a local user, use this: - info.RequestID.UserServiceURL = domain; - } - - m_clientRequestIDInfo.Add(client.AgentId, info); - } - - m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; - - return m_clientRequestIDInfo[client.AgentId].RequestID; - } -// Unreachable code! -// return new GroupRequestID(); - } - /// /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. /// @@ -1209,7 +1116,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembershipData membership in data) { - if (remoteClient.AgentId != dataForAgentID) + if (GetRequestingAgentID(remoteClient) != dataForAgentID) { if (!membership.ListInProfile) { @@ -1237,13 +1144,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap llDataStruct = new OSDMap(3); llDataStruct.Add("AgentData", AgentData); llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); + llDataStruct.Add("NewGroupData", NewGroupData); + + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); + } IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); } } @@ -1316,7 +1228,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) { - List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); + List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; if (requestingClient.AgentId != dataForAgentID) @@ -1338,7 +1250,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); foreach (GroupMembershipData membership in membershipArray) { - m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2} - {3}", dataForAgentID, membership.GroupName, membership.GroupTitle, membership.GroupPowers); } } @@ -1396,7 +1308,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // } - #endregion + #endregion + + private UUID GetRequestingAgentID(IClientAPI client) + { + UUID requestingAgentID = UUID.Zero; + if (client != null) + { + requestingAgentID = client.AgentId; + } + return requestingAgentID; + } } + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 621ab28..6487967 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -36,41 +36,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { interface IGroupsServicesConnector { - UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); - List FindGroups(GroupRequestID requestID, string search); - List GetGroupMembers(GroupRequestID requestID, UUID GroupID); + UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); + List FindGroups(UUID RequestingAgentID, string search); + List GetGroupMembers(UUID RequestingAgentID, UUID GroupID); - void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); - List GetGroupRoles(GroupRequestID requestID, UUID GroupID); - List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); + void AddGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID); + List GetGroupRoles(UUID RequestingAgentID, UUID GroupID); + List GetGroupRoleMembers(UUID RequestingAgentID, UUID GroupID); - void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void AddAgentToGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + void AddAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void RemoveAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); - void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void AddAgentToGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); + void SetAgentActiveGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(UUID RequestingAgentID, UUID AgentID); - void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); + GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID); - void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); - List GetGroupNotices(GroupRequestID requestID, UUID GroupID); + void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); + List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); } public class GroupInviteInfo @@ -80,11 +80,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public UUID AgentID = UUID.Zero; public UUID InviteID = UUID.Zero; } - - public class GroupRequestID - { - public UUID AgentID = UUID.Zero; - public string UserServiceURL = string.Empty; - public UUID SessionID = UUID.Zero; - } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs new file mode 100644 index 0000000..590753e --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -0,0 +1,1278 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; + +using Nwc.XmlRpc; + +using log4net; +using Mono.Addins; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; + +/*************************************************************************** + * Simian Data Map + * =============== + * + * OwnerID -> Type -> Key + * ----------------------- + * + * UserID -> Group -> ActiveGroup + * + GroupID + * + * UserID -> GroupMember -> GroupID + * + SelectedRoleID [UUID] + * + AcceptNotices [bool] + * + ListInProfile [bool] + * + Contribution [int] + * + * UserID -> GroupRole[GroupID] -> RoleID + * + * GroupID -> Group -> GroupName + * + Charter + * + ShowInList + * + InsigniaID + * + MembershipFee + * + OpenEnrollment + * + AllowPublish + * + MaturePublish + * + FounderID + * + EveryonePowers + * + OwnerRoleID + * + OwnersPowers + * + * GroupID -> GroupRole -> RoleID + * + Name + * + Description + * + Title + * + Powers + * + * GroupID -> GroupMemberInvite -> InviteID + * + AgentID + * + RoleID + * + * GroupID -> GroupNotice -> NoticeID + * + TimeStamp [uint] + * + FromName [string] + * + Subject [string] + * + Message [string] + * + BinaryBucket [byte[]] + * + * */ + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | + GroupPowers.VoteOnProposal; + + // Would this be cleaner as (GroupPowers)ulong.MaxValue; + public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + + private bool m_connectorEnabled = false; + + private string m_serviceURL = string.Empty; + + private bool m_debugEnabled = false; + + // private IUserAccountService m_accountService = null; + + + #region IRegionModuleBase Members + + public string Name + { + get { return "SimianGroupsServicesConnector"; } + } + + // this module is not intended to be replaced, but there should only be 1 of them. + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + if (groupsConfig == null) + { + // Do not run this module by default. + return; + } + else + { + // if groups aren't enabled, we're not needed. + // if we're not specified as the connector to use, then we're not wanted + if ((groupsConfig.GetBoolean("Enabled", false) == false) + || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) + { + m_connectorEnabled = false; + return; + } + + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + + m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); + if ((m_serviceURL == null) || + (m_serviceURL == string.Empty)) + { + m_log.ErrorFormat("Please specify a valid Simian Server URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_connectorEnabled = false; + return; + } + + // If we got all the config options we need, lets start'er'up + m_connectorEnabled = true; + + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); + + } + } + + public void Close() + { + m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + } + + public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (m_connectorEnabled) + { + scene.RegisterModuleInterface(this); + } + } + + public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (scene.RequestModuleInterface() == this) + { + scene.UnregisterModuleInterface(this); + } + } + + public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) + { + // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info + // scene.EventManager.OnNewClient += OnNewClient; + } + + #endregion + + #region ISharedRegionModule Members + + public void PostInitialise() + { + // NoOp + } + + #endregion + + + + + #region IGroupsServicesConnector Members + + /// + /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. + /// + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, + int membershipFee, bool openEnrollment, bool allowPublish, + bool maturePublish, UUID founderID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Random(); + UUID OwnerRoleID = UUID.Random(); + + OSDMap GroupInfoMap = new OSDMap(); + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + GroupInfoMap["FounderID"] = OSD.FromUUID(founderID); + GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers); + GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID); + GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers); + + if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) + { + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + + AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); + + return GroupID; + } + else + { + return UUID.Zero; + } + } + + + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, + UUID insigniaID, int membershipFee, bool openEnrollment, + bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // TODO: Check to make sure requestingAgentID has permission to update group + + string GroupName; + OSDMap GroupInfoMap; + if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) ) + { + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + + SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap); + } + + } + + + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupRoleInfo = new OSDMap(); + GroupRoleInfo["Name"] = OSD.FromString(name); + GroupRoleInfo["Description"] = OSD.FromString(description); + GroupRoleInfo["Title"] = OSD.FromString(title); + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + // TODO: Add security, make sure that requestingAgentID has permision to add roles + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Add security + + // Can't delete the Everyone Role + if (roleID != UUID.Zero) + { + // Remove all GroupRole Members from Role + Dictionary GroupRoleMembers; + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers)) + { + foreach(UUID UserID in GroupRoleMembers.Keys) + { + EnsureRoleNotSelectedByMember(groupID, roleID, UserID); + + SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString()); + } + } + + // Remove role + SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString()); + } + } + + + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security, check that requestingAgentID is allowed to update group roles + + OSDMap GroupRoleInfo; + if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo)) + { + if (name != null) + { + GroupRoleInfo["Name"] = OSD.FromString(name); + } + if (description != null) + { + GroupRoleInfo["Description"] = OSD.FromString(description); + } + if (title != null) + { + GroupRoleInfo["Title"] = OSD.FromString(title); + } + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + } + + + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupInfoMap = null; + if (groupID != UUID.Zero) + { + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap)) + { + return null; + } + } + else if ((groupName != null) && (groupName != string.Empty)) + { + if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) + { + return null; + } + } + + GroupRecord GroupInfo = new GroupRecord(); + + GroupInfo.GroupID = groupID; + GroupInfo.GroupName = groupName; + GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); + GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); + GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID(); + GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger(); + GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean(); + GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean(); + GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean(); + GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID(); + GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID(); + + return GroupInfo; + + } + + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap groupProfile; + string groupName; + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile)) + { + // GroupProfileData is not nullable + return new GroupProfileData(); + } + + GroupProfileData MemberGroupProfile = new GroupProfileData(); + MemberGroupProfile.GroupID = groupID; + MemberGroupProfile.Name = groupName; + + if (groupProfile["Charter"] != null) + { + MemberGroupProfile.Charter = groupProfile["Charter"].AsString(); + } + + MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1"; + MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID(); + MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger(); + MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean(); + MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean(); + MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean(); + MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();; + MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID(); + + Dictionary Members; + if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members)) + { + MemberGroupProfile.GroupMembershipCount = Members.Count; + } + + Dictionary Roles; + if (SimianGetGenericEntries(groupID, "GroupRole", out Roles)) + { + MemberGroupProfile.GroupRolesCount = Roles.Count; + } + + // TODO: Get Group Money balance from somewhere + // group.Money = 0; + + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID); + + MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; + MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; + + return MemberGroupProfile; + } + + public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap ActiveGroup = new OSDMap(); + ActiveGroup.Add("GroupID", OSD.FromUUID(groupID)); + SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup); + } + + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices); + GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile); + GroupMemberInfo["Contribution"] = OSD.FromInteger(0); + GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Invite = new OSDMap(); + Invite["AgentID"] = OSD.FromUUID(agentID); + Invite["RoleID"] = OSD.FromUUID(roleID); + + SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite); + } + + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInvite; + UUID GroupID; + if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite)) + { + return null; + } + + GroupInviteInfo inviteInfo = new GroupInviteInfo(); + inviteInfo.InviteID = inviteID; + inviteInfo.GroupID = GroupID; + inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID(); + inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID(); + + return inviteInfo; + } + + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID); + SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString()); + } + + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Setup Agent/Group information + SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true); + + // Add agent to Everyone Group + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero); + + // Add agent to Specified Role + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + + // Set selected role in this group to specified role + SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + } + + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If current active group is the group the agent is being removed from, change their group to UUID.Zero + GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID); + if (memberActiveMembership.GroupID == groupID) + { + SetAgentActiveGroup(agentID, agentID, UUID.Zero); + } + + // Remove Group Member information for this group + SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString()); + + // By using a Simian Generics Type consisting of a prefix and a groupID, + // combined with RoleID as key allows us to get a list of roles a particular member + // of a group is assigned to. + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + + // Take Agent out of all other group roles + Dictionary GroupRoles; + if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles)) + { + foreach (string roleID in GroupRoles.Keys) + { + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID); + } + } + } + + public void AddAgentToGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap()); + } + + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Cannot remove members from the Everyone Role + if (roleID != UUID.Zero) + { + EnsureRoleNotSelectedByMember(groupID, roleID, agentID); + + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString()); + } + } + + public List FindGroups(UUID requestingAgentID, string search) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List findings = new List(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", "Group" }, + { "Key", search }, + { "Fuzzy", "1" } + }; + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + DirGroupsReplyData data = new DirGroupsReplyData(); + data.groupID = entryMap["OwnerID"].AsUUID(); + data.groupName = entryMap["Key"].AsString(); + + // TODO: is there a better way to do this? + Dictionary Members; + if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members)) + { + data.members = Members.Count; + } + else + { + data.members = 0; + } + + // TODO: sort results? + // data.searchOrder = order; + + findings.Add(data); + } + } + + + return findings; + } + + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupMembershipData data = new GroupMembershipData(); + + /////////////////////////////// + // Agent Specific Information: + // + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); + } + + OSDMap UserGroupMemberInfo; + if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) ) + { + data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); + data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); + data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); + data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); + + /////////////////////////////// + // Role Specific Information: + // + + OSDMap GroupRoleInfo; + if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) ) + { + data.GroupTitle = GroupRoleInfo["Title"].AsString(); + data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); + } + } + + /////////////////////////////// + // Group Specific Information: + // + OSDMap GroupInfo; + string GroupName; + if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) ) + { + data.GroupID = groupID; + data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); + data.Charter = GroupInfo["Charter"].AsString(); + data.FounderID = GroupInfo["FounderID"].AsUUID(); + data.GroupName = GroupName; + data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); + data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); + data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); + data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); + data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); + } + + return data; + } + + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Zero; + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + GroupID = UserActiveGroup["GroupID"].AsUUID(); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); + } + + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List memberships = new List(); + + Dictionary GroupMemberShips; + if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips)) + { + foreach (string key in GroupMemberShips.Keys) + { + memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key))); + } + } + + return memberships; + } + + public List GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } + } + return Roles; + } + + public List GetGroupRoles(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach (KeyValuePair role in GroupRoles) + { + GroupRolesData data = new GroupRolesData(); + + data.RoleID = UUID.Parse(role.Key); + + data.Name = role.Value["Name"].AsString(); + data.Description = role.Value["Description"].AsString(); + data.Title = role.Value["Title"].AsString(); + data.Powers = role.Value["Powers"].AsULong(); + + Dictionary GroupRoleMembers; + if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers)) + { + data.Members = GroupRoleMembers.Count; + } + else + { + data.Members = 0; + } + + Roles.Add(data); + } + } + + return Roles; + + } + + + + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + OSDMap GroupInfo; + string GroupName; + UUID GroupOwnerRoleID = UUID.Zero; + if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo)) + { + return members; + } + GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID(); + + // Locally cache group roles, since we'll be needing this data for each member + Dictionary GroupRoles; + SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles); + + // Locally cache list of group owners + Dictionary GroupOwners; + SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners); + + + Dictionary GroupMembers; + if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers)) + { + foreach (KeyValuePair member in GroupMembers) + { + GroupMembersData data = new GroupMembersData(); + + data.AgentID = member.Key; + + UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID(); + + data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean(); + data.ListInProfile = member.Value["ListInProfile"].AsBoolean(); + data.Contribution = member.Value["Contribution"].AsInteger(); + + data.IsOwner = GroupOwners.ContainsKey(member.Key); + + OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()]; + data.Title = GroupRoleInfo["Title"].AsString(); + data.AgentPowers = GroupRoleInfo["Powers"].AsULong(); + + members.Add(data); + } + } + + return members; + + } + + public List GetGroupRoleMembers(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach( KeyValuePair Role in GroupRoles ) + { + Dictionary GroupRoleMembers; + if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) ) + { + foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = GroupRoleMember.Key; + data.RoleID = UUID.Parse(Role.Key); + + members.Add(data); + } + } + } + } + + return members; + } + + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List values = new List(); + + Dictionary Notices; + if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices)) + { + foreach (KeyValuePair Notice in Notices) + { + GroupNoticeData data = new GroupNoticeData(); + data.NoticeID = UUID.Parse(Notice.Key); + data.Timestamp = Notice.Value["TimeStamp"].AsUInteger(); + data.FromName = Notice.Value["FromName"].AsString(); + data.Subject = Notice.Value["Subject"].AsString(); + data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0; + + //TODO: Figure out how to get this + data.AssetType = 0; + + values.Add(data); + } + } + + return values; + + } + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupNotice; + UUID GroupID; + if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice)) + { + GroupNoticeInfo data = new GroupNoticeInfo(); + data.GroupID = GroupID; + data.Message = GroupNotice["Message"].AsString(); + data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(); + data.noticeData.NoticeID = noticeID; + data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger(); + data.noticeData.FromName = GroupNotice["FromName"].AsString(); + data.noticeData.Subject = GroupNotice["Subject"].AsString(); + data.noticeData.HasAttachment = data.BinaryBucket.Length > 0; + data.noticeData.AssetType = 0; + + if (data.Message == null) + { + data.Message = string.Empty; + } + + return data; + } + return null; + } + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Notice = new OSDMap(); + Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch()); + Notice["FromName"] = OSD.FromString(fromName); + Notice["Subject"] = OSD.FromString(subject); + Notice["Message"] = OSD.FromString(message); + Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket); + + SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); + + } + #endregion + + + private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If member's SelectedRole is roleID, change their selected role to Everyone + // before removing them from the role + OSDMap UserGroupInfo; + if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo)) + { + if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID) + { + UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero); + } + SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo); + } + } + + + #region Simian Util Methods + private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + string value = OSDParser.SerializeJsonString(map); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "AddGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key }, + { "Value", value} + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]); + return false; + } + } + + /// + /// Returns the first of possibly many entries for Owner/Type pair + /// + private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + key = null; + map = null; + return false; + } + private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + ownerID = UUID.Zero; + map = null; + return false; + } + + private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count == 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + map = null; + return false; + } + + private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + private bool SimianGetGenericEntries(string type, string key, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key } + }; + + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + + private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key } + }; + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]); + return false; + } + } + #endregion + } + +} + diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 24ae4f7..ab343c8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -40,7 +40,9 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; +using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { @@ -66,6 +68,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupReadKey = string.Empty; private string m_groupWriteKey = string.Empty; + private IUserAccountService m_accountService = null; + #region IRegionModuleBase Members @@ -116,6 +120,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); + + + // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; } @@ -129,13 +136,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (m_connectorEnabled) + { + + if (m_accountService == null) + { + m_accountService = scene.UserAccountService; + } + + scene.RegisterModuleInterface(this); + } } public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (scene.RequestModuleInterface() == this) + { scene.UnregisterModuleInterface(this); + } } public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) @@ -155,14 +173,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - - #region IGroupsServicesConnector Members /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) { @@ -234,7 +250,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); if (respData.Contains("error")) { @@ -246,7 +262,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { @@ -260,10 +276,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; - XmlRpcCall(requestID, "groups.updateGroup", param); + XmlRpcCall(requestingAgentID, "groups.updateGroup", param); } - public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -274,19 +290,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Title"] = title; param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.addRoleToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addRoleToGroup", param); } - public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); param["RoleID"] = roleID.ToString(); - XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); } - public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -306,10 +322,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.updateGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.updateGroupRole", param); } - public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); if (GroupID != UUID.Zero) @@ -321,7 +337,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -332,12 +348,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID GroupID, UUID AgentID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -345,7 +361,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return new GroupProfileData(); } - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID); GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; @@ -354,26 +370,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return MemberGroupProfile; } - public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void SetAgentActiveGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); + XmlRpcCall(requestingAgentID, "groups.setAgentActiveGroup", param); } - public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["SelectedRoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + public void SetAgentGroupInfo(UUID requestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); @@ -381,11 +397,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AcceptNotices"] = AcceptNotices ? "1" : "0"; param["ListInProfile"] = ListInProfile ? "1" : "0"; - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); @@ -393,16 +409,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); param["GroupID"] = groupID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupInvite", param); } - public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentToGroupInvite", param); if (respData.Contains("error")) { @@ -418,59 +434,59 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return inviteInfo; } - public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentToGroupInvite", param); } - public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroup", param); } - public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroup", param); } - public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupRole", param); } - public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroupRole", param); } - public List FindGroups(GroupRequestID requestID, string search) + public List FindGroups(UUID requestingAgentID, string search) { Hashtable param = new Hashtable(); param["Search"] = search; - Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.findGroups", param); List findings = new List(); @@ -492,13 +508,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return findings; } - public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMembership", param); if (respData.Contains("error")) { @@ -510,12 +526,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentActiveMembership", param); if (respData.Contains("error")) { @@ -525,12 +541,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMemberships", param); List memberships = new List(); @@ -545,13 +561,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return memberships; } - public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public List GetAgentGroupRoles(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentRoles", param); List Roles = new List(); @@ -577,12 +593,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoles(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoles", param); List Roles = new List(); @@ -610,12 +626,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupMembers", param); List members = new List(); @@ -643,12 +659,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoleMembers", param); List members = new List(); @@ -667,12 +683,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return members; } - public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotices", param); List values = new List(); @@ -694,12 +710,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return values; } - public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); if (respData.Contains("error")) @@ -725,7 +741,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -738,7 +754,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["BinaryBucket"] = binBucket; param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - XmlRpcCall(requestID, "groups.addGroupNotice", param); + XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } #endregion @@ -831,15 +847,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Encapsulate the XmlRpc call to standardize security and error handling. /// - private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) + private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - if (requestID == null) - { - requestID = new GroupRequestID(); - } - param.Add("RequestingAgentID", requestID.AgentID.ToString()); - param.Add("RequestingAgentUserService", requestID.UserServiceURL); - param.Add("RequestingSessionID", requestID.SessionID.ToString()); + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); param.Add("ReadKey", m_groupReadKey); @@ -930,15 +945,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } + + /// + /// Group Request Tokens are an attempt to allow the groups service to authenticate + /// requests. Currently uses UserService, AgentID, and SessionID + /// TODO: Find a better way to do this. + /// + /// + /// + private void GetClientGroupRequestID(UUID AgentID, out string UserServiceURL, out UUID SessionID) + { + UserServiceURL = ""; + SessionID = UUID.Zero; - } - public class GroupNoticeInfo - { - public GroupNoticeData noticeData = new GroupNoticeData(); - public UUID GroupID = UUID.Zero; - public string Message = string.Empty; - public byte[] BinaryBucket = new byte[0]; + // Need to rework this based on changes to User Services + /* + UserAccount userAccount = m_accountService.GetUserAccount(UUID.Zero,AgentID); + if (userAccount == null) + { + // This should be impossible. If I've been passed a reference to a client + // that client should be registered with the UserService. So something + // is horribly wrong somewhere. + + m_log.WarnFormat("[GROUPS]: Could not find a UserServiceURL for {0}", AgentID); + + } + else if (userProfile is ForeignUserProfileData) + { + // They aren't from around here + ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; + UserServiceURL = fupd.UserServerURI; + SessionID = fupd.CurrentAgent.SessionID; + + } + else + { + // They're a local user, use this: + UserServiceURL = m_commManager.NetworkServersInfo.UserURL; + SessionID = userProfile.CurrentAgent.SessionID; + } + */ + } + } } -- cgit v1.1 From 6485c576a177d521ec26df7c0a5e374e22682396 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 3 Apr 2010 12:03:34 -0700 Subject: * Made UserAccountService handle UserLevel, UserFlags and UserTitle appropriately. * Removed Store service from the UserAccount handler. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 62 ++++----- .../SimianGroupsServicesConnectorModule.cs | 150 ++++++++++----------- 2 files changed, 106 insertions(+), 106 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6b942cb..b2b8110 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -601,14 +601,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); - } + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); + } } return data; @@ -628,14 +628,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); - } + List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); + } } return data; } @@ -1144,11 +1144,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap llDataStruct = new OSDMap(3); llDataStruct.Add("AgentData", AgentData); llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); - - if (m_debugEnabled) - { - m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); + llDataStruct.Add("NewGroupData", NewGroupData); + + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); } IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); @@ -1308,16 +1308,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // } - #endregion - - private UUID GetRequestingAgentID(IClientAPI client) - { - UUID requestingAgentID = UUID.Zero; - if (client != null) - { - requestingAgentID = client.AgentId; - } - return requestingAgentID; + #endregion + + private UUID GetRequestingAgentID(IClientAPI client) + { + UUID requestingAgentID = UUID.Zero; + if (client != null) + { + requestingAgentID = client.AgentId; + } + return requestingAgentID; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 590753e..bc05b0f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -288,8 +288,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) { - AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); - AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); @@ -413,7 +413,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } else if ((groupName != null) && (groupName != string.Empty)) - { + { if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) { return null; @@ -422,7 +422,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord GroupInfo = new GroupRecord(); - GroupInfo.GroupID = groupID; + GroupInfo.GroupID = groupID; GroupInfo.GroupName = groupName; GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); @@ -751,9 +751,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) { GroupID = UserActiveGroup["GroupID"].AsUUID(); - } - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); } @@ -781,24 +781,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List Roles = new List(); - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - Dictionary MemberRoles; - if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) - { - foreach (KeyValuePair kvp in MemberRoles) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = UUID.Parse(kvp.Key); - data.Name = GroupRoles[kvp.Key]["Name"].AsString(); - data.Description = GroupRoles[kvp.Key]["Description"].AsString(); - data.Title = GroupRoles[kvp.Key]["Title"].AsString(); - data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); - - Roles.Add(data); - } - } + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } } return Roles; } @@ -912,8 +912,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) { - GroupRoleMembersData data = new GroupRoleMembersData(); - + GroupRoleMembersData data = new GroupRoleMembersData(); + data.MemberID = GroupRoleMember.Key; data.RoleID = UUID.Parse(Role.Key); @@ -1066,20 +1066,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1106,20 +1106,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - ownerID = entryMap["OwnerID"].AsUUID(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1152,16 +1152,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { OSDMap entryMap = entryArray[0] as OSDMap; key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } } else { @@ -1191,13 +1191,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); } - if(maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } return true; @@ -1229,14 +1229,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { + { if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if (maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } return true; } else -- cgit v1.1 From 936e08e20e3653b9173c39d327e4d585a7aa4788 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 4 Apr 2010 02:23:53 +0100 Subject: Patch from mcortez. This appears to be a huge change to the groups module and I can't say if this is beneficial or destructive due to the way it was delivered (zipfile). Pushing this on faith alone. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 216 +++++++++---------- .../Avatar/XmlRpcGroups/GroupsModule.cs | 9 +- .../XmlRpcGroups/IGroupsServicesConnector.cs | 8 +- .../SimianGroupsServicesConnectorModule.cs | 237 +++++++++++++-------- .../XmlRpcGroupsServicesConnectorModule.cs | 98 +++++++-- 5 files changed, 337 insertions(+), 231 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 533815f..17a5349 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -49,14 +49,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private List m_sceneList = new List(); - private IMessageTransferModule m_msgTransferModule = null; - - private IGroupsModule m_groupsModule = null; - - // TODO: Move this off to the Groups Server - public Dictionary> m_agentsInGroupSession = new Dictionary>(); - public Dictionary> m_agentsDroppedSession = new Dictionary>(); - + private IMessageTransferModule m_msgTransferModule = null; + + private IGroupsServicesConnector m_groupData = null; // Config Options private bool m_groupMessagingEnabled = false; @@ -113,14 +108,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupMessagingEnabled) return; - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - m_groupsModule = scene.RequestModuleInterface(); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + m_groupData = scene.RequestModuleInterface(); - // No groups module, no groups messaging - if (m_groupsModule == null) - { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, GroupsMessagingModule is now disabled."); + // No groups module, no groups messaging + if (m_groupData == null) + { + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; return; @@ -142,7 +137,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - + scene.EventManager.OnClientLogin += OnClientLogin; } public void RemoveRegion(Scene scene) @@ -170,7 +165,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_sceneList.Clear(); - m_groupsModule = null; + m_groupData = null; m_msgTransferModule = null; } @@ -195,16 +190,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + /// + /// Not really needed, but does confirm that the group exists. + /// public bool StartGroupChatSession(UUID agentID, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); if (groupInfo != null) - { - AddAgentToGroupSession(agentID.Guid, groupID.Guid); + { return true; } else @@ -216,11 +213,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) - { - if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) + { + if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); @@ -228,8 +226,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = groupID.Guid; msg.fromAgentName = im.fromAgentName; msg.message = im.message; msg.dialog = im.dialog; @@ -240,8 +238,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.binaryBucket = im.binaryBucket; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - // Updat Pertinate fields to make it a "group message" - msg.fromAgentID = groupID.Guid; + msg.fromAgentID = im.fromAgentID; msg.fromGroup = true; msg.toAgentID = member.AgentID.Guid; @@ -262,7 +259,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } - #region SimGridEventHandlers + #region SimGridEventHandlers + + void OnClientLogin(IClientAPI client) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); + + + } private void OnNewClient(IClientAPI client) { @@ -299,44 +303,48 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void ProcessMessageFromGroupSession(GridInstantMessage msg) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + + UUID AgentID = new UUID(msg.fromAgentID); + UUID GroupID = new UUID(msg.imSessionID); switch (msg.dialog) { - case (byte)InstantMessageDialog.SessionAdd: - AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); + case (byte)InstantMessageDialog.SessionAdd: + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); break; - case (byte)InstantMessageDialog.SessionDrop: - RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); + case (byte)InstantMessageDialog.SessionDrop: + m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); break; - case (byte)InstantMessageDialog.SessionSend: - if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) - && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + case (byte)InstantMessageDialog.SessionSend: + if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) + && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) + ) { // Agent not in session and hasn't dropped from session - // Add them to the session for now, and Invite them - AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); + // Add them to the session for now, and Invite them + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); IClientAPI activeClient = GetActiveClient(toAgentID); if (activeClient != null) { - UUID groupID = new UUID(msg.fromAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); - // Force? open the group session dialog??? + // Force? open the group session dialog??? + // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); IEventQueue eq = activeClient.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( - groupID + eq.ChatterboxInvitation( + GroupID , groupInfo.GroupName , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) + , msg.message + , new UUID(msg.toAgentID) , msg.fromAgentName , msg.dialog , msg.timestamp @@ -349,8 +357,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups , Utils.StringToBytes(groupInfo.GroupName) ); - eq.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) + eq.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) , new UUID(msg.fromAgentID) , new UUID(msg.toAgentID) , false //canVoiceChat @@ -359,8 +367,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ); } } - } - else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + } + else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. @@ -386,56 +394,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - #region ClientEvents - - private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) - { - if (m_agentsInGroupSession.ContainsKey(sessionID)) - { - // If in session remove - if (m_agentsInGroupSession[sessionID].Contains(agentID)) - { - m_agentsInGroupSession[sessionID].Remove(agentID); - } - - // If not in dropped list, add - if (!m_agentsDroppedSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); - m_agentsDroppedSession[sessionID].Add(agentID); - } - } - } - - private void AddAgentToGroupSession(Guid agentID, Guid sessionID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupSessionTracking(sessionID); - - // If nessesary, remove from dropped list - if (m_agentsDroppedSession[sessionID].Contains(agentID)) - { - m_agentsDroppedSession[sessionID].Remove(agentID); - } - - // If nessesary, add to in session list - if (!m_agentsInGroupSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); - m_agentsInGroupSession[sessionID].Add(agentID); - } - } - - private void CreateGroupSessionTracking(Guid sessionID) - { - if (!m_agentsInGroupSession.ContainsKey(sessionID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); - m_agentsInGroupSession.Add(sessionID, new List()); - m_agentsDroppedSession.Add(sessionID, new List()); - } - } - + + #region ClientEvents private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -447,20 +407,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) - { - UUID groupID = new UUID(im.toAgentID); - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); + + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) - { - AddAgentToGroupSession(im.fromAgentID, groupInfo.GroupID.Guid); + { + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - queue.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(im.fromAgentID) + queue.ChatterBoxSessionAgentListUpdates( + GroupID + , AgentID , new UUID(im.toAgentID) , false //canVoiceChat , false //isModerator @@ -471,13 +435,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) - { - UUID groupID = new UUID(im.toAgentID); + { + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); - SendMessageToGroup(im, groupID); + //If this agent is sending a message, then they want to be in the session + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + + SendMessageToGroup(im, GroupID); } } @@ -533,7 +501,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// Try to find an active IClientAPI reference for agentID giving preference to root connections /// private IClientAPI GetActiveClient(UUID agentID) - { + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); + IClientAPI child = null; // Try root avatar first @@ -544,17 +514,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) - { + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); return user.ControllingClient; } else - { + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); child = user.ControllingClient; } } } - // If we didn't find a root, then just return whichever child we found, or null if none + // If we didn't find a root, then just return whichever child we found, or null if none + if (child == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); + } + else + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); + } return child; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6b942cb..5328d7a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -175,14 +175,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; // The InstantMessageModule itself doesn't do this, // so lets see if things explode if we don't do it // scene.EventManager.OnClientClosed += OnClientClosed; - } - + } + public void RemoveRegion(Scene scene) { if (!m_groupsEnabled) @@ -510,7 +509,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { - UUID groupID = new UUID(im.fromAgentID); + UUID groupID = new UUID(im.imSessionID); ejectee.SendAgentDropGroup(groupID); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 6487967..54ffc81 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -70,7 +70,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); - List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); + List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); + + void ResetAgentGroupChatSessions(UUID agentID); + bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); + bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); + void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); + void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID); } public class GroupInviteInfo diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 590753e..4867c01 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -55,6 +55,9 @@ using OpenSim.Services.Interfaces; * UserID -> Group -> ActiveGroup * + GroupID * + * UserID -> GroupSessionDropped -> GroupID + * UserID -> GroupSessionInvited -> GroupID + * * UserID -> GroupMember -> GroupID * + SelectedRoleID [UUID] * + AcceptNotices [bool] @@ -63,6 +66,7 @@ using OpenSim.Services.Interfaces; * * UserID -> GroupRole[GroupID] -> RoleID * + * * GroupID -> Group -> GroupName * + Charter * + ShowInList @@ -159,7 +163,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_debugEnabled = false; @@ -199,13 +203,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) - { - m_log.ErrorFormat("Please specify a valid Simian Server URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) + { + m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } @@ -288,8 +292,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) { - AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); - AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); @@ -413,7 +417,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } else if ((groupName != null) && (groupName != string.Empty)) - { + { if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) { return null; @@ -422,7 +426,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord GroupInfo = new GroupRecord(); - GroupInfo.GroupID = groupID; + GroupInfo.GroupID = groupID; GroupInfo.GroupName = groupName; GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); @@ -653,7 +657,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)response["Entries"]; @@ -751,9 +755,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) { GroupID = UserActiveGroup["GroupID"].AsUUID(); - } - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); } @@ -781,24 +785,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List Roles = new List(); - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - Dictionary MemberRoles; - if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) - { - foreach (KeyValuePair kvp in MemberRoles) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = UUID.Parse(kvp.Key); - data.Name = GroupRoles[kvp.Key]["Name"].AsString(); - data.Description = GroupRoles[kvp.Key]["Description"].AsString(); - data.Title = GroupRoles[kvp.Key]["Title"].AsString(); - data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); - - Roles.Add(data); - } - } + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } } return Roles; } @@ -912,8 +916,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) { - GroupRoleMembersData data = new GroupRoleMembersData(); - + GroupRoleMembersData data = new GroupRoleMembersData(); + data.MemberID = GroupRoleMember.Key; data.RoleID = UUID.Parse(Role.Key); @@ -996,9 +1000,55 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); } + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + Dictionary agentSessions; + + if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); + } + } + + if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); + } + } + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + #endregion - private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) { if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -1036,7 +1086,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); if (Response["Success"].AsBoolean()) { return true; @@ -1063,23 +1113,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1103,23 +1153,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - ownerID = entryMap["OwnerID"].AsUUID(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1144,7 +1194,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1152,16 +1202,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { OSDMap entryMap = entryArray[0] as OSDMap; key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } } else { @@ -1184,20 +1234,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); } - if(maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } return true; @@ -1222,21 +1272,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { + { if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if (maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } return true; } else @@ -1260,7 +1310,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); if (response["Success"].AsBoolean()) { return true; @@ -1271,7 +1321,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return false; } } - #endregion + #endregion + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index ab343c8..8e7aa68 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -61,15 +61,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_disableKeepAlive = false; private string m_groupReadKey = string.Empty; private string m_groupWriteKey = string.Empty; - private IUserAccountService m_accountService = null; - + private IUserAccountService m_accountService = null; + + // Used to track which agents are have dropped from a group chat session + // Should be reset per agent, on logon + // TODO: move this to Flotsam XmlRpc Service + // SessionID, List + private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); + private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); + #region IRegionModuleBase Members @@ -104,13 +111,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) - { - m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) + { + m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } @@ -756,7 +763,70 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } - #endregion + + + + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) + { + agentList.Remove(agentID); + } + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking this group, and we can find them in the tracking, then they've been invited + return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) + && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking drops for this group, + // and we find them, well... then they've dropped + return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) + && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + // If not in dropped list, add + if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); + } + } + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupChatSessionTracking(groupID); + + // If nessesary, remove from dropped list + if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); + } + } + + private void CreateGroupChatSessionTracking(UUID groupID) + { + if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); + m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); + } + + } + #endregion #region XmlRpcHashtableMarshalling private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) @@ -871,7 +941,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups try { - resp = req.Send(m_serviceURL, 10000); + resp = req.Send(m_groupsServerURI, 10000); } catch (Exception e) { @@ -948,8 +1018,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Group Request Tokens are an attempt to allow the groups service to authenticate - /// requests. Currently uses UserService, AgentID, and SessionID - /// TODO: Find a better way to do this. + /// requests. + /// TODO: This broke after the big grid refactor, either find a better way, or discard this /// /// /// -- cgit v1.1 From 80346ad2e246a363dcf4c9a2819b52b1d7a0739c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 5 Apr 2010 19:56:03 -0700 Subject: * May fix mantis #4603. * My local git wants to commit the groups files for line endings, I'm gonna let it do it. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 128 +++++++++--------- .../Avatar/XmlRpcGroups/GroupsModule.cs | 6 +- .../XmlRpcGroups/IGroupsServicesConnector.cs | 12 +- .../SimianGroupsServicesConnectorModule.cs | 104 +++++++-------- .../XmlRpcGroupsServicesConnectorModule.cs | 144 ++++++++++----------- 5 files changed, 197 insertions(+), 197 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 17a5349..185d44d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -49,9 +49,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private List m_sceneList = new List(); - private IMessageTransferModule m_msgTransferModule = null; - - private IGroupsServicesConnector m_groupData = null; + private IMessageTransferModule m_msgTransferModule = null; + + private IGroupsServicesConnector m_groupData = null; // Config Options private bool m_groupMessagingEnabled = false; @@ -108,13 +108,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (!m_groupMessagingEnabled) return; - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + m_groupData = scene.RequestModuleInterface(); - // No groups module, no groups messaging + // No groups module, no groups messaging if (m_groupData == null) - { + { m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; @@ -190,9 +190,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - /// - /// Not really needed, but does confirm that the group exists. - /// + /// + /// Not really needed, but does confirm that the group exists. + /// public bool StartGroupChatSession(UUID agentID, UUID groupID) { if (m_debugEnabled) @@ -201,7 +201,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); if (groupInfo != null) - { + { return true; } else @@ -213,11 +213,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) - { + { if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session @@ -226,7 +226,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // Copy Message - GridInstantMessage msg = new GridInstantMessage(); + GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = groupID.Guid; msg.fromAgentName = im.fromAgentName; msg.message = im.message; @@ -259,13 +259,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } - #region SimGridEventHandlers - - void OnClientLogin(IClientAPI client) - { + #region SimGridEventHandlers + + void OnClientLogin(IClientAPI client) + { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); - - + + } private void OnNewClient(IClientAPI client) @@ -303,28 +303,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void ProcessMessageFromGroupSession(GridInstantMessage msg) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); - - UUID AgentID = new UUID(msg.fromAgentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + + UUID AgentID = new UUID(msg.fromAgentID); UUID GroupID = new UUID(msg.imSessionID); switch (msg.dialog) { - case (byte)InstantMessageDialog.SessionAdd: + case (byte)InstantMessageDialog.SessionAdd: m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); break; - case (byte)InstantMessageDialog.SessionDrop: + case (byte)InstantMessageDialog.SessionDrop: m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); break; - case (byte)InstantMessageDialog.SessionSend: - if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) + case (byte)InstantMessageDialog.SessionSend: + if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) ) { // Agent not in session and hasn't dropped from session - // Add them to the session for now, and Invite them + // Add them to the session for now, and Invite them m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); @@ -336,10 +336,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); - // Force? open the group session dialog??? + // Force? open the group session dialog??? // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); IEventQueue eq = activeClient.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( + eq.ChatterboxInvitation( GroupID , groupInfo.GroupName , new UUID(msg.fromAgentID) @@ -357,7 +357,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups , Utils.StringToBytes(groupInfo.GroupName) ); - eq.ChatterBoxSessionAgentListUpdates( + eq.ChatterBoxSessionAgentListUpdates( new UUID(GroupID) , new UUID(msg.fromAgentID) , new UUID(msg.toAgentID) @@ -367,7 +367,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ); } } - } + } else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, @@ -394,8 +394,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - - #region ClientEvents + + #region ClientEvents private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -407,23 +407,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) - { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); - - UUID GroupID = new UUID(im.imSessionID); - UUID AgentID = new UUID(im.fromAgentID); - + { + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); + + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) - { + { m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - queue.ChatterBoxSessionAgentListUpdates( - GroupID + queue.ChatterBoxSessionAgentListUpdates( + GroupID , AgentID , new UUID(im.toAgentID) , false //canVoiceChat @@ -435,16 +435,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) - { - UUID GroupID = new UUID(im.imSessionID); - UUID AgentID = new UUID(im.fromAgentID); + { + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); - //If this agent is sending a message, then they want to be in the session - m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - + //If this agent is sending a message, then they want to be in the session + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + SendMessageToGroup(im, GroupID); } } @@ -501,7 +501,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// Try to find an active IClientAPI reference for agentID giving preference to root connections /// private IClientAPI GetActiveClient(UUID agentID) - { + { if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); IClientAPI child = null; @@ -514,26 +514,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); return user.ControllingClient; } else - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); child = user.ControllingClient; } } } - // If we didn't find a root, then just return whichever child we found, or null if none - if (child == null) - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); - } - else - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); + // If we didn't find a root, then just return whichever child we found, or null if none + if (child == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); + } + else + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); } return child; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index e5dab93..56c0d98 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -175,13 +175,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; // The InstantMessageModule itself doesn't do this, // so lets see if things explode if we don't do it // scene.EventManager.OnClientClosed += OnClientClosed; - } - + } + public void RemoveRegion(Scene scene) { if (!m_groupsEnabled) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 54ffc81..a046e09 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -70,12 +70,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); - List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); - - void ResetAgentGroupChatSessions(UUID agentID); - bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); - bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); - void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); + List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); + + void ResetAgentGroupChatSessions(UUID agentID); + bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); + bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); + void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID); } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 4867c01..669373f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -203,12 +203,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); if ((m_groupsServerURI == null) || (m_groupsServerURI == string.Empty)) - { + { m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; @@ -1000,53 +1000,53 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); } - #endregion - - #region GroupSessionTracking - - public void ResetAgentGroupChatSessions(UUID agentID) - { - Dictionary agentSessions; - - if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) - { - foreach (string GroupID in agentSessions.Keys) - { - SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); - } - } - - if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) - { - foreach (string GroupID in agentSessions.Keys) - { - SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); - } - } - } - - public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) - { - OSDMap session; - return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); - } - - public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) - { - SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); - } - - public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); - } - - public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - OSDMap session; - return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); - } - + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + Dictionary agentSessions; + + if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); + } + } + + if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); + } + } + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + #endregion private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) @@ -1321,8 +1321,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return false; } } - #endregion - + #endregion + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 8e7aa68..523dfbe 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -68,14 +68,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupReadKey = string.Empty; private string m_groupWriteKey = string.Empty; - private IUserAccountService m_accountService = null; - - // Used to track which agents are have dropped from a group chat session - // Should be reset per agent, on logon - // TODO: move this to Flotsam XmlRpc Service - // SessionID, List - private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); - private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); + private IUserAccountService m_accountService = null; + + // Used to track which agents are have dropped from a group chat session + // Should be reset per agent, on logon + // TODO: move this to Flotsam XmlRpc Service + // SessionID, List + private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); + private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); #region IRegionModuleBase Members @@ -111,12 +111,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); if ((m_groupsServerURI == null) || (m_groupsServerURI == string.Empty)) - { + { m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; @@ -766,67 +766,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - #endregion - - #region GroupSessionTracking - - public void ResetAgentGroupChatSessions(UUID agentID) - { - foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) - { - agentList.Remove(agentID); - } - } - - public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - // If we're tracking this group, and we can find them in the tracking, then they've been invited - return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) - && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); - } - - public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) - { - // If we're tracking drops for this group, - // and we find them, well... then they've dropped - return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) - && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); - } - - public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) - { - if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) - { - // If not in dropped list, add - if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) - { - m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); - } - } - } - - public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupChatSessionTracking(groupID); - - // If nessesary, remove from dropped list - if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) - { - m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); - } - } - - private void CreateGroupChatSessionTracking(UUID groupID) - { - if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) - { - m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); - m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); - } - - } - #endregion + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) + { + agentList.Remove(agentID); + } + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking this group, and we can find them in the tracking, then they've been invited + return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) + && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking drops for this group, + // and we find them, well... then they've dropped + return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) + && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + // If not in dropped list, add + if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); + } + } + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupChatSessionTracking(groupID); + + // If nessesary, remove from dropped list + if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); + } + } + + private void CreateGroupChatSessionTracking(UUID groupID) + { + if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); + m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); + } + + } + #endregion #region XmlRpcHashtableMarshalling private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) -- cgit v1.1 From 8fa13e387110233e2a38ceb41906f65992f014e5 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 14 Apr 2010 19:48:40 -0700 Subject: Patch from mcortez to add basic caching to the groups module. This prevents database/network explosions when you have a significant number of group-owned prims in a scene --- .../SimianGroupsServicesConnectorModule.cs | 81 +++++++++++-- .../XmlRpcGroupsServicesConnectorModule.cs | 131 ++++++++++++++------- 2 files changed, 160 insertions(+), 52 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 669373f..9363205 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -167,6 +167,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_debugEnabled = false; + private ExpiringCache m_memoryCache; + private int m_cacheTimeout = 30; + // private IUserAccountService m_accountService = null; @@ -203,7 +206,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); if ((m_groupsServerURI == null) || @@ -214,6 +217,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } + + m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); + if (m_cacheTimeout == 0) + { + m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Disabled."); + } + else + { + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout); + } + + + + m_memoryCache = new ExpiringCache(); + + // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; @@ -224,7 +243,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -657,7 +676,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)response["Entries"]; @@ -1086,7 +1105,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean()) { return true; @@ -1113,7 +1132,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1153,7 +1172,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1194,7 +1213,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1234,7 +1253,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); @@ -1272,7 +1291,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); @@ -1310,7 +1329,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean()) { return true; @@ -1323,6 +1342,48 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } #endregion + #region CheesyCache + OSDMap CachedPostRequest(NameValueCollection requestArgs) + { + // Immediately forward the request if the cache is disabled. + if (m_cacheTimeout == 0) + { + return WebUtil.PostToService(m_groupsServerURI, requestArgs); + } + + // Check if this is an update or a request + if ( requestArgs["RequestMethod"] == "RemoveGeneric" + || requestArgs["RequestMethod"] == "AddGeneric" + ) + + { + // Any and all updates cause the cache to clear + m_memoryCache.Clear(); + + // Send update to server, return the response without caching it + return WebUtil.PostToService(m_groupsServerURI, requestArgs); + + } + + // If we're not doing an update, we must be requesting data + + // Create the cache key for the request and see if we have it cached + string CacheKey = WebUtil.BuildQueryString(requestArgs); + OSDMap response = null; + if (!m_memoryCache.TryGetValue(CacheKey, out response)) + { + // if it wasn't in the cache, pass the request to the Simian Grid Services + response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + + // and cache the response + m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + } + + // return cached response + return response; + } + #endregion + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 523dfbe..e7967d1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Text; using Nwc.XmlRpc; @@ -70,6 +71,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IUserAccountService m_accountService = null; + private ExpiringCache m_memoryCache; + private int m_cacheTimeout = 30; + // Used to track which agents are have dropped from a group chat session // Should be reset per agent, on logon // TODO: move this to Flotsam XmlRpc Service @@ -111,7 +115,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); if ((m_groupsServerURI == null) || @@ -127,7 +131,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); - + + m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); + if (m_cacheTimeout == 0) + { + m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Disabled."); + } + else + { + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); + } // If we got all the config options we need, lets start'er'up @@ -137,7 +150,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -919,50 +932,84 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - string UserService; - UUID SessionID; - GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); - param.Add("requestingAgentID", requestingAgentID.ToString()); - param.Add("RequestingAgentUserService", UserService); - param.Add("RequestingSessionID", SessionID.ToString()); - + XmlRpcResponse resp = null; + string CacheKey = null; + + // Only bother with the cache if it isn't disabled. + if (m_cacheTimeout > 0) + { + if (!function.StartsWith("groups.get")) + { + // Any and all updates cause the cache to clear + m_memoryCache.Clear(); + } + else + { + StringBuilder sb = new StringBuilder(requestingAgentID + function); + foreach (object key in param.Keys) + { + if (param[key] != null) + { + sb.AppendFormat(",{0}:{1}", key.ToString(), param[key].ToString()); + } + } + + CacheKey = sb.ToString(); + m_memoryCache.TryGetValue(CacheKey, out resp); + } - param.Add("ReadKey", m_groupReadKey); - param.Add("WriteKey", m_groupWriteKey); + } + + if( resp == null ) + { + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); - IList parameters = new ArrayList(); - parameters.Add(param); + param.Add("ReadKey", m_groupReadKey); + param.Add("WriteKey", m_groupWriteKey); - ConfigurableKeepAliveXmlRpcRequest req; - req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); - XmlRpcResponse resp = null; + IList parameters = new ArrayList(); + parameters.Add(param); - try - { - resp = req.Send(m_groupsServerURI, 10000); - } - catch (Exception e) - { - + ConfigurableKeepAliveXmlRpcRequest req; + req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); - m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + try { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); - } + resp = req.Send(m_groupsServerURI, 10000); + + if ((m_cacheTimeout > 0) && (CacheKey != null)) + { + m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout)); + } - foreach (string key in param.Keys) + } + catch (Exception e) { - m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", e.ToString()); + + foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) + { + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine); + } + + foreach (string key in param.Keys) + { + m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString()); + } + + Hashtable respData = new Hashtable(); + respData.Add("error", e.ToString()); + return respData; } - - Hashtable respData = new Hashtable(); - respData.Add("error", e.ToString()); - return respData; } if (resp.Value is Hashtable) @@ -976,21 +1023,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return respData; } - m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); if (resp.Value is ArrayList) { ArrayList al = (ArrayList)resp.Value; - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Contains {0} elements", al.Count); foreach (object o in al) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", o.GetType().ToString(), o.ToString()); } } else { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Function returned: {0}", resp.Value.ToString()); } Hashtable error = new Hashtable(); @@ -1000,16 +1047,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void LogRespDataToConsoleError(Hashtable respData) { - m_log.Error("[XMLRPCGROUPDATA]: Error:"); + m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); foreach (string key in respData.Keys) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key); string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); } } -- cgit v1.1 From 5459a90fc6b3864b90a10cd99e4e5a3a0e92d226 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 16 Apr 2010 21:23:01 +0100 Subject: minor: stop irc bridge warning about not attached to regions if it's not been turned on in the first place --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index e664b44..d49a489 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -109,7 +109,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } else { - m_log.WarnFormat("[IRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName); + //m_log.DebugFormat("[IRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName); } } -- cgit v1.1 From cf4673585616e4b45f095ec5837c2554f40b85b3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 16 Apr 2010 21:39:27 +0100 Subject: add a missing initialization of the m_memoryCache in XmlRpcGroupsServicesConnectorModule the lack of this caused me a NullReferenceException when calling some groups methods directly though in principle it would also fail in other situations --- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index e7967d1..79b9a16 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -142,8 +142,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); } - // If we got all the config options we need, lets start'er'up + m_memoryCache = new ExpiringCache(); m_connectorEnabled = true; } } -- cgit v1.1 From 8187fccd258bf0936d3db8663844e07a7b81e9fc Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 5 May 2010 16:12:52 +0100 Subject: Patch from mcortez: Update groups, add ALPHA Siman grid connector for groups Signed-off-by: Melanie --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 274 +++++++++---------- .../Avatar/XmlRpcGroups/GroupsModule.cs | 65 ++--- .../XmlRpcGroups/IGroupsServicesConnector.cs | 6 - .../SimianGroupsServicesConnectorModule.cs | 292 +++++++-------------- .../XmlRpcGroupsServicesConnectorModule.cs | 217 ++++----------- 5 files changed, 312 insertions(+), 542 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 185d44d..00fe5df 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -28,30 +28,41 @@ using System; using System.Collections.Generic; using System.Reflection; + + using log4net; using Mono.Addins; using Nini.Config; + using OpenMetaverse; using OpenMetaverse.StructuredData; + using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; + using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule + public class GroupsMessagingModule : ISharedRegionModule { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_sceneList = new List(); private IMessageTransferModule m_msgTransferModule = null; - private IGroupsServicesConnector m_groupData = null; + private IGroupsModule m_groupsModule = null; + + // TODO: Move this off to the Groups Server + public Dictionary> m_agentsInGroupSession = new Dictionary>(); + public Dictionary> m_agentsDroppedSession = new Dictionary>(); + // Config Options private bool m_groupMessagingEnabled = false; @@ -97,12 +108,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - if (!m_groupMessagingEnabled) - return; - - scene.RegisterModuleInterface(this); + // NoOp } - public void RegionLoaded(Scene scene) { if (!m_groupMessagingEnabled) @@ -110,12 +117,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData = scene.RequestModuleInterface(); + m_groupsModule = scene.RequestModuleInterface(); // No groups module, no groups messaging - if (m_groupData == null) + if (m_groupsModule == null) { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; return; @@ -137,7 +144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - scene.EventManager.OnClientLogin += OnClientLogin; + } public void RemoveRegion(Scene scene) @@ -165,7 +172,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_sceneList.Clear(); - m_groupData = null; + m_groupsModule = null; m_msgTransferModule = null; } @@ -190,84 +197,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - /// - /// Not really needed, but does confirm that the group exists. - /// - public bool StartGroupChatSession(UUID agentID, UUID groupID) - { - if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); - - if (groupInfo != null) - { - return true; - } - else - { - return false; - } - } - - public void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - - foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) - { - if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) - { - // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); - continue; - } - - // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = groupID.Guid; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = im.binaryBucket; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - - msg.fromAgentID = im.fromAgentID; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; - - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) - { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - else - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); - } - } - } - #region SimGridEventHandlers - void OnClientLogin(IClientAPI client) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); - - - } - private void OnNewClient(IClientAPI client) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); @@ -305,46 +236,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); - UUID AgentID = new UUID(msg.fromAgentID); - UUID GroupID = new UUID(msg.imSessionID); - switch (msg.dialog) { case (byte)InstantMessageDialog.SessionAdd: - m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); break; case (byte)InstantMessageDialog.SessionDrop: - m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); + RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); break; case (byte)InstantMessageDialog.SessionSend: - if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) - && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) - ) + if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) + && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) { // Agent not in session and hasn't dropped from session // Add them to the session for now, and Invite them - m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); UUID toAgentID = new UUID(msg.toAgentID); IClientAPI activeClient = GetActiveClient(toAgentID); if (activeClient != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + UUID groupID = new UUID(msg.fromAgentID); + + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); if (groupInfo != null) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); // Force? open the group session dialog??? - // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); IEventQueue eq = activeClient.Scene.RequestModuleInterface(); eq.ChatterboxInvitation( - GroupID + groupID , groupInfo.GroupName , new UUID(msg.fromAgentID) - , msg.message - , new UUID(msg.toAgentID) + , msg.message, new UUID(msg.toAgentID) , msg.fromAgentName , msg.dialog , msg.timestamp @@ -358,7 +285,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ); eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) + new UUID(groupID) , new UUID(msg.fromAgentID) , new UUID(msg.toAgentID) , false //canVoiceChat @@ -368,7 +295,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) + else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. @@ -394,8 +321,56 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - #region ClientEvents + + private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) + { + if (m_agentsInGroupSession.ContainsKey(sessionID)) + { + // If in session remove + if (m_agentsInGroupSession[sessionID].Contains(agentID)) + { + m_agentsInGroupSession[sessionID].Remove(agentID); + } + + // If not in dropped list, add + if (!m_agentsDroppedSession[sessionID].Contains(agentID)) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); + m_agentsDroppedSession[sessionID].Add(agentID); + } + } + } + + private void AddAgentToGroupSession(Guid agentID, Guid sessionID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupSessionTracking(sessionID); + + // If nessesary, remove from dropped list + if (m_agentsDroppedSession[sessionID].Contains(agentID)) + { + m_agentsDroppedSession[sessionID].Remove(agentID); + } + + // If nessesary, add to in session list + if (!m_agentsInGroupSession[sessionID].Contains(agentID)) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); + m_agentsInGroupSession[sessionID].Add(agentID); + } + } + + private void CreateGroupSessionTracking(Guid sessionID) + { + if (!m_agentsInGroupSession.ContainsKey(sessionID)) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); + m_agentsInGroupSession.Add(sessionID, new List()); + m_agentsDroppedSession.Add(sessionID, new List()); + } + } + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -408,23 +383,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { - if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); + UUID groupID = new UUID(im.toAgentID); - UUID GroupID = new UUID(im.imSessionID); - UUID AgentID = new UUID(im.fromAgentID); - - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); - + GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); if (groupInfo != null) { - m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); + + AddAgentToGroupSession(im.fromAgentID, im.imSessionID); - ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); queue.ChatterBoxSessionAgentListUpdates( - GroupID - , AgentID + new UUID(groupID) + , new UUID(im.fromAgentID) , new UUID(im.toAgentID) , false //canVoiceChat , false //isModerator @@ -436,21 +409,64 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) { - UUID GroupID = new UUID(im.imSessionID); - UUID AgentID = new UUID(im.fromAgentID); - - if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); + UUID groupID = new UUID(im.toAgentID); - //If this agent is sending a message, then they want to be in the session - m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); - SendMessageToGroup(im, GroupID); + SendMessageToGroup(im, groupID); } } #endregion + private void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) + { + if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) + { + // Don't deliver messages to people who have dropped this session + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; + } + + // Copy Message + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = im.imSessionID; + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.offline = im.offline; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = im.binaryBucket; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + + // Updat Pertinate fields to make it a "group message" + msg.fromAgentID = groupID.Guid; + msg.fromGroup = true; + + msg.toAgentID = member.AgentID.Guid; + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg); + } + } + } + void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -502,8 +518,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private IClientAPI GetActiveClient(UUID agentID) { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); - IClientAPI child = null; // Try root avatar first @@ -515,26 +529,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); return user.ControllingClient; } else { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); child = user.ControllingClient; } } } // If we didn't find a root, then just return whichever child we found, or null if none - if (child == null) - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); - } - else - { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); - } return child; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 56c0d98..6b942cb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -176,6 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + // The InstantMessageModule itself doesn't do this, // so lets see if things explode if we don't do it // scene.EventManager.OnClientClosed += OnClientClosed; @@ -509,7 +510,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { - UUID groupID = new UUID(im.imSessionID); + UUID groupID = new UUID(im.fromAgentID); ejectee.SendAgentDropGroup(groupID); } } @@ -600,14 +601,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); - } + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); + } } return data; @@ -627,14 +628,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); - } + List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); + } } return data; } @@ -1143,11 +1144,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap llDataStruct = new OSDMap(3); llDataStruct.Add("AgentData", AgentData); llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); - - if (m_debugEnabled) - { - m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); + llDataStruct.Add("NewGroupData", NewGroupData); + + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); } IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); @@ -1307,16 +1308,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // } - #endregion - - private UUID GetRequestingAgentID(IClientAPI client) - { - UUID requestingAgentID = UUID.Zero; - if (client != null) - { - requestingAgentID = client.AgentId; - } - return requestingAgentID; + #endregion + + private UUID GetRequestingAgentID(IClientAPI client) + { + UUID requestingAgentID = UUID.Zero; + if (client != null) + { + requestingAgentID = client.AgentId; + } + return requestingAgentID; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index a046e09..6487967 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -71,12 +71,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); - - void ResetAgentGroupChatSessions(UUID agentID); - bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); - bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); - void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); - void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID); } public class GroupInviteInfo diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 9363205..590753e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -55,9 +55,6 @@ using OpenSim.Services.Interfaces; * UserID -> Group -> ActiveGroup * + GroupID * - * UserID -> GroupSessionDropped -> GroupID - * UserID -> GroupSessionInvited -> GroupID - * * UserID -> GroupMember -> GroupID * + SelectedRoleID [UUID] * + AcceptNotices [bool] @@ -66,7 +63,6 @@ using OpenSim.Services.Interfaces; * * UserID -> GroupRole[GroupID] -> RoleID * - * * GroupID -> Group -> GroupName * + Charter * + ShowInList @@ -163,13 +159,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_groupsServerURI = string.Empty; + private string m_serviceURL = string.Empty; private bool m_debugEnabled = false; - private ExpiringCache m_memoryCache; - private int m_cacheTimeout = 30; - // private IUserAccountService m_accountService = null; @@ -206,33 +199,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); - if ((m_groupsServerURI == null) || - (m_groupsServerURI == string.Empty)) + m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); + if ((m_serviceURL == null) || + (m_serviceURL == string.Empty)) { - m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid Simian Server URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } - - m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); - if (m_cacheTimeout == 0) - { - m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Disabled."); - } - else - { - m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout); - } - - - - m_memoryCache = new ExpiringCache(); - - // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; @@ -243,7 +220,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { - m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -311,8 +288,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) { - AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); - AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); @@ -436,7 +413,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } else if ((groupName != null) && (groupName != string.Empty)) - { + { if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) { return null; @@ -445,7 +422,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord GroupInfo = new GroupRecord(); - GroupInfo.GroupID = groupID; + GroupInfo.GroupID = groupID; GroupInfo.GroupName = groupName; GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); @@ -676,7 +653,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = CachedPostRequest(requestArgs); + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)response["Entries"]; @@ -774,9 +751,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) { GroupID = UserActiveGroup["GroupID"].AsUUID(); - } - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); } @@ -804,24 +781,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List Roles = new List(); - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - Dictionary MemberRoles; - if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) - { - foreach (KeyValuePair kvp in MemberRoles) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = UUID.Parse(kvp.Key); - data.Name = GroupRoles[kvp.Key]["Name"].AsString(); - data.Description = GroupRoles[kvp.Key]["Description"].AsString(); - data.Title = GroupRoles[kvp.Key]["Title"].AsString(); - data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); - - Roles.Add(data); - } - } + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } } return Roles; } @@ -935,8 +912,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) { - GroupRoleMembersData data = new GroupRoleMembersData(); - + GroupRoleMembersData data = new GroupRoleMembersData(); + data.MemberID = GroupRoleMember.Key; data.RoleID = UUID.Parse(Role.Key); @@ -1021,52 +998,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } #endregion - #region GroupSessionTracking - - public void ResetAgentGroupChatSessions(UUID agentID) - { - Dictionary agentSessions; - - if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) - { - foreach (string GroupID in agentSessions.Keys) - { - SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); - } - } - - if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) - { - foreach (string GroupID in agentSessions.Keys) - { - SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); - } - } - } - - public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) - { - OSDMap session; - return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); - } - - public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) - { - SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); - } - - public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); - } - - public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - OSDMap session; - return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); - } - - #endregion private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) { @@ -1105,7 +1036,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = CachedPostRequest(RequestArgs); + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean()) { return true; @@ -1132,23 +1063,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = CachedPostRequest(RequestArgs); + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1172,23 +1103,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = CachedPostRequest(RequestArgs); + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - ownerID = entryMap["OwnerID"].AsUUID(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1213,7 +1144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = CachedPostRequest(RequestArgs); + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1221,16 +1152,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { OSDMap entryMap = entryArray[0] as OSDMap; key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } } else { @@ -1253,20 +1184,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = CachedPostRequest(requestArgs); + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); } - if(maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } return true; @@ -1291,21 +1222,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = CachedPostRequest(requestArgs); + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { + { if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if (maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } return true; } else @@ -1329,7 +1260,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = CachedPostRequest(requestArgs); + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); if (response["Success"].AsBoolean()) { return true; @@ -1341,49 +1272,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } #endregion - - #region CheesyCache - OSDMap CachedPostRequest(NameValueCollection requestArgs) - { - // Immediately forward the request if the cache is disabled. - if (m_cacheTimeout == 0) - { - return WebUtil.PostToService(m_groupsServerURI, requestArgs); - } - - // Check if this is an update or a request - if ( requestArgs["RequestMethod"] == "RemoveGeneric" - || requestArgs["RequestMethod"] == "AddGeneric" - ) - - { - // Any and all updates cause the cache to clear - m_memoryCache.Clear(); - - // Send update to server, return the response without caching it - return WebUtil.PostToService(m_groupsServerURI, requestArgs); - - } - - // If we're not doing an update, we must be requesting data - - // Create the cache key for the request and see if we have it cached - string CacheKey = WebUtil.BuildQueryString(requestArgs); - OSDMap response = null; - if (!m_memoryCache.TryGetValue(CacheKey, out response)) - { - // if it wasn't in the cache, pass the request to the Simian Grid Services - response = WebUtil.PostToService(m_groupsServerURI, requestArgs); - - // and cache the response - m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); - } - - // return cached response - return response; - } - #endregion - } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 79b9a16..ab343c8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -29,7 +29,6 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; -using System.Text; using Nwc.XmlRpc; @@ -62,7 +61,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_groupsServerURI = string.Empty; + private string m_serviceURL = string.Empty; private bool m_disableKeepAlive = false; @@ -70,17 +69,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupWriteKey = string.Empty; private IUserAccountService m_accountService = null; - - private ExpiringCache m_memoryCache; - private int m_cacheTimeout = 30; - - // Used to track which agents are have dropped from a group chat session - // Should be reset per agent, on logon - // TODO: move this to Flotsam XmlRpc Service - // SessionID, List - private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); - private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); - + #region IRegionModuleBase Members @@ -115,13 +104,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); - if ((m_groupsServerURI == null) || - (m_groupsServerURI == string.Empty)) + m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); + if ((m_serviceURL == null) || + (m_serviceURL == string.Empty)) { - m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } @@ -131,26 +120,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); + - m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); - if (m_cacheTimeout == 0) - { - m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Disabled."); - } - else - { - m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); - } // If we got all the config options we need, lets start'er'up - m_memoryCache = new ExpiringCache(); m_connectorEnabled = true; } } public void Close() { - m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -776,69 +756,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } - - - - #endregion - - #region GroupSessionTracking - - public void ResetAgentGroupChatSessions(UUID agentID) - { - foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) - { - agentList.Remove(agentID); - } - } - - public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - // If we're tracking this group, and we can find them in the tracking, then they've been invited - return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) - && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); - } - - public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) - { - // If we're tracking drops for this group, - // and we find them, well... then they've dropped - return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) - && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); - } - - public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) - { - if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) - { - // If not in dropped list, add - if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) - { - m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); - } - } - } - - public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupChatSessionTracking(groupID); - - // If nessesary, remove from dropped list - if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) - { - m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); - } - } - - private void CreateGroupChatSessionTracking(UUID groupID) - { - if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) - { - m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); - m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); - } - - } #endregion #region XmlRpcHashtableMarshalling @@ -932,84 +849,50 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - XmlRpcResponse resp = null; - string CacheKey = null; - - // Only bother with the cache if it isn't disabled. - if (m_cacheTimeout > 0) - { - if (!function.StartsWith("groups.get")) - { - // Any and all updates cause the cache to clear - m_memoryCache.Clear(); - } - else - { - StringBuilder sb = new StringBuilder(requestingAgentID + function); - foreach (object key in param.Keys) - { - if (param[key] != null) - { - sb.AppendFormat(",{0}:{1}", key.ToString(), param[key].ToString()); - } - } - - CacheKey = sb.ToString(); - m_memoryCache.TryGetValue(CacheKey, out resp); - } - - } + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); - if( resp == null ) - { - string UserService; - UUID SessionID; - GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); - param.Add("requestingAgentID", requestingAgentID.ToString()); - param.Add("RequestingAgentUserService", UserService); - param.Add("RequestingSessionID", SessionID.ToString()); + param.Add("ReadKey", m_groupReadKey); + param.Add("WriteKey", m_groupWriteKey); - param.Add("ReadKey", m_groupReadKey); - param.Add("WriteKey", m_groupWriteKey); + IList parameters = new ArrayList(); + parameters.Add(param); - IList parameters = new ArrayList(); - parameters.Add(param); - - ConfigurableKeepAliveXmlRpcRequest req; - req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); + ConfigurableKeepAliveXmlRpcRequest req; + req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); + XmlRpcResponse resp = null; - try - { - resp = req.Send(m_groupsServerURI, 10000); + try + { + resp = req.Send(m_serviceURL, 10000); + } + catch (Exception e) + { + - if ((m_cacheTimeout > 0) && (CacheKey != null)) - { - m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout)); - } + m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); + foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + { + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); } - catch (Exception e) + + foreach (string key in param.Keys) { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", e.ToString()); - - foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) - { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine); - } - - foreach (string key in param.Keys) - { - m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString()); - } - - Hashtable respData = new Hashtable(); - respData.Add("error", e.ToString()); - return respData; + m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); } + + Hashtable respData = new Hashtable(); + respData.Add("error", e.ToString()); + return respData; } if (resp.Value is Hashtable) @@ -1023,21 +906,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return respData; } - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); if (resp.Value is ArrayList) { ArrayList al = (ArrayList)resp.Value; - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Contains {0} elements", al.Count); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); foreach (object o in al) { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", o.GetType().ToString(), o.ToString()); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); } } else { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Function returned: {0}", resp.Value.ToString()); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); } Hashtable error = new Hashtable(); @@ -1047,16 +930,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void LogRespDataToConsoleError(Hashtable respData) { - m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); + m_log.Error("[XMLRPCGROUPDATA]: Error:"); foreach (string key in respData.Keys) { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); + m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); } } @@ -1065,8 +948,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Group Request Tokens are an attempt to allow the groups service to authenticate - /// requests. - /// TODO: This broke after the big grid refactor, either find a better way, or discard this + /// requests. Currently uses UserService, AgentID, and SessionID + /// TODO: Find a better way to do this. /// /// /// -- cgit v1.1 From ebc3726d52c772962cfa551721168079d5d563d2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 5 May 2010 16:54:48 -0700 Subject: Added copying of Viewer field to the agent circuit data that is being passed on TPs and crossings. (XmlRpcGroups files want to be committed too) --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 62 ++++----- .../SimianGroupsServicesConnectorModule.cs | 150 ++++++++++----------- 2 files changed, 106 insertions(+), 106 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6b942cb..b2b8110 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -601,14 +601,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); - } + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); + } } return data; @@ -628,14 +628,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); - } + List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); + } } return data; } @@ -1144,11 +1144,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap llDataStruct = new OSDMap(3); llDataStruct.Add("AgentData", AgentData); llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); - - if (m_debugEnabled) - { - m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); + llDataStruct.Add("NewGroupData", NewGroupData); + + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); } IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); @@ -1308,16 +1308,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // } - #endregion - - private UUID GetRequestingAgentID(IClientAPI client) - { - UUID requestingAgentID = UUID.Zero; - if (client != null) - { - requestingAgentID = client.AgentId; - } - return requestingAgentID; + #endregion + + private UUID GetRequestingAgentID(IClientAPI client) + { + UUID requestingAgentID = UUID.Zero; + if (client != null) + { + requestingAgentID = client.AgentId; + } + return requestingAgentID; } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 590753e..bc05b0f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -288,8 +288,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) { - AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); - AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); @@ -413,7 +413,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } else if ((groupName != null) && (groupName != string.Empty)) - { + { if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) { return null; @@ -422,7 +422,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupRecord GroupInfo = new GroupRecord(); - GroupInfo.GroupID = groupID; + GroupInfo.GroupID = groupID; GroupInfo.GroupName = groupName; GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); @@ -751,9 +751,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) { GroupID = UserActiveGroup["GroupID"].AsUUID(); - } - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); } @@ -781,24 +781,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List Roles = new List(); - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - Dictionary MemberRoles; - if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) - { - foreach (KeyValuePair kvp in MemberRoles) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = UUID.Parse(kvp.Key); - data.Name = GroupRoles[kvp.Key]["Name"].AsString(); - data.Description = GroupRoles[kvp.Key]["Description"].AsString(); - data.Title = GroupRoles[kvp.Key]["Title"].AsString(); - data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); - - Roles.Add(data); - } - } + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } } return Roles; } @@ -912,8 +912,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) { - GroupRoleMembersData data = new GroupRoleMembersData(); - + GroupRoleMembersData data = new GroupRoleMembersData(); + data.MemberID = GroupRoleMember.Key; data.RoleID = UUID.Parse(Role.Key); @@ -1066,20 +1066,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1106,20 +1106,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - ownerID = entryMap["OwnerID"].AsUUID(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } } else @@ -1152,16 +1152,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { OSDMap entryMap = entryArray[0] as OSDMap; key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } } else { @@ -1191,13 +1191,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); } - if(maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } return true; @@ -1229,14 +1229,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDArray entryArray = (OSDArray)response["Entries"]; foreach (OSDMap entryMap in entryArray) - { + { if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if (maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } return true; } else -- cgit v1.1 From 9ecebcdf13ddb29ae1aeec0d080371b7d0696e4d Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 6 May 2010 16:38:23 +0100 Subject: Revert "Patch from mcortez: Update groups, add ALPHA Siman grid connector for groups" Causes an exception within HttpServer, headers have already been sent. This reverts commit 8187fccd258bf0936d3db8663844e07a7b81e9fc. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 274 ++++++++++----------- .../Avatar/XmlRpcGroups/GroupsModule.cs | 3 +- .../XmlRpcGroups/IGroupsServicesConnector.cs | 6 + .../SimianGroupsServicesConnectorModule.cs | 142 +++++++++-- .../XmlRpcGroupsServicesConnectorModule.cs | 217 ++++++++++++---- 5 files changed, 436 insertions(+), 206 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 00fe5df..185d44d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -28,41 +28,30 @@ using System; using System.Collections.Generic; using System.Reflection; - - using log4net; using Mono.Addins; using Nini.Config; - using OpenMetaverse; using OpenMetaverse.StructuredData; - using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; - using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GroupsMessagingModule : ISharedRegionModule + public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_sceneList = new List(); private IMessageTransferModule m_msgTransferModule = null; - private IGroupsModule m_groupsModule = null; - - // TODO: Move this off to the Groups Server - public Dictionary> m_agentsInGroupSession = new Dictionary>(); - public Dictionary> m_agentsDroppedSession = new Dictionary>(); - + private IGroupsServicesConnector m_groupData = null; // Config Options private bool m_groupMessagingEnabled = false; @@ -108,8 +97,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - // NoOp + if (!m_groupMessagingEnabled) + return; + + scene.RegisterModuleInterface(this); } + public void RegionLoaded(Scene scene) { if (!m_groupMessagingEnabled) @@ -117,12 +110,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupsModule = scene.RequestModuleInterface(); + m_groupData = scene.RequestModuleInterface(); // No groups module, no groups messaging - if (m_groupsModule == null) + if (m_groupData == null) { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, GroupsMessagingModule is now disabled."); + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; return; @@ -144,7 +137,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - + scene.EventManager.OnClientLogin += OnClientLogin; } public void RemoveRegion(Scene scene) @@ -172,7 +165,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_sceneList.Clear(); - m_groupsModule = null; + m_groupData = null; m_msgTransferModule = null; } @@ -197,8 +190,84 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + /// + /// Not really needed, but does confirm that the group exists. + /// + public bool StartGroupChatSession(UUID agentID, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); + + if (groupInfo != null) + { + return true; + } + else + { + return false; + } + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) + { + if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) + { + // Don't deliver messages to people who have dropped this session + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; + } + + // Copy Message + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = groupID.Guid; + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.offline = im.offline; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = im.binaryBucket; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + + msg.fromAgentID = im.fromAgentID; + msg.fromGroup = true; + + msg.toAgentID = member.AgentID.Guid; + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg); + } + } + } + #region SimGridEventHandlers + void OnClientLogin(IClientAPI client) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); + + + } + private void OnNewClient(IClientAPI client) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); @@ -236,42 +305,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + UUID AgentID = new UUID(msg.fromAgentID); + UUID GroupID = new UUID(msg.imSessionID); + switch (msg.dialog) { case (byte)InstantMessageDialog.SessionAdd: - AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionDrop: - RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionSend: - if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) - && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) + && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) + ) { // Agent not in session and hasn't dropped from session // Add them to the session for now, and Invite them - AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); IClientAPI activeClient = GetActiveClient(toAgentID); if (activeClient != null) { - UUID groupID = new UUID(msg.fromAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); // Force? open the group session dialog??? + // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); IEventQueue eq = activeClient.Scene.RequestModuleInterface(); eq.ChatterboxInvitation( - groupID + GroupID , groupInfo.GroupName , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) + , msg.message + , new UUID(msg.toAgentID) , msg.fromAgentName , msg.dialog , msg.timestamp @@ -285,7 +358,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ); eq.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) + new UUID(GroupID) , new UUID(msg.fromAgentID) , new UUID(msg.toAgentID) , false //canVoiceChat @@ -295,7 +368,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. @@ -321,56 +394,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - #region ClientEvents - - private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) - { - if (m_agentsInGroupSession.ContainsKey(sessionID)) - { - // If in session remove - if (m_agentsInGroupSession[sessionID].Contains(agentID)) - { - m_agentsInGroupSession[sessionID].Remove(agentID); - } - - // If not in dropped list, add - if (!m_agentsDroppedSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); - m_agentsDroppedSession[sessionID].Add(agentID); - } - } - } - - private void AddAgentToGroupSession(Guid agentID, Guid sessionID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupSessionTracking(sessionID); - - // If nessesary, remove from dropped list - if (m_agentsDroppedSession[sessionID].Contains(agentID)) - { - m_agentsDroppedSession[sessionID].Remove(agentID); - } - - // If nessesary, add to in session list - if (!m_agentsInGroupSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); - m_agentsInGroupSession[sessionID].Add(agentID); - } - } - - private void CreateGroupSessionTracking(Guid sessionID) - { - if (!m_agentsInGroupSession.ContainsKey(sessionID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); - m_agentsInGroupSession.Add(sessionID, new List()); - m_agentsDroppedSession.Add(sessionID, new List()); - } - } + #region ClientEvents private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -383,21 +408,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { - UUID groupID = new UUID(im.toAgentID); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + if (groupInfo != null) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); - - AddAgentToGroupSession(im.fromAgentID, im.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); queue.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(im.fromAgentID) + GroupID + , AgentID , new UUID(im.toAgentID) , false //canVoiceChat , false //isModerator @@ -409,64 +436,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) { - UUID groupID = new UUID(im.toAgentID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + //If this agent is sending a message, then they want to be in the session + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - SendMessageToGroup(im, groupID); + SendMessageToGroup(im, GroupID); } } #endregion - private void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) - { - if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) - { - // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); - continue; - } - - // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = im.binaryBucket; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - - // Updat Pertinate fields to make it a "group message" - msg.fromAgentID = groupID.Guid; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; - - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) - { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - else - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); - } - } - } - void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -518,6 +502,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private IClientAPI GetActiveClient(UUID agentID) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); + IClientAPI child = null; // Try root avatar first @@ -529,16 +515,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); return user.ControllingClient; } else { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); child = user.ControllingClient; } } } // If we didn't find a root, then just return whichever child we found, or null if none + if (child == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); + } + else + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); + } return child; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b2b8110..56c0d98 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -176,7 +176,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - // The InstantMessageModule itself doesn't do this, // so lets see if things explode if we don't do it // scene.EventManager.OnClientClosed += OnClientClosed; @@ -510,7 +509,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { - UUID groupID = new UUID(im.fromAgentID); + UUID groupID = new UUID(im.imSessionID); ejectee.SendAgentDropGroup(groupID); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 6487967..a046e09 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -71,6 +71,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); + + void ResetAgentGroupChatSessions(UUID agentID); + bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); + bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); + void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); + void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID); } public class GroupInviteInfo diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index bc05b0f..9363205 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -55,6 +55,9 @@ using OpenSim.Services.Interfaces; * UserID -> Group -> ActiveGroup * + GroupID * + * UserID -> GroupSessionDropped -> GroupID + * UserID -> GroupSessionInvited -> GroupID + * * UserID -> GroupMember -> GroupID * + SelectedRoleID [UUID] * + AcceptNotices [bool] @@ -63,6 +66,7 @@ using OpenSim.Services.Interfaces; * * UserID -> GroupRole[GroupID] -> RoleID * + * * GroupID -> Group -> GroupName * + Charter * + ShowInList @@ -159,10 +163,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_debugEnabled = false; + private ExpiringCache m_memoryCache; + private int m_cacheTimeout = 30; + // private IUserAccountService m_accountService = null; @@ -199,17 +206,33 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) { - m_log.ErrorFormat("Please specify a valid Simian Server URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } + + m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); + if (m_cacheTimeout == 0) + { + m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Disabled."); + } + else + { + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout); + } + + + + m_memoryCache = new ExpiringCache(); + + // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; @@ -220,7 +243,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -653,7 +676,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)response["Entries"]; @@ -998,6 +1021,52 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } #endregion + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + Dictionary agentSessions; + + if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); + } + } + + if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); + } + } + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + #endregion private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) { @@ -1036,7 +1105,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean()) { return true; @@ -1063,7 +1132,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1103,7 +1172,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1144,7 +1213,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1184,7 +1253,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); @@ -1222,7 +1291,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); @@ -1260,7 +1329,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean()) { return true; @@ -1272,6 +1341,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } #endregion + + #region CheesyCache + OSDMap CachedPostRequest(NameValueCollection requestArgs) + { + // Immediately forward the request if the cache is disabled. + if (m_cacheTimeout == 0) + { + return WebUtil.PostToService(m_groupsServerURI, requestArgs); + } + + // Check if this is an update or a request + if ( requestArgs["RequestMethod"] == "RemoveGeneric" + || requestArgs["RequestMethod"] == "AddGeneric" + ) + + { + // Any and all updates cause the cache to clear + m_memoryCache.Clear(); + + // Send update to server, return the response without caching it + return WebUtil.PostToService(m_groupsServerURI, requestArgs); + + } + + // If we're not doing an update, we must be requesting data + + // Create the cache key for the request and see if we have it cached + string CacheKey = WebUtil.BuildQueryString(requestArgs); + OSDMap response = null; + if (!m_memoryCache.TryGetValue(CacheKey, out response)) + { + // if it wasn't in the cache, pass the request to the Simian Grid Services + response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + + // and cache the response + m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + } + + // return cached response + return response; + } + #endregion + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index ab343c8..79b9a16 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Text; using Nwc.XmlRpc; @@ -61,7 +62,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_disableKeepAlive = false; @@ -69,7 +70,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupWriteKey = string.Empty; private IUserAccountService m_accountService = null; - + + private ExpiringCache m_memoryCache; + private int m_cacheTimeout = 30; + + // Used to track which agents are have dropped from a group chat session + // Should be reset per agent, on logon + // TODO: move this to Flotsam XmlRpc Service + // SessionID, List + private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); + private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); + #region IRegionModuleBase Members @@ -104,13 +115,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) { - m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } @@ -120,17 +131,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); - + m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); + if (m_cacheTimeout == 0) + { + m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Disabled."); + } + else + { + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); + } // If we got all the config options we need, lets start'er'up + m_memoryCache = new ExpiringCache(); m_connectorEnabled = true; } } public void Close() { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -756,6 +776,69 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } + + + + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) + { + agentList.Remove(agentID); + } + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking this group, and we can find them in the tracking, then they've been invited + return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) + && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking drops for this group, + // and we find them, well... then they've dropped + return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) + && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + // If not in dropped list, add + if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); + } + } + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupChatSessionTracking(groupID); + + // If nessesary, remove from dropped list + if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); + } + } + + private void CreateGroupChatSessionTracking(UUID groupID) + { + if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); + m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); + } + + } #endregion #region XmlRpcHashtableMarshalling @@ -849,50 +932,84 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - string UserService; - UUID SessionID; - GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); - param.Add("requestingAgentID", requestingAgentID.ToString()); - param.Add("RequestingAgentUserService", UserService); - param.Add("RequestingSessionID", SessionID.ToString()); - + XmlRpcResponse resp = null; + string CacheKey = null; + + // Only bother with the cache if it isn't disabled. + if (m_cacheTimeout > 0) + { + if (!function.StartsWith("groups.get")) + { + // Any and all updates cause the cache to clear + m_memoryCache.Clear(); + } + else + { + StringBuilder sb = new StringBuilder(requestingAgentID + function); + foreach (object key in param.Keys) + { + if (param[key] != null) + { + sb.AppendFormat(",{0}:{1}", key.ToString(), param[key].ToString()); + } + } + + CacheKey = sb.ToString(); + m_memoryCache.TryGetValue(CacheKey, out resp); + } - param.Add("ReadKey", m_groupReadKey); - param.Add("WriteKey", m_groupWriteKey); + } + + if( resp == null ) + { + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); - IList parameters = new ArrayList(); - parameters.Add(param); + param.Add("ReadKey", m_groupReadKey); + param.Add("WriteKey", m_groupWriteKey); - ConfigurableKeepAliveXmlRpcRequest req; - req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); - XmlRpcResponse resp = null; + IList parameters = new ArrayList(); + parameters.Add(param); - try - { - resp = req.Send(m_serviceURL, 10000); - } - catch (Exception e) - { - + ConfigurableKeepAliveXmlRpcRequest req; + req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); - m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + try { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); - } + resp = req.Send(m_groupsServerURI, 10000); - foreach (string key in param.Keys) + if ((m_cacheTimeout > 0) && (CacheKey != null)) + { + m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout)); + } + + } + catch (Exception e) { - m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", e.ToString()); + + foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) + { + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine); + } + + foreach (string key in param.Keys) + { + m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString()); + } + + Hashtable respData = new Hashtable(); + respData.Add("error", e.ToString()); + return respData; } - - Hashtable respData = new Hashtable(); - respData.Add("error", e.ToString()); - return respData; } if (resp.Value is Hashtable) @@ -906,21 +1023,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return respData; } - m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); if (resp.Value is ArrayList) { ArrayList al = (ArrayList)resp.Value; - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Contains {0} elements", al.Count); foreach (object o in al) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", o.GetType().ToString(), o.ToString()); } } else { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Function returned: {0}", resp.Value.ToString()); } Hashtable error = new Hashtable(); @@ -930,16 +1047,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void LogRespDataToConsoleError(Hashtable respData) { - m_log.Error("[XMLRPCGROUPDATA]: Error:"); + m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); foreach (string key in respData.Keys) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key); string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); } } @@ -948,8 +1065,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Group Request Tokens are an attempt to allow the groups service to authenticate - /// requests. Currently uses UserService, AgentID, and SessionID - /// TODO: Find a better way to do this. + /// requests. + /// TODO: This broke after the big grid refactor, either find a better way, or discard this /// /// /// -- cgit v1.1 From e15f6905a53d686e3de9c2e16e842f3b735c3685 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 2 Jul 2010 06:20:36 +0200 Subject: Clean up IMoneyModule and adjust the other modules to the changes --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 56c0d98..3f15b69 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -722,11 +722,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (money != null) { // do the transaction, that is if the agent has got sufficient funds - if (!money.GroupCreationCovered(remoteClient)) { + if (!money.AmountCovered(remoteClient, money.GroupCreationCharge)) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); return UUID.Zero; } - money.ApplyGroupCreationCharge(GetRequestingAgentID(remoteClient)); + money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); } UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); -- cgit v1.1 From a8c0b131f9aa62d4b6260fd37f89014e55b457cf Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 17 Aug 2010 13:50:04 -0700 Subject: * Changed a few OSD.FromBinary() calls to the more accurate OSD.FromULong() to fix the build --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 3f15b69..2969503 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1129,7 +1129,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap NewGroupDataMap = new OSDMap(1); GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); - GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); + GroupDataMap.Add("GroupPowers", OSD.FromULong(membership.GroupPowers)); GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); -- cgit v1.1 From f1f0bc23f4501ba99035283d3407ddad2b21b785 Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Sun, 12 Sep 2010 13:43:49 -0400 Subject: Formatting cleanup. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- .../SimianGroupsServicesConnectorModule.cs | 39 ++++++++++------------ .../XmlRpcGroupsServicesConnectorModule.cs | 4 +-- 3 files changed, 21 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 2969503..6f044e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -962,7 +962,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((groupInfo == null) || (account == null)) { return; - } + } // Send Message to Ejectee GridInstantMessage msg = new GridInstantMessage(); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 9363205..0d265f2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -91,11 +91,11 @@ using OpenSim.Services.Interfaces; * + RoleID * * GroupID -> GroupNotice -> NoticeID - * + TimeStamp [uint] - * + FromName [string] - * + Subject [string] - * + Message [string] - * + BinaryBucket [byte[]] + * + TimeStamp [uint] + * + FromName [string] + * + Subject [string] + * + Message [string] + * + BinaryBucket [byte[]] * * */ @@ -309,7 +309,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID); GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers); - if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) + if (SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) { AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); @@ -334,7 +334,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string GroupName; OSDMap GroupInfoMap; - if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) ) + if (SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap)) { GroupInfoMap["Charter"] = OSD.FromString(charter); GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); @@ -379,7 +379,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string GroupRoleMemberType = "GroupRole" + groupID.ToString(); if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers)) { - foreach(UUID UserID in GroupRoleMembers.Keys) + foreach (UUID UserID in GroupRoleMembers.Keys) { EnsureRoleNotSelectedByMember(groupID, roleID, UserID); @@ -724,7 +724,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } OSDMap UserGroupMemberInfo; - if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) ) + if (SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo)) { data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); @@ -736,7 +736,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // OSDMap GroupRoleInfo; - if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) ) + if (SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo)) { data.GroupTitle = GroupRoleInfo["Title"].AsString(); data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); @@ -748,7 +748,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // OSDMap GroupInfo; string GroupName; - if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) ) + if (SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo)) { data.GroupID = groupID; data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); @@ -928,12 +928,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Dictionary GroupRoles; if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) { - foreach( KeyValuePair Role in GroupRoles ) + foreach (KeyValuePair Role in GroupRoles) { Dictionary GroupRoleMembers; - if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) ) + if (SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers)) { - foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) + foreach (KeyValuePair GroupRoleMember in GroupRoleMembers) { GroupRoleMembersData data = new GroupRoleMembersData(); @@ -1264,7 +1264,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); } - if(maps.Count == 0) + if (maps.Count == 0) { if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); } @@ -1352,17 +1352,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // Check if this is an update or a request - if ( requestArgs["RequestMethod"] == "RemoveGeneric" - || requestArgs["RequestMethod"] == "AddGeneric" - ) - + if (requestArgs["RequestMethod"] == "RemoveGeneric" + || requestArgs["RequestMethod"] == "AddGeneric") { // Any and all updates cause the cache to clear m_memoryCache.Clear(); // Send update to server, return the response without caching it return WebUtil.PostToService(m_groupsServerURI, requestArgs); - } // If we're not doing an update, we must be requesting data @@ -1372,7 +1369,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap response = null; if (!m_memoryCache.TryGetValue(CacheKey, out response)) { - // if it wasn't in the cache, pass the request to the Simian Grid Services + // if it wasn't in the cache, pass the request to the Simian Grid Services response = WebUtil.PostToService(m_groupsServerURI, requestArgs); // and cache the response diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 79b9a16..a88c5e2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -960,7 +960,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - if( resp == null ) + if (resp == null) { string UserService; UUID SessionID; @@ -1065,7 +1065,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Group Request Tokens are an attempt to allow the groups service to authenticate - /// requests. + /// requests. /// TODO: This broke after the big grid refactor, either find a better way, or discard this /// /// -- cgit v1.1 From b1ab3ea5d96c664c387504ad5d4ba5d9464ae3f1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 17 Sep 2010 23:48:44 +0100 Subject: For all Flotasm group module XMLRPC calls, correct parameter requestingAgentID to RequestingAgentID This was stopping the get group member roles call from working, and may have affected other things --- .../XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index a88c5e2..5fabbb0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -957,7 +957,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups CacheKey = sb.ToString(); m_memoryCache.TryGetValue(CacheKey, out resp); } - } if (resp == null) @@ -965,22 +964,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string UserService; UUID SessionID; GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); - param.Add("requestingAgentID", requestingAgentID.ToString()); + + param.Add("RequestingAgentID", requestingAgentID.ToString()); param.Add("RequestingAgentUserService", UserService); param.Add("RequestingSessionID", SessionID.ToString()); - - param.Add("ReadKey", m_groupReadKey); param.Add("WriteKey", m_groupWriteKey); - IList parameters = new ArrayList(); parameters.Add(param); ConfigurableKeepAliveXmlRpcRequest req; req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); - try { resp = req.Send(m_groupsServerURI, 10000); @@ -989,7 +985,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout)); } - } catch (Exception e) { @@ -1058,10 +1053,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); } - } } - /// /// Group Request Tokens are an attempt to allow the groups service to authenticate -- cgit v1.1 From b9bef50852cecab6e6fba75d44d4ee2306072299 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Oct 2010 23:21:34 +0100 Subject: Display more information when xmlrpcgroupsserver comms fails Improve debugging messages --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 17 +++++++++-------- .../XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 10 +++++----- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 185d44d..d178e18 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -212,12 +212,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { + List groupMembers = m_groupData.GetGroupMembers(UUID.Zero, groupID); + if (m_debugEnabled) - m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - - foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) - { + m_log.DebugFormat( + "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} members", + groupID, groupMembers.Count); + + foreach (GroupMembersData member in groupMembers) + { if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session @@ -263,9 +266,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void OnClientLogin(IClientAPI client) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); - - + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); } private void OnNewClient(IClientAPI client) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 5fabbb0..2631ac1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -641,11 +641,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - } - - public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); @@ -988,8 +985,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } catch (Exception e) { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", e.ToString()); + m_log.ErrorFormat( + "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}", + function, m_groupsServerURI); + + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace); foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) { -- cgit v1.1 From 478b44f231841aafb2ea19d2b21d0d3826456ad7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Oct 2010 01:54:51 +0100 Subject: Pass in requesting agent ID when GetGroupMembers is called in the XMLRPC groups module This allows the groups xmlrpc server to act appropriately if the requesting agent has permission to see all group members Not sure why this wasn't being done before... --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 4 ++-- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index d178e18..25dba7f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -212,11 +212,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { - List groupMembers = m_groupData.GetGroupMembers(UUID.Zero, groupID); + List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); if (m_debugEnabled) m_log.DebugFormat( - "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} members", + "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", groupID, groupMembers.Count); foreach (GroupMembersData member in groupMembers) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6f044e0..0c8113e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -599,7 +599,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name); + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); if (m_debugEnabled) -- cgit v1.1 From a331fd4e24012a246bea9ac11689afe933e7968e Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Wed, 27 Oct 2010 00:01:03 -0400 Subject: Formatting cleanup. --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 25dba7f..3d34441 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -220,7 +220,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups groupID, groupMembers.Count); foreach (GroupMembersData member in groupMembers) - { + { if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session @@ -266,7 +266,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void OnClientLogin(IClientAPI client) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); } private void OnNewClient(IClientAPI client) -- cgit v1.1 From e6c52f38c5a8b2c5ee59919942f25b9368bfa41b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 21 Nov 2010 22:25:50 +0000 Subject: Strip the dialplan and directory methods from the region module --- .../Voice/FreeSwitchVoice/FreeSwitchDialplan.cs | 104 ------ .../Voice/FreeSwitchVoice/FreeSwitchDirectory.cs | 348 --------------------- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 80 +---- 3 files changed, 10 insertions(+), 522 deletions(-) delete mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs delete mode 100644 OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs deleted file mode 100644 index 46ad30f..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 log4net; -using System; -using System.Reflection; -using System.Text; -using System.Collections; - -namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice -{ - public class FreeSwitchDialplan - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - - public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request) - { - m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString()); - - Hashtable response = new Hashtable(); - - foreach (DictionaryEntry item in request) - { - m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); - } - - string requestcontext = (string) request["Hunt-Context"]; - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - if (Context != String.Empty && Context != requestcontext) - { - m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); - response["str_response_string"] = ""; - } else { - response["str_response_string"] = String.Format(@" - -
- " + - -/* - - - - - - */ - - @" - - - - - - - - - - - - - - - - - - - - -
-
", Context, Realm); - } - - return response; - } - } - -} diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs deleted file mode 100644 index 17cdf74..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 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 log4net; -using System; -using System.Reflection; -using System.Text; -using System.Collections; - -namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice -{ - public class FreeSwitchDirectory - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request) - { - Hashtable response = new Hashtable(); - string domain = (string) request["domain"]; - if (domain != Realm) { - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = ""; - } else { - m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); - - // information in the request we might be interested in - - // Request 1 sip_auth for users account - - //Event-Calling-Function=sofia_reg_parse_auth - //Event-Calling-Line-Number=1494 - //action=sip_auth - //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41) - //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) - //sip_auth_realm=9.20.151.43 - //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) - //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers - //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D - //sip_to_host=9.20.151.43 - //sip_auth_method=REGISTER - //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D - //domain=9.20.151.43 - //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup - - foreach (DictionaryEntry item in request) - { - m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); - } - - string eventCallingFunction = (string) request["Event-Calling-Function"]; - if (eventCallingFunction == null) - { - eventCallingFunction = "sofia_reg_parse_auth"; - } - - if (eventCallingFunction.Length == 0) - { - eventCallingFunction = "sofia_reg_parse_auth"; - } - - if (eventCallingFunction == "sofia_reg_parse_auth") - { - string sipAuthMethod = (string)request["sip_auth_method"]; - - if (sipAuthMethod == "REGISTER") - { - response = HandleRegister(Context, Realm, request); - } - else if (sipAuthMethod == "INVITE") - { - response = HandleInvite(Context, Realm, request); - } - else - { - m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); - response["int_response_code"] = 404; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - } - else if (eventCallingFunction == "switch_xml_locate_user") - { - response = HandleLocateUser(Realm, request); - } - else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made - { - response = HandleLocateUser(Realm, request); - } - else if (eventCallingFunction == "user_outgoing_channel") - { - response = HandleRegister(Context, Realm, request); - } - else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup - { - response = HandleConfigSofia(Context, Realm, request); - } - else if (eventCallingFunction == "switch_load_network_lists") - { - //response = HandleLoadNetworkLists(request); - response["int_response_code"] = 404; - response["keepalive"] = false; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - else - { - m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); - response["int_response_code"] = 404; - response["keepalive"] = false; - response["content_type"] = "text/xml"; - response["str_response_string"] = ""; - } - } - return response; - } - - private Hashtable HandleRegister(string Context, string Realm, Hashtable request) - { - m_log.Info("[FreeSwitchDirectory] HandleRegister called"); - - // TODO the password we return needs to match that sent in the request, this is hard coded for now - string password = "1234"; - string domain = (string) request["domain"]; - string user = (string) request["user"]; - - Hashtable response = new Hashtable(); - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - - response["str_response_string"] = String.Format( - "\r\n" + - "\r\n" + - "
\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - ""+ - "\r\n" + - "\r\n" + - "\r\n" + - "
\r\n" + - "
\r\n", - domain , user, password, Context); - - return response; - } - - private Hashtable HandleInvite(string Context, string Realm, Hashtable request) - { - m_log.Info("[FreeSwitchDirectory] HandleInvite called"); - - // TODO the password we return needs to match that sent in the request, this is hard coded for now - string password = "1234"; - string domain = (string) request["domain"]; - string user = (string) request["user"]; - string sipRequestUser = (string) request["sip_request_user"]; - - Hashtable response = new Hashtable(); - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = String.Format( - "\r\n" + - "\r\n" + - "
\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - ""+ - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - ""+ - "\r\n" + - "\r\n" + - "\r\n" + - "
\r\n" + - "
\r\n", - domain , user, password,sipRequestUser, Context); - - return response; - } - - private Hashtable HandleLocateUser(String Realm, Hashtable request) - { - m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); - - // TODO the password we return needs to match that sent in the request, this is hard coded for now - string domain = (string) request["domain"]; - string user = (string) request["user"]; - - Hashtable response = new Hashtable(); - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = String.Format( - "\r\n" + - "\r\n" + - "
\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n"+ - "\r\n"+ - ""+ - "\r\n"+ - "\r\n" + - "\r\n" + - "
\r\n" + - "
\r\n", - domain , user); - - return response; - } - - private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request) - { - m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called"); - - // TODO the password we return needs to match that sent in the request, this is hard coded for now - string domain = (string) request["domain"]; - - Hashtable response = new Hashtable(); - response["content_type"] = "text/xml"; - response["keepalive"] = false; - response["int_response_code"] = 200; - response["str_response_string"] = String.Format( - "\r\n" + - "\r\n" + - "
\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n" + - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n"+ - ""+ - "\r\n" + - "\r\n"+ - "\r\n"+ - "\r\n"+ - "\r\n" + - "
\r\n" + - "
\r\n", - domain, Context); - - return response; - } - - -// private Hashtable HandleLoadNetworkLists(Hashtable request) -// { -// m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called"); -// -// // TODO the password we return needs to match that sent in the request, this is hard coded for now -// string domain = (string) request["domain"]; -// -// Hashtable response = new Hashtable(); -// response["content_type"] = "text/xml"; -// response["keepalive"] = false; -// response["int_response_code"] = 200; -// response["str_response_string"] = String.Format( -// "\r\n" + -// "\r\n" + -// "
\r\n" + -// "\r\n" + -// "\r\n" + -// "\r\n" + -// "\r\n" + -// "\r\n" + -// "\r\n"+ -// "\r\n"+ -// "\r\n"+ -// "\r\n" + -// "
\r\n" + -// "
\r\n", -// domain); -// -// -// return response; -// } - } -} diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 242bc3f..cceaa9b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -96,9 +96,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private string m_openSimWellKnownHTTPAddress; private string m_freeSwitchContext; - private FreeSwitchDirectory m_FreeSwitchDirectory; - private FreeSwitchDialplan m_FreeSwitchDialplan; - private readonly Dictionary m_UUIDName = new Dictionary(); private Dictionary m_ParcelAddress = new Dictionary(); @@ -172,41 +169,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // - buddies: viv_buddy.php // - ???: viv_watcher.php // - signout: viv_signout.php - if (UseProxy) - { - MainServer.Instance.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix), - ForwardProxyRequest); - } - else - { - MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceGetPreloginHTTPHandler); + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceGetPreloginHTTPHandler); - // RestStreamHandler h = new - // RestStreamHandler("GET", - // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); - // MainServer.Instance.AddStreamHandler(h); + // RestStreamHandler h = new + // RestStreamHandler("GET", + // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); + // MainServer.Instance.AddStreamHandler(h); - MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceSigninHTTPHandler); + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceSigninHTTPHandler); - // set up http request handlers to provide - // on-demand FreeSwitch configuration to - // FreeSwitch's mod_curl_xml - MainServer.Instance.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), - FreeSwitchConfigHTTPHandler); - - MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceBuddyHTTPHandler); - } + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceBuddyHTTPHandler); m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); - m_FreeSwitchDirectory = new FreeSwitchDirectory(); - m_FreeSwitchDialplan = new FreeSwitchDialplan(); - m_pluginEnabled = true; m_WOF = false; @@ -725,46 +705,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["int_response_code"] = 200; return response; - /* - - OKOklib_session - * xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592:: - * xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592:: - * 1 - * 7449 - * Teravus Ousley - */ - } - - public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request) - { - m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]); - - Hashtable response = new Hashtable(); - response["str_response_string"] = string.Empty; - // all the params come as NVPs in the request body - Hashtable requestBody = parseRequestBody((string) request["body"]); - - // is this a dialplan or directory request - string section = (string) requestBody["section"]; - - if (section == "directory") - response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); - else if (section == "dialplan") - response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody); - else - m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); - - // XXX: re-generate dialplan: - // - conf == region UUID - // - conf number = region port - // -> TODO Initialise(): keep track of regions via events - // re-generate accounts for all avatars - // -> TODO Initialise(): keep track of avatars via events - Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); - - m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",normalizeEndLines.Replace(((string)response["str_response_string"]), "")); - return response; } public Hashtable parseRequestBody(string body) -- cgit v1.1 From 6fa24f46712b7e266f6d5dfc55f395f2c489671c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 21 Nov 2010 22:40:03 +0000 Subject: Convert the Freeswitch module to new style --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 191 +++++++++++---------- 1 file changed, 98 insertions(+), 93 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index cceaa9b..4095674 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -41,6 +41,7 @@ using log4net; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; +using Mono.Addins; using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; @@ -52,7 +53,8 @@ using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { - public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FreeSwitchVoiceModule")] + public class FreeSwitchVoiceModule : INonSharedRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -64,8 +66,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly string m_chatSessionRequestPath = "0009/"; // Control info - private static bool m_WOF = true; - private static bool m_pluginEnabled = false; + private static bool m_Enabled = false; // FreeSwitch server is going to contact us and ask us all // sorts of things. @@ -104,9 +105,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private IConfig m_config; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - m_scene = scene; m_config = config.Configs["FreeSwitchVoice"]; if (null == m_config) @@ -121,86 +121,106 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return; } - // This is only done the FIRST time this method is invoked. - if (m_WOF) - { - m_pluginEnabled = true; - m_WOF = false; + m_Enabled = true; - try + try + { + m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty); + m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty); + m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty); + + // XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server) + + string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty); + int servicePort = m_config.GetInt("freeswitch_service_port", 80); + IPAddress serviceIPAddress = IPAddress.Parse(serviceIP); + // m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort); + m_freeSwitchServicePort = servicePort; + m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty); + m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm); + m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true); + // m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm); + m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm); + m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505); + m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm); + m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString()); + m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); + // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); + m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); + m_freeSwitchContext = m_config.GetString("freeswitch_context", "default"); + + if (String.IsNullOrEmpty(m_freeSwitchServerUser) || + String.IsNullOrEmpty(m_freeSwitchServerPass) || + String.IsNullOrEmpty(m_freeSwitchRealm) || + String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) { - m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty); - m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty); - m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty); - - // XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server) - - string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty); - int servicePort = m_config.GetInt("freeswitch_service_port", 80); - IPAddress serviceIPAddress = IPAddress.Parse(serviceIP); - // m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort); - m_freeSwitchServicePort = servicePort; - m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty); - m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm); - m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true); - // m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm); - m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm); - m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505); - m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm); - m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString()); - m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); - // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); - m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); - m_freeSwitchContext = m_config.GetString("freeswitch_context", "default"); - - if (String.IsNullOrEmpty(m_freeSwitchServerUser) || - String.IsNullOrEmpty(m_freeSwitchServerPass) || - String.IsNullOrEmpty(m_freeSwitchRealm) || - String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) - { - m_log.Error("[FreeSwitchVoice] plugin mis-configured"); - m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration"); - return; - } + m_log.Error("[FreeSwitchVoice] plugin mis-configured"); + m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration"); + return; + } - // set up http request handlers for - // - prelogin: viv_get_prelogin.php - // - signin: viv_signin.php - // - buddies: viv_buddy.php - // - ???: viv_watcher.php - // - signout: viv_signout.php - MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceGetPreloginHTTPHandler); + // set up http request handlers for + // - prelogin: viv_get_prelogin.php + // - signin: viv_signin.php + // - buddies: viv_buddy.php + // - ???: viv_watcher.php + // - signout: viv_signout.php + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceGetPreloginHTTPHandler); - // RestStreamHandler h = new - // RestStreamHandler("GET", - // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); - // MainServer.Instance.AddStreamHandler(h); + // RestStreamHandler h = new + // RestStreamHandler("GET", + // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); + // MainServer.Instance.AddStreamHandler(h); - MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceSigninHTTPHandler); + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceSigninHTTPHandler); - MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), - FreeSwitchSLVoiceBuddyHTTPHandler); + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceBuddyHTTPHandler); - m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); + m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); - m_pluginEnabled = true; - m_WOF = false; + m_Enabled = true; + + m_log.Info("[FreeSwitchVoice] plugin enabled"); + } + catch (Exception e) + { + m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message); + m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString()); + return; + } - m_log.Info("[FreeSwitchVoice] plugin enabled"); + // This here is a region module trying to make a global setting. + // Not really a good idea but it's Windows only, so I can't test. + try + { + ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation; + } + catch (NotImplementedException) + { + try + { +#pragma warning disable 0612, 0618 + // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this! + ServicePointManager.CertificatePolicy = new MonoCert(); +#pragma warning restore 0612, 0618 } - catch (Exception e) + catch (Exception) { - m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message); - m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString()); - return; + //m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); } } + } + + public void AddRegion(Scene scene) + { + m_scene = scene; - if (m_pluginEnabled) + if (m_Enabled) { // we need to capture scene in an anonymous method // here as we need it later in the callbacks @@ -208,36 +228,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { OnRegisterCaps(scene, agentID, caps); }; - - try - { - ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation; - } - catch (NotImplementedException) - { - try - { -#pragma warning disable 0612, 0618 - // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this! - ServicePointManager.CertificatePolicy = new MonoCert(); -#pragma warning restore 0612, 0618 - } - catch (Exception) - { - m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); - } - } } } - public void PostInitialise() + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) { - if (m_pluginEnabled) + if (m_Enabled) { m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); // register the voice interface for this module, so the script engine can call us - m_scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); } } @@ -250,9 +255,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice get { return "FreeSwitchVoiceModule"; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return true; } + get { return null; } } // -- cgit v1.1 From 21058425133dff8499f856a32af29547f537445a Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 21 Nov 2010 23:24:39 +0000 Subject: Finish the standalone mode freeswitch work and add config examples --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 90 +++++++++++----------- 1 file changed, 47 insertions(+), 43 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 4095674..a5e553c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -37,6 +37,7 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; using OpenMetaverse; +using OpenMetaverse.StructuredData; using log4net; using Nini.Config; using Nwc.XmlRpc; @@ -50,6 +51,9 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps = OpenSim.Framework.Capabilities.Caps; using System.Text.RegularExpressions; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OSDMap = OpenMetaverse.StructuredData.OSDMap; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { @@ -58,8 +62,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool UseProxy = false; - // Capability string prefixes private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; @@ -70,8 +72,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // FreeSwitch server is going to contact us and ask us all // sorts of things. - private static string m_freeSwitchServerUser; - private static string m_freeSwitchServerPass; // SLVoice client will do a GET on this prefix private static string m_freeSwitchAPIPrefix; @@ -85,73 +85,69 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static string m_freeSwitchRealm; private static string m_freeSwitchSIPProxy; private static bool m_freeSwitchAttemptUseSTUN; - // private static string m_freeSwitchSTUNServer; private static string m_freeSwitchEchoServer; private static int m_freeSwitchEchoPort; private static string m_freeSwitchDefaultWellKnownIP; private static int m_freeSwitchDefaultTimeout; - // private static int m_freeSwitchSubscribeRetry; private static string m_freeSwitchUrlResetPassword; - // private static IPEndPoint m_FreeSwitchServiceIP; - private int m_freeSwitchServicePort; + private uint m_freeSwitchServicePort; private string m_openSimWellKnownHTTPAddress; private string m_freeSwitchContext; private readonly Dictionary m_UUIDName = new Dictionary(); private Dictionary m_ParcelAddress = new Dictionary(); - private Scene m_scene; + private Scene m_Scene; + private IConfig m_Config; - private IConfig m_config; + private IFreeswitchService m_FreeswitchService; public void Initialise(IConfigSource config) { - m_config = config.Configs["FreeSwitchVoice"]; + m_Config = config.Configs["FreeSwitchVoice"]; - if (null == m_config) + if (m_Config == null) { m_log.Info("[FreeSwitchVoice] no config found, plugin disabled"); return; } - if (!m_config.GetBoolean("enabled", false)) + if (!m_Config.GetBoolean("Enabled", false)) { m_log.Info("[FreeSwitchVoice] plugin disabled by configuration"); return; } - m_Enabled = true; - try { - m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty); - m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty); - m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty); - - // XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server) - - string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty); - int servicePort = m_config.GetInt("freeswitch_service_port", 80); - IPAddress serviceIPAddress = IPAddress.Parse(serviceIP); - // m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort); - m_freeSwitchServicePort = servicePort; - m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty); - m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm); - m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true); - // m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm); - m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm); - m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505); - m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm); - m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString()); - m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000); - // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120); - m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty); - m_freeSwitchContext = m_config.GetString("freeswitch_context", "default"); - - if (String.IsNullOrEmpty(m_freeSwitchServerUser) || - String.IsNullOrEmpty(m_freeSwitchServerPass) || - String.IsNullOrEmpty(m_freeSwitchRealm) || + string serviceDll = m_Config.GetString("LocalServiceModule", + String.Empty); + + if (serviceDll == String.Empty) + { + m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice"); + return; + } + + Object[] args = new Object[] { config }; + m_FreeswitchService = ServerUtils.LoadPlugin(serviceDll, args); + + string jsonConfig = m_FreeswitchService.GetJsonConfig(); + OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig); + + m_freeSwitchAPIPrefix = map["APIPrefix"].AsString(); + m_freeSwitchRealm = map["Realm"].AsString(); + m_freeSwitchSIPProxy = map["SIPProxy"].AsString(); + m_freeSwitchAttemptUseSTUN = map["AttemptUseSTUN"].AsBoolean(); + m_freeSwitchEchoServer = map["EchoServer"].AsString(); + m_freeSwitchEchoPort = map["EchoPort"].AsInteger(); + m_freeSwitchDefaultWellKnownIP = map["DefaultWellKnownIP"].AsString(); + m_freeSwitchDefaultTimeout = map["DefaultTimeout"].AsInteger(); + m_freeSwitchUrlResetPassword = String.Empty; + m_freeSwitchContext = map["Context"].AsString(); + + if (String.IsNullOrEmpty(m_freeSwitchRealm) || String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) { m_log.Error("[FreeSwitchVoice] plugin mis-configured"); @@ -211,6 +207,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } catch (Exception) { + // COmmented multiline spam log message //m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); } } @@ -218,7 +215,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public void AddRegion(Scene scene) { - m_scene = scene; + m_Scene = scene; + + // We generate these like this: The region's external host name + // as defined in Regions.ini is a good address to use. It's a + // dotted quad (or should be!) and it can reach this host from + // a client. The port is grabbed from the region's HTTP server. + m_openSimWellKnownHTTPAddress = m_Scene.RegionInfo.ExternalHostName; + m_freeSwitchServicePort = MainServer.Instance.Port; if (m_Enabled) { -- cgit v1.1 From ddf08276f1c01f3d5f85ee3077062ca5d6a8a812 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Nov 2010 00:55:11 +0100 Subject: Fox the buglets in Freeswitch. Grid mode works now and there is no reason why standalone should not. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index a5e553c..294d4f0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -134,6 +134,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_FreeswitchService = ServerUtils.LoadPlugin(serviceDll, args); string jsonConfig = m_FreeswitchService.GetJsonConfig(); + m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig); OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig); m_freeSwitchAPIPrefix = map["APIPrefix"].AsString(); -- cgit v1.1 From 4e0a289a8dfc069201a856d2a67510c5b6b91ccf Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Nov 2010 14:13:27 +0000 Subject: Change FS Voice module to a shared module to avoid gratuitious server handler registrations. Add the missing bits to drive the local connector's HTTP requests. This makes standalones work. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 36 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 294d4f0..9a17233 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -58,7 +58,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FreeSwitchVoiceModule")] - public class FreeSwitchVoiceModule : INonSharedRegionModule, IVoiceModule + public class FreeSwitchVoiceModule : ISharedRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -97,8 +97,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private readonly Dictionary m_UUIDName = new Dictionary(); private Dictionary m_ParcelAddress = new Dictionary(); - private Scene m_Scene; - private IConfig m_Config; private IFreeswitchService m_FreeswitchService; @@ -165,6 +163,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); + MainServer.Instance.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), FreeSwitchConfigHTTPHandler); + // RestStreamHandler h = new // RestStreamHandler("GET", // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); @@ -214,15 +214,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } } - public void AddRegion(Scene scene) + public void PostInitialise() { - m_Scene = scene; + } + public void AddRegion(Scene scene) + { // We generate these like this: The region's external host name // as defined in Regions.ini is a good address to use. It's a // dotted quad (or should be!) and it can reach this host from // a client. The port is grabbed from the region's HTTP server. - m_openSimWellKnownHTTPAddress = m_Scene.RegionInfo.ExternalHostName; + m_openSimWellKnownHTTPAddress = scene.RegionInfo.ExternalHostName; m_freeSwitchServicePort = MainServer.Instance.Port; if (m_Enabled) @@ -790,6 +792,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { return true; } + + public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request) + { + Hashtable response = new Hashtable(); + response["str_response_string"] = string.Empty; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["int_response_code"] = 500; + + Hashtable requestBody = ParseRequestBody((string) request["body"]); + + string section = (string) requestBody["section"]; + + if (section == "directory") + response = m_FreeswitchService.HandleDirectoryRequest(requestBody); + else if (section == "dialplan") + response = m_FreeswitchService.HandleDialplanRequest(requestBody); + else + m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); + + return response; + } } public class MonoCert : ICertificatePolicy -- cgit v1.1 From d2aebbe0669481c9f416c78dd40ca6007da09f02 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Nov 2010 14:32:51 +0100 Subject: Fox case on a method --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 9a17233..a583cca 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -603,7 +603,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["str_response_string"] = string.Empty; response["content-type"] = "text/xml"; - Hashtable requestBody = parseRequestBody((string)request["body"]); + Hashtable requestBody = ParseRequestBody((string)request["body"]); if (!requestBody.ContainsKey("auth_token")) return response; @@ -675,7 +675,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string uri = (string)request["uri"]; string contenttype = (string)request["content-type"]; - Hashtable requestBody = parseRequestBody((string)request["body"]); + Hashtable requestBody = ParseRequestBody((string)request["body"]); //string pwd = (string) requestBody["pwd"]; string userid = (string) requestBody["userid"]; @@ -719,7 +719,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - public Hashtable parseRequestBody(string body) + public Hashtable ParseRequestBody(string body) { Hashtable bodyParams = new Hashtable(); // split string -- cgit v1.1 From 541a7660e06206c9a9eb2426dee0449afb554921 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 23 Nov 2010 16:08:10 -0800 Subject: Refactor appearance and avatar data sending code. Paritioning the routines into "one-to-many" and "many-to-one" makes it possible to call the right function on presence creation (both child and root) and when a child agent is promoted to root. This brings the total number of appearance sends down to one or two on login. Cleaned up the avatar update calls in the groups code. Cleaned up some commented and debugging code, and a few formating fixes. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 0c8113e..ccf5289 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1173,10 +1173,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups presence = scene.GetScenePresence(AgentID); if (presence != null) { - presence.Grouptitle = Title; + if (presence.Grouptitle != Title) + { + presence.Grouptitle = Title; - // FixMe: Ter suggests a "Schedule" method that I can't find. - presence.SendFullUpdateToAllClients(); + if (! presence.IsChildAgent) + presence.SendAvatarDataToAllAgents(); + } } } } -- cgit v1.1 From 5aeb83125a9485eb0ab38c65a939964973b7962b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 28 Nov 2010 23:30:55 +0000 Subject: Remove the most spammy XML dumps from the FS voice module --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index a583cca..0b51bf0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -132,7 +132,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_FreeswitchService = ServerUtils.LoadPlugin(serviceDll, args); string jsonConfig = m_FreeswitchService.GetJsonConfig(); - m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig); + //m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig); OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig); m_freeSwitchAPIPrefix = map["APIPrefix"].AsString(); @@ -363,7 +363,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice try { - m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", + //m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); //XmlElement resp; @@ -445,7 +445,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // voice channel LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", + //m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); // TODO: EstateSettings don't seem to get propagated... @@ -592,7 +592,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["int_response_code"] = 200; - m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler return {0}",response["str_response_string"]); + //m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler return {0}",response["str_response_string"]); return response; } @@ -664,7 +664,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["str_response_string"] = resp.ToString(); Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); - m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); + //m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); return response; } @@ -696,7 +696,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } } - m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype, + //m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype, requestbody); Hashtable response = new Hashtable(); response["str_response_string"] = string.Format(@" -- cgit v1.1 From 04ce7de5ed54b0586c3287b6c848dadfb507b132 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 29 Nov 2010 01:15:02 +0000 Subject: Fix the build break --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 0b51bf0..e9c5453 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -364,7 +364,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice try { //m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", - request, path, param); + // request, path, param); //XmlElement resp; string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); @@ -446,7 +446,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); //m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", - scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); + // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); // TODO: EstateSettings don't seem to get propagated... // if (!scene.RegionInfo.EstateSettings.AllowVoice) @@ -697,7 +697,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } //m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype, - requestbody); + // requestbody); Hashtable response = new Hashtable(); response["str_response_string"] = string.Format(@" -- cgit v1.1 From c620e4c8228d275cfe9659d55ca9ec0c2d7c1b1a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 14 Dec 2010 22:25:01 +0000 Subject: add infrastructure for groups module tests --- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs new file mode 100644 index 0000000..f9a736f --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -0,0 +1,54 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; +using OpenSim.Tests.Common.Setup; + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests +{ + /// + /// Basic groups module tests + /// + [TestFixture] + public class GroupsModuleTests + { + [Test] + public void TestBasic() + { + TestHelper.InMethod(); + } + } +} \ No newline at end of file -- cgit v1.1 From 42c9c30e4c3102d1f34e28353ddec23c854c5d35 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 14 Dec 2010 22:57:36 +0000 Subject: Add mock group services connector and use this in tests --- .../Avatar/XmlRpcGroups/IGroupsServicesConnector.cs | 4 +--- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 11 +++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index a046e09..5c779de 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -27,14 +27,12 @@ using System; using System.Collections.Generic; - using OpenMetaverse; - using OpenSim.Framework; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - interface IGroupsServicesConnector + public interface IGroupsServicesConnector { UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index f9a736f..bc55b04 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -27,6 +27,7 @@ using System; using System.Reflection; +using Nini.Config; using NUnit.Framework; using NUnit.Framework.SyntaxHelpers; using OpenMetaverse; @@ -49,6 +50,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests public void TestBasic() { TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestScene scene = SceneSetupHelpers.SetupScene(); + IConfigSource configSource = new IniConfigSource(); + IConfig config = configSource.AddConfig("Groups"); + config.Set("Enabled", true); + config.Set("Module", "GroupsModule"); + config.Set("DebugEnabled", true); + SceneSetupHelpers.SetupSceneModules( + scene, configSource, new object[] { new MockGroupsServicesConnector() }); } } } \ No newline at end of file -- cgit v1.1 From 81bccd6d132956e2de9e5ad473f87931df76cde8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 14 Dec 2010 23:36:34 +0000 Subject: Start implementing a test for 'share with group' object functionality. Not yet complete. While implementing this, a bug was fixed in scene setup helpers where module RegionLoaded() was called immediately after AddRegion() instead of waiting for all AddRegions() to complete. Also, XmlRpcGroupsModule non-message functionality will now work without a message transfer module (as indicated in the comments but with a contradictory implementation) --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index ccf5289..4aab87f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -163,9 +163,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_msgTransferModule == null) { m_groupsEnabled = false; - m_log.Error("[GROUPS]: Could not get MessageTransferModule"); - Close(); - return; + m_log.Warn("[GROUPS]: Could not get MessageTransferModule"); } } @@ -1299,7 +1297,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); localClient.SendInstantMessage(msg); } - else + else if (m_msgTransferModule != null) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is not local, delivering via TransferModule", msgTo); m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Message Sent: {0}", success?"Succeeded":"Failed"); }); -- cgit v1.1 From 4ac58093bf7fd89c473be259c0a6ca8524879245 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Jan 2011 23:23:42 +0000 Subject: Make the default for the very verbose XMLRPC groups debug setting false rather than true! --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 4aab87f..a8dec63 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -123,8 +123,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS]: Initializing {0}", this.Name); m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); - m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); - + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); } } -- cgit v1.1 From 0898be5750a9e5f0cfab566a34b65e4a227d82e6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 31 Jan 2011 22:54:36 +0000 Subject: Change SimianGroupsServicesConnectorModule.GetAgentGroupMembership() so that it returns null if the user isn't a member of the group. This matches the behaviour of the same method for Flotsam Groups. This is the behaviour assumed by existing code. Method doc also added to IGroupsServicesConnector to the make the contract clear. --- .../XmlRpcGroups/IGroupsServicesConnector.cs | 19 +++++++ .../SimianGroupsServicesConnectorModule.cs | 66 +++++++++++----------- 2 files changed, 52 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 5c779de..6d26075 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -63,7 +63,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + /// + /// Get information about a specific group to which the user belongs. + /// + /// The agent requesting the information. + /// The agent requested. + /// The group requested. + /// + /// If the user is a member of the group then the data structure is returned. If not, then null is returned. + /// GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + + /// + /// Get information about the groups to which a user belongs. + /// + /// The agent requesting the information. + /// The agent requested. + /// + /// Information about the groups to which the user belongs. If the user belongs to no groups then an empty + /// list is returned. + /// List GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID); void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 0d265f2..81725c5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -704,7 +704,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } - return findings; } @@ -712,54 +711,55 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupMembershipData data = new GroupMembershipData(); - - /////////////////////////////// - // Agent Specific Information: - // - OSDMap UserActiveGroup; - if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) - { - data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); - } + GroupMembershipData data = null; + bool foundData = false; OSDMap UserGroupMemberInfo; if (SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo)) { + data = new GroupMembershipData(); data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); - data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); + data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); + + /////////////////////////////// + // Agent Specific Information: + // + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); + } /////////////////////////////// // Role Specific Information: // - OSDMap GroupRoleInfo; if (SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo)) { data.GroupTitle = GroupRoleInfo["Title"].AsString(); data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); - } - } - - /////////////////////////////// - // Group Specific Information: - // - OSDMap GroupInfo; - string GroupName; - if (SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo)) - { - data.GroupID = groupID; - data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); - data.Charter = GroupInfo["Charter"].AsString(); - data.FounderID = GroupInfo["FounderID"].AsUUID(); - data.GroupName = GroupName; - data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); - data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); - data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); - data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); - data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); + } + + /////////////////////////////// + // Group Specific Information: + // + OSDMap GroupInfo; + string GroupName; + if (SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo)) + { + data.GroupID = groupID; + data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); + data.Charter = GroupInfo["Charter"].AsString(); + data.FounderID = GroupInfo["FounderID"].AsUUID(); + data.GroupName = GroupName; + data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); + data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); + data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); + data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); + data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); + } } return data; -- cgit v1.1 From 8efb01b3df1ea98d5e4a68aa220bafc4ab5306f4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 5 Mar 2011 01:15:27 +0000 Subject: minor: remove some mono compiler warnings --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 12 ++++++------ .../XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index e9c5453..05a1c3b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -92,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static string m_freeSwitchUrlResetPassword; private uint m_freeSwitchServicePort; private string m_openSimWellKnownHTTPAddress; - private string m_freeSwitchContext; +// private string m_freeSwitchContext; private readonly Dictionary m_UUIDName = new Dictionary(); private Dictionary m_ParcelAddress = new Dictionary(); @@ -144,7 +144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_freeSwitchDefaultWellKnownIP = map["DefaultWellKnownIP"].AsString(); m_freeSwitchDefaultTimeout = map["DefaultTimeout"].AsInteger(); m_freeSwitchUrlResetPassword = String.Empty; - m_freeSwitchContext = map["Context"].AsString(); +// m_freeSwitchContext = map["Context"].AsString(); if (String.IsNullOrEmpty(m_freeSwitchRealm) || String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) @@ -662,7 +662,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice resp.Append(""); response["str_response_string"] = resp.ToString(); - Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); +// Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); //m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); return response; @@ -671,9 +671,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) { m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called"); - string requestbody = (string)request["body"]; - string uri = (string)request["uri"]; - string contenttype = (string)request["content-type"]; +// string requestbody = (string)request["body"]; +// string uri = (string)request["uri"]; +// string contenttype = (string)request["content-type"]; Hashtable requestBody = ParseRequestBody((string)request["body"]); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 81725c5..02751ea 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -712,7 +712,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupMembershipData data = null; - bool foundData = false; +// bool foundData = false; OSDMap UserGroupMemberInfo; if (SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo)) -- cgit v1.1 From 9456bb77fbf794bb6fc2808e6cfd69c9bb1d1326 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 9 Mar 2011 23:25:24 +0000 Subject: Upgrade nunit.framework.dll to version 2.5.9. Fix up tests appropriately. This version removes the NUnit.Framework.SyntaxHelpers namespace, so any modules with their own tests will need to delete this using statement. --- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index bc55b04..6de97b7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -29,7 +29,6 @@ using System; using System.Reflection; using Nini.Config; using NUnit.Framework; -using NUnit.Framework.SyntaxHelpers; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; -- cgit v1.1 From 4f56c732bc00588cd8ced1be85bc4d13815f86bd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Apr 2011 02:29:42 +0100 Subject: Comment out some startup logging lines to make up for the one I added earlier on. Most of these are where the region modules are telling us they are disabled. Convention is only to log when enabled (even that is really noisy) --- .../Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 9 ++------- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 ------ .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 8 -------- .../OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 3 --- 4 files changed, 2 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 2fcc477..0d6313a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -80,16 +80,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge m_config = config.Configs["Concierge"]; if (null == m_config) - { - m_log.Info("[Concierge]: no config found, plugin disabled"); return; - } if (!m_config.GetBoolean("enabled", false)) - { - m_log.Info("[Concierge]: plugin disabled by configuration"); return; - } + m_enabled = true; @@ -113,9 +108,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge { m_replacingChatModule = false; } + m_log.InfoFormat("[Concierge] {0} ChatModule", m_replacingChatModule ? "replacing" : "not replacing"); - // take note of concierge channel and of identity m_conciergeChannel = config.Configs["Concierge"].GetInt("concierge_channel", m_conciergeChannel); m_whoami = m_config.GetString("whoami", "conferencier"); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 05a1c3b..7909d8a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -106,16 +106,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_Config = config.Configs["FreeSwitchVoice"]; if (m_Config == null) - { - m_log.Info("[FreeSwitchVoice] no config found, plugin disabled"); return; - } if (!m_Config.GetBoolean("Enabled", false)) - { - m_log.Info("[FreeSwitchVoice] plugin disabled by configuration"); return; - } try { diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 34d0e24..534bf92 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -121,16 +121,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice m_config = config.Configs["VivoxVoice"]; if (null == m_config) - { - m_log.Info("[VivoxVoice] no config found, plugin disabled"); return; - } if (!m_config.GetBoolean("enabled", false)) - { - m_log.Info("[VivoxVoice] plugin disabled by configuration"); return; - } try { @@ -218,7 +212,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice m_pluginEnabled = true; m_log.Info("[VivoxVoice] plugin enabled"); - } catch (Exception e) { @@ -228,7 +221,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice } } - // Called to indicate that the module has been added to the region public void AddRegion(Scene scene) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 3d34441..8c01d75 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -86,13 +86,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.Info("[GROUPS-MESSAGING]: Initializing GroupsMessagingModule"); - m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); } m_log.Info("[GROUPS-MESSAGING]: GroupsMessagingModule starting up"); - } public void AddRegion(Scene scene) -- cgit v1.1 From 2fa210243b64bb10fbca37f89176f10efeb25f41 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Apr 2011 21:54:26 +0100 Subject: Clean up freeswitch config to what is currently required. Add explanation to config parameters. Clean up some log messages. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 7909d8a..962b5ca 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -118,7 +118,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice if (serviceDll == String.Empty) { - m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice"); + m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice. Not starting."); return; } @@ -143,8 +143,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice if (String.IsNullOrEmpty(m_freeSwitchRealm) || String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) { - m_log.Error("[FreeSwitchVoice] plugin mis-configured"); - m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration"); + m_log.Error("[FreeSwitchVoice]: Freeswitch service mis-configured. Not starting."); return; } @@ -172,16 +171,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceBuddyHTTPHandler); - m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); + m_log.InfoFormat("[FreeSwitchVoice]: using FreeSwitch server {0}", m_freeSwitchRealm); m_Enabled = true; - m_log.Info("[FreeSwitchVoice] plugin enabled"); + m_log.Info("[FreeSwitchVoice]: plugin enabled"); } catch (Exception e) { - m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message); - m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString()); + m_log.ErrorFormat("[FreeSwitchVoice]: plugin initialization failed: {0} {1}", e.Message, e.StackTrace); return; } @@ -240,7 +238,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { if (m_Enabled) { - m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); + m_log.Info("[FreeSwitchVoice]: registering IVoiceModule with the scene"); // register the voice interface for this module, so the script engine can call us scene.RegisterModuleInterface(this); @@ -302,7 +300,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps) { - m_log.DebugFormat("[FreeSwitchVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + m_log.DebugFormat( + "[FreeSwitchVoice]: OnRegisterCaps called with agentID {0} caps {1} in scene {2}", + agentID, caps, scene.RegionInfo.RegionName); string capsBase = "/CAPS/" + caps.CapsObjectPath; caps.RegisterHandler("ProvisionVoiceAccountRequest", @@ -558,7 +558,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) { - m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler called"); + m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceGetPreloginHTTPHandler called"); Hashtable response = new Hashtable(); response["content_type"] = "text/xml"; @@ -664,7 +664,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) { - m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called"); + m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceSigninHTTPHandler called"); // string requestbody = (string)request["body"]; // string uri = (string)request["uri"]; // string contenttype = (string)request["content-type"]; @@ -795,16 +795,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["keepalive"] = false; response["int_response_code"] = 500; - Hashtable requestBody = ParseRequestBody((string) request["body"]); + Hashtable requestBody = ParseRequestBody((string)request["body"]); string section = (string) requestBody["section"]; + + m_log.DebugFormat("[FreeSwitchVoice]: Received request for config section {0}", section); if (section == "directory") response = m_FreeswitchService.HandleDirectoryRequest(requestBody); else if (section == "dialplan") response = m_FreeswitchService.HandleDialplanRequest(requestBody); else - m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); + m_log.WarnFormat("[FreeSwitchVoice]: Unknown section {0} was requested.", section); return response; } -- cgit v1.1 From ccc26f74436f0e3069587efd96497053e4129c3c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Apr 2011 01:02:40 +0100 Subject: Get Viewer 2 voice working with OpenSim. See http://opensimulator.org/mantis/view.php?id=5336 It turns out that viewer 2 was upset by the lack of a response to viv_watcher.php. This would send it into a continuous login loop. Viewer 1 was quite happy to ignore the lack of response. This commit puts in the bare minimum 'OK' message in response to viv_watcher.php. This allows viewer 2 voice to connect and appears to work. However, at some point we need to fill out the watcher response, whatever that is. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 79 ++++++++++++++++++---- 1 file changed, 66 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 962b5ca..373ffeb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -163,13 +163,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); // MainServer.Instance.AddStreamHandler(h); - - MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceSigninHTTPHandler); MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceBuddyHTTPHandler); + + MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_watcher.php", m_freeSwitchAPIPrefix), + FreeSwitchSLVoiceWatcherHTTPHandler); m_log.InfoFormat("[FreeSwitchVoice]: using FreeSwitch server {0}", m_freeSwitchRealm); @@ -301,7 +302,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps) { m_log.DebugFormat( - "[FreeSwitchVoice]: OnRegisterCaps called with agentID {0} caps {1} in scene {2}", + "[FreeSwitchVoice]: OnRegisterCaps() called with agentID {0} caps {1} in scene {2}", agentID, caps, scene.RegionInfo.RegionName); string capsBase = "/CAPS/" + caps.CapsObjectPath; @@ -344,6 +345,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, UUID agentID, Caps caps) { + m_log.DebugFormat( + "[FreeSwitchVoice][PROVISIONVOICE]: ProvisionVoiceAccountRequest() request: {0}, path: {1}, param: {2}", request, path, param); + ScenePresence avatar = scene.GetScenePresence(agentID); if (avatar == null) { @@ -357,9 +361,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice try { - //m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", - // request, path, param); - //XmlElement resp; string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); string password = "1234";//temp hack//new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16); @@ -416,6 +417,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param, UUID agentID, Caps caps) { +// m_log.DebugFormat( +// "[FreeSwitchVoice][PARCELVOICE]: ParcelVoiceInfoRequest() on {0} for {1}", +// scene.RegionInfo.RegionName, agentID); + ScenePresence avatar = scene.GetScenePresence(agentID); string avatarName = avatar.Name; @@ -502,6 +507,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.DebugFormat("[FreeSwitchVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", avatarName, request, path, param); + return "true"; } @@ -555,7 +561,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) { m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceGetPreloginHTTPHandler called"); @@ -592,6 +597,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public Hashtable FreeSwitchSLVoiceBuddyHTTPHandler(Hashtable request) { + m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceBuddyHTTPHandler called"); + Hashtable response = new Hashtable(); response["int_response_code"] = 200; response["str_response_string"] = string.Empty; @@ -650,18 +657,61 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice A {3} - ", ids[i],i,m_freeSwitchRealm,dt)); + ", ids[i], i ,m_freeSwitchRealm, dt)); } resp.Append(""); response["str_response_string"] = resp.ToString(); -// Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); - - //m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); +// Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); +// +// m_log.DebugFormat( +// "[FREESWITCH]: FreeSwitchSLVoiceBuddyHTTPHandler() response {0}", +// normalizeEndLines.Replace((string)response["str_response_string"],"")); + return response; } + public Hashtable FreeSwitchSLVoiceWatcherHTTPHandler(Hashtable request) + { + m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceWatcherHTTPHandler called"); + + Hashtable response = new Hashtable(); + response["int_response_code"] = 200; + response["content-type"] = "text/xml"; + + Hashtable requestBody = ParseRequestBody((string)request["body"]); + + string auth_token = (string)requestBody["auth_token"]; + //string[] auth_tokenvals = auth_token.Split(':'); + //string username = auth_tokenvals[0]; + + StringBuilder resp = new StringBuilder(); + resp.Append(""); + + // FIXME: This is enough of a response to stop viewer 2 complaining about a login failure and get voice to work. If we don't + // give an OK response, then viewer 2 engages in an continuous viv_signin.php, viv_buddy.php, viv_watcher.php loop + // Viewer 1 appeared happy to ignore the lack of reply and still works with this reply. + // + // However, really we need to fill in whatever watcher data should be here (whatever that is). + resp.Append(string.Format(@" + OK + lib_session + {0} + {0} + ", auth_token)); + + response["str_response_string"] = resp.ToString(); + +// Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); +// +// m_log.DebugFormat( +// "[FREESWITCH]: FreeSwitchSLVoiceWatcherHTTPHandler() response {0}", +// normalizeEndLines.Replace((string)response["str_response_string"],"")); + + return response; + } + public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) { m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceSigninHTTPHandler called"); @@ -709,7 +759,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice ", userid, pos, avatarName); - response["int_response_code"] = 200; + response["int_response_code"] = 200; + +// m_log.DebugFormat("[FreeSwitchVoice]: Sending FreeSwitchSLVoiceSigninHTTPHandler response"); + return response; } @@ -823,4 +876,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice #endregion } -} +} \ No newline at end of file -- cgit v1.1 From 60685c35179c74c5714abdb0c17611fb59d52c10 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Apr 2011 19:17:38 +0100 Subject: Adjust freeswitch logging to be somewhat less noisy. However, there is still quite a large amount of logging present for debug purposes. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 373ffeb..42efd67 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -391,7 +391,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); - m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); +// m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); return r; } @@ -458,8 +458,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) { - m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", - scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); +// m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", +// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); channelUri = String.Empty; } else @@ -474,8 +474,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); - m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", - scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); +// m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", +// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); return r; } catch (Exception e) @@ -850,16 +850,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice Hashtable requestBody = ParseRequestBody((string)request["body"]); - string section = (string) requestBody["section"]; - - m_log.DebugFormat("[FreeSwitchVoice]: Received request for config section {0}", section); + string section = (string) requestBody["section"]; if (section == "directory") + { + string eventCallingFunction = (string)requestBody["Event-Calling-Function"]; + m_log.DebugFormat( + "[FreeSwitchVoice]: Received request for config section directory, event calling function '{0}'", + eventCallingFunction); + response = m_FreeswitchService.HandleDirectoryRequest(requestBody); + } else if (section == "dialplan") + { + m_log.DebugFormat("[FreeSwitchVoice]: Received request for config section dialplan"); + response = m_FreeswitchService.HandleDialplanRequest(requestBody); + } else - m_log.WarnFormat("[FreeSwitchVoice]: Unknown section {0} was requested.", section); + m_log.WarnFormat("[FreeSwitchVoice]: Unknown section {0} was requested from config.", section); return response; } -- cgit v1.1 From d8ee0cbe1cf93ca521f52ce39aa2a15cb5784e48 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 09:24:15 -0700 Subject: First stab at cleaning up Caps. Compiles. Untested. --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 3 +-- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 8c01d75..dcbcd85 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -34,7 +34,6 @@ using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -472,7 +471,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); + queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index a8dec63..d9168b0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -39,7 +39,6 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -1154,7 +1153,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); + queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); } } -- cgit v1.1 From 3e79842312ace5b4294e3d6501b1d35ffea5f1b5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 11:03:22 -0700 Subject: Renamed OpenSim.Framework.Capabilities.dll to OpenSim.Capabilities.dll --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 -- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 1 - 2 files changed, 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index dcbcd85..2bf8489 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -37,8 +37,6 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Capabilities.Caps; - namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d9168b0..1c791b9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; -using Caps = OpenSim.Framework.Capabilities.Caps; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; -- cgit v1.1 From d4fcba08af080bcc60da490155cc88d3f20e7dda Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 7 May 2011 01:06:55 +0100 Subject: Add module with "appearance show" command. At the moment, this command just asks the AvatarFactory to perform the existing baked texture check for each avatar in the simulator and returns "OK" or "corrupt". This is for debugging purposes --- .../Avatar/Appearance/AppearanceInfoModule.cs | 122 +++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs new file mode 100644 index 0000000..8589901 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -0,0 +1,122 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Appearance +{ + /// + /// A module that just holds commands for inspecting avatar appearance. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AppearanceInfoModule")] + public class AppearanceInfoModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected Dictionary m_scenes = new Dictionary(); + protected IAvatarFactory m_avatarFactory; + + public string Name { get { return "Appearance Information Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Remove(scene.RegionInfo.RegionID); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes[scene.RegionInfo.RegionID] = scene; + + scene.AddCommand( + this, "appearance show", + "appearance show", + "Show appearance information for each avatar in the simulator. At the moment, ", + ShowAppearanceInfo); + } + + protected void ShowAppearanceInfo(string module, string[] cmd) + { + lock (m_scenes) + { + foreach (Scene scene in m_scenes.Values) + { + scene.ForEachClient( + delegate(IClientAPI client) + { + if (client is LLClientView && !((LLClientView)client).ChildAgentStatus()) + { + bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(client); + MainConsole.Instance.OutputFormat( + "{0} baked apperance texture is {1}", client.Name, bakedTextureValid ? "OK" : "corrupt"); + } + }); + } + } + } + } +} \ No newline at end of file -- cgit v1.1 From bb9b317f1521720a6da98c6f21735126d9c060ce Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 21 May 2011 01:05:20 +0100 Subject: Get rid of OpenSim.Tests.Common.Setup subpackage in favour of just OpenSim.Tests.Common instead --- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index 6de97b7..ee52a39 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -35,7 +35,6 @@ using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Scenes; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; -using OpenSim.Tests.Common.Setup; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests { -- cgit v1.1 From 91ec1a572ab82b67a3e3090bb9d90009c294ef99 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 26 May 2011 02:48:47 +0100 Subject: improve help information for "appearance show" at the moment, this just performs a baked avatar check for everybody in the region. If the check returns 'corrupt' then a baked texture is missing and other avatars will continue to see the gas ball. --- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 8589901..7304145 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -95,8 +95,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance scene.AddCommand( this, "appearance show", "appearance show", - "Show appearance information for each avatar in the simulator. At the moment, ", - ShowAppearanceInfo); + "Show appearance information for each avatar in the simulator.", + "At the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", + ShowAppearanceInfo); } protected void ShowAppearanceInfo(string module, string[] cmd) -- cgit v1.1 From c4b265aeae712432bebaca1aa3c97bbafe14e3e2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 18:47:13 +0100 Subject: update libomv libraries to 0.9.0 this is a prerequisite to fixing llDialog issues for the latest Linden viewers, since they are now making use of a new OwnerData field in the ScriptDialog message --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 1c791b9..05223e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,20 +1231,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - if (requestingClient.AgentId != dataForAgentID) - { + // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for + // those with a GodLike aspect. + Scene c_scene = (Scene) requestingClient.Scene; + bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); + + if(is_god) { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.FindAll(showInProfile).ToArray(); + membershipArray = membershipData.ToArray(); } else { - membershipArray = membershipData.ToArray(); - } + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + } if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1257,6 +1273,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From 392d270264610e7c20cb4becedc652843715ef30 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 18:49:38 +0100 Subject: revert the patch that accidentally got added in the last commit --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++------------------ 1 file changed, 5 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 05223e0..1c791b9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,36 +1231,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for - // those with a GodLike aspect. - Scene c_scene = (Scene) requestingClient.Scene; - bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); - - if(is_god) { + if (requestingClient.AgentId != dataForAgentID) + { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.ToArray(); + membershipArray = membershipData.FindAll(showInProfile).ToArray(); } else { - - if (requestingClient.AgentId != dataForAgentID) - { - Predicate showInProfile = delegate(GroupMembershipData membership) - { - return membership.ListInProfile; - }; - - membershipArray = membershipData.FindAll(showInProfile).ToArray(); - } - else - { - membershipArray = membershipData.ToArray(); - } + membershipArray = membershipData.ToArray(); } + if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1273,7 +1257,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } - private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From 8129e64e2acea6509d5c3a80425f6aa68baa037c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 31 May 2011 19:25:01 +0100 Subject: Fill in the new OwnerData field in the LLUDP ScriptDialog message. If we don't do this then viewer 2.8 crashes. Resolves http://opensimulator.org/mantis/view.php?id=5510 --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 1c791b9..05223e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,20 +1231,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - if (requestingClient.AgentId != dataForAgentID) - { + // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for + // those with a GodLike aspect. + Scene c_scene = (Scene) requestingClient.Scene; + bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); + + if(is_god) { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.FindAll(showInProfile).ToArray(); + membershipArray = membershipData.ToArray(); } else { - membershipArray = membershipData.ToArray(); - } + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + } if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1257,6 +1273,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From 8bacf56e46413edaf2d6afc227ff6bb5f2ac4d4d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 1 Jun 2011 20:51:38 +0100 Subject: revert the prematurely included groups patch, yet again --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++------------------ 1 file changed, 5 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 05223e0..1c791b9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1231,36 +1231,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - // c_scene and property accessor 'is_god' are in support of the opertions to bypass 'hidden' group attributes for - // those with a GodLike aspect. - Scene c_scene = (Scene) requestingClient.Scene; - bool is_god = c_scene.Permissions.IsGod(requestingClient.AgentId); - - if(is_god) { + if (requestingClient.AgentId != dataForAgentID) + { Predicate showInProfile = delegate(GroupMembershipData membership) { return membership.ListInProfile; }; - membershipArray = membershipData.ToArray(); + membershipArray = membershipData.FindAll(showInProfile).ToArray(); } else { - - if (requestingClient.AgentId != dataForAgentID) - { - Predicate showInProfile = delegate(GroupMembershipData membership) - { - return membership.ListInProfile; - }; - - membershipArray = membershipData.FindAll(showInProfile).ToArray(); - } - else - { - membershipArray = membershipData.ToArray(); - } + membershipArray = membershipData.ToArray(); } + if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1273,7 +1257,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } - private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From c43ad8a0e7728c41ed2a4aed6a8b76678aaa7071 Mon Sep 17 00:00:00 2001 From: James Stallings aka Hiro Protagonist Date: Tue, 31 May 2011 19:33:40 -0500 Subject: A final couple of tweaks to GroupsModule.cs. Remove unneeded delegate, and prettify codeing style/formatting --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 31 +++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 1c791b9..61c5503 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1223,6 +1223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Get a list of groups memberships for the agent that are marked "ListInProfile" + /// (unless that agent has a godLike aspect, in which case get all groups) /// /// /// @@ -1231,20 +1232,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; - if (requestingClient.AgentId != dataForAgentID) - { - Predicate showInProfile = delegate(GroupMembershipData membership) - { - return membership.ListInProfile; - }; + // cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for + // those with a GodLike aspect. + Scene cScene = (Scene) requestingClient.Scene; + bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId); - membershipArray = membershipData.FindAll(showInProfile).ToArray(); + if (isGod) { + membershipArray = membershipData.ToArray(); } else { - membershipArray = membershipData.ToArray(); - } + if (requestingClient.AgentId != dataForAgentID) + { + Predicate showInProfile = delegate(GroupMembershipData membership) + { + return membership.ListInProfile; + }; + + membershipArray = membershipData.FindAll(showInProfile).ToArray(); + } + else + { + membershipArray = membershipData.ToArray(); + } + } if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); @@ -1257,6 +1269,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return membershipArray; } + private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From a3e0895f12fa81074138a356c01fbcbc40d6aba2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 1 Jun 2011 20:55:03 +0100 Subject: a few minor formatting tweaks --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 61c5503..630fcab 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1234,15 +1234,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for // those with a GodLike aspect. - Scene cScene = (Scene) requestingClient.Scene; + Scene cScene = (Scene)requestingClient.Scene; bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId); - if (isGod) { + if (isGod) + { membershipArray = membershipData.ToArray(); } else { - if (requestingClient.AgentId != dataForAgentID) { Predicate showInProfile = delegate(GroupMembershipData membership) @@ -1257,6 +1257,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups membershipArray = membershipData.ToArray(); } } + if (m_debugEnabled) { m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); -- cgit v1.1 From de20f0603fa419ba16c56d16c2ad55301cad8b83 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 24 Jun 2011 19:49:05 +0100 Subject: Tell hypergridders when their teleports fail because of the 4096 limit rather than just saying "destination not found" Instead of performing the 4096 check when the region is linked (and subsequently removing the link), leave the link in place and perform the check in the entity transfer module This allows us to explicitly tell the hypergridder why the teleport failed (region out of range). It also allows people on regions that are within range (on a large source grid) to teleport. The Check4096 config parameter in the [GridService] section is replaced by a max_distance paramter in a new [EntityTransfer] section in OpenSimDefaults.ini Since the parameter is in OpenSimDefaults.ini no action needs to be taken unless you want to increase this limit. It could also be decreased. The check is being made in the base entity transfer module, since I believe the viewer problem occurs both on extremely large grids and while hypergridding. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 42efd67..a5bba4f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -417,9 +417,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param, UUID agentID, Caps caps) { -// m_log.DebugFormat( -// "[FreeSwitchVoice][PARCELVOICE]: ParcelVoiceInfoRequest() on {0} for {1}", -// scene.RegionInfo.RegionName, agentID); + m_log.DebugFormat( + "[FreeSwitchVoice][PARCELVOICE]: ParcelVoiceInfoRequest() on {0} for {1}", + scene.RegionInfo.RegionName, agentID); ScenePresence avatar = scene.GetScenePresence(agentID); string avatarName = avatar.Name; @@ -885,4 +885,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice #endregion } -} \ No newline at end of file +} -- cgit v1.1 From 7545692f32a6d5326c008464dda1bd3b0ebd5a08 Mon Sep 17 00:00:00 2001 From: Makopoppo Date: Mon, 13 Jun 2011 22:09:03 +0900 Subject: Changed actual default values of 'ServiceConnectorModule' and 'MessagingModule' in [Groups] section in accordance with OpenSim.ini.example descriptions --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 +- .../Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | 2 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 2bf8489..0800e98 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // if groups aren't enabled, we're not needed. // if we're not specified as the connector to use, then we're not wanted if ((groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("MessagingModule", "Default") != Name)) + || (groupsConfig.GetString("MessagingModule", "GroupsMessagingModule") != Name)) { m_groupMessagingEnabled = false; return; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 02751ea..42008da 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -200,7 +200,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // if groups aren't enabled, we're not needed. // if we're not specified as the connector to use, then we're not wanted if ((groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) + || (groupsConfig.GetString("ServicesConnectorModule", "XmlRpcGroupsServicesConnector") != Name)) { m_connectorEnabled = false; return; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 2631ac1..a08bcd0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -109,7 +109,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // if groups aren't enabled, we're not needed. // if we're not specified as the connector to use, then we're not wanted if ((groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) + || (groupsConfig.GetString("ServicesConnectorModule", "XmlRpcGroupsServicesConnector") != Name)) { m_connectorEnabled = false; return; -- cgit v1.1 From 22f25fae387a801e8545f6ab6e2c9700926ae6e4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 29 Jun 2011 00:28:22 +0100 Subject: Hack around with the NPC module to get osNpcCreate() partially working again. This now creates an avatar but appearance is always cloudy. Move doesn't work. Really, creating an NPC should only involve a ScenePresence rather than doing anything with IClientAPI, since an NPC has no viewer to communicate with! --- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 7304145..77e7acf 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(client); MainConsole.Instance.OutputFormat( - "{0} baked apperance texture is {1}", client.Name, bakedTextureValid ? "OK" : "corrupt"); + "{0} baked appearance texture is {1}", client.Name, bakedTextureValid ? "OK" : "corrupt"); } }); } -- cgit v1.1 From bda1a4be4567181df6c18ce6e059ca8982bc5fa1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 00:26:37 +0100 Subject: rename test SceneSetupHelpers -> SceneHelpers for consistency --- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index ee52a39..1e56a08 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -50,13 +50,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneSetupHelpers.SetupScene(); + TestScene scene = SceneHelpers.SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Groups"); config.Set("Enabled", true); config.Set("Module", "GroupsModule"); config.Set("DebugEnabled", true); - SceneSetupHelpers.SetupSceneModules( + SceneHelpers.SetupSceneModules( scene, configSource, new object[] { new MockGroupsServicesConnector() }); } } -- cgit v1.1 From dad1d6df181151ae45fb998447b58d5589459627 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 6 Aug 2011 00:31:03 +0100 Subject: rename TestHelper => TestHelpers for consistency --- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index 1e56a08..d2f6327 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests [Test] public void TestBasic() { - TestHelper.InMethod(); + TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); TestScene scene = SceneHelpers.SetupScene(); -- cgit v1.1 From ca74088d942393fedc143dfa547f3c7951a077bd Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 12 Oct 2011 09:21:46 +0100 Subject: Change default groups messaging module in hardcode to the empty string. Modules should not assume thet they are the one and only, but only be enabled when explicitly configured. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 0800e98..a12e6ea 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // if groups aren't enabled, we're not needed. // if we're not specified as the connector to use, then we're not wanted if ((groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("MessagingModule", "GroupsMessagingModule") != Name)) + || (groupsConfig.GetString("MessagingModule", "") != Name)) { m_groupMessagingEnabled = false; return; -- cgit v1.1 From da794f34a56f7c88904315ae538de8f3790e6891 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Wed, 19 Oct 2011 14:41:44 -0700 Subject: Renamed and rearranged AvatarFactoryModule to eliminate redundant lookups of scene presence by client ID. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 77e7acf..2cef8a9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Dictionary m_scenes = new Dictionary(); - protected IAvatarFactory m_avatarFactory; + protected IAvatarFactoryModule m_avatarFactory; public string Name { get { return "Appearance Information Module"; } } @@ -106,14 +106,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { foreach (Scene scene in m_scenes.Values) { - scene.ForEachClient( - delegate(IClientAPI client) + scene.ForEachScenePresence( + delegate(ScenePresence sp) { - if (client is LLClientView && !((LLClientView)client).ChildAgentStatus()) + if (sp.ControllingClient is LLClientView && !((LLClientView)sp.ControllingClient).ChildAgentStatus()) { - bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(client); + bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); MainConsole.Instance.OutputFormat( - "{0} baked appearance texture is {1}", client.Name, bakedTextureValid ? "OK" : "corrupt"); + "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); } }); } -- cgit v1.1 From 8a0a78cbccce796addacab7ed1609279b802a9b3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 25 Oct 2011 20:24:21 +0100 Subject: Make OpenSim.Framework.Servers.HttpServer rely on OpenSim.Framework instead of the other way around. This is necessary so that code in HttpServer can use framework facilities such as the thread watchdog for monitoring purposes. Doing this shuffle meant that MainServer was moved into OpenSim/Framework/Servers Also had to make OpenSim.Framework.Console rely on OpenSim.Framework rather than the other way around since it in turn relies on HttpServer MainConsole and some new interfaces had to be moved into OpenSim/Framework to allow this. This can be reverted if parts of OpenSim.Framework stop relying on console presence (cheifly RegionInfo) --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index d49a489..913d934 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -34,6 +34,7 @@ using log4net; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; +using OpenSim.Framework.Servers; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -- cgit v1.1 From b98613091cd6dc2f914fb5ab38ca33cdff21fc24 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 27 Oct 2011 00:42:21 -0700 Subject: Added new ForEachRootScenePresence to Scene since almost every delegate passed to ForEachScenePresence checks for !IsChildAgent first. It consolidates child and root handling for coming refactors. --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 0d6313a..e22618d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -373,13 +373,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge scene.GetRootAgentCount(), scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); - scene.ForEachScenePresence(delegate(ScenePresence sp) + scene.ForEachRootScenePresence(delegate(ScenePresence sp) { - if (!sp.IsChildAgent) - { list.Append(String.Format(" \n", sp.Name, sp.UUID)); list.Append(""); - } }); string payload = list.ToString(); -- cgit v1.1 From 272bf712796ad8e98e79aee50311a84deaf23d79 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 27 Oct 2011 02:26:37 -0700 Subject: Removed use of 'is' operator and casting to find the root ScenePresence in MessageTransfer modules and Groups module. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 15 +++++++-------- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 11 +++++------ 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index a12e6ea..10b83e6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -504,19 +504,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Try root avatar first foreach (Scene scene in m_sceneList) { - if (scene.Entities.ContainsKey(agentID) && - scene.Entities[agentID] is ScenePresence) + ScenePresence sp = scene.GetScenePresence(agentID); + if (sp != null) { - ScenePresence user = (ScenePresence)scene.Entities[agentID]; - if (!user.IsChildAgent) + if (!sp.IsChildAgent) { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); - return user.ControllingClient; + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name); + return sp.ControllingClient; } else { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); - child = user.ControllingClient; + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name); + child = sp.ControllingClient; } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 630fcab..b2c0f48 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1076,17 +1076,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Try root avatar first foreach (Scene scene in m_sceneList) { - if (scene.Entities.ContainsKey(agentID) && - scene.Entities[agentID] is ScenePresence) + ScenePresence sp = scene.GetScenePresence(agentID); + if (sp != null) { - ScenePresence user = (ScenePresence)scene.Entities[agentID]; - if (!user.IsChildAgent) + if (!sp.IsChildAgent) { - return user.ControllingClient; + return sp.ControllingClient; } else { - child = user.ControllingClient; + child = sp.ControllingClient; } } } -- cgit v1.1 From 9456a540c50b90d2c2cdb1b556e9d6190f817426 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 1 Nov 2011 23:23:45 +0000 Subject: Add "appearance send" command to allow manual sending of appearance. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 2cef8a9..f8120aa 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -98,7 +98,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance "Show appearance information for each avatar in the simulator.", "At the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", ShowAppearanceInfo); - } + + scene.AddCommand( + this, "appearance send", + "appearance send", + "Send appearance data for each avatar in the simulator to viewers.", + SendAppearance); + } + + private void SendAppearance(string module, string[] cmd) + { + lock (m_scenes) + { + foreach (Scene scene in m_scenes.Values) + { + scene.ForEachRootScenePresence(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); + } + } + } protected void ShowAppearanceInfo(string module, string[] cmd) { -- cgit v1.1 From 08fcf958c278c703a790fd964a5af74425bcf67d Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Nov 2011 23:50:47 +0000 Subject: Port the Avination offline messaging system to Core --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b2c0f48..d452905 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -881,7 +881,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.dialog = dialog; // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; msg.fromGroup = true; - msg.offline = (byte)1; // Allow this message to be stored for offline use + msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; -- cgit v1.1 From 94dc7d07ebc22ce0e0d9b77e91538ddc90799bee Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 3 Nov 2011 17:06:08 -0700 Subject: Renamed ForEachRootScenePresence to ForEachAvatar. Cleaned up calls to the 3 iteration functions so more of them are using the correct iteration for the action they are performing. The 3 iterators that seem to fit all actions within OpenSim at this time are: ForEachAvatar: Perform an action on all avatars (root presences) ForEachClient: Perform an action on all clients (root or child clients) ForEachRootClient: Perform an action on all clients that have an avatar There are still a dozen places or so calling the old ForEachScenePresence that will take a little more refactoring to eliminate. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 13 +++++-------- .../OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index f8120aa..5a3a62f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -112,7 +112,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { foreach (Scene scene in m_scenes.Values) { - scene.ForEachRootScenePresence(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); + scene.ForEachAvatar(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); } } } @@ -123,15 +123,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { foreach (Scene scene in m_scenes.Values) { - scene.ForEachScenePresence( + scene.ForEachAvatar( delegate(ScenePresence sp) { - if (sp.ControllingClient is LLClientView && !((LLClientView)sp.ControllingClient).ChildAgentStatus()) - { - bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); - MainConsole.Instance.OutputFormat( - "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); - } + bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); + MainConsole.Instance.OutputFormat( + "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); }); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index e22618d..bea5807 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -373,7 +373,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge scene.GetRootAgentCount(), scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); - scene.ForEachRootScenePresence(delegate(ScenePresence sp) + scene.ForEachAvatar(delegate(ScenePresence sp) { list.Append(String.Format(" \n", sp.Name, sp.UUID)); list.Append(""); -- cgit v1.1 From b8d50b10fbb03ed8c8a9aac94564c354559c3bb0 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 3 Nov 2011 17:53:51 -0700 Subject: Rename ForEachAvatar back to ForEachScenePresence. The other changes from previous commit which sort out which iterator is used are left intact. A discussion is needed as to what constitutes an avatar vs a ScenePresence. --- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 4 ++-- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 5a3a62f..28f04b3 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -112,7 +112,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { foreach (Scene scene in m_scenes.Values) { - scene.ForEachAvatar(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); + scene.ForEachRootScenePresence(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); } } } @@ -123,7 +123,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { foreach (Scene scene in m_scenes.Values) { - scene.ForEachAvatar( + scene.ForEachRootScenePresence( delegate(ScenePresence sp) { bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index bea5807..e22618d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -373,7 +373,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge scene.GetRootAgentCount(), scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); - scene.ForEachAvatar(delegate(ScenePresence sp) + scene.ForEachRootScenePresence(delegate(ScenePresence sp) { list.Append(String.Format(" \n", sp.Name, sp.UUID)); list.Append(""); -- cgit v1.1 From 4567555c49cb560dd6f109bbfec42086af3de56f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 5 Dec 2011 20:44:20 +0000 Subject: Implement IOSHttpRequest and IOSHttpResponse http interfaces and use instead of OSHttpRequest/OSHttpResponse. This is required for the substitution of different HTTP servers or the newer HttpServer.dll without having to commit to a particular implementation. This is also required to write regression tests that involve the HTTP layer. If you need to recompile, all you need to do is replace OSHttpRequest/OSHttpResponse references with IOSHttpRequest/IOSHttpResponse. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index a5bba4f..5323a95 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -309,7 +309,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice caps.RegisterHandler("ProvisionVoiceAccountRequest", new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) + IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps); @@ -317,7 +317,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice caps.RegisterHandler("ParcelVoiceInfoRequest", new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) + IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps); @@ -325,7 +325,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice caps.RegisterHandler("ChatSessionRequest", new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) + IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return ChatSessionRequest(scene, request, path, param, agentID, caps); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 534bf92..70e2f7e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -421,7 +421,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice caps.RegisterHandler("ProvisionVoiceAccountRequest", new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) + IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps); @@ -429,7 +429,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice caps.RegisterHandler("ParcelVoiceInfoRequest", new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) + IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps); @@ -437,7 +437,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice caps.RegisterHandler("ChatSessionRequest", new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, delegate(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) + IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return ChatSessionRequest(scene, request, path, param, agentID, caps); -- cgit v1.1 From d33d12ba83fae18d720ef24b56cba5c17688d386 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 6 Dec 2011 16:07:24 +0000 Subject: Provide feedback as to which avatars are resending appearance informion on "appearance send" console command --- .../Avatar/Appearance/AppearanceInfoModule.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 28f04b3..59ad008 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AppearanceInfoModule")] public class AppearanceInfoModule : ISharedRegionModule { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Dictionary m_scenes = new Dictionary(); protected IAvatarFactoryModule m_avatarFactory; @@ -112,7 +112,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { foreach (Scene scene in m_scenes.Values) { - scene.ForEachRootScenePresence(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); + scene.ForEachRootScenePresence( + sp => + { + MainConsole.Instance.OutputFormat( + "Sending appearance information for {0} to all other avatars in {1}", + sp.Name, scene.RegionInfo.RegionName); + + scene.AvatarFactory.SendAppearance(sp.UUID); + } + ); } } } -- cgit v1.1 From 4be85eeaa53029381c9f6e0fec7ab18ab59eef06 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 6 Dec 2011 16:42:28 +0000 Subject: Make it possible to manually send appearance information via the "appearance send" command for a chosen avatar as well as all --- .../Avatar/Appearance/AppearanceInfoModule.cs | 53 +++++++++++++++++----- 1 file changed, 42 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 59ad008..c6ee36b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -97,36 +97,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance "appearance show", "Show appearance information for each avatar in the simulator.", "At the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", - ShowAppearanceInfo); + HandleShowAppearanceCommand); scene.AddCommand( this, "appearance send", - "appearance send", - "Send appearance data for each avatar in the simulator to viewers.", - SendAppearance); + "appearance send [ ]", + "Send appearance data for each avatar in the simulator to other viewers." + + "\nOptionally, you can specify that only a particular avatar's information is sent.", + HandleSendAppearanceCommand); } - private void SendAppearance(string module, string[] cmd) + private void HandleSendAppearanceCommand(string module, string[] cmd) { + if (cmd.Length != 2 && cmd.Length < 4) + { + MainConsole.Instance.OutputFormat("Usage: appearance send [ ]"); + return; + } + + bool targetNameSupplied = false; + string optionalTargetFirstName = null; + string optionalTargetLastName = null; + + if (cmd.Length >= 4) + { + targetNameSupplied = true; + optionalTargetFirstName = cmd[2]; + optionalTargetLastName = cmd[3]; + } + lock (m_scenes) { foreach (Scene scene in m_scenes.Values) { - scene.ForEachRootScenePresence( - sp => + if (targetNameSupplied) + { + ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); + if (sp != null && !sp.IsChildAgent) { MainConsole.Instance.OutputFormat( "Sending appearance information for {0} to all other avatars in {1}", sp.Name, scene.RegionInfo.RegionName); - - scene.AvatarFactory.SendAppearance(sp.UUID); } - ); + } + else + { + scene.ForEachRootScenePresence( + sp => + { + MainConsole.Instance.OutputFormat( + "Sending appearance information for {0} to all other avatars in {1}", + sp.Name, scene.RegionInfo.RegionName); + + scene.AvatarFactory.SendAppearance(sp.UUID); + } + ); + } } } } - protected void ShowAppearanceInfo(string module, string[] cmd) + protected void HandleShowAppearanceCommand(string module, string[] cmd) { lock (m_scenes) { -- cgit v1.1 From 1b9eb5285033839bdc1b948ec085aa8736473ad6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 6 Dec 2011 18:03:16 +0000 Subject: Allow "appearance show" command to take an optional avatar name --- .../Avatar/Appearance/AppearanceInfoModule.cs | 48 ++++++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index c6ee36b..7f3f365 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -96,14 +96,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance this, "appearance show", "appearance show", "Show appearance information for each avatar in the simulator.", - "At the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", + "Optionally, you can view just a particular avatar's appearance information" + + "\nAt the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", HandleShowAppearanceCommand); scene.AddCommand( this, "appearance send", "appearance send [ ]", - "Send appearance data for each avatar in the simulator to other viewers." - + "\nOptionally, you can specify that only a particular avatar's information is sent.", + "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); } @@ -148,7 +149,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance MainConsole.Instance.OutputFormat( "Sending appearance information for {0} to all other avatars in {1}", sp.Name, scene.RegionInfo.RegionName); - + scene.AvatarFactory.SendAppearance(sp.UUID); } ); @@ -158,18 +159,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance } protected void HandleShowAppearanceCommand(string module, string[] cmd) - { + { + if (cmd.Length != 2 && cmd.Length < 4) + { + MainConsole.Instance.OutputFormat("Usage: appearance show [ ]"); + return; + } + + bool targetNameSupplied = false; + string optionalTargetFirstName = null; + string optionalTargetLastName = null; + + if (cmd.Length >= 4) + { + targetNameSupplied = true; + optionalTargetFirstName = cmd[2]; + optionalTargetLastName = cmd[3]; + } + lock (m_scenes) { foreach (Scene scene in m_scenes.Values) { - scene.ForEachRootScenePresence( - delegate(ScenePresence sp) + if (targetNameSupplied) + { + ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); + if (sp != null && !sp.IsChildAgent) { bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); MainConsole.Instance.OutputFormat( "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); - }); + } + } + else + { + scene.ForEachRootScenePresence( + sp => + { + bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); + MainConsole.Instance.OutputFormat( + "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); + } + ); + } } } } -- cgit v1.1 From ec4f217af8bb5ff90978ba068860ed38e75d40f8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 6 Dec 2011 18:06:29 +0000 Subject: Actually send the avatar data if an individual avatar is specified, rather than accidentally doing nothing --- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 7f3f365..b6dfc5c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -139,6 +139,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance MainConsole.Instance.OutputFormat( "Sending appearance information for {0} to all other avatars in {1}", sp.Name, scene.RegionInfo.RegionName); + + scene.AvatarFactory.SendAppearance(sp.UUID); } } else -- cgit v1.1 From b9a461c5ad10753e98a17b17858cc3b2eae568ea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 6 Dec 2011 18:32:27 +0000 Subject: In "appearance show", if a particular avatar is specified, print out texture UUID for each bake type and whether the simulator can find it. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 40 +++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index b6dfc5c..b949059 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -49,9 +49,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance public class AppearanceInfoModule : ISharedRegionModule { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected Dictionary m_scenes = new Dictionary(); - protected IAvatarFactoryModule m_avatarFactory; + + public const string SHOW_APPEARANCE_FORMAT = "{0,-9} {1}"; + + private Dictionary m_scenes = new Dictionary(); + private IAvatarFactoryModule m_avatarFactory; public string Name { get { return "Appearance Information Module"; } } @@ -96,8 +98,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance this, "appearance show", "appearance show", "Show appearance information for each avatar in the simulator.", - "Optionally, you can view just a particular avatar's appearance information" - + "\nAt the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", + "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " + + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." + + "\nOptionally, you can view just a particular avatar's appearance information." + + "\nIn this case, the texture UUID for each bake type is also shown and whether the simulator can find the referenced texture.", HandleShowAppearanceCommand); scene.AddCommand( @@ -188,6 +192,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); if (sp != null && !sp.IsChildAgent) { + MainConsole.Instance.OutputFormat("For {0} in {1}", sp.Name, scene.RegionInfo.RegionName); + MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, "Bake Type", "UUID"); + + Dictionary bakedTextures + = scene.AvatarFactory.GetBakedTextureFaces(sp.UUID); + foreach (BakeType bt in bakedTextures.Keys) + { + string rawTextureID; + + if (bakedTextures[bt] == null) + { + rawTextureID = "not set"; + } + else + { + rawTextureID = bakedTextures[bt].TextureID.ToString(); + + if (scene.AssetService.Get(rawTextureID) == null) + rawTextureID += " (not found)"; + else + rawTextureID += " (uploaded)"; + } + + MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, bt, rawTextureID); + } + bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); MainConsole.Instance.OutputFormat( "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); -- cgit v1.1 From 136a6a6e0fe7bcb5d24675dae2c3c538df404d62 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 6 Dec 2011 18:36:11 +0000 Subject: Make "show appearance" a synonym for "appearance show" --- .../OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index b949059..89704d5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -92,11 +92,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); lock (m_scenes) - m_scenes[scene.RegionInfo.RegionID] = scene; + m_scenes[scene.RegionInfo.RegionID] = scene; + + scene.AddCommand( + this, "show appearance", + "show appearance [ ]", + "Synonym for 'appearance show'", + HandleShowAppearanceCommand); scene.AddCommand( this, "appearance show", - "appearance show", + "appearance show [ ]", "Show appearance information for each avatar in the simulator.", "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." -- cgit v1.1 From e88ad5aab99886eb70caf37627e8a6e3fc840e6e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 9 Dec 2011 23:55:54 +0000 Subject: minor: remove a mono compiler warning --- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 89704d5..40cbc60 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -53,7 +53,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance public const string SHOW_APPEARANCE_FORMAT = "{0,-9} {1}"; private Dictionary m_scenes = new Dictionary(); - private IAvatarFactoryModule m_avatarFactory; +// private IAvatarFactoryModule m_avatarFactory; public string Name { get { return "Appearance Information Module"; } } -- cgit v1.1 From a9b39d6e5d7961a03043e4a793dce8534035214a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 16 Dec 2011 20:53:50 +0000 Subject: Tunnel [GroupsModule] DebugEnabled setting down into XmlRpcGroupsServicesConnectorModule so that we can record cache misses --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 9 +-------- .../XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 12 +++++++++--- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d452905..8baeaa4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -29,25 +29,18 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Timers; - using log4net; using Mono.Addins; using Nini.Config; - using OpenMetaverse; using OpenMetaverse.StructuredData; - using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; - using OpenSim.Services.Interfaces; - using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; - - namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] @@ -90,7 +83,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Configuration settings private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; - private bool m_debugEnabled = true; + private bool m_debugEnabled = false; #region IRegionModuleBase Members diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index a08bcd0..52fc27d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -52,6 +52,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private bool m_debugEnabled = false; + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | @@ -81,7 +83,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); - #region IRegionModuleBase Members public string Name @@ -115,7 +116,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); if ((m_groupsServerURI == null) || @@ -142,6 +143,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); } + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); + // If we got all the config options we need, lets start'er'up m_memoryCache = new ExpiringCache(); m_connectorEnabled = true; @@ -150,7 +153,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { - m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -958,6 +961,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (resp == null) { + if (m_debugEnabled) + m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Cache miss for key {0}", CacheKey); + string UserService; UUID SessionID; GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); -- cgit v1.1 From f9137c923bcdc952efe37c7dd328c2d0d8323317 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 17 Dec 2011 02:23:24 +0000 Subject: Fix bug where objects could not be set to a new group if the group had been created in that client session, or if no other action has been performed on the object. There were two problems here: 1) On object group update, we looked for the group is the IClientAPI group cache rather than in the groups service. This fails to groups created newly in that session 2) On object group update, we weren't setting the HasGroupChanged flag. This meant that the change was not persisted unless some other action set this flag. This commit fixes these issues and hopefully addresses http://opensimulator.org/mantis/view.php?id=5588 This commit also moves HandleObjectGroupUpdate() to the GroupsModule from the Scene.PacketHandlers.cs file --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 +++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8baeaa4..9969a15 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -218,6 +218,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; + client.OnObjectGroupRequest += HandleObjectGroupUpdate; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnDirFindQuery += OnDirFindQuery; client.OnRequestAvatarProperties += OnRequestAvatarProperties; @@ -225,7 +226,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - // Send client thier groups information. + // Send client their groups information. SendAgentGroupDataUpdate(client, client.AgentId); } @@ -328,6 +329,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendGroupNameReply(GroupID, GroupName); } + private void HandleObjectGroupUpdate( + IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) + { + GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); + + if (gmd == null) + { +// m_log.WarnFormat( +// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", +// remoteClient.Name, GroupID, objectLocalID); + + return; + } + + SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID); + if (so != null) + { + if (so.OwnerID == remoteClient.AgentId) + { + so.SetGroup(GroupID, remoteClient); + } + } + } + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From 684482352c2f580f2868704e2ba2236a751c5bc4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 17 Dec 2011 02:35:08 +0000 Subject: Fix bug where objects couldn't be set back to the "none" group. This is handled by treating UUID.Zero as a special case. Currently, asking for the "none" group returns nothing because XMLRPC groups, at least, is not properly handling this case. It may be better in the future to have GroupsModule return an appropriate GroupsData structure instead or require the underlying services to behave appropriately. This is a further component of http://opensimulator.org/mantis/view.php?id=5588 --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 9969a15..e959821 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -332,15 +332,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void HandleObjectGroupUpdate( IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) { - GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); - - if (gmd == null) + // XXX: Might be better to get rid of this special casing and have GetMembershipData return something + // reasonable for a UUID.Zero group. + if (GroupID != UUID.Zero) { -// m_log.WarnFormat( -// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", -// remoteClient.Name, GroupID, objectLocalID); - - return; + GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); + + if (gmd == null) + { +// m_log.WarnFormat( +// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", +// remoteClient.Name, GroupID, objectLocalID); + + return; + } } SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID); -- cgit v1.1 From 0b91ec8dd2b78461cb0fcdec567a83e88a76ac87 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 19 Dec 2011 18:58:05 +0000 Subject: Migrate detailed "appearance show" report generation up to AvatarFactoryModule from AppearanceInfoModule so that it can be used in debug (inactive). Further filters "debug packet " to exclused [Request]ObjectPropertiesFamily if level is below 25. Adjust some method doc Minor changes to some logging messages. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 34 +--------------------- 1 file changed, 1 insertion(+), 33 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 40cbc60..1ce24f1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -50,8 +50,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public const string SHOW_APPEARANCE_FORMAT = "{0,-9} {1}"; - private Dictionary m_scenes = new Dictionary(); // private IAvatarFactoryModule m_avatarFactory; @@ -197,37 +195,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); if (sp != null && !sp.IsChildAgent) - { - MainConsole.Instance.OutputFormat("For {0} in {1}", sp.Name, scene.RegionInfo.RegionName); - MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, "Bake Type", "UUID"); - - Dictionary bakedTextures - = scene.AvatarFactory.GetBakedTextureFaces(sp.UUID); - foreach (BakeType bt in bakedTextures.Keys) - { - string rawTextureID; - - if (bakedTextures[bt] == null) - { - rawTextureID = "not set"; - } - else - { - rawTextureID = bakedTextures[bt].TextureID.ToString(); - - if (scene.AssetService.Get(rawTextureID) == null) - rawTextureID += " (not found)"; - else - rawTextureID += " (uploaded)"; - } - - MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, bt, rawTextureID); - } - - bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); - MainConsole.Instance.OutputFormat( - "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); - } + scene.AvatarFactory.WriteBakedTexturesReport(sp, MainConsole.Instance.OutputFormat); } else { -- cgit v1.1 From 87a2d8d51b66db12a487014deb8447fb2432e2a3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 19 Dec 2011 23:03:45 +0000 Subject: Move HandleObjectGroupUpdate() from GroupsModule to Scene.PacketHandlers.cs as this is updating SOG/SOP.GroupID, which is arguably generic. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 30 ---------------------- 1 file changed, 30 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index e959821..740dbdd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -218,7 +218,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; - client.OnObjectGroupRequest += HandleObjectGroupUpdate; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnDirFindQuery += OnDirFindQuery; client.OnRequestAvatarProperties += OnRequestAvatarProperties; @@ -329,35 +328,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendGroupNameReply(GroupID, GroupName); } - private void HandleObjectGroupUpdate( - IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) - { - // XXX: Might be better to get rid of this special casing and have GetMembershipData return something - // reasonable for a UUID.Zero group. - if (GroupID != UUID.Zero) - { - GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); - - if (gmd == null) - { -// m_log.WarnFormat( -// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", -// remoteClient.Name, GroupID, objectLocalID); - - return; - } - } - - SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID); - if (so != null) - { - if (so.OwnerID == remoteClient.AgentId) - { - so.SetGroup(GroupID, remoteClient); - } - } - } - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); -- cgit v1.1 From 8fb70a2058e98dea63e7ee7c5b55532668fccd38 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Jan 2012 22:45:07 +0000 Subject: Add "appearance rebake" command to ask a specific viewer to rebake textures from the server end. This is not as useful as it sounds, since you can only request rebakes for texture IDs already received. In other words, if the viewer has never sent the server this information (which happens quite often) then it will have no effect. Nonetheless, this is useful for diagnostic/debugging purposes. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 40 +++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 1ce24f1..7e15718 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 -- cgit v1.1 From c201b54b8524033310c59fe353616e84616a542e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 5 Jan 2012 19:40:54 +0000 Subject: Improve "app rebake" command to return a better message if no uploaded texture ids were available for the rebake request --- .../Avatar/Appearance/AppearanceInfoModule.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 7e15718..39cd4c9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -240,11 +240,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance 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); + int rebakesRequested = scene.AvatarFactory.RequestRebake(sp, false); - scene.AvatarFactory.RequestRebake(sp, false); + if (rebakesRequested > 0) + MainConsole.Instance.OutputFormat( + "Requesting rebake of {0} uploaded textures for {1} in {2}", + rebakesRequested, sp.Name, scene.RegionInfo.RegionName); + else + MainConsole.Instance.OutputFormat( + "No texture IDs available for rebake request for {0} in {1}", + sp.Name, scene.RegionInfo.RegionName); } } } -- cgit v1.1 From d67e8291c86beb5c3c8e8b11a7f95b49c834c779 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 10 Jan 2012 18:41:07 +0000 Subject: Add "app find " command to find the appearance using a particular baked texture, if any. This is for debugging to relate texture console entries back to particular users on the simulator end. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 39cd4c9..2369d94 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text; using log4net; @@ -124,6 +125,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance + "\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); + + scene.AddCommand( + this, "appearance find", + "appearance find ", + "Find out which avatar uses the given asset as a baked texture, if any.", + "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", + HandleFindAppearanceCommand); } private void HandleSendAppearanceCommand(string module, string[] cmd) @@ -254,5 +262,47 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance } } } + + protected void HandleFindAppearanceCommand(string module, string[] cmd) + { + if (cmd.Length != 3) + { + MainConsole.Instance.OutputFormat("Usage: appearance find "); + return; + } + + string rawUuid = cmd[2]; + + HashSet matchedAvatars = new HashSet(); + + lock (m_scenes) + { + foreach (Scene scene in m_scenes.Values) + { + scene.ForEachRootScenePresence( + sp => + { + Dictionary bakedFaces = scene.AvatarFactory.GetBakedTextureFaces(sp.UUID); + foreach (Primitive.TextureEntryFace face in bakedFaces.Values) + { + if (face != null && face.TextureID.ToString().StartsWith(rawUuid)) + matchedAvatars.Add(sp); + } + }); + } + } + + if (matchedAvatars.Count == 0) + { + MainConsole.Instance.OutputFormat("{0} did not match any baked avatar textures in use", rawUuid); + } + else + { + MainConsole.Instance.OutputFormat( + "{0} matched {1}", + rawUuid, + string.Join(", ", matchedAvatars.ToList().ConvertAll(sp => sp.Name).ToArray())); + } + } } } \ No newline at end of file -- cgit v1.1 From 7352aea9ac82c0c1a580ffd00d4436a8ea98f2b6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 28 Jan 2012 00:18:12 +0000 Subject: Remove IClientAPI from the money module. It was only used to pass in the agent id anyway --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 740dbdd..b60cd42 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -713,7 +713,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (money != null) { // do the transaction, that is if the agent has got sufficient funds - if (!money.AmountCovered(remoteClient, money.GroupCreationCharge)) { + if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); return UUID.Zero; } -- cgit v1.1 From 4589ce61bc68311d6ab7b5e7aa40ed1def40f52e Mon Sep 17 00:00:00 2001 From: PixelTomsen Date: Sat, 11 Feb 2012 19:00:01 +0100 Subject: Fix: get embedded objects from Notecard fails with activated FreeSwitchVoiceModul http://opensimulator.org/mantis/view.php?id=2607 --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 5323a95..05678c0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -63,9 +63,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Capability string prefixes - private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; - private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; - private static readonly string m_chatSessionRequestPath = "0009/"; + private static readonly string m_parcelVoiceInfoRequestPath = "0207/"; + private static readonly string m_provisionVoiceAccountRequestPath = "0208/"; + private static readonly string m_chatSessionRequestPath = "0209/"; // Control info private static bool m_Enabled = false; -- cgit v1.1 From a9e8bd59a377e7c7ce81e3693875467926dd7d4b Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 13 Feb 2012 19:38:22 -0800 Subject: Fix a race condition in the simian groups connector. When requests were too slow they would circumvent the cache (piling up on the network service and making the problem even worse). This condition happens frequently during permission checks. --- .../SimianGroupsServicesConnectorModule.cs | 71 +++++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 42008da..130513d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Reflection; +using System.Threading; using Nwc.XmlRpc; @@ -167,6 +168,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_debugEnabled = false; + private Dictionary m_pendingRequests = new Dictionary(); + private ExpiringCache m_memoryCache; private int m_cacheTimeout = 30; @@ -1348,6 +1351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Immediately forward the request if the cache is disabled. if (m_cacheTimeout == 0) { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: cache is disabled"); return WebUtil.PostToService(m_groupsServerURI, requestArgs); } @@ -1355,6 +1359,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (requestArgs["RequestMethod"] == "RemoveGeneric" || requestArgs["RequestMethod"] == "AddGeneric") { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache"); + // Any and all updates cause the cache to clear m_memoryCache.Clear(); @@ -1366,18 +1372,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Create the cache key for the request and see if we have it cached string CacheKey = WebUtil.BuildQueryString(requestArgs); - OSDMap response = null; - if (!m_memoryCache.TryGetValue(CacheKey, out response)) + + // This code uses a leader/follower pattern. On a cache miss, the request is added + // to a queue; the first thread to add it to the queue completes the request while + // follow on threads busy wait for the results, this situation seems to happen + // often when checking permissions + while (true) { - // if it wasn't in the cache, pass the request to the Simian Grid Services - response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + OSDMap response = null; + bool firstRequest = false; - // and cache the response - m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + lock (m_memoryCache) + { + if (m_memoryCache.TryGetValue(CacheKey, out response)) + return response; + + if (! m_pendingRequests.ContainsKey(CacheKey)) + { + m_pendingRequests.Add(CacheKey,true); + firstRequest = true; + } + } + + if (firstRequest) + { + // if it wasn't in the cache, pass the request to the Simian Grid Services + try + { + response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + } + catch (Exception e) + { + m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey); + } + + // and cache the response + lock (m_memoryCache) + { + m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + m_pendingRequests.Remove(CacheKey); + } + + return response; + } + + Thread.Sleep(50); // waiting for a web request to complete, 50msecs is reasonable } - // return cached response - return response; + // if (!m_memoryCache.TryGetValue(CacheKey, out response)) + // { + // m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache"); + // Util.PrintCallStack(); + + // // if it wasn't in the cache, pass the request to the Simian Grid Services + // response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + + // // and cache the response + // m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + // } + + // // return cached response + // return response; } #endregion -- cgit v1.1 From 749c3fef8ad2d3af97fcd9ab9c72740675e46715 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 8 Mar 2012 01:51:37 +0000 Subject: Change "help" to display categories/module list then "help " to display commands in a category. This is to deal with the hundred lines of command splurge when one previously typed "help" Modelled somewhat on the mysql console One can still type help to get per command help at any point. Categories capitalized to avoid conflict with the all-lowercase commands (except for commander system, as of yet). Does not affect command parsing or any other aspects of the console apart from the help system. Backwards compatible with existing modules. --- .../OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 2369d94..6bb6729 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -94,13 +94,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance m_scenes[scene.RegionInfo.RegionID] = scene; scene.AddCommand( - this, "show appearance", + "Users", this, "show appearance", "show appearance [ ]", "Synonym for 'appearance show'", HandleShowAppearanceCommand); scene.AddCommand( - this, "appearance show", + "Users", this, "appearance show", "appearance show [ ]", "Show appearance information for each avatar in the simulator.", "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " @@ -110,14 +110,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance HandleShowAppearanceCommand); scene.AddCommand( - this, "appearance send", + "Users", this, "appearance send", "appearance send [ ]", "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", + "Users", 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." @@ -127,7 +127,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance HandleRebakeAppearanceCommand); scene.AddCommand( - this, "appearance find", + "Users", this, "appearance find", "appearance find ", "Find out which avatar uses the given asset as a baked texture, if any.", "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", -- cgit v1.1 From 7223b63563f28f6fe8044bdabcd1b9900d28c54a Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 27 Mar 2012 22:09:58 +0200 Subject: User level based restrictions for HyperGrid teleports, asset uploads, group creations and getting contacted from other grids. Incoming HyperGrid teleports can also be restricted to local users. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b60cd42..ea5d805 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -84,6 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; private bool m_debugEnabled = false; + private int m_levelGroupCreate = 0; #region IRegionModuleBase Members @@ -115,6 +116,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); + m_levelGroupCreate = groupsConfig.GetInt("LevelGroupCreate", 0); } } @@ -708,13 +710,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } + + // check user level + ScenePresence avatar = null; + Scene scene = (Scene)remoteClient.Scene; + scene.TryGetScenePresence(remoteClient.AgentId, out avatar); + + if (avatar != null) + { + if (avatar.UserLevel < m_levelGroupCreate) + { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient permissions to create a group."); + return UUID.Zero; + } + } + + // check funds // is there is a money module present ? - IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); + IMoneyModule money = scene.RequestModuleInterface(); if (money != null) { // do the transaction, that is if the agent has got sufficient funds if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); return UUID.Zero; } money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); -- cgit v1.1 From 19837ff4dd8b01cf1f0a458cafc02c56be48bf66 Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 27 Mar 2012 22:30:02 +0200 Subject: Two new scripting functions osInviteToGroup(userID) and osEjectFromGroup(userID) that invite/eject users to/from groups the object containing the script is set to. These functions also work for closed groups. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 122 +++++++++++++++++---- 1 file changed, 99 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index ea5d805..2a15e5d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -957,17 +957,55 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + EjectGroupMember(remoteClient, GetRequestingAgentID(remoteClient), groupID, ejecteeID); + } + public void EjectGroupMember(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID ejecteeID) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check? - m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(agentID, ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(GetRequestingAgentID(remoteClient), groupID, true); + string agentName; + RegionInfo regionInfo; - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); + // remoteClient provided or just agentID? + if (remoteClient != null) + { + agentName = remoteClient.Name; + regionInfo = remoteClient.Scene.RegionInfo; + remoteClient.SendEjectGroupMemberReply(agentID, groupID, true); + } + else + { + IClientAPI client = GetActiveClient(agentID); + + if (client != null) + { + agentName = client.Name; + regionInfo = client.Scene.RegionInfo; + client.SendEjectGroupMemberReply(agentID, groupID, true); + } + else + { + regionInfo = m_sceneList[0].RegionInfo; + UserAccount acc = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, agentID); + + if (acc != null) + { + agentName = acc.FirstName + " " + acc.LastName; + } + else + { + agentName = "Unknown member"; + } + } + } + + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); - UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, ejecteeID); + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID); if ((groupInfo == null) || (account == null)) { return; @@ -977,23 +1015,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.fromAgentID = agentID.Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); + msg.fromAgentName = agentName; + msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; msg.fromGroup = false; msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.RegionID = regionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; OutgoingInstantMessage(msg, ejecteeID); - // Message to ejector // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid @@ -1003,26 +1040,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; - msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.fromAgentID = agentID.Guid; + msg.toAgentID = agentID.Guid; msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; + msg.fromAgentName = agentName; if (account != null) { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, account.FirstName + " " + account.LastName); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, account.FirstName + " " + account.LastName); } else { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, "Unknown member"); } msg.dialog = (byte)210; //interop msg.fromGroup = false; msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.RegionID = regionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); + OutgoingInstantMessage(msg, agentID); // SL sends out messages to everyone in the group @@ -1032,16 +1069,55 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) { + InviteGroup(remoteClient, GetRequestingAgentID(remoteClient), groupID, invitedAgentID, roleID); + } + + public void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID invitedAgentID, UUID roleID) + { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + string agentName; + RegionInfo regionInfo; + + // remoteClient provided or just agentID? + if (remoteClient != null) + { + agentName = remoteClient.Name; + regionInfo = remoteClient.Scene.RegionInfo; + } + else + { + IClientAPI client = GetActiveClient(agentID); + + if (client != null) + { + agentName = client.Name; + regionInfo = client.Scene.RegionInfo; + } + else + { + regionInfo = m_sceneList[0].RegionInfo; + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, agentID); + + if (account != null) + { + agentName = account.FirstName + " " + account.LastName; + } + else + { + agentName = "Unknown member"; + } + } + } + // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - m_groupData.AddAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(agentID, InviteID, groupID, roleID, invitedAgentID); // Check to see if the invite went through, if it did not then it's possible // the remoteClient did not validate or did not have permission to invite. - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(agentID, InviteID); if (inviteInfo != null) { @@ -1053,19 +1129,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = inviteUUID; - // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + // msg.fromAgentID = agentID.Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); + msg.fromAgentName = agentName; + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", agentName); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; msg.fromGroup = true; msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.RegionID = regionInfo.RegionID.Guid; msg.binaryBucket = new byte[20]; OutgoingInstantMessage(msg, invitedAgentID); -- cgit v1.1 From b74a89bc125a9f3c0c7aac0001a84df4ec28a192 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 27 Mar 2012 22:33:42 +0100 Subject: minor: clean up some code formatting in VivoxVoiceModule.cs --- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 79 +++++++--------------- 1 file changed, 25 insertions(+), 54 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 70e2f7e..738133c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -221,15 +221,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice } } - // Called to indicate that the module has been added to the region public void AddRegion(Scene scene) { - if (m_pluginEnabled) { lock (vlock) { - string channelId; string sceneUUID = scene.RegionInfo.RegionID.ToString(); @@ -273,23 +270,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice } } - // Create a dictionary entry unconditionally. This eliminates the // need to check for a parent in the core code. The end result is // the same, if the parent table entry is an empty string, then // region channels will be created as first-level channels. - - lock (m_parents) - if (m_parents.ContainsKey(sceneUUID)) - { - RemoveRegion(scene); - m_parents.Add(sceneUUID, channelId); - } - else - { - m_parents.Add(sceneUUID, channelId); - } - + lock (m_parents) + { + if (m_parents.ContainsKey(sceneUUID)) + { + RemoveRegion(scene); + m_parents.Add(sceneUUID, channelId); + } + else + { + m_parents.Add(sceneUUID, channelId); + } + } } // we need to capture scene in an anonymous method @@ -298,26 +294,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice { OnRegisterCaps(scene, agentID, caps); }; - } - } - - // Called to indicate that all loadable modules have now been added + public void RegionLoaded(Scene scene) { // Do nothing. } - // Called to indicate that the region is going away. public void RemoveRegion(Scene scene) { - if (m_pluginEnabled) { lock (vlock) { - string channelId; string sceneUUID = scene.RegionInfo.RegionID.ToString(); @@ -328,10 +318,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // iteration over the set of chidren identified. // This assumes that there is just one directory per // region. - if (VivoxTryGetDirectory(sceneUUID + "D", out channelId)) { - m_log.DebugFormat("[VivoxVoice]: region {0}: uuid {1}: located directory id {2}", sceneName, sceneUUID, channelId); @@ -360,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice lock (m_parents) { - if (m_parents.ContainsKey(sceneUUID)) + if (m_parents.ContainsKey(sceneUUID)) { m_parents.Remove(sceneUUID); } @@ -459,11 +447,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice { try { - ScenePresence avatar = null; string avatarName = null; - if (scene == null) throw new Exception("[VivoxVoice][PROVISIONVOICE] Invalid scene"); + if (scene == null) + throw new Exception("[VivoxVoice][PROVISIONVOICE]: Invalid scene"); avatar = scene.GetScenePresence(agentID); while (avatar == null) @@ -566,7 +554,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice } } } - } while (retry); + } + while (retry); if (code != "OK") { @@ -676,7 +665,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice } } - /// /// Callback for a client request for a private chat channel /// @@ -698,10 +686,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return "true"; } - private string RegionGetOrCreateChannel(Scene scene, LandData land) { - string channelUri = null; string channelId = null; @@ -709,11 +695,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice string landName; string parentId; - lock (m_parents) parentId = m_parents[scene.RegionInfo.RegionID.ToString()]; + lock (m_parents) + parentId = m_parents[scene.RegionInfo.RegionID.ToString()]; // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same // as the directory ID. Otherwise, it reflects the parcel's ID. - if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) { landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); @@ -741,14 +727,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parent channel id {1}: retrieved parcel channel_uri {2} ", landName, parentId, channelUri); - - } return channelUri; } - private static readonly string m_vivoxLoginPath = "http://{0}/api2/viv_signin.php?userid={1}&pwd={2}"; /// @@ -761,7 +744,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return VivoxCall(requrl, false); } - private static readonly string m_vivoxLogoutPath = "http://{0}/api2/viv_signout.php?auth_token={1}"; /// @@ -773,7 +755,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return VivoxCall(requrl, false); } - private static readonly string m_vivoxGetAccountPath = "http://{0}/api2/viv_get_acct.php?auth_token={1}&user_name={2}"; /// @@ -786,7 +767,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return VivoxCall(requrl, true); } - private static readonly string m_vivoxNewAccountPath = "http://{0}/api2/viv_adm_acct_new.php?username={1}&pwd={2}&auth_token={3}"; /// @@ -801,7 +781,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return VivoxCall(requrl, true); } - private static readonly string m_vivoxPasswordPath = "http://{0}/api2/viv_adm_password.php?user_name={1}&new_pwd={2}&auth_token={3}"; /// @@ -813,7 +792,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return VivoxCall(requrl, true); } - private static readonly string m_vivoxChannelPath = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_name={2}&auth_token={3}"; /// @@ -828,7 +806,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice /// /// In this case the call handles parent and description as optional values. /// - private bool VivoxTryCreateChannel(string parent, string channelId, string description, out string channelUri) { string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", channelId, m_authToken); @@ -864,7 +841,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice /// channel name space. /// The parent and description are optional values. /// - private bool VivoxTryCreateDirectory(string dirId, string description, out string channelId) { string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", dirId, m_authToken); @@ -901,7 +877,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice /// are required in a later phase. /// In this case the call handles parent and description as optional values. /// - private bool VivoxTryGetChannel(string channelParent, string channelName, out string channelId, out string channelUri) { @@ -1044,6 +1019,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // return VivoxCall(requrl, true); // } + private static readonly string m_vivoxChannelDel = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}"; + /// /// Delete a channel. /// Once again, there a multitude of options possible. In the simplest case @@ -1055,9 +1032,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice /// are required in a later phase. /// In this case the call handles parent and description as optional values. /// - - private static readonly string m_vivoxChannelDel = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}"; - private XmlElement VivoxDeleteChannel(string parent, string channelid) { string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken); @@ -1068,12 +1042,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return VivoxCall(requrl, true); } + private static readonly string m_vivoxChannelSearch = "http://{0}/api2/viv_chan_search.php?&cond_chanparent={1}&auth_token={2}"; + /// /// Return information on channels in the given directory /// - - private static readonly string m_vivoxChannelSearch = "http://{0}/api2/viv_chan_search.php?&cond_chanparent={1}&auth_token={2}"; - private XmlElement VivoxListChildren(string channelid) { string requrl = String.Format(m_vivoxChannelSearch, m_vivoxServer, channelid, m_authToken); @@ -1118,7 +1091,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice /// The outcome of the call can be determined by examining the /// status value in the hash table. /// - private XmlElement VivoxCall(string requrl, bool admin) { @@ -1164,7 +1136,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice /// /// Just say if it worked. /// - private bool IsOK(XmlElement resp) { string status; @@ -1337,4 +1308,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return false; } } -} +} \ No newline at end of file -- cgit v1.1 From bce7964ac2b0e67ff8c8e5ab00bb45b93da219ad Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 30 Mar 2012 01:05:29 +0100 Subject: refactor: Move "friends show cache" console command out into separate FriendsCommandsModule. Expose required methods on IFriendsModule. Rename GetFriends() -> GetFriendsFromCache() for self-documentation --- .../Avatar/Friends/FriendsCommandsModule.cs | 165 +++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs new file mode 100644 index 0000000..2bcb8a7 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs @@ -0,0 +1,165 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; + +namespace OpenSim.Region.OptionalModules.Avatar.Friends +{ + /// + /// A module that just holds commands for inspecting avatar appearance. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FriendsCommandModule")] + public class FriendsCommandsModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + private IFriendsModule m_friendsModule; + private IUserManagement m_userManagementModule; + +// private IAvatarFactoryModule m_avatarFactory; + + public string Name { get { return "Appearance Information Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[FRIENDS COMMANDO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + if (m_scene == null) + m_scene = scene; + + m_friendsModule = m_scene.RequestModuleInterface(); + m_userManagementModule = m_scene.RequestModuleInterface(); + + if (m_friendsModule != null && m_userManagementModule != null) + { + m_scene.AddCommand( + "Friends", this, "friends show cache", + "friends show cache [ ]", + "Show the friends cache for the given user", + HandleFriendsShowCacheCommand); + } + } + + protected void HandleFriendsShowCacheCommand(string module, string[] cmd) + { + if (cmd.Length != 5) + { + MainConsole.Instance.OutputFormat("Usage: friends show cache [ ]"); + return; + } + + string firstName = cmd[3]; + string lastName = cmd[4]; + + UUID userId = m_userManagementModule.GetUserIdByName(firstName, lastName); + +// UserAccount ua +// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName); + + if (userId == UUID.Zero) + { + MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); + return; + } + + if (m_friendsModule.AreFriendsCached(userId)) + { + MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName); + return; + } + + MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName); + + MainConsole.Instance.OutputFormat("UUID\n"); + + FriendInfo[] friends = m_friendsModule.GetFriendsFromCache(userId); + + foreach (FriendInfo friend in friends) + { +// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString()); + +// string friendFirstName, friendLastName; +// +// UserAccount friendUa +// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID); + + UUID friendId; + string friendName; + + if (UUID.TryParse(friend.Friend, out friendId)) + friendName = m_userManagementModule.GetUserName(friendId); + else + friendName = friend.Friend; + + MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags); + } + } + } +} \ No newline at end of file -- cgit v1.1 From 3525c876c8972fb89a9981d4dc3dcb3220adee9e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 30 Mar 2012 01:57:38 +0100 Subject: Make default "show friends" console command show friends fetched from the friends service. There is no a --cache option which will show friends from the local cache if available. --- .../Avatar/Friends/FriendsCommandsModule.cs | 87 +++++++++++++++++++++- 1 file changed, 83 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs index 2bcb8a7..fe73770 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs @@ -32,14 +32,17 @@ using System.Reflection; using System.Text; using log4net; using Mono.Addins; +using NDesk.Options; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Framework.Statistics; using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.CoreModules.Avatar.Friends; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; namespace OpenSim.Region.OptionalModules.Avatar.Friends @@ -100,10 +103,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends if (m_friendsModule != null && m_userManagementModule != null) { m_scene.AddCommand( - "Friends", this, "friends show cache", - "friends show cache [ ]", - "Show the friends cache for the given user", - HandleFriendsShowCacheCommand); + "Friends", this, "friends show", + "friends show [--cache] ", + "Show the friends for the given user if they exist.\n", + "The --cache option will show locally cached information for that user.", + HandleFriendsShowCommand); } } @@ -161,5 +165,80 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags); } } + + protected void HandleFriendsShowCommand(string module, string[] cmd) + { + Dictionary options = new Dictionary(); + OptionSet optionSet = new OptionSet().Add("c|cache", delegate (string v) { options["cache"] = v != null; }); + + List mainParams = optionSet.Parse(cmd); + + if (mainParams.Count != 4) + { + MainConsole.Instance.OutputFormat("Usage: friends show [--cache] "); + return; + } + + string firstName = mainParams[2]; + string lastName = mainParams[3]; + + UUID userId = m_userManagementModule.GetUserIdByName(firstName, lastName); + +// UserAccount ua +// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName); + + if (userId == UUID.Zero) + { + MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); + return; + } + + FriendInfo[] friends; + + if (options.ContainsKey("cache")) + { + if (!m_friendsModule.AreFriendsCached(userId)) + { + MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName); + return; + } + else + { + friends = m_friendsModule.GetFriendsFromCache(userId); + } + } + else + { + // FIXME: We're forced to do this right now because IFriendsService has no region connectors. We can't + // just expose FriendsModule.GetFriendsFromService() because it forces an IClientAPI requirement that + // can't currently be changed because of HGFriendsModule code that takes the scene from the client. + friends = ((FriendsModule)m_friendsModule).FriendsService.GetFriends(userId); + } + + MainConsole.Instance.OutputFormat("Friends for {0} {1} {2}:", firstName, lastName, userId); + + MainConsole.Instance.OutputFormat("UUID, Name, MyFlags, TheirFlags"); + + foreach (FriendInfo friend in friends) + { +// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString()); + +// string friendFirstName, friendLastName; +// +// UserAccount friendUa +// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID); + + UUID friendId; + string friendName; + + if (UUID.TryParse(friend.Friend, out friendId)) + friendName = m_userManagementModule.GetUserName(friendId); + else + friendName = friend.Friend; + + MainConsole.Instance.OutputFormat( + "{0} {1} {2} {3}", friend.Friend, friendName, friend.MyFlags, friend.TheirFlags); + } + } } } \ No newline at end of file -- cgit v1.1 From 269e479cdc25c5420b4feaaebc233933323f93e2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 30 Mar 2012 02:00:01 +0100 Subject: minor: remove some now unneeded code from FriendsCommandsModule --- .../Avatar/Friends/FriendsCommandsModule.cs | 55 ---------------------- 1 file changed, 55 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs index fe73770..e68f9d0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs @@ -111,61 +111,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends } } - protected void HandleFriendsShowCacheCommand(string module, string[] cmd) - { - if (cmd.Length != 5) - { - MainConsole.Instance.OutputFormat("Usage: friends show cache [ ]"); - return; - } - - string firstName = cmd[3]; - string lastName = cmd[4]; - - UUID userId = m_userManagementModule.GetUserIdByName(firstName, lastName); - -// UserAccount ua -// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName); - - if (userId == UUID.Zero) - { - MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); - return; - } - - if (m_friendsModule.AreFriendsCached(userId)) - { - MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName); - return; - } - - MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName); - - MainConsole.Instance.OutputFormat("UUID\n"); - - FriendInfo[] friends = m_friendsModule.GetFriendsFromCache(userId); - - foreach (FriendInfo friend in friends) - { -// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString()); - -// string friendFirstName, friendLastName; -// -// UserAccount friendUa -// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID); - - UUID friendId; - string friendName; - - if (UUID.TryParse(friend.Friend, out friendId)) - friendName = m_userManagementModule.GetUserName(friendId); - else - friendName = friend.Friend; - - MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags); - } - } - protected void HandleFriendsShowCommand(string module, string[] cmd) { Dictionary options = new Dictionary(); -- cgit v1.1 From 67537f359688bfa592312baf808e9d399fc164fa Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Thu, 5 Apr 2012 13:03:57 +0200 Subject: Added missing refresh of group membership client side cache to the groups module. Before memberships of non active groups often were not stored in the cache (n_groupPowers). --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 2a15e5d..e669f4c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1294,7 +1294,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); - // Need to send a group membership update to the client // UDP version doesn't seem to behave nicely. But we're going to send it out here // with an empty group membership to hopefully remove groups being displayed due @@ -1305,6 +1304,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); + if (remoteClient.AgentId == dataForAgentID) + remoteClient.RefreshGroupMembership(); } /// -- cgit v1.1 From 6c21e15cb9542c06e69fd8acd6d4c04aad2cd7da Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 24 Apr 2012 00:32:01 +0100 Subject: Add online/offline indicator to "friends show" region console command. Improve output table formatting. --- .../Avatar/Friends/FriendsCommandsModule.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs index e68f9d0..2602050 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs @@ -58,6 +58,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends private Scene m_scene; private IFriendsModule m_friendsModule; private IUserManagement m_userManagementModule; + private IPresenceService m_presenceService; // private IAvatarFactoryModule m_avatarFactory; @@ -99,8 +100,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends m_friendsModule = m_scene.RequestModuleInterface(); m_userManagementModule = m_scene.RequestModuleInterface(); + m_presenceService = m_scene.RequestModuleInterface(); - if (m_friendsModule != null && m_userManagementModule != null) + if (m_friendsModule != null && m_userManagementModule != null && m_presenceService != null) { m_scene.AddCommand( "Friends", this, "friends show", @@ -162,7 +164,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends MainConsole.Instance.OutputFormat("Friends for {0} {1} {2}:", firstName, lastName, userId); - MainConsole.Instance.OutputFormat("UUID, Name, MyFlags, TheirFlags"); + MainConsole.Instance.OutputFormat( + "{0,-36} {1,-36} {2,-7} {3,7} {4,10}", "UUID", "Name", "Status", "MyFlags", "TheirFlags"); foreach (FriendInfo friend in friends) { @@ -175,14 +178,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends UUID friendId; string friendName; + string onlineText; if (UUID.TryParse(friend.Friend, out friendId)) friendName = m_userManagementModule.GetUserName(friendId); else friendName = friend.Friend; + OpenSim.Services.Interfaces.PresenceInfo[] pi = m_presenceService.GetAgents(new string[] { friend.Friend }); + if (pi.Length > 0) + onlineText = "online"; + else + onlineText = "offline"; + MainConsole.Instance.OutputFormat( - "{0} {1} {2} {3}", friend.Friend, friendName, friend.MyFlags, friend.TheirFlags); + "{0,-36} {1,-36} {2,-7} {3,-7} {4,-10}", + friend.Friend, friendName, onlineText, friend.MyFlags, friend.TheirFlags); } } } -- cgit v1.1 From 07e62df5582e28675275b3f5143ec37e5697d283 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 27 Apr 2012 00:58:54 +0100 Subject: Add regression test for teleporting an agent between separated regions on the same simulator. This involves a large amount of change in test scene setup code to allow test scenes to share shared modules SetupScene is now an instance method that requires an instantiation of SceneHelpers, though other SceneHelpers methods are still static May split these out into separate classes in the future. --- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index d2f6327..ac638f1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - TestScene scene = SceneHelpers.SetupScene(); + TestScene scene = new SceneHelpers().SetupScene(); IConfigSource configSource = new IniConfigSource(); IConfig config = configSource.AddConfig("Groups"); config.Set("Enabled", true); -- cgit v1.1 From cd755fe5983b1960f771bf6f6bf3fa15b338182b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 28 Apr 2012 00:31:11 +0100 Subject: Remove mono compiler warning. Adjust message log to error from info --- .../Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 130513d..5d57f70 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -1401,9 +1401,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { response = WebUtil.PostToService(m_groupsServerURI, requestArgs); } - catch (Exception e) + catch (Exception) { - m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey); + m_log.ErrorFormat("[SIMIAN GROUPS CONNECTOR]: request failed {0}", CacheKey); } // and cache the response -- cgit v1.1 From 231a3bf147315a9284140476d2b09e13c3fee1c0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 May 2012 01:45:49 +0100 Subject: Implement optional name and description on http stream handlers so that we can relate a slow request to what the handler actually does and the agent it serves, if applicable. This is most useful for capabilities where the url is not self-describing. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 53 +++++++++++---------- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 54 ++++++++++++---------- 2 files changed, 59 insertions(+), 48 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 05678c0..be8873d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -306,30 +306,35 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice agentID, caps, scene.RegionInfo.RegionName); string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("ProvisionVoiceAccountRequest", - new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ProvisionVoiceAccountRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ParcelVoiceInfoRequest", - new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ParcelVoiceInfoRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ChatSessionRequest", - new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ChatSessionRequest(scene, request, path, param, - agentID, caps); - })); + caps.RegisterHandler( + "ProvisionVoiceAccountRequest", + new RestStreamHandler( + "POST", + capsBase + m_provisionVoiceAccountRequestPath, + (request, path, param, httpRequest, httpResponse) + => ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps), + "ProvisionVoiceAccountRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ParcelVoiceInfoRequest", + new RestStreamHandler( + "POST", + capsBase + m_parcelVoiceInfoRequestPath, + (request, path, param, httpRequest, httpResponse) + => ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps), + "ParcelVoiceInfoRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ChatSessionRequest", + new RestStreamHandler( + "POST", + capsBase + m_chatSessionRequestPath, + (request, path, param, httpRequest, httpResponse) + => ChatSessionRequest(scene, request, path, param, agentID, caps), + "ChatSessionRequest", + agentID.ToString())); } /// diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 738133c..a36fd74 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -406,30 +406,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice m_log.DebugFormat("[VivoxVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("ProvisionVoiceAccountRequest", - new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ProvisionVoiceAccountRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ParcelVoiceInfoRequest", - new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ParcelVoiceInfoRequest(scene, request, path, param, - agentID, caps); - })); - caps.RegisterHandler("ChatSessionRequest", - new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, - delegate(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - return ChatSessionRequest(scene, request, path, param, - agentID, caps); - })); + + caps.RegisterHandler( + "ProvisionVoiceAccountRequest", + new RestStreamHandler( + "POST", + capsBase + m_provisionVoiceAccountRequestPath, + (request, path, param, httpRequest, httpResponse) + => ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps), + "ProvisionVoiceAccountRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ParcelVoiceInfoRequest", + new RestStreamHandler( + "POST", + capsBase + m_parcelVoiceInfoRequestPath, + (request, path, param, httpRequest, httpResponse) + => ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps), + "ParcelVoiceInfoRequest", + agentID.ToString())); + + caps.RegisterHandler( + "ChatSessionRequest", + new RestStreamHandler( + "POST", + capsBase + m_chatSessionRequestPath, + (request, path, param, httpRequest, httpResponse) + => ChatSessionRequest(scene, request, path, param, agentID, caps), + "ChatSessionRequest", + agentID.ToString())); } /// -- cgit v1.1 From bce3e7cb06611db887ee50c793d72674ad326ba7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 May 2012 22:48:03 +0100 Subject: Add "attachments" show console command that will show the server's record of which attachments an in-scene avatar has. For debugging purposes. --- .../Avatar/Attachments/AttachmentsCommandModule.cs | 177 +++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs new file mode 100644 index 0000000..ce23613 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -0,0 +1,177 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Attachments +{ + /// + /// A module that just holds commands for inspecting avatar appearance. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsCommandModule")] + public class AttachmentsCommandModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_scenes = new List(); +// private IAvatarFactoryModule m_avatarFactory; + + public string Name { get { return "Attachments Command Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Remove(scene); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Add(scene); + + scene.AddCommand( + "Users", this, "attachments show", + "attachments show [ ]", + "Show attachment information for avatars in this simulator.", + HandleShowAttachmentsCommand); + } + + protected void HandleShowAttachmentsCommand(string module, string[] cmd) + { + if (cmd.Length != 2 && cmd.Length < 4) + { + MainConsole.Instance.OutputFormat("Usage: attachments show [ ]"); + return; + } + + bool targetNameSupplied = false; + string optionalTargetFirstName = null; + string optionalTargetLastName = null; + + if (cmd.Length >= 4) + { + targetNameSupplied = true; + optionalTargetFirstName = cmd[2]; + optionalTargetLastName = cmd[3]; + } + + StringBuilder sb = new StringBuilder(); + + lock (m_scenes) + { + foreach (Scene scene in m_scenes) + { + if (targetNameSupplied) + { + ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); + if (sp != null && !sp.IsChildAgent) + GetAttachmentsReport(sp, sb); + } + else + { + scene.ForEachRootScenePresence(sp => GetAttachmentsReport(sp, sb)); + } + } + } + + MainConsole.Instance.Output(sb.ToString()); + } + + private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb) + { + sb.AppendFormat("Attachments for {0}\n", sp.Name); + + sb.AppendFormat( + " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", + "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); + + List attachmentObjects = sp.GetAttachments(); + foreach (SceneObjectGroup attachmentObject in attachmentObjects) + { +// InventoryItemBase attachmentItem +// = m_scenes[0].InventoryService.GetItem(new InventoryItemBase(attachmentObject.FromItemID)); + +// if (attachmentItem == null) +// { +// sb.AppendFormat( +// "WARNING: Couldn't find attachment for item {0} at point {1}\n", +// attachmentData.ItemID, (AttachmentPoint)attachmentData.AttachPoint); +// continue; +// } +// else +// { + sb.AppendFormat( + " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", + attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, + (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); +// } + } + + sb.Append("\n"); + } + } +} \ No newline at end of file -- cgit v1.1 From 903cff9264ce405d00eab2739fcfb461749b4772 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 May 2012 23:47:39 +0100 Subject: Add ConsoleTable framework class for future uniform formatting of console output tables. Still subject to change - if you use this be prepared to change your output code if/when the methods change. Make new "attachments show" command use this. --- .../Avatar/Attachments/AttachmentsCommandModule.cs | 34 +++++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index ce23613..a95514c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -53,7 +53,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments private List m_scenes = new List(); // private IAvatarFactoryModule m_avatarFactory; - + public string Name { get { return "Attachments Command Module"; } } public Type ReplaceableInterface { get { return null; } } @@ -145,9 +145,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { sb.AppendFormat("Attachments for {0}\n", sp.Name); - sb.AppendFormat( - " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", - "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); + ConsoleTable ct = new ConsoleTable() { Indent = 2 }; + ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); + ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); + ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); + ct.Columns.Add(new ConsoleTableColumn("Attach Point", 14)); + ct.Columns.Add(new ConsoleTableColumn("Position", 15)); + +// sb.AppendFormat( +// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", +// "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); List attachmentObjects = sp.GetAttachments(); foreach (SceneObjectGroup attachmentObject in attachmentObjects) @@ -164,13 +171,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // } // else // { - sb.AppendFormat( - " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", - attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, - (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); +// sb.AppendFormat( +// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", +// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, +// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); + ct.Rows.Add( + new ConsoleTableRow( + new List() + { + attachmentObject.Name, + attachmentObject.LocalId.ToString(), + attachmentObject.FromItemID.ToString(), + ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(), + attachmentObject.RootPart.AttachedPos.ToString() + })); // } } + ct.AddToStringBuilder(sb); sb.Append("\n"); } } -- cgit v1.1 From 2222d979cc723ee2f3bad92ffe4991d074b2403a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:37:38 +0100 Subject: refactor: rename ConsoleTable -> ConsoleDisplayTable for clarity --- .../OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index a95514c..df32a1d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -145,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { sb.AppendFormat("Attachments for {0}\n", sp.Name); - ConsoleTable ct = new ConsoleTable() { Indent = 2 }; + ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); -- cgit v1.1 From 8f88c17df969b1fd3e4a93747201e9436c9a1fcd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 03:23:37 +0100 Subject: refactor: Rename ConsoleTableRow and ConsoleTableColumn to ConsoleDisplayTableRow and ConsoleDisplayTableColumn --- .../Avatar/Attachments/AttachmentsCommandModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index df32a1d..1b9e3ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -146,11 +146,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments sb.AppendFormat("Attachments for {0}\n", sp.Name); ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; - ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); - ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); - ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); - ct.Columns.Add(new ConsoleTableColumn("Attach Point", 14)); - ct.Columns.Add(new ConsoleTableColumn("Position", 15)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Position", 15)); // sb.AppendFormat( // " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", @@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, // (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); ct.Rows.Add( - new ConsoleTableRow( + new ConsoleDisplayTableRow( new List() { attachmentObject.Name, -- cgit v1.1 From 916e3bf886ee622e2f18d6eb74f90fee8c630471 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 11 Jul 2012 22:54:22 +0100 Subject: Where possible, use the system Encoding.ASCII and Encoding.UTF8 rather than constructing fresh copies. The encodings are thread-safe and already used in such a manner in other places. This isn't done where Byte Order Mark output is suppressed, since Encoding.UTF8 is constructed to output the BOM. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 3 +-- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index be8873d..7fafdc6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -823,11 +823,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", landName, land.LocalID, landUUID); } - System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); // slvoice handles the sip address differently if it begins with confctl, hiding it from the user in the friends list. however it also disables // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator. - channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); + channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(Encoding.ASCII.GetBytes(landUUID)), m_freeSwitchRealm); lock (m_ParcelAddress) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 52fc27d..61aaf04 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1120,7 +1120,6 @@ namespace Nwc.XmlRpc /// Class supporting the request side of an XML-RPC transaction. public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest { - private Encoding _encoding = new ASCIIEncoding(); private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); private bool _disableKeepAlive = true; @@ -1153,7 +1152,7 @@ namespace Nwc.XmlRpc request.KeepAlive = !_disableKeepAlive; Stream stream = request.GetRequestStream(); - XmlTextWriter xml = new XmlTextWriter(stream, _encoding); + XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII); _serializer.Serialize(xml, this); xml.Flush(); xml.Close(); -- cgit v1.1 From 35efa88c26d249d315837fdca0faf643511e1a4e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Jul 2012 23:11:50 +0100 Subject: Rename OpenSim.Framework.Statistics to OpenSim.Framework.Monitoring. This better reflects the long-term purpose of that project and matches Monitoring modules. --- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 2 +- .../OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 6bb6729..d718a2f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -36,7 +36,7 @@ using Nini.Config; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; -using OpenSim.Framework.Statistics; +using OpenSim.Framework.Monitoring; using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index 1b9e3ac..d68aabc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -36,7 +36,7 @@ using Nini.Config; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; -using OpenSim.Framework.Statistics; +using OpenSim.Framework.Monitoring; using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs index 2602050..4e84364 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs @@ -37,7 +37,7 @@ using Nini.Config; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; -using OpenSim.Framework.Statistics; +using OpenSim.Framework.Monitoring; using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.CoreModules.Avatar.Friends; using OpenSim.Region.Framework.Interfaces; -- cgit v1.1 From 5aec0ff207e9427b8756471eb003fd68859f67b1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 25 Jul 2012 23:27:00 +0100 Subject: Move Watchdog and MemoryWatchdog classes into OpenSim.Framework.Monitoring with other monitoring code from OpenSim.Framework --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index cd401a6..ca956fb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -37,6 +37,7 @@ using OpenMetaverse; using log4net; using Nini.Config; using OpenSim.Framework; +using OpenSim.Framework.Monitoring; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -- cgit v1.1 From 72075e68c7209afee10f365fc14b1fabffcc66a3 Mon Sep 17 00:00:00 2001 From: Kevin Cozens Date: Sun, 29 Jul 2012 17:02:10 -0400 Subject: Save membership fee to the database when a group is created. --- .../XmlRpcGroupsServicesConnectorModule.cs | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 61aaf04..d412cd1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -54,12 +54,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_debugEnabled = false; - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | - GroupPowers.Accountable | - GroupPowers.JoinChat | - GroupPowers.AllowVoiceChat | - GroupPowers.ReceiveNotices | - GroupPowers.StartProposal | + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | GroupPowers.VoteOnProposal; private bool m_connectorEnabled = false; @@ -201,8 +201,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, - int membershipFee, bool openEnrollment, bool allowPublish, + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, + int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) { UUID GroupID = UUID.Random(); @@ -214,7 +214,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Charter"] = charter; param["ShowInList"] = showInList == true ? 1 : 0; param["InsigniaID"] = insigniaID.ToString(); - param["MembershipFee"] = 0; + param["MembershipFee"] = membershipFee; param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; @@ -285,8 +285,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, - UUID insigniaID, int membershipFee, bool openEnrollment, + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, + UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { Hashtable param = new Hashtable(); @@ -302,7 +302,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.updateGroup", param); } - public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -325,7 +325,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); } - public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -580,7 +580,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); } } - + return memberships; } @@ -800,9 +800,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) { - // If we're tracking drops for this group, + // If we're tracking drops for this group, // and we find them, well... then they've dropped - return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) + return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); } @@ -888,7 +888,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } - + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) { GroupMembershipData data = new GroupMembershipData(); @@ -921,7 +921,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.MembershipFee = int.Parse((string)respData["MembershipFee"]); data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); data.ShowInList = ((string)respData["ShowInList"] == "1"); - + return data; } @@ -958,7 +958,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_memoryCache.TryGetValue(CacheKey, out resp); } } - + if (resp == null) { if (m_debugEnabled) @@ -967,7 +967,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string UserService; UUID SessionID; GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); - + param.Add("RequestingAgentID", requestingAgentID.ToString()); param.Add("RequestingAgentUserService", UserService); param.Add("RequestingSessionID", SessionID.ToString()); @@ -992,9 +992,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups catch (Exception e) { m_log.ErrorFormat( - "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}", + "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}", function, m_groupsServerURI); - + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace); foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) @@ -1061,9 +1061,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - + /// - /// Group Request Tokens are an attempt to allow the groups service to authenticate + /// Group Request Tokens are an attempt to allow the groups service to authenticate /// requests. /// TODO: This broke after the big grid refactor, either find a better way, or discard this /// @@ -1103,7 +1103,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } */ } - + } } -- cgit v1.1 From 62acfabec4638284e0d9c88ccbd50d2d0f4b65a6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Aug 2012 00:54:12 +0100 Subject: Add the skeleton for the temp attachments module --- .../Avatar/Attachments/TempAttachmentsModule.cs | 82 ++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs new file mode 100644 index 0000000..c1efd7c --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -0,0 +1,82 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Attachments +{ + /// + /// A module that just holds commands for inspecting avatar appearance. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TempAttachmentsModule")] + public class TempAttachmentsModule : INonSharedRegionModule + { + public void Initialise(IConfigSource configSource) + { + } + + public void AddRegion(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + } + + public void Close() + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public string Name + { + get { return "TempAttachmentsModule"; } + } + } +} -- cgit v1.1 From 4bbdcfb5ee81f459df9ff9a2ac477f6419cfc279 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Aug 2012 01:45:02 +0100 Subject: Implement the temp attachments. UNTESTED --- .../Avatar/Attachments/TempAttachmentsModule.cs | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index c1efd7c..e659ec0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -49,12 +49,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TempAttachmentsModule")] public class TempAttachmentsModule : INonSharedRegionModule { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + public void Initialise(IConfigSource configSource) { } public void AddRegion(Scene scene) { + m_scene = scene; + + IScriptModuleComms comms = scene.RequestModuleInterface(); + if (comms != null) + { + comms.RegisterScriptInvocation( this, "llAttachToAvatarTemp"); + m_log.DebugFormat("[TEMP ATTACHS]: Registered script functions"); + } + else + { + m_log.ErrorFormat("[TEMP ATTACHS]: Failed to register script functions"); + } } public void RemoveRegion(Scene scene) @@ -78,5 +94,33 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { get { return "TempAttachmentsModule"; } } + + private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) + { + SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); + + if (hostPart == null) + return; + + if (hostPart.ParentGroup.IsAttachment) + return; + + IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface(); + if (attachmentsModule == null) + return; + + TaskInventoryItem item = hostPart.Inventory.GetInventoryItem(script); + if (item == null) + return; + + if ((item.PermsMask & 32) == 0) // PERMISSION_ATTACH + return; + + ScenePresence target; + if (!m_scene.TryGetScenePresence(item.PermsGranter, out target)) + return; + + attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true); + } } } -- cgit v1.1 From 1be072f19ee72f8b983aeceb036b1e6c6e041991 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Aug 2012 09:55:44 +0100 Subject: Move inititalization to RegionLoaded to avoid a module loading order issue --- .../Avatar/Attachments/TempAttachmentsModule.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index e659ec0..7011f38 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -59,6 +59,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments public void AddRegion(Scene scene) { + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { m_scene = scene; IScriptModuleComms comms = scene.RequestModuleInterface(); @@ -73,14 +81,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments } } - public void RemoveRegion(Scene scene) - { - } - - public void RegionLoaded(Scene scene) - { - } - public void Close() { } -- cgit v1.1 From a5b6492223ae0dfeb12d768c12e6347e93225d14 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Aug 2012 13:40:13 +0100 Subject: Perform ownership transfer and permission propagation as well as needed updates on the new temp attachment. --- .../Avatar/Attachments/TempAttachmentsModule.cs | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 7011f38..27ba5c9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -120,6 +120,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments if (!m_scene.TryGetScenePresence(item.PermsGranter, out target)) return; + if (target.UUID != hostPart.ParentGroup.OwnerID) + { + uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions(); + + if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) + return; + + hostPart.ParentGroup.SetOwnerId(target.UUID); + hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId); + + if (m_scene.Permissions.PropagatePermissions()) + { + foreach (SceneObjectPart child in hostPart.ParentGroup.Parts) + { + child.Inventory.ChangeInventoryOwner(target.UUID); + child.TriggerScriptChangedEvent(Changed.OWNER); + child.ApplyNextOwnerPermissions(); + } + } + + hostPart.ParentGroup.RootPart.ObjectSaleType = 0; + hostPart.ParentGroup.RootPart.SalePrice = 10; + + hostPart.ParentGroup.HasGroupChanged = true; + hostPart.ParentGroup.RootPart.SendPropertiesToClient(target.ControllingClient); + hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); + } + attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true); } } -- cgit v1.1 From ebbf349c6a883ea641ee02b0517313f6391f60ef Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 15 Aug 2012 18:22:52 +0200 Subject: Let the temp attachment module add a command to allow attaching without permissions and add support for this (incomplete!) to LSL --- .../Avatar/Attachments/TempAttachmentsModule.cs | 41 ++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 27ba5c9..cb89cd1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -43,15 +43,13 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Avatar.Attachments { - /// - /// A module that just holds commands for inspecting avatar appearance. - /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TempAttachmentsModule")] public class TempAttachmentsModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; + private IRegionConsole m_console; public void Initialise(IConfigSource configSource) { @@ -74,6 +72,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { comms.RegisterScriptInvocation( this, "llAttachToAvatarTemp"); m_log.DebugFormat("[TEMP ATTACHS]: Registered script functions"); + m_console = scene.RequestModuleInterface(); + + if (m_console != null) + { + m_console.AddCommand("TempATtachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner os estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); + } } else { @@ -95,6 +99,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments get { return "TempAttachmentsModule"; } } + private void SendConsoleOutput(UUID agentID, string text) + { + if (m_console == null) + return; + + m_console.SendConsoleOutput(agentID, text); + } + + private void SetAutoGrantAttachPerms(string module, string[] parms) + { + UUID agentID = new UUID(parms[parms.Length - 1]); + Array.Resize(ref parms, parms.Length - 1); + + if (parms.Length != 3) + { + SendConsoleOutput(agentID, "Command parameter error"); + return; + } + + string val = parms[2]; + if (val != "true" && val != "false") + { + SendConsoleOutput(agentID, "Command parameter error"); + return; + } + + m_scene.StoreExtraSetting("auto_grant_attach_perms", val); + + SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val)); + } + private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) { SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); -- cgit v1.1 From e041f09750419f60c819ee7e7a99044fe43a811c Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 6 Sep 2012 11:45:52 +0100 Subject: refactoring to allow Scene.GetLandData to accept Vector3 as an argument. Note that the prior work on LSL_Vector implicit operators means one does not need to explicitly cast a LSL_Vector to Vector3 --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 2 +- .../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 7fafdc6..37ab35a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -447,7 +447,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // settings allow voice, then whether parcel allows // voice, if all do retrieve or obtain the parcel // voice channel - LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + LandData land = scene.GetLandData(avatar.AbsolutePosition); //m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index a36fd74..c5fcef4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -623,7 +623,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // settings allow voice, then whether parcel allows // voice, if all do retrieve or obtain the parcel // voice channel - LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + LandData land = scene.GetLandData(avatar.AbsolutePosition); m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); -- cgit v1.1 From 5e626ce55de0b12797f2da7819e15747721779e6 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Mon, 17 Sep 2012 13:02:56 +0100 Subject: script invocations cannot have void return type --- .../Avatar/Attachments/TempAttachmentsModule.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index cb89cd1..d7fb272 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -130,37 +130,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val)); } - private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) + private int llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) { SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); if (hostPart == null) - return; + return 0; if (hostPart.ParentGroup.IsAttachment) - return; + return 0; IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface(); if (attachmentsModule == null) - return; + return 0; TaskInventoryItem item = hostPart.Inventory.GetInventoryItem(script); if (item == null) - return; + return 0; if ((item.PermsMask & 32) == 0) // PERMISSION_ATTACH - return; + return 0; ScenePresence target; if (!m_scene.TryGetScenePresence(item.PermsGranter, out target)) - return; + return 0; if (target.UUID != hostPart.ParentGroup.OwnerID) { uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions(); if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) - return; + return 0; hostPart.ParentGroup.SetOwnerId(target.UUID); hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId); @@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); } - attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true); + return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true) ? 1 : 0; } } } -- cgit v1.1 From b481a782341b721b14f30108b411a580e5f8651e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 20 Sep 2012 02:01:01 +0100 Subject: Don't fail to create an IRC nick if nick randomization is disabled in the IRC module. Patch from http://opensimulator.org/mantis/view.php?id=6293 Thanks Starflower. --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index ca956fb..a014798 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -231,12 +231,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (m_server == null || m_baseNick == null || m_ircChannel == null || m_user == null) throw new Exception("Invalid connector configuration"); - // Generate an initial nickname if randomizing is enabled + // Generate an initial nickname if (m_randomizeNick) - { m_nick = m_baseNick + Util.RandomClass.Next(1, 99); - } + else + m_nick = m_baseNick; m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); -- cgit v1.1 From 531edd51d82ecd6a842a2611c99e9919634491ef Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 30 Sep 2012 07:22:55 -0700 Subject: Added request.Proxy=null everywhere, as discussed in http://stackoverflow.com/questions/2519655/httpwebrequest-is-extremely-slow. Thanks R.Gunther (rigun@rigutech.nl) https://lists.berlios.de/pipermail/opensim-users/2012-September/010986.html --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 1 + .../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 1 + .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index e22618d..fbbb60f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -386,7 +386,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge updatePost.ContentType = "text/xml"; updatePost.ContentLength = payload.Length; updatePost.UserAgent = "OpenSim.Concierge"; - + updatePost.Proxy = null; BrokerState bs = new BrokerState(uri, payload, updatePost); bs.Timer = new Timer(delegate(object state) diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 37ab35a..8a5ce62 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -541,6 +541,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice forwardreq.Method = method; forwardreq.ContentType = contenttype; forwardreq.KeepAlive = false; + forwardreq.Proxy = null; if (method == "POST") { diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index c5fcef4..f5d8e19 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -1119,6 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // We are sending just parameters, no content req.ContentLength = 0; + req.Proxy = null; // Send request and retrieve the response rsp = (HttpWebResponse)req.GetResponse(); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index d412cd1..5102115 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1150,6 +1150,7 @@ namespace Nwc.XmlRpc request.ContentType = "text/xml"; request.AllowWriteStreamBuffering = true; request.KeepAlive = !_disableKeepAlive; + request.Proxy = null; Stream stream = request.GetRequestStream(); XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII); -- cgit v1.1 From 91a5c602e313b96ffaf1d50b7f0d2923a2e141ba Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 30 Sep 2012 07:48:03 -0700 Subject: Revert "Added request.Proxy=null everywhere, as discussed in http://stackoverflow.com/questions/2519655/httpwebrequest-is-extremely-slow." But the patch is here, in case anyone wants to try it. This reverts commit 531edd51d82ecd6a842a2611c99e9919634491ef. --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 +- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 1 - .../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 1 - .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index fbbb60f..e22618d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -386,7 +386,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge updatePost.ContentType = "text/xml"; updatePost.ContentLength = payload.Length; updatePost.UserAgent = "OpenSim.Concierge"; - updatePost.Proxy = null; + BrokerState bs = new BrokerState(uri, payload, updatePost); bs.Timer = new Timer(delegate(object state) diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 8a5ce62..37ab35a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -541,7 +541,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice forwardreq.Method = method; forwardreq.ContentType = contenttype; forwardreq.KeepAlive = false; - forwardreq.Proxy = null; if (method == "POST") { diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index f5d8e19..c5fcef4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -1119,7 +1119,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // We are sending just parameters, no content req.ContentLength = 0; - req.Proxy = null; // Send request and retrieve the response rsp = (HttpWebResponse)req.GetResponse(); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 5102115..d412cd1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1150,7 +1150,6 @@ namespace Nwc.XmlRpc request.ContentType = "text/xml"; request.AllowWriteStreamBuffering = true; request.KeepAlive = !_disableKeepAlive; - request.Proxy = null; Stream stream = request.GetRequestStream(); XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII); -- cgit v1.1 From f7dcd3300837f3be42031448198f70cbbb29e467 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 19 Oct 2012 03:12:58 +0100 Subject: minor: Increase attachment name field from 36 to 50 chars in "attachments show" report --- .../OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index d68aabc..68bcb4a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments sb.AppendFormat("Attachments for {0}\n", sp.Name); ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; - ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 50)); ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10)); ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36)); ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14)); -- cgit v1.1 From e46987972525f7727eb4bd9d6eafa522937558cb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 19 Oct 2012 23:45:55 +0100 Subject: Add "debug groups verbose " region console command This allows one to turn on super-verbose groups debug logging on and off whilst the region is in operation. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index e669f4c..6b69de2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -123,7 +123,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { if (m_groupsEnabled) + { scene.RegisterModuleInterface(this); + scene.AddCommand( + "debug", + this, + "debug groups verbose", + "debug groups verbose ", + "This setting turns on very verbose groups debugging", + HandleDebugGroupsVerbose); + } + } + + private void HandleDebugGroupsVerbose(object modules, string[] args) + { + if (args.Length < 4) + { + MainConsole.Instance.Output("Usage: debug groups verbose "); + return; + } + + bool verbose = false; + if (!bool.TryParse(args[3], out verbose)) + { + MainConsole.Instance.Output("Usage: debug groups verbose "); + return; + } + + m_debugEnabled = verbose; + + MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled); } public void RegionLoaded(Scene scene) -- cgit v1.1 From 6cca7136799c2f89c0511eb1831102e4b7a87fed Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 20 Oct 2012 01:08:52 +0100 Subject: Fix build break from commit e469879 --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6b69de2..b9b4413 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -152,7 +152,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_debugEnabled = verbose; - MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled); + MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled); } public void RegionLoaded(Scene scene) -- cgit v1.1 From cd3762ca9f97052a6fe91a3eca491407cc6f039e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 20 Oct 2012 01:26:04 +0100 Subject: Add experimental [Groups] MessageOnlineUsersOnly option for Flotsam XmlRpc groups. This retrieves and caches information from the PresenceService to only send messages to online users. This is reported to much improve performance for large groups where most users are offline. Cache is 20 seconds to balance requests against users not receiving messages until cache updates. This is an alternative to an approach where login/logout notification is sent directly from simulator to groups service. However, I'm not convinced that this PresenceService approach is actually better. Needs more thought. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 76 ++++++++++++++++++++-- 1 file changed, 69 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 10b83e6..55bb7dc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using log4net; using Mono.Addins; @@ -36,6 +37,8 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { @@ -45,6 +48,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_sceneList = new List(); + private IPresenceService m_presenceService; private IMessageTransferModule m_msgTransferModule = null; @@ -54,6 +58,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_groupMessagingEnabled = false; private bool m_debugEnabled = true; + /// + /// If enabled, module only tries to send group IMs to online users by querying cached presence information. + /// + private bool m_messageOnlineAgentsOnly; + + /// + /// Cache for online users. + /// + /// + /// Group ID is key, presence information for online members is value. + /// Will only be non-null if m_messageOnlineAgentsOnly = true + /// We cache here so that group messages don't constantly have to re-request the online user list to avoid + /// attempted expensive sending of messages to offline users. + /// The tradeoff is that a user that comes online will not receive messages consistently from all other users + /// until caches have updated. + /// Therefore, we set the cache expiry to just 20 seconds. + /// + private ExpiringCache m_usersOnlineCache; + + private int m_usersOnlineCacheExpirySeconds = 20; + #region IRegionModuleBase Members public void Initialise(IConfigSource config) @@ -83,10 +108,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } + m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false); + + if (m_messageOnlineAgentsOnly) + m_usersOnlineCache = new ExpiringCache(); + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); } - m_log.Info("[GROUPS-MESSAGING]: GroupsMessagingModule starting up"); + m_log.InfoFormat( + "[GROUPS-MESSAGING]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}", + m_messageOnlineAgentsOnly, m_debugEnabled); } public void AddRegion(Scene scene) @@ -126,6 +158,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } + if (m_presenceService == null) + m_presenceService = scene.PresenceService; m_sceneList.Add(scene); @@ -207,12 +241,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); - - if (m_debugEnabled) - m_log.DebugFormat( - "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", - groupID, groupMembers.Count); - + + if (m_messageOnlineAgentsOnly) + { + string[] t1 = groupMembers.ConvertAll(gmd => gmd.AgentID.ToString()).ToArray(); + + // We cache in order not to overwhlem the presence service on large grids with many groups. This does + // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. + // (assuming this is the same across all grid simulators). + PresenceInfo[] onlineAgents; + if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) + { + onlineAgents = m_presenceService.GetAgents(t1); + m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); + } + + HashSet onlineAgentsUuidSet = new HashSet(); + Array.ForEach(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); + + int allMembersCount = groupMembers.Count; + groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); + + // if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", + groupID, allMembersCount, groupMembers.Count()); + } + else + { + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", + groupID, groupMembers.Count); + } + foreach (GroupMembersData member in groupMembers) { if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) -- cgit v1.1 From 1937e5f1ec73dcfb9663ad4fe4b59f33a2210d64 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 20 Oct 2012 02:13:00 +0100 Subject: Relocate temporary debug message for sending group IMs to online members only so that we can add ms it takes to send. This is chiefly to assess how long it may still take to send messages to such filtered groups. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 55bb7dc..1528330 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -241,6 +241,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); + int groupMembersCount = groupMembers.Count; if (m_messageOnlineAgentsOnly) { @@ -259,13 +260,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups HashSet onlineAgentsUuidSet = new HashSet(); Array.ForEach(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); - int allMembersCount = groupMembers.Count; groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); // if (m_debugEnabled) - m_log.DebugFormat( - "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", - groupID, allMembersCount, groupMembers.Count()); +// m_log.DebugFormat( +// "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", +// groupID, groupMembersCount, groupMembers.Count()); } else { @@ -275,6 +275,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups groupID, groupMembers.Count); } + int requestStartTick = Environment.TickCount; + foreach (GroupMembersData member in groupMembers) { if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) @@ -316,6 +318,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ProcessMessageFromGroupSession(msg); } } + + // Temporary for assessing how long it still takes to send messages to large online groups. + if (m_messageOnlineAgentsOnly) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", + groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); } #region SimGridEventHandlers -- cgit v1.1 From c13a99dc5cc82efac5497dab27dcb6b0d9865cea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 25 Oct 2012 03:26:12 +0100 Subject: Fix script error messages not showing up in viewer 3 and associated viewers. Viewer 3 will discard such a message if the chat message owner does not match the avatar. We were filling the ownerID with the primID, so this never matched, hence viewer 3 did not see any script error messages. This commit fills the ownerID in with the prim ownerID so the script owner will receive script error messages. This does not affect viewer 1 and associated viewers which continue to process script errors as normal. --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index e22618d..5c3be29 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -546,8 +546,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge c.SenderUUID = UUID.Zero; c.Scene = agent.Scene; - agent.ControllingClient.SendChatMessage(msg, (byte) ChatTypeEnum.Say, PosOfGod, m_whoami, UUID.Zero, - (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); + agent.ControllingClient.SendChatMessage( + msg, (byte) ChatTypeEnum.Say, PosOfGod, m_whoami, UUID.Zero, UUID.Zero, + (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); } private static void checkStringParameters(XmlRpcRequest request, string[] param) -- cgit v1.1 From 0d15a6a01feeb129b015f7516fd13a541b3e6fce Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 12 Nov 2012 19:18:20 +0000 Subject: Remove any mention of IRegionModule from region names and comments to aid grepping for remaining uses --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- .../Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | 2 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 1528330..e03a27c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private int m_usersOnlineCacheExpirySeconds = 20; - #region IRegionModuleBase Members + #region Region Module interfaceBase Members public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b9b4413..856e4e2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -86,7 +86,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_debugEnabled = false; private int m_levelGroupCreate = 0; - #region IRegionModuleBase Members + #region Region Module interfaceBase Members public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 5d57f70..5c7a3ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // private IUserAccountService m_accountService = null; - #region IRegionModuleBase Members + #region Region Module interfaceBase Members public string Name { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index d412cd1..cfc26a0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); - #region IRegionModuleBase Members + #region Region Module interfaceBase Members public string Name { -- cgit v1.1 From 86903f23dd9c0e671fcc9854c031bcc0c6d6cc7f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 12 Nov 2012 18:08:02 -0800 Subject: Cleanup on region modules: gave short node id's to all of them. --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 +- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- .../Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | 2 +- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index e03a27c..2802e2f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -42,7 +42,7 @@ using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsMessagingModule")] public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 856e4e2..193d1db 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -43,7 +43,7 @@ using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")] public class GroupsModule : ISharedRegionModule, IGroupsModule { /// diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 5c7a3ac..7bae8f7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -102,7 +102,7 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianGroupsServicesConnectorModule")] public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index cfc26a0..d0c3ea5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -47,7 +47,7 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XmlRpcGroupsServicesConnectorModule")] public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); -- cgit v1.1 From 18c5d33f0a6ccd08261e753f7bc9834708a1c777 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 13 Nov 2012 09:48:56 -0800 Subject: All optional modules' directives moved out of addin.xml --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 2 ++ OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 2 ++ .../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 2 ++ 3 files changed, 6 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 913d934..2e1d03d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Net; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; @@ -40,6 +41,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Avatar.Chat { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "IRCBridgeModule")] public class IRCBridgeModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 5c3be29..018357a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -36,6 +36,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -47,6 +48,7 @@ using OpenSim.Region.CoreModules.Avatar.Chat; namespace OpenSim.Region.OptionalModules.Avatar.Concierge { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ConciergeModule")] public class ConciergeModule : ChatModule, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index c5fcef4..881807a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -36,6 +36,7 @@ using System.Reflection; using System.Threading; using OpenMetaverse; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; @@ -49,6 +50,7 @@ using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "VivoxVoiceModule")] public class VivoxVoiceModule : ISharedRegionModule { -- cgit v1.1 From 82690e138448ebac6456ab03dcca4b0a8a1cc57a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 02:43:31 +0000 Subject: Fix bug where loading an OAR with a deeded parcel would always set the parcel owner ID to the estate owner even if the group UUID was present. Aims to address http://opensimulator.org/mantis/view.php?id=6355 As part of this work, an incomplete IXGroupsData was added which currently only allows store/fetch/delete of group records (i.e. no membership data etc) This is subject to change and currently only an in-memory storage implementation exists for regression test purposes. --- .../XmlRpcGroups/IGroupsServicesConnector.cs | 15 +++ .../XmlRpcGroupsServicesConnectorModule.cs | 127 ++++++++++----------- 2 files changed, 76 insertions(+), 66 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 6d26075..6b5b40a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -36,7 +36,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + + /// + /// Get the group record. + /// + /// + /// The UUID of the user making the request. + /// + /// The ID of the record to retrieve. + /// GroupName may be specified instead, in which case this parameter will be UUID.Zero + /// + /// + /// The name of the group to retrieve. + /// GroupID may be specified instead, in which case this parmeter will be null. + /// GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); + List FindGroups(UUID RequestingAgentID, string search); List GetGroupMembers(UUID RequestingAgentID, UUID GroupID); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index d0c3ea5..1101851 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -54,13 +54,62 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_debugEnabled = false; - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | - GroupPowers.Accountable | - GroupPowers.JoinChat | - GroupPowers.AllowVoiceChat | - GroupPowers.ReceiveNotices | - GroupPowers.StartProposal | - GroupPowers.VoteOnProposal; + public const GroupPowers DefaultEveryonePowers + = GroupPowers.AllowSetHome + | GroupPowers.Accountable + | GroupPowers.JoinChat + | GroupPowers.AllowVoiceChat + | GroupPowers.ReceiveNotices + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + + // Would this be cleaner as (GroupPowers)ulong.MaxValue? + public const GroupPowers DefaultOwnerPowers + = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; private bool m_connectorEnabled = false; @@ -219,59 +268,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; param["FounderID"] = founderID.ToString(); - param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); + param["EveryonePowers"] = ((ulong)DefaultEveryonePowers).ToString(); param["OwnerRoleID"] = OwnerRoleID.ToString(); - - // Would this be cleaner as (GroupPowers)ulong.MaxValue; - GroupPowers OwnerPowers = GroupPowers.Accountable - | GroupPowers.AllowEditLand - | GroupPowers.AllowFly - | GroupPowers.AllowLandmark - | GroupPowers.AllowRez - | GroupPowers.AllowSetHome - | GroupPowers.AllowVoiceChat - | GroupPowers.AssignMember - | GroupPowers.AssignMemberLimited - | GroupPowers.ChangeActions - | GroupPowers.ChangeIdentity - | GroupPowers.ChangeMedia - | GroupPowers.ChangeOptions - | GroupPowers.CreateRole - | GroupPowers.DeedObject - | GroupPowers.DeleteRole - | GroupPowers.Eject - | GroupPowers.FindPlaces - | GroupPowers.Invite - | GroupPowers.JoinChat - | GroupPowers.LandChangeIdentity - | GroupPowers.LandDeed - | GroupPowers.LandDivideJoin - | GroupPowers.LandEdit - | GroupPowers.LandEjectAndFreeze - | GroupPowers.LandGardening - | GroupPowers.LandManageAllowed - | GroupPowers.LandManageBanned - | GroupPowers.LandManagePasses - | GroupPowers.LandOptions - | GroupPowers.LandRelease - | GroupPowers.LandSetSale - | GroupPowers.ModerateChat - | GroupPowers.ObjectManipulate - | GroupPowers.ObjectSetForSale - | GroupPowers.ReceiveNotices - | GroupPowers.RemoveMember - | GroupPowers.ReturnGroupOwned - | GroupPowers.ReturnGroupSet - | GroupPowers.ReturnNonGroup - | GroupPowers.RoleProperties - | GroupPowers.SendNotices - | GroupPowers.SetLandingPoint - | GroupPowers.StartProposal - | GroupPowers.VoteOnProposal; - param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); - - - + param["OwnersPowers"] = ((ulong)DefaultOwnerPowers).ToString(); Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); @@ -612,8 +611,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - - } public List GetGroupRoles(UUID requestingAgentID, UUID GroupID) @@ -676,7 +673,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return members; - } public List GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) @@ -727,9 +723,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups values.Add(data); } } - return values; + return values; } + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Hashtable param = new Hashtable(); @@ -737,7 +734,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); - if (respData.Contains("error")) { return null; @@ -761,6 +757,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -777,8 +774,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } - - #endregion #region GroupSessionTracking -- cgit v1.1 From 22d4c52ffc374e167cb674e0e20815615d8a6927 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 03:15:24 +0000 Subject: Consistenly make NUnit test cases inherit from OpenSimTestCase which automatically turns off any logging enabled between tests --- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index ac638f1..c1bdacb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests /// Basic groups module tests /// [TestFixture] - public class GroupsModuleTests + public class GroupsModuleTests : OpenSimTestCase { [Test] public void TestBasic() -- cgit v1.1 From addab1244ecc586b0a6fc8560b94c871567b78da Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 21:38:00 +0000 Subject: Add "show animations" console command for debug purposes. This shows the current animation sequence and default anims for avatars. --- .../Avatar/Animations/AnimationsCommandModule.cs | 215 +++++++++++++++++++++ .../Avatar/Attachments/AttachmentsCommandModule.cs | 1 + 2 files changed, 216 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs new file mode 100644 index 0000000..2d418f1 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -0,0 +1,215 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.OptionalModules.Avatar.Animations +{ + /// + /// A module that just holds commands for inspecting avatar animations. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")] + public class AnimationsCommandModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_scenes = new List(); + + public string Name { get { return "Animations Command Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Remove(scene); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Add(scene); + + scene.AddCommand( + "Users", this, "show animations", + "show animations [ ]", + "Show animation information for avatars in this simulator.", + "If no name is supplied then information for all avatars is shown.\n" + + "Please note that for inventory animations, the animation name is the name under which the animation was originally uploaded\n" + + ", which is not necessarily the current inventory name.", + HandleShowAnimationsCommand); + } + + protected void HandleShowAnimationsCommand(string module, string[] cmd) + { + if (cmd.Length != 2 && cmd.Length < 4) + { + MainConsole.Instance.OutputFormat("Usage: show animations [ ]"); + return; + } + + bool targetNameSupplied = false; + string optionalTargetFirstName = null; + string optionalTargetLastName = null; + + if (cmd.Length >= 4) + { + targetNameSupplied = true; + optionalTargetFirstName = cmd[2]; + optionalTargetLastName = cmd[3]; + } + + StringBuilder sb = new StringBuilder(); + + lock (m_scenes) + { + foreach (Scene scene in m_scenes) + { + if (targetNameSupplied) + { + ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); + if (sp != null && !sp.IsChildAgent) + GetAttachmentsReport(sp, sb); + } + else + { + scene.ForEachRootScenePresence(sp => GetAttachmentsReport(sp, sb)); + } + } + } + + MainConsole.Instance.Output(sb.ToString()); + } + + private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb) + { + sb.AppendFormat("Animations for {0}\n", sp.Name); + + ConsoleDisplayList cdl = new ConsoleDisplayList(); + ScenePresenceAnimator spa = sp.Animator; + AnimationSet anims = sp.Animator.Animations; + + string cma = spa.CurrentMovementAnimation; + cdl.AddRow( + "Current movement anim", + string.Format("{0}, {1}", DefaultAvatarAnimations.GetDefaultAnimation(cma), cma)); + + UUID defaultAnimId = anims.DefaultAnimation.AnimID; + cdl.AddRow( + "Default anim", + string.Format("{0}, {1}", defaultAnimId, GetAnimName(sp.Scene.AssetService, defaultAnimId))); + + UUID implicitDefaultAnimId = anims.ImplicitDefaultAnimation.AnimID; + cdl.AddRow( + "Implicit default anim", + string.Format("{0}, {1}", implicitDefaultAnimId, GetAnimName(sp.Scene.AssetService, implicitDefaultAnimId))); + + cdl.AddToStringBuilder(sb); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable() { Indent = 2 }; + cdt.AddColumn("Animation ID", 36); + cdt.AddColumn("Name", 20); + cdt.AddColumn("Seq", 3); + cdt.AddColumn("Object ID", 36); + + UUID[] animIds; + int[] sequenceNumbers; + UUID[] objectIds; + + sp.Animator.Animations.GetArrays(out animIds, out sequenceNumbers, out objectIds); + + for (int i = 0; i < animIds.Length; i++) + { + UUID animId = animIds[i]; + string animName = GetAnimName(sp.Scene.AssetService, animId); + int seq = sequenceNumbers[i]; + UUID objectId = objectIds[i]; + + cdt.Rows.Add(new ConsoleDisplayTableRow(animId, animName, seq, objectId)); + } + + cdt.AddToStringBuilder(sb); + sb.Append("\n"); + } + + private string GetAnimName(IAssetService assetService, UUID animId) + { + string animName; + + if (!DefaultAvatarAnimations.AnimsNames.TryGetValue(animId, out animName)) + { + AssetMetadata amd = assetService.GetMetadata(animId.ToString()); + if (amd != null) + animName = amd.Name; + else + animName = "Unknown"; + } + + return animName; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index 68bcb4a..d97e3b3 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -97,6 +97,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments "Users", this, "attachments show", "attachments show [ ]", "Show attachment information for avatars in this simulator.", + "If no name is supplied then information for all avatars is shown.", HandleShowAttachmentsCommand); } -- cgit v1.1 From 6b55f5183787fb719c7bd4547e5894096a7aed51 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 22:11:13 +0000 Subject: minor: Allow objects to be added directly to a row on a ConsoleDisplayTable rather than having to ToString() them first --- .../Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs index 2d418f1..ffef912 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -189,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations int seq = sequenceNumbers[i]; UUID objectId = objectIds[i]; - cdt.Rows.Add(new ConsoleDisplayTableRow(animId, animName, seq, objectId)); + cdt.AddRow(animId, animName, seq, objectId); } cdt.AddToStringBuilder(sb); -- cgit v1.1 From 8f31649faddfc2f7a28131f592b1e79ae75b863f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 22:37:50 +0000 Subject: Fix indenting on ConsoleDisplayTable, align indenting on "show animations" console command --- .../Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs index ffef912..e951d9e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -149,7 +149,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations { sb.AppendFormat("Animations for {0}\n", sp.Name); - ConsoleDisplayList cdl = new ConsoleDisplayList(); + ConsoleDisplayList cdl = new ConsoleDisplayList() { Indent = 2 }; ScenePresenceAnimator spa = sp.Animator; AnimationSet anims = sp.Animator.Animations; -- cgit v1.1 From 17f21ba9a0d11f68fa892ab9d83eaa7db89aae37 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 22:46:25 +0000 Subject: minor: Capitalize GroupsModule command category --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 193d1db..29f9591 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -126,7 +126,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { scene.RegisterModuleInterface(this); scene.AddCommand( - "debug", + "Debug", this, "debug groups verbose", "debug groups verbose ", -- cgit v1.1 From 115e1c2abb7755eb7b5ffeafbc0aecd255ccfc4e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 Jan 2013 23:22:02 +0000 Subject: Add "debug set set animations true|false" region console command. Setting this logs extra information about animation add/remove, such as uuid and animation name Unfortunately cannot be done per client yet --- .../Avatar/Animations/AnimationsCommandModule.cs | 23 ++++------------------ 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs index e951d9e..84211a9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -161,12 +161,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations UUID defaultAnimId = anims.DefaultAnimation.AnimID; cdl.AddRow( "Default anim", - string.Format("{0}, {1}", defaultAnimId, GetAnimName(sp.Scene.AssetService, defaultAnimId))); + string.Format("{0}, {1}", defaultAnimId, sp.Animator.GetAnimName(defaultAnimId))); UUID implicitDefaultAnimId = anims.ImplicitDefaultAnimation.AnimID; cdl.AddRow( "Implicit default anim", - string.Format("{0}, {1}", implicitDefaultAnimId, GetAnimName(sp.Scene.AssetService, implicitDefaultAnimId))); + string.Format("{0}, {1}", + implicitDefaultAnimId, sp.Animator.GetAnimName(implicitDefaultAnimId))); cdl.AddToStringBuilder(sb); @@ -185,7 +186,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations for (int i = 0; i < animIds.Length; i++) { UUID animId = animIds[i]; - string animName = GetAnimName(sp.Scene.AssetService, animId); + string animName = sp.Animator.GetAnimName(animId); int seq = sequenceNumbers[i]; UUID objectId = objectIds[i]; @@ -195,21 +196,5 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations cdt.AddToStringBuilder(sb); sb.Append("\n"); } - - private string GetAnimName(IAssetService assetService, UUID animId) - { - string animName; - - if (!DefaultAvatarAnimations.AnimsNames.TryGetValue(animId, out animName)) - { - AssetMetadata amd = assetService.GetMetadata(animId.ToString()); - if (amd != null) - animName = amd.Name; - else - animName = "Unknown"; - } - - return animName; - } } } \ No newline at end of file -- cgit v1.1 From 9c590e51b6a1457ccb9eaee525d1e5a244b50274 Mon Sep 17 00:00:00 2001 From: PixelTomsen Date: Sun, 13 Jan 2013 20:18:40 +0100 Subject: IRCBridgeModule: optional agent-alertbox for IRC enabled Regions look in OpenSimDefaults.ini / section [IRC] http://opensimulator.org/mantis/view.php?id=6470 idea: https://github.com/ssm2017/IrcBridgeAlert --- .../OptionalModules/Avatar/Chat/ChannelState.cs | 158 ++++++------ .../OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 41 +-- .../OptionalModules/Avatar/Chat/IRCConnector.cs | 283 +++++++++++---------- .../OptionalModules/Avatar/Chat/RegionState.cs | 96 ++++--- 4 files changed, 305 insertions(+), 273 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 66265d8..5a37fad 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -55,42 +55,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // These are the IRC Connector configurable parameters with hard-wired // default values (retained for compatability). - internal string Server = null; - internal string Password = null; - internal string IrcChannel = null; - internal string BaseNickname = "OSimBot"; - internal uint Port = 6667; - internal string User = null; - - internal bool ClientReporting = true; - internal bool RelayChat = true; - internal bool RelayPrivateChannels = false; - internal int RelayChannel = 1; + internal string Server = null; + internal string Password = null; + internal string IrcChannel = null; + internal string BaseNickname = "OSimBot"; + internal uint Port = 6667; + internal string User = null; + + internal bool ClientReporting = true; + internal bool RelayChat = true; + internal bool RelayPrivateChannels = false; + internal int RelayChannel = 1; internal List ValidInWorldChannels = new List(); // Connector agnostic parameters. These values are NOT shared with the // connector and do not differentiate at an IRC level internal string PrivateMessageFormat = "PRIVMSG {0} :<{2}> {1} {3}"; - internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; - internal int RelayChannelOut = -1; - internal bool RandomizeNickname = true; - internal bool CommandsEnabled = false; - internal int CommandChannel = -1; - internal int ConnectDelay = 10; - internal int PingDelay = 15; - internal string DefaultZone = "Sim"; - - internal string _accessPassword = String.Empty; - internal Regex AccessPasswordRegex = null; - internal List ExcludeList = new List(); + internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; + internal int RelayChannelOut = -1; + internal bool RandomizeNickname = true; + internal bool CommandsEnabled = false; + internal int CommandChannel = -1; + internal int ConnectDelay = 10; + internal int PingDelay = 15; + internal string DefaultZone = "Sim"; + + internal string _accessPassword = String.Empty; + internal Regex AccessPasswordRegex = null; + internal List ExcludeList = new List(); internal string AccessPassword { get { return _accessPassword; } - set + set { _accessPassword = value; - AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?[^,]+),\s*(?.+)$", _accessPassword), + AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?[^,]+),\s*(?.+)$", _accessPassword), RegexOptions.Compiled); } } @@ -99,9 +99,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // IRC connector reference - internal IRCConnector irc = null; + internal IRCConnector irc = null; - internal int idn = _idk_++; + internal int idn = _idk_++; // List of regions dependent upon this connection @@ -119,29 +119,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal ChannelState(ChannelState model) { - Server = model.Server; - Password = model.Password; - IrcChannel = model.IrcChannel; - Port = model.Port; - BaseNickname = model.BaseNickname; - RandomizeNickname = model.RandomizeNickname; - User = model.User; - CommandsEnabled = model.CommandsEnabled; - CommandChannel = model.CommandChannel; - RelayChat = model.RelayChat; + Server = model.Server; + Password = model.Password; + IrcChannel = model.IrcChannel; + Port = model.Port; + BaseNickname = model.BaseNickname; + RandomizeNickname = model.RandomizeNickname; + User = model.User; + CommandsEnabled = model.CommandsEnabled; + CommandChannel = model.CommandChannel; + RelayChat = model.RelayChat; RelayPrivateChannels = model.RelayPrivateChannels; - RelayChannelOut = model.RelayChannelOut; - RelayChannel = model.RelayChannel; + RelayChannelOut = model.RelayChannelOut; + RelayChannel = model.RelayChannel; ValidInWorldChannels = model.ValidInWorldChannels; PrivateMessageFormat = model.PrivateMessageFormat; - NoticeMessageFormat = model.NoticeMessageFormat; - ClientReporting = model.ClientReporting; - AccessPassword = model.AccessPassword; - DefaultZone = model.DefaultZone; - ConnectDelay = model.ConnectDelay; - PingDelay = model.PingDelay; + NoticeMessageFormat = model.NoticeMessageFormat; + ClientReporting = model.ClientReporting; + AccessPassword = model.AccessPassword; + DefaultZone = model.DefaultZone; + ConnectDelay = model.ConnectDelay; + PingDelay = model.PingDelay; } - + // Read the configuration file, performing variable substitution and any // necessary aliasing. See accompanying documentation for how this works. // If you don't need variables, then this works exactly as before. @@ -160,54 +160,54 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Channel-{0}] Initial request by Region {1} to connect to IRC", cs.idn, rs.Region); - cs.Server = Substitute(rs, config.GetString("server", null)); + cs.Server = Substitute(rs, config.GetString("server", null)); m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); - cs.Password = Substitute(rs, config.GetString("password", null)); + cs.Password = Substitute(rs, config.GetString("password", null)); // probably not a good idea to put a password in the log file - cs.User = Substitute(rs, config.GetString("user", null)); - cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); + cs.User = Substitute(rs, config.GetString("user", null)); + cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); - cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); + cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); m_log.DebugFormat("[IRC-Channel-{0}] Port : <{1}>", cs.idn, cs.Port); - cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); + cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); m_log.DebugFormat("[IRC-Channel-{0}] BaseNickname : <{1}>", cs.idn, cs.BaseNickname); - cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); + cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); - cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); + cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); - cs.User = Substitute(rs, config.GetString("username", cs.User)); + cs.User = Substitute(rs, config.GetString("username", cs.User)); m_log.DebugFormat("[IRC-Channel-{0}] User : <{1}>", cs.idn, cs.User); - cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); + cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandsEnabled : <{1}>", cs.idn, cs.CommandsEnabled); - cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); + cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); - cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); + cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); - cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); + cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); - cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); + cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannelOut : <{1}>", cs.idn, cs.RelayChannelOut); - cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); + cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); - cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); + cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); cs.PrivateMessageFormat = Substitute(rs, config.GetString("msgformat", cs.PrivateMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] PrivateMessageFormat : <{1}>", cs.idn, cs.PrivateMessageFormat); cs.NoticeMessageFormat = Substitute(rs, config.GetString("noticeformat", cs.NoticeMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] NoticeMessageFormat : <{1}>", cs.idn, cs.NoticeMessageFormat); - cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting?"1":"0"))) > 0; + cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting ? "1" : "0"))) > 0; m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); - cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); + cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); - cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); + cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); - cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); + cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); - cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); + cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); @@ -217,7 +217,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { cs.ExcludeList.Add(name.Trim().ToLower()); } - + // Fail if fundamental information is still missing if (cs.Server == null) @@ -306,8 +306,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat IRCBridgeModule.m_channels.Add(cs); - m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", - cs.idn, rs.Region, cs.DefaultZone, + m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", + cs.idn, rs.Region, cs.DefaultZone, cs.CommandsEnabled ? "enabled" : "not enabled", cs.RelayPrivateChannels ? "relayed" : "not relayed"); } @@ -417,7 +417,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private bool IsAConnectionMatchFor(ChannelState cs) { return ( - Server == cs.Server && + Server == cs.Server && IrcChannel == cs.IrcChannel && Port == cs.Port && BaseNickname == cs.BaseNickname && @@ -473,27 +473,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { string vvar = arg.Match(result).ToString(); - string var = vvar.Substring(1,vvar.Length-2).Trim(); + string var = vvar.Substring(1, vvar.Length - 2).Trim(); switch (var.ToLower()) { - case "%region" : + case "%region": result = result.Replace(vvar, rs.Region); break; - case "%host" : + case "%host": result = result.Replace(vvar, rs.Host); break; - case "%locx" : + case "%locx": result = result.Replace(vvar, rs.LocX); break; - case "%locy" : + case "%locy": result = result.Replace(vvar, rs.LocY); break; - case "%k" : + case "%k": result = result.Replace(vvar, rs.IDK); break; - default : - result = result.Replace(vvar, rs.config.GetString(var,var)); + default: + result = result.Replace(vvar, rs.config.GetString(var, var)); break; } // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 2e1d03d..351dbfe 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -46,18 +46,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - internal static bool m_pluginEnabled = false; + internal static bool Enabled = false; internal static IConfig m_config = null; internal static List m_channels = new List(); - internal static List m_regions = new List(); + internal static List m_regions = new List(); internal static string m_password = String.Empty; internal RegionState m_region = null; #region INonSharedRegionModule Members - public Type ReplaceableInterface + public Type ReplaceableInterface { get { return null; } } @@ -72,13 +72,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_config = config.Configs["IRC"]; if (m_config == null) { -// m_log.InfoFormat("[IRC-Bridge] module not configured"); + // m_log.InfoFormat("[IRC-Bridge] module not configured"); return; } if (!m_config.GetBoolean("enabled", false)) { -// m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); + // m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); return; } @@ -87,19 +87,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_password = config.Configs["RemoteAdmin"].GetString("access_password", m_password); } - m_pluginEnabled = true; - m_log.InfoFormat("[IRC-Bridge]: Module enabled"); + Enabled = true; + + m_log.InfoFormat("[IRC-Bridge]: Module is enabled"); } public void AddRegion(Scene scene) { - if (m_pluginEnabled) + if (Enabled) { try { m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); + if (!String.IsNullOrEmpty(m_password)) MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); + m_region = new RegionState(scene, m_config); lock (m_regions) m_regions.Add(m_region); m_region.Open(); @@ -123,7 +126,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void RemoveRegion(Scene scene) { - if (!m_pluginEnabled) + if (!Enabled) return; if (m_region == null) @@ -150,12 +153,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.Debug("[IRC-Bridge]: XML RPC Admin Entry"); XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = new Hashtable(); try { Hashtable requestData = (Hashtable)request.Params[0]; - bool found = false; + bool found = false; string region = String.Empty; if (m_password != String.Empty) @@ -169,18 +172,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (!requestData.ContainsKey("region")) throw new Exception("No region name specified"); region = (string)requestData["region"]; - + foreach (RegionState rs in m_regions) { if (rs.Region == region) { - responseData["server"] = rs.cs.Server; - responseData["port"] = (int)rs.cs.Port; - responseData["user"] = rs.cs.User; - responseData["channel"] = rs.cs.IrcChannel; - responseData["enabled"] = rs.cs.irc.Enabled; + responseData["server"] = rs.cs.Server; + responseData["port"] = (int)rs.cs.Port; + responseData["user"] = rs.cs.User; + responseData["channel"] = rs.cs.IrcChannel; + responseData["enabled"] = rs.cs.irc.Enabled; responseData["connected"] = rs.cs.irc.Connected; - responseData["nickname"] = rs.cs.irc.Nick; + responseData["nickname"] = rs.cs.irc.Nick; found = true; break; } @@ -195,7 +198,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.ErrorFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); responseData["success"] = "false"; - responseData["error"] = e.Message; + responseData["error"] = e.Message; } finally { diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index a014798..c5cba8e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -53,16 +53,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Local constants private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); - private static readonly char[] CS_SPACE = { ' ' }; + private static readonly char[] CS_SPACE = { ' ' }; - private const int WD_INTERVAL = 1000; // base watchdog interval - private static int PING_PERIOD = 15; // WD intervals per PING - private static int ICCD_PERIOD = 10; // WD intervals between Connects - private static int L_TIMEOUT = 25; // Login time out interval + private const int WD_INTERVAL = 1000; // base watchdog interval + private static int PING_PERIOD = 15; // WD intervals per PING + private static int ICCD_PERIOD = 10; // WD intervals between Connects + private static int L_TIMEOUT = 25; // Login time out interval - private static int _idk_ = 0; // core connector identifier - private static int _pdk_ = 0; // ping interval counter - private static int _icc_ = ICCD_PERIOD; // IRC connect counter + private static int _idk_ = 0; // core connector identifier + private static int _pdk_ = 0; // ping interval counter + private static int _icc_ = ICCD_PERIOD; // IRC connect counter // List of configured connectors @@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private Object msyncConnect = new Object(); - internal bool m_randomizeNick = true; // add random suffix + internal bool m_randomizeNick = true; // add random suffix internal string m_baseNick = null; // base name for randomizing internal string m_nick = null; // effective nickname @@ -122,7 +122,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat get { return m_nick; } set { m_nick = value; } } - + private bool m_enabled = false; // connector enablement public bool Enabled { @@ -130,8 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } private bool m_connected = false; // connection status - private bool m_pending = false; // login disposition - private int m_timeout = L_TIMEOUT; // login timeout counter + private bool m_pending = false; // login disposition + private int m_timeout = L_TIMEOUT; // login timeout counter public bool Connected { get { return m_connected; } @@ -143,9 +143,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat get { return m_ircChannel; } set { m_ircChannel = value; } } - + private uint m_port = 6667; // session port - public uint Port + public uint Port { get { return m_port; } set { m_port = value; } @@ -172,10 +172,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Network interface - private TcpClient m_tcp; + private TcpClient m_tcp; private NetworkStream m_stream = null; - private StreamReader m_reader; - private StreamWriter m_writer; + private StreamReader m_reader; + private StreamWriter m_writer; // Channel characteristic info (if available) @@ -193,26 +193,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Prepare network interface - m_tcp = null; + m_tcp = null; m_writer = null; m_reader = null; // Setup IRC session parameters - m_server = cs.Server; - m_password = cs.Password; - m_baseNick = cs.BaseNickname; + m_server = cs.Server; + m_password = cs.Password; + m_baseNick = cs.BaseNickname; m_randomizeNick = cs.RandomizeNickname; - m_ircChannel = cs.IrcChannel; - m_port = cs.Port; - m_user = cs.User; + m_ircChannel = cs.IrcChannel; + m_port = cs.Port; + m_user = cs.User; if (m_watchdog == null) { // Non-differentiating - ICCD_PERIOD = cs.ConnectDelay; - PING_PERIOD = cs.PingDelay; + ICCD_PERIOD = cs.ConnectDelay; + PING_PERIOD = cs.PingDelay; // Smaller values are not reasonable @@ -235,7 +235,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (m_randomizeNick) m_nick = m_baseNick + Util.RandomClass.Next(1, 99); - else + else m_nick = m_baseNick; m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); @@ -295,18 +295,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_nick, m_ircChannel, m_server)); m_writer.Flush(); } - catch (Exception) {} - + catch (Exception) { } + m_connected = false; - try { m_writer.Close(); } catch (Exception) {} - try { m_reader.Close(); } catch (Exception) {} - try { m_stream.Close(); } catch (Exception) {} - try { m_tcp.Close(); } catch (Exception) {} + try { m_writer.Close(); } + catch (Exception) { } + try { m_reader.Close(); } + catch (Exception) { } + try { m_stream.Close(); } + catch (Exception) { } + try { m_tcp.Close(); } + catch (Exception) { } } - + lock (m_connectors) m_connectors.Remove(this); @@ -347,15 +351,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (m_connected) return; m_connected = true; - m_pending = true; - m_timeout = L_TIMEOUT; + m_pending = true; + m_timeout = L_TIMEOUT; - m_tcp = new TcpClient(m_server, (int)m_port); + m_tcp = new TcpClient(m_server, (int)m_port); m_stream = m_tcp.GetStream(); m_reader = new StreamReader(m_stream); m_writer = new StreamWriter(m_stream); - m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); + m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); m_listener = new Thread(new ThreadStart(ListenerRun)); m_listener.Name = "IRCConnectorListenerThread"; @@ -418,12 +422,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // the socket and it will disappear of its own accord, once this // processing is completed. - try { m_writer.Close(); } catch (Exception) {} - try { m_reader.Close(); } catch (Exception) {} - try { m_tcp.Close(); } catch (Exception) {} + try { m_writer.Close(); } + catch (Exception) { } + try { m_reader.Close(); } + catch (Exception) { } + try { m_tcp.Close(); } + catch (Exception) { } m_connected = false; - m_pending = false; + m_pending = false; m_resetk++; } @@ -495,7 +502,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { string inputLine; - int resetk = m_resetk; + int resetk = m_resetk; try { @@ -555,7 +562,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat Reconnect(); } - private Regex RE = new Regex(@":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)", + private Regex RE = new Regex(@":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)", RegexOptions.Multiline); private Dictionary ExtractMsg(string input) @@ -617,8 +624,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat string[] commArgs; string c_server = m_server; - string pfx = String.Empty; - string cmd = String.Empty; + string pfx = String.Empty; + string cmd = String.Empty; string parms = String.Empty; // ":" indicates that a prefix is present @@ -627,15 +634,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // ":" indicates that the remainder of the // line is a single parameter value. - commArgs = command.Split(CS_SPACE,2); + commArgs = command.Split(CS_SPACE, 2); if (commArgs[0].StartsWith(":")) { pfx = commArgs[0].Substring(1); - commArgs = commArgs[1].Split(CS_SPACE,2); + commArgs = commArgs[1].Split(CS_SPACE, 2); } - cmd = commArgs[0]; + cmd = commArgs[0]; parms = commArgs[1]; // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd); @@ -646,44 +653,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Messages 001-004 are always sent // following signon. - case "001" : // Welcome ... - case "002" : // Server information - case "003" : // Welcome ... + case "001": // Welcome ... + case "002": // Server information + case "003": // Welcome ... break; - case "004" : // Server information + case "004": // Server information m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); commArgs = parms.Split(CS_SPACE); c_server = commArgs[1]; m_server = c_server; - version = commArgs[2]; - usermod = commArgs[3]; - chanmod = commArgs[4]; + version = commArgs[2]; + usermod = commArgs[3]; + chanmod = commArgs[4]; break; - case "005" : // Server information + case "005": // Server information break; - case "042" : - case "250" : - case "251" : - case "252" : - case "254" : - case "255" : - case "265" : - case "266" : - case "332" : // Subject - case "333" : // Subject owner (?) - case "353" : // Name list - case "366" : // End-of-Name list marker - case "372" : // MOTD body - case "375" : // MOTD start + case "042": + case "250": + case "251": + case "252": + case "254": + case "255": + case "265": + case "266": + case "332": // Subject + case "333": // Subject owner (?) + case "353": // Name list + case "366": // End-of-Name list marker + case "372": // MOTD body + case "375": // MOTD start // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); break; - case "376" : // MOTD end + case "376": // MOTD end // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); motd = true; break; - case "451" : // Not registered + case "451": // Not registered break; - case "433" : // Nickname in use + case "433": // Nickname in use // Gen a new name m_nick = m_baseNick + Util.RandomClass.Next(1, 99); m_log.ErrorFormat("[IRC-Connector-{0}]: [{1}] IRC SERVER reports NicknameInUse, trying {2}", idn, cmd, m_nick); @@ -695,29 +702,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); m_writer.Flush(); break; - case "479" : // Bad channel name, etc. This will never work, so disable the connection - m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + case "479": // Bad channel name, etc. This will never work, so disable the connection + m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE, 2)[1]); m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] Connector disabled", idn, cmd); - m_enabled = false; + m_enabled = false; m_connected = false; - m_pending = false; + m_pending = false; break; - case "NOTICE" : + case "NOTICE": // m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); break; - case "ERROR" : - m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + case "ERROR": + m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE, 2)[1]); if (parms.Contains("reconnect too fast")) ICCD_PERIOD++; - m_pending = false; + m_pending = false; Reconnect(); break; - case "PING" : + case "PING": m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); m_writer.WriteLine(String.Format("PONG {0}", parms)); m_writer.Flush(); break; - case "PONG" : + case "PONG": break; case "JOIN": if (m_pending) @@ -748,19 +755,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); eventIrcQuit(pfx, cmd, parms); break; - default : + default: m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms); break; } // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd); - + } public void eventIrcJoin(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); - string IrcUser = prefix.Split('!')[0]; + string[] args = parms.Split(CS_SPACE, 2); + string IrcUser = prefix.Split('!')[0]; string IrcChannel = args[0]; if (IrcChannel.StartsWith(":")) @@ -772,8 +779,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcPart(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); - string IrcUser = prefix.Split('!')[0]; + string[] args = parms.Split(CS_SPACE, 2); + string IrcUser = prefix.Split('!')[0]; string IrcChannel = args[0]; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel); @@ -782,7 +789,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcMode(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); + string[] args = parms.Split(CS_SPACE, 2); string UserMode = args[1]; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel); @@ -794,7 +801,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcNickChange(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); + string[] args = parms.Split(CS_SPACE, 2); string UserOldNick = prefix.Split('!')[0]; string UserNewNick = args[0].Remove(0, 1); @@ -804,11 +811,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcKick(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,3); - string UserKicker = prefix.Split('!')[0]; - string IrcChannel = args[0]; - string UserKicked = args[1]; - string KickMessage = args[2]; + string[] args = parms.Split(CS_SPACE, 3); + string UserKicker = prefix.Split('!')[0]; + string IrcChannel = args[0]; + string UserKicked = args[1]; + string KickMessage = args[2]; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel); BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage); @@ -822,7 +829,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcQuit(string prefix, string command, string parms) { - string IrcUser = prefix.Split('!')[0]; + string IrcUser = prefix.Split('!')[0]; string QuitMessage = parms; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel); @@ -842,65 +849,65 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_); - _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger + _pdk_ = (_pdk_ + 1) % PING_PERIOD; // cycle the ping trigger _icc_++; // increment the inter-consecutive-connect-delay counter lock (m_connectors) - foreach (IRCConnector connector in m_connectors) - { + foreach (IRCConnector connector in m_connectors) + { - // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); + // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); - if (connector.Enabled) - { - if (!connector.Connected) + if (connector.Enabled) { - try + if (!connector.Connected) { - // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); - connector.Connect(); + try + { + // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); + connector.Connect(); + } + catch (Exception e) + { + m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message); + } } - catch (Exception e) + else { - m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message); - } - } - else - { - if (connector.m_pending) - { - if (connector.m_timeout == 0) + if (connector.m_pending) { - m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); - connector.Reconnect(); + if (connector.m_timeout == 0) + { + m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); + connector.Reconnect(); + } + else + connector.m_timeout--; } - else - connector.m_timeout--; - } - // Being marked connected is not enough to ping. Socket establishment can sometimes take a long - // time, in which case the watch dog might try to ping the server before the socket has been - // set up, with nasty side-effects. + // Being marked connected is not enough to ping. Socket establishment can sometimes take a long + // time, in which case the watch dog might try to ping the server before the socket has been + // set up, with nasty side-effects. - else if (_pdk_ == 0) - { - try - { - connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); - connector.m_writer.Flush(); - } - catch (Exception e) + else if (_pdk_ == 0) { - m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); - m_log.Debug(e); - connector.Reconnect(); + try + { + connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); + connector.m_writer.Flush(); + } + catch (Exception e) + { + m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); + m_log.Debug(e); + connector.Reconnect(); + } } - } + } } } - } // m_log.InfoFormat("[IRC-Watchdog] Status scan completed"); diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index 53b103e..d4fe5e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -41,49 +41,71 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal class RegionState { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); - private const int DEBUG_CHANNEL = 2147483647; + private const int DEBUG_CHANNEL = 2147483647; - private static int _idk_ = 0; + private static int _idk_ = 0; // Runtime variables; these values are assigned when the // IrcState is created and remain constant thereafter. - internal string Region = String.Empty; - internal string Host = String.Empty; - internal string LocX = String.Empty; - internal string LocY = String.Empty; - internal string IDK = String.Empty; + internal string Region = String.Empty; + internal string Host = String.Empty; + internal string LocX = String.Empty; + internal string LocY = String.Empty; + internal string IDK = String.Empty; // System values - used only be the IRC classes themselves - internal ChannelState cs = null; // associated IRC configuration - internal Scene scene = null; // associated scene - internal IConfig config = null; // configuration file reference - internal bool enabled = true; - + internal ChannelState cs = null; // associated IRC configuration + internal Scene scene = null; // associated scene + internal IConfig config = null; // configuration file reference + internal bool enabled = true; + + //AgentAlert + internal bool showAlert = false; + internal string alertMessage = String.Empty; + internal IDialogModule dialogModule = null; + // This list is used to keep track of who is here, and by // implication, who is not. - internal List clients = new List(); + internal List clients = new List(); // Setup runtime variable values public RegionState(Scene p_scene, IConfig p_config) { - - scene = p_scene; + scene = p_scene; config = p_config; Region = scene.RegionInfo.RegionName; - Host = scene.RegionInfo.ExternalHostName; - LocX = Convert.ToString(scene.RegionInfo.RegionLocX); - LocY = Convert.ToString(scene.RegionInfo.RegionLocY); - IDK = Convert.ToString(_idk_++); + Host = scene.RegionInfo.ExternalHostName; + LocX = Convert.ToString(scene.RegionInfo.RegionLocX); + LocY = Convert.ToString(scene.RegionInfo.RegionLocY); + IDK = Convert.ToString(_idk_++); + + showAlert = config.GetBoolean("alert_show", false); + string alertServerInfo = String.Empty; + + if (showAlert) + { + bool showAlertServerInfo = config.GetBoolean("alert_show_serverinfo", true); + + if (showAlertServerInfo) + alertServerInfo = String.Format("\nServer: {0}\nPort: {1}\nChannel: {2}\n\n", + config.GetString("server", ""), config.GetString("port", ""), config.GetString("channel", "")); + + string alertPreMessage = config.GetString("alert_msg_pre", "This region is linked to Irc."); + string alertPostMessage = config.GetString("alert_msg_post", "Everything you say in public chat can be listened."); + + alertMessage = String.Format("{0}\n{1}{2}", alertPreMessage, alertServerInfo, alertPostMessage); + + dialogModule = scene.RequestModuleInterface(); + } // OpenChannel conditionally establishes a connection to the // IRC server. The request will either succeed, or it will @@ -93,9 +115,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Connect channel to world events - scene.EventManager.OnChatFromWorld += OnSimChat; + scene.EventManager.OnChatFromWorld += OnSimChat; scene.EventManager.OnChatFromClient += OnSimChat; - scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; m_log.InfoFormat("[IRC-Region {0}] Initialization complete", Region); @@ -106,8 +128,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat ~RegionState() { - if (cs != null) - cs.RemoveRegion(this); + if (cs != null) + cs.RemoveRegion(this); } // Called by PostInitialize after all regions have been created @@ -138,7 +160,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { if (clients.Contains(client)) { - if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) + if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) { m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name); //Check if this person is excluded from IRC @@ -147,7 +169,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); } } - client.OnLogout -= OnClientLoggedOut; + client.OnLogout -= OnClientLoggedOut; client.OnConnectionClosed -= OnClientLoggedOut; clients.Remove(client); } @@ -171,13 +193,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { if (clients.Contains(client)) { - if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) + if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) { string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); m_log.DebugFormat("[IRC-Region {0}] {1} has left", Region, clientName); cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", clientName)); } - client.OnLogout -= OnClientLoggedOut; + client.OnLogout -= OnClientLoggedOut; client.OnConnectionClosed -= OnClientLoggedOut; clients.Remove(client); } @@ -195,14 +217,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private void OnMakeRootAgent(ScenePresence presence) { - IClientAPI client = presence.ControllingClient; try { if (!clients.Contains(client)) { - client.OnLogout += OnClientLoggedOut; + client.OnLogout += OnClientLoggedOut; client.OnConnectionClosed += OnClientLoggedOut; clients.Add(client); if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) @@ -216,17 +237,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } } } + + if (dialogModule != null && showAlert) + dialogModule.SendAlertToUser(client, alertMessage, true); } catch (Exception ex) { m_log.ErrorFormat("[IRC-Region {0}]: MakeRootAgent exception: {1}", Region, ex.Message); m_log.Debug(ex); } - } // This handler detects chat events int he virtual world. - public void OnSimChat(Object sender, OSChatMessage msg) { @@ -317,14 +339,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // that evident. default: - m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", + m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", Region, msg.Message); cs.irc.Send(msg.Message); break; } } catch (Exception ex) - { + { m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}", Region, ex.Message); m_log.Debug(ex); @@ -366,7 +388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); - if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) + if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) { string txt = msg.Message; if (txt.StartsWith("/me ")) @@ -376,13 +398,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat return; } - if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && + if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && msg.Channel == cs.RelayChannelOut) { Match m = cs.AccessPasswordRegex.Match(msg.Message); if (null != m) { - m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), + m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), m.Groups["message"].ToString()); cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(), scene.RegionInfo.RegionName, m.Groups["message"].ToString()); -- cgit v1.1 From 9de670c550fd6847c2c14413d2c956f446b958f0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Feb 2013 23:08:50 +0000 Subject: minor: Change summary in "show appearance" console command to "incomplete" rather than "corrupt" Corrupt is misleading - it implies textures were uploaded but are not j2k valid. The actual situation is that at least one required baked texture is not present. --- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index d718a2f..fa35f0f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); MainConsole.Instance.OutputFormat( - "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); + "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete"); } ); } -- cgit v1.1 From 80c19b7cac52a57fd04966169c657400aeee3de8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Feb 2013 00:21:02 +0000 Subject: Make sure we dispose of WebResponse, StreamReader and Stream in various places where we were not already. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 21 ++++++---- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 12 +++--- .../XmlRpcGroupsServicesConnectorModule.cs | 46 +++++++++++++--------- 3 files changed, 47 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 37ab35a..ef1b92e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -551,13 +551,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice reqStream.Close(); } - HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse(); - Encoding encoding = Util.UTF8; - StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding); - fwdresponsestr = fwdresponsestream.ReadToEnd(); - fwdresponsecontenttype = fwdrsp.ContentType; - fwdresponsecode = (int)fwdrsp.StatusCode; - fwdresponsestream.Close(); + using (HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse()) + { + Encoding encoding = Util.UTF8; + + using (Stream s = fwdrsp.GetResponseStream()) + { + using (StreamReader fwdresponsestream = new StreamReader(s)) + { + fwdresponsestr = fwdresponsestream.ReadToEnd(); + fwdresponsecontenttype = fwdrsp.ContentType; + fwdresponsecode = (int)fwdrsp.StatusCode; + } + } + } response["content_type"] = fwdresponsecontenttype; response["str_response_string"] = fwdresponsestr; diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 881807a..cb69411 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -1116,18 +1116,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // Otherwise prepare the request m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); - HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); - HttpWebResponse rsp = null; + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); // We are sending just parameters, no content req.ContentLength = 0; // Send request and retrieve the response - rsp = (HttpWebResponse)req.GetResponse(); - - XmlTextReader rdr = new XmlTextReader(rsp.GetResponseStream()); - doc.Load(rdr); - rdr.Close(); + using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) + using (Stream s = rsp.GetResponseStream()) + using (XmlTextReader rdr = new XmlTextReader(s)) + doc.Load(rdr); } catch (Exception e) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 1101851..71b24ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1146,28 +1146,38 @@ namespace Nwc.XmlRpc request.AllowWriteStreamBuffering = true; request.KeepAlive = !_disableKeepAlive; - Stream stream = request.GetRequestStream(); - XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII); - _serializer.Serialize(xml, this); - xml.Flush(); - xml.Close(); - - HttpWebResponse response = (HttpWebResponse)request.GetResponse(); - StreamReader input = new StreamReader(response.GetResponseStream()); - - string inputXml = input.ReadToEnd(); - XmlRpcResponse resp; - try + using (Stream stream = request.GetRequestStream()) { - resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); + using (XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII)) + { + _serializer.Serialize(xml, this); + xml.Flush(); + } } - catch (Exception e) + + XmlRpcResponse resp; + + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { - RequestResponse = inputXml; - throw e; + using (Stream s = response.GetResponseStream()) + { + using (StreamReader input = new StreamReader(s)) + { + string inputXml = input.ReadToEnd(); + + try + { + resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); + } + catch (Exception e) + { + RequestResponse = inputXml; + throw e; + } + } + } } - input.Close(); - response.Close(); + return resp; } } -- cgit v1.1 From b0985f7019d7fc9ea6bb32c4f1d174e6f635c9e3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 2 Mar 2013 17:53:57 -0800 Subject: Fixed typos in TempAttachmentsModule. No changes. --- .../Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index d7fb272..1e7bc02 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments if (m_console != null) { - m_console.AddCommand("TempATtachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner os estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); + m_console.AddCommand("TempAttachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner or estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); } } else -- cgit v1.1 From fcecfc81bbd6ee8ebfa2dc0585d92ebf899358c1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Mar 2013 22:56:03 +0000 Subject: Multiattach, part 1 Conflicts: OpenSim/Framework/AvatarAppearance.cs OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs OpenSim/Region/Framework/Scenes/Scene.cs OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs --- .../Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 1e7bc02..e9ddbbe 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); } - return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true) ? 1 : 0; + return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true) ? 1 : 0; } } } -- cgit v1.1 From c0ff5635ba696d1701a6ce0356f247c69a7a52b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Mar 2013 02:00:56 +0000 Subject: Fix "show attachments" command probably broken in commit addab12 (Wed Jan 2 21:38:00 2013) This break was not connected with the recent attachment code changes. --- .../Avatar/Attachments/AttachmentsCommandModule.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index d97e3b3..0333747 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -176,16 +176,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", // attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, // (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); - ct.Rows.Add( - new ConsoleDisplayTableRow( - new List() - { - attachmentObject.Name, - attachmentObject.LocalId.ToString(), - attachmentObject.FromItemID.ToString(), - ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(), - attachmentObject.RootPart.AttachedPos.ToString() - })); + + ct.AddRow( + attachmentObject.Name, + attachmentObject.LocalId, + attachmentObject.FromItemID, + ((AttachmentPoint)attachmentObject.AttachmentPoint), + attachmentObject.RootPart.AttachedPos); // } } -- cgit v1.1 From 5f4c4df227025c6b6156ce8238b56553dca4b5ae Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 26 Mar 2013 03:40:06 +0000 Subject: Phase 1 of implementing a transfer permission. Overwrite libOMV's PermissionMask with our own and add export permissions as well as a new definition for "All" as meaning "all conventional permissions" rather than "all possible permissions" --- .../Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index e9ddbbe..54c86ae 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -40,6 +40,7 @@ using OpenSim.Framework.Monitoring; using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.OptionalModules.Avatar.Attachments { -- cgit v1.1 From c92654fb43f303da8e1623f9fff8a404aad72374 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 23:57:35 +0000 Subject: Stop attempts to update/add existing attachments in user inventory when teleporting between regions. This appears to resolve issues on teleport where attachments disappear or become labelled as invalid within user inventory. --- .../Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 54c86ae..535bf67 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -184,7 +184,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); } - return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true) ? 1 : 0; + return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true) ? 1 : 0; } } } -- cgit v1.1 From 115e0aaf830d31530680b38afd705380be3f284a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 23 Apr 2013 21:54:32 +0100 Subject: Fix issue in ConciergeModule where UpdateBroker was sending malformed XML if any number of avatars other than 1 was in the region. I don't know how well the rest of ConiergeModule works since I've practically never looked at this code. Addresses http://opensimulator.org/mantis/view.php?id=6605 --- OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index 018357a..c48e585 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -375,11 +375,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge scene.GetRootAgentCount(), scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, DateTime.UtcNow.ToString("s"))); + scene.ForEachRootScenePresence(delegate(ScenePresence sp) { - list.Append(String.Format(" \n", sp.Name, sp.UUID)); - list.Append(""); + list.Append(String.Format(" \n", sp.Name, sp.UUID)); }); + + list.Append(""); string payload = list.ToString(); // post via REST to broker -- cgit v1.1 From 533bbf033df88fd231eb0e7d2b0aa5a0058163ea Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 25 May 2013 02:08:54 +0100 Subject: Update the money framework to allow sending the new style linden "serverside is now viewerside" messages regarding currency This will require all money modules to be refactored! --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 29f9591..32fb54b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -764,7 +764,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); return UUID.Zero; } - money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); + money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate); } UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); -- cgit v1.1 From 7e1c7f54c719910145a88bfebf16435b9f142901 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 28 May 2013 20:59:25 -0700 Subject: First change in Vivox for ages! -- added a lock to serialize calls to vivox servers. This may ameliorate things when lots of avies arrive in a sim at about the same time. Turns out that there are 4 http requests per avie to Vivox. --- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 39 ++++++++++++++-------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index cb69411..db4869d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -117,6 +117,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice private IConfig m_config; + private object m_Lock; + public void Initialise(IConfigSource config) { @@ -128,6 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice if (!m_config.GetBoolean("enabled", false)) return; + m_Lock = new object(); + try { // retrieve configuration variables @@ -1111,25 +1115,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice doc = new XmlDocument(); - try + // Let's serialize all calls to Vivox. Most of these are driven by + // the clients (CAPs), when the user arrives at the region. We don't + // want to issue many simultaneous http requests to Vivox, because mono + // doesn't like that + lock (m_Lock) { - // Otherwise prepare the request - m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); + try + { + // Otherwise prepare the request + m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); - HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); - // We are sending just parameters, no content - req.ContentLength = 0; + // We are sending just parameters, no content + req.ContentLength = 0; - // Send request and retrieve the response - using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) + // Send request and retrieve the response + using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) using (Stream s = rsp.GetResponseStream()) - using (XmlTextReader rdr = new XmlTextReader(s)) - doc.Load(rdr); - } - catch (Exception e) - { - m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message); + using (XmlTextReader rdr = new XmlTextReader(s)) + doc.Load(rdr); + } + catch (Exception e) + { + m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message); + } } // If we're debugging server responses, dump the whole -- cgit v1.1 From 12a3b855619735b2e36a67ab99027029c8b57260 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 30 May 2013 22:20:02 +0100 Subject: Fix passing of voice distance attenuation to the Vivox voice server. Because of a typo, this wasn't being done at all - now the 'default' value as described in OpenSimDefaults.ini of 10m is passed (vivox_channel_clamping_distance) Thanks to Ai Austin for spotting this. --- .../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index db4869d..2d65530 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -836,7 +836,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff); requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel); requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange); - requrl = String.Format("{0}&chan_ckamping_distance={1}", requrl, m_vivoxChannelClampingDistance); + requrl = String.Format("{0}&chan_clamping_distance={1}", requrl, m_vivoxChannelClampingDistance); XmlElement resp = VivoxCall(requrl, true); if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri)) -- cgit v1.1 From 428916a64d27e5f00e74d34fd4b0453f32c3d2de Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 26 Jul 2013 21:14:21 -0700 Subject: Commented out ChatSessionRequest capability in Vivox and Freeswitch. We aren't processing it in any meaningful way, and it seems to get invoked everytime someone types a message in group chat. --- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 18 +++++++++--------- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index ef1b92e..5a5a70c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -326,15 +326,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice "ParcelVoiceInfoRequest", agentID.ToString())); - caps.RegisterHandler( - "ChatSessionRequest", - new RestStreamHandler( - "POST", - capsBase + m_chatSessionRequestPath, - (request, path, param, httpRequest, httpResponse) - => ChatSessionRequest(scene, request, path, param, agentID, caps), - "ChatSessionRequest", - agentID.ToString())); + //caps.RegisterHandler( + // "ChatSessionRequest", + // new RestStreamHandler( + // "POST", + // capsBase + m_chatSessionRequestPath, + // (request, path, param, httpRequest, httpResponse) + // => ChatSessionRequest(scene, request, path, param, agentID, caps), + // "ChatSessionRequest", + // agentID.ToString())); } /// diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 2d65530..cdab116 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -433,15 +433,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice "ParcelVoiceInfoRequest", agentID.ToString())); - caps.RegisterHandler( - "ChatSessionRequest", - new RestStreamHandler( - "POST", - capsBase + m_chatSessionRequestPath, - (request, path, param, httpRequest, httpResponse) - => ChatSessionRequest(scene, request, path, param, agentID, caps), - "ChatSessionRequest", - agentID.ToString())); + //caps.RegisterHandler( + // "ChatSessionRequest", + // new RestStreamHandler( + // "POST", + // capsBase + m_chatSessionRequestPath, + // (request, path, param, httpRequest, httpResponse) + // => ChatSessionRequest(scene, request, path, param, agentID, caps), + // "ChatSessionRequest", + // agentID.ToString())); } /// -- cgit v1.1 From 7b0b5c9d97dea840e1ede6e2318b3c049c804983 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 28 Jul 2013 13:49:58 -0700 Subject: Added BasicSearchModule.cs which handles OnDirFindQuery events. Removed that handler from both Groups modules in core, and replaced them with an operation on IGroupsModule. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 32fb54b..f4734b7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -250,7 +250,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; - client.OnDirFindQuery += OnDirFindQuery; client.OnRequestAvatarProperties += OnRequestAvatarProperties; // Used for Notices and Group Invites/Accept/Reject @@ -303,21 +302,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } */ - void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) - { - if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) - { - if (m_debugEnabled) - m_log.DebugFormat( - "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", - System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); - - // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray()); - } - - } - private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -1178,6 +1162,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } + public List FindGroups(IClientAPI remoteClient, string query) + { + return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query); + } + + #endregion #region Client/Update Tools -- cgit v1.1 From 377fe63c60b6632777da5f0a8a0c4c2d32a1f4ac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 12 Aug 2013 21:02:50 +0100 Subject: Don't try and send group updates to NPCs via event queue, since NPCs have no event queue. I think there is an argument for sending this information to NPCs anyway since in some cases it appears a lot easier to write server-side bots by hooking into such internal events. However, would need to stop event messages building up on NPC queues if they are never retrieved. --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index f4734b7..d744a14 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1212,7 +1212,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); AgentData.Add(AgentDataMap); - OSDArray GroupData = new OSDArray(data.Length); OSDArray NewGroupData = new OSDArray(data.Length); -- cgit v1.1 From e384ff604e081970ae9351431115a87e82345b18 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 20 Aug 2013 17:43:02 +0100 Subject: Add experimental "sit user name" and "stand user name" console commands in SitStandCommandsModule. "sit user name" will currently only sit the given avatar on prims which have a sit target set and are not already sat upon. Chiefly for debug purposes. --- .../Avatar/SitStand/SitStandCommandsModule.cs | 180 +++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs new file mode 100644 index 0000000..874723c --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs @@ -0,0 +1,180 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.OptionalModules.Avatar.SitStand +{ + /// + /// A module that just holds commands for changing avatar sitting and standing states. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")] + public class SitStandCommandModule : INonSharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + + public string Name { get { return "SitStand Command Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + m_scene = scene; + + scene.AddCommand( + "Users", this, "sit user name", + "sit user name ", + "Sit the named user on an unoccupied object with a sit target.\n" + + "If there are no such objects then nothing happens", + HandleSitUserNameCommand); + + scene.AddCommand( + "Users", this, "stand user name", + "stand user name ", + "Stand the named user.", + HandleStandUserNameCommand); + } + + protected void HandleSitUserNameCommand(string module, string[] cmd) + { + if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) + return; + + if (cmd.Length != 5) + { + MainConsole.Instance.Output("Usage: sit user name "); + return; + } + + string firstName = cmd[3]; + string lastName = cmd[4]; + + ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); + + if (sp == null || sp.IsChildAgent) + return; + + SceneObjectPart sitPart = null; + List sceneObjects = m_scene.GetSceneObjectGroups(); + + foreach (SceneObjectGroup sceneObject in sceneObjects) + { + foreach (SceneObjectPart part in sceneObject.Parts) + { + if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) + { + sitPart = part; + break; + } + } + } + + if (sitPart != null) + { + MainConsole.Instance.OutputFormat( + "Sitting {0} on {1} {2} in {3}", + sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name); + + sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero); + sp.HandleAgentSit(sp.ControllingClient, sp.UUID); + } + else + { + MainConsole.Instance.OutputFormat( + "Could not find any unoccupied set seat on which to sit {0} in {1}", + sp.Name, m_scene.Name); + } + } + + protected void HandleStandUserNameCommand(string module, string[] cmd) + { + if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) + return; + + if (cmd.Length != 5) + { + MainConsole.Instance.Output("Usage: stand user name "); + return; + } + + string firstName = cmd[3]; + string lastName = cmd[4]; + + ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); + + if (sp == null || sp.IsChildAgent) + return; + + sp.StandUp(); + } + } +} \ No newline at end of file -- cgit v1.1 From 43940f656210d5e572ef05bd223b3959513ee687 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 20 Aug 2013 18:13:40 +0100 Subject: Add --regex options to "sit user name" and "stand user name" console commands to sit/stand many avatars at once. Currently, first name and last name are input separate but are concatenated with a space in the middle to form a regex. So to sit all bots with the first name "ima", for instance, the command is "sit user name --regex ima .*" --- .../Avatar/SitStand/SitStandCommandsModule.cs | 131 +++++++++++++-------- 1 file changed, 81 insertions(+), 50 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs index 874723c..e9cb213 100644 --- a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs @@ -30,18 +30,16 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using log4net; using Mono.Addins; +using NDesk.Options; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; -using OpenSim.Framework.Monitoring; -using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Animation; -using OpenSim.Services.Interfaces; namespace OpenSim.Region.OptionalModules.Avatar.SitStand { @@ -92,89 +90,122 @@ namespace OpenSim.Region.OptionalModules.Avatar.SitStand scene.AddCommand( "Users", this, "sit user name", - "sit user name ", - "Sit the named user on an unoccupied object with a sit target.\n" - + "If there are no such objects then nothing happens", + "sit user name [--regex] ", + "Sit the named user on an unoccupied object with a sit target.", + "If there are no such objects then nothing happens.\n" + + "If --regex is specified then the names are treated as regular expressions.", HandleSitUserNameCommand); scene.AddCommand( "Users", this, "stand user name", - "stand user name ", + "stand user name [--regex] ", "Stand the named user.", + "If --regex is specified then the names are treated as regular expressions.", HandleStandUserNameCommand); } - protected void HandleSitUserNameCommand(string module, string[] cmd) + private void HandleSitUserNameCommand(string module, string[] cmd) { if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) return; - if (cmd.Length != 5) + if (cmd.Length < 5) { - MainConsole.Instance.Output("Usage: sit user name "); + MainConsole.Instance.Output("Usage: sit user name [--regex] "); return; } - string firstName = cmd[3]; - string lastName = cmd[4]; + List scenePresences = GetScenePresences(cmd); - ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); - - if (sp == null || sp.IsChildAgent) - return; - - SceneObjectPart sitPart = null; - List sceneObjects = m_scene.GetSceneObjectGroups(); - - foreach (SceneObjectGroup sceneObject in sceneObjects) + foreach (ScenePresence sp in scenePresences) { - foreach (SceneObjectPart part in sceneObject.Parts) + SceneObjectPart sitPart = null; + List sceneObjects = m_scene.GetSceneObjectGroups(); + + foreach (SceneObjectGroup sceneObject in sceneObjects) { - if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) + foreach (SceneObjectPart part in sceneObject.Parts) { - sitPart = part; - break; + if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) + { + sitPart = part; + break; + } } } - } - if (sitPart != null) - { - MainConsole.Instance.OutputFormat( - "Sitting {0} on {1} {2} in {3}", - sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name); + if (sitPart != null) + { + MainConsole.Instance.OutputFormat( + "Sitting {0} on {1} {2} in {3}", + sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name); - sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero); - sp.HandleAgentSit(sp.ControllingClient, sp.UUID); - } - else - { - MainConsole.Instance.OutputFormat( - "Could not find any unoccupied set seat on which to sit {0} in {1}", - sp.Name, m_scene.Name); + sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero); + sp.HandleAgentSit(sp.ControllingClient, sp.UUID); + } + else + { + MainConsole.Instance.OutputFormat( + "Could not find any unoccupied set seat on which to sit {0} in {1}. Aborting", + sp.Name, m_scene.Name); + + break; + } } } - protected void HandleStandUserNameCommand(string module, string[] cmd) + private void HandleStandUserNameCommand(string module, string[] cmd) { if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) return; - if (cmd.Length != 5) + if (cmd.Length < 5) { - MainConsole.Instance.Output("Usage: stand user name "); + MainConsole.Instance.Output("Usage: stand user name [--regex] "); return; } - string firstName = cmd[3]; - string lastName = cmd[4]; + List scenePresences = GetScenePresences(cmd); - ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); - - if (sp == null || sp.IsChildAgent) - return; + foreach (ScenePresence sp in scenePresences) + { + MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name); + sp.StandUp(); + } + } + + private List GetScenePresences(string[] cmdParams) + { + bool useRegex = false; + OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); + + List mainParams = options.Parse(cmdParams); + + string firstName = mainParams[3]; + string lastName = mainParams[4]; + + List scenePresencesMatched = new List(); + + if (useRegex) + { + Regex nameRegex = new Regex(string.Format("{0} {1}", firstName, lastName)); + List scenePresences = m_scene.GetScenePresences(); + + foreach (ScenePresence sp in scenePresences) + { + if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name)) + scenePresencesMatched.Add(sp); + } + } + else + { + ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); + + if (sp != null && !sp.IsChildAgent) + scenePresencesMatched.Add(sp); + } - sp.StandUp(); + return scenePresencesMatched; } } } \ No newline at end of file -- cgit v1.1 From 832c35d4d5288de0f976e40ede1c8f2ad7df4bcf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 Aug 2013 20:05:57 +0100 Subject: Stop "sit user name" and "stand user name" console commands from trying to sit/stand avatars already sitting/standing --- .../OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs index e9cb213..4a591cf 100644 --- a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs @@ -119,6 +119,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.SitStand foreach (ScenePresence sp in scenePresences) { + if (sp.SitGround || sp.IsSatOnObject) + continue; + SceneObjectPart sitPart = null; List sceneObjects = m_scene.GetSceneObjectGroups(); @@ -169,8 +172,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.SitStand foreach (ScenePresence sp in scenePresences) { - MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name); - sp.StandUp(); + if (sp.SitGround || sp.IsSatOnObject) + { + MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name); + sp.StandUp(); + } } } -- cgit v1.1 From beb9d966f9efb571b3d6635ba2500b6b0e685fc0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 Aug 2013 22:49:23 +0100 Subject: Stop "handle sit user name" command from trying to sit avatars on objects which have sit positions but are attachments --- .../Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs index 4a591cf..5a6b284 100644 --- a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs @@ -127,6 +127,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.SitStand foreach (SceneObjectGroup sceneObject in sceneObjects) { + if (sceneObject.IsAttachment) + continue; + foreach (SceneObjectPart part in sceneObject.Parts) { if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) -- cgit v1.1 From 5ca7395e175b476fd20fcf97383c8eb09b64ae3a Mon Sep 17 00:00:00 2001 From: Kevin Cozens Date: Fri, 2 Aug 2013 15:26:28 -0400 Subject: Added support for attachments to group notices when using Flotsam groups. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 172 +++++++++++++++------ 1 file changed, 122 insertions(+), 50 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d744a14..d09d3ad 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -39,6 +39,7 @@ using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using System.Text; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups @@ -421,44 +422,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string Subject = im.message.Substring(0, im.message.IndexOf('|')); string Message = im.message.Substring(Subject.Length + 1); + InventoryItemBase item = null; + bool hasAttachment = false; + UUID itemID = UUID.Zero; //Assignment to quiet compiler + UUID ownerID = UUID.Zero; //Assignment to quiet compiler byte[] bucket; - if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) - { - bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno - } - else + if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) { string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); binBucket = binBucket.Remove(0, 14).Trim(); - if (m_debugEnabled) + + OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + if (binBucketOSD is OSD) { - m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); + OSDMap binBucketMap = (OSDMap)binBucketOSD; + + itemID = binBucketMap["item_id"].AsUUID(); + ownerID = binBucketMap["owner_id"].AsUUID(); - OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); - - foreach (string key in binBucketOSD.Keys) + //Attempt to get the details of the attached item. + //If sender doesn't own the attachment, the item + //variable will be set to null and attachment will + //not be included with the group notice. + Scene scene = (Scene)remoteClient.Scene; + item = new InventoryItemBase(itemID, ownerID); + item = scene.InventoryService.GetItem(item); + + if (item != null) { - if (binBucketOSD.ContainsKey(key)) - { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); - } + //Got item details so include the attachment. + hasAttachment = true; } } - - // treat as if no attachment + else + { + m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); + } + } + + if (hasAttachment) + { + //Bucket contains information about attachment. + // + //Byte offset and description of bucket data: + //0: 1 byte indicating if attachment is present + //1: 1 byte indicating the type of attachment + //2: 16 bytes - Group UUID + //18: 16 bytes - UUID of the attachment owner + //34: 16 bytes - UUID of the attachment + //50: variable - Name of the attachment + //??: NUL byte to terminate the attachment name + byte[] name = Encoding.UTF8.GetBytes(item.Name); + bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name + bucket[0] = 1; //Has attachment flag + bucket[1] = (byte)item.InvType; //Type of Attachment + GroupID.ToBytes(bucket, 2); + ownerID.ToBytes(bucket, 18); + itemID.ToBytes(bucket, 34); + name.CopyTo(bucket, 50); + } + else + { bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno + bucket[0] = 0; //Has attachment flag + bucket[1] = 0; //Type of attachment GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno + bucket[18] = 0; //NUL terminate name of attachment } - m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { @@ -483,7 +515,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (member.AcceptNotices) { - // Build notice IIM + // Build notice IM GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); msg.toAgentID = member.AgentID.Guid; @@ -492,10 +524,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - + + if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) + { + //Is bucket large enough to hold UUID of the attachment? + if (im.binaryBucket.Length < 16) + return; + + UUID noticeID = new UUID(im.imSessionID); + + GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); + if (notice != null) + { + UUID giver = new UUID(notice.BinaryBucket, 18); + UUID attachmentUUID = new UUID(notice.BinaryBucket, 34); + + if (m_debugEnabled) + m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); + + InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, + giver, attachmentUUID); + + if (itemCopy == null) + { + remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); + return; + } + + remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); + } + } + // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the + // TODO:FIXME: Use a presence server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue if ((im.dialog == 210)) @@ -873,26 +935,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); - - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; - msg.message = data.noticeData.Subject + "|" + data.Message; - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = data.BinaryBucket; + GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); } - } public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) @@ -900,10 +946,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; + byte[] bucket; + + msg.imSessionID = groupNoticeID.Guid; msg.toAgentID = agentID.Guid; msg.dialog = dialog; - // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; msg.fromGroup = true; msg.offline = (byte)0; msg.ParentEstateID = 0; @@ -917,13 +964,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.timestamp = info.noticeData.Timestamp; msg.fromAgentName = info.noticeData.FromName; msg.message = info.noticeData.Subject + "|" + info.Message; - msg.binaryBucket = info.BinaryBucket; + + if (info.BinaryBucket[0] > 0) + { + //32 is due to not needing space for two of the UUIDs. + //(Don't need UUID of attachment or its owner in IM) + //50 offset gets us to start of attachment name. + //We are skipping the attachment flag, type, and + //the three UUID fields at the start of the bucket. + bucket = new byte[info.BinaryBucket.Length-32]; + bucket[0] = 1; //Has attachment + bucket[1] = info.BinaryBucket[1]; + Array.Copy(info.BinaryBucket, 50, + bucket, 18, info.BinaryBucket.Length-50); + } + else + { + bucket = new byte[19]; + bucket[0] = 0; //No attachment + bucket[1] = 0; //Attachment type + bucket[18] = 0; //NUL terminate name + } + + info.GroupID.ToBytes(bucket, 2); + msg.binaryBucket = bucket; } else { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); + msg.fromAgentID = UUID.Zero.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = string.Empty; msg.message = string.Empty; msg.binaryBucket = new byte[0]; @@ -1047,7 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Message to ejector // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the + // TODO:FIXME: Use a presence server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue -- cgit v1.1 From 7cab41f4223b7febd3fdd42fa7cfefef25e4a9c9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Nov 2013 21:45:08 +0000 Subject: refactor: replace verbose checks with String.IsNullOrEmpty where applicable. Thanks to Kira for this patch from http://opensimulator.org/mantis/view.php?id=6845 --- OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs | 2 +- .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 8 ++++---- .../Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs | 5 ++--- .../Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 5 ++--- 4 files changed, 9 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 5a37fad..b5d9fda 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -461,7 +461,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat string result = instr; - if (result == null || result.Length == 0) + if (string.IsNullOrEmpty(result)) return result; // Repeatedly scan the string until all possible diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index cdab116..b4fae9d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -822,11 +822,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice { string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", channelId, m_authToken); - if (parent != null && parent != String.Empty) + if (!string.IsNullOrEmpty(parent)) { requrl = String.Format("{0}&chan_parent={1}", requrl, parent); } - if (description != null && description != String.Empty) + if (!string.IsNullOrEmpty(description)) { requrl = String.Format("{0}&chan_desc={1}", requrl, description); } @@ -862,7 +862,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // requrl = String.Format("{0}&chan_parent={1}", requrl, parent); // } - if (description != null && description != String.Empty) + if (!string.IsNullOrEmpty(description)) { requrl = String.Format("{0}&chan_desc={1}", requrl, description); } @@ -1047,7 +1047,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice private XmlElement VivoxDeleteChannel(string parent, string channelid) { string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken); - if (parent != null && parent != String.Empty) + if (!string.IsNullOrEmpty(parent)) { requrl = String.Format("{0}&chan_parent={1}", requrl, parent); } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 7bae8f7..8095b28 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -212,8 +212,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); - if ((m_groupsServerURI == null) || - (m_groupsServerURI == string.Empty)) + if (string.IsNullOrEmpty(m_groupsServerURI)) { m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; @@ -438,7 +437,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return null; } } - else if ((groupName != null) && (groupName != string.Empty)) + else if (!string.IsNullOrEmpty(groupName)) { if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 71b24ac..e28d0c2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -168,8 +168,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); - if ((m_groupsServerURI == null) || - (m_groupsServerURI == string.Empty)) + if (string.IsNullOrEmpty(m_groupsServerURI)) { m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; @@ -354,7 +353,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { param["GroupID"] = GroupID.ToString(); } - if ((GroupName != null) && (GroupName != string.Empty)) + if (!string.IsNullOrEmpty(GroupName)) { param["Name"] = GroupName.ToString(); } -- cgit v1.1 From a5ca15c42893681a777d091c737d5c7615af4f48 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 18 Dec 2013 23:35:38 +0000 Subject: Create regression test TestSendAgentGroupDataUpdate() for groups agent data sending --- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 65 +++++++++++++++++++++- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index c1bdacb..26d2597 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -26,13 +26,23 @@ */ using System; +using System.Collections; +using System.Net; using System.Reflection; using Nini.Config; using NUnit.Framework; using OpenMetaverse; +using OpenMetaverse.Messages.Linden; +using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.ClientStack.Linden; +using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -44,11 +54,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests [TestFixture] public class GroupsModuleTests : OpenSimTestCase { + [SetUp] + public override void SetUp() + { + base.SetUp(); + + uint port = 9999; + uint sslPort = 9998; + + // This is an unfortunate bit of clean up we have to do because MainServer manages things through static + // variables and the VM is not restarted between tests. + MainServer.RemoveHttpServer(port); + + BaseHttpServer server = new BaseHttpServer(port, false, sslPort, ""); + MainServer.AddHttpServer(server); + MainServer.Instance = server; + } + [Test] - public void TestBasic() + public void TestSendAgentGroupDataUpdate() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); TestScene scene = new SceneHelpers().SetupScene(); IConfigSource configSource = new IniConfigSource(); @@ -56,8 +83,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests config.Set("Enabled", true); config.Set("Module", "GroupsModule"); config.Set("DebugEnabled", true); + + GroupsModule gm = new GroupsModule(); + EventQueueGetModule eqgm = new EventQueueGetModule(); + + // We need a capabilities module active so that adding the scene presence creates an event queue in the + // EventQueueGetModule SceneHelpers.SetupSceneModules( - scene, configSource, new object[] { new MockGroupsServicesConnector() }); + scene, configSource, gm, new MockGroupsServicesConnector(), new CapabilitiesModule(), eqgm); + + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseStem("1")); + + gm.SendAgentGroupDataUpdate(sp.ControllingClient); + + Hashtable eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID); + + Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); + +// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); + + OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]); + OSDArray eventsOsd = (OSDArray)rawOsd["events"]; + + bool foundUpdate = false; + foreach (OSD osd in eventsOsd) + { + OSDMap eventOsd = (OSDMap)osd; + + if (eventOsd["message"] == "AgentGroupDataUpdate") + foundUpdate = true; + } + + Assert.That(foundUpdate, Is.True, "Did not find AgentGroupDataUpdate in response"); + + // TODO: More checking of more actual event data. } } } \ No newline at end of file -- cgit v1.1 From 2d2bea4aa75ff6e82384f0842fe3719bf946b1cc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 26 Dec 2013 22:45:59 -0800 Subject: varregion: many more updates removing the constant RegionSize and replacing with a passed region size. This time in the map code and grid services code. --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 2 ++ OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs | 2 ++ 2 files changed, 4 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index c5cba8e..f5bd44d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -52,6 +52,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Local constants + // This computation is not the real region center if the region is larger than 256. + // This computation isn't fixed because there is not a handle back to the region. private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); private static readonly char[] CS_SPACE = { ' ' }; diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index d4fe5e0..5505001 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -44,6 +44,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + // This computation is not the real region center if the region is larger than 256. + // This computation isn't fixed because there is not a handle back to the region. private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); private const int DEBUG_CHANNEL = 2147483647; -- cgit v1.1 From 733e067958bb2ddbb016b97272473b3372563fc3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 14 Feb 2014 21:28:45 +0000 Subject: Log information about which function, request data and agent ID triggered an XmlRpcGroupsServiceConnector error --- .../XmlRpcGroupsServicesConnectorModule.cs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index e28d0c2..a040f43 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1012,7 +1012,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable respData = (Hashtable)resp.Value; if (respData.Contains("error") && !respData.Contains("succeed")) { - LogRespDataToConsoleError(respData); + LogRespDataToConsoleError(requestingAgentID, function, param, respData); } return respData; @@ -1040,20 +1040,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return error; } - private void LogRespDataToConsoleError(Hashtable respData) + private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData) { - m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); - - foreach (string key in respData.Keys) - { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key); - - string[] lines = respData[key].ToString().Split(new char[] { '\n' }); - foreach (string line in lines) - { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); - } - } + m_log.ErrorFormat( + "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}", + function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData)); } /// -- cgit v1.1 From 71918eeab4beee076d53469e8d19addab49135b7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 7 Mar 2014 01:04:40 +0000 Subject: Add regression test for sending group notices via xmlrpc groups connector. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 1 + .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 55 ++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d09d3ad..62020ee 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -497,6 +497,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OnNewGroupNotice(GroupID, NoticeID); } + /*** We would insert call code here ***/ // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index 26d2597..08a93b8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -27,6 +27,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Net; using System.Reflection; using Nini.Config; @@ -118,5 +119,59 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests // TODO: More checking of more actual event data. } + + [Test] + public void TestSendGroupNotice() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + TestScene scene = new SceneHelpers().SetupScene(); + IConfigSource configSource = new IniConfigSource(); + IConfig config = configSource.AddConfig("Groups"); + config.Set("Enabled", true); + config.Set("Module", "GroupsModule"); + config.Set("DebugEnabled", true); + + GroupsModule gm = new GroupsModule(); + + SceneHelpers.SetupSceneModules(scene, configSource, gm, new MockGroupsServicesConnector()); + + UUID userId = TestHelpers.ParseTail(0x1); + string subjectText = "newman"; + string messageText = "Hello"; + string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText); + + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); + TestClient tc = (TestClient)sp.ControllingClient; + + UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true); + gm.JoinGroupRequest(tc, groupID); + + // Create a second user who doesn't want to receive notices + ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2)); + TestClient tc2 = (TestClient)sp2.ControllingClient; + gm.JoinGroupRequest(tc2, groupID); + gm.SetGroupAcceptNotices(tc2, groupID, false, true); + + List spReceivedMessages = new List(); + tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im); + + List sp2ReceivedMessages = new List(); + tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im); + + GridInstantMessage noticeIm = new GridInstantMessage(); + noticeIm.fromAgentID = userId.Guid; + noticeIm.toAgentID = groupID.Guid; + noticeIm.message = combinedSubjectMessage; + noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice; + + tc.HandleImprovedInstantMessage(noticeIm); + + Assert.That(spReceivedMessages.Count, Is.EqualTo(1)); + Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage)); + + Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0)); + } } } \ No newline at end of file -- cgit v1.1 From 77e7bbcbf753018074211ca8358c642dd7204f42 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 11 Mar 2014 00:11:18 +0000 Subject: Send group notices through the same messaging module mechanism used to send group chat to avoid timeout issues when sending messages to large groups. Only implementing for XmlRpcGroups initially to test. May require MessageOnlineUsersOnly = true in [Groups] to be effective. In relation to http://opensimulator.org/mantis/view.php?id=7037 --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 156 ++++++++++++--------- .../Avatar/XmlRpcGroups/GroupsModule.cs | 60 +++++--- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 26 +++- 3 files changed, 151 insertions(+), 91 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 2802e2f..741a98f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -237,9 +237,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return false; } } + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { + SendMessageToGroup(im, groupID, null); + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID, Func sendCondition) + { List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); int groupMembersCount = groupMembers.Count; @@ -279,10 +285,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembersData member in groupMembers) { - if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) + if (sendCondition != null) + { + if (!sendCondition(member)) + { + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: Not sending to {0} as they do not fulfill send condition", + member.AgentID); + + continue; + } + } + else if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; } @@ -315,7 +336,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { // Deliver locally, directly if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); + ProcessMessageFromGroupSession(msg, client); } } @@ -348,7 +369,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Any other message type will not be delivered to a client by the // Instant Message Module - if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -362,11 +382,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) { - ProcessMessageFromGroupSession(msg); + IClientAPI client = null; + + if (msg.dialog == (byte)InstantMessageDialog.SessionSend) + { + client = GetActiveClient(new UUID(msg.toAgentID)); + + if (client != null) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); + } + else + { + m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); + + return; + } + } + + ProcessMessageFromGroupSession(msg, client); } } - private void ProcessMessageFromGroupSession(GridInstantMessage msg) + private void ProcessMessageFromGroupSession(GridInstantMessage msg, IClientAPI client) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); @@ -393,67 +432,58 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); - IClientAPI activeClient = GetActiveClient(toAgentID); - if (activeClient != null) + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + if (groupInfo != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); - if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); - - // Force? open the group session dialog??? - // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); - IEventQueue eq = activeClient.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( - GroupID - , groupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message - , new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp - , msg.offline == 1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , Utils.StringToBytes(groupInfo.GroupName) - ); - - eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - } + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); + + // Force? open the group session dialog??? + // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); + IEventQueue eq = client.Scene.RequestModuleInterface(); + eq.ChatterboxInvitation( + GroupID + , groupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message + , new UUID(msg.toAgentID) + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline == 1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(groupInfo.GroupName) + ); + + eq.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) + , new UUID(msg.fromAgentID) + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); } + + break; } else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. - IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); - if (client != null) - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); - client.SendInstantMessage(msg); - } - else - { - m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); - } + client.SendInstantMessage(msg); } + break; default: - m_log.WarnFormat("[GROUPS-MESSAGING]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); - break; + client.SendInstantMessage(msg); + + break;; } } @@ -549,13 +579,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent) { m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", (InstantMessageDialog)im.dialog); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID); m_log.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 62020ee..d4f70a7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -77,9 +77,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private List m_sceneList = new List(); - private IMessageTransferModule m_msgTransferModule = null; + private IMessageTransferModule m_msgTransferModule; + + private IGroupsMessagingModule m_groupsMessagingModule; - private IGroupsServicesConnector m_groupData = null; + private IGroupsServicesConnector m_groupData; // Configuration settings private bool m_groupsEnabled = false; @@ -185,10 +187,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_msgTransferModule == null) { m_groupsEnabled = false; - m_log.Warn("[GROUPS]: Could not get MessageTransferModule"); + m_log.Warn("[GROUPS]: Could not get IMessageTransferModule"); } } + if (m_groupsMessagingModule == null) + { + m_groupsMessagingModule = scene.RequestModuleInterface(); + + // No message transfer module, no notices, group invites, rejects, ejects, etc + if (m_groupsMessagingModule == null) + m_log.Warn("[GROUPS]: Could not get IGroupsMessagingModule"); + } + lock (m_sceneList) { m_sceneList.Add(scene); @@ -497,32 +508,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OnNewGroupNotice(GroupID, NoticeID); } - /*** We would insert call code here ***/ - // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) + if (m_debugEnabled) { - if (m_debugEnabled) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) { - UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); - if (targetUser != null) + if (m_debugEnabled) { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); - } - else - { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); + UserAccount targetUser + = m_sceneList[0].UserAccountService.GetUserAccount( + remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); + + if (targetUser != null) + { + m_log.DebugFormat( + "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", + NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); + } + else + { + m_log.DebugFormat( + "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", + NoticeID, member.AgentID, member.AcceptNotices); + } } } + } - if (member.AcceptNotices) - { - // Build notice IM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + GridInstantMessage msg + = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); - msg.toAgentID = member.AgentID.Guid; - OutgoingInstantMessage(msg, member.AgentID); - } - } + if (m_groupsMessagingModule != null) + m_groupsMessagingModule.SendMessageToGroup(msg, GroupID, gmd => gmd.AcceptNotices); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index 08a93b8..71f1098 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -41,6 +41,7 @@ using OpenSim.Framework.Communications; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.ClientStack.Linden; +using OpenSim.Region.CoreModules.Avatar.InstantMessage; using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; @@ -127,15 +128,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests // TestHelpers.EnableLogging(); TestScene scene = new SceneHelpers().SetupScene(); - IConfigSource configSource = new IniConfigSource(); - IConfig config = configSource.AddConfig("Groups"); - config.Set("Enabled", true); - config.Set("Module", "GroupsModule"); - config.Set("DebugEnabled", true); + MessageTransferModule mtm = new MessageTransferModule(); GroupsModule gm = new GroupsModule(); + GroupsMessagingModule gmm = new GroupsMessagingModule(); + + IConfigSource configSource = new IniConfigSource(); + + { + IConfig config = configSource.AddConfig("Messaging"); + config.Set("MessageTransferModule", mtm.Name); + } + + { + IConfig config = configSource.AddConfig("Groups"); + config.Set("Enabled", true); + config.Set("Module", gm.Name); + config.Set("DebugEnabled", true); + config.Set("MessagingModule", gmm.Name); + config.Set("MessagingEnabled", true); + } - SceneHelpers.SetupSceneModules(scene, configSource, gm, new MockGroupsServicesConnector()); + SceneHelpers.SetupSceneModules(scene, configSource, new MockGroupsServicesConnector(), mtm, gm, gmm); UUID userId = TestHelpers.ParseTail(0x1); string subjectText = "newman"; -- cgit v1.1 From beba20846f1935e2769f78fb0c87746cf77a6b50 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 12 Mar 2014 19:31:04 +0000 Subject: When sending group notices through group messaging, allow the agent ID to use for fetching group data to be different from im.fromAgentID This is because xmlrpcgroups currently always checks visibility for the requesting agent ID (unlike Groups v2, which can accept UUID.Zero) But group notice IMs have a from agent which is the group rather than the sending agent. Further addresses http://opensimulator.org/mantis/view.php?id=7037 --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 9 ++++----- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 3 ++- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 741a98f..fd804cd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -238,15 +238,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } - public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { - SendMessageToGroup(im, groupID, null); + SendMessageToGroup(im, groupID, new UUID(im.fromAgentID), null); } - public void SendMessageToGroup(GridInstantMessage im, UUID groupID, Func sendCondition) + public void SendMessageToGroup( + GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func sendCondition) { - List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); + List groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID); int groupMembersCount = groupMembers.Count; if (m_messageOnlineAgentsOnly) @@ -489,7 +489,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - #region ClientEvents private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d4f70a7..fc8cae2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -538,7 +538,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); if (m_groupsMessagingModule != null) - m_groupsMessagingModule.SendMessageToGroup(msg, GroupID, gmd => gmd.AcceptNotices); + m_groupsMessagingModule.SendMessageToGroup( + msg, GroupID, remoteClient.AgentId, gmd => gmd.AcceptNotices); } } -- cgit v1.1 From 998d7009a65def0a4debc9369d35b63611db5b55 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 22 Apr 2014 20:04:12 +0300 Subject: Eliminated many warnings --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 2 +- .../OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 5a5a70c..45af212 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -65,7 +65,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice // Capability string prefixes private static readonly string m_parcelVoiceInfoRequestPath = "0207/"; private static readonly string m_provisionVoiceAccountRequestPath = "0208/"; - private static readonly string m_chatSessionRequestPath = "0209/"; + //private static readonly string m_chatSessionRequestPath = "0209/"; // Control info private static bool m_Enabled = false; diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index b4fae9d..dd44564 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -92,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // Capability strings private static readonly string m_parcelVoiceInfoRequestPath = "0107/"; private static readonly string m_provisionVoiceAccountRequestPath = "0108/"; - private static readonly string m_chatSessionRequestPath = "0109/"; + //private static readonly string m_chatSessionRequestPath = "0109/"; // Control info, e.g. vivox server, admin user, admin password private static bool m_pluginEnabled = false; @@ -1325,4 +1325,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice return false; } } -} \ No newline at end of file +} -- cgit v1.1 From 1e5cff32fc41356971d6ad601cbee7ad62472c76 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 5 May 2014 11:06:49 +0300 Subject: Show more meaningful error messages when failed to give an item to another user --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index fc8cae2..f34152c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -560,12 +560,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); + string message; InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, - giver, attachmentUUID); + giver, attachmentUUID, out message); if (itemCopy == null) { - remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); + remoteClient.SendAgentAlertMessage(message, false); return; } -- cgit v1.1 From 19d8f05584f67d73539616235a5de2d9f4f56cd4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 12 May 2014 22:15:01 +0100 Subject: minor: eliminate unused UUID in xmlrpc GroupsMessagingModule.ProcessMessageFromGroupSession() --- .../Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index fd804cd..f8fcd65 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -431,8 +431,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Add them to the session for now, and Invite them m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - UUID toAgentID = new UUID(msg.toAgentID); - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) { -- cgit v1.1 From 515d373a8e5204410797d450def00e87f7c9cd74 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 12 May 2014 22:54:54 +0100 Subject: Add send group notice regression test for when MessageOnlineUsersOnly=true --- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index 71f1098..b5a10af 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -187,5 +187,76 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0)); } + + /// + /// Run test with the MessageOnlineUsersOnly flag set. + /// + [Test] + public void TestSendGroupNoticeOnlineOnly() + { + TestHelpers.InMethod(); + // TestHelpers.EnableLogging(); + + TestScene scene = new SceneHelpers().SetupScene(); + + MessageTransferModule mtm = new MessageTransferModule(); + GroupsModule gm = new GroupsModule(); + GroupsMessagingModule gmm = new GroupsMessagingModule(); + + IConfigSource configSource = new IniConfigSource(); + + { + IConfig config = configSource.AddConfig("Messaging"); + config.Set("MessageTransferModule", mtm.Name); + } + + { + IConfig config = configSource.AddConfig("Groups"); + config.Set("Enabled", true); + config.Set("Module", gm.Name); + config.Set("DebugEnabled", true); + config.Set("MessagingModule", gmm.Name); + config.Set("MessagingEnabled", true); + config.Set("MessageOnlineUsersOnly", true); + } + + SceneHelpers.SetupSceneModules(scene, configSource, new MockGroupsServicesConnector(), mtm, gm, gmm); + + UUID userId = TestHelpers.ParseTail(0x1); + string subjectText = "newman"; + string messageText = "Hello"; + string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText); + + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); + TestClient tc = (TestClient)sp.ControllingClient; + + UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true); + gm.JoinGroupRequest(tc, groupID); + + // Create a second user who doesn't want to receive notices + ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2)); + TestClient tc2 = (TestClient)sp2.ControllingClient; + gm.JoinGroupRequest(tc2, groupID); + gm.SetGroupAcceptNotices(tc2, groupID, false, true); + + List spReceivedMessages = new List(); + tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im); + + List sp2ReceivedMessages = new List(); + tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im); + + GridInstantMessage noticeIm = new GridInstantMessage(); + noticeIm.fromAgentID = userId.Guid; + noticeIm.toAgentID = groupID.Guid; + noticeIm.message = combinedSubjectMessage; + noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice; + + tc.HandleImprovedInstantMessage(noticeIm); + + Assert.That(spReceivedMessages.Count, Is.EqualTo(1)); + Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage)); + + Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0)); + } } } \ No newline at end of file -- cgit v1.1 From 87e2668529af4479e3dd94215193ff63ae685148 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 12 May 2014 23:30:44 +0100 Subject: For XmlRpcGroups (Flotsam) module, when MessageOnlineUsersOnly = true, handle notices to offline users directly as known undeliverable messages rather than discarding or attempting delivery. Offline notices can still be controlled with the [Messaging] ForwardOfflineGroupMessages setting. Looks to address more of http://opensimulator.org/mantis/view.php?id=7037 Only for Flotsam now for testing, but if approach works should be possible with core offline notices as well. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 39 ++++++++++++++-------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index f8fcd65..26b70a1 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -248,6 +248,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { List groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID); int groupMembersCount = groupMembers.Count; + HashSet attemptDeliveryUuidSet = null; if (m_messageOnlineAgentsOnly) { @@ -263,10 +264,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); } - HashSet onlineAgentsUuidSet = new HashSet(); - Array.ForEach(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); + attemptDeliveryUuidSet + = new HashSet(Array.ConvertAll(onlineAgents, pi => pi.UserID)); - groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); + //Array.ForEach(onlineAgents, pi => attemptDeliveryUuidSet.Add(pi.UserID)); + + //groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); // if (m_debugEnabled) // m_log.DebugFormat( @@ -275,6 +278,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } else { + attemptDeliveryUuidSet + = new HashSet(groupMembers.ConvertAll(gmd => gmd.AgentID.ToString())); + if (m_debugEnabled) m_log.DebugFormat( "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", @@ -325,26 +331,33 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.toAgentID = member.AgentID.Guid; - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) + if (attemptDeliveryUuidSet.Contains(member.AgentID.ToString())) { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg, client); + } } else { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg, client); + m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { }); } } // Temporary for assessing how long it still takes to send messages to large online groups. if (m_messageOnlineAgentsOnly) m_log.DebugFormat( - "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", - groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); + "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3}ms", + groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick); } #region SimGridEventHandlers -- cgit v1.1 From 3a6f3124841ee91778df1d7fa2fbda9893079c6d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 19 May 2014 22:06:41 +0100 Subject: Fix recent regression from 77e7bbc where an attachment on a received group notice with XmlRpcGroups messaging did not appear in the user's inventory. This was because the "session ID" when the message template was copied was always replaced with the group ID, whereas a notice requires this to be the notice ID. Instead just copy the "session ID" as is - other callers already have this set properly so replacing with group ID was redundant anyway. Relates to http://opensimulator.org/mantis/view.php?id=7037 --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 7 +++++-- .../OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 15 ++++++++++++++- .../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 9 ++++++++- 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 26b70a1..3724a2c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -315,7 +315,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Copy Message GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = groupID.Guid; + msg.imSessionID = im.imSessionID; msg.fromAgentName = im.fromAgentName; msg.message = im.message; msg.dialog = im.dialog; @@ -420,7 +420,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void ProcessMessageFromGroupSession(GridInstantMessage msg, IClientAPI client) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: Session message from {0} going to agent {1}, sessionID {2}, type {3}", + msg.fromAgentName, msg.toAgentID, msg.imSessionID, (InstantMessageDialog)msg.dialog); UUID AgentID = new UUID(msg.fromAgentID); UUID GroupID = new UUID(msg.imSessionID); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index f34152c..8a9e4d2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -357,7 +357,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called for {1}, message type {2}", + System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog); // Group invitations if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) @@ -551,6 +554,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups UUID noticeID = new UUID(im.imSessionID); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId); + GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); if (notice != null) { @@ -572,6 +578,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); } + else + { + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.", + noticeID, remoteClient.AgentId); + } } // Interop, received special 210 code for ejecting a group member diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index b5a10af..d944087 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -132,6 +132,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests MessageTransferModule mtm = new MessageTransferModule(); GroupsModule gm = new GroupsModule(); GroupsMessagingModule gmm = new GroupsMessagingModule(); + MockGroupsServicesConnector mgsc = new MockGroupsServicesConnector(); IConfigSource configSource = new IniConfigSource(); @@ -149,7 +150,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests config.Set("MessagingEnabled", true); } - SceneHelpers.SetupSceneModules(scene, configSource, new MockGroupsServicesConnector(), mtm, gm, gmm); + SceneHelpers.SetupSceneModules(scene, configSource, mgsc, mtm, gm, gmm); UUID userId = TestHelpers.ParseTail(0x1); string subjectText = "newman"; @@ -185,6 +186,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests Assert.That(spReceivedMessages.Count, Is.EqualTo(1)); Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage)); + List notices = mgsc.GetGroupNotices(UUID.Zero, groupID); + Assert.AreEqual(1, notices.Count); + + // OpenSimulator (possibly also SL) transport the notice ID as the session ID! + Assert.AreEqual(notices[0].NoticeID.Guid, spReceivedMessages[0].imSessionID); + Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0)); } -- cgit v1.1 From b46be88db62bcfa7dcf70c3677a1a1270d177a22 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 19 May 2014 22:45:17 +0100 Subject: Split verbose groups messaging logging into its own setting separate from that of the groups module. This is to allow us to get useful information on messaging without being overwhelmed by the rest of groups debug. Enabled with [Groups] DebugMessagingEnabled = true in config (default false) Or "debug groups messaging verbose true|false on the console" (similar to existing groups setting). Done for both xmlrpc and V2 groups. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 100 ++++++++++++++++----- 1 file changed, 77 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 3724a2c..09bbec2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -55,8 +55,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupsServicesConnector m_groupData = null; // Config Options - private bool m_groupMessagingEnabled = false; - private bool m_debugEnabled = true; + private bool m_groupMessagingEnabled; + private bool m_debugEnabled; /// /// If enabled, module only tries to send group IMs to online users by querying cached presence information. @@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_messageOnlineAgentsOnly) m_usersOnlineCache = new ExpiringCache(); - m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); + m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled); } m_log.InfoFormat( @@ -127,6 +127,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; scene.RegisterModuleInterface(this); + + scene.AddCommand( + "Debug", + this, + "debug groups messaging verbose", + "debug groups messaging verbose ", + "This setting turns on very verbose groups messaging debugging", + HandleDebugGroupsMessagingVerbose); } public void RegionLoaded(Scene scene) @@ -218,6 +226,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + private void HandleDebugGroupsMessagingVerbose(object modules, string[] args) + { + if (args.Length < 5) + { + MainConsole.Instance.Output("Usage: debug groups messaging verbose "); + return; + } + + bool verbose = false; + if (!bool.TryParse(args[4], out verbose)) + { + MainConsole.Instance.Output("Usage: debug groups messaging verbose "); + return; + } + + m_debugEnabled = verbose; + + MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled); + } + /// /// Not really needed, but does confirm that the group exists. /// @@ -336,27 +364,45 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IClientAPI client = GetActiveClient(member.AgentID); if (client == null) { + int startTick = Environment.TickCount; + // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: Delivering to {0} via grid took {1} ms", + member.AgentID, Environment.TickCount - startTick); } else { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + int startTick = Environment.TickCount; + ProcessMessageFromGroupSession(msg, client); + + // Deliver locally, directly + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: Delivering to {0} locally took {1} ms", + member.AgentID, Environment.TickCount - startTick); } } else { + int startTick = Environment.TickCount; + m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { }); + + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: Handling undeliverable message for {0} took {1} ms", + member.AgentID, Environment.TickCount - startTick); } } - // Temporary for assessing how long it still takes to send messages to large online groups. - if (m_messageOnlineAgentsOnly) + if (m_debugEnabled) m_log.DebugFormat( - "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3}ms", + "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms", groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick); } @@ -591,15 +637,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Don't log any normal IMs (privacy!) if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent) { - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", (InstantMessageDialog)im.dialog); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", (InstantMessageDialog)im.dialog); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID); + m_log.DebugFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); } } @@ -610,7 +656,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private IClientAPI GetActiveClient(UUID agentID) { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); IClientAPI child = null; @@ -622,12 +669,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (!sp.IsChildAgent) { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name); + return sp.ControllingClient; } else { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name); + child = sp.ControllingClient; } } @@ -636,12 +687,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // If we didn't find a root, then just return whichever child we found, or null if none if (child == null) { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); } else { - if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); } + return child; } -- cgit v1.1 From 5ec3429843ecb8058698f663556ae1d4cae53434 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 19 May 2014 23:01:48 +0100 Subject: On verbose groups messaging logging, count all operations in reported time when sending group messages, not just those after get group members and get presence status, as applicable --- .../OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 09bbec2..e1b6abb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -274,6 +274,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void SendMessageToGroup( GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func sendCondition) { + int requestStartTick = Environment.TickCount; + List groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID); int groupMembersCount = groupMembers.Count; HashSet attemptDeliveryUuidSet = null; @@ -313,9 +315,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.DebugFormat( "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", groupID, groupMembers.Count); - } - - int requestStartTick = Environment.TickCount; + } foreach (GroupMembersData member in groupMembers) { -- cgit v1.1 From 91e1aaa5d41c29fa17609c69ca8bc2a8017dc161 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Aug 2014 21:34:58 +0100 Subject: On teleport to a region that already has a child agent established (e.g. a neighbour) don't resend all the initial avatar and object data again. This is unnecessary since it has been received (and data continues to be received) in the existing child connection. --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8a9e4d2..dff3f78 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1381,7 +1381,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups presence.Grouptitle = Title; if (! presence.IsChildAgent) - presence.SendAvatarDataToAllAgents(); + presence.SendAvatarDataToAllClients(); } } } -- cgit v1.1 From 0692ebfbc6bfbbae428d79cb824622cea297fbaf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 4 Sep 2014 00:00:51 +0100 Subject: Start long-lived thread in IRCConnector via watchdog rather than indepedently, so that it can be seen in "show threads" and stats --- .../Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index f5bd44d..bdd07e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -109,10 +109,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal int m_resetk = 0; - // Working threads - - private Thread m_listener = null; - private Object msyncConnect = new Object(); internal bool m_randomizeNick = true; // add random suffix @@ -363,10 +359,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); - m_listener = new Thread(new ThreadStart(ListenerRun)); - m_listener.Name = "IRCConnectorListenerThread"; - m_listener.IsBackground = true; - m_listener.Start(); + Watchdog.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); // This is the message order recommended by RFC 2812 if (m_password != null) @@ -510,21 +503,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { while (m_enabled && m_connected) { - if ((inputLine = m_reader.ReadLine()) == null) throw new Exception("Listener input socket closed"); + Watchdog.UpdateThread(); + // m_log.Info("[IRCConnector]: " + inputLine); if (inputLine.Contains("PRIVMSG")) { - Dictionary data = ExtractMsg(inputLine); // Any chat ??? if (data != null) { - OSChatMessage c = new OSChatMessage(); c.Message = data["msg"]; c.Type = ChatTypeEnum.Region; @@ -540,9 +532,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat c.Message = String.Format("/me {0}", c.Message.Substring(8, c.Message.Length - 9)); ChannelState.OSChat(this, c, false); - } - } else { @@ -562,6 +552,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (m_enabled && (m_resetk == resetk)) Reconnect(); + + Watchdog.RemoveThread(); } private Regex RE = new Regex(@":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)", -- cgit v1.1 From fc878a33edcb403018e485ba0e8b7a6b3a8c3a16 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 8 Oct 2014 21:09:25 +0100 Subject: refactor: consistently put all test classes in the OpenSim.Tests.Common package rather than some in OpenSim.Tests.Common.Mock the separate mock package was not useful and was just another using line to always add --- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index d944087..e03e71d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -46,7 +46,6 @@ using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests { -- cgit v1.1 From 9b09dd357556b0a038c2f7f83e4cd7318555bd11 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 28 Oct 2014 17:29:04 +0000 Subject: Add "wearables show" console command. This shows summary wearables information (shape, hair, etc.) for all avatars in the scene or specific information about a given avatar's wearables. Similar to the existing "attachments show" command. --- .../Avatar/Appearance/AppearanceInfoModule.cs | 100 ++++++++++++++++++++- 1 file changed, 97 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index fa35f0f..51dfd47 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -102,7 +102,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance scene.AddCommand( "Users", this, "appearance show", "appearance show [ ]", - "Show appearance information for each avatar in the simulator.", + "Show appearance information for avatars.", "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." + "\nOptionally, you can view just a particular avatar's appearance information." @@ -132,6 +132,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance "Find out which avatar uses the given asset as a baked texture, if any.", "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", HandleFindAppearanceCommand); + + scene.AddCommand( + "Users", this, "wearables show", + "wearables show [ ]", + "Show information about wearables for avatars.", + "If no avatar name is given then a general summary for all avatars in the scene is shown.\n" + + "If an avatar name is given then specific information about current wearables is shown.", + HandleShowWearablesCommand); } private void HandleSendAppearanceCommand(string module, string[] cmd) @@ -186,7 +194,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance } } - protected void HandleShowAppearanceCommand(string module, string[] cmd) + private void HandleShowAppearanceCommand(string module, string[] cmd) { if (cmd.Length != 2 && cmd.Length < 4) { @@ -263,7 +271,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance } } - protected void HandleFindAppearanceCommand(string module, string[] cmd) + private void HandleFindAppearanceCommand(string module, string[] cmd) { if (cmd.Length != 3) { @@ -304,5 +312,91 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance string.Join(", ", matchedAvatars.ToList().ConvertAll(sp => sp.Name).ToArray())); } } + + protected void HandleShowWearablesCommand(string module, string[] cmd) + { + if (cmd.Length != 2 && cmd.Length < 4) + { + MainConsole.Instance.OutputFormat("Usage: wearables show [ ]"); + return; + } + + bool targetNameSupplied = false; + string optionalTargetFirstName = null; + string optionalTargetLastName = null; + + if (cmd.Length >= 4) + { + targetNameSupplied = true; + optionalTargetFirstName = cmd[2]; + optionalTargetLastName = cmd[3]; + } + + StringBuilder sb = new StringBuilder(); + + if (targetNameSupplied) + { + lock (m_scenes) + { + foreach (Scene scene in m_scenes.Values) + { + ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); + if (sp != null && !sp.IsChildAgent) + AppendWearablesDetailReport(sp, sb); + } + } + } + else + { + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Name", ConsoleDisplayUtil.UserNameSize); + cdt.AddColumn("Wearables", 2); + + lock (m_scenes) + { + foreach (Scene scene in m_scenes.Values) + { + scene.ForEachRootScenePresence( + sp => + { + int count = 0; + + for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) + count += sp.Appearance.Wearables[i].Count; + + cdt.AddRow(sp.Name, count); + } + ); + } + } + + sb.Append(cdt.ToString()); + } + + MainConsole.Instance.Output(sb.ToString()); + } + + private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb) + { + sb.AppendFormat("\nWearables for {0}\n", sp.Name); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Type", 10); + cdt.AddColumn("Item UUID", ConsoleDisplayUtil.UuidSize); + cdt.AddColumn("Asset UUID", ConsoleDisplayUtil.UuidSize); + + for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) + { + AvatarWearable aw = sp.Appearance.Wearables[i]; + + for (int j = 0; j < aw.Count; j++) + { + WearableItem wi = aw[j]; + cdt.AddRow(Enum.GetName(typeof(WearableType), i), wi.ItemID, wi.AssetID); + } + } + + sb.Append(cdt.ToString()); + } } } \ No newline at end of file -- cgit v1.1 From 3a1ce2715a522dcb1971944af17ad10d2263c7ab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 28 Oct 2014 23:00:49 +0000 Subject: Add "wearables check" console command This checks that all the wearable assets and any assets for a given logged in avatar exist in the asset service --- .../Avatar/Appearance/AppearanceInfoModule.cs | 96 ++++++++++++++++++++-- 1 file changed, 87 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 51dfd47..f67f613 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -51,7 +51,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Dictionary m_scenes = new Dictionary(); + private List m_scenes = new List(); + // private IAvatarFactoryModule m_avatarFactory; public string Name { get { return "Appearance Information Module"; } } @@ -83,7 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); lock (m_scenes) - m_scenes.Remove(scene.RegionInfo.RegionID); + m_scenes.Remove(scene); } public void RegionLoaded(Scene scene) @@ -91,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); lock (m_scenes) - m_scenes[scene.RegionInfo.RegionID] = scene; + m_scenes.Add(scene); scene.AddCommand( "Users", this, "show appearance", @@ -140,6 +141,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance "If no avatar name is given then a general summary for all avatars in the scene is shown.\n" + "If an avatar name is given then specific information about current wearables is shown.", HandleShowWearablesCommand); + + scene.AddCommand( + "Users", this, "wearables check", + "wearables check ", + "Check that the wearables of a given avatar in the scene are valid.", + "This currently checks that the wearable assets themselves and any assets referenced by them exist.", + HandleCheckWearablesCommand); } private void HandleSendAppearanceCommand(string module, string[] cmd) @@ -163,7 +171,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance lock (m_scenes) { - foreach (Scene scene in m_scenes.Values) + foreach (Scene scene in m_scenes) { if (targetNameSupplied) { @@ -215,7 +223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance lock (m_scenes) { - foreach (Scene scene in m_scenes.Values) + foreach (Scene scene in m_scenes) { if (targetNameSupplied) { @@ -251,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance lock (m_scenes) { - foreach (Scene scene in m_scenes.Values) + foreach (Scene scene in m_scenes) { ScenePresence sp = scene.GetScenePresence(firstname, lastname); if (sp != null && !sp.IsChildAgent) @@ -285,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance lock (m_scenes) { - foreach (Scene scene in m_scenes.Values) + foreach (Scene scene in m_scenes) { scene.ForEachRootScenePresence( sp => @@ -338,7 +346,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { lock (m_scenes) { - foreach (Scene scene in m_scenes.Values) + foreach (Scene scene in m_scenes) { ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); if (sp != null && !sp.IsChildAgent) @@ -354,7 +362,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance lock (m_scenes) { - foreach (Scene scene in m_scenes.Values) + foreach (Scene scene in m_scenes) { scene.ForEachRootScenePresence( sp => @@ -376,6 +384,76 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance MainConsole.Instance.Output(sb.ToString()); } + private void HandleCheckWearablesCommand(string module, string[] cmd) + { + if (cmd.Length != 4) + { + MainConsole.Instance.OutputFormat("Usage: wearables check "); + return; + } + + string firstname = cmd[2]; + string lastname = cmd[3]; + + StringBuilder sb = new StringBuilder(); + UuidGatherer uuidGatherer = new UuidGatherer(m_scenes[0].AssetService); + + lock (m_scenes) + { + foreach (Scene scene in m_scenes) + { + ScenePresence sp = scene.GetScenePresence(firstname, lastname); + if (sp != null && !sp.IsChildAgent) + { + sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name); + + for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) + { + AvatarWearable aw = sp.Appearance.Wearables[i]; + + if (aw.Count > 0) + { + sb.Append(Enum.GetName(typeof(WearableType), i)); + sb.Append("\n"); + + for (int j = 0; j < aw.Count; j++) + { + WearableItem wi = aw[j]; + + ConsoleDisplayList cdl = new ConsoleDisplayList(); + cdl.Indent = 2; + cdl.AddRow("Item UUID", wi.ItemID); + cdl.AddRow("Assets", ""); + sb.Append(cdl.ToString()); + + Dictionary assetUuids = new Dictionary(); + uuidGatherer.GatherAssetUuids(wi.AssetID, assetUuids); + string[] assetStrings + = Array.ConvertAll(assetUuids.Keys.ToArray(), u => u.ToString()); + + bool[] existChecks = scene.AssetService.AssetsExist(assetStrings); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.Indent = 4; + cdt.AddColumn("Type", 10); + cdt.AddColumn("UUID", ConsoleDisplayUtil.UuidSize); + cdt.AddColumn("Found", 5); + + for (int k = 0; k < existChecks.Length; k++) + cdt.AddRow((AssetType)assetUuids[new UUID(assetStrings[k])], assetStrings[k], existChecks[k] ? "yes" : "no"); + + sb.Append(cdt.ToString()); + sb.Append("\n"); + } + } + } + } + } + } + + MainConsole.Instance.Output(sb.ToString()); + } + private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb) { sb.AppendFormat("\nWearables for {0}\n", sp.Name); -- cgit v1.1 From 86367d7219b3bd52f63045b2b17bcbde328844ed Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 25 Nov 2014 23:56:32 +0000 Subject: refactor: Move methods to start a monitored thread, start work in its own thread and run work in the jobengine from Watchdog to a WorkManager class. This is to achieve a clean separation of concerns - the watchdog is an inappropriate place for work management. Also adds a WorkManager.RunInThreadPool() class which feeds through to Util.FireAndForget. Also switches around the name and obj arguments to the new RunInThread() and RunJob() methods so that the callback obj comes after the callback as seen in the SDK and elsewhere --- OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index bdd07e0..6985371 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -359,7 +359,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); - Watchdog.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); + WorkManager.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); // This is the message order recommended by RFC 2812 if (m_password != null) -- cgit v1.1 From 08606ae409b400b6f9b83006ed04826eede8a9c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 8 Jan 2015 20:21:40 +0000 Subject: Make the IteratingUuidGatherer the only UuidGatherer. This UUID gatherer provides a superset of the previous gatherer's functionality as it also allows the caller to control gathering iterations for load purposes. --- .../OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/OptionalModules/Avatar') diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index f67f613..2f9bb1e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -426,10 +426,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance cdl.AddRow("Assets", ""); sb.Append(cdl.ToString()); - Dictionary assetUuids = new Dictionary(); - uuidGatherer.GatherAssetUuids(wi.AssetID, assetUuids); + uuidGatherer.AddForInspection(wi.AssetID); + uuidGatherer.GatherAll(); string[] assetStrings - = Array.ConvertAll(assetUuids.Keys.ToArray(), u => u.ToString()); + = Array.ConvertAll(uuidGatherer.GatheredUuids.Keys.ToArray(), u => u.ToString()); bool[] existChecks = scene.AssetService.AssetsExist(assetStrings); @@ -440,7 +440,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance cdt.AddColumn("Found", 5); for (int k = 0; k < existChecks.Length; k++) - cdt.AddRow((AssetType)assetUuids[new UUID(assetStrings[k])], assetStrings[k], existChecks[k] ? "yes" : "no"); + cdt.AddRow( + (AssetType)uuidGatherer.GatheredUuids[new UUID(assetStrings[k])], + assetStrings[k], existChecks[k] ? "yes" : "no"); sb.Append(cdt.ToString()); sb.Append("\n"); -- cgit v1.1