change eventqueue queues type, move event methods to other file (using partial class)

master
UbitUmarov 2020-05-07 02:26:25 +01:00
parent 6c49f16132
commit 58a4f45712
7 changed files with 708 additions and 580 deletions

View File

@ -252,7 +252,7 @@ namespace OpenSim.Groups
m_debugEnabled = verbose; 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);
} }
/// <summary> /// <summary>
@ -599,13 +599,16 @@ namespace OpenSim.Groups
{ {
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");
UUID fromAgent = new UUID(msg.fromAgentID);
// 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); // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>(); IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
if (eq != null)
{
eq.ChatterboxInvitation( eq.ChatterboxInvitation(
GroupID GroupID
, groupInfo.GroupName , groupInfo.GroupName
, new UUID(msg.fromAgentID) , fromAgent
, msg.message , msg.message
, AgentID , AgentID
, msg.fromAgentName , msg.fromAgentName
@ -620,15 +623,10 @@ namespace OpenSim.Groups
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName) , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
); );
eq.ChatterBoxSessionAgentListUpdates( var update = new GroupChatListAgentUpdateData(AgentID);
new UUID(GroupID) var updates = new List<GroupChatListAgentUpdateData> { update };
, AgentID eq.ChatterBoxSessionAgentListUpdates(GroupID, new UUID(msg.toAgentID), updates);
, new UUID(msg.toAgentID) }
, false //canVoiceChat
, false //isModerator
, false //text mute
, true // Enter
);
} }
} }
} }
@ -663,15 +661,12 @@ namespace OpenSim.Groups
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
queue.ChatterBoxSessionAgentListUpdates( if (queue != null)
GroupID {
, AgentID var update = new GroupChatListAgentUpdateData(AgentID);
, new UUID(im.toAgentID) var updates = new List<GroupChatListAgentUpdateData> { update };
, false //canVoiceChat queue.ChatterBoxSessionAgentListUpdates(GroupID, remoteClient.AgentId, updates);
, false //isModerator }
, false //text mute
, true
);
} }
} }
@ -713,11 +708,7 @@ namespace OpenSim.Groups
bodyMap.Add("session_info", sessionMap); bodyMap.Add("session_info", sessionMap);
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
queue?.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
if (queue != null)
{
queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
}
} }
private void DebugGridInstantMessage(GridInstantMessage im) private void DebugGridInstantMessage(GridInstantMessage im)

View File

@ -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<GroupChatListAgentUpdateData> 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<bool> lstInProfiles = new List<bool>(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));
}
}
}

View File

@ -35,12 +35,8 @@ using log4net;
using Nini.Config; using Nini.Config;
using Mono.Addins; using Mono.Addins;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Messages.Linden;
using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -55,11 +51,15 @@ namespace OpenSim.Region.ClientStack.Linden
} }
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EventQueueGetModule")] [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 readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static string LogHeader = "[EVENT QUEUE GET MODULE]"; 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
/// <value> /// <value>
/// Debug level. /// Debug level.
/// </value> /// </value>
@ -69,7 +69,7 @@ namespace OpenSim.Region.ClientStack.Linden
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>(); private Dictionary<UUID, Queue<byte[]>> queues = new Dictionary<UUID, Queue<byte[]>>();
private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
#region INonSharedRegionModule methods #region INonSharedRegionModule methods
@ -149,22 +149,19 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
DebugLevel = debugLevel; DebugLevel = debugLevel;
MainConsole.Instance.Output( 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) 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) lock (queues)
{ {
foreach (KeyValuePair<UUID, Queue<OSD>> kvp in queues) foreach (KeyValuePair<UUID, Queue<byte[]>> kvp in queues)
{ {
MainConsole.Instance.Output( MainConsole.Instance.Output(" {0} {1}", kvp.Key, kvp.Value.Count);
"For agent {0} there are {1} messages queued for send.",
null,
kvp.Key, kvp.Value.Count);
} }
} }
} }
@ -174,21 +171,23 @@ namespace OpenSim.Region.ClientStack.Linden
/// </summary> /// </summary>
/// <param name="agentId"></param> /// <param name="agentId"></param>
/// <returns></returns> /// <returns></returns>
private Queue<OSD> TryGetQueue(UUID agentId) private Queue<byte[]> TryGetQueue(UUID agentId)
{ {
lock (queues) lock (queues)
{ {
if (!queues.ContainsKey(agentId)) Queue<byte[]> queue;
{ if (queues.TryGetValue(agentId, out queue))
return queue;
if (DebugLevel > 0) if (DebugLevel > 0)
m_log.DebugFormat( m_log.DebugFormat(
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
agentId, m_scene.RegionInfo.RegionName); agentId, m_scene.RegionInfo.RegionName);
queues[agentId] = new Queue<OSD>(); queue = new Queue<byte[]>();
} queues[agentId] = queue;
return queues[agentId]; return queue;
} }
} }
@ -198,31 +197,29 @@ namespace OpenSim.Region.ClientStack.Linden
/// </summary> /// </summary>
/// <param name="agentId"></param> /// <param name="agentId"></param>
/// <returns></returns> /// <returns></returns>
private Queue<OSD> GetQueue(UUID agentId) private Queue<byte[]> GetQueue(UUID agentId)
{ {
lock (queues) lock (queues)
{ {
if (queues.ContainsKey(agentId)) if (queues.TryGetValue(agentId, out Queue<byte[]> queue))
{ return queue;
return queues[agentId];
}
else
return null; return null;
} }
} }
#region IEventQueue Members #region IEventQueue Members
//legacy
public bool Enqueue(OSD ev, UUID avatarID) public bool Enqueue(OSD data, UUID avatarID)
{ {
//m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName); //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
try try
{ {
Queue<OSD> queue = GetQueue(avatarID); Queue<byte[]> queue = GetQueue(avatarID);
if (queue != null) if (queue != null)
{ {
byte[] evData = Util.UTF8NBGetbytes(OSDParser.SerializeLLSDInnerXmlString(data));
lock (queue) lock (queue)
queue.Enqueue(ev); queue.Enqueue(evData);
} }
else else
{ {
@ -236,7 +233,62 @@ namespace OpenSim.Region.ClientStack.Linden
m_log.Error("[EVENTQUEUE] Caught exception: " + e); m_log.Error("[EVENTQUEUE] Caught exception: " + e);
return false; 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<byte[]> queue = GetQueue(avatarID);
if (queue != null)
{
byte[] evData = Util.UTF8NBGetbytes(ev);
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;
}
*/
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<byte[]> 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; return true;
} }
@ -267,7 +319,7 @@ namespace OpenSim.Region.ClientStack.Linden
/// <param name='eqgUuid'></param> /// <param name='eqgUuid'></param>
private string GenerateEqgCapPath(UUID eqgUuid) 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) public void OnRegisterCaps(UUID agentID, Caps caps)
@ -280,16 +332,15 @@ namespace OpenSim.Region.ClientStack.Linden
agentID, caps, m_scene.RegionInfo.RegionName); agentID, caps, m_scene.RegionInfo.RegionName);
UUID eventQueueGetUUID; UUID eventQueueGetUUID;
Queue<OSD> queue = null; Queue<Byte[]> queue = null;
lock (queues) lock (queues)
{ {
if (queues.ContainsKey(agentID)) queues.TryGetValue(agentID, out queue);
queue = queues[agentID];
if (queue == null) if (queue == null)
{ {
queue = new Queue<OSD>(); queue = new Queue<byte[]>();
queues[agentID] = queue; queues[agentID] = queue;
lock (m_AvatarQueueUUIDMapping) lock (m_AvatarQueueUUIDMapping)
@ -338,7 +389,6 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
eventQueueGetUUID = UUID.Random(); eventQueueGetUUID = UUID.Random();
m_AvatarQueueUUIDMapping[agentID] = eventQueueGetUUID; m_AvatarQueueUUIDMapping[agentID] = eventQueueGetUUID;
m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
lock (m_ids) lock (m_ids)
{ {
if (m_ids.ContainsKey(agentID)) if (m_ids.ContainsKey(agentID))
@ -356,19 +406,20 @@ namespace OpenSim.Region.ClientStack.Linden
caps.RegisterPollHandler( caps.RegisterPollHandler(
"EventQueueGet", "EventQueueGet",
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, int.MaxValue)); new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, VIEWERKEEPALIVE));
} }
public bool HasEvents(UUID requestID, UUID agentID) public bool HasEvents(UUID requestID, UUID agentID)
{ {
Queue<OSD> queue = GetQueue(agentID); Queue<byte[]> queue = GetQueue(agentID);
if (queue != null) if (queue != null)
{
lock (queue) lock (queue)
{ {
//m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count); //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
return queue.Count > 0; return queue.Count > 0;
} }
}
//m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID); //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
return true; return true;
} }
@ -387,22 +438,32 @@ namespace OpenSim.Region.ClientStack.Linden
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name); ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
} }
} }
public void Drop(UUID requestID, UUID pAgentId) public void Drop(UUID requestID, UUID pAgentId)
{ {
// do nothing, in last case http server will do it // do nothing, in last case http server will do it
} }
private readonly byte[] EventHeader = GenEventHeader();
private static byte[] GenEventHeader()
{
return Encoding.UTF8.GetBytes("<llsd><map><key>events</key><array>");
}
public Hashtable GetEvents(UUID requestID, UUID pAgentId) public Hashtable GetEvents(UUID requestID, UUID pAgentId)
{ {
if (DebugLevel >= 2) if (DebugLevel >= 2)
m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name); m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name);
Queue<OSD> queue = GetQueue(pAgentId); Queue<byte[]> queue = GetQueue(pAgentId);
if (queue == null) if (queue == null)
return NoEvents(requestID, pAgentId); return NoAgent(requestID, pAgentId);
OSD element = null;; byte[] element = null;
OSDArray array = new OSDArray(); List<byte[]> elements;
int totalSize = 0;
int thisID = 0; int thisID = 0;
bool negativeID = false; bool negativeID = false;
@ -420,6 +481,9 @@ namespace OpenSim.Region.ClientStack.Linden
thisID = -thisID; thisID = -thisID;
} }
elements = new List<byte[]>(queue.Count + 2);
elements.Add(EventHeader);
while (queue.Count > 0) while (queue.Count > 0)
{ {
element = queue.Dequeue(); element = queue.Dequeue();
@ -430,7 +494,9 @@ namespace OpenSim.Region.ClientStack.Linden
if (DebugLevel > 0) if (DebugLevel > 0)
LogOutboundDebugMessage(element, pAgentId); 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; m_ids[pAgentId] = thisID + 1;
} }
if (array.Count == 0) if (totalSize == 0)
return NoEvents(requestID, pAgentId); return NoEvents(requestID, pAgentId);
OSDMap events = new OSDMap(); totalSize += EventHeader.Length;
events.Add("events", array);
events.Add("id", new OSDInteger(thisID)); 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(); Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["content_type"] = "application/xml"; responsedata["content_type"] = "application/xml";
//string tt = OSDParser.SerializeLLSDXmlString(events);
responsedata["bin_response_data"] = Encoding.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(events)); //temporary
responsedata["keepaliveTimeout"] = 60; byte[] finalData = new byte[totalSize];
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); 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; return responsedata;
} }
public Hashtable NoEvents(UUID requestID, UUID agentID) public Hashtable NoEvents(UUID requestID, UUID agentID)
{ {
Hashtable responsedata = new Hashtable(); Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 502; Queue<byte[]> queue = GetQueue(agentID);
responsedata["content_type"] = "text/plain"; if (queue == null)
responsedata["str_response_string"] = "<llsd></llsd>"; {
responsedata["error_status_text"] = "<llsd></llsd>"; responsedata["int_response_code"] = (int)HttpStatusCode.NotFound;
responsedata["keepalive"] = false; return responsedata;
}
responsedata["int_response_code"] = (int)HttpStatusCode.BadGateway;
return responsedata; return responsedata;
} }
/* this is not a event message public Hashtable NoAgent(UUID requestID, UUID agentID)
public void DisableSimulator(ulong handle, UUID avatarID)
{ {
OSD item = EventQueueHelper.DisableSimulator(handle); Hashtable responsedata = new Hashtable();
Enqueue(item, avatarID); responsedata["int_response_code"] = (int)HttpStatusCode.NotFound;
} return responsedata;
*/
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<bool> lstInProfiles = new List<bool>(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);
} }
} }
} }

View File

@ -41,232 +41,5 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
private EventQueueHelper() {} // no construction possible, it's an utility class 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;
}
} }
} }

View File

@ -171,7 +171,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, TestHelpers.ParseTail(0x1)); 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));
} }
/// <summary> /// <summary>
@ -195,7 +195,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, npc.UUID); 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));
} }
} }
} }

View File

@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System.Collections.Generic;
using System.Text; using System.Text;
using System.Net; using System.Net;
using OpenMetaverse; using OpenMetaverse;
@ -35,11 +36,47 @@ using OpenSim.Framework;
namespace OpenSim.Region.Framework.Interfaces 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 public interface IEventQueue
{ {
bool Enqueue(OSD o, UUID avatarID); 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 EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY);
void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint,
@ -56,16 +93,20 @@ namespace OpenSim.Region.Framework.Interfaces
UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
uint timeStamp, bool offline, int parentEstateID, Vector3 position, uint timeStamp, bool offline, int parentEstateID, Vector3 position,
uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket);
void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, void ChatterBoxSessionStartReply(UUID sessionID, string sessionName, int type,
bool canVoiceChat, bool isModerator, bool textMute, bool isEnterorLeave); bool voiceEnabled, bool voiceModerated, UUID tmpSessionID,
bool sucess, string error,
UUID toAgent);
void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID toAgent, List<GroupChatListAgentUpdateData> updates);
void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason); void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason);
//void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); //void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID);
void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data); void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data);
void ScriptRunningEvent(UUID objectID, UUID itemID, bool running, UUID avatarID); 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 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); StringBuilder StartEvent(string eventName);
string EndEvent(StringBuilder sb); string EndEvent(StringBuilder sb);
byte[] EndEventToBytes(StringBuilder sb);
} }
} }

View File

@ -104,11 +104,19 @@ namespace OpenSim.Tests.Common
Events.Clear(); Events.Clear();
} }
public bool Enqueue(OSD o, UUID avatarID) public bool Enqueue(string o, UUID avatarID)
{ {
AddEvent(avatarID, "Enqueue", o); AddEvent(avatarID, "Enqueue", o);
return true; return true;
} }
public bool Enqueue(byte[] o, UUID avatarID)
{
return true;
}
public bool Enqueue(OSD o, UUID avatarID)
{
return true;
}
/* /*
public void DisableSimulator(ulong handle, UUID avatarID) public void DisableSimulator(ulong handle, UUID avatarID)
{ {
@ -148,9 +156,19 @@ namespace OpenSim.Tests.Common
timeStamp, offline, parentEstateID, position, ttl, transactionID, fromGroup, binaryBucket); 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<GroupChatListAgentUpdateData> updates)
{
AddEvent(toAgent, "ChatterBoxSessionAgentListUpdates", sessionID, toAgent, updates);
} }
public void ChatterBoxForceClose (UUID toAgent, UUID sessionID, string reason) public void ChatterBoxForceClose (UUID toAgent, UUID sessionID, string reason)
@ -174,9 +192,9 @@ namespace OpenSim.Tests.Common
throw new System.NotImplementedException (); throw new System.NotImplementedException ();
} }
public OSD BuildEvent(string eventName, OSD eventBody) public byte[] BuildEvent(string eventName, OSD eventBody)
{ {
Console.WriteLine("TWO"); Console.WriteLine("TWOoo");
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
@ -185,6 +203,10 @@ namespace OpenSim.Tests.Common
AddEvent(avatarID, "partPhysicsProperties", localID, physhapetype, density, friction, bounce, gravmod); AddEvent(avatarID, "partPhysicsProperties", localID, physhapetype, density, friction, bounce, gravmod);
} }
public void WindlightRefreshEvent(int interpolate, UUID avatarID)
{
}
public StringBuilder StartEvent(string eventName) public StringBuilder StartEvent(string eventName)
{ {
return null; return null;
@ -194,5 +216,9 @@ namespace OpenSim.Tests.Common
{ {
return ""; return "";
} }
public byte[] EndEventToBytes(StringBuilder sb)
{
return new byte[0];
}
} }
} }