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("