Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor

avinationmerge
Melanie 2011-04-30 14:23:20 +02:00
commit 27891fddcf
105 changed files with 1068 additions and 4465 deletions

View File

@ -1,34 +1,36 @@
The following people have contributed to OpenSim (Thank you The following people have contributed to OpenSim (Thank you
for your effort!) for your effort!)
Add your name in here if you have committed to OpenSim
= Current OpenSim Developers (in very rough order of appearance) = = Current OpenSim Developers (in very rough order of appearance) =
These folks represent the current core team for OpenSim, and are the These folks represent the current core team for OpenSim, and are the
people that make the day to day of OpenSim happen. people that make the day to day of OpenSim happen.
* justincc
* chi11ken (Genkii)
* dahlia
* Melanie Thielker
* Diva (Crista Lopes, University of California, Irvine)
* Dan Lake (Intel)
* Marck
* Mic Bowman (Intel)
* BlueWall (James Hughes)
= Core Developers Following the White Rabbit =
Core developers who have temporarily (we hope) gone chasing the white rabbit.
They are in all similar to the active core developers, except that they haven't
been that active lately, so their voting rights are awaiting their come back.
* MW (Tribal Media AB) * MW (Tribal Media AB)
* Adam Frisby (DeepThink Pty Ltd) * Adam Frisby (DeepThink Pty Ltd)
* MingChen (DeepThink Pty Ltd)
* lbsa71 (Tribal Media AB) * lbsa71 (Tribal Media AB)
* Sean Dague / sdague (IBM)
* Tedd
* justincc
* Teravus (w3z) * Teravus (w3z)
* Johan Berntsson (3Di)
* Ckrinke (Charles Krinke) * Ckrinke (Charles Krinke)
* chi11ken (Genkii)
* adjohn (Genkii)
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich) * Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
* dahlia
* mikem (3Di) * mikem (3Di)
* Melanie Thielker
* Homer_Horwitz * Homer_Horwitz
* idb (Ian Brown)
* Diva (Crista Lopes, University of California, Irvine)
* nlin (3Di) * nlin (3Di)
* Arthur Rodrigo S Valadares (IBM) * Arthur Rodrigo S Valadares (IBM)
* BlueWall (James Hughes) * John Hurliman
= Past Open Sim Developers = = Past Open Sim Developers =
These folks are alumns of the OpenSim core group, but are now These folks are alumns of the OpenSim core group, but are now
@ -44,6 +46,12 @@ where we are today.
* Dalien * Dalien
* Darok * Darok
* Alondria * Alondria
* Sean Dague / sdague (IBM)
* Tedd
* MingChen (DeepThink Pty Ltd)
* adjohn (Genkii)
* idb (Ian Brown)
* Johan Berntsson (3Di)
= Additional OpenSim Contributors = = Additional OpenSim Contributors =
@ -102,6 +110,7 @@ what it is today.
* Misterblue (Intel) * Misterblue (Intel)
* Mircea Kitsune * Mircea Kitsune
* mpallari * mpallari
* MrMonkE
* nornalbion * nornalbion
* Omar Vera Ustariz (IBM) * Omar Vera Ustariz (IBM)
* openlifegrid.com * openlifegrid.com

File diff suppressed because it is too large Load Diff

View File

@ -1,131 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Timers;
using log4net;
using MXP;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Client.MXP.PacketHandler;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Client.MXP
{
/**
* MXP Client Module which adds MXP support to client / region communication.
*/
public class MXPModule : IRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private MXPPacketServer m_server;
private IConfigSource m_config;
private int m_port = 1253;
private Timer m_ticker;
private readonly Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
private bool m_shutdown;
public void Initialise(Scene scene, IConfigSource source)
{
if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID))
m_scenes.Add(scene.RegionInfo.RegionID, scene);
m_config = source;
}
public void PostInitialise()
{
if (m_config.Configs["MXP"] != null)
{
IConfig con = m_config.Configs["MXP"];
if (!con.GetBoolean("Enabled", false))
return;
m_port = con.GetInt("Port", m_port);
m_server = new MXPPacketServer(m_port, m_scenes,m_config.Configs["StandAlone"].GetBoolean("accounts_authenticate",true));
m_ticker = new Timer(100);
m_ticker.AutoReset = false;
m_ticker.Elapsed += ticker_Elapsed;
lock (m_ticker)
m_ticker.Start();
m_log.Info("[MXP ClientStack] MXP Enabled and Listening");
}
}
void ticker_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
m_server.Process();
}
catch (Exception ex)
{
m_log.Error("[MXP ClientStack]: Unhandled exception in process loop: " + ex.ToString() + " :" + ex.StackTrace.ToString());
}
if (!m_shutdown)
{
lock (m_ticker)
m_ticker.Start();
}
}
public void Close()
{
m_shutdown = true;
if (m_ticker != null)
{
lock (m_ticker)
m_ticker.Stop();
}
}
public string Name
{
get { return "MXP ClientStack Module"; }
}
public bool IsSharedModule
{
get { return true; }
}
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
namespace OpenSim.Client.MXP
{
public static class MXPUtil
{
public static string GenerateMXPURL(string server, int port, UUID bubbleID, Vector3 location)
{
return string.Format("mxp://{0}:{1}/{2}/{3}", server, port, bubbleID.Guid, location);
}
}
}

View File

@ -1,561 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* This file borrows heavily from MXPServer.cs - the reference MXPServer
* See http://www.bubblecloud.org for a copy of the original file and
* implementation details. */
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using MXP;
using MXP.Messages;
using OpenMetaverse;
using OpenSim.Client.MXP.ClientStack;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Communications;
using OpenSim.Services.Interfaces;
using System.Security.Cryptography;
namespace OpenSim.Client.MXP.PacketHandler
{
public class MXPPacketServer
{
internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region Fields
private readonly List<MXPClientView> m_clients = new List<MXPClientView>();
private readonly Dictionary<UUID, Scene> m_scenes;
private readonly Transmitter m_transmitter;
// private readonly Thread m_clientThread;
private readonly IList<Session> m_sessions = new List<Session>();
private readonly IList<Session> m_sessionsToClient = new List<Session>();
private readonly IList<MXPClientView> m_sessionsToRemove = new List<MXPClientView>();
private readonly int m_port;
// private readonly bool m_accountsAuthenticate;
private readonly String m_programName;
private readonly byte m_programMajorVersion;
private readonly byte m_programMinorVersion;
#endregion
#region Constructors
public MXPPacketServer(int port, Dictionary<UUID, Scene> scenes, bool accountsAuthenticate)
{
m_port = port;
// m_accountsAuthenticate = accountsAuthenticate;
m_scenes = scenes;
m_programMinorVersion = 63;
m_programMajorVersion = 0;
m_programName = "OpenSimulator";
m_transmitter = new Transmitter(port);
StartListener();
}
public void StartListener()
{
m_log.Info("[MXP ClientStack] Transmitter starting on UDP server port: " + m_port);
m_transmitter.Startup();
m_log.Info("[MXP ClientStack] Transmitter started. MXP version: "+MxpConstants.ProtocolMajorVersion+"."+MxpConstants.ProtocolMinorVersion+" Source Revision: "+MxpConstants.ProtocolSourceRevision);
}
#endregion
#region Properties
/// <summary>
/// Number of sessions pending. (Process() accepts pending sessions).
/// </summary>
public int PendingSessionCount
{
get
{
return m_transmitter.PendingSessionCount;
}
}
/// <summary>
/// Number of connected sessions.
/// </summary>
public int SessionCount
{
get
{
return m_sessions.Count;
}
}
/// <summary>
/// Property reflecting whether client transmitter threads are alive.
/// </summary>
public bool IsTransmitterAlive
{
get
{
return m_transmitter != null && m_transmitter.IsAlive;
}
}
/// <summary>
/// Number of packets sent.
/// </summary>
public ulong PacketsSent
{
get
{
return m_transmitter != null ? m_transmitter.PacketsSent : 0;
}
}
/// <summary>
/// Number of packets received.
/// </summary>
public ulong PacketsReceived
{
get
{
return m_transmitter != null ? m_transmitter.PacketsReceived : 0;
}
}
/// <summary>
/// Bytes client has received so far.
/// </summary>
public ulong BytesReceived
{
get
{
return m_transmitter != null ? m_transmitter.BytesReceived : 0;
}
}
/// <summary>
/// Bytes client has sent so far.
/// </summary>
public ulong BytesSent
{
get
{
return m_transmitter != null ? m_transmitter.BytesSent : 0;
}
}
/// <summary>
/// Number of bytes received (bytes per second) during past second.
/// </summary>
public double ReceiveRate
{
get
{
return m_transmitter != null ? m_transmitter.ReceiveRate : 0;
}
}
/// <summary>
/// Number of bytes sent (bytes per second) during past second.
/// </summary>
public double SendRate
{
get
{
return m_transmitter != null ? m_transmitter.SendRate : 0;
}
}
#endregion
#region Session Management
public void Disconnect(Session session)
{
if (session.IsConnected)
{
Message message = MessageFactory.Current.ReserveMessage(typeof(LeaveRequestMessage));
session.Send(message);
MessageFactory.Current.ReleaseMessage(message);
}
else
{
throw new Exception("Not connected.");
}
}
#endregion
#region Processing
public void Process()
{
ProcessMessages();
Clean();
}
public void Clean()
{
foreach (MXPClientView clientView in m_clients)
{
if (clientView.Session.SessionState == SessionState.Disconnected)
{
m_sessionsToRemove.Add(clientView);
}
}
foreach (MXPClientView clientView in m_sessionsToRemove)
{
clientView.Scene.RemoveClient(clientView.AgentId);
clientView.OnClean();
m_clients.Remove(clientView);
m_sessions.Remove(clientView.Session);
}
m_sessionsToRemove.Clear();
}
public void ProcessMessages()
{
if (m_transmitter.PendingSessionCount > 0)
{
Session tmp = m_transmitter.AcceptPendingSession();
m_sessions.Add(tmp);
m_sessionsToClient.Add(tmp);
}
List<Session> tmpRemove = new List<Session>();
foreach (Session session in m_sessionsToClient)
{
while (session.AvailableMessages > 0)
{
Message message = session.Receive();
if (message.GetType() == typeof (JoinRequestMessage))
{
JoinRequestMessage joinRequestMessage = (JoinRequestMessage) message;
m_log.Info("[MXP ClientStack]: Session join request: " + session.SessionId + " (" +
(session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
session.RemoteEndPoint.Port + ")");
try
{
if (joinRequestMessage.BubbleId == Guid.Empty)
{
foreach (Scene scene in m_scenes.Values)
{
if (scene.RegionInfo.RegionName == joinRequestMessage.BubbleName)
{
m_log.Info("[MXP ClientStack]: Resolved region by name: " + joinRequestMessage.BubbleName + " (" + scene.RegionInfo.RegionID + ")");
joinRequestMessage.BubbleId = scene.RegionInfo.RegionID.Guid;
}
}
}
if (joinRequestMessage.BubbleId == Guid.Empty)
{
m_log.Warn("[MXP ClientStack]: Failed to resolve region by name: " + joinRequestMessage.BubbleName);
}
UUID sceneId = new UUID(joinRequestMessage.BubbleId);
bool regionExists = true;
if (!m_scenes.ContainsKey(sceneId))
{
m_log.Info("[MXP ClientStack]: No such region: " + sceneId);
regionExists = false;
}
UUID userId = UUID.Zero;
UserAccount account = null;
bool authorized = regionExists ? AuthoriseUser(joinRequestMessage.ParticipantName,
joinRequestMessage.ParticipantPassphrase,
new UUID(joinRequestMessage.BubbleId), out account)
: false;
if (authorized)
{
Scene scene = m_scenes[sceneId];
UUID mxpSessionID = UUID.Random();
string reason;
m_log.Debug("[MXP ClientStack]: Session join request success: " + session.SessionId + " (" +
(session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
session.RemoteEndPoint.Port + ")");
m_log.Debug("[MXP ClientStack]: Attaching UserAgent to UserProfile...");
UUID secureSession = UUID.Zero;
AttachUserAgentToUserProfile(account, session, mxpSessionID, sceneId, out secureSession);
m_log.Debug("[MXP ClientStack]: Attached UserAgent to UserProfile.");
m_log.Debug("[MXP ClientStack]: Preparing Scene to Connection...");
if (!PrepareSceneForConnection(mxpSessionID, secureSession, sceneId, account, out reason))
{
m_log.DebugFormat("[MXP ClientStack]: Scene refused connection: {0}", reason);
DeclineConnection(session, joinRequestMessage);
tmpRemove.Add(session);
continue;
}
m_log.Debug("[MXP ClientStack]: Prepared Scene to Connection.");
m_log.Debug("[MXP ClientStack]: Accepting connection...");
AcceptConnection(session, joinRequestMessage, mxpSessionID, userId);
m_log.Info("[MXP ClientStack]: Accepted connection.");
m_log.Debug("[MXP ClientStack]: Creating ClientView....");
MXPClientView client = new MXPClientView(session, mxpSessionID, userId, scene, account.FirstName, account.LastName);
m_clients.Add(client);
m_log.Debug("[MXP ClientStack]: Created ClientView.");
client.MXPSendSynchronizationBegin(m_scenes[new UUID(joinRequestMessage.BubbleId)].SceneContents.GetTotalObjectsCount());
m_log.Debug("[MXP ClientStack]: Starting ClientView...");
try
{
client.Start();
m_log.Debug("[MXP ClientStack]: Started ClientView.");
}
catch (Exception e)
{
m_log.Error(e);
}
m_log.Debug("[MXP ClientStack]: Connected");
}
else
{
m_log.Info("[MXP ClientStack]: Session join request failure: " + session.SessionId + " (" +
(session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
session.RemoteEndPoint.Port + ")");
DeclineConnection(session, joinRequestMessage);
}
}
catch (Exception e)
{
m_log.Error("[MXP ClientStack]: Session join request failure: " + session.SessionId + " (" +
(session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
session.RemoteEndPoint.Port + "): "+e.ToString()+" :"+e.StackTrace.ToString());
}
tmpRemove.Add(session);
}
}
}
foreach (Session session in tmpRemove)
{
m_sessionsToClient.Remove(session);
}
foreach (MXPClientView clientView in m_clients)
{
int messagesProcessedCount = 0;
Session session = clientView.Session;
while (session.AvailableMessages > 0)
{
Message message = session.Receive();
if (message.GetType() == typeof(LeaveRequestMessage))
{
LeaveResponseMessage leaveResponseMessage = (LeaveResponseMessage)MessageFactory.Current.ReserveMessage(
typeof(LeaveResponseMessage));
m_log.Debug("[MXP ClientStack]: Session leave request: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
leaveResponseMessage.RequestMessageId = message.MessageId;
leaveResponseMessage.FailureCode = 0;
session.Send(leaveResponseMessage);
if (session.SessionState != SessionState.Disconnected)
{
session.SetStateDisconnected();
}
m_log.Debug("[MXP ClientStack]: Removing Client from Scene");
//clientView.Scene.RemoveClient(clientView.AgentId);
}
if (message.GetType() == typeof(LeaveResponseMessage))
{
LeaveResponseMessage leaveResponseMessage = (LeaveResponseMessage)message;
m_log.Debug("[MXP ClientStack]: Session leave response: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
if (leaveResponseMessage.FailureCode == 0)
{
session.SetStateDisconnected();
}
m_log.Debug("[MXP ClientStack]: Removing Client from Scene");
//clientView.Scene.RemoveClient(clientView.AgentId);
}
else
{
clientView.MXPPRocessMessage(message);
}
MessageFactory.Current.ReleaseMessage(message);
messagesProcessedCount++;
if (messagesProcessedCount > 1000)
{
break;
}
}
}
}
private void AcceptConnection(Session session, JoinRequestMessage joinRequestMessage, UUID mxpSessionID, UUID userId)
{
JoinResponseMessage joinResponseMessage = (JoinResponseMessage)MessageFactory.Current.ReserveMessage(
typeof(JoinResponseMessage));
joinResponseMessage.RequestMessageId = joinRequestMessage.MessageId;
joinResponseMessage.FailureCode = MxpResponseCodes.SUCCESS;
joinResponseMessage.BubbleId = joinRequestMessage.BubbleId;
joinResponseMessage.ParticipantId = userId.Guid;
joinResponseMessage.AvatarId = userId.Guid;
joinResponseMessage.BubbleAssetCacheUrl = "http://" +
NetworkUtil.GetHostFor(session.RemoteEndPoint.Address,
m_scenes[
new UUID(joinRequestMessage.BubbleId)].
RegionInfo.
ExternalHostName) + ":" +
m_scenes[new UUID(joinRequestMessage.BubbleId)].RegionInfo.
HttpPort + "/assets/";
joinResponseMessage.BubbleName = m_scenes[new UUID(joinRequestMessage.BubbleId)].RegionInfo.RegionName;
joinResponseMessage.BubbleRange = 128;
joinResponseMessage.BubblePerceptionRange = 128 + 256;
joinResponseMessage.BubbleRealTime = 0;
joinResponseMessage.ProgramName = m_programName;
joinResponseMessage.ProgramMajorVersion = m_programMajorVersion;
joinResponseMessage.ProgramMinorVersion = m_programMinorVersion;
joinResponseMessage.ProtocolMajorVersion = MxpConstants.ProtocolMajorVersion;
joinResponseMessage.ProtocolMinorVersion = MxpConstants.ProtocolMinorVersion;
joinResponseMessage.ProtocolSourceRevision = MxpConstants.ProtocolSourceRevision;
session.Send(joinResponseMessage);
session.SetStateConnected();
}
private void DeclineConnection(Session session, Message joinRequestMessage)
{
JoinResponseMessage joinResponseMessage = (JoinResponseMessage)MessageFactory.Current.ReserveMessage(typeof(JoinResponseMessage));
joinResponseMessage.RequestMessageId = joinRequestMessage.MessageId;
joinResponseMessage.FailureCode = MxpResponseCodes.UNAUTHORIZED_OPERATION;
joinResponseMessage.ProgramName = m_programName;
joinResponseMessage.ProgramMajorVersion = m_programMajorVersion;
joinResponseMessage.ProgramMinorVersion = m_programMinorVersion;
joinResponseMessage.ProtocolMajorVersion = MxpConstants.ProtocolMajorVersion;
joinResponseMessage.ProtocolMinorVersion = MxpConstants.ProtocolMinorVersion;
joinResponseMessage.ProtocolSourceRevision = MxpConstants.ProtocolSourceRevision;
session.Send(joinResponseMessage);
session.SetStateDisconnected();
}
public bool AuthoriseUser(string participantName, string password, UUID sceneId, out UserAccount account)
{
string firstName = "";
string lastName = "";
account = null;
string[] nameParts = participantName.Split(' ');
if (nameParts.Length != 2)
{
m_log.Error("[MXP ClientStack]: Login failed as user name is not formed of first and last name separated by space: " + participantName);
return false;
}
firstName = nameParts[0];
lastName = nameParts[1];
account = m_scenes[sceneId].UserAccountService.GetUserAccount(m_scenes[sceneId].RegionInfo.ScopeID, firstName, lastName);
if (account != null)
return (m_scenes[sceneId].AuthenticationService.Authenticate(account.PrincipalID, password, 1) != string.Empty);
return false;
}
private void AttachUserAgentToUserProfile(UserAccount account, Session session, UUID sessionId, UUID sceneId, out UUID secureSessionId)
{
secureSessionId = UUID.Random();
Scene scene = m_scenes[sceneId];
scene.PresenceService.LoginAgent(account.PrincipalID.ToString(), sessionId, secureSessionId);
}
private bool PrepareSceneForConnection(UUID sessionId, UUID secureSessionId, UUID sceneId, UserAccount account, out string reason)
{
Scene scene = m_scenes[sceneId];
AgentCircuitData agent = new AgentCircuitData();
agent.AgentID = account.PrincipalID;
agent.firstname = account.FirstName;
agent.lastname = account.LastName;
agent.SessionID = sessionId;
agent.SecureSessionID = secureSessionId;
agent.circuitcode = sessionId.CRC();
agent.BaseFolder = UUID.Zero;
agent.InventoryFolder = UUID.Zero;
agent.startpos = new Vector3(0, 0, 0); // TODO Fill in region start position
agent.CapsPath = "http://localhost/";
agent.Appearance = scene.AvatarService.GetAppearance(account.PrincipalID);
if (agent.Appearance == null)
{
m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname);
agent.Appearance = new AvatarAppearance();
}
return scene.NewUserConnection(agent, 0, out reason);
}
public void PrintDebugInformation()
{
m_log.Info("[MXP ClientStack]: Statistics report");
m_log.Info("Pending Sessions: " + PendingSessionCount);
m_log.Info("Sessions: " + SessionCount + " (Clients: " + m_clients.Count + " )");
m_log.Info("Transmitter Alive?: " + IsTransmitterAlive);
m_log.Info("Packets Sent/Received: " + PacketsSent + " / " + PacketsReceived);
m_log.Info("Bytes Sent/Received: " + BytesSent + " / " + BytesReceived);
m_log.Info("Send/Receive Rate (bps): " + SendRate + " / " + ReceiveRate);
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Client.VWoHTTP.ClientStack;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Client.VWoHTTP
{
class VWoHTTPModule : IRegionModule, IHttpAgentHandler
{
private bool m_disabled = true;
private IHttpServer m_httpd;
private readonly List<Scene> m_scenes = new List<Scene>();
private Dictionary<UUID, VWHClientView> m_clients = new Dictionary<UUID, VWHClientView>();
#region Implementation of IRegionModule
public void Initialise(Scene scene, IConfigSource source)
{
if (m_disabled)
return;
m_scenes.Add(scene);
m_httpd = MainServer.Instance;
}
public void PostInitialise()
{
if (m_disabled)
return;
m_httpd.AddAgentHandler("vwohttp", this);
}
public void Close()
{
if (m_disabled)
return;
m_httpd.RemoveAgentHandler("vwohttp", this);
}
public string Name
{
get { return "VWoHTTP ClientStack"; }
}
public bool IsSharedModule
{
get { return true; }
}
#endregion
#region Implementation of IHttpAgentHandler
public bool Handle(OSHttpRequest req, OSHttpResponse resp)
{
string[] urlparts = req.Url.AbsolutePath.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
if (urlparts.Length < 2)
return false;
if (urlparts[1] == "connect")
{
UUID sessID = UUID.Random();
VWHClientView client = new VWHClientView(sessID, UUID.Random(), "VWoHTTPClient", m_scenes[0]);
m_clients.Add(sessID, client);
return true;
}
else
{
if (urlparts.Length < 3)
return false;
UUID sessionID;
if (!UUID.TryParse(urlparts[1], out sessionID))
return false;
if (!m_clients.ContainsKey(sessionID))
return false;
return m_clients[sessionID].ProcessInMsg(req, resp);
}
}
public bool Match(OSHttpRequest req, OSHttpResponse resp)
{
return req.Url.ToString().Contains("vwohttp");
}
#endregion
}
}

View File

@ -57,14 +57,14 @@ namespace OpenSim.Data.MSSQL
{ {
m_Realm = realm; m_Realm = realm;
m_ConnectionString = connectionString;
if (storeName != String.Empty) if (storeName != String.Empty)
{ {
Assembly assem = GetType().Assembly;
m_ConnectionString = connectionString;
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
{ {
conn.Open(); conn.Open();
Migration m = new Migration(conn, assem, storeName); Migration m = new Migration(conn, GetType().Assembly, storeName);
m.Update(); m.Update();
} }

View File

@ -61,7 +61,8 @@ namespace OpenSim.Data.MSSQL
} }
catch catch
{ {
// Something went wrong, so we're version 0 // Return -1 to indicate table does not exist
return -1;
} }
} }
return version; return version;

View File

@ -492,12 +492,11 @@ ELSE
using (SqlConnection conn = new SqlConnection(m_connectionString)) using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn)) using (SqlCommand cmd = new SqlCommand(sql, conn))
{ {
conn.Open();
foreach (TaskInventoryItem taskItem in items) foreach (TaskInventoryItem taskItem in items)
{ {
cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem)); cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem));
conn.Open();
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
cmd.Parameters.Clear(); cmd.Parameters.Clear();
} }
} }
@ -1154,9 +1153,9 @@ VALUES
PrimitiveBaseShape baseShape = new PrimitiveBaseShape(); PrimitiveBaseShape baseShape = new PrimitiveBaseShape();
baseShape.Scale = new Vector3( baseShape.Scale = new Vector3(
Convert.ToSingle(shapeRow["ScaleX"]), (float)Convert.ToDouble(shapeRow["ScaleX"]),
Convert.ToSingle(shapeRow["ScaleY"]), (float)Convert.ToDouble(shapeRow["ScaleY"]),
Convert.ToSingle(shapeRow["ScaleZ"])); (float)Convert.ToDouble(shapeRow["ScaleZ"]));
// paths // paths
baseShape.PCode = Convert.ToByte(shapeRow["PCode"]); baseShape.PCode = Convert.ToByte(shapeRow["PCode"]);
@ -1194,7 +1193,10 @@ VALUES
} }
if (!(shapeRow["Media"] is System.DBNull) ) if (!(shapeRow["Media"] is System.DBNull) )
{
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]); baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
}
return baseShape; return baseShape;
} }
@ -1573,7 +1575,16 @@ VALUES
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry)); parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
parameters.Add(_Database.CreateParameter("State", s.State)); parameters.Add(_Database.CreateParameter("State", s.State));
parameters.Add(_Database.CreateParameter("Media", null == s.Media ? null : s.Media.ToXml()));
if(null == s.Media )
{
parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
}
else
{
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
}
return parameters.ToArray(); return parameters.ToArray();
} }

View File

@ -22,7 +22,11 @@ COMMIT
BEGIN TRANSACTION BEGIN TRANSACTION
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND type in (N'U'))
INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey, accountType) SELECT [UUID] AS UUID, [passwordHash] AS passwordHash, [passwordSalt] AS passwordSalt, [webLoginKey] AS webLoginKey, 'UserAccount' as [accountType] FROM users; INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey, accountType) SELECT [UUID] AS UUID, [passwordHash] AS passwordHash, [passwordSalt] AS passwordSalt, [webLoginKey] AS webLoginKey, 'UserAccount' as [accountType] FROM users;
COMMIT COMMIT

View File

@ -13,5 +13,28 @@ PRIMARY KEY CLUSTERED
) ON [PRIMARY] ) ON [PRIMARY]
COMMIT
:VERSION 2
BEGIN TRANSACTION
CREATE TABLE dbo.Tmp_Avatars
(
PrincipalID uniqueidentifier NOT NULL,
[Name] varchar(32) NOT NULL,
Value text NOT NULL DEFAULT '',
) ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
IF EXISTS(SELECT * FROM dbo.Avatars)
EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
DROP TABLE dbo.Avatars
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
COMMIT COMMIT

View File

@ -15,6 +15,8 @@ COMMIT
BEGIN TRANSACTION BEGIN TRANSACTION
INSERT INTO Friends (PrincipalID, Friend, Flags, Offered) SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends; IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[userfriends]') AND type in (N'U'))
INSERT INTO Friends (PrincipalID, Friend, Flags, Offered)
SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends;
COMMIT COMMIT

View File

@ -222,4 +222,17 @@ ALTER TABLE [regions] ADD [Token] varchar(255) NOT NULL DEFAULT 0;
COMMIT COMMIT
:VERSION 8
BEGIN TRANSACTION
ALTER TABLE regions ALTER COLUMN regionName VarChar(128)
DROP INDEX IX_regions_name ON dbo.regions
ALTER TABLE regions ALTER COLUMN regionName VarChar(128) null
CREATE NONCLUSTERED INDEX IX_regions_name ON dbo.regions
(
regionName
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
COMMIT

View File

@ -238,7 +238,10 @@ alter table inventoryitems
COMMIT COMMIT
:VERSION 8
ALTER TABLE inventoryitems
ADD CONSTRAINT DF_inventoryitems_creatorID
DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID
:GO

View File

@ -7,14 +7,7 @@ CREATE TABLE [Presence] (
[RegionID] uniqueidentifier NOT NULL, [RegionID] uniqueidentifier NOT NULL,
[SessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', [SessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
[SecureSessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', [SecureSessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
[Online] char(5) NOT NULL DEFAULT 'false',
[Login] char(16) NOT NULL DEFAULT '0',
[Logout] char(16) NOT NULL DEFAULT '0',
[Position] char(64) NOT NULL DEFAULT '<0,0,0>',
[LookAt] char(64) NOT NULL DEFAULT '<0,0,0>',
[HomeRegionID] uniqueidentifier NOT NULL,
[HomePosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
[HomeLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
) )
ON [PRIMARY] ON [PRIMARY]
@ -28,3 +21,11 @@ CREATE UNIQUE INDEX SessionID ON Presence(SessionID);
CREATE INDEX UserID ON Presence(UserID); CREATE INDEX UserID ON Presence(UserID);
COMMIT COMMIT
:VERSION 2
BEGIN TRANSACTION
ALTER TABLE Presence ADD LastSeen DateTime
COMMIT

View File

@ -1,4 +1,3 @@
:VERSION 1 :VERSION 1
CREATE TABLE [dbo].[prims]( CREATE TABLE [dbo].[prims](
@ -926,11 +925,121 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
COMMIT COMMIT
:VERSION 24 :VERSION 24
-- Added post 0.7
BEGIN TRANSACTION BEGIN TRANSACTION
ALTER TABLE prims ADD COLUMN MediaURL varchar(255) ALTER TABLE prims ADD MediaURL varchar(255)
ALTER TABLE primshapes ADD COLUMN Media TEXT ALTER TABLE primshapes ADD Media TEXT NULL
COMMIT
:VERSION 25
BEGIN TRANSACTION
CREATE TABLE "regionwindlight" (
"region_id" varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
"water_color_r" [float] NOT NULL DEFAULT '4.000000',
"water_color_g" [float] NOT NULL DEFAULT '38.000000',
"water_color_b" [float] NOT NULL DEFAULT '64.000000',
"water_fog_density_exponent" [float] NOT NULL DEFAULT '4.0',
"underwater_fog_modifier" [float] NOT NULL DEFAULT '0.25',
"reflection_wavelet_scale_1" [float] NOT NULL DEFAULT '2.0',
"reflection_wavelet_scale_2" [float] NOT NULL DEFAULT '2.0',
"reflection_wavelet_scale_3" [float] NOT NULL DEFAULT '2.0',
"fresnel_scale" [float] NOT NULL DEFAULT '0.40',
"fresnel_offset" [float] NOT NULL DEFAULT '0.50',
"refract_scale_above" [float] NOT NULL DEFAULT '0.03',
"refract_scale_below" [float] NOT NULL DEFAULT '0.20',
"blur_multiplier" [float] NOT NULL DEFAULT '0.040',
"big_wave_direction_x" [float] NOT NULL DEFAULT '1.05',
"big_wave_direction_y" [float] NOT NULL DEFAULT '-0.42',
"little_wave_direction_x" [float] NOT NULL DEFAULT '1.11',
"little_wave_direction_y" [float] NOT NULL DEFAULT '-1.16',
"normal_map_texture" varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
"horizon_r" [float] NOT NULL DEFAULT '0.25',
"horizon_g" [float] NOT NULL DEFAULT '0.25',
"horizon_b" [float] NOT NULL DEFAULT '0.32',
"horizon_i" [float] NOT NULL DEFAULT '0.32',
"haze_horizon" [float] NOT NULL DEFAULT '0.19',
"blue_density_r" [float] NOT NULL DEFAULT '0.12',
"blue_density_g" [float] NOT NULL DEFAULT '0.22',
"blue_density_b" [float] NOT NULL DEFAULT '0.38',
"blue_density_i" [float] NOT NULL DEFAULT '0.38',
"haze_density" [float] NOT NULL DEFAULT '0.70',
"density_multiplier" [float] NOT NULL DEFAULT '0.18',
"distance_multiplier" [float] NOT NULL DEFAULT '0.8',
"max_altitude" int NOT NULL DEFAULT '1605',
"sun_moon_color_r" [float] NOT NULL DEFAULT '0.24',
"sun_moon_color_g" [float] NOT NULL DEFAULT '0.26',
"sun_moon_color_b" [float] NOT NULL DEFAULT '0.30',
"sun_moon_color_i" [float] NOT NULL DEFAULT '0.30',
"sun_moon_position" [float] NOT NULL DEFAULT '0.317',
"ambient_r" [float] NOT NULL DEFAULT '0.35',
"ambient_g" [float] NOT NULL DEFAULT '0.35',
"ambient_b" [float] NOT NULL DEFAULT '0.35',
"ambient_i" [float] NOT NULL DEFAULT '0.35',
"east_angle" [float] NOT NULL DEFAULT '0.00',
"sun_glow_focus" [float] NOT NULL DEFAULT '0.10',
"sun_glow_size" [float] NOT NULL DEFAULT '1.75',
"scene_gamma" [float] NOT NULL DEFAULT '1.00',
"star_brightness" [float] NOT NULL DEFAULT '0.00',
"cloud_color_r" [float] NOT NULL DEFAULT '0.41',
"cloud_color_g" [float] NOT NULL DEFAULT '0.41',
"cloud_color_b" [float] NOT NULL DEFAULT '0.41',
"cloud_color_i" [float] NOT NULL DEFAULT '0.41',
"cloud_x" [float] NOT NULL DEFAULT '1.00',
"cloud_y" [float] NOT NULL DEFAULT '0.53',
"cloud_density" [float] NOT NULL DEFAULT '1.00',
"cloud_coverage" [float] NOT NULL DEFAULT '0.27',
"cloud_scale" [float] NOT NULL DEFAULT '0.42',
"cloud_detail_x" [float] NOT NULL DEFAULT '1.00',
"cloud_detail_y" [float] NOT NULL DEFAULT '0.53',
"cloud_detail_density" [float] NOT NULL DEFAULT '0.12',
"cloud_scroll_x" [float] NOT NULL DEFAULT '0.20',
"cloud_scroll_x_lock" tinyint NOT NULL DEFAULT '0',
"cloud_scroll_y" [float] NOT NULL DEFAULT '0.01',
"cloud_scroll_y_lock" tinyint NOT NULL DEFAULT '0',
"draw_classic_clouds" tinyint NOT NULL DEFAULT '1',
PRIMARY KEY ("region_id")
)
COMMIT TRANSACTION
:VERSION 26
BEGIN TRANSACTION
ALTER TABLE regionsettings ADD map_tile_ID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'
COMMIT
:VERSION 27 #---------------------
BEGIN TRANSACTION
ALTER TABLE land ADD MediaType VARCHAR(32) NOT NULL DEFAULT 'none/none'
ALTER TABLE land ADD MediaDescription VARCHAR(255) NOT NULL DEFAULT ''
ALTER TABLE land ADD MediaSize VARCHAR(16) NOT NULL DEFAULT '0,0'
ALTER TABLE land ADD MediaLoop bit NOT NULL DEFAULT 0
ALTER TABLE land ADD ObscureMusic bit NOT NULL DEFAULT 0
ALTER TABLE land ADD ObscureMedia bit NOT NULL DEFAULT 0
COMMIT
:VERSION 28 #---------------------
BEGIN TRANSACTION
ALTER TABLE prims
ADD CONSTRAINT DF_prims_CreatorID
DEFAULT '00000000-0000-0000-0000-000000000000'
FOR CreatorID
ALTER TABLE prims ALTER COLUMN CreatorID uniqueidentifier NOT NULL
ALTER TABLE primitems
ADD CONSTRAINT DF_primitems_CreatorID
DEFAULT '00000000-0000-0000-0000-000000000000'
FOR CreatorID
ALTER TABLE primitems ALTER COLUMN CreatorID uniqueidentifier NOT NULL
COMMIT COMMIT

View File

@ -19,7 +19,7 @@ CREATE TABLE [UserAccounts] (
:VERSION 2 :VERSION 2
BEGIN TRANSACTION BEGIN TRANSACTION
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND type in (N'U'))
INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT [UUID] AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT [UUID] AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID,
username AS FirstName, username AS FirstName,
lastname AS LastName, lastname AS LastName,

View File

@ -151,27 +151,6 @@ namespace OpenSim.Framework
{ {
} }
/// <summary>
/// Create AgentCircuitData from a Serializable AgentCircuitData
/// </summary>
/// <param name="cAgent"></param>
public AgentCircuitData(sAgentCircuitData cAgent)
{
AgentID = new UUID(cAgent.AgentID);
SessionID = new UUID(cAgent.SessionID);
SecureSessionID = new UUID(cAgent.SecureSessionID);
startpos = new Vector3(cAgent.startposx, cAgent.startposy, cAgent.startposz);
firstname = cAgent.firstname;
lastname = cAgent.lastname;
circuitcode = cAgent.circuitcode;
child = cAgent.child;
InventoryFolder = new UUID(cAgent.InventoryFolder);
BaseFolder = new UUID(cAgent.BaseFolder);
CapsPath = cAgent.CapsPath;
ChildrenCapSeeds = cAgent.ChildrenCapSeeds;
Viewer = cAgent.Viewer;
}
/// <summary> /// <summary>
/// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json
/// </summary> /// </summary>
@ -369,52 +348,4 @@ namespace OpenSim.Framework
} }
/// <summary>
/// Serializable Agent Circuit Data
/// </summary>
[Serializable]
public class sAgentCircuitData
{
public Guid AgentID;
public Guid BaseFolder;
public string CapsPath = String.Empty;
public Dictionary<ulong, string> ChildrenCapSeeds;
public bool child;
public uint circuitcode;
public string firstname;
public Guid InventoryFolder;
public string lastname;
public Guid SecureSessionID;
public Guid SessionID;
public float startposx;
public float startposy;
public float startposz;
public string Viewer;
public string Channel;
public string Mac;
public string Id0;
public sAgentCircuitData()
{
}
public sAgentCircuitData(AgentCircuitData cAgent)
{
AgentID = cAgent.AgentID.Guid;
SessionID = cAgent.SessionID.Guid;
SecureSessionID = cAgent.SecureSessionID.Guid;
startposx = cAgent.startpos.X;
startposy = cAgent.startpos.Y;
startposz = cAgent.startpos.Z;
firstname = cAgent.firstname;
lastname = cAgent.lastname;
circuitcode = cAgent.circuitcode;
child = cAgent.child;
InventoryFolder = cAgent.InventoryFolder.Guid;
BaseFolder = cAgent.BaseFolder.Guid;
CapsPath = cAgent.CapsPath;
ChildrenCapSeeds = cAgent.ChildrenCapSeeds;
Viewer = cAgent.Viewer;
}
}
} }

View File

@ -62,7 +62,7 @@ namespace OpenSim.Framework
UUID AgentID { get; set; } UUID AgentID { get; set; }
OSDMap Pack(); OSDMap Pack();
void Unpack(OSDMap map); void Unpack(OSDMap map, IScene scene);
} }
/// <summary> /// <summary>
@ -122,7 +122,7 @@ namespace OpenSim.Framework
return args; return args;
} }
public void Unpack(OSDMap args) public void Unpack(OSDMap args, IScene scene)
{ {
if (args.ContainsKey("region_handle")) if (args.ContainsKey("region_handle"))
UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle);
@ -329,6 +329,10 @@ namespace OpenSim.Framework
public string CallbackURI; public string CallbackURI;
// These two must have the same Count
public List<ISceneObject> AttachmentObjects;
public List<string> AttachmentObjectStates;
public virtual OSDMap Pack() public virtual OSDMap Pack()
{ {
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
@ -441,7 +445,30 @@ namespace OpenSim.Framework
if ((CallbackURI != null) && (!CallbackURI.Equals(""))) if ((CallbackURI != null) && (!CallbackURI.Equals("")))
args["callback_uri"] = OSD.FromString(CallbackURI); args["callback_uri"] = OSD.FromString(CallbackURI);
// Attachment objects for fatpack messages
if (AttachmentObjects != null)
{
int i = 0;
OSDArray attObjs = new OSDArray(AttachmentObjects.Count);
foreach (ISceneObject so in AttachmentObjects)
{
OSDMap info = new OSDMap(4);
info["sog"] = OSD.FromString(so.ToXml2());
info["extra"] = OSD.FromString(so.ExtraToXmlString());
info["modified"] = OSD.FromBoolean(so.HasGroupChanged);
try
{
info["state"] = OSD.FromString(AttachmentObjectStates[i++]);
}
catch (IndexOutOfRangeException e)
{
m_log.WarnFormat("[CHILD AGENT DATA]: scrtips list is shorter than object list.");
}
attObjs.Add(info);
}
args["attach_objects"] = attObjs;
}
return args; return args;
} }
@ -450,7 +477,7 @@ namespace OpenSim.Framework
/// Avoiding reflection makes it painful to write, but that's the price! /// Avoiding reflection makes it painful to write, but that's the price!
/// </summary> /// </summary>
/// <param name="hash"></param> /// <param name="hash"></param>
public virtual void Unpack(OSDMap args) public virtual void Unpack(OSDMap args, IScene scene)
{ {
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data");
@ -628,6 +655,26 @@ namespace OpenSim.Framework
if (args["callback_uri"] != null) if (args["callback_uri"] != null)
CallbackURI = args["callback_uri"].AsString(); CallbackURI = args["callback_uri"].AsString();
// Attachment objects
if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array)
{
OSDArray attObjs = (OSDArray)(args["attach_objects"]);
AttachmentObjects = new List<ISceneObject>();
AttachmentObjectStates = new List<string>();
foreach (OSD o in attObjs)
{
if (o.Type == OSDType.Map)
{
OSDMap info = (OSDMap)o;
ISceneObject so = scene.DeserializeObject(info["sog"].AsString());
so.ExtraFromXmlString(info["extra"].AsString());
so.HasGroupChanged = info["modified"].AsBoolean();
AttachmentObjects.Add(so);
AttachmentObjectStates.Add(info["state"].AsString());
}
}
}
} }
public AgentData() public AgentData()
@ -655,9 +702,9 @@ namespace OpenSim.Framework
return base.Pack(); return base.Pack();
} }
public override void Unpack(OSDMap map) public override void Unpack(OSDMap map, IScene scene)
{ {
base.Unpack(map); base.Unpack(map, scene);
} }
} }
} }

View File

@ -31,10 +31,9 @@ using System.Net;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
[Serializable]
public class ClientInfo public class ClientInfo
{ {
public sAgentCircuitData agentcircuit; public AgentCircuitData agentcircuit;
public Dictionary<uint, byte[]> needAck; public Dictionary<uint, byte[]> needAck;

View File

@ -42,22 +42,40 @@ namespace OpenSim.Framework
public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity);
// Heap[0] for self updates /// <summary>
// Heap[1..12] for entity updates /// Total number of queues (priorities) available
/// </summary>
public const uint NumberOfQueues = 12; public const uint NumberOfQueues = 12;
public const uint ImmediateQueue = 0;
/// <summary>
/// Number of queuest (priorities) that are processed immediately
/// </summary.
public const uint NumberOfImmediateQueues = 2;
private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues]; private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues];
private Dictionary<uint, LookupItem> m_lookupTable; private Dictionary<uint, LookupItem> m_lookupTable;
// internal state used to ensure the deqeues are spread across the priority
// queues "fairly". queuecounts is the amount to pull from each queue in
// each pass. weighted towards the higher priority queues
private uint m_nextQueue = 0; private uint m_nextQueue = 0;
private uint m_countFromQueue = 0;
private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 };
// next request is a counter of the number of updates queued, it provides
// a total ordering on the updates coming through the queue and is more
// lightweight (and more discriminating) than tick count
private UInt64 m_nextRequest = 0; private UInt64 m_nextRequest = 0;
/// <summary>
/// Lock for enqueue and dequeue operations on the priority queue
/// </summary>
private object m_syncRoot = new object(); private object m_syncRoot = new object();
public object SyncRoot { public object SyncRoot {
get { return this.m_syncRoot; } get { return this.m_syncRoot; }
} }
#region constructor
public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { }
public PriorityQueue(int capacity) public PriorityQueue(int capacity)
@ -66,8 +84,16 @@ namespace OpenSim.Framework
for (int i = 0; i < m_heaps.Length; ++i) for (int i = 0; i < m_heaps.Length; ++i)
m_heaps[i] = new MinHeap<MinHeapItem>(capacity); m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
}
m_nextQueue = NumberOfImmediateQueues;
m_countFromQueue = m_queueCounts[m_nextQueue];
}
#endregion Constructor
#region PublicMethods
/// <summary>
/// Return the number of items in the queues
/// </summary>
public int Count public int Count
{ {
get get
@ -75,10 +101,14 @@ namespace OpenSim.Framework
int count = 0; int count = 0;
for (int i = 0; i < m_heaps.Length; ++i) for (int i = 0; i < m_heaps.Length; ++i)
count += m_heaps[i].Count; count += m_heaps[i].Count;
return count; return count;
} }
} }
/// <summary>
/// Enqueue an item into the specified priority queue
/// </summary>
public bool Enqueue(uint pqueue, IEntityUpdate value) public bool Enqueue(uint pqueue, IEntityUpdate value)
{ {
LookupItem lookup; LookupItem lookup;
@ -100,13 +130,40 @@ namespace OpenSim.Framework
return true; return true;
} }
/// <summary>
/// Remove an item from one of the queues. Specifically, it removes the
/// oldest item from the next queue in order to provide fair access to
/// all of the queues
/// </summary>
public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
{ {
// If there is anything in priority queue 0, return it first no // If there is anything in priority queue 0, return it first no
// matter what else. Breaks fairness. But very useful. // matter what else. Breaks fairness. But very useful.
if (m_heaps[ImmediateQueue].Count > 0) for (int iq = 0; iq < NumberOfImmediateQueues; iq++)
{ {
MinHeapItem item = m_heaps[ImmediateQueue].RemoveMin(); if (m_heaps[iq].Count > 0)
{
MinHeapItem item = m_heaps[iq].RemoveMin();
m_lookupTable.Remove(item.Value.Entity.LocalId);
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
value = item.Value;
return true;
}
}
// To get the fair queing, we cycle through each of the
// queues when finding an element to dequeue.
// We pull (NumberOfQueues - QueueIndex) items from each queue in order
// to give lower numbered queues a higher priority and higher percentage
// of the bandwidth.
// Check for more items to be pulled from the current queue
if (m_heaps[m_nextQueue].Count > 0 && m_countFromQueue > 0)
{
m_countFromQueue--;
MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
m_lookupTable.Remove(item.Value.Entity.LocalId); m_lookupTable.Remove(item.Value.Entity.LocalId);
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
value = item.Value; value = item.Value;
@ -114,18 +171,21 @@ namespace OpenSim.Framework
return true; return true;
} }
// Find the next non-immediate queue with updates in it
for (int i = 0; i < NumberOfQueues; ++i) for (int i = 0; i < NumberOfQueues; ++i)
{ {
// To get the fair queing, we cycle through each of the m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues);
// queues when finding an element to dequeue, this code m_countFromQueue = m_queueCounts[m_nextQueue];
// assumes that the distribution of updates in the queues
// is polynomial, probably quadractic (eg distance of PI * R^2)
uint h = (uint)((m_nextQueue + i) % NumberOfQueues);
if (m_heaps[h].Count > 0)
{
m_nextQueue = (uint)((h + 1) % NumberOfQueues);
MinHeapItem item = m_heaps[h].RemoveMin(); // if this is one of the immediate queues, just skip it
if (m_nextQueue < NumberOfImmediateQueues)
continue;
if (m_heaps[m_nextQueue].Count > 0)
{
m_countFromQueue--;
MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
m_lookupTable.Remove(item.Value.Entity.LocalId); m_lookupTable.Remove(item.Value.Entity.LocalId);
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
value = item.Value; value = item.Value;
@ -139,6 +199,10 @@ namespace OpenSim.Framework
return false; return false;
} }
/// <summary>
/// Reapply the prioritization function to each of the updates currently
/// stored in the priority queues.
/// </summary
public void Reprioritize(UpdatePriorityHandler handler) public void Reprioritize(UpdatePriorityHandler handler)
{ {
MinHeapItem item; MinHeapItem item;
@ -174,17 +238,18 @@ namespace OpenSim.Framework
} }
} }
/// <summary>
/// </summary>
public override string ToString() public override string ToString()
{ {
string s = ""; string s = "";
for (int i = 0; i < NumberOfQueues; i++) for (int i = 0; i < NumberOfQueues; i++)
{ s += String.Format("{0,7} ",m_heaps[i].Count);
if (s != "") s += ",";
s += m_heaps[i].Count.ToString();
}
return s; return s;
} }
#endregion PublicMethods
#region MinHeapItem #region MinHeapItem
private struct MinHeapItem : IComparable<MinHeapItem> private struct MinHeapItem : IComparable<MinHeapItem>
{ {

View File

@ -115,7 +115,7 @@ namespace OpenSim.Framework.Tests
position2 = new AgentPosition(); position2 = new AgentPosition();
Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition");
position2.Unpack(position1.Pack()); position2.Unpack(position1.Pack(), null);
Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed");
Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed");

View File

@ -394,6 +394,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
/// <summary>
/// Entity update queues
/// </summary>
public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } }
/// <summary> /// <summary>
/// First name of the agent/avatar represented by the client /// First name of the agent/avatar represented by the client
/// </summary> /// </summary>
@ -3625,7 +3630,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Remove the update packet from the list of packets waiting for acknowledgement // Remove the update packet from the list of packets waiting for acknowledgement
// because we are requeuing the list of updates. They will be resent in new packets // because we are requeuing the list of updates. They will be resent in new packets
// with the most recent state and priority. // with the most recent state and priority.
m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true); m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
// Count this as a resent packet since we are going to requeue all of the updates contained in it
Interlocked.Increment(ref m_udpClient.PacketsResent);
foreach (EntityUpdate update in updates) foreach (EntityUpdate update in updates)
ResendPrimUpdate(update); ResendPrimUpdate(update);
} }
@ -4092,7 +4101,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Remove the update packet from the list of packets waiting for acknowledgement // Remove the update packet from the list of packets waiting for acknowledgement
// because we are requeuing the list of updates. They will be resent in new packets // because we are requeuing the list of updates. They will be resent in new packets
// with the most recent state. // with the most recent state.
m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true); m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
// Count this as a resent packet since we are going to requeue all of the updates contained in it
Interlocked.Increment(ref m_udpClient.PacketsResent);
foreach (ObjectPropertyUpdate update in updates) foreach (ObjectPropertyUpdate update in updates)
ResendPropertyUpdate(update); ResendPropertyUpdate(update);
} }
@ -4897,7 +4910,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
data.RelativePosition.ToBytes(objectData, 0); data.RelativePosition.ToBytes(objectData, 0);
data.Velocity.ToBytes(objectData, 12); data.Velocity.ToBytes(objectData, 12);
data.Acceleration.ToBytes(objectData, 24); data.Acceleration.ToBytes(objectData, 24);
try
{
data.RotationOffset.ToBytes(objectData, 36); data.RotationOffset.ToBytes(objectData, 36);
}
catch (Exception e)
{
m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString());
OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36);
}
data.AngularVelocity.ToBytes(objectData, 48); data.AngularVelocity.ToBytes(objectData, 48);
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@ -11513,7 +11534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <returns></returns> /// <returns></returns>
public byte[] GetThrottlesPacked(float multiplier) public byte[] GetThrottlesPacked(float multiplier)
{ {
return m_udpClient.GetThrottlesPacked(); return m_udpClient.GetThrottlesPacked(multiplier);
} }
/// <summary> /// <summary>
@ -11706,7 +11727,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
info.userEP = m_userEndPoint; info.userEP = m_userEndPoint;
info.proxyEP = null; info.proxyEP = null;
info.agentcircuit = new sAgentCircuitData(RequestClientInfo()); info.agentcircuit = RequestClientInfo();
return info; return info;
} }

View File

@ -182,9 +182,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_maxRTO = maxRTO; m_maxRTO = maxRTO;
// Create a token bucket throttle for this client that has the scene token bucket as a parent // Create a token bucket throttle for this client that has the scene token bucket as a parent
m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.TotalLimit); m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
// Create a token bucket throttle for the total categary with the client bucket as a throttle // Create a token bucket throttle for the total categary with the client bucket as a throttle
m_throttleCategory = new TokenBucket(m_throttleClient, rates.TotalLimit); m_throttleCategory = new TokenBucket(m_throttleClient, 0);
// Create an array of token buckets for this clients different throttle categories // Create an array of token buckets for this clients different throttle categories
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
@ -195,7 +195,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Initialize the packet outboxes, where packets sit while they are waiting for tokens // Initialize the packet outboxes, where packets sit while they are waiting for tokens
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
// Initialize the token buckets that control the throttling for each category // Initialize the token buckets that control the throttling for each category
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetLimit(type)); m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
} }
// Default the retransmission timeout to three seconds // Default the retransmission timeout to three seconds
@ -229,26 +229,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <returns>Information about the client connection</returns> /// <returns>Information about the client connection</returns>
public ClientInfo GetClientInfo() public ClientInfo GetClientInfo()
{ {
///<mic>
TokenBucket tb;
tb = m_throttleClient.Parent;
m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest,"ROOT");
tb = m_throttleClient;
m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CLIENT");
tb = m_throttleCategory;
m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CATEGORY");
for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
{
tb = m_throttleCategories[i];
m_log.WarnFormat("[TOKENS] {4} <{0}:{1}>: Actual={2},Requested={3}",AgentID,i,tb.DripRate,tb.RequestedDripRate," BUCKET");
}
///</mic>
// TODO: This data structure is wrong in so many ways. Locking and copying the entire lists // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists
// of pending and needed ACKs for every client every time some method wants information about // of pending and needed ACKs for every client every time some method wants information about
// this connection is a recipe for poor performance // this connection is a recipe for poor performance
@ -260,12 +240,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate;
info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate;
info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate;
// info.taskThrottle = m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate + m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + info.totalThrottle = (int)m_throttleCategory.DripRate;
info.taskThrottle + info.assetThrottle + info.textureThrottle;
return info; return info;
} }
@ -352,8 +330,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
// State is a subcategory of task that we allocate a percentage to // State is a subcategory of task that we allocate a percentage to
int state = 0; int state = 0;
// int state = (int)((float)task * STATE_TASK_PERCENTAGE);
// task -= state;
// Make sure none of the throttles are set below our packet MTU, // Make sure none of the throttles are set below our packet MTU,
// otherwise a throttle could become permanently clogged // otherwise a throttle could become permanently clogged
@ -364,19 +340,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
task = Math.Max(task, LLUDPServer.MTU); task = Math.Max(task, LLUDPServer.MTU);
texture = Math.Max(texture, LLUDPServer.MTU); texture = Math.Max(texture, LLUDPServer.MTU);
asset = Math.Max(asset, LLUDPServer.MTU); asset = Math.Max(asset, LLUDPServer.MTU);
state = Math.Max(state, LLUDPServer.MTU);
int total = resend + land + wind + cloud + task + texture + asset + state; //int total = resend + land + wind + cloud + task + texture + asset;
//m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}",
//m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", // AgentID, resend, land, wind, cloud, task, texture, asset, total);
// AgentID, resend, land, wind, cloud, task, texture, asset, state, total);
// Update the token buckets with new throttle values // Update the token buckets with new throttle values
TokenBucket bucket; TokenBucket bucket;
bucket = m_throttleCategory;
bucket.RequestedDripRate = total;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
bucket.RequestedDripRate = resend; bucket.RequestedDripRate = resend;
@ -405,22 +376,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_packedThrottles = null; m_packedThrottles = null;
} }
public byte[] GetThrottlesPacked() public byte[] GetThrottlesPacked(float multiplier)
{ {
byte[] data = m_packedThrottles; byte[] data = m_packedThrottles;
if (data == null) if (data == null)
{ {
float rate;
data = new byte[7 * 4]; data = new byte[7 * 4];
int i = 0; int i = 0;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate), 0, data, i, 4); i += 4; // multiply by 8 to convert bytes back to bits
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate), 0, data, i, 4); i += 4; rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate * 8 * multiplier;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate), 0, data, i, 4); i += 4; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate), 0, data, i, 4); i += 4;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate), 0, data, i, 4); i += 4; rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate * 8 * multiplier;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate), 0, data, i, 4); i += 4; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate), 0, data, i, 4); i += 4;
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate * 8 * multiplier;
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate * 8 * multiplier;
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate * 8 * multiplier;
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate * 8 * multiplier;
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate * 8 * multiplier;
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
m_packedThrottles = data; m_packedThrottles = data;
} }

View File

@ -672,7 +672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Header.AppendedAcks && packet.Header.AckList != null) if (packet.Header.AppendedAcks && packet.Header.AckList != null)
{ {
for (int i = 0; i < packet.Header.AckList.Length; i++) for (int i = 0; i < packet.Header.AckList.Length; i++)
udpClient.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent); udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
} }
// Handle PacketAck packets // Handle PacketAck packets
@ -681,7 +681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
PacketAckPacket ackPacket = (PacketAckPacket)packet; PacketAckPacket ackPacket = (PacketAckPacket)packet;
for (int i = 0; i < ackPacket.Packets.Length; i++) for (int i = 0; i < ackPacket.Packets.Length; i++)
udpClient.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent); udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
// We don't need to do anything else with PacketAck packets // We don't need to do anything else with PacketAck packets
return; return;

View File

@ -52,29 +52,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public int Texture; public int Texture;
/// <summary>Drip rate for asset packets</summary> /// <summary>Drip rate for asset packets</summary>
public int Asset; public int Asset;
/// <summary>Drip rate for state packets</summary>
public int State;
/// <summary>Drip rate for the parent token bucket</summary> /// <summary>Drip rate for the parent token bucket</summary>
public int Total; public int Total;
/// <summary>Maximum burst rate for resent packets</summary> /// <summary>Flag used to enable adaptive throttles</summary>
public int ResendLimit; public bool AdaptiveThrottlesEnabled;
/// <summary>Maximum burst rate for land packets</summary>
public int LandLimit;
/// <summary>Maximum burst rate for wind packets</summary>
public int WindLimit;
/// <summary>Maximum burst rate for cloud packets</summary>
public int CloudLimit;
/// <summary>Maximum burst rate for task (state and transaction) packets</summary>
public int TaskLimit;
/// <summary>Maximum burst rate for texture packets</summary>
public int TextureLimit;
/// <summary>Maximum burst rate for asset packets</summary>
public int AssetLimit;
/// <summary>Maximum burst rate for state packets</summary>
public int StateLimit;
/// <summary>Burst rate for the parent token bucket</summary>
public int TotalLimit;
/// <summary> /// <summary>
/// Default constructor /// Default constructor
@ -86,26 +69,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"];
Resend = throttleConfig.GetInt("resend_default", 12500); Resend = throttleConfig.GetInt("resend_default", 6625);
Land = throttleConfig.GetInt("land_default", 1000); Land = throttleConfig.GetInt("land_default", 9125);
Wind = throttleConfig.GetInt("wind_default", 1000); Wind = throttleConfig.GetInt("wind_default", 1750);
Cloud = throttleConfig.GetInt("cloud_default", 1000); Cloud = throttleConfig.GetInt("cloud_default", 1750);
Task = throttleConfig.GetInt("task_default", 1000); Task = throttleConfig.GetInt("task_default", 18500);
Texture = throttleConfig.GetInt("texture_default", 1000); Texture = throttleConfig.GetInt("texture_default", 18500);
Asset = throttleConfig.GetInt("asset_default", 1000); Asset = throttleConfig.GetInt("asset_default", 10500);
State = throttleConfig.GetInt("state_default", 1000);
ResendLimit = throttleConfig.GetInt("resend_limit", 18750);
LandLimit = throttleConfig.GetInt("land_limit", 29750);
WindLimit = throttleConfig.GetInt("wind_limit", 18750);
CloudLimit = throttleConfig.GetInt("cloud_limit", 18750);
TaskLimit = throttleConfig.GetInt("task_limit", 18750);
TextureLimit = throttleConfig.GetInt("texture_limit", 55750);
AssetLimit = throttleConfig.GetInt("asset_limit", 27500);
StateLimit = throttleConfig.GetInt("state_limit", 37000);
Total = throttleConfig.GetInt("client_throttle_max_bps", 0); Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
TotalLimit = Total;
AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);
} }
catch (Exception) { } catch (Exception) { }
} }
@ -128,34 +102,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return Texture; return Texture;
case ThrottleOutPacketType.Asset: case ThrottleOutPacketType.Asset:
return Asset; return Asset;
case ThrottleOutPacketType.State:
return State;
case ThrottleOutPacketType.Unknown:
default:
return 0;
}
}
public int GetLimit(ThrottleOutPacketType type)
{
switch (type)
{
case ThrottleOutPacketType.Resend:
return ResendLimit;
case ThrottleOutPacketType.Land:
return LandLimit;
case ThrottleOutPacketType.Wind:
return WindLimit;
case ThrottleOutPacketType.Cloud:
return CloudLimit;
case ThrottleOutPacketType.Task:
return TaskLimit;
case ThrottleOutPacketType.Texture:
return TextureLimit;
case ThrottleOutPacketType.Asset:
return AssetLimit;
case ThrottleOutPacketType.State:
return StateLimit;
case ThrottleOutPacketType.Unknown: case ThrottleOutPacketType.Unknown:
default: default:
return 0; return 0;

View File

@ -29,6 +29,8 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using OpenSim.Framework;
using log4net; using log4net;
namespace OpenSim.Region.ClientStack.LindenUDP namespace OpenSim.Region.ClientStack.LindenUDP
@ -177,7 +179,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
RequestedDripRate = dripRate; RequestedDripRate = dripRate;
// TotalDripRequest = dripRate; // this will be overwritten when a child node registers // TotalDripRequest = dripRate; // this will be overwritten when a child node registers
// MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst); // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst);
m_lastDrip = Environment.TickCount & Int32.MaxValue; m_lastDrip = Util.EnvironmentTickCount();
} }
#endregion Constructor #endregion Constructor
@ -210,6 +212,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// changes up the hierarchy. /// changes up the hierarchy.
/// </summary> /// </summary>
public void RegisterRequest(TokenBucket child, Int64 request) public void RegisterRequest(TokenBucket child, Int64 request)
{
lock (m_children)
{ {
m_children[child] = request; m_children[child] = request;
// m_totalDripRequest = m_children.Values.Sum(); // m_totalDripRequest = m_children.Values.Sum();
@ -217,6 +221,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_totalDripRequest = 0; m_totalDripRequest = 0;
foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
m_totalDripRequest += cref.Value; m_totalDripRequest += cref.Value;
}
// Pass the new values up to the parent // Pass the new values up to the parent
if (m_parent != null) if (m_parent != null)
@ -228,6 +233,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// changes up the hierarchy. /// changes up the hierarchy.
/// </summary> /// </summary>
public void UnregisterRequest(TokenBucket child) public void UnregisterRequest(TokenBucket child)
{
lock (m_children)
{ {
m_children.Remove(child); m_children.Remove(child);
// m_totalDripRequest = m_children.Values.Sum(); // m_totalDripRequest = m_children.Values.Sum();
@ -235,6 +242,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_totalDripRequest = 0; m_totalDripRequest = 0;
foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
m_totalDripRequest += cref.Value; m_totalDripRequest += cref.Value;
}
// Pass the new values up to the parent // Pass the new values up to the parent
if (m_parent != null) if (m_parent != null)
@ -297,10 +306,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Determine the interval over which we are adding tokens, never add // Determine the interval over which we are adding tokens, never add
// more than a single quantum of tokens // more than a single quantum of tokens
Int32 now = Environment.TickCount & Int32.MaxValue; Int32 deltaMS = Math.Min(Util.EnvironmentTickCountSubtract(m_lastDrip), m_ticksPerQuantum);
Int32 deltaMS = Math.Min(now - m_lastDrip, m_ticksPerQuantum); m_lastDrip = Util.EnvironmentTickCount();
m_lastDrip = now;
// This can be 0 in the very unusual case that the timer wrapped // This can be 0 in the very unusual case that the timer wrapped
// It can be 0 if we try add tokens at a sub-tick rate // It can be 0 if we try add tokens at a sub-tick rate
@ -315,10 +322,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// <summary> /// <summary>
// The minimum rate for flow control. /// The minimum rate for flow control. Minimum drip rate is one
// </summary> /// packet per second. Open the throttle to 15 packets per second
protected const Int64 m_minimumFlow = m_minimumDripRate * 10; /// or about 160kbps.
/// </summary>
protected const Int64 m_minimumFlow = m_minimumDripRate * 15;
// <summary> // <summary>
// The maximum rate for flow control. Drip rate can never be // The maximum rate for flow control. Drip rate can never be
@ -331,6 +340,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); } set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); }
} }
private bool m_enabled = false;
// <summary> // <summary>
// //
// </summary> // </summary>
@ -348,9 +359,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// <summary> // <summary>
// //
// </summary> // </summary>
public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate) : base(parent,m_minimumFlow) public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate)
{ {
m_enabled = enabled;
if (m_enabled)
{
// m_log.DebugFormat("[TOKENBUCKET] Adaptive throttle enabled");
MaxDripRate = maxDripRate; MaxDripRate = maxDripRate;
AdjustedDripRate = m_minimumFlow;
}
} }
// <summary> // <summary>
@ -359,6 +377,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void ExpirePackets(Int32 count) public void ExpirePackets(Int32 count)
{ {
// m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count); // m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count);
if (m_enabled)
AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count)); AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count));
} }
@ -367,6 +386,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// </summary> // </summary>
public void AcknowledgePackets(Int32 count) public void AcknowledgePackets(Int32 count)
{ {
if (m_enabled)
AdjustedDripRate = AdjustedDripRate + count; AdjustedDripRate = AdjustedDripRate + count;
} }
} }

View File

@ -65,7 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Holds packets that need to be added to the unacknowledged list</summary> /// <summary>Holds packets that need to be added to the unacknowledged list</summary>
private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>(); private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>();
/// <summary>Holds information about pending acknowledgements</summary> /// <summary>Holds information about pending acknowledgements</summary>
private LocklessQueue<PendingAck> m_pendingRemoves = new LocklessQueue<PendingAck>(); private LocklessQueue<PendingAck> m_pendingAcknowledgements = new LocklessQueue<PendingAck>();
/// <summary>Holds information about pending removals</summary>
private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>();
/// <summary> /// <summary>
/// Add an unacked packet to the collection /// Add an unacked packet to the collection
@ -83,15 +85,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary> /// <summary>
/// Marks a packet as acknowledged /// Marks a packet as acknowledged
/// This method is used when an acknowledgement is received from the network for a previously
/// sent packet. Effects of removal this way are to update unacked byte count, adjust RTT
/// and increase throttle to the coresponding client.
/// </summary> /// </summary>
/// <param name="sequenceNumber">Sequence number of the packet to /// <param name="sequenceNumber">Sequence number of the packet to
/// acknowledge</param> /// acknowledge</param>
/// <param name="currentTime">Current value of Environment.TickCount</param> /// <param name="currentTime">Current value of Environment.TickCount</param>
/// <remarks>This does not immediately acknowledge the packet, it only /// <remarks>This does not immediately acknowledge the packet, it only
/// queues the ack so it can be handled in a thread-safe way later</remarks> /// queues the ack so it can be handled in a thread-safe way later</remarks>
public void Remove(uint sequenceNumber, int currentTime, bool fromResend) public void Acknowledge(uint sequenceNumber, int currentTime, bool fromResend)
{ {
m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); m_pendingAcknowledgements.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend));
}
/// <summary>
/// Marks a packet as no longer needing acknowledgement without a received acknowledgement.
/// This method is called when a packet expires and we no longer need an acknowledgement.
/// When some reliable packet types expire, they are handled in a way other than simply
/// resending them. The only effect of removal this way is to update unacked byte count.
/// </summary>
/// <param name="sequenceNumber">Sequence number of the packet to
/// acknowledge</param>
/// <remarks>The does not immediately remove the packet, it only queues the removal
/// so it can be handled in a thread safe way later</remarks>
public void Remove(uint sequenceNumber)
{
m_pendingRemoves.Enqueue(sequenceNumber);
} }
/// <summary> /// <summary>
@ -151,15 +171,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_packets[pendingAdd.SequenceNumber] = pendingAdd; m_packets[pendingAdd.SequenceNumber] = pendingAdd;
// Process all the pending removes, including updating statistics and round-trip times // Process all the pending removes, including updating statistics and round-trip times
PendingAck pendingRemove; PendingAck pendingAcknowledgement;
OutgoingPacket ackedPacket; while (m_pendingAcknowledgements.TryDequeue(out pendingAcknowledgement))
while (m_pendingRemoves.TryDequeue(out pendingRemove))
{ {
if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) OutgoingPacket ackedPacket;
if (m_packets.TryGetValue(pendingAcknowledgement.SequenceNumber, out ackedPacket))
{ {
if (ackedPacket != null) if (ackedPacket != null)
{ {
m_packets.Remove(pendingRemove.SequenceNumber); m_packets.Remove(pendingAcknowledgement.SequenceNumber);
// As with other network applications, assume that an acknowledged packet is an // As with other network applications, assume that an acknowledged packet is an
// indication that the network can handle a little more load, speed up the transmission // indication that the network can handle a little more load, speed up the transmission
@ -168,16 +188,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Update stats // Update stats
Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
if (!pendingRemove.FromResend) if (!pendingAcknowledgement.FromResend)
{ {
// Calculate the round-trip time for this packet and its ACK // Calculate the round-trip time for this packet and its ACK
int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; int rtt = pendingAcknowledgement.RemoveTime - ackedPacket.TickCount;
if (rtt > 0) if (rtt > 0)
ackedPacket.Client.UpdateRoundTrip(rtt); ackedPacket.Client.UpdateRoundTrip(rtt);
} }
} }
} }
} }
uint pendingRemove;
while(m_pendingRemoves.TryDequeue(out pendingRemove))
{
OutgoingPacket removedPacket;
if (m_packets.TryGetValue(pendingRemove, out removedPacket))
{
if (removedPacket != null)
{
m_packets.Remove(pendingRemove);
// Update stats
Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
}
}
}
} }
} }
} }

View File

@ -41,8 +41,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
/// </summary> /// </summary>
public class AgentAssetTransactions public class AgentAssetTransactions
{ {
// private static readonly ILog m_log = LogManager.GetLogger( // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// MethodBase.GetCurrentMethod().DeclaringType);
// Fields // Fields
private bool m_dumpAssetsToFile; private bool m_dumpAssetsToFile;
@ -149,6 +148,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
if (asset != null) if (asset != null)
{ {
// m_log.DebugFormat(
// "[AGENT ASSETS TRANSACTIONS]: Updating item {0} in {1} for transaction {2}",
// item.Name, part.Name, transactionID);
asset.FullID = UUID.Random(); asset.FullID = UUID.Random();
asset.Name = item.Name; asset.Name = item.Name;
asset.Description = item.Description; asset.Description = item.Description;
@ -156,8 +159,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
item.AssetID = asset.FullID; item.AssetID = asset.FullID;
m_Scene.AssetService.Store(asset); m_Scene.AssetService.Store(asset);
part.Inventory.UpdateInventoryItem(item);
} }
} }
} }

View File

@ -571,14 +571,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// <param name="sp"></param> /// <param name="sp"></param>
/// <param name="so"></param> /// <param name="so"></param>
/// <param name="attachmentpoint"></param> /// <param name="attachmentpoint"></param>
/// <param name="AttachOffset"></param> /// <param name="attachOffset"></param>
/// <param name="silent"></param> /// <param name="silent"></param>
protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 AttachOffset, bool silent) protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
{ {
// don't attach attachments to child agents
if (avatar.IsChildAgent) return;
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1}", Name, avatar.Name); m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name,
attachmentpoint, attachOffset, so.RootPart.AttachedPos);
so.DetachFromBackup(); so.DetachFromBackup();
@ -599,8 +598,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
so.RootPart.PhysActor = null; so.RootPart.PhysActor = null;
} }
so.AbsolutePosition = AttachOffset; so.AbsolutePosition = attachOffset;
so.RootPart.AttachedPos = AttachOffset; so.RootPart.AttachedPos = attachOffset;
so.RootPart.IsAttachment = true; so.RootPart.IsAttachment = true;
so.RootPart.SetParentLocalId(avatar.LocalId); so.RootPart.SetParentLocalId(avatar.LocalId);

View File

@ -286,11 +286,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
string reason; string reason;
if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out reason)) string version;
if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
{ {
sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason);
return; return;
} }
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendTeleportStart(teleportFlags);
@ -372,20 +374,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
} }
// Expect avatar crossing is a heavy-duty function at the destination.
// That is where MakeRoot is called, which fetches appearance and inventory.
// Plus triggers OnMakeRoot, which spawns a series of asynchronous updates.
//m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
// position, false);
//{
// avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
// // We should close that agent we just created over at destination...
// List<ulong> lst = new List<ulong>();
// lst.Add(reg.RegionHandle);
// SendCloseChildAgentAsync(avatar.UUID, lst);
// return;
//}
SetInTransit(sp.UUID); SetInTransit(sp.UUID);
@ -427,7 +415,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
// that the client contacted the destination before we send the attachments and close things here. // that the client contacted the destination before we close things here.
if (!WaitForCallback(sp.UUID)) if (!WaitForCallback(sp.UUID))
{ {
m_log.WarnFormat( m_log.WarnFormat(
@ -438,14 +426,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return; return;
} }
// For backwards compatibility
if (version == "Unknown" || version == string.Empty)
{
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one...");
CrossAttachmentsIntoNewRegion(finalDestination, sp, true); CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
}
// May need to logout or other cleanup
AgentHasMovedAway(sp, logout);
// Well, this is it. The agent is over there. // Well, this is it. The agent is over there.
KillEntity(sp.Scene, sp.LocalId); KillEntity(sp.Scene, sp.LocalId);
// May need to logout or other cleanup
AgentHasMovedAway(sp.ControllingClient.SessionId, logout);
// Now let's make it officially a child agent // Now let's make it officially a child agent
sp.MakeChildAgent(); sp.MakeChildAgent();
@ -486,7 +480,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Fail. Reset it back // Fail. Reset it back
sp.IsChildAgent = false; sp.IsChildAgent = false;
ReInstantiateScripts(sp);
ResetFromTransit(sp.UUID); ResetFromTransit(sp.UUID);
EnableChildAgents(sp); EnableChildAgents(sp);
@ -514,8 +508,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
protected virtual void AgentHasMovedAway(UUID sessionID, bool logout) protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
{ {
foreach (SceneObjectGroup sop in sp.Attachments)
{
sop.Scene.DeleteSceneObject(sop, true);
}
sp.Attachments.Clear();
} }
protected void KillEntity(Scene scene, uint localID) protected void KillEntity(Scene scene, uint localID)
@ -803,7 +802,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
string reason; string reason;
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out reason)) string version;
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
{ {
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
if (r == null) if (r == null)
@ -823,7 +823,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.InTransit(); agent.InTransit();
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, CrossAgentToNewRegionCompleted, d); d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
return true; return true;
} }
@ -880,17 +880,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
icon.EndInvoke(iar); icon.EndInvoke(iar);
} }
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying); public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
/// <summary> /// <summary>
/// This Closes child agents on neighbouring regions /// This Closes child agents on neighbouring regions
/// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary> /// </summary>
protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying) protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version)
{ {
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
Scene m_scene = agent.Scene; Scene m_scene = agent.Scene;
@ -953,6 +953,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (!WaitForCallback(agent.UUID)) if (!WaitForCallback(agent.UUID))
{ {
m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent"); m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent");
ReInstantiateScripts(agent);
ResetFromTransit(agent.UUID); ResetFromTransit(agent.UUID);
// Yikes! We should just have a ref to scene here. // Yikes! We should just have a ref to scene here.
@ -968,7 +969,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.SendOtherAgentsAvatarDataToMe(); agent.SendOtherAgentsAvatarDataToMe();
agent.SendOtherAgentsAppearanceToMe(); agent.SendOtherAgentsAppearanceToMe();
// Backwards compatibility
if (version == "Unknown" || version == string.Empty)
{
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old neighbor, passing attachments one by one...");
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
}
AgentHasMovedAway(agent, false);
// the user may change their profile information in other region, // the user may change their profile information in other region,
// so the userinfo in UserProfileCache is not reliable any more, delete it // so the userinfo in UserProfileCache is not reliable any more, delete it
@ -1775,7 +1783,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return false; return false;
} }
protected void ReInstantiateScripts(ScenePresence sp)
{
sp.Attachments.ForEach(delegate(SceneObjectGroup sog)
{
sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0);
sog.ResumeScripts();
});
}
#endregion #endregion
} }

View File

@ -142,11 +142,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return false; return false;
} }
protected override void AgentHasMovedAway(UUID sessionID, bool logout) protected override void AgentHasMovedAway(ScenePresence sp, bool logout)
{ {
base.AgentHasMovedAway(sp, logout);
if (logout) if (logout)
// Log them out of this grid // Log them out of this grid
m_aScene.PresenceService.LogoutAgent(sessionID); m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
} }
protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)

View File

@ -41,6 +41,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// Version of this service
private const string m_Version = "SIMULATION/0.1";
private List<Scene> m_sceneList = new List<Scene>(); private List<Scene> m_sceneList = new List<Scene>();
private IEntityTransferModule m_AgentTransferModule; private IEntityTransferModule m_AgentTransferModule;
@ -257,9 +260,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
return false; return false;
} }
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
{ {
reason = "Communications failure"; reason = "Communications failure";
version = m_Version;
if (destination == null) if (destination == null)
return false; return false;

View File

@ -229,19 +229,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
} }
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
{ {
reason = "Communications failure"; reason = "Communications failure";
version = "Unknown";
if (destination == null) if (destination == null)
return false; return false;
// Try local first // Try local first
if (m_localBackend.QueryAccess(destination, id, position, out reason)) if (m_localBackend.QueryAccess(destination, id, position, out version, out reason))
return true; return true;
// else do the remote thing // else do the remote thing
if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
return m_remoteConnector.QueryAccess(destination, id, position, out reason); return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason);
return false; return false;

View File

@ -88,7 +88,7 @@ namespace OpenSim.Region.Framework.Scenes
// If this is an update for our own avatar give it the highest priority // If this is an update for our own avatar give it the highest priority
if (client.AgentId == entity.UUID) if (client.AgentId == entity.UUID)
return PriorityQueue.ImmediateQueue; return 0;
uint priority; uint priority;
@ -119,16 +119,40 @@ namespace OpenSim.Region.Framework.Scenes
private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity) private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity)
{ {
// And anything attached to this avatar gets top priority as well
if (entity is SceneObjectPart)
{
SceneObjectPart sop = (SceneObjectPart)entity;
if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar)
return 1; return 1;
} }
return PriorityQueue.NumberOfImmediateQueues; // first queue past the immediate queues
}
private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity) private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity)
{ {
// And anything attached to this avatar gets top priority as well
if (entity is SceneObjectPart)
{
SceneObjectPart sop = (SceneObjectPart)entity;
if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar)
return 1;
}
return ComputeDistancePriority(client,entity,false); return ComputeDistancePriority(client,entity,false);
} }
private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
{ {
// And anything attached to this avatar gets top priority as well
if (entity is SceneObjectPart)
{
SceneObjectPart sop = (SceneObjectPart)entity;
if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar)
return 1;
}
return ComputeDistancePriority(client,entity,true); return ComputeDistancePriority(client,entity,true);
} }
@ -143,18 +167,20 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (!presence.IsChildAgent) if (!presence.IsChildAgent)
{ {
// All avatars other than our own go into pqueue 1
if (entity is ScenePresence)
return 1;
if (entity is SceneObjectPart) if (entity is SceneObjectPart)
{ {
// Attachments are high priority,
if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
return 1;
// Non physical prims are lower priority than physical prims // Non physical prims are lower priority than physical prims
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
if (physActor == null || !physActor.IsPhysical) if (physActor == null || !physActor.IsPhysical)
pqueue++; pqueue++;
// Attachments are high priority,
// MIC: shouldn't these already be in the highest priority queue already
// since their root position is same as the avatars?
if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
pqueue = 1;
} }
} }
} }
@ -205,8 +231,10 @@ namespace OpenSim.Region.Framework.Scenes
// And convert the distance to a priority queue, this computation gives queues // And convert the distance to a priority queue, this computation gives queues
// at 10, 20, 40, 80, 160, 320, 640, and 1280m // at 10, 20, 40, 80, 160, 320, 640, and 1280m
uint pqueue = 1; uint pqueue = PriorityQueue.NumberOfImmediateQueues;
for (int i = 0; i < 8; i++) uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues;
for (int i = 0; i < queues - 1; i++)
{ {
if (distance < 10 * Math.Pow(2.0,i)) if (distance < 10 * Math.Pow(2.0,i))
break; break;

View File

@ -1449,6 +1449,10 @@ namespace OpenSim.Region.Framework.Scenes
} }
else // Updating existing item with new perms etc else // Updating existing item with new perms etc
{ {
// m_log.DebugFormat(
// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()",
// currentItem.Name, part.Name);
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
if (agentTransactions != null) if (agentTransactions != null)
{ {
@ -2089,6 +2093,12 @@ namespace OpenSim.Region.Framework.Scenes
if (rot != null) if (rot != null)
group.UpdateGroupRotationR((Quaternion)rot); group.UpdateGroupRotationR((Quaternion)rot);
// TODO: This needs to be refactored with the similar code in
// SceneGraph.AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel)
// possibly by allowing this method to take a null rotation.
if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
group.RootPart.ApplyImpulse((vel * group.GetMass()), false);
// We can only call this after adding the scene object, since the scene object references the scene // We can only call this after adding the scene object, since the scene object references the scene
// to find out if scripts should be activated at all. // to find out if scripts should be activated at all.
group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);

View File

@ -1255,7 +1255,6 @@ namespace OpenSim.Region.Framework.Scenes
// Increment the frame counter // Increment the frame counter
++Frame; ++Frame;
try try
{ {
// Check if any objects have reached their targets // Check if any objects have reached their targets
@ -2383,7 +2382,9 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns></returns> /// <returns></returns>
public bool IncomingCreateObject(ISceneObject sog) public bool IncomingCreateObject(ISceneObject sog)
{ {
//m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); //m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
// ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
SceneObjectGroup newObject; SceneObjectGroup newObject;
try try
{ {
@ -2401,9 +2402,13 @@ namespace OpenSim.Region.Framework.Scenes
return false; return false;
} }
// For attachments, we need to wait until the agent is root
// before we restart the scripts, or else some functions won't work.
if (!newObject.IsAttachment)
{
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
newObject.ResumeScripts(); newObject.ResumeScripts();
}
// Do this as late as possible so that listeners have full access to the incoming object // Do this as late as possible so that listeners have full access to the incoming object
EventManager.TriggerOnIncomingSceneObject(newObject); EventManager.TriggerOnIncomingSceneObject(newObject);
@ -2540,17 +2545,8 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence sp = GetScenePresence(sog.OwnerID); ScenePresence sp = GetScenePresence(sog.OwnerID);
if (sp != null) if (sp != null)
{ return sp.GetStateSource();
AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(sp.UUID);
if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
{
// This will get your attention
//m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
return 5; // StateSource.Teleporting
}
}
return 2; // StateSource.PrimCrossing return 2; // StateSource.PrimCrossing
} }

View File

@ -884,6 +884,8 @@ namespace OpenSim.Region.Framework.Scenes
if (m_items.ContainsKey(item.ItemID)) if (m_items.ContainsKey(item.ItemID))
{ {
// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
item.ParentID = m_part.UUID; item.ParentID = m_part.UUID;
item.ParentPartID = m_part.UUID; item.ParentPartID = m_part.UUID;
@ -899,6 +901,7 @@ namespace OpenSim.Region.Framework.Scenes
m_inventorySerial++; m_inventorySerial++;
if (fireScriptEvents) if (fireScriptEvents)
m_part.TriggerScriptChangedEvent(Changed.INVENTORY); m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
if (considerChanged) if (considerChanged)
{ {
HasInventoryChanged = true; HasInventoryChanged = true;

View File

@ -924,6 +924,9 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
bool wasChild = m_isChildAgent;
m_isChildAgent = false;
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
if (gm != null) if (gm != null)
m_grouptitle = gm.GetGroupTitle(m_uuid); m_grouptitle = gm.GetGroupTitle(m_uuid);
@ -1070,13 +1073,20 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.SwapRootAgentCount(false); m_scene.SwapRootAgentCount(false);
//CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); // The initial login scene presence is already root when it gets here
//if (userInfo != null) // and it has already rezzed the attachments and started their scripts.
// userInfo.FetchInventory(); // We do the following only for non-login agents, because their scripts
//else // haven't started yet.
// m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); if (wasChild)
{
m_isChildAgent = false; m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
// Resume scripts
Attachments.ForEach(delegate(SceneObjectGroup sog)
{
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
});
}
// send the animations of the other presences to me // send the animations of the other presences to me
m_scene.ForEachScenePresence(delegate(ScenePresence presence) m_scene.ForEachScenePresence(delegate(ScenePresence presence)
@ -1088,6 +1098,20 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.EventManager.TriggerOnMakeRootAgent(this); m_scene.EventManager.TriggerOnMakeRootAgent(this);
} }
public int GetStateSource()
{
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID);
if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
{
// This will get your attention
//m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
return 5; // StateSource.Teleporting
}
return 2; // StateSource.PrimCrossing
}
/// <summary> /// <summary>
/// This turns a root agent into a child agent /// This turns a root agent into a child agent
/// when an agent departs this region for a neighbor, this gets called. /// when an agent departs this region for a neighbor, this gets called.
@ -1288,7 +1312,6 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = pos; AbsolutePosition = pos;
} }
m_isChildAgent = false;
bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
MakeRootAgent(AbsolutePosition, m_flying); MakeRootAgent(AbsolutePosition, m_flying);
@ -2757,12 +2780,14 @@ namespace OpenSim.Region.Framework.Scenes
#region Update Client(s) #region Update Client(s)
/// <summary> /// <summary>
/// Sends a location update to the client connected to this scenePresence /// Sends a location update to the client connected to this scenePresence
/// </summary> /// </summary>
/// <param name="remoteClient"></param> /// <param name="remoteClient"></param>
public void SendTerseUpdateToClient(IClientAPI remoteClient) public void SendTerseUpdateToClient(IClientAPI remoteClient)
{ {
// If the client is inactive, it's getting its updates from another // If the client is inactive, it's getting its updates from another
// server. // server.
if (remoteClient.IsActive) if (remoteClient.IsActive)
@ -2784,17 +2809,32 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
// vars to support reduced update frequency when velocity is unchanged
private Vector3 lastVelocitySentToAllClients = Vector3.Zero;
private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount();
/// <summary> /// <summary>
/// Send a location/velocity/accelleration update to all agents in scene /// Send a location/velocity/accelleration update to all agents in scene
/// </summary> /// </summary>
public void SendTerseUpdateToAllClients() public void SendTerseUpdateToAllClients()
{ {
m_perfMonMS = Util.EnvironmentTickCount(); int currentTick = Util.EnvironmentTickCount();
// decrease update frequency when avatar is moving but velocity is not changing
if (m_velocity.Length() < 0.01f
|| Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f
|| currentTick - lastTerseUpdateToAllClientsTick > 1500)
{
m_perfMonMS = currentTick;
lastVelocitySentToAllClients = m_velocity;
lastTerseUpdateToAllClientsTick = currentTick;
m_scene.ForEachClient(SendTerseUpdateToClient); m_scene.ForEachClient(SendTerseUpdateToClient);
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
} }
}
public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
{ {
@ -3049,18 +3089,17 @@ namespace OpenSim.Region.Framework.Scenes
cadu.GroupAccess = 0; cadu.GroupAccess = 0;
cadu.Position = AbsolutePosition; cadu.Position = AbsolutePosition;
cadu.regionHandle = m_rootRegionHandle; cadu.regionHandle = m_rootRegionHandle;
float multiplier = 1;
int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
if (innacurateNeighbors != 0)
{
multiplier = 1f / (float)innacurateNeighbors;
}
if (multiplier <= 0f)
{
multiplier = 0.25f;
}
//m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); // Throttles
float multiplier = 1;
int childRegions = m_knownChildRegions.Count;
if (childRegions != 0)
multiplier = 1f / childRegions;
// Minimum throttle for a child region is 1/4 of the root region throttle
if (multiplier <= 0.25f)
multiplier = 0.25f;
cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier);
cadu.Velocity = Velocity; cadu.Velocity = Velocity;
@ -3456,16 +3495,14 @@ namespace OpenSim.Region.Framework.Scenes
// Throttles // Throttles
float multiplier = 1; float multiplier = 1;
int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); int childRegions = m_knownChildRegions.Count;
if (innacurateNeighbors != 0) if (childRegions != 0)
{ multiplier = 1f / childRegions;
multiplier = 1f / innacurateNeighbors;
} // Minimum throttle for a child region is 1/4 of the root region throttle
if (multiplier <= 0f) if (multiplier <= 0.25f)
{
multiplier = 0.25f; multiplier = 0.25f;
}
//m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier);
cAgent.HeadRotation = m_headrotation; cAgent.HeadRotation = m_headrotation;
@ -3481,54 +3518,6 @@ namespace OpenSim.Region.Framework.Scenes
cAgent.Appearance = new AvatarAppearance(m_appearance); cAgent.Appearance = new AvatarAppearance(m_appearance);
/*
try
{
// We might not pass the Wearables in all cases...
// They're only needed so that persistent changes to the appearance
// are preserved in the new region where the user is moving to.
// But in Hypergrid we might not let this happen.
int i = 0;
UUID[] wears = new UUID[m_appearance.Wearables.Length * 2];
foreach (AvatarWearable aw in m_appearance.Wearables)
{
if (aw != null)
{
wears[i++] = aw.ItemID;
wears[i++] = aw.AssetID;
}
else
{
wears[i++] = UUID.Zero;
wears[i++] = UUID.Zero;
}
}
cAgent.Wearables = wears;
cAgent.VisualParams = m_appearance.VisualParams;
if (m_appearance.Texture != null)
cAgent.AgentTextures = m_appearance.Texture.GetBytes();
}
catch (Exception e)
{
m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message);
}
//Attachments
List<int> attPoints = m_appearance.GetAttachedPoints();
if (attPoints != null)
{
//m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count);
int i = 0;
AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count];
foreach (int point in attPoints)
{
attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point));
}
cAgent.Attachments = attachs;
}
*/
lock (scriptedcontrols) lock (scriptedcontrols)
{ {
ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
@ -3548,9 +3537,26 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch { } catch { }
// cAgent.GroupID = ?? // Attachment objects
// Groups??? if (m_attachments != null && m_attachments.Count > 0)
{
cAgent.AttachmentObjects = new List<ISceneObject>();
cAgent.AttachmentObjectStates = new List<string>();
IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
foreach (SceneObjectGroup sog in m_attachments)
{
// We need to make a copy and pass that copy
// because of transfers withn the same sim
ISceneObject clone = sog.CloneForNewScene();
// Attachment module assumes that GroupPosition holds the offsets...!
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
((SceneObjectGroup)clone).RootPart.IsAttachment = false;
cAgent.AttachmentObjects.Add(clone);
cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot());
// Let's remove the scripts of the original object here
sog.RemoveScriptInstances(true);
}
}
} }
public void CopyFrom(AgentData cAgent) public void CopyFrom(AgentData cAgent)
@ -3592,50 +3598,6 @@ namespace OpenSim.Region.Framework.Scenes
AddToPhysicalScene(isFlying); AddToPhysicalScene(isFlying);
} }
/*
uint i = 0;
try
{
if (cAgent.Wearables == null)
cAgent.Wearables = new UUID[0];
AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2];
for (uint n = 0; n < cAgent.Wearables.Length; n += 2)
{
UUID itemId = cAgent.Wearables[n];
UUID assetId = cAgent.Wearables[n + 1];
wears[i++] = new AvatarWearable(itemId, assetId);
}
// m_appearance.Wearables = wears;
Primitive.TextureEntry textures = null;
if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);
byte[] visuals = null;
if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
visuals = (byte[])cAgent.VisualParams.Clone();
m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals);
}
catch (Exception e)
{
m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message);
}
// Attachments
try
{
if (cAgent.Attachments != null)
{
m_appearance.ClearAttachments();
foreach (AvatarAttachment att in cAgent.Attachments)
{
m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
}
}
}
catch { }
*/
try try
{ {
lock (scriptedcontrols) lock (scriptedcontrols)
@ -3665,8 +3627,18 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch { } catch { }
//cAgent.GroupID = ?? if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0)
//Groups??? {
m_attachments = new List<SceneObjectGroup>();
int i = 0;
foreach (ISceneObject so in cAgent.AttachmentObjects)
{
((SceneObjectGroup)so).LocalId = 0;
((SceneObjectGroup)so).RootPart.UpdateFlag = 0;
so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
m_scene.IncomingCreateObject(so);
}
}
} }
public bool CopyAgent(out IAgentData agent) public bool CopyAgent(out IAgentData agent)

View File

@ -81,6 +81,14 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
lock (m_scenes) lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene; m_scenes[scene.RegionInfo.RegionID] = scene;
scene.AddCommand(
this, "show pqueues",
"show pqueues [full]",
"Show priority queue data for each client",
"Without the 'full' option, only root agents are shown."
+ " With the 'full' option child agents are also shown.",
ShowPQueuesReport);
scene.AddCommand( scene.AddCommand(
this, "show queues", this, "show queues",
"show queues [full]", "show queues [full]",
@ -119,6 +127,11 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
} }
protected void ShowPQueuesReport(string module, string[] cmd)
{
MainConsole.Instance.Output(GetPQueuesReport(cmd));
}
protected void ShowQueuesReport(string module, string[] cmd) protected void ShowQueuesReport(string module, string[] cmd)
{ {
MainConsole.Instance.Output(GetQueuesReport(cmd)); MainConsole.Instance.Output(GetQueuesReport(cmd));
@ -155,6 +168,80 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
""); "");
} }
/// <summary>
/// Generate UDP Queue data report for each client
/// </summary>
/// <param name="showParams"></param>
/// <returns></returns>
protected string GetPQueuesReport(string[] showParams)
{
bool showChildren = false;
string pname = "";
if (showParams.Length > 2 && showParams[2] == "full")
showChildren = true;
else if (showParams.Length > 3)
pname = showParams[2] + " " + showParams[3];
StringBuilder report = new StringBuilder();
int columnPadding = 2;
int maxNameLength = 18;
int maxRegionNameLength = 14;
int maxTypeLength = 4;
int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
report.AppendFormat(
"{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7} {10,7} {11,7}\n",
"Pri 0",
"Pri 1",
"Pri 2",
"Pri 3",
"Pri 4",
"Pri 5",
"Pri 6",
"Pri 7",
"Pri 8",
"Pri 9",
"Pri 10",
"Pri 11");
lock (m_scenes)
{
foreach (Scene scene in m_scenes.Values)
{
scene.ForEachClient(
delegate(IClientAPI client)
{
if (client is LLClientView)
{
bool isChild = scene.PresenceChildStatus(client.AgentId);
if (isChild && !showChildren)
return;
string name = client.Name;
if (pname != "" && name != pname)
return;
string regionName = scene.RegionInfo.RegionName;
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
report.AppendLine(((LLClientView)client).EntityUpdateQueue.ToString());
}
});
}
}
return report.ToString();
}
/// <summary> /// <summary>
/// Generate UDP Queue data report for each client /// Generate UDP Queue data report for each client
/// </summary> /// </summary>
@ -163,9 +250,12 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
protected string GetQueuesReport(string[] showParams) protected string GetQueuesReport(string[] showParams)
{ {
bool showChildren = false; bool showChildren = false;
string pname = "";
if (showParams.Length > 2 && showParams[2] == "full") if (showParams.Length > 2 && showParams[2] == "full")
showChildren = true; showChildren = true;
else if (showParams.Length > 3)
pname = showParams[2] + " " + showParams[3];
StringBuilder report = new StringBuilder(); StringBuilder report = new StringBuilder();
@ -224,6 +314,9 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
return; return;
string name = client.Name; string name = client.Name;
if (pname != "" && name != pname)
return;
string regionName = scene.RegionInfo.RegionName; string regionName = scene.RegionInfo.RegionName;
report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
@ -249,9 +342,12 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
protected string GetThrottlesReport(string[] showParams) protected string GetThrottlesReport(string[] showParams)
{ {
bool showChildren = false; bool showChildren = false;
string pname = "";
if (showParams.Length > 2 && showParams[2] == "full") if (showParams.Length > 2 && showParams[2] == "full")
showChildren = true; showChildren = true;
else if (showParams.Length > 3)
pname = showParams[2] + " " + showParams[3];
StringBuilder report = new StringBuilder(); StringBuilder report = new StringBuilder();
@ -314,6 +410,9 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
return; return;
string name = client.Name; string name = client.Name;
if (pname != "" && name != pname)
return;
string regionName = scene.RegionInfo.RegionName; string regionName = scene.RegionInfo.RegionName;
LLUDPClient llUdpClient = llClient.UDPClient; LLUDPClient llUdpClient = llClient.UDPClient;
@ -352,7 +451,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
int maxRegionNameLength = 14; int maxRegionNameLength = 14;
int maxTypeLength = 4; int maxTypeLength = 4;
string name = "SERVER AGENT LIMITS"; string name = "SERVER AGENT RATES";
report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding)); report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding));
@ -362,13 +461,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
report.AppendFormat( report.AppendFormat(
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
(throttleRates.Total * 8) / 1000, (throttleRates.Total * 8) / 1000,
(throttleRates.ResendLimit * 8) / 1000, (throttleRates.Resend * 8) / 1000,
(throttleRates.LandLimit * 8) / 1000, (throttleRates.Land * 8) / 1000,
(throttleRates.WindLimit * 8) / 1000, (throttleRates.Wind * 8) / 1000,
(throttleRates.CloudLimit * 8) / 1000, (throttleRates.Cloud * 8) / 1000,
(throttleRates.TaskLimit * 8) / 1000, (throttleRates.Task * 8) / 1000,
(throttleRates.TextureLimit * 8) / 1000, (throttleRates.Texture * 8) / 1000,
(throttleRates.AssetLimit * 8) / 1000); (throttleRates.Asset * 8) / 1000);
return report.ToString(); return report.ToString();
} }

View File

@ -88,6 +88,7 @@ namespace OpenSim.Region.Physics.Meshing
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
if(mesh_config != null)
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
try try

View File

@ -50,6 +50,7 @@ namespace OpenSim.Server.Handlers.Simulation
public class AgentHandler public class AgentHandler
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private ISimulationService m_SimulationService; private ISimulationService m_SimulationService;
protected bool m_Proxy = false; protected bool m_Proxy = false;
@ -280,7 +281,7 @@ namespace OpenSim.Server.Handlers.Simulation
AgentData agent = new AgentData(); AgentData agent = new AgentData();
try try
{ {
agent.Unpack(args); agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -300,7 +301,7 @@ namespace OpenSim.Server.Handlers.Simulation
AgentPosition agent = new AgentPosition(); AgentPosition agent = new AgentPosition();
try try
{ {
agent.Unpack(args); agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -347,7 +348,8 @@ namespace OpenSim.Server.Handlers.Simulation
destination.RegionID = regionID; destination.RegionID = regionID;
string reason; string reason;
bool result = m_SimulationService.QueryAccess(destination, id, position, out reason); string version;
bool result = m_SimulationService.QueryAccess(destination, id, position, out version, out reason);
responsedata["int_response_code"] = HttpStatusCode.OK; responsedata["int_response_code"] = HttpStatusCode.OK;
@ -355,6 +357,7 @@ namespace OpenSim.Server.Handlers.Simulation
resp["success"] = OSD.FromBoolean(result); resp["success"] = OSD.FromBoolean(result);
resp["reason"] = OSD.FromString(reason); resp["reason"] = OSD.FromString(reason);
resp["version"] = OSD.FromString(version);
responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
} }

View File

@ -241,7 +241,7 @@ namespace OpenSim.Services.Connectors.Simulation
if (args != null) if (args != null)
{ {
agent = new CompleteAgentData(); agent = new CompleteAgentData();
agent.Unpack(args); agent.Unpack(args, null);
return true; return true;
} }
} }
@ -256,9 +256,10 @@ namespace OpenSim.Services.Connectors.Simulation
/// <summary> /// <summary>
/// </summary> /// </summary>
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
{ {
reason = "Failed to contact destination"; reason = "Failed to contact destination";
version = "Unknown";
// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position); // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position);
@ -274,23 +275,27 @@ namespace OpenSim.Services.Connectors.Simulation
try try
{ {
OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000); OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000);
bool success = result["success"].AsBoolean(); OSDMap data = (OSDMap)result["_Result"];
reason = result["reason"].AsString();
//m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}", uri, success); bool success = result["success"].AsBoolean();
reason = data["reason"].AsString();
if (data["version"] != null && data["version"].AsString() != string.Empty)
version = data["version"].AsString();
m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString());
if (!success) if (!success)
{ {
if (result.ContainsKey("Message")) if (data.ContainsKey("Message"))
{ {
string message = result["Message"].AsString(); string message = data["Message"].AsString();
if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region
{ {
m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored"); m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored");
return true; return true;
} }
reason = result["Message"]; reason = data["Message"];
} }
else else
{ {

View File

@ -29,6 +29,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Text.RegularExpressions;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
@ -57,6 +58,9 @@ namespace OpenSim.Services.HypergridService
private static IUserAgentService m_UserAgentService; private static IUserAgentService m_UserAgentService;
private static ISimulationService m_SimulationService; private static ISimulationService m_SimulationService;
protected string m_AllowedClients = string.Empty;
protected string m_DeniedClients = string.Empty;
private static UUID m_ScopeID; private static UUID m_ScopeID;
private static bool m_AllowTeleportsToAnyRegion; private static bool m_AllowTeleportsToAnyRegion;
private static string m_ExternalName; private static string m_ExternalName;
@ -104,6 +108,9 @@ namespace OpenSim.Services.HypergridService
else if (simulationService != string.Empty) else if (simulationService != string.Empty)
m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args); m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
m_AllowedClients = serverConfig.GetString("AllowedClients", string.Empty);
m_DeniedClients = serverConfig.GetString("DeniedClients", string.Empty);
if (m_GridService == null || m_PresenceService == null || m_SimulationService == null) if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function."); throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function.");
@ -181,8 +188,36 @@ namespace OpenSim.Services.HypergridService
string authURL = string.Empty; string authURL = string.Empty;
if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
authURL = aCircuit.ServiceURLs["HomeURI"].ToString(); authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}", m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}",
aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName); aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName,
aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0);
//
// Check client
//
if (m_AllowedClients != string.Empty)
{
Regex arx = new Regex(m_AllowedClients);
Match am = arx.Match(aCircuit.Viewer);
if (!am.Success)
{
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", aCircuit.Viewer);
return false;
}
}
if (m_DeniedClients != string.Empty)
{
Regex drx = new Regex(m_DeniedClients);
Match dm = drx.Match(aCircuit.Viewer);
if (dm.Success)
{
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", aCircuit.Viewer);
return false;
}
}
// //
// Authenticate the user // Authenticate the user

View File

@ -67,7 +67,7 @@ namespace OpenSim.Services.Interfaces
bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent); bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent);
bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason); bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason);
/// <summary> /// <summary>
/// Message from receiving region to departing region, telling it got contacted by the client. /// Message from receiving region to departing region, telling it got contacted by the client.

View File

@ -77,7 +77,11 @@ namespace OpenSim.Services.LLLoginService
protected string m_MapTileURL; protected string m_MapTileURL;
protected string m_SearchURL; protected string m_SearchURL;
protected string m_AllowedClients;
protected string m_DeniedClients;
IConfig m_LoginServerConfig; IConfig m_LoginServerConfig;
IConfig m_ClientsConfig;
public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService) public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService)
{ {
@ -106,6 +110,9 @@ namespace OpenSim.Services.LLLoginService
m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty); m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty);
m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty); m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty);
m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty);
m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty);
// These are required; the others aren't // These are required; the others aren't
if (accountService == string.Empty || authService == string.Empty) if (accountService == string.Empty || authService == string.Empty)
throw new Exception("LoginService is missing service specifications"); throw new Exception("LoginService is missing service specifications");
@ -216,10 +223,37 @@ namespace OpenSim.Services.LLLoginService
bool success = false; bool success = false;
UUID session = UUID.Random(); UUID session = UUID.Random();
m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} from {2} with user agent {3} starting in {4}", m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}",
firstName, lastName, clientIP.Address.ToString(), clientVersion, startLocation); firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0);
try try
{ {
//
// Check client
//
if (m_AllowedClients != string.Empty)
{
Regex arx = new Regex(m_AllowedClients);
Match am = arx.Match(clientVersion);
if (!am.Success)
{
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is not allowed", clientVersion);
return LLFailedLoginResponse.LoginBlockedProblem;
}
}
if (m_DeniedClients != string.Empty)
{
Regex drx = new Regex(m_DeniedClients);
Match dm = drx.Match(clientVersion);
if (dm.Success)
{
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is denied", clientVersion);
return LLFailedLoginResponse.LoginBlockedProblem;
}
}
// //
// Get the account and check that it exists // Get the account and check that it exists
// //

View File

@ -37,7 +37,7 @@ Now see the "Configuring OpenSim" section
=== Running OpenSim on Linux === === Running OpenSim on Linux ===
================================ ================================
You will need Mono >= 2.4.2 to run OpenSim. On some Linux distributions you You will need Mono >= 2.4.3 to run OpenSim. On some Linux distributions you
may need to install additional packages. See http://opensimulator.org/wiki/Dependencies may need to install additional packages. See http://opensimulator.org/wiki/Dependencies
for more information. for more information.

0
bin/Axiom.MathLib.dll Normal file → Executable file
View File

0
bin/BulletDotNET.dll Normal file → Executable file
View File

0
bin/C5.dll Normal file → Executable file
View File

0
bin/CSJ2K.dll Normal file → Executable file
View File

0
bin/Community.CsharpSqlite.Sqlite.dll Normal file → Executable file
View File

0
bin/Community.CsharpSqlite.dll Normal file → Executable file
View File

0
bin/CookComputing.XmlRpcV2.dll Normal file → Executable file
View File

0
bin/DotNetOpenId.dll Normal file → Executable file
View File

0
bin/DotNetOpenMail.dll Normal file → Executable file
View File

0
bin/Fadd.Globalization.Yaml.dll Normal file → Executable file
View File

0
bin/Fadd.dll Normal file → Executable file
View File

0
bin/GlynnTucker.Cache.dll Normal file → Executable file
View File

0
bin/Google.ProtocolBuffers.dll Normal file → Executable file
View File

0
bin/HttpServer.dll Normal file → Executable file
View File

0
bin/HttpServer_OpenSim.dll Normal file → Executable file
View File

0
bin/Iesi.Collections.dll Normal file → Executable file
View File

0
bin/Kds.Serialization.dll Normal file → Executable file
View File

Binary file not shown.

0
bin/Modified.XnaDevRu.BulletX.dll Normal file → Executable file
View File

0
bin/Mono.Addins.CecilReflector.dll Normal file → Executable file
View File

0
bin/Mono.Addins.Setup.dll Normal file → Executable file
View File

0
bin/Mono.Addins.dll Normal file → Executable file
View File

0
bin/Mono.Data.Sqlite.dll Normal file → Executable file
View File

0
bin/Mono.Data.SqliteClient.dll Normal file → Executable file
View File

0
bin/MonoXnaCompactMaths.dll Normal file → Executable file
View File

0
bin/MySql.Data.dll Normal file → Executable file
View File

0
bin/NDesk.Options.dll Normal file → Executable file
View File

0
bin/Newtonsoft.Json.Net20.dll Normal file → Executable file
View File

0
bin/Nini.dll Normal file → Executable file
View File

0
bin/Npgsql.dll Normal file → Executable file
View File

0
bin/Ode.NET.dll Normal file → Executable file
View File

0
bin/OpenMetaverse.StructuredData.dll Normal file → Executable file
View File

0
bin/OpenMetaverse.dll Normal file → Executable file
View File

0
bin/OpenMetaverseTypes.dll Normal file → Executable file
View File

View File

@ -626,7 +626,7 @@
; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector ; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector
;; If using a remote connector, specify the server URL ;; If using a remote connector, specify the server URL
; FreeswitchServiceURL = http://my.grid.server:8003/fsapi ; FreeswitchServiceURL = http://my.grid.server:8004/fsapi
[FreeswitchService] [FreeswitchService]

View File

@ -362,30 +362,24 @@
; ;
;client_throttle_max_bps = 196608 ;client_throttle_max_bps = 196608
; Per-client bytes per second rates for the various throttle categories. ; Adaptive throttling attempts to limit network overload when multiple
; These are default values that will be overriden by clients ; clients login by starting each connection more slowly. Disabled by
; default
; ;
;resend_default = 12500 ;enable_adaptive_throttles = true
;land_default = 1000
;wind_default = 1000
;cloud_default = 1000
;task_default = 1000
;texture_default = 1000
;asset_default = 1000
;state_default = 1000
; Per-client maximum burst rates in bytes per second for the various ; Per-client bytes per second rates for the various throttle categories.
; throttle categories. These are default values that will be overriden by ; These are default values that will be overriden by clients. These
; clients ; defaults are approximately equivalent to the throttles set by the Imprudence
; ; viewer when maximum bandwidth is set to 350kbps
;resend_limit = 18750
;land_limit = 29750 ;resend_default = 6625
;wind_limit = 18750 ;land_default = 9125
;cloud_limit = 18750 ;wind_default = 1750
;task_limit = 18750 ;cloud_default = 1750
;texture_limit = 55750 ;task_default = 18500
;asset_limit = 27500 ;texture_default = 18500
;state_limit = 37000 ;asset_default = 10500
; Configures how ObjectUpdates are aggregated. These numbers ; Configures how ObjectUpdates are aggregated. These numbers
; do not literally mean how many updates will be put in each ; do not literally mean how many updates will be put in each

0
bin/PhysX-wrapper.dll Normal file → Executable file
View File

0
bin/PhysX_Wrapper_Dotnet.dll Normal file → Executable file
View File

0
bin/PrimMesher.dll Normal file → Executable file
View File

0
bin/PumaCode.SvnDotNet.dll Normal file → Executable file
View File

View File

@ -21,7 +21,7 @@
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>] ; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
; * ; *
[Startup] [Startup]
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector" ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector"
; * This is common for all services, it's the network setup for the entire ; * This is common for all services, it's the network setup for the entire
; * server instance, if none is specified above ; * server instance, if none is specified above
@ -197,6 +197,23 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
SRV_AssetServerURI = "http://127.0.0.1:8002" SRV_AssetServerURI = "http://127.0.0.1:8002"
SRV_ProfileServerURI = "http://127.0.0.1:8002/user" SRV_ProfileServerURI = "http://127.0.0.1:8002/user"
;; Regular expressions for controlling which client versions are accepted/denied.
;; An empty string means nothing is checked.
;;
;; Example 1: allow only these 3 types of clients (any version of them)
;; AllowedClients = "Imprudence|Hippo|Second Life"
;;
;; Example 2: allow all clients except these
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
;;
;; Note that these are regular expressions, so every character counts.
;; Also note that this is very weak security and should not be trusted as a reliable means
;; for keeping bad clients out; modified clients can fake their identifiers.
;;
;;
;AllowedClients = ""
;DeniedClients = ""
[GridInfoService] [GridInfoService]
; These settings are used to return information on a get_grid_info call. ; These settings are used to return information on a get_grid_info call.
; Client launcher scripts and third-party clients make use of this to ; Client launcher scripts and third-party clients make use of this to
@ -256,6 +273,22 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
; If you run this gatekeeper server behind a proxy, set this to true ; If you run this gatekeeper server behind a proxy, set this to true
; HasProxy = false ; HasProxy = false
;; Regular expressions for controlling which client versions are accepted/denied.
;; An empty string means nothing is checked.
;;
;; Example 1: allow only these 3 types of clients (any version of them)
;; AllowedClients = "Imprudence|Hippo|Second Life"
;;
;; Example 2: allow all clients except these
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
;;
;; Note that these are regular expressions, so every character counts.
;; Also note that this is very weak security and should not be trusted as a reliable means
;; for keeping bad clients out; modified clients can fake their identifiers.
;;
;;
;AllowedClients = ""
;DeniedClients = ""
[UserAgentService] [UserAgentService]
LocalServiceModule = "OpenSim.Services.HypergridService.dll:UserAgentService" LocalServiceModule = "OpenSim.Services.HypergridService.dll:UserAgentService"

View File

@ -13,7 +13,7 @@
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>] ; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
; * ; *
[Startup] [Startup]
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector" ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
; * This is common for all services, it's the network setup for the entire ; * This is common for all services, it's the network setup for the entire
; * server instance, if none is specified above ; * server instance, if none is specified above
@ -176,6 +176,23 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
; If you run this login server behind a proxy, set this to true ; If you run this login server behind a proxy, set this to true
; HasProxy = false ; HasProxy = false
;; Regular expressions for controlling which client versions are accepted/denied.
;; An empty string means nothing is checked.
;;
;; Example 1: allow only these 3 types of clients (any version of them)
;; AllowedClients = "Imprudence|Hippo|Second Life"
;;
;; Example 2: allow all clients except these
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
;;
;; Note that these are regular expressions, so every character counts.
;; Also note that this is very weak security and should not be trusted as a reliable means
;; for keeping bad clients out; modified clients can fake their identifiers.
;;
;;
;AllowedClients = ""
;DeniedClients = ""
[GridInfoService] [GridInfoService]
; These settings are used to return information on a get_grid_info call. ; These settings are used to return information on a get_grid_info call.
; Client launcher scripts and third-party clients make use of this to ; Client launcher scripts and third-party clients make use of this to

0
bin/Tools.dll Normal file → Executable file
View File

0
bin/Warp3D.dll Normal file → Executable file
View File

0
bin/XMLRPC.dll Normal file → Executable file
View File

View File

@ -83,6 +83,23 @@
SRV_AssetServerURI = "http://127.0.0.1:9000" SRV_AssetServerURI = "http://127.0.0.1:9000"
SRV_ProfileServerURI = "http://127.0.0.1:9000" SRV_ProfileServerURI = "http://127.0.0.1:9000"
;; Regular expressions for controlling which client versions are accepted/denied.
;; An empty string means nothing is checked.
;;
;; Example 1: allow only these 3 types of clients (any version of them)
;; AllowedClients = "Imprudence|Hippo|Second Life"
;;
;; Example 2: allow all clients except these
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
;;
;; Note that these are regular expressions, so every character counts.
;; Also note that this is very weak security and should not be trusted as a reliable means
;; for keeping bad clients out; modified clients can fake their identifiers.
;;
;;
;AllowedClients = ""
;DeniedClients = ""
[GatekeeperService] [GatekeeperService]
ExternalName = "http://127.0.0.1:9000" ExternalName = "http://127.0.0.1:9000"
@ -90,6 +107,23 @@
; If false, HG TPs happen only to the Default regions specified in [GridService] section ; If false, HG TPs happen only to the Default regions specified in [GridService] section
AllowTeleportsToAnyRegion = true AllowTeleportsToAnyRegion = true
;; Regular expressions for controlling which client versions are accepted/denied.
;; An empty string means nothing is checked.
;;
;; Example 1: allow only these 3 types of clients (any version of them)
;; AllowedClients = "Imprudence|Hippo|Second Life"
;;
;; Example 2: allow all clients except these
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
;;
;; Note that these are regular expressions, so every character counts.
;; Also note that this is very weak security and should not be trusted as a reliable means
;; for keeping bad clients out; modified clients can fake their identifiers.
;;
;;
;AllowedClients = ""
;DeniedClients = ""
[GridInfoService] [GridInfoService]
; These settings are used to return information on a get_grid_info call. ; These settings are used to return information on a get_grid_info call.
; Client launcher scripts and third-party clients make use of this to ; Client launcher scripts and third-party clients make use of this to

0
bin/libbulletnet.dll Normal file → Executable file
View File

0
bin/libdb_dotNET43.dll Normal file → Executable file
View File

0
bin/log4net.dll Normal file → Executable file
View File

0
bin/nunit.framework.dll Normal file → Executable file
View File

0
bin/ode.dll Normal file → Executable file
View File

0
bin/openjpeg-dotnet-x86_64.dll Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More