This patch improves MXP connect and disconnect functionality.
- Avatars are now properly on top of terrain. - ScenePresence is now removed from Scene only once. Fixes Mantis #3302. Thanks tlaukkan.0.6.5-rc1
parent
c9a3a764f1
commit
abc5df12c8
|
@ -189,8 +189,6 @@ namespace OpenSim.Client.MXP.ClientStack
|
|||
|
||||
private void MXPProcessModifyRequest(ModifyRequestMessage modifyRequest)
|
||||
{
|
||||
m_log.Debug("Received modify request for: " + modifyRequest.ObjectFragment.ObjectName);
|
||||
|
||||
ObjectFragment objectFragment=modifyRequest.ObjectFragment;
|
||||
if (objectFragment.ObjectId == m_userID.Guid)
|
||||
{
|
||||
|
@ -448,7 +446,7 @@ namespace OpenSim.Client.MXP.ClientStack
|
|||
Session.Send(pe);
|
||||
}
|
||||
|
||||
public void MXPSentSynchronizationBegin(int objectCount)
|
||||
public void MXPSendSynchronizationBegin(int objectCount)
|
||||
{
|
||||
m_objectsToSynchronize = objectCount;
|
||||
m_objectsSynchronized = 0;
|
||||
|
@ -767,6 +765,15 @@ namespace OpenSim.Client.MXP.ClientStack
|
|||
//throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnClean()
|
||||
{
|
||||
if (OnLogout != null)
|
||||
OnLogout(this);
|
||||
|
||||
if (OnConnectionClosed != null)
|
||||
OnConnectionClosed(this);
|
||||
}
|
||||
|
||||
public void Close(bool ShutdownCircuit)
|
||||
{
|
||||
m_log.Info("[MXP ClientStack] Close Called with SC=" + ShutdownCircuit);
|
||||
|
@ -780,16 +787,6 @@ namespace OpenSim.Client.MXP.ClientStack
|
|||
Session.SetStateDisconnected();
|
||||
}
|
||||
|
||||
// Handle OpenSim cleanup
|
||||
if (ShutdownCircuit)
|
||||
{
|
||||
if (OnConnectionClosed != null)
|
||||
OnConnectionClosed(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Scene.RemoveClient(AgentId);
|
||||
}
|
||||
}
|
||||
|
||||
public void Kick(string message)
|
||||
|
@ -800,6 +797,17 @@ namespace OpenSim.Client.MXP.ClientStack
|
|||
public void Start()
|
||||
{
|
||||
Scene.AddNewClient(this);
|
||||
|
||||
// Mimicking LLClientView which gets always set appearance from client.
|
||||
OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene;
|
||||
AvatarAppearance appearance;
|
||||
scene.GetAvatarAppearance(this,out appearance);
|
||||
List<byte> visualParams = new List<byte>();
|
||||
foreach (byte visualParam in appearance.VisualParams)
|
||||
{
|
||||
visualParams.Add(visualParam);
|
||||
}
|
||||
OnSetAppearance(appearance.Texture.ToBytes(), visualParams);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
|
|
|
@ -38,21 +38,20 @@ 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 int m_port = 1253;
|
||||
//private int m_ticks = 0;
|
||||
private bool m_shutdown = false;
|
||||
private MXPPacketServer m_server;
|
||||
|
||||
private IConfigSource m_config;
|
||||
private readonly Timer m_ticker = new Timer(100);
|
||||
private readonly Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
||||
private int m_port = 1253;
|
||||
|
||||
private MXPPacketServer m_server;
|
||||
private readonly Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
||||
private readonly Timer m_ticker = new Timer(100);
|
||||
private bool m_shutdown = false;
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
|
@ -88,13 +87,6 @@ namespace OpenSim.Client.MXP
|
|||
|
||||
if (!m_shutdown)
|
||||
m_ticker.Start();
|
||||
|
||||
// Commenting this at because of the excess flood to log.
|
||||
// TODO: Add ini file option.
|
||||
/*if (++ticks % 100 == 0)
|
||||
{
|
||||
server.PrintDebugInformation();
|
||||
}*/
|
||||
}
|
||||
|
||||
public void Close()
|
||||
|
|
|
@ -40,6 +40,7 @@ using OpenSim.Client.MXP.ClientStack;
|
|||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Framework.Communications;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace OpenSim.Client.MXP.PacketHandler
|
||||
{
|
||||
|
@ -214,17 +215,6 @@ namespace OpenSim.Client.MXP.PacketHandler
|
|||
|
||||
#region Processing
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public void Process()
|
||||
{
|
||||
ProcessMessages();
|
||||
|
@ -243,7 +233,7 @@ namespace OpenSim.Client.MXP.PacketHandler
|
|||
|
||||
foreach (MXPClientView clientView in m_sessionsToRemove)
|
||||
{
|
||||
clientView.Scene.RemoveClient(clientView.AgentId);
|
||||
clientView.OnClean();
|
||||
m_clients.Remove(clientView);
|
||||
m_sessions.Remove(clientView.Session);
|
||||
}
|
||||
|
@ -251,59 +241,6 @@ namespace OpenSim.Client.MXP.PacketHandler
|
|||
m_sessionsToRemove.Clear();
|
||||
}
|
||||
|
||||
public bool AuthoriseUser(string participantName, string password, UUID sceneId, out UUID userId, out string firstName, out string lastName)
|
||||
{
|
||||
userId = UUID.Zero;
|
||||
firstName = "";
|
||||
lastName = "";
|
||||
|
||||
if (!m_scenes.ContainsKey(sceneId))
|
||||
{
|
||||
m_log.Info("Login failed as region was not found: " + sceneId);
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] nameParts=participantName.Split(' ');
|
||||
if (nameParts.Length != 2)
|
||||
{
|
||||
m_log.Info("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];
|
||||
|
||||
UserProfileData userProfile = m_scenes[sceneId].CommsManager.UserService.GetUserProfile(firstName, lastName);
|
||||
if (userProfile == null && !m_accountsAuthenticate)
|
||||
{
|
||||
userId = ((UserManagerBase)m_scenes[sceneId].CommsManager.UserService).AddUser(firstName, lastName, "test", "", 1000, 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (userProfile == null)
|
||||
{
|
||||
m_log.Info("Login failed as user was not found: " + participantName);
|
||||
return false;
|
||||
}
|
||||
userId = userProfile.ID;
|
||||
}
|
||||
|
||||
if (m_accountsAuthenticate)
|
||||
{
|
||||
if (!password.StartsWith("$1$"))
|
||||
{
|
||||
password = "$1$" + Util.Md5Hash(password);
|
||||
}
|
||||
password = password.Remove(0, 3); //remove $1$
|
||||
string s = Util.Md5Hash(password + ":" + userProfile.PasswordSalt);
|
||||
return (userProfile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
|
||||
|| userProfile.PasswordHash.Equals(password, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessMessages()
|
||||
{
|
||||
if (m_transmitter.PendingSessionCount > 0)
|
||||
|
@ -327,9 +264,9 @@ namespace OpenSim.Client.MXP.PacketHandler
|
|||
|
||||
JoinRequestMessage joinRequestMessage = (JoinRequestMessage) message;
|
||||
|
||||
UUID userId;
|
||||
string firstName;
|
||||
string lastName;
|
||||
m_log.Info("[MXP ClientStack] Session join request: " + session.SessionId + " (" +
|
||||
(session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
|
||||
session.RemoteEndPoint.Port + ")");
|
||||
|
||||
if (joinRequestMessage.BubbleId == Guid.Empty)
|
||||
{
|
||||
|
@ -337,7 +274,7 @@ namespace OpenSim.Client.MXP.PacketHandler
|
|||
{
|
||||
if (scene.RegionInfo.RegionName == joinRequestMessage.BubbleName)
|
||||
{
|
||||
m_log.Info("Resolved region by name: " + joinRequestMessage.BubbleName + " (" + scene.RegionInfo.RegionID+")");
|
||||
m_log.Info("[MXP ClientStack] Resolved region by name: " + joinRequestMessage.BubbleName + " (" + scene.RegionInfo.RegionID + ")");
|
||||
joinRequestMessage.BubbleId = scene.RegionInfo.RegionID.Guid;
|
||||
}
|
||||
}
|
||||
|
@ -345,47 +282,71 @@ namespace OpenSim.Client.MXP.PacketHandler
|
|||
|
||||
if (joinRequestMessage.BubbleId == Guid.Empty)
|
||||
{
|
||||
m_log.Warn("Failed to resolve region by name: "+joinRequestMessage.BubbleName);
|
||||
m_log.Warn("[MXP ClientStack] Failed to resolve region by name: " + joinRequestMessage.BubbleName);
|
||||
}
|
||||
|
||||
bool authorized = AuthoriseUser(joinRequestMessage.ParticipantName,
|
||||
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;
|
||||
}
|
||||
|
||||
UserProfileData user=null;
|
||||
UUID userId=UUID.Zero;
|
||||
string firstName=null;
|
||||
string lastName=null;
|
||||
bool authorized = regionExists?AuthoriseUser(joinRequestMessage.ParticipantName,
|
||||
joinRequestMessage.ParticipantPassphrase,
|
||||
new UUID(joinRequestMessage.BubbleId), out userId, out firstName, out lastName);
|
||||
new UUID(joinRequestMessage.BubbleId), out userId, out firstName, out lastName, out user)
|
||||
:false;
|
||||
|
||||
if (authorized)
|
||||
{
|
||||
Scene target = m_scenes[new UUID(joinRequestMessage.BubbleId)];
|
||||
|
||||
Scene scene = m_scenes[sceneId];
|
||||
UUID mxpSessionID = UUID.Random();
|
||||
|
||||
m_log.Info("[MXP ClientStack] Session join request success: " + session.SessionId + " (" +
|
||||
(session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
|
||||
session.RemoteEndPoint.Port + ")");
|
||||
|
||||
AcceptConnection(session, joinRequestMessage, mxpSessionID,userId);
|
||||
m_log.Info("[MXP ClientStack] Attaching UserAgent to UserProfile...");
|
||||
AttachUserAgentToUserProfile(session, mxpSessionID, sceneId, user);
|
||||
m_log.Info("[MXP ClientStack] Attached UserAgent to UserProfile.");
|
||||
m_log.Info("[MXP ClientStack] Preparing Scene to Connection...");
|
||||
PrepareSceneForConnection(mxpSessionID, sceneId, user);
|
||||
m_log.Info("[MXP ClientStack] Prepared Scene to Connection.");
|
||||
m_log.Info("[MXP ClientStack] Accepting connection...");
|
||||
AcceptConnection(session, joinRequestMessage, mxpSessionID, userId);
|
||||
m_log.Info("[MXP ClientStack] Accepted connection.");
|
||||
|
||||
MXPClientView client = new MXPClientView(session, mxpSessionID,userId, target,
|
||||
firstName, lastName);
|
||||
m_log.Info("[MXP ClientStack] Created Client");
|
||||
m_log.Info("[MXP ClientStack] Creating ClientView....");
|
||||
MXPClientView client = new MXPClientView(session, mxpSessionID, userId, scene, firstName, lastName);
|
||||
m_clients.Add(client);
|
||||
m_log.Info("[MXP ClientStack] Created ClientView.");
|
||||
|
||||
m_log.Info("[MXP ClientStack] Adding to Scene");
|
||||
target.ClientManager.Add(client.CircuitCode, client);
|
||||
|
||||
m_log.Info("[MXP ClientStack] Initialising...");
|
||||
m_log.Info("[MXP ClientStack] Adding ClientView to Scene...");
|
||||
scene.ClientManager.Add(client.CircuitCode, client);
|
||||
m_log.Info("[MXP ClientStack] Added ClientView to Scene.");
|
||||
|
||||
client.MXPSentSynchronizationBegin(m_scenes[new UUID(joinRequestMessage.BubbleId)].SceneContents.GetTotalObjectsCount());
|
||||
|
||||
client.MXPSendSynchronizationBegin(m_scenes[new UUID(joinRequestMessage.BubbleId)].SceneContents.GetTotalObjectsCount());
|
||||
|
||||
m_log.Info("[MXP ClientStack] Starting ClientView...");
|
||||
try
|
||||
{
|
||||
client.Start();
|
||||
} catch( Exception e)
|
||||
m_log.Info("[MXP ClientStack] Started ClientView.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Info(e);
|
||||
}
|
||||
|
||||
m_log.Info("[MXP ClientStack] Connected");
|
||||
//target.EventManager.TriggerOnNewClient(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -512,6 +473,138 @@ namespace OpenSim.Client.MXP.PacketHandler
|
|||
session.SetStateDisconnected();
|
||||
}
|
||||
|
||||
public bool AuthoriseUser(string participantName, string password, UUID sceneId, out UUID userId, out string firstName, out string lastName, out UserProfileData userProfile)
|
||||
{
|
||||
userId = UUID.Zero;
|
||||
firstName = "";
|
||||
lastName = "";
|
||||
userProfile = null;
|
||||
|
||||
string[] nameParts = participantName.Split(' ');
|
||||
if (nameParts.Length != 2)
|
||||
{
|
||||
m_log.Info("[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];
|
||||
|
||||
userProfile = m_scenes[sceneId].CommsManager.UserService.GetUserProfile(firstName, lastName);
|
||||
if (userProfile == null && !m_accountsAuthenticate)
|
||||
{
|
||||
userId = ((UserManagerBase)m_scenes[sceneId].CommsManager.UserService).AddUser(firstName, lastName, "test", "", 1000, 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (userProfile == null)
|
||||
{
|
||||
m_log.Info("Login failed as user was not found: " + participantName);
|
||||
return false;
|
||||
}
|
||||
userId = userProfile.ID;
|
||||
}
|
||||
|
||||
if (m_accountsAuthenticate)
|
||||
{
|
||||
if (!password.StartsWith("$1$"))
|
||||
{
|
||||
password = "$1$" + Util.Md5Hash(password);
|
||||
}
|
||||
password = password.Remove(0, 3); //remove $1$
|
||||
string s = Util.Md5Hash(password + ":" + userProfile.PasswordSalt);
|
||||
return (userProfile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
|
||||
|| userProfile.PasswordHash.Equals(password, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void AttachUserAgentToUserProfile(Session session, UUID sessionId, UUID sceneId, UserProfileData userProfile)
|
||||
{
|
||||
Scene scene = m_scenes[sceneId];
|
||||
CommunicationsManager commsManager = m_scenes[sceneId].CommsManager;
|
||||
UserManagerBase userService = (UserManagerBase)commsManager.UserService;
|
||||
|
||||
UserAgentData agent = new UserAgentData();
|
||||
|
||||
// User connection
|
||||
agent.AgentOnline = true;
|
||||
agent.AgentIP = session.RemoteEndPoint.Address.ToString();
|
||||
agent.AgentPort = (uint)session.RemoteEndPoint.Port;
|
||||
|
||||
agent.SecureSessionID = UUID.Random();
|
||||
agent.SessionID = sessionId;
|
||||
|
||||
// Profile UUID
|
||||
agent.ProfileID = userProfile.ID;
|
||||
|
||||
// Current location/position/alignment
|
||||
if (userProfile.CurrentAgent != null)
|
||||
{
|
||||
agent.Region = userProfile.CurrentAgent.Region;
|
||||
agent.Handle = userProfile.CurrentAgent.Handle;
|
||||
agent.Position = userProfile.CurrentAgent.Position;
|
||||
agent.LookAt = userProfile.CurrentAgent.LookAt;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.Region = userProfile.HomeRegionID;
|
||||
agent.Handle = userProfile.HomeRegion;
|
||||
agent.Position = userProfile.HomeLocation;
|
||||
agent.LookAt = userProfile.HomeLookAt;
|
||||
}
|
||||
|
||||
// What time did the user login?
|
||||
agent.LoginTime = Util.UnixTimeSinceEpoch();
|
||||
agent.LogoutTime = 0;
|
||||
|
||||
userProfile.CurrentAgent = agent;
|
||||
|
||||
userService.CommitAgent(ref userProfile);
|
||||
}
|
||||
|
||||
private void PrepareSceneForConnection(UUID sessionId, UUID sceneId, UserProfileData userProfile)
|
||||
{
|
||||
Scene scene = m_scenes[sceneId];
|
||||
CommunicationsManager commsManager = m_scenes[sceneId].CommsManager;
|
||||
UserManagerBase userService = (UserManagerBase)commsManager.UserService;
|
||||
|
||||
AgentCircuitData agent = new AgentCircuitData();
|
||||
agent.AgentID = userProfile.ID;
|
||||
agent.firstname = userProfile.FirstName;
|
||||
agent.lastname = userProfile.SurName;
|
||||
agent.SessionID = sessionId;
|
||||
agent.SecureSessionID = userProfile.CurrentAgent.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 = userService.GetUserAppearance(userProfile.ID);
|
||||
|
||||
if (agent.Appearance == null)
|
||||
{
|
||||
m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname);
|
||||
agent.Appearance = new AvatarAppearance();
|
||||
}
|
||||
|
||||
scene.NewUserConnection(agent);
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue