summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/tests/lleventcoro_test.cpp827
-rw-r--r--indra/newview/lllogininstance.cpp14
-rw-r--r--indra/newview/llstartup.cpp1368
-rw-r--r--indra/newview/tests/llxmlrpclistener_test.cpp2
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