diff options
| author | Nat Goodspeed <nat@lindenlab.com> | 2009-05-13 23:35:42 +0000 | 
|---|---|---|
| committer | Nat Goodspeed <nat@lindenlab.com> | 2009-05-13 23:35:42 +0000 | 
| commit | 3975de991d2afa2ed903ac28bcc91246dfb22c20 (patch) | |
| tree | 3f6d7d09d05768d7f1095ecb7602e688e8fa8a3b /indra | |
| parent | a087bbeda3229745cb625fbd1106438572dfee4a (diff) | |
svn merge -r113003:119136 svn+ssh://svn.lindenlab.com/svn/linden/branches/login-api/login-api-2 svn+ssh://svn.lindenlab.com/svn/linden/branches/login-api/login-api-3
(finish)
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/lleventcoro_test.cpp | 827 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 1368 | ||||
| -rw-r--r-- | indra/newview/tests/llxmlrpclistener_test.cpp | 2 | 
5 files changed, 1281 insertions, 932 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d3d75f78df..62476fd59d 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -228,4 +228,4 @@ target_link_libraries(  ADD_BUILD_TEST(lllazy llcommon)  ADD_BUILD_TEST(lleventfilter llcommon) -ADD_BUILD_TEST(coroutine llcommon) +ADD_BUILD_TEST(lleventcoro llcommon) diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp new file mode 100644 index 0000000000..cd39ac4df3 --- /dev/null +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -0,0 +1,827 @@ +/** + * @file   coroutine_test.cpp + * @author Nat Goodspeed + * @date   2009-04-22 + * @brief  Test for coroutine. + *  + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * Copyright (c) 2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +/*****************************************************************************/ +//  test<1>() is cloned from a Boost.Coroutine example program whose copyright +//  info is reproduced here: +/*---------------------------------------------------------------------------*/ +//  Copyright (c) 2006, Giovanni P. Deretta +// +//  This code may be used under either of the following two licences: +// +//  Permission is hereby granted, free of charge, to any person obtaining a copy  +//  of this software and associated documentation files (the "Software"), to deal  +//  in the Software without restriction, including without limitation the rights  +//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  +//  copies of the Software, and to permit persons to whom the Software is  +//  furnished to do so, subject to the following conditions: +// +//  The above copyright notice and this permission notice shall be included in  +//  all copies or substantial portions of the Software. +// +//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  +//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  +//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL  +//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  +//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  +//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN  +//  THE SOFTWARE. OF SUCH DAMAGE. +// +//  Or: +// +//  Distributed under the Boost Software License, Version 1.0. +//  (See accompanying file LICENSE_1_0.txt or copy at +//  http://www.boost.org/LICENSE_1_0.txt) +/*****************************************************************************/ + +// On some platforms, Boost.Coroutine must #define magic symbols before +// #including platform-API headers. Naturally, that's ineffective unless the +// Boost.Coroutine #include is the *first* #include of the platform header. +// That means that client code must generally #include Boost.Coroutine headers +// before anything else. +#include <boost/coroutine/coroutine.hpp> +// Normally, lleventcoro.h obviates future.hpp. We only include this because +// we implement a "by hand" test of future functionality. +#include <boost/coroutine/future.hpp> +#include <boost/bind.hpp> +#include <boost/range.hpp> +#include <iostream> +#include <string> + +#include "../test/lltut.h" +#include "llsd.h" +#include "llevents.h" +#include "tests/wrapllerrs.h" +#include "stringize.h" +#include "lleventcoro.h" + +/***************************************************************************** +*   Debugging stuff +*****************************************************************************/ +// This class is intended to illuminate entry to a given block, exit from the +// same block and checkpoints along the way. It also provides a convenient +// place to turn std::cout output on and off. +class Debug +{ +public: +    Debug(const std::string& block): +        mBlock(block) +    { +        (*this)("entry"); +    } + +    ~Debug() +    { +        (*this)("exit"); +    } + +    void operator()(const std::string& status) +    { +//      std::cout << mBlock << ' ' << status << std::endl; +    } + +private: +    const std::string mBlock; +}; + +// It's often convenient to use the name of the enclosing function as the name +// of the Debug block. +#define DEBUG Debug debug(__FUNCTION__) + +// These BEGIN/END macros are specifically for debugging output -- please +// don't assume you must use such for coroutines in general! They only help to +// make control flow (as well as exception exits) explicit. +#define BEGIN                                   \ +{                                               \ +    DEBUG;                                      \ +    try + +#define END                                             \ +    catch (...)                                         \ +    {                                                   \ +/*      std::cout << "*** exceptional " << std::flush; */    \ +        throw;                                          \ +    }                                                   \ +} + +/***************************************************************************** +*   from the banana.cpp example program borrowed for test<1>() +*****************************************************************************/ +namespace coroutines = boost::coroutines; +using coroutines::coroutine; + +template<typename Iter> +bool match(Iter first, Iter last, std::string match) { +  std::string::iterator i = match.begin(); +  i != match.end(); +  for(; (first != last) && (i != match.end()); ++i) { +    if (*first != *i) +      return false; +    ++first; +  } +  return i == match.end(); +} + +template<typename BidirectionalIterator>  +BidirectionalIterator  +match_substring(BidirectionalIterator begin,  +		BidirectionalIterator end,  +		std::string xmatch, +		BOOST_DEDUCED_TYPENAME coroutine<BidirectionalIterator(void)>::self& self) {  +  BidirectionalIterator begin_ = begin; +  for(; begin != end; ++begin)  +    if(match(begin, end, xmatch)) { +      self.yield(begin); +    } +  return end; +}  + +typedef coroutine<std::string::iterator(void)> match_coroutine_type; + +/***************************************************************************** +*   Test helpers +*****************************************************************************/ +// I suspect this will be typical of coroutines used in Linden software +typedef boost::coroutines::coroutine<void()> coroutine_type; + +/// Simulate an event API whose response is immediate: sent on receipt of the +/// initial request, rather than after some delay. This is the case that +/// distinguishes postAndWait() from calling post(), then calling +/// waitForEventOn(). +class ImmediateAPI +{ +public: +    ImmediateAPI(): +        mPump("immediate", true) +    { +        mPump.listen("API", boost::bind(&ImmediateAPI::operator(), this, _1)); +    } + +    LLEventPump& getPump() { return mPump; } + +    // Invoke this with an LLSD map containing: +    // ["value"]: Integer value. We will reply with ["value"] + 1. +    // ["reply"]: Name of LLEventPump on which to send success response. +    // ["error"]: Name of LLEventPump on which to send error response. +    // ["fail"]: Presence of this key selects ["error"], else ["success"] as +    // the name of the pump on which to send the response. +    bool operator()(const LLSD& event) const +    { +        LLSD::Integer value(event["value"]); +        LLSD::String replyPumpName(event.has("fail")? "error" : "reply"); +        LLEventPumps::instance().obtain(event[replyPumpName]).post(value + 1); +        return false; +    } + +private: +    LLEventStream mPump; +}; + +/***************************************************************************** +*   TUT +*****************************************************************************/ +namespace tut +{ +    struct coroutine_data +    { +        // Define coroutine bodies as methods here so they can use ensure*() + +        void explicit_wait(coroutine_type::self& self) +        { +            BEGIN +            { +                // ... do whatever preliminary stuff must happen ... + +                // declare the future +                boost::coroutines::future<LLSD> future(self); +                // tell the future what to wait for +                LLTempBoundListener connection( +                    LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::coroutines::make_callback(future)))); +                ensure("Not yet", ! future); +                // attempting to dereference ("resolve") the future causes the calling +                // coroutine to wait for it +                debug("about to wait"); +                result = *future; +                ensure("Got it", future); +            } +            END +        } + +        void waitForEventOn1(coroutine_type::self& self) +        { +            BEGIN +            { +                result = waitForEventOn(self, "source"); +            } +            END +        } + +        void waitForEventOn2(coroutine_type::self& self) +        { +            BEGIN +            { +                LLEventWithID pair = waitForEventOn(self, "reply", "error"); +                result = pair.first; +                which  = pair.second; +                debug(STRINGIZE("result = " << result << ", which = " << which)); +            } +            END +        } + +        void postAndWait1(coroutine_type::self& self) +        { +            BEGIN +            { +                result = postAndWait(self, +                                     LLSD().insert("value", 17), // request event +                                     immediateAPI.getPump(),     // requestPump +                                     "reply1",                   // replyPump +                                     "reply");                   // request["reply"] = name +            } +            END +        } + +        void postAndWait2(coroutine_type::self& self) +        { +            BEGIN +            { +                LLEventWithID pair = ::postAndWait2(self, +                                                    LLSD().insert("value", 18), +                                                    immediateAPI.getPump(), +                                                    "reply2", +                                                    "error2", +                                                    "reply", +                                                    "error"); +                result = pair.first; +                which  = pair.second; +                debug(STRINGIZE("result = " << result << ", which = " << which)); +            } +            END +        } + +        void postAndWait2_1(coroutine_type::self& self) +        { +            BEGIN +            { +                LLEventWithID pair = ::postAndWait2(self, +                                                    LLSD().insert("value", 18).insert("fail", LLSD()), +                                                    immediateAPI.getPump(), +                                                    "reply2", +                                                    "error2", +                                                    "reply", +                                                    "error"); +                result = pair.first; +                which  = pair.second; +                debug(STRINGIZE("result = " << result << ", which = " << which)); +            } +            END +        } + +        void coroPump(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPump waiter; +                replyName = waiter.getName(); +                result = waiter.wait(self); +            } +            END +        } + +        void coroPumpPost(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPump waiter; +                result = waiter.postAndWait(self, LLSD().insert("value", 17), +                                            immediateAPI.getPump(), "reply"); +            } +            END +        } + +        void coroPumps(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                replyName = waiter.getName0(); +                errorName = waiter.getName1(); +                LLEventWithID pair(waiter.wait(self)); +                result = pair.first; +                which  = pair.second; +            } +            END +        } + +        void coroPumpsNoEx(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                replyName = waiter.getName0(); +                errorName = waiter.getName1(); +                result = waiter.waitWithException(self); +            } +            END +        } + +        void coroPumpsEx(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                replyName = waiter.getName0(); +                errorName = waiter.getName1(); +                try +                { +                    result = waiter.waitWithException(self); +                    debug("no exception"); +                } +                catch (const LLErrorEvent& e) +                { +                    debug(STRINGIZE("exception " << e.what())); +                    errordata = e.getData(); +                } +            } +            END +        } + +        void coroPumpsNoLog(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                replyName = waiter.getName0(); +                errorName = waiter.getName1(); +                result = waiter.waitWithLog(self); +            } +            END +        } + +        void coroPumpsLog(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                replyName = waiter.getName0(); +                errorName = waiter.getName1(); +                WrapLL_ERRS capture; +                try +                { +                    result = waiter.waitWithLog(self); +                    debug("no exception"); +                } +                catch (const WrapLL_ERRS::FatalException& e) +                { +                    debug(STRINGIZE("exception " << e.what())); +                    threw = e.what(); +                } +            } +            END +        } + +        void coroPumpsPost(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                LLEventWithID pair(waiter.postAndWait(self, LLSD().insert("value", 23), +                                                      immediateAPI.getPump(), "reply", "error")); +                result = pair.first; +                which  = pair.second; +            } +            END +        } + +        void coroPumpsPost_1(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                LLEventWithID pair( +                    waiter.postAndWait(self, LLSD().insert("value", 23).insert("fail", LLSD()), +                                       immediateAPI.getPump(), "reply", "error")); +                result = pair.first; +                which  = pair.second; +            } +            END +        } + +        void coroPumpsPostNoEx(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                result = waiter.postAndWaitWithException(self, LLSD().insert("value", 8), +                                                         immediateAPI.getPump(), "reply", "error"); +            } +            END +        } + +        void coroPumpsPostEx(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                try +                { +                    result = waiter.postAndWaitWithException(self, +                        LLSD().insert("value", 9).insert("fail", LLSD()), +                        immediateAPI.getPump(), "reply", "error"); +                    debug("no exception"); +                } +                catch (const LLErrorEvent& e) +                { +                    debug(STRINGIZE("exception " << e.what())); +                    errordata = e.getData(); +                } +            } +            END +        } + +        void coroPumpsPostNoLog(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                result = waiter.postAndWaitWithLog(self, LLSD().insert("value", 30), +                                                   immediateAPI.getPump(), "reply", "error"); +            } +            END +        } + +        void coroPumpsPostLog(coroutine_type::self& self) +        { +            BEGIN +            { +                LLCoroEventPumps waiter; +                WrapLL_ERRS capture; +                try +                { +                    result = waiter.postAndWaitWithLog(self, +                        LLSD().insert("value", 31).insert("fail", LLSD()), +                        immediateAPI.getPump(), "reply", "error"); +                    debug("no exception"); +                } +                catch (const WrapLL_ERRS::FatalException& e) +                { +                    debug(STRINGIZE("exception " << e.what())); +                    threw = e.what(); +                } +            } +            END +        } + +        void ensure_done(coroutine_type& coro) +        { +            ensure("coroutine complete", ! coro); +        } + +        ImmediateAPI immediateAPI; +        std::string replyName, errorName, threw; +        LLSD result, errordata; +        int which; +    }; +    typedef test_group<coroutine_data> coroutine_group; +    typedef coroutine_group::object object; +    coroutine_group coroutinegrp("coroutine"); + +    template<> template<> +    void object::test<1>() +    { +        set_test_name("From banana.cpp example program in Boost.Coroutine distro"); +        std::string buffer = "banananana";  +        std::string match = "nana";  +        std::string::iterator begin = buffer.begin(); +        std::string::iterator end = buffer.end(); + +#if defined(BOOST_CORO_POSIX_IMPL) +//      std::cout << "Using Boost.Coroutine " << BOOST_CORO_POSIX_IMPL << '\n'; +#else +//      std::cout << "Using non-Posix Boost.Coroutine implementation" << std::endl; +#endif + +        typedef std::string::iterator signature(std::string::iterator,  +                                                std::string::iterator,  +                                                std::string, +                                                match_coroutine_type::self&); + +        coroutine<std::string::iterator(void)> matcher +            (boost::bind(static_cast<signature*>(match_substring),  +                         begin,  +                         end,  +                         match,  +                         _1));  + +        std::string::iterator i = matcher(); +/*==========================================================================*| +        while(matcher && i != buffer.end()) { +            std::cout <<"Match at: "<< std::distance(buffer.begin(), i)<<'\n';  +            i = matcher(); +        } +|*==========================================================================*/ +        size_t matches[] = { 2, 4, 6 }; +        for (size_t *mi(boost::begin(matches)), *mend(boost::end(matches)); +             mi != mend; ++mi, i = matcher()) +        { +            ensure("more", matcher); +            ensure("found", i != buffer.end()); +            ensure_equals("value", std::distance(buffer.begin(), i), *mi); +        } +        ensure("done", ! matcher); +    } + +    template<> template<> +    void object::test<2>() +    { +        set_test_name("explicit_wait"); +        DEBUG; + +        // Construct the coroutine instance that will run explicit_wait. +        // Pass the ctor a callable that accepts the coroutine_type::self +        // param passed by the library. +        coroutine_type coro(boost::bind(&coroutine_data::explicit_wait, this, _1)); +        // Start the coroutine +        coro(std::nothrow); +        // When the coroutine waits for the event pump, it returns here. +        debug("about to send"); +        // Satisfy the wait. +        LLEventPumps::instance().obtain("source").post("received"); +        // Now wait for the coroutine to complete. +        ensure_done(coro); +        // ensure the coroutine ran and woke up again with the intended result +        ensure_equals(result.asString(), "received"); +    } + +    template<> template<> +    void object::test<3>() +    { +        set_test_name("waitForEventOn1"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn1, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain("source").post("received"); +        debug("back from send"); +        ensure_done(coro); +        ensure_equals(result.asString(), "received"); +    } + +    template<> template<> +    void object::test<4>() +    { +        set_test_name("waitForEventOn2 reply"); +        { +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain("reply").post("received"); +        debug("back from send"); +        ensure_done(coro); +        } +        ensure_equals(result.asString(), "received"); +        ensure_equals("which pump", which, 0); +    } + +    template<> template<> +    void object::test<5>() +    { +        set_test_name("waitForEventOn2 error"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::waitForEventOn2, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain("error").post("badness"); +        debug("back from send"); +        ensure_done(coro); +        ensure_equals(result.asString(), "badness"); +        ensure_equals("which pump", which, 1); +    } + +    template<> template<> +    void object::test<6>() +    { +        set_test_name("coroPump"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPump, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain(replyName).post("received"); +        debug("back from send"); +        ensure_done(coro); +        ensure_equals(result.asString(), "received"); +    } + +    template<> template<> +    void object::test<7>() +    { +        set_test_name("coroPumps reply"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain(replyName).post("received"); +        debug("back from send"); +        ensure_done(coro); +        ensure_equals(result.asString(), "received"); +        ensure_equals("which pump", which, 0); +    } + +    template<> template<> +    void object::test<8>() +    { +        set_test_name("coroPumps error"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumps, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain(errorName).post("badness"); +        debug("back from send"); +        ensure_done(coro); +        ensure_equals(result.asString(), "badness"); +        ensure_equals("which pump", which, 1); +    } + +    template<> template<> +    void object::test<9>() +    { +        set_test_name("coroPumpsNoEx"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoEx, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain(replyName).post("received"); +        debug("back from send"); +        ensure_done(coro); +        ensure_equals(result.asString(), "received"); +    } + +    template<> template<> +    void object::test<10>() +    { +        set_test_name("coroPumpsEx"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsEx, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain(errorName).post("badness"); +        debug("back from send"); +        ensure_done(coro); +        ensure("no result", result.isUndefined()); +        ensure_equals("got error", errordata.asString(), "badness"); +    } + +    template<> template<> +    void object::test<11>() +    { +        set_test_name("coroPumpsNoLog"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsNoLog, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain(replyName).post("received"); +        debug("back from send"); +        ensure_done(coro); +        ensure_equals(result.asString(), "received"); +    } + +    template<> template<> +    void object::test<12>() +    { +        set_test_name("coroPumpsLog"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsLog, this, _1)); +        coro(std::nothrow); +        debug("about to send"); +        LLEventPumps::instance().obtain(errorName).post("badness"); +        debug("back from send"); +        ensure_done(coro); +        ensure("no result", result.isUndefined()); +        ensure_contains("got error", threw, "badness"); +    } + +    template<> template<> +    void object::test<13>() +    { +        set_test_name("postAndWait1"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::postAndWait1, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 18); +    } + +    template<> template<> +    void object::test<14>() +    { +        set_test_name("postAndWait2"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 19); +        ensure_equals(which, 0); +    } + +    template<> template<> +    void object::test<15>() +    { +        set_test_name("postAndWait2_1"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::postAndWait2_1, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 19); +        ensure_equals(which, 1); +    } + +    template<> template<> +    void object::test<16>() +    { +        set_test_name("coroPumpPost"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpPost, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 18); +    } + +    template<> template<> +    void object::test<17>() +    { +        set_test_name("coroPumpsPost reply"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 24); +        ensure_equals("which pump", which, 0); +    } + +    template<> template<> +    void object::test<18>() +    { +        set_test_name("coroPumpsPost error"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPost_1, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 24); +        ensure_equals("which pump", which, 1); +    } + +    template<> template<> +    void object::test<19>() +    { +        set_test_name("coroPumpsPostNoEx"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoEx, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 9); +    } + +    template<> template<> +    void object::test<20>() +    { +        set_test_name("coroPumpsPostEx"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostEx, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure("no result", result.isUndefined()); +        ensure_equals("got error", errordata.asInteger(), 10); +    } + +    template<> template<> +    void object::test<21>() +    { +        set_test_name("coroPumpsPostNoLog"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostNoLog, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure_equals(result.asInteger(), 31); +    } + +    template<> template<> +    void object::test<22>() +    { +        set_test_name("coroPumpsPostLog"); +        DEBUG; +        coroutine_type coro(boost::bind(&coroutine_data::coroPumpsPostLog, this, _1)); +        coro(std::nothrow); +        ensure_done(coro); +        ensure("no result", result.isUndefined()); +        ensure_contains("got error", threw, "32"); +    } +} // namespace tut diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 388bf38d61..606f145d3b 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -292,10 +292,9 @@ void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)  {  	// store off config state, as we might quit soon  	gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);	 +	gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE);  	std::ostringstream message; - -	//*TODO:translate  	std::string msg;  	if (!auth_msg.empty())  	{ @@ -409,6 +408,7 @@ bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD&  	query_map["userserver"] = LLViewerLogin::getInstance()->getGridLabel();  	query_map["channel"] = gSavedSettings.getString("VersionChannelName");  	// *TODO constantize this guy +	// *NOTE: This URL is also used in win_setup/lldownloader.cpp  	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);  	if(LLAppViewer::sUpdaterInfo) @@ -495,9 +495,7 @@ bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD&  	system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */  #elif LL_LINUX || LL_SOLARIS -	OSMessageBox("Automatic updating is not yet implemented for Linux.\n" -		"Please download the latest version from www.secondlife.com.", -		LLStringUtil::null, OSMB_OK); +	OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK);  #endif  	// *REMOVE:Mani - Saving for reference... @@ -520,13 +518,9 @@ std::string construct_start_string()  						<< LLURLSimString::sInstance.mZ);  		start = xml_escape_string(unescaped_start);  	} -	else if (gSavedSettings.getBOOL("LoginLastLocation")) -	{ -		start = "last"; -	}  	else  	{ -		start = "home"; +		start = gSavedSettings.getString("LoginLocation");  	}  	return start;  } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 4cf94b5bc4..eddc23b0c4 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -55,7 +55,6 @@  #include "llviewercontrol.h"  #include "lldir.h"  #include "llerrorcontrol.h" -#include "llfiltersd2xmlrpc.h"  #include "llfloaterreg.h"  #include "llfocusmgr.h"  #include "llhttpsender.h" @@ -102,7 +101,6 @@  #include "llfloaterhud.h"  #include "llfloaterland.h"  #include "llfloatertopobjects.h" -#include "llfloatertos.h"  #include "llfloaterworldmap.h"  #include "llgesturemgr.h"  #include "llgroupmgr.h" @@ -114,6 +112,7 @@  #include "llinventoryview.h"  #include "llkeyboard.h"  #include "llloginhandler.h"			// gLoginHandler, SLURL support +#include "lllogininstance.h" // Host the login module.  #include "llpanellogin.h"  #include "llprefsim.h"  #include "llmutelist.h" @@ -134,7 +133,6 @@  #include "llsecondlifeurls.h"  #include "llselectmgr.h"  #include "llsky.h" -#include "llsrv.h"  #include "llstatview.h"  #include "lltrans.h"  #include "llstatusbar.h"		// sendMoneyBalanceRequest(), owns L$ balance @@ -147,7 +145,6 @@  #include "llurlsimstring.h"  #include "llurlhistory.h"  #include "llurlwhitelist.h" -#include "lluserauth.h"  #include "llvieweraudio.h"  #include "llviewerassetstorage.h"  #include "llviewercamera.h" @@ -188,6 +185,8 @@  #include "llwearable.h"  #include "llinventorybridge.h" +#include "lllogin.h" +  #if LL_LIBXUL_ENABLED  #include "llmozlib.h"  #endif // LL_LIBXUL_ENABLED @@ -201,12 +200,12 @@  // exported globals  //  bool gAgentMovementCompleted = false; -std::string gInitialOutfit; -std::string gInitialOutfitGender;  std::string SCREEN_HOME_FILENAME = "screen_home.bmp";  std::string SCREEN_LAST_FILENAME = "screen_last.bmp"; +LLPointer<LLImageGL> gStartImageGL; +  //  // Imported globals  // @@ -216,12 +215,6 @@ extern S32 gStartImageHeight;  //  // local globals  // - -LLPointer<LLImageGL> gStartImageGL; - -static LLHost gAgentSimHost; -static BOOL gSkipOptionalUpdate = FALSE; -  static bool gGotUseCircuitCodeAck = false;  static std::string sInitialOutfit;  static std::string sInitialOutfitGender;	// "male" or "female" @@ -230,6 +223,17 @@ static bool gUseCircuitCallbackCalled = false;  EStartupState LLStartUp::gStartupState = STATE_FIRST; +// *NOTE:Mani - to reconcile with giab changes... +static std::string gFirstname; +static std::string gLastname; +static std::string gPassword; + +static U64 gFirstSimHandle = 0; +static LLHost gFirstSim; +static std::string gFirstSimSeedCap; +static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f); +static std::string gAgentStartLocation = "safe"; +  //  // local function declaration @@ -242,8 +246,6 @@ void show_first_run_dialog();  bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);  void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);  bool login_alert_status(const LLSD& notification, const LLSD& response); -void update_app(BOOL mandatory, const std::string& message); -bool update_dialog_callback(const LLSD& notification, const LLSD& response);  void login_packet_failed(void**, S32 result);  void use_circuit_callback(void**, S32 result);  void register_viewer_callbacks(LLMessageSystem* msg); @@ -253,6 +255,7 @@ void init_start_screen(S32 location_id);  void release_start_screen();  void reset_login();  void apply_udp_blacklist(const std::string& csv); +bool process_login_success_response();  void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group)  { @@ -309,9 +312,6 @@ void update_texture_fetch()  	gImageList.updateImages(0.10f);  } -static std::vector<std::string> sAuthUris; -static S32 sAuthUriNum = -1; -  // Returns false to skip other idle processing. Should only return  // true when all initialization done.  bool idle_startup() @@ -330,23 +330,11 @@ bool idle_startup()  	// auth/transform loop will do.  	static F32 progress = 0.10f; -	static std::string auth_method;  	static std::string auth_desc;  	static std::string auth_message; -	static std::string firstname; -	static std::string lastname; -	static LLUUID web_login_key; -	static std::string password; -	static std::vector<const char*> requested_options; - -	static U64 first_sim_handle = 0; -	static LLHost first_sim; -	static std::string first_sim_seed_cap;  	static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);  	static LLVector3 agent_start_position_region(10.f, 10.f, 10.f);		// default for when no space server -	static LLVector3 agent_start_look_at(1.0f, 0.f, 0.f); -	static std::string agent_start_location = "safe";  	// last location by default  	static S32  agent_location_id = START_LOCATION_ID_LAST; @@ -354,7 +342,7 @@ bool idle_startup()  	static bool show_connect_box = true; -	static bool stipend_since_login = false; +	//static bool stipend_since_login = false;  	// HACK: These are things from the main loop that usually aren't done  	// until initialization is complete, but need to be done here for things @@ -375,12 +363,7 @@ bool idle_startup()  	LLStringUtil::setLocale (LLTrans::getString(system)); -	if (gNoRender) -	{ -		// HACK, skip optional updates if you're running drones -		gSkipOptionalUpdate = TRUE; -	} -	else +	if (!gNoRender)  	{  		// Update images?  		gImageList.updateImages(0.01f); @@ -675,24 +658,23 @@ bool idle_startup()  			|| !gLoginHandler.getWebLoginKey().isNull() )  		{  			// We have at least some login information on a SLURL -			firstname = gLoginHandler.getFirstName(); -			lastname = gLoginHandler.getLastName(); -			web_login_key = gLoginHandler.getWebLoginKey(); +			gFirstname = gLoginHandler.getFirstName(); +			gLastname = gLoginHandler.getLastName();  			// Show the login screen if we don't have everything  			show_connect_box =  -				firstname.empty() || lastname.empty() || web_login_key.isNull(); +				gFirstname.empty() || gLastname.empty();  		}          else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)          {              LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo"); -			firstname = cmd_line_login[0].asString(); -			lastname = cmd_line_login[1].asString(); +			gFirstname = cmd_line_login[0].asString(); +			gLastname = cmd_line_login[1].asString();  			LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str());  			char md5pass[33];               /* Flawfinder: ignore */  			pass.hex_digest(md5pass); -			password = md5pass; +			gPassword = md5pass;  #ifdef USE_VIEWER_AUTH  			show_connect_box = true; @@ -703,9 +685,9 @@ bool idle_startup()          }  		else if (gSavedSettings.getBOOL("AutoLogin"))  		{ -			firstname = gSavedSettings.getString("FirstName"); -			lastname = gSavedSettings.getString("LastName"); -			password = LLStartUp::loadPasswordFromDisk(); +			gFirstname = gSavedSettings.getString("FirstName"); +			gLastname = gSavedSettings.getString("LastName"); +			gPassword = LLStartUp::loadPasswordFromDisk();  			gSavedSettings.setBOOL("RememberPassword", TRUE);  #ifdef USE_VIEWER_AUTH @@ -718,9 +700,9 @@ bool idle_startup()  		{  			// if not automatically logging in, display login dialog  			// a valid grid is selected -			firstname = gSavedSettings.getString("FirstName"); -			lastname = gSavedSettings.getString("LastName"); -			password = LLStartUp::loadPasswordFromDisk(); +			gFirstname = gSavedSettings.getString("FirstName"); +			gLastname = gSavedSettings.getString("LastName"); +			gPassword = LLStartUp::loadPasswordFromDisk();  			show_connect_box = true;  		} @@ -757,7 +739,7 @@ bool idle_startup()  			// Load all the name information out of the login view  			// NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't  			// show the login view until login_show() is called below.   -			// LLPanelLogin::getFields(firstname, lastname, password); +			// LLPanelLogin::getFields(gFirstname, gLastname, gPassword);  			if (gNoRender)  			{ @@ -769,7 +751,7 @@ bool idle_startup()  			// Show the login dialog  			login_show();  			// connect dialog is already shown, so fill in the names -			LLPanelLogin::setFields( firstname, lastname, password); +			LLPanelLogin::setFields( gFirstname, gLastname, gPassword);  			LLPanelLogin::giveFocus(); @@ -826,37 +808,29 @@ bool idle_startup()  	if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())  	{ -		//reset the values that could have come in from a slurl -		if (!gLoginHandler.getWebLoginKey().isNull()) -		{ -			firstname = gLoginHandler.getFirstName(); -			lastname = gLoginHandler.getLastName(); -			web_login_key = gLoginHandler.getWebLoginKey(); -		} -				  		if (show_connect_box)  		{  			// TODO if not use viewer auth  			// Load all the name information out of the login view -			LLPanelLogin::getFields(&firstname, &lastname, &password); +			LLPanelLogin::getFields(&gFirstname, &gLastname, &gPassword);  			// end TODO  			// HACK: Try to make not jump on login  			gKeyboard->resetKeys();  		} -		if (!firstname.empty() && !lastname.empty()) +		if (!gFirstname.empty() && !gLastname.empty())  		{ -			gSavedSettings.setString("FirstName", firstname); -			gSavedSettings.setString("LastName", lastname); +			gSavedSettings.setString("FirstName", gFirstname); +			gSavedSettings.setString("LastName", gLastname); -			LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << LL_ENDL; -			gDebugInfo["LoginName"] = firstname + " " + lastname;	 +			LL_INFOS("AppInit") << "Attempting login as: " << gFirstname << " " << gLastname << LL_ENDL; +			gDebugInfo["LoginName"] = gFirstname + " " + gLastname;	  		}  		// create necessary directories  		// *FIX: these mkdir's should error check -		gDirUtilp->setLindenUserDir(firstname, lastname); +		gDirUtilp->setLindenUserDir(gFirstname, gLastname);      	LLFile::mkdir(gDirUtilp->getLindenUserDir());          // Set PerAccountSettingsFile to the default value. @@ -887,7 +861,7 @@ bool idle_startup()  			gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));		  		} -		gDirUtilp->setPerAccountChatLogsDir(firstname, lastname); +		gDirUtilp->setPerAccountChatLogsDir(gFirstname, gLastname);  		LLFile::mkdir(gDirUtilp->getChatLogsDir());  		LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); @@ -908,13 +882,6 @@ bool idle_startup()  		if (show_connect_box)  		{ -			if ( LLPanelLogin::isGridComboDirty() ) -			{ -				// User picked a grid from the popup, so clear the  -				// stored uris and they will be reacquired from the grid choice. -				sAuthUris.clear(); -			} -			  			std::string location;  			LLPanelLogin::getLocation( location );  			LLURLSimString::setString( location ); @@ -944,7 +911,7 @@ bool idle_startup()  			agent_location_id = START_LOCATION_ID_URL;  			// doesn't really matter what location_which is, since -			// agent_start_look_at will be overwritten when the +			// gAgentStartLookAt will be overwritten when the  			// UserLoginLocationReply arrives  			location_which = START_LOCATION_ID_LAST;  		} @@ -977,594 +944,115 @@ bool idle_startup()  		gVFS->pokeFiles(); -		// skipping over STATE_UPDATE_CHECK because that just waits for input  		LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );  		return FALSE;  	} -	if (STATE_UPDATE_CHECK == LLStartUp::getStartupState()) -	{ -		// wait for user to give input via dialog box -		return FALSE; -	} -  	if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())  	{ -//#define LL_MINIMIAL_REQUESTED_OPTIONS  		gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel(); -		// *Note: this is where gUserAuth used to be created. -		requested_options.clear(); -		requested_options.push_back("inventory-root"); -		requested_options.push_back("inventory-skeleton"); -		//requested_options.push_back("inventory-meat"); -		//requested_options.push_back("inventory-skel-targets"); -#if (!defined LL_MINIMIAL_REQUESTED_OPTIONS) -		if(FALSE == gSavedSettings.getBOOL("NoInventoryLibrary")) -		{ -			requested_options.push_back("inventory-lib-root"); -			requested_options.push_back("inventory-lib-owner"); -			requested_options.push_back("inventory-skel-lib"); -		//	requested_options.push_back("inventory-meat-lib"); -		} - -		requested_options.push_back("initial-outfit"); -		requested_options.push_back("gestures"); -		requested_options.push_back("event_categories"); -		requested_options.push_back("event_notifications"); -		requested_options.push_back("classified_categories"); -		//requested_options.push_back("inventory-targets"); -		requested_options.push_back("buddy-list"); -		requested_options.push_back("ui-config"); -#endif -		requested_options.push_back("tutorial_setting"); -		requested_options.push_back("login-flags"); -		requested_options.push_back("global-textures"); -		if(gSavedSettings.getBOOL("ConnectAsGod")) -		{ -			gSavedSettings.setBOOL("UseDebugMenus", TRUE); -			requested_options.push_back("god-connect"); -		} -		std::vector<std::string> uris; -		LLViewerLogin::getInstance()->getLoginURIs(uris); -		std::vector<std::string>::const_iterator iter, end; -		for (iter = uris.begin(), end = uris.end(); iter != end; ++iter) -		{ -			std::vector<std::string> rewritten; -			rewritten = LLSRV::rewriteURI(*iter); -			sAuthUris.insert(sAuthUris.end(), -							 rewritten.begin(), rewritten.end()); -		} -		sAuthUriNum = 0; -		auth_method = "login_to_simulator"; -		 +		// Update progress status and the display loop.  		auth_desc = LLTrans::getString("LoginInProgress"); -		LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); -	} - -	if (STATE_LOGIN_AUTHENTICATE == LLStartUp::getStartupState()) -	{ -		LL_DEBUGS("AppInit") << "STATE_LOGIN_AUTHENTICATE" << LL_ENDL;  		set_startup_status(progress, auth_desc, auth_message);  		progress += 0.02f;  		display_startup(); -		 -		std::stringstream start; -		if (LLURLSimString::parse()) -		{ -			// a startup URL was specified -			std::stringstream unescaped_start; -			unescaped_start << "uri:"  -							<< LLURLSimString::sInstance.mSimName << "&"  -							<< LLURLSimString::sInstance.mX << "&"  -							<< LLURLSimString::sInstance.mY << "&"  -							<< LLURLSimString::sInstance.mZ; -			start << xml_escape_string(unescaped_start.str()); -			 -		} -		else -		{ -			start << gSavedSettings.getString("LoginLocation"); -		} - -		char hashed_mac_string[MD5HEX_STR_SIZE];		/* Flawfinder: ignore */ -		LLMD5 hashed_mac; -		hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES ); -		hashed_mac.finalize(); -		hashed_mac.hex_digest(hashed_mac_string); - -		// TODO if statement here to use web_login_key -		sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1); -		LLUserAuth::getInstance()->authenticate( -			sAuthUris[sAuthUriNum], -			auth_method, -			firstname, -			lastname,			 -			password, // web_login_key, -			start.str(), -			gSkipOptionalUpdate, -			gAcceptTOS, -			gAcceptCriticalMessage, -			gLastExecEvent, -			requested_options, -			hashed_mac_string, -			LLAppViewer::instance()->getSerialNumber()); - -		// reset globals -		gAcceptTOS = FALSE; -		gAcceptCriticalMessage = FALSE; -		LLStartUp::setStartupState( STATE_LOGIN_NO_DATA_YET ); -		return FALSE; -	} -	if(STATE_LOGIN_NO_DATA_YET == LLStartUp::getStartupState()) -	{ -		LL_DEBUGS("AppInit") << "STATE_LOGIN_NO_DATA_YET" << LL_ENDL; -		// If we get here we have gotten past the potential stall -		// in curl, so take "may appear frozen" out of progress bar. JC -		auth_desc = LLTrans::getString("LoginInProgressNoFrozen"); -		set_startup_status(progress, auth_desc, auth_message); -		// Process messages to keep from dropping circuit. -		LLMessageSystem* msg = gMessageSystem; -		while (msg->checkAllMessages(gFrameCount, gServicePump)) +		// Setting initial values... +		if(gNoRender)  		{ +			// HACK, skip optional updates if you're running drones +			LLLoginInstance::getInstance()->setSkipOptionalUpdate(true);  		} -		msg->processAcks(); -		LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse(); -		if(LLUserAuth::E_NO_RESPONSE_YET == error) -		{ -			LL_DEBUGS("AppInit") << "waiting..." << LL_ENDL; -			return FALSE; -		} -		LLStartUp::setStartupState( STATE_LOGIN_DOWNLOADING ); -		progress += 0.01f; -		set_startup_status(progress, auth_desc, auth_message); -		return FALSE; -	} -	if(STATE_LOGIN_DOWNLOADING == LLStartUp::getStartupState()) -	{ -		LL_DEBUGS("AppInit") << "STATE_LOGIN_DOWNLOADING" << LL_ENDL; -		// Process messages to keep from dropping circuit. -		LLMessageSystem* msg = gMessageSystem; -		while (msg->checkAllMessages(gFrameCount, gServicePump)) -		{ -		} -		msg->processAcks(); -		LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse(); -		if(LLUserAuth::E_DOWNLOADING == error) -		{ -			LL_DEBUGS("AppInit") << "downloading..." << LL_ENDL; -			return FALSE; -		} +		LLLoginInstance::getInstance()->setUserInteraction(show_connect_box); + +		// This call to LLLoginInstance::connect() starts the  +		// authentication process. +		LLSD credentials; +		credentials["first"] = gFirstname; +		credentials["last"] = gLastname; +		credentials["passwd"] = gPassword; +		LLLoginInstance::getInstance()->connect(credentials); +  		LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE ); -		progress += 0.01f; -		set_startup_status(progress, LLTrans::getString("LoginProcessingResponse"), auth_message);  		return FALSE;  	} -	if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState()) +	if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState())   	{ -		LL_DEBUGS("AppInit") << "STATE_LOGIN_PROCESS_RESPONSE" << LL_ENDL; +		bool transitionBackToLoginPanel = false;  		std::ostringstream emsg; -		bool quit = false; -		bool update = false; -		std::string login_response; -		std::string reason_response; -		std::string message_response; -		bool successful_login = false; -		LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse(); -		// reset globals -		gAcceptTOS = FALSE; -		gAcceptCriticalMessage = FALSE; -		switch(error) -		{ -		case LLUserAuth::E_OK: -			login_response = LLUserAuth::getInstance()->getResponse("login"); -			if(login_response == "true") -			{ -				// Yay, login! -				successful_login = true; -			} -			else if(login_response == "indeterminate") +		if(LLLoginInstance::getInstance()->authFailure()) +		{ +			// Still have error conditions that may need some  +			// sort of handling. +			emsg << "Login failed.\n"; +			std::string reason_response = LLLoginInstance::getInstance()->getResponse("reason"); +			std::string message_response = LLLoginInstance::getInstance()->getResponse("message"); +	 +			if(!message_response.empty())  			{ -				LL_INFOS("AppInit") << "Indeterminate login..." << LL_ENDL; -				sAuthUris = LLSRV::rewriteURI(LLUserAuth::getInstance()->getResponse("next_url")); -				sAuthUriNum = 0; -				auth_method = LLUserAuth::getInstance()->getResponse("next_method"); -				auth_message = LLUserAuth::getInstance()->getResponse("message"); -				if(auth_method.substr(0, 5) == "login") +				// XUI: fix translation for strings returned during login +				// We need a generic table for translations +				std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ]; +				if ( big_reason.size() == 0 )  				{ -					auth_desc.assign(LLTrans::getString("LoginAuthenticating")); +					emsg << message_response;  				}  				else  				{ -					auth_desc.assign(LLTrans::getString("LoginMaintenance")); -				} -				// ignoring the duration & options array for now. -				// Go back to authenticate. -				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); -				return FALSE; -			} -			else -			{ -				emsg << "Login failed.\n"; -				reason_response = LLUserAuth::getInstance()->getResponse("reason"); -				message_response = LLUserAuth::getInstance()->getResponse("message"); - -				if (!message_response.empty()) -				{ -					// XUI: fix translation for strings returned during login -					// We need a generic table for translations -					std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ]; -					if ( big_reason.size() == 0 ) -					{ -						emsg << message_response; -					} -					else -					{ -						emsg << big_reason; -					} -				} - -				if(reason_response == "tos") -				{ -					if (show_connect_box) -					{ -						LL_DEBUGS("AppInit") << "Need tos agreement" << LL_ENDL; -						LLStartUp::setStartupState( STATE_UPDATE_CHECK ); -						LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_TOS, -																	message_response); -						tos_dialog->startModal(); -						// LLFloaterTOS deletes itself. -						return false; -					} -					else -					{ -						quit = true; -					} -				} -				if(reason_response == "critical") -				{ -					if (show_connect_box) -					{ -						LL_DEBUGS("AppInit") << "Need critical message" << LL_ENDL; -						LLStartUp::setStartupState( STATE_UPDATE_CHECK ); -						LLFloaterTOS* tos_dialog = LLFloaterTOS::show(LLFloaterTOS::TOS_CRITICAL_MESSAGE, -																	message_response); -						tos_dialog->startModal(); -						// LLFloaterTOS deletes itself. -						return false; -					} -					else -					{ -						quit = true; -					} -				} -				if(reason_response == "key") -				{ -					// Couldn't login because user/password is wrong -					// Clear the password -					password = ""; -				} -				if(reason_response == "update") -				{ -					auth_message = LLUserAuth::getInstance()->getResponse("message"); -					update = true; -				} -				if(reason_response == "optional") -				{ -					LL_DEBUGS("AppInit") << "Login got optional update" << LL_ENDL; -					auth_message = LLUserAuth::getInstance()->getResponse("message"); -					if (show_connect_box) -					{ -						update_app(FALSE, auth_message); -						LLStartUp::setStartupState( STATE_UPDATE_CHECK ); -						gSkipOptionalUpdate = TRUE; -						return false; -					} +					emsg << big_reason;  				}  			} -			break; -		case LLUserAuth::E_COULDNT_RESOLVE_HOST: -		case LLUserAuth::E_SSL_PEER_CERTIFICATE: -		case LLUserAuth::E_UNHANDLED_ERROR: -		case LLUserAuth::E_SSL_CACERT: -		case LLUserAuth::E_SSL_CONNECT_ERROR: -		default: -			if (sAuthUriNum >= (int) sAuthUris.size() - 1) -			{ -				emsg << "Unable to connect to " << LLAppViewer::instance()->getSecondLifeTitle() << ".\n"; -				emsg << LLUserAuth::getInstance()->errorMessage(); -			} else { -				sAuthUriNum++; -				std::ostringstream s; -				LLStringUtil::format_map_t args; -				args["[NUMBER]"] = llformat("%d", sAuthUriNum + 1); -				auth_desc = LLTrans::getString("LoginAttempt", args); -				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); -				return FALSE; -			} -			break; -		} - -		if (update || gSavedSettings.getBOOL("ForceMandatoryUpdate")) -		{ -			gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); -			update_app(TRUE, auth_message); -			LLStartUp::setStartupState( STATE_UPDATE_CHECK ); -			return false; -		} - -		// Version update and we're not showing the dialog -		if(quit) -		{ -			LLUserAuth::getInstance()->reset(); -			LLAppViewer::instance()->forceQuit(); -			return false; -		} -		if(successful_login) -		{ -			std::string text; -			text = LLUserAuth::getInstance()->getResponse("udp_blacklist"); -			if(!text.empty()) -			{ -				apply_udp_blacklist(text); -			} - -			// unpack login data needed by the application -			text = LLUserAuth::getInstance()->getResponse("agent_id"); -			if(!text.empty()) gAgentID.set(text); -			gDebugInfo["AgentID"] = text; -			 -			text = LLUserAuth::getInstance()->getResponse("session_id"); -			if(!text.empty()) gAgentSessionID.set(text); -			gDebugInfo["SessionID"] = text; -			 -			text = LLUserAuth::getInstance()->getResponse("secure_session_id"); -			if(!text.empty()) gAgent.mSecureSessionID.set(text); - -			text = LLUserAuth::getInstance()->getResponse("first_name"); -			if(!text.empty())  +			if(reason_response == "key")  			{ -				// Remove quotes from string.  Login.cgi sends these to force -				// names that look like numbers into strings. -				firstname.assign(text); -				LLStringUtil::replaceChar(firstname, '"', ' '); -				LLStringUtil::trim(firstname); +				// Couldn't login because user/password is wrong +				// Clear the password +				gPassword = "";  			} -			text = LLUserAuth::getInstance()->getResponse("last_name"); -			if(!text.empty()) lastname.assign(text); -			gSavedSettings.setString("FirstName", firstname); -			gSavedSettings.setString("LastName", lastname); -			if (gSavedSettings.getBOOL("RememberPassword")) +			if(reason_response == "update"  +				|| reason_response == "optional")  			{ -				// Successful login means the password is valid, so save it. -				LLStartUp::savePasswordToDisk(password); +				// In the case of a needed update, quit. +				// Its either downloading or declined. +				// If optional was skipped this case shouldn't  +				// be reached. +				LLLoginInstance::getInstance()->disconnect(); +				LLAppViewer::instance()->forceQuit();  			}  			else  			{ -				// Don't leave password from previous session sitting around -				// during this login session. -				LLStartUp::deletePasswordFromDisk(); -			} - -			// this is their actual ability to access content -			text = LLUserAuth::getInstance()->getResponse("agent_access_max"); -			if (!text.empty()) -			{ -				// agent_access can be 'A', 'M', and 'PG'. -				gAgent.setMaturity(text[0]); -			} -			 -			// this is the value of their preference setting for that content -			// which will always be <= agent_access_max -			text = LLUserAuth::getInstance()->getResponse("agent_region_access"); -			if (!text.empty()) -			{ -				int preferredMaturity = LLAgent::convertTextToMaturity(text[0]); -				gSavedSettings.setU32("PreferredMaturity", preferredMaturity); -			} -			// During the AO transition, this flag will be true. Then the flag will -			// go away. After the AO transition, this code and all the code that -			// uses it can be deleted. -			text = LLUserAuth::getInstance()->getResponse("ao_transition"); -			if (!text.empty()) -			{ -				if (text == "1") -				{ -					gAgent.setAOTransition(); -				} -			} - -			text = LLUserAuth::getInstance()->getResponse("start_location"); -			if(!text.empty()) agent_start_location.assign(text); -			text = LLUserAuth::getInstance()->getResponse("circuit_code"); -			if(!text.empty()) -			{ -				gMessageSystem->mOurCircuitCode = strtoul(text.c_str(), NULL, 10); -			} -			std::string sim_ip_str = LLUserAuth::getInstance()->getResponse("sim_ip"); -			std::string sim_port_str = LLUserAuth::getInstance()->getResponse("sim_port"); -			if(!sim_ip_str.empty() && !sim_port_str.empty()) -			{ -				U32 sim_port = strtoul(sim_port_str.c_str(), NULL, 10); -				first_sim.set(sim_ip_str, sim_port); -				if (first_sim.isOk()) -				{ -					gMessageSystem->enableCircuit(first_sim, TRUE); -				} -			} -			std::string region_x_str = LLUserAuth::getInstance()->getResponse("region_x"); -			std::string region_y_str = LLUserAuth::getInstance()->getResponse("region_y"); -			if(!region_x_str.empty() && !region_y_str.empty()) -			{ -				U32 region_x = strtoul(region_x_str.c_str(), NULL, 10); -				U32 region_y = strtoul(region_y_str.c_str(), NULL, 10); -				first_sim_handle = to_region_handle(region_x, region_y); -			} -			 -			const std::string look_at_str = LLUserAuth::getInstance()->getResponse("look_at"); -			if (!look_at_str.empty()) -			{ -				size_t len = look_at_str.size(); -				LLMemoryStream mstr((U8*)look_at_str.c_str(), len); -				LLSD sd = LLSDSerialize::fromNotation(mstr, len); -				agent_start_look_at = ll_vector3_from_sd(sd); -			} - -			text = LLUserAuth::getInstance()->getResponse("seed_capability"); -			if (!text.empty()) first_sim_seed_cap = text; -						 -			text = LLUserAuth::getInstance()->getResponse("seconds_since_epoch"); -			if(!text.empty()) -			{ -				U32 server_utc_time = strtoul(text.c_str(), NULL, 10); -				if(server_utc_time) -				{ -					time_t now = time(NULL); -					gUTCOffset = (server_utc_time - now); -				} -			} - -			std::string home_location = LLUserAuth::getInstance()->getResponse("home"); -			if(!home_location.empty()) -			{ -				size_t len = home_location.size(); -				LLMemoryStream mstr((U8*)home_location.c_str(), len); -				LLSD sd = LLSDSerialize::fromNotation(mstr, len); -				S32 region_x = sd["region_handle"][0].asInteger(); -				S32 region_y = sd["region_handle"][1].asInteger(); -				U64 region_handle = to_region_handle(region_x, region_y); -				LLVector3 position = ll_vector3_from_sd(sd["position"]); -				gAgent.setHomePosRegion(region_handle, position); -			} - -			gAgent.mMOTD.assign(LLUserAuth::getInstance()->getResponse("message")); -			LLUserAuth::options_t options; -			if(LLUserAuth::getInstance()->getOptions("inventory-root", options)) -			{ -				LLUserAuth::response_t::iterator it; -				it = options[0].find("folder_id"); -				if(it != options[0].end()) -				{ -					gAgent.mInventoryRootID.set((*it).second); -					//gInventory.mock(gAgent.getInventoryRootID()); -				} -			} - -			options.clear(); -			if(LLUserAuth::getInstance()->getOptions("login-flags", options)) -			{ -				LLUserAuth::response_t::iterator it; -				LLUserAuth::response_t::iterator no_flag = options[0].end(); -				it = options[0].find("ever_logged_in"); -				if(it != no_flag) -				{ -					if((*it).second == "N") gAgent.setFirstLogin(TRUE); -					else gAgent.setFirstLogin(FALSE); -				} -				it = options[0].find("stipend_since_login"); -				if(it != no_flag) -				{ -					if((*it).second == "Y") stipend_since_login = true; -				} -				it = options[0].find("gendered"); -				if(it != no_flag) -				{ -					if((*it).second == "Y") gAgent.setGenderChosen(TRUE); -				} -				it = options[0].find("daylight_savings"); -				if(it != no_flag) -				{ -					if((*it).second == "Y")  gPacificDaylightTime = TRUE; -					else gPacificDaylightTime = FALSE; -				} - -				//setup map of datetime strings to codes and slt & local time offset from utc -				LLStringOps::setupDatetimeInfo (gPacificDaylightTime); +				transitionBackToLoginPanel = true;  			} -			options.clear(); -			if (LLUserAuth::getInstance()->getOptions("initial-outfit", options) -				&& !options.empty()) -			{ -				LLUserAuth::response_t::iterator it; -				LLUserAuth::response_t::iterator it_end = options[0].end(); -				it = options[0].find("folder_name"); -				if(it != it_end) -				{ -					// Initial outfit is a folder in your inventory, -					// must be an exact folder-name match. -					sInitialOutfit = (*it).second; -				} -				it = options[0].find("gender"); -				if (it != it_end) -				{ -					sInitialOutfitGender = (*it).second; -				} -			} - -			options.clear(); -			if(LLUserAuth::getInstance()->getOptions("global-textures", options)) -			{ -				// Extract sun and moon texture IDs.  These are used -				// in the LLVOSky constructor, but I can't figure out -				// how to pass them in.  JC -				LLUserAuth::response_t::iterator it; -				LLUserAuth::response_t::iterator no_texture = options[0].end(); -				it = options[0].find("sun_texture_id"); -				if(it != no_texture) -				{ -					gSunTextureID.set((*it).second); -				} -				it = options[0].find("moon_texture_id"); -				if(it != no_texture) -				{ -					gMoonTextureID.set((*it).second); -				} -				it = options[0].find("cloud_texture_id"); -				if(it != no_texture) -				{ -					gCloudTextureID.set((*it).second); -				} -			} - - -			// JC: gesture loading done below, when we have an asset system -			// in place.  Don't delete/clear user_credentials until then. - -			if(gAgentID.notNull() -			   && gAgentSessionID.notNull() -			   && gMessageSystem->mOurCircuitCode -			   && first_sim.isOk() -			   && gAgent.mInventoryRootID.notNull()) +		} +		else if(LLLoginInstance::getInstance()->authSuccess()) +		{ +			if(process_login_success_response())  			{ -				LLStartUp::setStartupState( STATE_WORLD_INIT ); +				// Pass the user information to the voice chat server interface. +				gVoiceClient->userAuthorized(gFirstname, gLastname, gAgentID); +				LLStartUp::setStartupState( STATE_WORLD_INIT);  			}  			else  			{ -				if (gNoRender) -				{ -					LL_WARNS("AppInit") << "Bad login - missing return values" << LL_ENDL; -					LL_WARNS("AppInit") << emsg << LL_ENDL; -					exit(0); -				} -				// Bounce back to the login screen. -				LLSD args; -				args["ERROR_MESSAGE"] = emsg.str(); -				LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done); -				reset_login(); -				gSavedSettings.setBOOL("AutoLogin", FALSE); -				show_connect_box = true; +				transitionBackToLoginPanel = false;  			} -			 -			// Pass the user information to the voice chat server interface. -			gVoiceClient->userAuthorized(firstname, lastname, gAgentID);  		} -		else // if(successful_login) +		else +		{ +			// Still waiting for response. +			// *TODO:Mani - Actually check for login progress. +			// If we get here we have gotten past the potential stall +			// in curl, so take "may appear frozen" out of progress bar. JC +			auth_desc = LLTrans::getString("LoginInProgressNoFrozen"); +			set_startup_status(progress, auth_desc, auth_message); +		} + +		if(transitionBackToLoginPanel)  		{  			if (gNoRender)  			{ @@ -1572,11 +1060,12 @@ bool idle_startup()  				LL_WARNS("AppInit") << emsg << LL_ENDL;  				exit(0);  			} +  			// Bounce back to the login screen.  			LLSD args;  			args["ERROR_MESSAGE"] = emsg.str();  			LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done); -			reset_login(); +			reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );  			gSavedSettings.setBOOL("AutoLogin", FALSE);  			show_connect_box = true;  		} @@ -1640,14 +1129,14 @@ bool idle_startup()  		// This is necessary because creating objects before this is set will result in a  		// bad mPositionAgent cache. -		gAgent.initOriginGlobal(from_region_handle(first_sim_handle)); +		gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle)); -		LLWorld::getInstance()->addRegion(first_sim_handle, first_sim); +		LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim); -		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(first_sim_handle); +		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle);  		LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL; -		regionp->setSeedCapability(first_sim_seed_cap); +		regionp->setSeedCapability(gFirstSimSeedCap);  		LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL;  		// Set agent's initial region to be the one we just created. @@ -1818,7 +1307,7 @@ bool idle_startup()  		// the coordinates handed to us to fit in the local region.  		gAgent.setPositionAgent(agent_start_position_region); -		gAgent.resetAxes(agent_start_look_at); +		gAgent.resetAxes(gAgentStartLookAt);  		gAgent.stopCameraAnimation();  		gAgent.resetCamera(); @@ -1857,18 +1346,18 @@ bool idle_startup()  			LL_WARNS("AppInit") << "Attempting to connect to simulator with a zero circuit code!" << LL_ENDL;  		} -		gUseCircuitCallbackCalled = FALSE; +		gUseCircuitCallbackCalled = false; -		msg->enableCircuit(first_sim, TRUE); +		msg->enableCircuit(gFirstSim, TRUE);  		// now, use the circuit info to tell simulator about us! -		LL_INFOS("AppInit") << "viewer: UserLoginLocationReply() Enabling " << first_sim << " with code " << msg->mOurCircuitCode << LL_ENDL; +		LL_INFOS("AppInit") << "viewer: UserLoginLocationReply() Enabling " << gFirstSim << " with code " << msg->mOurCircuitCode << LL_ENDL;  		msg->newMessageFast(_PREHASH_UseCircuitCode);  		msg->nextBlockFast(_PREHASH_CircuitCode);  		msg->addU32Fast(_PREHASH_Code, msg->mOurCircuitCode);  		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  		msg->addUUIDFast(_PREHASH_ID, gAgent.getID());  		msg->sendReliable( -			first_sim, +			gFirstSim,  			MAX_TIMEOUT_COUNT,  			FALSE,  			TIMEOUT_SECONDS, @@ -1979,122 +1468,113 @@ bool idle_startup()  		LLAgentLanguage::update();  		// unpack thin inventory -		LLUserAuth::options_t options; -		options.clear(); +		LLSD response = LLLoginInstance::getInstance()->getResponse();  		//bool dump_buffer = false; -		 -		if(LLUserAuth::getInstance()->getOptions("inventory-lib-root", options) -			&& !options.empty()) + +		LLSD inv_lib_root = response["inventory-lib-root"]; +		if(inv_lib_root.isDefined())  		{  			// should only be one -			LLUserAuth::response_t::iterator it; -			it = options[0].find("folder_id"); -			if(it != options[0].end()) +			LLSD id = inv_lib_root[0]["folder_id"]; +			if(id.isDefined())  			{ -				gInventoryLibraryRoot.set((*it).second); +				gInventoryLibraryRoot = id.asUUID();  			}  		} - 		options.clear(); -		if(LLUserAuth::getInstance()->getOptions("inventory-lib-owner", options) -			&& !options.empty()) + 		 +		LLSD inv_lib_owner = response["inventory-lib-owner"]; +		if(inv_lib_owner.isDefined())  		{  			// should only be one -			LLUserAuth::response_t::iterator it; -			it = options[0].find("agent_id"); -			if(it != options[0].end()) +			LLSD id = inv_lib_owner[0]["agent_id"]; +			if(id.isDefined())  			{ -				gInventoryLibraryOwner.set((*it).second); +				gInventoryLibraryOwner = id.asUUID();  			}  		} - 		options.clear(); - 		if(LLUserAuth::getInstance()->getOptions("inventory-skel-lib", options) -			&& gInventoryLibraryOwner.notNull()) + +		LLSD inv_skel_lib = response["inventory-skel-lib"]; + 		if(inv_skel_lib.isDefined() && gInventoryLibraryOwner.notNull())   		{ - 			if(!gInventory.loadSkeleton(options, gInventoryLibraryOwner)) + 			if(!gInventory.loadSkeleton(inv_skel_lib, gInventoryLibraryOwner))   			{   				LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;   			}   		} - 		options.clear(); - 		if(LLUserAuth::getInstance()->getOptions("inventory-skeleton", options)) + +		LLSD inv_skeleton = response["inventory-skeleton"]; + 		if(inv_skeleton.isDefined())   		{ - 			if(!gInventory.loadSkeleton(options, gAgent.getID())) + 			if(!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))   			{   				LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;   			}   		} -		options.clear(); - 		if(LLUserAuth::getInstance()->getOptions("buddy-list", options)) +		LLSD buddy_list = response["buddy-list"]; + 		if(buddy_list.isDefined())   		{ -			LLUserAuth::options_t::iterator it = options.begin(); -			LLUserAuth::options_t::iterator end = options.end();  			LLAvatarTracker::buddy_map_t list;  			LLUUID agent_id;  			S32 has_rights = 0, given_rights = 0; -			for (; it != end; ++it) +			for(LLSD::array_const_iterator it = buddy_list.beginArray(), +				end = buddy_list.endArray(); it != end; ++it)  			{ -				LLUserAuth::response_t::const_iterator option_it; -				option_it = (*it).find("buddy_id"); -				if(option_it != (*it).end()) +				LLSD buddy_id = (*it)["buddy_id"]; +				if(buddy_id.isDefined())  				{ -					agent_id.set((*option_it).second); +					agent_id = buddy_id.asUUID();  				} -				option_it = (*it).find("buddy_rights_has"); -				if(option_it != (*it).end()) + +				LLSD buddy_rights_has = (*it)["buddy_rights_has"]; +				if(buddy_rights_has.isDefined())  				{ -					has_rights = atoi((*option_it).second.c_str()); +					has_rights = buddy_rights_has.asInteger();  				} -				option_it = (*it).find("buddy_rights_given"); -				if(option_it != (*it).end()) + +				LLSD buddy_rights_given = (*it)["buddy_rights_given"]; +				if(buddy_rights_given.isDefined())  				{ -					given_rights = atoi((*option_it).second.c_str()); +					given_rights = buddy_rights_given.asInteger();  				} +  				list[agent_id] = new LLRelationship(given_rights, has_rights, false);  			}  			LLAvatarTracker::instance().addBuddyList(list);   		} -		options.clear(); - 		if(LLUserAuth::getInstance()->getOptions("ui-config", options)) +		LLSD ui_config = response["ui-config"]; + 		if(ui_config.isDefined())   		{ -			LLUserAuth::options_t::iterator it = options.begin(); -			LLUserAuth::options_t::iterator end = options.end(); -			for (; it != end; ++it) +			for(LLSD::array_const_iterator it = ui_config.beginArray(), +				end = ui_config.endArray(); it != end; ++it)  			{ -				LLUserAuth::response_t::const_iterator option_it; -				option_it = (*it).find("allow_first_life"); -				if(option_it != (*it).end()) +				LLSD allow_first_life = (*it)["allow_first_life"]; +				if(allow_first_life.asString() == "Y")  				{ -					if (option_it->second == "Y") -					{ -						LLPanelAvatar::sAllowFirstLife = TRUE; -					} +					LLPanelAvatar::sAllowFirstLife = TRUE;  				}  			}   		} -		options.clear(); +  		bool show_hud = false; -		if(LLUserAuth::getInstance()->getOptions("tutorial_setting", options)) +		LLSD tutorial_setting = response["tutorial_setting"]; +		if(tutorial_setting.isDefined())  		{ -			LLUserAuth::options_t::iterator it = options.begin(); -			LLUserAuth::options_t::iterator end = options.end(); -			for (; it != end; ++it) +			for(LLSD::array_const_iterator it = tutorial_setting.beginArray(), +				end = tutorial_setting.endArray(); it != end; ++it)  			{ -				LLUserAuth::response_t::const_iterator option_it; -				option_it = (*it).find("tutorial_url"); -				if(option_it != (*it).end()) +				LLSD tutorial_url = (*it)["tutorial_url"]; +				if(tutorial_url.isDefined())  				{  					// Tutorial floater will append language code -					gSavedSettings.setString("TutorialURL", option_it->second); +					gSavedSettings.setString("TutorialURL", tutorial_url.asString());  				} -				option_it = (*it).find("use_tutorial"); -				if(option_it != (*it).end()) +				 +				LLSD use_tutorial = (*it)["use_tutorial"]; +				if(use_tutorial.asString() == "true")  				{ -					if (option_it->second == "true") -					{ -						show_hud = true; -					} +					show_hud = true;  				}  			}  		} @@ -2107,19 +1587,22 @@ bool idle_startup()  			LLFloaterHUD::showHUD();  		} -		options.clear(); -		if(LLUserAuth::getInstance()->getOptions("event_categories", options)) +		LLSD event_categories = response["event_categories"]; +		if(event_categories.isDefined())  		{ -			LLEventInfo::loadCategories(options); +			LLEventInfo::loadCategories(event_categories);  		} -		if(LLUserAuth::getInstance()->getOptions("event_notifications", options)) + +		LLSD event_notifications = response["event_notifications"]; +		if(event_notifications.isDefined())  		{ -			gEventNotifier.load(options); +			gEventNotifier.load(event_notifications);  		} -		options.clear(); -		if(LLUserAuth::getInstance()->getOptions("classified_categories", options)) + +		LLSD classified_categories = response["classified_categories"]; +		if(classified_categories.isDefined())  		{ -			LLClassifiedInfo::loadCategories(options); +			LLClassifiedInfo::loadCategories(classified_categories);  		} @@ -2176,7 +1659,7 @@ bool idle_startup()  			// This is actually a pessimistic computation, because TCP may not have enough  			// time to ramp up on the (small) default inventory file to truly measure max  			// bandwidth. JC -			F64 rate_bps = LLUserAuth::getInstance()->getLastTransferRateBPS(); +			F64 rate_bps = LLLoginInstance::getInstance()->getLastTransferRateBPS();  			const F32 FAST_RATE_BPS = 600.f * 1024.f;  			const F32 FASTER_RATE_BPS = 750.f * 1024.f;  			F32 max_bandwidth = gViewerThrottle.getMaxBandwidth(); @@ -2223,34 +1706,20 @@ bool idle_startup()  			// JC: Initialize "active" gestures.  This may also trigger  			// many gesture downloads, if this is the user's first  			// time on this machine or -purge has been run. -			LLUserAuth::options_t gesture_options; -			if (LLUserAuth::getInstance()->getOptions("gestures", gesture_options)) +			LLSD gesture_options  +				= LLLoginInstance::getInstance()->getResponse("gestures"); +			if (gesture_options.isDefined())  			{  				LL_DEBUGS("AppInit") << "Gesture Manager loading " << gesture_options.size()  					<< LL_ENDL;  				std::vector<LLUUID> item_ids; -				LLUserAuth::options_t::iterator resp_it; -				for (resp_it = gesture_options.begin(); -					 resp_it != gesture_options.end(); -					 ++resp_it) +				for(LLSD::array_const_iterator resp_it = gesture_options.beginArray(), +					end = gesture_options.endArray(); resp_it != end; ++resp_it)  				{ -					const LLUserAuth::response_t& response = *resp_it; -					LLUUID item_id; -					LLUUID asset_id; -					LLUserAuth::response_t::const_iterator option_it; - -					option_it = response.find("item_id"); -					if (option_it != response.end()) -					{ -						const std::string& uuid_string = (*option_it).second; -						item_id.set(uuid_string); -					} -					option_it = response.find("asset_id"); -					if (option_it != response.end()) -					{ -						const std::string& uuid_string = (*option_it).second; -						asset_id.set(uuid_string); -					} +					// If the id is not specifed in the LLSD, +					// the LLSD operator[]() will return a null LLUUID.  +					LLUUID item_id = (*resp_it)["item_id"]; +					LLUUID asset_id = (*resp_it)["asset_id"];  					if (item_id.notNull() && asset_id.notNull())  					{ @@ -2306,8 +1775,8 @@ bool idle_startup()  		if (!gAgent.isFirstLogin())  		{  			bool url_ok = LLURLSimString::sInstance.parse(); -			if ((url_ok && agent_start_location == "url") || -				(!url_ok && ((agent_start_location == gSavedSettings.getString("LoginLocation"))))) +			if ((url_ok && gAgentStartLocation == "url") || +				(!url_ok && ((gAgentStartLocation == gSavedSettings.getString("LoginLocation")))))  			{  				// Start location is OK  				// Disabled code to restore camera location and focus if logging in to default location @@ -2518,8 +1987,10 @@ bool idle_startup()  		// then the data is cached for the viewer's lifetime)  		LLProductInfoRequestManager::instance(); +		// *FIX:Mani - What do I do here? +		// Need we really clear the Auth response data?  		// Clean up the userauth stuff. -		LLUserAuth::getInstance()->reset(); +		// LLUserAuth::getInstance()->reset();  		LLStartUp::setStartupState( STATE_STARTED ); @@ -2804,194 +2275,6 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)  	return false;  } -void update_app(BOOL mandatory, const std::string& auth_msg) -{ -	// store off config state, as we might quit soon -	gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);	 -	gSavedSkinSettings.saveToFile(gSavedSettings.getString("SkinningSettingsFile"), TRUE); -	std::ostringstream message; - -	std::string msg; -	if (!auth_msg.empty()) -	{ -		msg = "("+ auth_msg + ") \n"; -	} - -	LLSD args; -	args["MESSAGE"] = msg; -	 -	LLSD payload; -	payload["mandatory"] = mandatory; - -/* - We're constructing one of the following 6 strings here: -	 "DownloadWindowsMandatory" -	 "DownloadWindowsReleaseForDownload" -	 "DownloadWindows" -	 "DownloadMacMandatory" -	 "DownloadMacReleaseForDownload" -	 "DownloadMac" -  - I've called them out explicitly in this comment so that they can be grepped for. -  - Also, we assume that if we're not Windows we're Mac. If we ever intend to support  - Linux with autoupdate, this should be an explicit #elif LL_DARWIN, but  - we'd rather deliver the wrong message than no message, so until Linux is supported - we'll leave it alone. - */ -	std::string notification_name = "Download"; -	 -#if LL_WINDOWS -	notification_name += "Windows"; -#else -	notification_name += "Mac"; -#endif -	 -	if (mandatory) -	{ -		notification_name += "Mandatory"; -	} -	else -	{ -#if LL_RELEASE_FOR_DOWNLOAD -		notification_name += "ReleaseForDownload"; -#endif -	} -	 -	LLNotifications::instance().add(notification_name, args, payload, update_dialog_callback); -	 -} - -bool update_dialog_callback(const LLSD& notification, const LLSD& response) -{ -	S32 option = LLNotification::getSelectedOption(notification, response); -	std::string update_exe_path; -	bool mandatory = notification["payload"]["mandatory"].asBoolean(); - -#if !LL_RELEASE_FOR_DOWNLOAD -	if (option == 2) -	{ -		LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );  -		return false; -	} -#endif - -	if (option == 1) -	{ -		// ...user doesn't want to do it -		if (mandatory) -		{ -			LLAppViewer::instance()->forceQuit(); -			// Bump them back to the login screen. -			//reset_login(); -		} -		else -		{ -			LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); -		} -		return false; -	} -	 -	LLSD query_map = LLSD::emptyMap(); -	// *TODO place os string in a global constant -#if LL_WINDOWS   -	query_map["os"] = "win"; -#elif LL_DARWIN -	query_map["os"] = "mac"; -#elif LL_LINUX -	query_map["os"] = "lnx"; -#elif LL_SOLARIS -	query_map["os"] = "sol"; -#endif -	// *TODO change userserver to be grid on both viewer and sim, since -	// userserver no longer exists. -	query_map["userserver"] = LLViewerLogin::getInstance()->getGridLabel(); -	query_map["channel"] = gSavedSettings.getString("VersionChannelName"); -	// *TODO constantize this guy -	// *NOTE: This URL is also used in win_setup/lldownloader.cpp -	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map); -	 -	if(LLAppViewer::sUpdaterInfo) -	{ -		delete LLAppViewer::sUpdaterInfo ; -	} -	LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ; -	 -#if LL_WINDOWS -	LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename(); -	if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty()) -	{ -		delete LLAppViewer::sUpdaterInfo ; -		LLAppViewer::sUpdaterInfo = NULL ; - -		// We're hosed, bail -		LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL; -		LLAppViewer::instance()->forceQuit(); -		return false; -	} - -	LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe"; - -	std::string updater_source = gDirUtilp->getAppRODataDir(); -	updater_source += gDirUtilp->getDirDelimiter(); -	updater_source += "updater.exe"; - -	LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source -			<< " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath -			<< LL_ENDL; - - -	if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE)) -	{ -		delete LLAppViewer::sUpdaterInfo ; -		LLAppViewer::sUpdaterInfo = NULL ; - -		LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL; -		LLAppViewer::instance()->forceQuit(); -		return false; -	} - -	// if a sim name was passed in via command line parameter (typically through a SLURL) -	if ( LLURLSimString::sInstance.mSimString.length() ) -	{ -		// record the location to start at next time -		gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );  -	}; - -	LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\""; - -	LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL; - -	//Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird. -	LLAppViewer::instance()->removeMarkerFile(); // In case updater fails -	 -#elif LL_DARWIN -	// if a sim name was passed in via command line parameter (typically through a SLURL) -	if ( LLURLSimString::sInstance.mSimString.length() ) -	{ -		// record the location to start at next time -		gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );  -	}; -	 -	LLAppViewer::sUpdaterInfo->mUpdateExePath = "'"; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir(); -	LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \""; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString(); -	LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \""; -	LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle(); -	LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &"; - -	LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL; - -	// Run the auto-updater. -	system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */ - -#elif LL_LINUX || LL_SOLARIS -	OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK); -#endif -	LLAppViewer::instance()->forceQuit(); -	return false; -}  void use_circuit_callback(void**, S32 result)  { @@ -3348,11 +2631,7 @@ std::string LLStartUp::startupStateToString(EStartupState state)  		RTNENUM( STATE_LOGIN_SHOW );  		RTNENUM( STATE_LOGIN_WAIT );  		RTNENUM( STATE_LOGIN_CLEANUP ); -		RTNENUM( STATE_UPDATE_CHECK );  		RTNENUM( STATE_LOGIN_AUTH_INIT ); -		RTNENUM( STATE_LOGIN_AUTHENTICATE ); -		RTNENUM( STATE_LOGIN_NO_DATA_YET ); -		RTNENUM( STATE_LOGIN_DOWNLOADING );  		RTNENUM( STATE_LOGIN_PROCESS_RESPONSE );  		RTNENUM( STATE_WORLD_INIT );  		RTNENUM( STATE_SEED_GRANTED_WAIT ); @@ -3493,3 +2772,252 @@ void apply_udp_blacklist(const std::string& csv)  } +bool process_login_success_response() +{ +	LLSD response = LLLoginInstance::getInstance()->getResponse(); + +	std::string text(response["udp_blacklist"]); +	if(!text.empty()) +	{ +		apply_udp_blacklist(text); +	} + +	// unpack login data needed by the application +	text = response["agent_id"].asString(); +	if(!text.empty()) gAgentID.set(text); +	gDebugInfo["AgentID"] = text; +	 +	text = response["session_id"].asString(); +	if(!text.empty()) gAgentSessionID.set(text); +	gDebugInfo["SessionID"] = text; +	 +	text = response["secure_session_id"].asString(); +	if(!text.empty()) gAgent.mSecureSessionID.set(text); + +	text = response["first_name"].asString(); +	if(!text.empty())  +	{ +		// Remove quotes from string.  Login.cgi sends these to force +		// names that look like numbers into strings. +		gFirstname.assign(text); +		LLStringUtil::replaceChar(gFirstname, '"', ' '); +		LLStringUtil::trim(gFirstname); +	} +	text = response["last_name"].asString(); +	if(!text.empty())  +	{ +		gLastname.assign(text); +	} +	gSavedSettings.setString("FirstName", gFirstname); +	gSavedSettings.setString("LastName", gLastname); + +	if (gSavedSettings.getBOOL("RememberPassword")) +	{ +		// Successful login means the password is valid, so save it. +		LLStartUp::savePasswordToDisk(gPassword); +	} +	else +	{ +		// Don't leave password from previous session sitting around +		// during this login session. +		LLStartUp::deletePasswordFromDisk(); +	} + +	// this is their actual ability to access content +	text = response["agent_access_max"].asString(); +	if (!text.empty()) +	{ +		// agent_access can be 'A', 'M', and 'PG'. +		gAgent.setMaturity(text[0]); +	} +	 +	// this is the value of their preference setting for that content +	// which will always be <= agent_access_max +	text = response["agent_region_access"].asString(); +	if (!text.empty()) +	{ +		int preferredMaturity = LLAgent::convertTextToMaturity(text[0]); +		gSavedSettings.setU32("PreferredMaturity", preferredMaturity); +	} +	// During the AO transition, this flag will be true. Then the flag will +	// go away. After the AO transition, this code and all the code that +	// uses it can be deleted. +	text = response["ao_transition"].asString(); +	if (!text.empty()) +	{ +		if (text == "1") +		{ +			gAgent.setAOTransition(); +		} +	} + +	text = response["start_location"].asString(); +	if(!text.empty())  +	{ +		gAgentStartLocation.assign(text); +	} + +	text = response["circuit_code"].asString(); +	if(!text.empty()) +	{ +		gMessageSystem->mOurCircuitCode = strtoul(text.c_str(), NULL, 10); +	} +	std::string sim_ip_str = response["sim_ip"]; +	std::string sim_port_str = response["sim_port"]; +	if(!sim_ip_str.empty() && !sim_port_str.empty()) +	{ +		U32 sim_port = strtoul(sim_port_str.c_str(), NULL, 10); +		gFirstSim.set(sim_ip_str, sim_port); +		if (gFirstSim.isOk()) +		{ +			gMessageSystem->enableCircuit(gFirstSim, TRUE); +		} +	} +	std::string region_x_str = response["region_x"]; +	std::string region_y_str = response["region_y"]; +	if(!region_x_str.empty() && !region_y_str.empty()) +	{ +		U32 region_x = strtoul(region_x_str.c_str(), NULL, 10); +		U32 region_y = strtoul(region_y_str.c_str(), NULL, 10); +		gFirstSimHandle = to_region_handle(region_x, region_y); +	} +	 +	const std::string look_at_str = response["look_at"]; +	if (!look_at_str.empty()) +	{ +		size_t len = look_at_str.size(); +		LLMemoryStream mstr((U8*)look_at_str.c_str(), len); +		LLSD sd = LLSDSerialize::fromNotation(mstr, len); +		gAgentStartLookAt = ll_vector3_from_sd(sd); +	} + +	text = response["seed_capability"].asString(); +	if (!text.empty()) gFirstSimSeedCap = text; +				 +	text = response["seconds_since_epoch"].asString(); +	if(!text.empty()) +	{ +		U32 server_utc_time = strtoul(text.c_str(), NULL, 10); +		if(server_utc_time) +		{ +			time_t now = time(NULL); +			gUTCOffset = (server_utc_time - now); +		} +	} + +	std::string home_location = response["home"]; +	if(!home_location.empty()) +	{ +		size_t len = home_location.size(); +		LLMemoryStream mstr((U8*)home_location.c_str(), len); +		LLSD sd = LLSDSerialize::fromNotation(mstr, len); +		S32 region_x = sd["region_handle"][0].asInteger(); +		S32 region_y = sd["region_handle"][1].asInteger(); +		U64 region_handle = to_region_handle(region_x, region_y); +		LLVector3 position = ll_vector3_from_sd(sd["position"]); +		gAgent.setHomePosRegion(region_handle, position); +	} + +	gAgent.mMOTD.assign(response["message"]); + +	// Options... +	// Each 'option' is an array of submaps.  +	// It appears that we only ever use the first element of the array. +	LLUUID inv_root_folder_id = response["inventory-root"][0]["folder_id"]; +	if(inv_root_folder_id.notNull()) +	{ +		gAgent.mInventoryRootID = inv_root_folder_id; +		//gInventory.mock(gAgent.getInventoryRootID()); +	} + +	LLSD login_flags = response["login-flags"][0]; +	if(login_flags.size()) +	{ +		std::string flag = login_flags["ever_logged_in"]; +		if(!flag.empty()) +		{ +			gAgent.setFirstLogin((flag == "N") ? TRUE : FALSE); +		} + +		/*  Flag is currently ignored by the viewer. +		flag = login_flags["stipend_since_login"]; +		if(flag == "Y")  +		{ +			stipend_since_login = true; +		} +		*/ + +		flag = login_flags["gendered"].asString(); +		if(flag == "Y") +		{ +			gAgent.setGenderChosen(TRUE); +		} +		 +		flag = login_flags["daylight_savings"].asString(); +		if(flag == "Y") +		{ +			gPacificDaylightTime  = (flag == "Y") ? TRUE : FALSE; +		} + +		//setup map of datetime strings to codes and slt & local time offset from utc +		LLStringOps::setupDatetimeInfo (gPacificDaylightTime); +	} + +	LLSD initial_outfit = response["initial-outfit"][0]; +	if(initial_outfit.size()) +	{ +		std::string flag = initial_outfit["folder_name"]; +		if(!flag.empty()) +		{ +			// Initial outfit is a folder in your inventory, +			// must be an exact folder-name match. +			sInitialOutfit = flag; +		} + +		flag = initial_outfit["gender"].asString(); +		if(!flag.empty()) +		{ +			sInitialOutfitGender = flag; +		} +	} + +	LLSD global_textures = response["global-textures"][0]; +	if(global_textures.size()) +	{ +		// Extract sun and moon texture IDs.  These are used +		// in the LLVOSky constructor, but I can't figure out +		// how to pass them in.  JC +		LLUUID id = global_textures["sun_texture_id"]; +		if(id.notNull()) +		{ +			gSunTextureID = id; +		} + +		id = global_textures["moon_texture_id"]; +		if(id.notNull()) +		{ +			gMoonTextureID = id; +		} + +		id = global_textures["cloud_texture_id"]; +		if(id.notNull()) +		{ +			gCloudTextureID = id; +		} +	} + + +	bool success = false; +	// JC: gesture loading done below, when we have an asset system +	// in place.  Don't delete/clear user_credentials until then. +	if(gAgentID.notNull() +	   && gAgentSessionID.notNull() +	   && gMessageSystem->mOurCircuitCode +	   && gFirstSim.isOk() +	   && gAgent.mInventoryRootID.notNull()) +	{ +		success = true; +	} + +	return success; +} diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp index 0c1ee42ffc..c94ba0a3e8 100644 --- a/indra/newview/tests/llxmlrpclistener_test.cpp +++ b/indra/newview/tests/llxmlrpclistener_test.cpp @@ -26,7 +26,7 @@  #include "llcontrol.h"  #include "tests/wrapllerrs.h" -LLControlGroup gSavedSettings; +LLControlGroup gSavedSettings("Global");  /*****************************************************************************  *   TUT | 
