diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index 854a125a4c..f8ed18e2c6 100755 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -252,7 +252,7 @@ namespace OpenSim.Groups m_debugEnabled = verbose; - MainConsole.Instance.Output("{0} verbose logging set to {1}", null, Name, m_debugEnabled); + MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled); } /// @@ -599,13 +599,16 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message"); + UUID fromAgent = new UUID(msg.fromAgentID); // 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( + if (eq != null) + { + eq.ChatterboxInvitation( GroupID , groupInfo.GroupName - , new UUID(msg.fromAgentID) + , fromAgent , msg.message , AgentID , msg.fromAgentName @@ -620,15 +623,10 @@ namespace OpenSim.Groups , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName) ); - eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , AgentID - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - , true // Enter - ); + var update = new GroupChatListAgentUpdateData(AgentID); + var updates = new List { update }; + eq.ChatterBoxSessionAgentListUpdates(GroupID, new UUID(msg.toAgentID), updates); + } } } } @@ -663,15 +661,12 @@ namespace OpenSim.Groups ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - queue.ChatterBoxSessionAgentListUpdates( - GroupID - , AgentID - , new UUID(im.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - , true - ); + if (queue != null) + { + var update = new GroupChatListAgentUpdateData(AgentID); + var updates = new List { update }; + queue.ChatterBoxSessionAgentListUpdates(GroupID, remoteClient.AgentId, updates); + } } } @@ -713,11 +708,7 @@ namespace OpenSim.Groups bodyMap.Add("session_info", sessionMap); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); - - if (queue != null) - { - queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); - } + queue?.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); } private void DebugGridInstantMessage(GridInstantMessage im) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetHandlers.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetHandlers.cs new file mode 100644 index 0000000000..bc75b27f87 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetHandlers.cs @@ -0,0 +1,455 @@ +/* + * 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.Net; +using System.Reflection; +using System.Text; +using log4net; +using Nini.Config; +using Mono.Addins; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps=OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.ClientStack.Linden +{ + public partial class EventQueueGetModule : IEventQueue, INonSharedRegionModule + { + /* this is not a event message + public void DisableSimulator(ulong handle, UUID avatarID) + { + OSD item = EventQueueHelper.DisableSimulator(handle); + Enqueue(item, avatarID); + } + */ + + public StringBuilder StartEvent(string eventName) + { + StringBuilder sb = new StringBuilder(256); + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("message", eventName, sb); + LLSDxmlEncode.AddMap("body", sb); + + return sb; + } + + public StringBuilder StartEvent(string eventName, int cap) + { + StringBuilder sb = new StringBuilder(cap); + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("message", eventName, sb); + LLSDxmlEncode.AddMap("body", sb); + + return sb; + } + + public string EndEvent(StringBuilder sb) + { + LLSDxmlEncode.AddEndMap(sb); // close body + LLSDxmlEncode.AddEndMap(sb); // close event + return sb.ToString(); + } + + public byte[] EndEventToBytes(StringBuilder sb) + { + LLSDxmlEncode.AddEndMap(sb); // close body + LLSDxmlEncode.AddEndMap(sb); // close event + return Util.UTF8NBGetbytes(sb.ToString()); + } + + public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) + { + if (DebugLevel > 0) + m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}", + LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY); + + StringBuilder sb = StartEvent("EnableSimulator"); + LLSDxmlEncode.AddArrayAndMap("SimulatorInfo", sb); + LLSDxmlEncode.AddElem("Handle", handle, sb); + LLSDxmlEncode.AddElem("IP", endPoint.Address.GetAddressBytes(), sb); + LLSDxmlEncode.AddElem("Port", endPoint.Port, sb); + LLSDxmlEncode.AddElem("RegionSizeX", (uint)regionSizeX, sb); + LLSDxmlEncode.AddElem("RegionSizeY", (uint)regionSizeY, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + Enqueue(EndEventToBytes(sb), avatarID); + } + + public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, + ulong regionHandle, int regionSizeX, int regionSizeY) + { + if (DebugLevel > 0) + m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}", + LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY); + + StringBuilder sb = StartEvent("EstablishAgentCommunication"); + + LLSDxmlEncode.AddElem("agent-id", avatarID, sb); + LLSDxmlEncode.AddElem("sim-ip-and-port", endPoint.ToString(), sb); + LLSDxmlEncode.AddElem("seed-capability", capsPath, sb); + // current viewers ignore this, also not needed its sent on enablesim + //LLSDxmlEncode.AddElem("region-handle", regionHandle, sb); + //LLSDxmlEncode.AddElem("region-size-x", (uint)regionSizeX, sb); + //LLSDxmlEncode.AddElem("region-size-y", (uint)regionSizeY, sb); + + Enqueue(EndEventToBytes(sb), avatarID); + } + + public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess, + IPEndPoint regionExternalEndPoint, + uint locationID, uint flags, string capsURL, + UUID avatarID, int regionSizeX, int regionSizeY) + { + if (DebugLevel > 0) + m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}", + LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY); + + // not sure why flags get overwritten here + if ((flags & (uint)TeleportFlags.IsFlying) != 0) + flags = (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.IsFlying; + else + flags = (uint)TeleportFlags.ViaLocation; + + StringBuilder sb = StartEvent("TeleportFinish"); + + LLSDxmlEncode.AddArrayAndMap("Info", sb); + LLSDxmlEncode.AddElem("AgentID", avatarID, sb); + LLSDxmlEncode.AddElem("LocationID", (uint)4, sb); // TODO what is this? + LLSDxmlEncode.AddElem("SimIP", regionExternalEndPoint.Address.GetAddressBytes(), sb); + LLSDxmlEncode.AddElem("SimPort", regionExternalEndPoint.Port, sb); + LLSDxmlEncode.AddElem("RegionHandle", regionHandle, sb); + LLSDxmlEncode.AddElem("SeedCapability", capsURL, sb); + LLSDxmlEncode.AddElem("SimAccess",(int)simAccess, sb); + LLSDxmlEncode.AddElem("TeleportFlags", flags, sb); + LLSDxmlEncode.AddElem("RegionSizeX", (uint)regionSizeX, sb); + LLSDxmlEncode.AddElem("RegionSizeY", (uint)regionSizeY, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + Enqueue(EndEventToBytes(sb), avatarID); + } + + public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, + IPEndPoint newRegionExternalEndPoint, + string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY) + { + if (DebugLevel > 0) + m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>", + LogHeader, handle, avatarID, regionSizeX, regionSizeY); + + StringBuilder sb = StartEvent("CrossedRegion"); + + LLSDxmlEncode.AddArrayAndMap("AgentData", sb); + LLSDxmlEncode.AddElem("AgentID", avatarID, sb); + LLSDxmlEncode.AddElem("SessionID", sessionID, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + LLSDxmlEncode.AddArrayAndMap("Info", sb); + LLSDxmlEncode.AddElem("LookAt", lookAt, sb); + LLSDxmlEncode.AddElem("Position", pos, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + LLSDxmlEncode.AddArrayAndMap("RegionData", sb); + LLSDxmlEncode.AddElem("RegionHandle", handle, sb); + LLSDxmlEncode.AddElem("SeedCapability", capsURL, sb); + LLSDxmlEncode.AddElem("SimIP", newRegionExternalEndPoint.Address.GetAddressBytes(), sb); + LLSDxmlEncode.AddElem("SimPort", newRegionExternalEndPoint.Port, sb); + LLSDxmlEncode.AddElem("RegionSizeX", (uint)regionSizeX, sb); + LLSDxmlEncode.AddElem("RegionSizeY", (uint)regionSizeY, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + Enqueue(EndEventToBytes(sb), avatarID); + } + + private static string InstantMessageBody(UUID fromAgent, string message, UUID toAgent, + string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID, + Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket, + bool checkEstate, int godLevel, bool limitedToEstate) + { + StringBuilder sb = new StringBuilder(512); + LLSDxmlEncode.AddMap("instantmessage", sb); + LLSDxmlEncode.AddMap("message_params", sb); //messageParams + LLSDxmlEncode.AddElem("type", dialog, sb); + LLSDxmlEncode.AddElem("position", position, sb); + LLSDxmlEncode.AddElem("region_id", UUID.Zero, sb); + LLSDxmlEncode.AddElem("to_id", toAgent, sb); + LLSDxmlEncode.AddElem("source", 0, sb); + + LLSDxmlEncode.AddMap("data", sb); //messageParams data + LLSDxmlEncode.AddElem("binary_bucket", binaryBucket, sb); + LLSDxmlEncode.AddEndMap(sb); //messageParams data + + LLSDxmlEncode.AddElem("message", message, sb); + LLSDxmlEncode.AddElem("id", transactionID, sb); + LLSDxmlEncode.AddElem("from_name", fromName, sb); + LLSDxmlEncode.AddElem("timestamp", timeStamp, sb); + LLSDxmlEncode.AddElem("offline", (offline ? 1 : 0), sb); + LLSDxmlEncode.AddElem("parent_estate_id", parentEstateID, sb); + LLSDxmlEncode.AddElem("ttl", (int)ttl, sb); + LLSDxmlEncode.AddElem("from_id", fromAgent, sb); + LLSDxmlEncode.AddElem("from_group", fromGroup, sb); + LLSDxmlEncode.AddEndMap(sb); //messageParams + + LLSDxmlEncode.AddMap("agent_params", sb); + LLSDxmlEncode.AddElem("agent_id", fromAgent, sb); + LLSDxmlEncode.AddElem("check_estate", checkEstate, sb); + LLSDxmlEncode.AddElem("god_level", godLevel, sb); + LLSDxmlEncode.AddElem("limited_to_estate", limitedToEstate, sb); + LLSDxmlEncode.AddEndMap(sb); // agent params + LLSDxmlEncode.AddEndMap(sb); + + return sb.ToString(); + } + + public void ChatterboxInvitation(UUID sessionID, string sessionName, + UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, + uint timeStamp, bool offline, int parentEstateID, Vector3 position, + uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket) + { + StringBuilder sb = StartEvent("ChatterBoxInvitation"); + LLSDxmlEncode.AddElem("session_id", sessionID, sb); + LLSDxmlEncode.AddElem("from_name", fromName, sb); + LLSDxmlEncode.AddElem("session_name", sessionName, sb); + LLSDxmlEncode.AddElem("from_id", fromAgent, sb); + + LLSDxmlEncode.AddLLSD(InstantMessageBody(fromAgent, message, toAgent, + fromName, dialog, timeStamp, offline, parentEstateID, position, + ttl, transactionID, fromGroup, binaryBucket, true, 0, true), sb); + + Enqueue(EndEventToBytes(sb), toAgent); + } + + public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID toAgent, List updates) + { + StringBuilder sb = StartEvent("ChatterBoxSessionAgentListUpdates",1024); + LLSDxmlEncode.AddMap("agent_updates",sb); + foreach (GroupChatListAgentUpdateData up in updates) + { + LLSDxmlEncode.AddMap(up.agentID.ToString(), sb); + LLSDxmlEncode.AddMap("info", sb); + LLSDxmlEncode.AddElem("can_voice_chat", up.canVoice, sb); + LLSDxmlEncode.AddElem("is_moderator", up.isModerator, sb); + LLSDxmlEncode.AddMap("mutes",sb); + LLSDxmlEncode.AddElem("text", up.mutedText, sb); + LLSDxmlEncode.AddEndMap(sb); // mutes + LLSDxmlEncode.AddEndMap(sb); // info + if (up.enterOrLeave) + LLSDxmlEncode.AddElem("transition", "ENTER", sb); + else + LLSDxmlEncode.AddElem("transition", "LEAVE", sb); + LLSDxmlEncode.AddEndMap(sb); //agentid + } + LLSDxmlEncode.AddEndMap(sb); // agent_updates + LLSDxmlEncode.AddEmptyMap("updates",sb); + LLSDxmlEncode.AddElem("session_id", sessionID, sb); + + Enqueue(EndEventToBytes(sb), toAgent); + } + + public void ChatterBoxSessionStartReply(UUID sessionID, string sessionName, int type, + bool voiceEnabled, bool voiceModerated, UUID tmpSessionID, + bool sucess, string error, + UUID toAgent) + { + StringBuilder sb = StartEvent("ChatterBoxSessionStartReply"); + LLSDxmlEncode.AddElem("session_id", sessionID, sb); + LLSDxmlEncode.AddElem("temp_session_id", tmpSessionID, sb); + LLSDxmlEncode.AddElem("success", sucess, sb); + if(sucess) + { + LLSDxmlEncode.AddMap("session_info", sb); + LLSDxmlEncode.AddMap("moderated_mode", sb); + LLSDxmlEncode.AddElem("voice", voiceModerated, sb); + LLSDxmlEncode.AddEndMap(sb); + LLSDxmlEncode.AddElem("session_name", sessionName, sb); + LLSDxmlEncode.AddElem("type", type, sb); + LLSDxmlEncode.AddElem("voice_enabled", voiceEnabled, sb); + LLSDxmlEncode.AddEndMap(sb); + } + else + LLSDxmlEncode.AddElem("error", String.IsNullOrEmpty(error) ? "" : error, sb); + + Enqueue(EndEventToBytes(sb), toAgent); + } + + public void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason) + { + StringBuilder sb = StartEvent("ForceCloseChatterBoxSession"); + LLSDxmlEncode.AddElem("session_id", sessionID, sb); + LLSDxmlEncode.AddElem("reason", reason, sb); + + Enqueue(EndEventToBytes(sb), toAgent); + } + + public void GroupMembershipData(UUID AgentID, GroupMembershipData[] data) + { + StringBuilder sb = StartEvent("AgentGroupDataUpdate"); + + LLSDxmlEncode.AddArrayAndMap("AgentData", sb); + LLSDxmlEncode.AddElem("AgentID", AgentID, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + if (data.Length == 0) + { + LLSDxmlEncode.AddEmptyArray("GroupData", sb); + LLSDxmlEncode.AddEmptyArray("NewGroupData", sb); + } + else + { + List lstInProfiles = new List(data.Length); + LLSDxmlEncode.AddArray("GroupData", sb); + foreach (GroupMembershipData m in data) + { + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("GroupID", m.GroupID, sb); + LLSDxmlEncode.AddElem("GroupPowers", m.GroupPowers, sb); + LLSDxmlEncode.AddElem("AcceptNotices", m.AcceptNotices, sb); + LLSDxmlEncode.AddElem("GroupInsigniaID", m.GroupPicture, sb); + LLSDxmlEncode.AddElem("Contribution", m.Contribution, sb); + LLSDxmlEncode.AddElem("GroupName", m.GroupName, sb); + LLSDxmlEncode.AddEndMap(sb); + lstInProfiles.Add(m.ListInProfile); + } + LLSDxmlEncode.AddEndArray(sb); + + LLSDxmlEncode.AddArray("NewGroupData", sb); + foreach(bool b in lstInProfiles) + { + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("ListInProfile", b, sb); + LLSDxmlEncode.AddEndMap(sb); + } + LLSDxmlEncode.AddEndArray(sb); + } + + Enqueue(EndEventToBytes(sb), AgentID); + } + + public void PlacesQueryReply(UUID avatarID, UUID queryID, UUID transactionID, PlacesReplyData[] replyDataArray) + { + StringBuilder sb = new StringBuilder(256); + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("message", "PlacesReplyMessage", sb); + LLSDxmlEncode.AddMap("QueryData[]", sb); LLSDxmlEncode.AddArray(sb); + LLSDxmlEncode.AddArray("AgentData", sb); + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("AgentID", avatarID, sb); + LLSDxmlEncode.AddElem("QueryID", queryID, sb); + LLSDxmlEncode.AddElem("TransactionID", transactionID, sb); + LLSDxmlEncode.AddEndMap(sb); + LLSDxmlEncode.AddEndArray(sb); + + LLSDxmlEncode.AddArray("QueryData", sb); + + for (int i = 0; i < replyDataArray.Length; ++i) + { + PlacesReplyData data = replyDataArray[i]; + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("ActualArea", data.ActualArea, sb); + LLSDxmlEncode.AddElem("BillableArea", data.BillableArea, sb); + LLSDxmlEncode.AddElem("Description", data.Desc, sb); + LLSDxmlEncode.AddElem("Dwell", data.Dwell, sb); + LLSDxmlEncode.AddElem("Flags", data.Flags, sb); + LLSDxmlEncode.AddElem("GlobalX", data.GlobalX, sb); + LLSDxmlEncode.AddElem("GlobalY", data.GlobalY, sb); + LLSDxmlEncode.AddElem("GlobalZ", data.GlobalZ, sb); + LLSDxmlEncode.AddElem("Name", data.Name, sb); + LLSDxmlEncode.AddElem("OwnerID", data.OwnerID, sb); + LLSDxmlEncode.AddElem("SimName", data.SimName, sb); + LLSDxmlEncode.AddElem("SnapShotID", data.SnapshotID, sb); + LLSDxmlEncode.AddElem("ProductSku", (int)0, sb); + LLSDxmlEncode.AddElem("Price", data.Price, sb); + LLSDxmlEncode.AddEndMap(sb); + } + LLSDxmlEncode.AddEndArray(sb); + + Enqueue(EndEventToBytes(sb), avatarID); + } + + public void ScriptRunningEvent(UUID objectID, UUID itemID, bool running, UUID avatarID) + { + StringBuilder sb = StartEvent("ScriptRunningReply"); + LLSDxmlEncode.AddArrayAndMap("Script", sb); + LLSDxmlEncode.AddElem("ObjectID", objectID, sb); + LLSDxmlEncode.AddElem("ItemID", itemID, sb); + LLSDxmlEncode.AddElem("Running", running, sb); + LLSDxmlEncode.AddElem("Mono", true, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + Enqueue(EndEventToBytes(sb), avatarID); + } + + public void partPhysicsProperties(uint localID, byte physhapetype, + float density, float friction, float bounce, float gravmod, UUID avatarID) + { + StringBuilder sb = StartEvent("ObjectPhysicsProperties"); + LLSDxmlEncode.AddArrayAndMap("ObjectData", sb); + LLSDxmlEncode.AddElem("LocalID", (int)localID, sb); + LLSDxmlEncode.AddElem("Density", density, sb); + LLSDxmlEncode.AddElem("Friction", friction, sb); + LLSDxmlEncode.AddElem("GravityMultiplier", gravmod, sb); + LLSDxmlEncode.AddElem("Restitution", bounce, sb); + LLSDxmlEncode.AddElem("PhysicsShapeType", (int)physhapetype, sb); + LLSDxmlEncode.AddEndMapAndArray(sb); + + Enqueue(EndEventToBytes(sb), avatarID); + } + + public void WindlightRefreshEvent(int interpolate, UUID avatarID) + { + StringBuilder sb = StartEvent("WindLightRefresh"); + LLSDxmlEncode.AddElem("Interpolate", interpolate > 0 ? 1 : 0, sb); + Enqueue(EndEventToBytes(sb), avatarID); + } + + public static string KeepAliveEvent() + { + StringBuilder sb = new StringBuilder(256); + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("message", "FAKEEVENT", sb); + LLSDxmlEncode.AddMap("body", sb); + LLSDxmlEncode.AddEndMap(sb); // close body + LLSDxmlEncode.AddEndMap(sb); // close event + return sb.ToString(); + } + + public byte[] BuildEvent(string eventName, OSD eventBody) + { + OSDMap llsdEvent = new OSDMap(2); + llsdEvent.Add("message", new OSDString(eventName)); + llsdEvent.Add("body", eventBody); + + return Util.UTF8NBGetbytes(OSDParser.SerializeLLSDInnerXmlString(llsdEvent)); + } + } +} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 260cd50e61..76eba90f7f 100755 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -35,12 +35,8 @@ using log4net; using Nini.Config; using Mono.Addins; using OpenMetaverse; -using OpenMetaverse.Messages.Linden; -using OpenMetaverse.Packets; using OpenMetaverse.StructuredData; using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -55,11 +51,15 @@ namespace OpenSim.Region.ClientStack.Linden } [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EventQueueGetModule")] - public class EventQueueGetModule : IEventQueue, INonSharedRegionModule + public partial class EventQueueGetModule : IEventQueue, INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static string LogHeader = "[EVENT QUEUE GET MODULE]"; + private const int KEEPALIVE = 60; // this could be larger now, but viewers expect it on opensim + // we need to go back to close before viwers, or we may lose data + private const int VIEWERKEEPALIVE = (KEEPALIVE - 1) * 1000; // do it shorter + /// /// Debug level. /// @@ -69,7 +69,7 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_ids = new Dictionary(); - private Dictionary> queues = new Dictionary>(); + private Dictionary> queues = new Dictionary>(); private Dictionary m_AvatarQueueUUIDMapping = new Dictionary(); #region INonSharedRegionModule methods @@ -149,22 +149,19 @@ namespace OpenSim.Region.ClientStack.Linden { DebugLevel = debugLevel; MainConsole.Instance.Output( - "Set event queue debug level to {0} in {1}", null, DebugLevel, m_scene.RegionInfo.RegionName); + "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName); } } protected void HandleShowEq(string module, string[] args) { - MainConsole.Instance.Output("For scene {0}", null, m_scene.Name); + MainConsole.Instance.Output("Events in Scene {0} agents queues :", m_scene.Name); lock (queues) { - foreach (KeyValuePair> kvp in queues) + foreach (KeyValuePair> kvp in queues) { - MainConsole.Instance.Output( - "For agent {0} there are {1} messages queued for send.", - null, - kvp.Key, kvp.Value.Count); + MainConsole.Instance.Output(" {0} {1}", kvp.Key, kvp.Value.Count); } } } @@ -174,21 +171,23 @@ namespace OpenSim.Region.ClientStack.Linden /// /// /// - private Queue TryGetQueue(UUID agentId) + private Queue TryGetQueue(UUID agentId) { lock (queues) { - if (!queues.ContainsKey(agentId)) - { - if (DebugLevel > 0) - m_log.DebugFormat( - "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", - agentId, m_scene.RegionInfo.RegionName); + Queue queue; + if (queues.TryGetValue(agentId, out queue)) + return queue; + + if (DebugLevel > 0) + m_log.DebugFormat( + "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", + agentId, m_scene.RegionInfo.RegionName); - queues[agentId] = new Queue(); - } + queue = new Queue(); + queues[agentId] = queue; - return queues[agentId]; + return queue; } } @@ -198,31 +197,58 @@ namespace OpenSim.Region.ClientStack.Linden /// /// /// - private Queue GetQueue(UUID agentId) + private Queue GetQueue(UUID agentId) { lock (queues) { - if (queues.ContainsKey(agentId)) - { - return queues[agentId]; - } - else - return null; + if (queues.TryGetValue(agentId, out Queue queue)) + return queue; + return null; } } #region IEventQueue Members - - public bool Enqueue(OSD ev, UUID avatarID) + //legacy + public bool Enqueue(OSD data, UUID avatarID) { //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName); try { - Queue queue = GetQueue(avatarID); + Queue queue = GetQueue(avatarID); if (queue != null) { + byte[] evData = Util.UTF8NBGetbytes(OSDParser.SerializeLLSDInnerXmlString(data)); lock (queue) - queue.Enqueue(ev); + queue.Enqueue(evData); + } + else + { + m_log.WarnFormat( + "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {1}", + avatarID, m_scene.Name); + } + } + catch (NullReferenceException e) + { + m_log.Error("[EVENTQUEUE] Caught exception: " + e); + return false; + } + return true; + } + + //legacy + /* + public bool Enqueue(string ev, UUID avatarID) + { + //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName); + try + { + Queue queue = GetQueue(avatarID); + if (queue != null) + { + byte[] evData = Util.UTF8NBGetbytes(ev); + lock (queue) + queue.Enqueue(evData); } else { @@ -236,7 +262,33 @@ namespace OpenSim.Region.ClientStack.Linden m_log.Error("[EVENTQUEUE] Caught exception: " + e); return false; } + return true; + } + */ + public bool Enqueue(byte[] evData, UUID avatarID) + { + //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName); + try + { + Queue queue = GetQueue(avatarID); + if (queue != null) + { + lock (queue) + queue.Enqueue(evData); + } + else + { + m_log.WarnFormat( + "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {1}", + avatarID, m_scene.Name); + } + } + catch (NullReferenceException e) + { + m_log.Error("[EVENTQUEUE] Caught exception: " + e); + return false; + } return true; } @@ -267,7 +319,7 @@ namespace OpenSim.Region.ClientStack.Linden /// private string GenerateEqgCapPath(UUID eqgUuid) { - return string.Format("/CAPS/EQG/{0}/", eqgUuid); + return string.Format("/CE/{0}/", eqgUuid); } public void OnRegisterCaps(UUID agentID, Caps caps) @@ -280,16 +332,15 @@ namespace OpenSim.Region.ClientStack.Linden agentID, caps, m_scene.RegionInfo.RegionName); UUID eventQueueGetUUID; - Queue queue = null; + Queue queue = null; lock (queues) { - if (queues.ContainsKey(agentID)) - queue = queues[agentID]; + queues.TryGetValue(agentID, out queue); if (queue == null) { - queue = new Queue(); + queue = new Queue(); queues[agentID] = queue; lock (m_AvatarQueueUUIDMapping) @@ -338,7 +389,6 @@ namespace OpenSim.Region.ClientStack.Linden { eventQueueGetUUID = UUID.Random(); m_AvatarQueueUUIDMapping[agentID] = eventQueueGetUUID; - m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); lock (m_ids) { if (m_ids.ContainsKey(agentID)) @@ -354,21 +404,22 @@ namespace OpenSim.Region.ClientStack.Linden } } - caps.RegisterPollHandler( - "EventQueueGet", - new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, int.MaxValue)); + caps.RegisterPollHandler( + "EventQueueGet", + new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, VIEWERKEEPALIVE)); } public bool HasEvents(UUID requestID, UUID agentID) { - Queue queue = GetQueue(agentID); + Queue queue = GetQueue(agentID); if (queue != null) + { lock (queue) { //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count); return queue.Count > 0; } - + } //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID); return true; } @@ -387,22 +438,32 @@ namespace OpenSim.Region.ClientStack.Linden ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name); } } + public void Drop(UUID requestID, UUID pAgentId) { // do nothing, in last case http server will do it } + private readonly byte[] EventHeader = GenEventHeader(); + + private static byte[] GenEventHeader() + { + return Encoding.UTF8.GetBytes("events"); + } + public Hashtable GetEvents(UUID requestID, UUID pAgentId) { if (DebugLevel >= 2) m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name); - Queue queue = GetQueue(pAgentId); + Queue queue = GetQueue(pAgentId); if (queue == null) - return NoEvents(requestID, pAgentId); + return NoAgent(requestID, pAgentId); - OSD element = null;; - OSDArray array = new OSDArray(); + byte[] element = null; + List elements; + + int totalSize = 0; int thisID = 0; bool negativeID = false; @@ -420,6 +481,9 @@ namespace OpenSim.Region.ClientStack.Linden thisID = -thisID; } + elements = new List(queue.Count + 2); + elements.Add(EventHeader); + while (queue.Count > 0) { element = queue.Dequeue(); @@ -430,7 +494,9 @@ namespace OpenSim.Region.ClientStack.Linden if (DebugLevel > 0) LogOutboundDebugMessage(element, pAgentId); - array.Add(element); + + elements.Add(element); + totalSize += element.Length; } } @@ -445,280 +511,56 @@ namespace OpenSim.Region.ClientStack.Linden m_ids[pAgentId] = thisID + 1; } - if (array.Count == 0) + if (totalSize == 0) return NoEvents(requestID, pAgentId); - OSDMap events = new OSDMap(); - events.Add("events", array); - events.Add("id", new OSDInteger(thisID)); + totalSize += EventHeader.Length; + + StringBuilder sb = new StringBuilder(); + LLSDxmlEncode.AddEndArray(sb); // events array + LLSDxmlEncode.AddElem("id", thisID, sb); + LLSDxmlEncode.AddEndMap(sb); + element = Encoding.UTF8.GetBytes(LLSDxmlEncode.End(sb)); + elements.Add(element); + totalSize += element.Length; Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 200; responsedata["content_type"] = "application/xml"; -//string tt = OSDParser.SerializeLLSDXmlString(events); - responsedata["bin_response_data"] = Encoding.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(events)); - responsedata["keepaliveTimeout"] = 60; - //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); + + //temporary + byte[] finalData = new byte[totalSize]; + int dst = 0; + foreach(byte[] src in elements) + { + Array.Copy(src, 0, finalData, dst, src.Length); + dst += src.Length; + } + + responsedata["bin_response_data"] = finalData; + responsedata["keepaliveTimeout"] = KEEPALIVE; + return responsedata; } public Hashtable NoEvents(UUID requestID, UUID agentID) { Hashtable responsedata = new Hashtable(); - responsedata["int_response_code"] = 502; - responsedata["content_type"] = "text/plain"; - responsedata["str_response_string"] = ""; - responsedata["error_status_text"] = ""; - responsedata["keepalive"] = false; + Queue queue = GetQueue(agentID); + if (queue == null) + { + responsedata["int_response_code"] = (int)HttpStatusCode.NotFound; + return responsedata; + } + responsedata["int_response_code"] = (int)HttpStatusCode.BadGateway; return responsedata; } -/* this is not a event message - public void DisableSimulator(ulong handle, UUID avatarID) + public Hashtable NoAgent(UUID requestID, UUID agentID) { - OSD item = EventQueueHelper.DisableSimulator(handle); - Enqueue(item, avatarID); - } -*/ - public StringBuilder StartEvent(string eventName) - { - StringBuilder sb = new StringBuilder(256); - LLSDxmlEncode.AddMap(sb); - LLSDxmlEncode.AddElem("message", eventName, sb); - LLSDxmlEncode.AddMap("body", sb); - - return sb; - } - - public string EndEvent(StringBuilder sb) - { - LLSDxmlEncode.AddEndMap(sb); // close body - LLSDxmlEncode.AddEndMap(sb); // close event - return sb.ToString(); - } - - public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) - { - if (DebugLevel > 0) - m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}", - LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY); - - StringBuilder sb = StartEvent("EnableSimulator"); - LLSDxmlEncode.AddArrayAndMap("SimulatorInfo", sb); - LLSDxmlEncode.AddElem("Handle", handle, sb); - LLSDxmlEncode.AddElem("IP", endPoint.Address.GetAddressBytes(), sb); - LLSDxmlEncode.AddElem("Port", endPoint.Port, sb); - LLSDxmlEncode.AddElem("RegionSizeX", (uint)regionSizeX, sb); - LLSDxmlEncode.AddElem("RegionSizeY", (uint)regionSizeY, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - OSD item = new OSDllsdxml(EndEvent(sb)); - - Enqueue(item, avatarID); - } - - public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, - ulong regionHandle, int regionSizeX, int regionSizeY) - { - if (DebugLevel > 0) - m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}", - LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY); - - StringBuilder sb = StartEvent("EstablishAgentCommunication"); - - LLSDxmlEncode.AddElem("agent-id", avatarID, sb); - LLSDxmlEncode.AddElem("sim-ip-and-port", endPoint.ToString(), sb); - LLSDxmlEncode.AddElem("seed-capability", capsPath, sb); - // current viewers ignore this, also not needed its sent on enablesim - //LLSDxmlEncode.AddElem("region-handle", regionHandle, sb); - //LLSDxmlEncode.AddElem("region-size-x", (uint)regionSizeX, sb); - //LLSDxmlEncode.AddElem("region-size-y", (uint)regionSizeY, sb); - - OSD ev = new OSDllsdxml(EndEvent(sb)); - Enqueue(ev, avatarID); - } - - public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess, - IPEndPoint regionExternalEndPoint, - uint locationID, uint flags, string capsURL, - UUID avatarID, int regionSizeX, int regionSizeY) - { - if (DebugLevel > 0) - m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}", - LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY); - - // not sure why flags get overwritten here - if ((flags & (uint)TeleportFlags.IsFlying) != 0) - flags = (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.IsFlying; - else - flags = (uint)TeleportFlags.ViaLocation; - - StringBuilder sb = StartEvent("TeleportFinish"); - - LLSDxmlEncode.AddArrayAndMap("Info", sb); - LLSDxmlEncode.AddElem("AgentID", avatarID, sb); - LLSDxmlEncode.AddElem("LocationID", (uint)4, sb); // TODO what is this? - LLSDxmlEncode.AddElem("SimIP", regionExternalEndPoint.Address.GetAddressBytes(), sb); - LLSDxmlEncode.AddElem("SimPort", regionExternalEndPoint.Port, sb); - LLSDxmlEncode.AddElem("RegionHandle", regionHandle, sb); - LLSDxmlEncode.AddElem("SeedCapability", capsURL, sb); - LLSDxmlEncode.AddElem("SimAccess",(int)simAccess, sb); - LLSDxmlEncode.AddElem("TeleportFlags", flags, sb); - LLSDxmlEncode.AddElem("RegionSizeX", (uint)regionSizeX, sb); - LLSDxmlEncode.AddElem("RegionSizeY", (uint)regionSizeY, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - OSD ev = new OSDllsdxml(EndEvent(sb)); - Enqueue(ev, avatarID); - } - - public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, - IPEndPoint newRegionExternalEndPoint, - string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY) - { - if (DebugLevel > 0) - m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>", - LogHeader, handle, avatarID, regionSizeX, regionSizeY); - - StringBuilder sb = StartEvent("CrossedRegion"); - - LLSDxmlEncode.AddArrayAndMap("AgentData", sb); - LLSDxmlEncode.AddElem("AgentID", avatarID, sb); - LLSDxmlEncode.AddElem("SessionID", sessionID, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - LLSDxmlEncode.AddArrayAndMap("Info", sb); - LLSDxmlEncode.AddElem("LookAt", lookAt, sb); - LLSDxmlEncode.AddElem("Position", pos, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - LLSDxmlEncode.AddArrayAndMap("RegionData", sb); - LLSDxmlEncode.AddElem("RegionHandle", handle, sb); - LLSDxmlEncode.AddElem("SeedCapability", capsURL, sb); - LLSDxmlEncode.AddElem("SimIP", newRegionExternalEndPoint.Address.GetAddressBytes(), sb); - LLSDxmlEncode.AddElem("SimPort", newRegionExternalEndPoint.Port, sb); - LLSDxmlEncode.AddElem("RegionSizeX", (uint)regionSizeX, sb); - LLSDxmlEncode.AddElem("RegionSizeY", (uint)regionSizeY, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - OSD ev = new OSDllsdxml(EndEvent(sb)); - Enqueue(ev, avatarID); - } - - public void ChatterboxInvitation(UUID sessionID, string sessionName, - UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, - uint timeStamp, bool offline, int parentEstateID, Vector3 position, - uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket) - { - OSD item = EventQueueHelper.ChatterboxInvitation(sessionID, sessionName, fromAgent, message, toAgent, fromName, dialog, - timeStamp, offline, parentEstateID, position, ttl, transactionID, - fromGroup, binaryBucket); - Enqueue(item, toAgent); - //m_log.InfoFormat("########### eq ChatterboxInvitation #############\n{0}", item); - - } - - public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, - bool isModerator, bool textMute, bool isEnterorLeave) - { - OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, - isModerator, textMute, isEnterorLeave); - Enqueue(item, toAgent); - //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); - } - - public void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason) - { - OSD item = EventQueueHelper.ChatterBoxForceClose(sessionID, reason); - - Enqueue(item, toAgent); - } - - public void GroupMembershipData(UUID AgentID, GroupMembershipData[] data) - { - StringBuilder sb = StartEvent("AgentGroupDataUpdate"); - - LLSDxmlEncode.AddArrayAndMap("AgentData", sb); - LLSDxmlEncode.AddElem("AgentID", AgentID, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - if (data.Length == 0) - { - LLSDxmlEncode.AddEmptyArray("GroupData", sb); - LLSDxmlEncode.AddEmptyArray("NewGroupData", sb); - } - else - { - List lstInProfiles = new List(data.Length); - LLSDxmlEncode.AddArray("GroupData", sb); - foreach (GroupMembershipData m in data) - { - LLSDxmlEncode.AddMap(sb); - LLSDxmlEncode.AddElem("GroupID", m.GroupID, sb); - LLSDxmlEncode.AddElem("GroupPowers", m.GroupPowers, sb); - LLSDxmlEncode.AddElem("AcceptNotices", m.AcceptNotices, sb); - LLSDxmlEncode.AddElem("GroupInsigniaID", m.GroupPicture, sb); - LLSDxmlEncode.AddElem("Contribution", m.Contribution, sb); - LLSDxmlEncode.AddElem("GroupName", m.GroupName, sb); - LLSDxmlEncode.AddEndMap(sb); - lstInProfiles.Add(m.ListInProfile); - } - LLSDxmlEncode.AddEndArray(sb); - - LLSDxmlEncode.AddArray("NewGroupData", sb); - foreach(bool b in lstInProfiles) - { - LLSDxmlEncode.AddMap(sb); - LLSDxmlEncode.AddElem("ListInProfile", b, sb); - LLSDxmlEncode.AddEndMap(sb); - } - LLSDxmlEncode.AddEndArray(sb); - } - - OSD ev = new OSDllsdxml(EndEvent(sb)); - Enqueue(ev, AgentID); - } - - public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID) - { - OSD item = EventQueueHelper.PlacesQuery(groupUpdate); - Enqueue(item, avatarID); - } - - public void ScriptRunningEvent(UUID objectID, UUID itemID, bool running, UUID avatarID) - { - StringBuilder sb = StartEvent("ScriptRunningReply"); - LLSDxmlEncode.AddArrayAndMap("Script", sb); - LLSDxmlEncode.AddElem("ObjectID", objectID, sb); - LLSDxmlEncode.AddElem("ItemID", itemID, sb); - LLSDxmlEncode.AddElem("Running", running, sb); - LLSDxmlEncode.AddElem("Mono", true, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - OSDllsdxml item = new OSDllsdxml(EndEvent(sb)); - Enqueue(item, avatarID); - } - - public void partPhysicsProperties(uint localID, byte physhapetype, - float density, float friction, float bounce, float gravmod,UUID avatarID) - { - StringBuilder sb = StartEvent("ObjectPhysicsProperties"); - LLSDxmlEncode.AddArrayAndMap("ObjectData", sb); - LLSDxmlEncode.AddElem("LocalID", (int)localID, sb); - LLSDxmlEncode.AddElem("Density", density, sb); - LLSDxmlEncode.AddElem("Friction", friction, sb); - LLSDxmlEncode.AddElem("GravityMultiplier", gravmod, sb); - LLSDxmlEncode.AddElem("Restitution", bounce, sb); - LLSDxmlEncode.AddElem("PhysicsShapeType", (int)physhapetype, sb); - LLSDxmlEncode.AddEndMapAndArray(sb); - - OSDllsdxml item = new OSDllsdxml(EndEvent(sb)); - Enqueue(item, avatarID); - } - - public OSD BuildEvent(string eventName, OSD eventBody) - { - return EventQueueHelper.BuildEvent(eventName, eventBody); + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = (int)HttpStatusCode.NotFound; + return responsedata; } } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index 206c0de1c8..c27828d44f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -41,232 +41,5 @@ namespace OpenSim.Region.ClientStack.Linden { private EventQueueHelper() {} // no construction possible, it's an utility class - public static StringBuilder StartEvent(string eventName) - { - StringBuilder sb = new StringBuilder(256); - LLSDxmlEncode.AddMap(sb); - LLSDxmlEncode.AddElem("message", eventName, sb); - LLSDxmlEncode.AddMap("body", sb); - - return sb; - } - - public static string EndEvent(StringBuilder sb) - { - LLSDxmlEncode.AddEndMap(sb); // close body - LLSDxmlEncode.AddEndMap(sb); // close event - return sb.ToString(); - } - - public static OSD BuildEvent(string eventName, OSD eventBody) - { - OSDMap llsdEvent = new OSDMap(2); - llsdEvent.Add("message", new OSDString(eventName)); - llsdEvent.Add("body", eventBody); - - return llsdEvent; - } - - public static OSD KeepAliveEvent() - { - return BuildEvent("FAKEEVENT", new OSDMap()); - } - - public static OSD AgentParams(UUID agentID, bool checkEstate, int godLevel, bool limitedToEstate) - { - OSDMap body = new OSDMap(4); - - body.Add("agent_id", new OSDUUID(agentID)); - body.Add("check_estate", new OSDInteger(checkEstate ? 1 : 0)); - body.Add("god_level", new OSDInteger(godLevel)); - body.Add("limited_to_estate", new OSDInteger(limitedToEstate ? 1 : 0)); - - return body; - } - - public static OSD InstantMessageParams(UUID fromAgent, string message, UUID toAgent, - string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID, - Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket) - { - OSDMap messageParams = new OSDMap(15); - messageParams.Add("type", new OSDInteger((int)dialog)); - - OSDArray positionArray = new OSDArray(3); - positionArray.Add(OSD.FromReal(position.X)); - positionArray.Add(OSD.FromReal(position.Y)); - positionArray.Add(OSD.FromReal(position.Z)); - messageParams.Add("position", positionArray); - - messageParams.Add("region_id", new OSDUUID(UUID.Zero)); - messageParams.Add("to_id", new OSDUUID(toAgent)); - messageParams.Add("source", new OSDInteger(0)); - - OSDMap data = new OSDMap(1); - data.Add("binary_bucket", OSD.FromBinary(binaryBucket)); - messageParams.Add("data", data); - messageParams.Add("message", new OSDString(message)); - messageParams.Add("id", new OSDUUID(transactionID)); - messageParams.Add("from_name", new OSDString(fromName)); - messageParams.Add("timestamp", new OSDInteger((int)timeStamp)); - messageParams.Add("offline", new OSDInteger(offline ? 1 : 0)); - messageParams.Add("parent_estate_id", new OSDInteger(parentEstateID)); - messageParams.Add("ttl", new OSDInteger((int)ttl)); - messageParams.Add("from_id", new OSDUUID(fromAgent)); - messageParams.Add("from_group", new OSDInteger(fromGroup ? 1 : 0)); -/* - StringBuilder sb = new StringBuilder(256); - LLSDxmlEncode.AddMap(sb); //messageParams - - LLSDxmlEncode.AddElem("type", dialog, sb); - LLSDxmlEncode.AddElem("position", position, sb); - LLSDxmlEncode.AddElem("region_id", UUID.Zero, sb); - LLSDxmlEncode.AddElem("to_id", toAgent, sb); - LLSDxmlEncode.AddElem("source", 0, sb); - - LLSDxmlEncode.AddMap("data", sb); //messageParams data - LLSDxmlEncode.AddElem("binary_bucket", binaryBucket, sb); - LLSDxmlEncode.AddEndMap(sb); //messageParams data - - LLSDxmlEncode.AddElem("message", message, sb); - LLSDxmlEncode.AddElem("id", transactionID, sb); - LLSDxmlEncode.AddElem("from_name", fromName, sb); - LLSDxmlEncode.AddElem("timestamp", timeStamp, sb); - LLSDxmlEncode.AddElem("offline", (offline ? 1 : 0), sb); - LLSDxmlEncode.AddElem("parent_estate_id", parentEstateID, sb); - LLSDxmlEncode.AddElem("ttl", (int)ttl, sb); - LLSDxmlEncode.AddElem("from_id", fromAgent, sb); - LLSDxmlEncode.AddElem("from_group",fromGroup, sb); - - LLSDxmlEncode.AddEndMap(sb); //messageParams - string tt = sb.ToString(); -*/ - return messageParams; - } - - public static OSD InstantMessage(UUID fromAgent, string message, UUID toAgent, - string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID, - Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket, - bool checkEstate, int godLevel, bool limitedToEstate) - { - OSDMap im = new OSDMap(2); - im.Add("message_params", InstantMessageParams(fromAgent, message, toAgent, - fromName, dialog, timeStamp, offline, parentEstateID, - position, ttl, transactionID, fromGroup, binaryBucket)); - - im.Add("agent_params", AgentParams(fromAgent, checkEstate, godLevel, limitedToEstate)); - - return im; - } - - - public static OSD ChatterboxInvitation(UUID sessionID, string sessionName, - UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, - uint timeStamp, bool offline, int parentEstateID, Vector3 position, - uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket) - { - OSDMap body = new OSDMap(5); - body.Add("session_id", new OSDUUID(sessionID)); - body.Add("from_name", new OSDString(fromName)); - body.Add("session_name", new OSDString(sessionName)); - body.Add("from_id", new OSDUUID(fromAgent)); - - body.Add("instantmessage", InstantMessage(fromAgent, message, toAgent, - fromName, dialog, timeStamp, offline, parentEstateID, position, - ttl, transactionID, fromGroup, binaryBucket, true, 0, true)); - - OSDMap chatterboxInvitation = new OSDMap(2); - chatterboxInvitation.Add("message", new OSDString("ChatterBoxInvitation")); - chatterboxInvitation.Add("body", body); - return chatterboxInvitation; - } - - public static OSD ChatterBoxSessionAgentListUpdates(UUID sessionID, - UUID agentID, bool canVoiceChat, bool isModerator, bool textMute, bool isEnterorLeave) - { - OSDMap body = new OSDMap(); - OSDMap agentUpdates = new OSDMap(); - OSDMap infoDetail = new OSDMap(); - OSDMap mutes = new OSDMap(); - - // this should be a list of agents and parameters - // foreach agent - mutes.Add("text", OSD.FromBoolean(textMute)); - infoDetail.Add("can_voice_chat", OSD.FromBoolean(canVoiceChat)); - infoDetail.Add("is_moderator", OSD.FromBoolean(isModerator)); - infoDetail.Add("mutes", mutes); - OSDMap info = new OSDMap(); - info.Add("info", infoDetail); - if(isEnterorLeave) - info.Add("transition",OSD.FromString("ENTER")); - else - info.Add("transition",OSD.FromString("LEAVE")); - agentUpdates.Add(agentID.ToString(), info); - - // foreach end - - body.Add("agent_updates", agentUpdates); - body.Add("session_id", OSD.FromUUID(sessionID)); - body.Add("updates", new OSD()); - - OSDMap chatterBoxSessionAgentListUpdates = new OSDMap(); - chatterBoxSessionAgentListUpdates.Add("message", OSD.FromString("ChatterBoxSessionAgentListUpdates")); - chatterBoxSessionAgentListUpdates.Add("body", body); - - return chatterBoxSessionAgentListUpdates; - } - - public static OSD ChatterBoxForceClose(UUID sessionID, string reason) - { - OSDMap body = new OSDMap(2); - body.Add("session_id", new OSDUUID(sessionID)); - body.Add("reason", new OSDString(reason)); - - OSDMap chatterBoxForceClose = new OSDMap(2); - chatterBoxForceClose.Add("message", new OSDString("ForceCloseChatterBoxSession")); - chatterBoxForceClose.Add("body", body); - return chatterBoxForceClose; - } - - public static OSD PlacesQuery(PlacesReplyPacket PlacesReply) - { - OSDMap placesReply = new OSDMap(); - placesReply.Add("message", OSD.FromString("PlacesReplyMessage")); - - OSDMap body = new OSDMap(); - OSDArray agentData = new OSDArray(); - OSDMap agentDataMap = new OSDMap(); - agentDataMap.Add("AgentID", OSD.FromUUID(PlacesReply.AgentData.AgentID)); - agentDataMap.Add("QueryID", OSD.FromUUID(PlacesReply.AgentData.QueryID)); - agentDataMap.Add("TransactionID", OSD.FromUUID(PlacesReply.TransactionData.TransactionID)); - agentData.Add(agentDataMap); - body.Add("AgentData", agentData); - - OSDArray QueryData = new OSDArray(); - - foreach (PlacesReplyPacket.QueryDataBlock groupDataBlock in PlacesReply.QueryData) - { - OSDMap QueryDataMap = new OSDMap(); - QueryDataMap.Add("ActualArea", OSD.FromInteger(groupDataBlock.ActualArea)); - QueryDataMap.Add("BillableArea", OSD.FromInteger(groupDataBlock.BillableArea)); - QueryDataMap.Add("Description", OSD.FromBinary(groupDataBlock.Desc)); - QueryDataMap.Add("Dwell", OSD.FromInteger((int)groupDataBlock.Dwell)); - QueryDataMap.Add("Flags", OSD.FromString(Convert.ToString(groupDataBlock.Flags))); - QueryDataMap.Add("GlobalX", OSD.FromInteger((int)groupDataBlock.GlobalX)); - QueryDataMap.Add("GlobalY", OSD.FromInteger((int)groupDataBlock.GlobalY)); - QueryDataMap.Add("GlobalZ", OSD.FromInteger((int)groupDataBlock.GlobalZ)); - QueryDataMap.Add("Name", OSD.FromBinary(groupDataBlock.Name)); - QueryDataMap.Add("OwnerID", OSD.FromUUID(groupDataBlock.OwnerID)); - QueryDataMap.Add("SimName", OSD.FromBinary(groupDataBlock.SimName)); - QueryDataMap.Add("SnapShotID", OSD.FromUUID(groupDataBlock.SnapshotID)); - QueryDataMap.Add("ProductSku", OSD.FromInteger(0)); - QueryDataMap.Add("Price", OSD.FromInteger(groupDataBlock.Price)); - - QueryData.Add(QueryDataMap); - } - body.Add("QueryData", QueryData); - placesReply.Add("QueryData[]", body); - - return placesReply; - } } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index 080cef929a..16b341a2dc 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs @@ -171,7 +171,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, TestHelpers.ParseTail(0x1)); - Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway)); + Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.NotFound)); } /// @@ -195,7 +195,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, npc.UUID); - Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway)); + Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.NotFound)); } } } diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index 8e69d4b0f9..96c9b5a147 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System.Collections.Generic; using System.Text; using System.Net; using OpenMetaverse; @@ -35,12 +36,48 @@ using OpenSim.Framework; namespace OpenSim.Region.Framework.Interfaces { + public struct GroupChatListAgentUpdateData + { + public UUID agentID; + public bool enterOrLeave; // true means enter + public bool isModerator; + public bool mutedText; + public bool canVoice; + + public GroupChatListAgentUpdateData(UUID ID) + { + agentID = ID; + canVoice = false; + isModerator = false; + mutedText = false; + enterOrLeave = true; + } + + public GroupChatListAgentUpdateData(UUID ID, bool eOL) + { + agentID = ID; + canVoice = false; + isModerator = false; + mutedText = false; + enterOrLeave = eOL; + } + + public GroupChatListAgentUpdateData(UUID ID, bool cv, bool isMod, bool mtd, bool eOrL) + { + agentID = ID; + enterOrLeave = eOrL; + isModerator = isMod; + mutedText = mtd; + canVoice = cv; + } + } + public interface IEventQueue { bool Enqueue(OSD o, UUID avatarID); + bool Enqueue(byte[] o, UUID avatarID); - // These are required to decouple Scenes from EventQueueHelper -// void DisableSimulator(ulong handle, UUID avatarID); + // void DisableSimulator(ulong handle, UUID avatarID); void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY); void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, ulong regionHandle, int regionSizeX, int regionSizeY); @@ -56,16 +93,20 @@ namespace OpenSim.Region.Framework.Interfaces UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID, Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); - void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, - bool canVoiceChat, bool isModerator, bool textMute, bool isEnterorLeave); + void ChatterBoxSessionStartReply(UUID sessionID, string sessionName, int type, + bool voiceEnabled, bool voiceModerated, UUID tmpSessionID, + bool sucess, string error, + UUID toAgent); + void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID toAgent, List updates); void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason); //void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data); void ScriptRunningEvent(UUID objectID, UUID itemID, bool running, UUID avatarID); - OSD BuildEvent(string eventName, OSD eventBody); + byte[] BuildEvent(string eventName, OSD eventBody); void partPhysicsProperties(uint localID, byte physhapetype, float density, float friction, float bounce, float gravmod, UUID avatarID); - + void WindlightRefreshEvent(int interpolate, UUID avatarID); StringBuilder StartEvent(string eventName); string EndEvent(StringBuilder sb); + byte[] EndEventToBytes(StringBuilder sb); } } diff --git a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs index b17425a408..ef40c3c0ee 100644 --- a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs +++ b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs @@ -104,17 +104,25 @@ namespace OpenSim.Tests.Common Events.Clear(); } - public bool Enqueue(OSD o, UUID avatarID) + public bool Enqueue(string o, UUID avatarID) { AddEvent(avatarID, "Enqueue", o); return true; } -/* - public void DisableSimulator(ulong handle, UUID avatarID) + public bool Enqueue(byte[] o, UUID avatarID) { - AddEvent(avatarID, "DisableSimulator", handle); + return true; } -*/ + public bool Enqueue(OSD o, UUID avatarID) + { + return true; + } + /* + public void DisableSimulator(ulong handle, UUID avatarID) + { + AddEvent(avatarID, "DisableSimulator", handle); + } + */ public void EnableSimulator (ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) { AddEvent(avatarID, "EnableSimulator", handle); @@ -148,9 +156,19 @@ namespace OpenSim.Tests.Common timeStamp, offline, parentEstateID, position, ttl, transactionID, fromGroup, binaryBucket); } - public void ChatterBoxSessionAgentListUpdates (UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, bool isModerator, bool textMute , bool isEnterorLeave) + public void ChatterBoxSessionStartReply(UUID sessionID, string sessionName, int type, + bool voiceEnabled, bool voiceModerated, UUID tmpSessionID, + bool sucess, string error, + UUID toAgent) { - AddEvent(toAgent, "ChatterBoxSessionAgentListUpdates", sessionID, fromAgent, canVoiceChat, isModerator, textMute, isEnterorLeave); + AddEvent(toAgent, "ChatterBoxSessionStartReply", sessionID, sessionName, type, + voiceEnabled, voiceModerated, tmpSessionID, + sucess, error); + } + + public void ChatterBoxSessionAgentListUpdates (UUID sessionID, UUID toAgent, List updates) + { + AddEvent(toAgent, "ChatterBoxSessionAgentListUpdates", sessionID, toAgent, updates); } public void ChatterBoxForceClose (UUID toAgent, UUID sessionID, string reason) @@ -174,10 +192,10 @@ namespace OpenSim.Tests.Common throw new System.NotImplementedException (); } - public OSD BuildEvent(string eventName, OSD eventBody) + public byte[] BuildEvent(string eventName, OSD eventBody) { - Console.WriteLine("TWO"); - throw new System.NotImplementedException (); + Console.WriteLine("TWOoo"); + throw new System.NotImplementedException(); } public void partPhysicsProperties (uint localID, byte physhapetype, float density, float friction, float bounce, float gravmod, UUID avatarID) @@ -185,6 +203,10 @@ namespace OpenSim.Tests.Common AddEvent(avatarID, "partPhysicsProperties", localID, physhapetype, density, friction, bounce, gravmod); } + public void WindlightRefreshEvent(int interpolate, UUID avatarID) + { + } + public StringBuilder StartEvent(string eventName) { return null; @@ -194,5 +216,9 @@ namespace OpenSim.Tests.Common { return ""; } -} + public byte[] EndEventToBytes(StringBuilder sb) + { + return new byte[0]; + } + } } \ No newline at end of file