Now this code is possibly not exactly the same as what I have on my test box at home and I'm looking at both vanilla opensim and aurora so it's not a 100% match but it should give some ideas as to what's going on. Anyways.. let's dig through the code:
2.1 Looking at HandleUseCircuitCode(object o) (follows). You will notice that this calls AddNewClient with a circuitcode packet and a remoteendpoint, so these are possibly necessary. Right now we don't call this function in our code, but instead mimic in the background and our c ircuitcode is built up manually and passed to the scene manually instead of coming in as a packet. We also have a null endpoint. So definitely we can say that the flow is different here though the steps are similar. So next, jump past the code to section 2.2 to see what AddNewClient with two parameters does.
private void HandleUseCircuitCode(object o)
{
object[] array = (object[])o;
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
// Begin the process of adding the client to the simulator
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
// Acknowledge the UseCircuitCode packet
SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
}
2.2 two parameter AddNewClient. What does this do? Let's see... It checks circuitcode to see if it's valid, asking for a sessionID, a remoteEndPoint and sessioninfo which it uses to call AddClient. Right off the bat our sessionID is 00000's, our remoteEndPoint is null and we haven't set sessionInfo either. So we possibly need to look into that. It also Authenticates the response with sessioninfo and also checks to see if the client is authorized before it calls AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo). So let's jump past this code block to 2.3
private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
{
UUID agentID = useCircuitCode.CircuitCode.ID;
UUID sessionID = useCircuitCode.CircuitCode.SessionID;
uint circuitCode = useCircuitCode.CircuitCode.Code;
if (m_scene.RegionStatus != RegionStatus.SlaveScene)
{
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(useCircuitCode, out sessionInfo))
{
AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
}
else
{
// Don't create circuits for unauthorized clients
m_log.WarnFormat(
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
}
}
else
{
// Slave regions don't accept new clients
m_log.Debug("[LLUDPSERVER]: Slave region " + m_scene.RegionInfo.RegionName + " ignoring UseCircuitCode packet");
}
}
2.3 In this section we're looking at AddClient. There are a bunch of things we are not doing here such as adding a LogoutHandler event as well as doing client.Start in the vanilla code. I'd like to get a look at client.Start to see what it does but I don't seem to have that code here so instead I'm going to look at the Aurora version which I can see more easily on the web. The aurora version has the line m_scene.AddNewClient(client) which is an overriden single parameter version. So in 2.4 we'll look at that: m_scene.AddNewClient
protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
{
// Create the LLUDPClient
LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
IClientAPI existingClient;
if (!m_scene.TryGetClient(agentID, out existingClient))
{
// Create the LLClientView
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
// Start the IClientAPI
client.Start();
}
else
{
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
udpClient.AgentID, remoteEndPoint, circuitCode);
}
}
2.4 This is the aurora code for m_scene.AddNewClient which is pretty interesting and might in fact have most of what we need. I think I should look at this and do a compare of what I have in the relevant section of NPCModule because this might be the majority of code needed and it appears like it gives a significant number of clues as to what we might be missing. For example: it's pulling the appearance out of the circuitdata whereas I know we have null for appearance in circuit data. Maybe need to run a test and intercept this code to see what a real client has in it's circuit data….
00547 ///
00548 /// Adding a New Client and Create a Presence for it.
00549 ///
00550 /// 00551 public void AddNewClient(IClientAPI client)
00552 {
00553 System.Net.IPEndPoint ep = (System.Net.IPEndPoint)client.GetClientEP();
00554 AgentCircuitData aCircuit = AuthenticateHandler.AuthenticateSession(client.SessionId, client.AgentId, client.CircuitCode, ep);
00555
00556 if (aCircuit == null) // no good, didn't pass NewUserConnection successfully
00557 return;
00558
00559 //Create the scenepresence, then update it with any info that we have about it
00560 ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client);
00561 lock (m_incomingChildAgentData)
00562 {
00563 if (m_incomingChildAgentData.ContainsKey(sp.UUID))
00564 {
00565 //Found info, update the agent then remove it
00566 sp.ChildAgentDataUpdate(m_incomingChildAgentData[sp.UUID]);
00567 m_incomingChildAgentData.Remove(sp.UUID);
00568 }
00569 }
00570 //Make sure the appearanace is updated
00571 if (aCircuit != null)
00572 sp.Appearance = aCircuit.Appearance;
00573 sp.IsChildAgent = aCircuit.child;
00574
00575 m_clientManager.Add(client);
00576
00577 //Trigger events
00578 m_eventManager.TriggerOnNewPresence(sp);
00579
00580 if (GetScenePresence(client.AgentId) != null)
00581 {
00582 EventManager.TriggerOnNewClient(client);
00583 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0)
00584 EventManager.TriggerOnClientLogin(client);
00585 }
00586
00587 //Add the client to login stats
00588 ILoginMonitor monitor = (ILoginMonitor)RequestModuleInterface
00589 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0 && monitor != null)
00590 {
00591 monitor.AddSuccessfulLogin();
00592 }
00593 }
No comments:
Post a Comment