a few more changes on initial objects send

0.9.1.0-post-fixes
UbitUmarov 2019-03-30 12:07:49 +00:00
parent f6db9e044d
commit 6cf85a3db1
8 changed files with 120 additions and 194 deletions

View File

@ -816,7 +816,7 @@ namespace OpenSim.Framework
event TeleportCancel OnTeleportCancel; event TeleportCancel OnTeleportCancel;
event DeRezObject OnDeRezObject; event DeRezObject OnDeRezObject;
event RezRestoreToWorld OnRezRestoreToWorld; event RezRestoreToWorld OnRezRestoreToWorld;
event Action<IClientAPI, uint> OnRegionHandShakeReply; event Action<IClientAPI> OnRegionHandShakeReply;
event GenericCall1 OnRequestWearables; event GenericCall1 OnRequestWearables;
event Action<IClientAPI, bool> OnCompleteMovementToRegion; event Action<IClientAPI, bool> OnCompleteMovementToRegion;
@ -1511,6 +1511,6 @@ namespace OpenSim.Framework
void SendAgentTerseUpdate(ISceneEntity presence); void SendAgentTerseUpdate(ISceneEntity presence);
void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data); void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data);
void CheckViewerCaps(); uint GetViewerCaps();
} }
} }

View File

@ -80,7 +80,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event ModifyTerrain OnModifyTerrain; public event ModifyTerrain OnModifyTerrain;
public event Action<IClientAPI, uint> OnRegionHandShakeReply; public event Action<IClientAPI> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
@ -8923,7 +8923,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandlerRegionHandshakeReply(IClientAPI sender, Packet Pack) private bool HandlerRegionHandshakeReply(IClientAPI sender, Packet Pack)
{ {
Action<IClientAPI, uint> handlerRegionHandShakeReply = OnRegionHandShakeReply; Action<IClientAPI> handlerRegionHandShakeReply = OnRegionHandShakeReply;
if (handlerRegionHandShakeReply == null) if (handlerRegionHandShakeReply == null)
return true; // silence the warning return true; // silence the warning
@ -8936,7 +8936,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else else
m_viewerHandShakeFlags = 0; m_viewerHandShakeFlags = 0;
handlerRegionHandShakeReply(this, m_viewerHandShakeFlags); handlerRegionHandShakeReply(this);
return true; return true;
} }
@ -15364,15 +15364,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return new HashSet<string>(m_inPacketsToDrop); return new HashSet<string>(m_inPacketsToDrop);
} }
public void CheckViewerCaps() public uint GetViewerCaps()
{ {
m_SupportObjectAnimations = false; m_SupportObjectAnimations = false;
uint ret;
if(m_supportViewerCache)
ret = m_viewerHandShakeFlags;
else
ret = m_viewerHandShakeFlags & 4;
if (m_scene.CapsModule != null) if (m_scene.CapsModule != null)
{ {
Caps cap = m_scene.CapsModule.GetCapsForUser(CircuitCode); Caps cap = m_scene.CapsModule.GetCapsForUser(CircuitCode);
if (cap != null && (cap.Flags & Caps.CapsFlags.ObjectAnim) != 0) if(cap != null)
m_SupportObjectAnimations = true; {
if((cap.Flags & Caps.CapsFlags.SentSeeds) != 0)
ret |= 0x1000;
if ((cap.Flags & Caps.CapsFlags.ObjectAnim) != 0)
{
m_SupportObjectAnimations = true;
ret |= 0x2000;
}
}
} }
return ret; // ???
} }
} }
} }

View File

@ -1698,7 +1698,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
// Now we know we can handle more data // Now we know we can handle more data
Thread.Sleep(200); //Thread.Sleep(200);
// Obtain the pending queue and remove it from the cache // Obtain the pending queue and remove it from the cache
Queue<UDPPacketBuffer> queue = null; Queue<UDPPacketBuffer> queue = null;
@ -1727,7 +1727,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if(aCircuit.teleportFlags <= 0) if(aCircuit.teleportFlags <= 0)
client.SendRegionHandshake(); client.SendRegionHandshake();
client.CheckViewerCaps();
} }
} }
else else
@ -1743,8 +1742,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
} }
catch (Exception e) catch (Exception e)
@ -1758,117 +1757,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
e.StackTrace); e.StackTrace);
} }
} }
/*
protected void HandleCompleteMovementIntoRegion(object o)
{
IPEndPoint endPoint = null;
IClientAPI client = null;
try
{
object[] array = (object[])o;
endPoint = (IPEndPoint)array[0];
CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
m_log.DebugFormat(
"[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, Scene.Name);
// Determine which agent this packet came from
// We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
// simulator with no existing child presence, the viewer (at least LL 3.3.4) will send UseCircuitCode
// and then CompleteAgentMovement immediately without waiting for an ack. As we are now handling these
// packets asynchronously, we need to account for this thread proceeding more quickly than the
// UseCircuitCode thread.
int count = 40;
while (count-- > 0)
{
if (Scene.TryGetClient(endPoint, out client))
{
if (!client.IsActive)
{
// This check exists to catch a condition where the client has been closed by another thread
// but has not yet been removed from the client manager (and possibly a new connection has
// not yet been established).
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.",
endPoint, client.Name, Scene.Name);
}
else if (client.SceneAgent == null)
{
// This check exists to catch a condition where the new client has been added to the client
// manager but the SceneAgent has not yet been set in Scene.AddNewAgent(). If we are too
// eager, then the new ScenePresence may not have registered a listener for this messsage
// before we try to process it.
// XXX: A better long term fix may be to add the SceneAgent before the client is added to
// the client manager
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.",
endPoint, client.Name, Scene.Name);
}
else
{
break;
}
}
else
{
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
endPoint, Scene.Name);
}
Thread.Sleep(200);
}
if (client == null)
{
m_log.DebugFormat(
"[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
endPoint, Scene.Name);
return;
}
else if (!client.IsActive || client.SceneAgent == null)
{
// This check exists to catch a condition where the client has been closed by another thread
// but has not yet been removed from the client manager.
// The packet could be simply ignored but it is useful to know if this condition occurred for other debugging
// purposes.
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.",
endPoint, client.Name, Scene.Name);
return;
}
IncomingPacket incomingPacket1;
// Inbox insertion
if (UsePools)
{
incomingPacket1 = m_incomingPacketPool.GetObject();
incomingPacket1.Client = (LLClientView)client;
incomingPacket1.Packet = packet;
}
else
{
incomingPacket1 = new IncomingPacket((LLClientView)client, packet);
}
packetInbox.Enqueue(incomingPacket1);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[LLUDPSERVER]: CompleteAgentMovement handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
endPoint != null ? endPoint.ToString() : "n/a",
client != null ? client.Name : "unknown",
client != null ? client.AgentId.ToString() : "unknown",
e.Message,
e.StackTrace);
}
}
*/
/// <summary> /// <summary>
/// Send an ack immediately to the given endpoint. /// Send an ack immediately to the given endpoint.
@ -1936,7 +1824,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (Scene.TryGetClient(agentID, out client)) if (Scene.TryGetClient(agentID, out client))
{ {
if (client.SceneAgent != null) if (client.SceneAgent != null &&
client.CircuitCode == circuitCode &&
client.SessionId == sessionID &&
client.RemoteEndPoint == remoteEndPoint &&
client.SceneAgent.ControllingClient.SecureSessionId == sessionInfo.LoginInfo.SecureSession)
return client; return client;
Scene.CloseAgent(agentID, true); Scene.CloseAgent(agentID, true);
} }

View File

@ -1841,7 +1841,7 @@ namespace OpenSim.Region.CoreModules.World.Land
UUID lgid = LandData.GlobalID; UUID lgid = LandData.GlobalID;
m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
{ {
if(sp.IsNPC || sp.IsLoggingIn || sp.IsDeleted || sp.currentParcelUUID != lgid) if(sp.IsNPC || sp.IsDeleted || sp.currentParcelUUID != lgid)
return; return;
cur += (now - sp.ParcelDwellTickMS); cur += (now - sp.ParcelDwellTickMS);
sp.ParcelDwellTickMS = now; sp.ParcelDwellTickMS = now;

View File

@ -99,6 +99,8 @@ namespace OpenSim.Region.Framework.Scenes
public bool IsViewerUIGod { get; set; } public bool IsViewerUIGod { get; set; }
public bool IsGod { get; set; } public bool IsGod { get; set; }
private bool m_gotRegionHandShake = false;
private PresenceType m_presenceType; private PresenceType m_presenceType;
public PresenceType PresenceType public PresenceType PresenceType
{ {
@ -288,7 +290,7 @@ namespace OpenSim.Region.Framework.Scenes
private Quaternion m_lastRotation; private Quaternion m_lastRotation;
private Vector3 m_lastVelocity; private Vector3 m_lastVelocity;
private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
private bool SentInitialData = false; private bool NeedInitialData = false;
private int m_userFlags; private int m_userFlags;
public int UserFlags public int UserFlags
@ -881,7 +883,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
public bool IsChildAgent { get; set; } public bool IsChildAgent { get; set; }
public bool IsLoggingIn { get; set; }
/// <summary> /// <summary>
/// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
@ -1074,7 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes
AttachmentsSyncLock = new Object(); AttachmentsSyncLock = new Object();
AllowMovement = true; AllowMovement = true;
IsChildAgent = true; IsChildAgent = true;
IsLoggingIn = false;
m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
Animator = new ScenePresenceAnimator(this); Animator = new ScenePresenceAnimator(this);
Overrides = new MovementAnimationOverrides(); Overrides = new MovementAnimationOverrides();
@ -1307,7 +1307,6 @@ namespace OpenSim.Region.Framework.Scenes
ParentPart = null; ParentPart = null;
PrevSitOffset = Vector3.Zero; PrevSitOffset = Vector3.Zero;
HandleForceReleaseControls(ControllingClient, UUID); // needs testing HandleForceReleaseControls(ControllingClient, UUID); // needs testing
IsLoggingIn = false;
} }
else else
{ {
@ -1331,10 +1330,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
ParentUUID = UUID.Zero; ParentUUID = UUID.Zero;
} }
else
{
IsLoggingIn = false;
}
IsChildAgent = false; IsChildAgent = false;
} }
@ -2163,7 +2158,7 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts));
// recheck to reduce timing issues // recheck to reduce timing issues
ControllingClient.CheckViewerCaps(); ControllingClient.GetViewerCaps();
bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0; bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0;
@ -2325,9 +2320,40 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} }
if(!IsNPC) //m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (!IsNPC)
{ {
//m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); if (!string.IsNullOrEmpty(m_callbackURI))
{
m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with old callback to {2}",
client.Name, client.AgentId, m_callbackURI);
UUID originID;
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
m_callbackURI = null;
//m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
}
else if (!string.IsNullOrEmpty(m_newCallbackURI))
{
m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
client.Name, client.AgentId, m_newCallbackURI);
UUID originID;
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
Scene.SimulationService.ReleaseAgent(originID, UUID, m_newCallbackURI);
m_newCallbackURI = null;
//m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
}
if (openChildAgents) if (openChildAgents)
{ {
// Create child agents in neighbouring regions // Create child agents in neighbouring regions
@ -2360,36 +2386,6 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts));
if (!string.IsNullOrEmpty(m_callbackURI))
{
m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with old callback to {2}",
client.Name, client.AgentId, m_callbackURI);
UUID originID;
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
m_callbackURI = null;
//m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
}
else if (!string.IsNullOrEmpty(m_newCallbackURI))
{
m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
client.Name, client.AgentId, m_newCallbackURI);
UUID originID;
lock (m_originRegionIDAccessLock)
originID = m_originRegionID;
Scene.SimulationService.ReleaseAgent(originID, UUID, m_newCallbackURI);
m_newCallbackURI = null;
//m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
}
if (openChildAgents) if (openChildAgents)
{ {
@ -3850,15 +3846,21 @@ namespace OpenSim.Region.Framework.Scenes
public override void Update() public override void Update()
{ {
if(IsChildAgent || IsDeleted) if (IsDeleted)
return;
if (NeedInitialData)
{
SendInitialData();
return;
}
if (IsChildAgent || IsInTransit)
return; return;
CheckForBorderCrossing(); CheckForBorderCrossing();
if (IsInTransit || IsLoggingIn) if (m_movingToTarget)
return;
if(m_movingToTarget)
{ {
m_delayedStop = -1; m_delayedStop = -1;
Vector3 control = Vector3.Zero; Vector3 control = Vector3.Zero;
@ -4033,25 +4035,28 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
} }
public void RegionHandShakeReply (IClientAPI client, uint flags) public void RegionHandShakeReply (IClientAPI client)
{ {
if(IsNPC) if(IsNPC)
return; return;
lock (m_completeMovementLock) lock (m_completeMovementLock)
{ {
if (SentInitialData) if(m_gotRegionHandShake)
return; return;
SentInitialData = true; NeedInitialData = true;
} }
}
private void SendInitialData()
{
uint flags = ControllingClient.GetViewerCaps();
if((flags & 0x1000) == 0) // wait for seeds sending
return;
NeedInitialData = false;
bool selfappearance = (flags & 4) != 0; bool selfappearance = (flags & 4) != 0;
bool cacheCulling = (flags & 1) != 0;
bool cacheEmpty;
if(cacheCulling)
cacheEmpty = (flags & 2) != 0;
else
cacheEmpty = true;
Util.FireAndForget(delegate Util.FireAndForget(delegate
{ {
@ -4066,9 +4071,6 @@ namespace OpenSim.Region.Framework.Scenes
SendOtherAgentsAvatarFullToMe(); SendOtherAgentsAvatarFullToMe();
} }
// recheck to reduce timing issues
ControllingClient.CheckViewerCaps();
if (m_scene.ObjectsCullingByDistance) if (m_scene.ObjectsCullingByDistance)
{ {
m_reprioritizationBusy = true; m_reprioritizationBusy = true;
@ -4081,6 +4083,13 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
} }
bool cacheCulling = (flags & 1) != 0;
bool cacheEmpty;
if (cacheCulling)
cacheEmpty = (flags & 2) != 0;
else
cacheEmpty = true;
EntityBase[] entities = Scene.Entities.GetEntities(); EntityBase[] entities = Scene.Entities.GetEntities();
if(cacheEmpty) if(cacheEmpty)
{ {
@ -6816,7 +6825,8 @@ namespace OpenSim.Region.Framework.Scenes
lock (m_completeMovementLock) lock (m_completeMovementLock)
{ {
GodController.HasMovedAway(); GodController.HasMovedAway();
SentInitialData = false; NeedInitialData = false;
m_gotRegionHandShake = false;
} }
List<ScenePresence> allpresences = m_scene.GetScenePresences(); List<ScenePresence> allpresences = m_scene.GetScenePresences();

View File

@ -699,7 +699,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event TeleportCancel OnTeleportCancel; public event TeleportCancel OnTeleportCancel;
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event Action<IClientAPI, uint> OnRegionHandShakeReply; public event Action<IClientAPI> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event Action<IClientAPI, bool> OnCompleteMovementToRegion; public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnPreAgentUpdate;
@ -938,12 +938,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
if (OnRegionHandShakeReply != null) if (OnRegionHandShakeReply != null)
{ {
OnRegionHandShakeReply(this, 0); OnRegionHandShakeReply(this);
} }
if (OnCompleteMovementToRegion != null) if (OnCompleteMovementToRegion != null)
{ {
OnCompleteMovementToRegion(this, true); OnCompleteMovementToRegion(this, false);
} }
} }
@ -1773,7 +1773,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
return 0; return 0;
} }
public void CheckViewerCaps() { } public uint GetViewerCaps()
{
return 0;
}
} }
} }

View File

@ -319,7 +319,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event Action<IClientAPI, uint> OnRegionHandShakeReply; public event Action<IClientAPI> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event Action<IClientAPI, bool> OnCompleteMovementToRegion; public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnPreAgentUpdate;
@ -928,7 +928,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
if (OnRegionHandShakeReply != null) if (OnRegionHandShakeReply != null)
{ {
OnRegionHandShakeReply(this, 0); OnRegionHandShakeReply(this);
} }
} }
@ -1384,7 +1384,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
return 0; return 0;
} }
public void CheckViewerCaps() { } public uint GetViewerCaps()
{
return 0;
}
} }
} }

View File

@ -119,7 +119,7 @@ namespace OpenSim.Tests.Common
public event DeRezObject OnDeRezObject; public event DeRezObject OnDeRezObject;
public event RezRestoreToWorld OnRezRestoreToWorld; public event RezRestoreToWorld OnRezRestoreToWorld;
public event Action<IClientAPI, uint> OnRegionHandShakeReply; public event Action<IClientAPI> OnRegionHandShakeReply;
public event GenericCall1 OnRequestWearables; public event GenericCall1 OnRequestWearables;
public event Action<IClientAPI, bool> OnCompleteMovementToRegion; public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnPreAgentUpdate;
@ -880,7 +880,7 @@ namespace OpenSim.Tests.Common
{ {
if (OnRegionHandShakeReply != null) if (OnRegionHandShakeReply != null)
{ {
OnRegionHandShakeReply(this, 0); OnRegionHandShakeReply(this);
} }
} }
@ -1398,7 +1398,10 @@ namespace OpenSim.Tests.Common
{ {
} }
public void CheckViewerCaps() { } public uint GetViewerCaps()
{
return 0;
}
} }
} }