Exemple #1
0
        protected void ParseFault(XmlNode faultNode)
        {
            Parameters = new XmlRpcParameterArray();

            if (faultNode.Name != "fault")
            {
                throw new Exception($"WARN XmlRpcResponse.ParseFault: Unexpected node name, expected \"fault\" found \"{faultNode.Name}\".");
            }

            if (faultNode.ChildNodes.Count != 1)
            {
                throw new Exception("WARN XmlRpcResponse.ParseFault: Unexpected number of nodes in fault.");
            }

            XmlNode valueNode = faultNode.FirstChild;

            if (valueNode.Name != "value")
            {
                throw new Exception($"WARN XmlRpcResponse.ParseFault: Unexpected node name, expected \"value\" found \"{valueNode.Name}\".");
            }
            if (valueNode.ChildNodes.Count != 1)
            {
                throw new Exception("WARN XmlRpcResponse.ParseFault: Unexpected number of nodes in value.");
            }

            XmlRpcValue faultValue = XmlRpcValue.FromXmlNode(valueNode.FirstChild);

            if (faultValue is XmlRpcStruct == false)
            {
                throw new Exception("WARN XmlRpcResponse.ParseFault: Unexpected value type.");
            }

            XmlRpcStruct fault = (XmlRpcStruct)faultValue;

            if (fault.Has("faultCode") == false)
            {
                throw new Exception("WARN XmlRpcResponse.ParseFault: Fault response has no faultCode.");
            }
            if (fault["faultCode"] is XmlRpcInteger == false)
            {
                throw new Exception("WARN XmlRpcResponse.ParseFault: faultCode is not an integer.");
            }
            FaultCode = ((XmlRpcInteger)fault["faultCode"]).Value;

            if (fault.Has("faultString") == false)
            {
                throw new Exception("WARN XmlRpcResponse.ParseFault: Fault response has no faultString.");
            }
            if (fault["faultString"] is XmlRpcString == false)
            {
                throw new Exception("WARN XmlRpcResponse.ParseFault: faultString is not a string.");
            }
            FaultString = ((XmlRpcString)fault["faultString"]).Value;
        }
Exemple #2
0
    public async Task <LoginResponse> Connect(string uri, Credential credential, Slurl slurl = null, bool getInventoryLibrary = true, bool godMode = false)
    {
        if (slurl == null)
        {
            slurl = new Slurl(Slurl.SIM_LOCATION_LAST);
        }
        Logger.LogDebug($"INFO Login.Connect: Connecting {credential.First} {credential.Last} using {uri}.");

        XmlRpcParameterArray parameters = CreateLoginParameters(credential, slurl, getInventoryLibrary, godMode);

        XmlRpcResponse response = await XmlRpcClient.Call(uri, "login_to_simulator", parameters);

        LoginResponse loginResponse = new LoginResponse();

        if (response.FaultCode != 0)
        {
            loginResponse.LoginSucceeded  = false;
            loginResponse.LoginFailReason = response.FaultCode.ToString();
            loginResponse.Message         = response.FaultString;
            loginResponse.MessageId       = "XmlRpcError";
            return(loginResponse);
        }

        if (response.Parameters.Count != 1 || (response.Parameters[0] is XmlRpcStruct == false))
        {
            loginResponse.LoginSucceeded  = false;
            loginResponse.LoginFailReason = "500";
            loginResponse.Message         = "Login response contained incorrect parameters.";
            loginResponse.MessageId       = "XmlRpcError";
            return(loginResponse);
        }

        XmlRpcStruct responseData = (XmlRpcStruct)response.Parameters[0];

        if (responseData.Has("login") == false ||
            (responseData["login"] is XmlRpcString == false) ||
            ((XmlRpcString)responseData["login"]).Value != "true")
        {
            loginResponse.LoginSucceeded  = false;
            loginResponse.LoginFailReason = responseData["reason"]?.AsString;
            loginResponse.Message         = responseData["message"]?.AsString;
            loginResponse.MessageId       = responseData["message_id"]?.AsString;
            return(loginResponse);
        }

        Logger.LogInfo("Login.Connect: Connection was successful.");

        if (ProcessLoginSuccessResponse(responseData, loginResponse))
        {
            loginResponse.LoginSucceeded = true;
            return(loginResponse);
        }
        else
        {
            // Yet another error
        }

        return(loginResponse);
    }
Exemple #3
0
    protected bool ProcessLoginSuccessResponse(XmlRpcStruct responseData, LoginResponse loginResponse)
    {
        // TODO: Parse benefits
        // TODO: Parse "udp_blacklist"

        loginResponse.SessionId = Guid.Empty;
        if (responseData.Has("session_id"))
        {
            loginResponse.SessionId = Guid.Parse(responseData["session_id"].AsString);
        }
        if (loginResponse.SessionId == Guid.Empty)
        {
            return(false);
        }

        #region Agent
        loginResponse.AgentId = Guid.Empty;
        if (responseData.Has("agent_id"))
        {
            loginResponse.AgentId = Guid.Parse(responseData["agent_id"].AsString);
        }
        if (loginResponse.AgentId == Guid.Empty)
        {
            return(false);
        }

        // TODO: Send agentId and agentSessionId to the LLUrlEntryParcel


        //Guid agentSecureSessionId = Guid.Empty;
        //if (responseData.Has("secure_session_id"))
        //{
        //    agentSecureSessionId = Guid.Parse(responseData["secure_session_id"].AsString);
        //}

        string agentUserName = "";
        if (responseData.Has("first_name"))
        {
            agentUserName           = responseData["first_name"].AsString.Replace('"', ' ').Trim(); // NOTE: login.cgi sends " to force names that look like numbers into strings
            loginResponse.FirstName = agentUserName;
        }
        if (responseData.Has("last_name"))
        {
            string lastName = responseData["last_name"].AsString.Replace('"', ' ').Trim(); // NOTE: login.cgi sends " to force names that look like numbers into strings
            loginResponse.LastName = lastName;
            if (lastName != "Resident")
            {
                agentUserName += $" {lastName}";
            }
        }
        string displayName = "";
        if (responseData.Has("display_name"))
        {
            displayName = responseData["display_name"].AsString.Replace('"', ' ').Trim(); // NOTE: login.cgi sends " to force names that look like numbers into strings
        }
        else if (agentUserName != "")
        {
            displayName = agentUserName;
        }
        else
        {
            // TODO: Construct display name from request credentials
        }
        loginResponse.DisplayName = displayName;

        //RegionMaturityLevel regionMaturityLevel = RegionMaturityLevel.A; // TODO: Get from settings
        //if (responseData.Has("agent_access_max"))
        //{
        //    Enum.TryParse<RegionMaturityLevel>(responseData["agent_access_max"].AsString, out regionMaturityLevel);
        //}

        //RegionMaturityLevel preferredMaturityLevel = RegionMaturityLevel.A; // TODO: Get from settings
        //if (responseData.Has("agent_region_access"))
        //{
        //    Enum.TryParse<RegionMaturityLevel>(responseData["agent_region_access"].AsString, out preferredMaturityLevel);
        //}

        //string agentStartLocation = "";
        //if (responseData.Has("start_location"))
        //{
        //    agentStartLocation = responseData["start_location"].AsString;
        //}

        //Vector3 agentStartLookAt = Vector3.forward;
        //if (responseData.Has("look_at"))
        //{
        //    // TODO: Decode "[r0.75787899999999996936,r0.65239599999999997593,r0]"
        //}

        #endregion Agent

        #region Region
        if (responseData.Has("region_x") && responseData.Has("region_y"))
        {
            UInt32 x = UInt32.Parse(responseData["region_x"].AsString);
            UInt32 y = UInt32.Parse(responseData["region_y"].AsString);
            loginResponse.RegionHandle = new RegionHandle(x, y);
        }

        loginResponse.CircuitCode = 0;
        loginResponse.SimIp       = "";
        loginResponse.SimPort     = 0;

        if (responseData.Has("circuit_code"))
        {
            loginResponse.CircuitCode = UInt32.Parse(responseData["circuit_code"].AsString);
        }
        if (responseData.Has("sim_ip"))
        {
            loginResponse.SimIp = responseData["sim_ip"].AsString;
        }
        if (responseData.Has("sim_port"))
        {
            loginResponse.SimPort = int.Parse(responseData["sim_port"].AsString);
        }
        if (loginResponse.CircuitCode == 0 || string.IsNullOrEmpty(loginResponse.SimIp) || loginResponse.SimPort == 0)
        {
            return(false);
        }

        if (responseData.Has("seed_capability"))
        {
            loginResponse.SeedCapability = responseData["seed_capability"]?.AsString;
        }

        #endregion Region

        #region BuddyList

        if (responseData.Has("buddy-list") && responseData["buddy-list"] is XmlRpcArray)
        {
            loginResponse.BuddyList.Clear();
            foreach (XmlRpcValue value in (XmlRpcArray)responseData["buddy-list"])
            {
                if (value is XmlRpcStruct == false ||
                    ((XmlRpcStruct)value).Has("buddy_id") == false || ((XmlRpcStruct)value)["buddy_id"]           is XmlRpcString == false ||
                    ((XmlRpcStruct)value).Has("buddy_rights_given") == false || ((XmlRpcStruct)value)["buddy_rights_given"] is XmlRpcInteger == false ||
                    ((XmlRpcStruct)value).Has("buddy_rights_has") == false || ((XmlRpcStruct)value)["buddy_rights_has"]   is XmlRpcInteger == false
                    )
                {
                    continue;
                }

                XmlRpcStruct        data      = (XmlRpcStruct)value;
                Guid                buddyId   = Guid.Parse(data["buddy_id"].AsString);
                Relationship.Rights toAgent   = (Relationship.Rights)((XmlRpcInteger)data["buddy_rights_given"]).Value;
                Relationship.Rights fromAgent = (Relationship.Rights)((XmlRpcInteger)data["buddy_rights_has"]).Value;
                loginResponse.BuddyList[buddyId] = new Relationship(toAgent, fromAgent, false);
            }
        }
        #endregion BuddyList

        // TODO: Parse more things, see llstartup.cpp line 3439 and onwards

        // TODO: Non-existent Inventory.RootFolderId is a fail

        return(true);
    }