Example #1
0
        /// <summary>
        /// Disconnect from this simulator
        /// </summary>
        public void Disconnect(bool sendCloseCircuit)
        {
            if (connected)
            {
                connected = false;

                // Destroy the timers
                if (AckTimer != null)
                {
                    AckTimer.Dispose();
                }
                if (StatsTimer != null)
                {
                    StatsTimer.Dispose();
                }
                if (PingTimer != null)
                {
                    PingTimer.Dispose();
                }

                // Kill the current CAPS system
                if (Caps != null)
                {
                    Caps.Disconnect(true);
                    Caps = null;
                }

                if (sendCloseCircuit)
                {
                    // Try to send the CloseCircuit notice
                    CloseCircuitPacket close = new CloseCircuitPacket();
                    UDPPacketBuffer    buf   = new UDPPacketBuffer(ipEndPoint, false);
                    buf.Data       = close.ToBytes();
                    buf.DataLength = buf.Data.Length;

                    AsyncBeginSend(buf);
                }

                // Shut the socket communication down
                Stop();
            }
        }
Example #2
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="capsEvent">Capability event name unregister the 
 /// handler for</param>
 /// <param name="eventHandler">Callback to unregister</param>
 public void UnregisterEvent(string capsEvent, Caps.EventQueueCallback eventHandler)
 {
     lock (_EventTable)
     {
         if (_EventTable.ContainsKey(capsEvent) && _EventTable[capsEvent] != null)
             _EventTable[capsEvent] -= eventHandler;
     }
 }
Example #3
0
 /// <summary>
 /// Register an event handler
 /// </summary>
 /// <remarks>Use String.Empty to fire this event on every CAPS event</remarks>
 /// <param name="capsEvent">Capability event name to register the 
 /// handler for</param>
 /// <param name="eventHandler">Callback to fire</param>
 public void RegisterEvent(string capsEvent, Caps.EventQueueCallback eventHandler)
 {
     lock (_EventTable)
     {
         if (_EventTable.ContainsKey(capsEvent))
             _EventTable[capsEvent] += eventHandler;
         else
             _EventTable[capsEvent] = eventHandler;
     }
 }
 /// <summary>
 /// Unregister a CAPS event handler. This is a low level event interface
 /// and should only be used if you are doing something not supported in
 /// libsecondlife
 /// </summary>
 /// <param name="capsEvent">Name of the CAPS event this callback is
 /// registered with</param>
 /// <param name="callback">Callback to stop firing events for</param>
 public void UnregisterEventCallback(string capsEvent, Caps.EventQueueCallback callback)
 {
     CapsEvents.UnregisterEvent(capsEvent, callback);
 }
Example #5
0
        /// <summary>
        /// Disconnect from this simulator
        /// </summary>
        public void Disconnect(bool sendCloseCircuit)
        {
            if (connected)
            {
                connected = false;

                // Destroy the timers
                if (AckTimer != null) AckTimer.Dispose();
                if (StatsTimer != null) StatsTimer.Dispose();
                if (PingTimer != null) PingTimer.Dispose();

                // Kill the current CAPS system
                if (Caps != null)
                {
                    Caps.Disconnect(true);
                    Caps = null;
                }

                if (sendCloseCircuit)
                {
                    // Try to send the CloseCircuit notice
                    CloseCircuitPacket close = new CloseCircuitPacket();
                    UDPPacketBuffer buf = new UDPPacketBuffer(ipEndPoint, false);
                    buf.Data = close.ToBytes();
                    buf.DataLength = buf.Data.Length;

                    AsyncBeginSend(buf);
                }

                // Shut the socket communication down
                Stop();
            }
        }
Example #6
0
 /// <summary>
 /// Register a CAPS event handler
 /// </summary>
 /// <param name="callback">Callback to fire when a CAPS event is received</param>
 public void RegisterEventCallback(Caps.EventQueueCallback callback)
 {
     lock (EventQueueCallbacks) EventQueueCallbacks.Add(callback);
 }
Example #7
0
        public void SetSeedCaps(string seedcaps)
        {
            if (Caps != null)
            {
                if (Caps._SeedCapsURI == seedcaps) return;

                Client.Log("Unexpected change of seed capability", Helpers.LogLevel.Warning);
                Caps.Disconnect(true);
                Caps = null;
            }

            if (Client.Settings.ENABLE_CAPS)
            {
                // Connect to the new CAPS system
                if (!String.IsNullOrEmpty(seedcaps))
                    Caps = new Caps(this, seedcaps);
                else
                    Client.Log("Setting up a sim without a valid capabilities server!", Helpers.LogLevel.Error);
            }

        }
Example #8
0
        /// <summary>
        /// Disconnect from this simulator
        /// </summary>
        public void Disconnect()
        {
            connected = false;
            AckTimer.Stop();
            StatsTimer.Stop();
            if (Client.Settings.SEND_PINGS) PingTimer.Stop();

            // Kill the current CAPS system
            if (SimCaps != null)
            {
                SimCaps.Disconnect(true);
                SimCaps = null;
            }


            // Make sure the socket is hooked up
            if (!Connection.Connected) return;

            // Try to send the CloseCircuit notice
            CloseCircuitPacket close = new CloseCircuitPacket();

            // There's a high probability of this failing if the network is
            // disconnecting, so don't even bother logging the error
            try { Connection.Send(close.ToBytes()); }
            catch (SocketException) { }

            // Shut the socket communication down
            try { Connection.Shutdown(SocketShutdown.Both); }
            catch (SocketException) { }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="loginParams"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public bool Login(Dictionary<string, object> loginParams, string url)
        {
            // Rebuild the Dictionary<> in to a Hashtable for compatibility with XmlRpcCS
            Hashtable loginValues = new Hashtable(loginParams.Count);
            foreach (KeyValuePair<string, object> kvp in loginParams)
            {
                if (kvp.Value is IList)
                {
                    IList list = ((IList)kvp.Value);
                    ArrayList array = new ArrayList(list.Count);
                    foreach (object obj in list)
                    {
                        array.Add(obj);
                    }
                    loginValues[kvp.Key] = array;
                }
                else
                {
                    loginValues[kvp.Key] = kvp.Value;
                }
            }

            XmlRpcResponse result;
            XmlRpcRequest xmlrpc = new XmlRpcRequest();
            xmlrpc.MethodName = "login_to_simulator";
            xmlrpc.Params.Clear();
            xmlrpc.Params.Add(loginValues);

            try
            {
                result = (XmlRpcResponse)xmlrpc.Send(url, LoginTimeout);
            }
            catch (Exception e)
            {
                LoginError = "XML-RPC Error: " + e.Message;
                LoginValues.Clear();
                return false;
            }

            if (result.IsFault)
            {
                Client.Log("Fault " + result.FaultCode + ": " + result.FaultString, Helpers.LogLevel.Error);
                LoginError = "XML-RPC Fault: " + result.FaultCode + ": " + result.FaultString;
                LoginValues.Clear();
                return false;
            }

            Hashtable values = (Hashtable)result.Value;
            foreach (DictionaryEntry entry in values)
            {
                LoginValues[(string)entry.Key] = entry.Value;
            }

            if ((string)LoginValues["login"] == "indeterminate")
            {
                //FIXME: We need to do another XML-RPC, handle this case
                LoginError = "Got a redirect, login with the official client to update";
                return false;
            }
            else if ((string)LoginValues["login"] == "false")
            {
                LoginError = LoginValues["reason"] + ": " + LoginValues["message"];
                return false;
            }
            else if ((string)LoginValues["login"] != "true")
            {
                LoginError = "Unknown error";
                return false;
            }

            System.Text.RegularExpressions.Regex LLSDtoJSON =
                new System.Text.RegularExpressions.Regex(@"('|r([0-9])|r(\-))");
            string json;
            Dictionary<string, object> jsonObject = null;
            LLVector3 vector = LLVector3.Zero;
            LLVector3 posVector = LLVector3.Zero;
            LLVector3 lookatVector = LLVector3.Zero;
            ulong regionHandle = 0;

            try
            {
                if (LoginValues.ContainsKey("look_at"))
                {
                    // Replace LLSD variables with object representations

                    // Convert LLSD string to JSON
                    json = "{vector:" + LLSDtoJSON.Replace((string)LoginValues["look_at"], "$2") + "}";

                    // Convert JSON string to a JSON object
                    jsonObject = JsonFacade.fromJSON(json);
                    JSONArray jsonVector = (JSONArray)jsonObject["vector"];

                    // Convert the JSON object to an LLVector3
                    vector = new LLVector3(Convert.ToSingle(jsonVector[0], CultureInfo.InvariantCulture),
                        Convert.ToSingle(jsonVector[1], CultureInfo.InvariantCulture), Convert.ToSingle(jsonVector[2], CultureInfo.InvariantCulture));

                    LoginValues["look_at"] = vector;
                }
            }
            catch (Exception e)
            {
                Client.Log(e.ToString(), Helpers.LogLevel.Warning);
                LoginValues["look_at"] = null;
            }

            try
            {
                if (LoginValues.ContainsKey("home"))
                {
                    Dictionary<string, object> home;

                    // Convert LLSD string to JSON
                    json = LLSDtoJSON.Replace((string)LoginValues["home"], "$2");

                    // Convert JSON string to an object
                    jsonObject = JsonFacade.fromJSON(json);

                    // Create the position vector
                    JSONArray array = (JSONArray)jsonObject["position"];
                    posVector = new LLVector3(Convert.ToSingle(array[0], CultureInfo.InvariantCulture), Convert.ToSingle(array[1], CultureInfo.InvariantCulture),
                        Convert.ToSingle(array[2], CultureInfo.InvariantCulture));

                    // Create the look_at vector
                    array = (JSONArray)jsonObject["look_at"];
                    lookatVector = new LLVector3(Convert.ToSingle(array[0], CultureInfo.InvariantCulture),
                        Convert.ToSingle(array[1], CultureInfo.InvariantCulture), Convert.ToSingle(array[2], CultureInfo.InvariantCulture));

                    // Create the regionhandle
                    array = (JSONArray)jsonObject["region_handle"];
                    regionHandle = Helpers.UIntsToLong((uint)(int)array[0], (uint)(int)array[1]);

                    Client.Self.Position = posVector;
                    Client.Self.LookAt = lookatVector;

                    // Create a dictionary to hold the home values
                    home = new Dictionary<string, object>();
                    home["position"] = posVector;
                    home["look_at"] = lookatVector;
                    home["region_handle"] = regionHandle;
                    LoginValues["home"] = home;
                }
            }
            catch (Exception e)
            {
                Client.Log(e.ToString(), Helpers.LogLevel.Warning);
                LoginValues["home"] = null;
            }

            try
            {
                this.AgentID = new LLUUID((string)LoginValues["agent_id"]);
                this.SessionID = new LLUUID((string)LoginValues["session_id"]);
                Client.Self.ID = this.AgentID;
                // Names are wrapped in quotes now, have to strip those
                Client.Self.FirstName = ((string)LoginValues["first_name"]).Trim(new char[] { '"' });
                Client.Self.LastName = ((string)LoginValues["last_name"]).Trim(new char[] { '"' });
                Client.Self.LookAt = vector;
                Client.Self.HomePosition = posVector;
                Client.Self.HomeLookAt = lookatVector;

                // Get Inventory Root Folder
                Client.Log("Pulling root folder UUID from login data.", Helpers.LogLevel.Debug);
                ArrayList alInventoryRoot = (ArrayList)LoginValues["inventory-root"];
                Hashtable htInventoryRoot = (Hashtable)alInventoryRoot[0];
                Client.Self.InventoryRootFolderUUID = new LLUUID((string)htInventoryRoot["folder_id"]);

                // Connect to the sim given in the login reply
                Simulator simulator = new Simulator(Client, this.Callbacks, (uint)(int)LoginValues["circuit_code"],
                    IPAddress.Parse((string)LoginValues["sim_ip"]), (int)LoginValues["sim_port"]);
                if (!simulator.Connected)
                {
                    LoginError = "Unable to connect to the simulator";
                    return false;
                }

                simulator.Region.Handle = regionHandle;
                CurrentSim = simulator;

                // Simulator is successfully connected, add it to the list and set it as default
                Simulators.Add(simulator);

            if(LoginValues.ContainsKey("seed_capability") && (string)LoginValues["seed_capability"] != "") {
            CurrentCaps = new Caps(Client,simulator.Region,(string)LoginValues["seed_capability"], EventQueueCallbacks);
            }

                // Move our agent in to the sim to complete the connection
                Client.Self.CompleteAgentMovement(simulator);

                SendInitialPackets();

                DisconnectTimer.Start();
                connected = true;
                if (OnConnected != null) OnConnected(this.Client);
                return true;
            }
            catch (Exception e)
            {
                Client.Log("Login error: " + e.ToString(), Helpers.LogLevel.Error);
                return false;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="circuitCode"></param>
        /// <param name="setDefault"></param>
        /// <returns></returns>
        public Simulator Connect(IPAddress ip, ushort port, uint circuitCode, bool setDefault, string seedcaps)
        {
            Simulator simulator = new Simulator(Client, this.Callbacks, circuitCode, ip, (int)port);

            if (!simulator.Connected)
            {
                simulator = null;
                return null;
            }

            lock (Simulators)
            {
                Simulators.Add(simulator);
            }

            if (setDefault)
            {
                CurrentSim = simulator;
            if(CurrentCaps != null) CurrentCaps.Disconnect();
            CurrentCaps = null;
            if(seedcaps != null && seedcaps != "")
            CurrentCaps = new Caps(Client,simulator.Region,seedcaps,EventQueueCallbacks);
            }

            DisconnectTimer.Start();
            connected = true;
            return simulator;
        }
        /// <summary>
        /// Shutdown will disconnect all the sims except for the current sim
        /// first, and then kill the connection to CurrentSim.
        /// </summary>
        private void Shutdown()
        {
            Client.Log("NetworkManager shutdown initiated", Helpers.LogLevel.Info);

            lock (Simulators)
            {
                // Disconnect all simulators except the current one
                foreach (Simulator simulator in Simulators)
                {
                    // Don't disconnect the current sim, we'll use LogoutRequest for that
                    if (simulator != null && simulator != CurrentSim)
                    {
                        DisconnectSim(simulator);

                        // Fire the SimDisconnected event if a handler is registered
                        if (OnSimDisconnected != null)
                        {
                            OnSimDisconnected(simulator, DisconnectType.NetworkTimeout);
                        }
                    }
                }

                Simulators.Clear();
            }

            if (CurrentSim != null)
            {
                DisconnectSim(CurrentSim);
                CurrentSim = null;
            }
            if (CurrentCaps != null) {
            CurrentCaps.Disconnect(); CurrentCaps = null;
            }
        }
Example #12
0
	    private void EventQueueHandler(string message, Hashtable body, Caps caps)
        {
            if (message == "TeleportFinish" && body.ContainsKey("Info"))
            {
                ArrayList infoList = (ArrayList)body["Info"];
                Hashtable info = (Hashtable)infoList[0];

                // Backwards compatibility hack 
                TeleportFinishPacket packet = new TeleportFinishPacket();

                packet.Info.SimIP = Helpers.BytesToUIntBig((byte[])info["SimIP"]);
                packet.Info.LocationID = Helpers.BytesToUInt((byte[])info["LocationID"]);
                packet.Info.TeleportFlags = Helpers.BytesToUInt((byte[])info["TeleportFlags"]);
                packet.Info.AgentID = (LLUUID)info["AgentID"];
                packet.Info.RegionHandle = Helpers.BytesToUInt64((byte[])info["RegionHandle"]);
                packet.Info.SeedCapability = Helpers.StringToField((string)info["SeedCapability"]);
                packet.Info.SimPort = (ushort)(int)info["SimPort"];
                packet.Info.SimAccess = (byte)(int)info["SimAccess"];

                Client.DebugLog(String.Format(
                    "Received a TeleportFinish event from {0}, SimIP: {1}, Location: {2}, RegionHandle: {3}", 
                    caps.Simulator.ToString(), packet.Info.SimIP, packet.Info.LocationID, packet.Info.RegionHandle));

                TeleportHandler(packet, Client.Network.CurrentSim);
	    }
	    else if(message == "EstablishAgentCommunication" && Client.Settings.MULTIPLE_SIMS)
	    {
		string ipAndPort = (string)body["sim-ip-and-port"];
		string[] pieces = ipAndPort.Split(':');
		IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(pieces[0]), Convert.ToInt32(pieces[1]));
		Simulator sim = Client.Network.FindSimulator(endPoint);
		if(sim == null) {
			Client.Log("Got EstablishAgentCommunication for unknown sim "
				+ ipAndPort,  Helpers.LogLevel.Error);
		}
		else
		{
			Client.Log("Got EstablishAgentCommunication for sim "
				+ ipAndPort + ", seed cap " + (string)body["seed-capability"],  Helpers.LogLevel.Info);
			sim.setSeedCaps((string)body["seed-capability"]);
		}
            }
            else
            {
                Client.Log("Received unhandled event " + message + " in the EventQueueHandler", 
                    Helpers.LogLevel.Warning);
            }
	    }