aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden
diff options
context:
space:
mode:
Diffstat (limited to 'linden')
-rw-r--r--linden/indra/llcommon/llstring.cpp34
-rw-r--r--linden/indra/llcommon/llstring.h2
-rw-r--r--linden/indra/llimage/llimageworker.cpp2
-rw-r--r--linden/indra/llimagej2coj/llimagej2coj.cpp49
-rw-r--r--linden/indra/newview/app_settings/settings.xml62
-rw-r--r--linden/indra/newview/floatergridmanager.cpp63
-rw-r--r--linden/indra/newview/floatergridmanager.h8
-rw-r--r--linden/indra/newview/floatervoicelicense.cpp12
-rw-r--r--linden/indra/newview/hippogridmanager.cpp96
-rw-r--r--linden/indra/newview/hippogridmanager.h6
-rw-r--r--linden/indra/newview/linux_tools/alsoft.conf253
-rwxr-xr-xlinden/indra/newview/linux_tools/wrapper.sh45
-rw-r--r--linden/indra/newview/llagent.cpp29
-rw-r--r--linden/indra/newview/llappviewer.cpp20
-rw-r--r--linden/indra/newview/llfloaterchat.cpp3
-rw-r--r--linden/indra/newview/llfloaterpreference.cpp2
-rw-r--r--linden/indra/newview/llloginhandler.cpp20
-rw-r--r--linden/indra/newview/llpanellogin.cpp62
-rw-r--r--linden/indra/newview/llpanellogin.h5
-rw-r--r--linden/indra/newview/llprefsadvanced.cpp8
-rw-r--r--linden/indra/newview/llprefsadvanced.h2
-rw-r--r--linden/indra/newview/llprefsim.cpp4
-rw-r--r--linden/indra/newview/llstartup.cpp242
-rw-r--r--linden/indra/newview/llstartup.h9
-rw-r--r--linden/indra/newview/llvoavatar.cpp5
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml18
-rwxr-xr-xlinden/indra/newview/viewer_manifest.py1
-rw-r--r--linden/indra/newview/viewertime.cpp8
28 files changed, 653 insertions, 417 deletions
diff --git a/linden/indra/llcommon/llstring.cpp b/linden/indra/llcommon/llstring.cpp
index 0f72d5e..cd5a9f2 100644
--- a/linden/indra/llcommon/llstring.cpp
+++ b/linden/indra/llcommon/llstring.cpp
@@ -596,6 +596,40 @@ std::string utf8str_removeCRLF(const std::string& utf8str)
596 return out; 596 return out;
597} 597}
598 598
599bool is_hex_string(U8* str, S32 len)
600{
601 bool rv = true;
602 U8* c = str;
603 while(rv && len--)
604 {
605 switch(*c)
606 {
607 case '0':
608 case '1':
609 case '2':
610 case '3':
611 case '4':
612 case '5':
613 case '6':
614 case '7':
615 case '8':
616 case '9':
617 case 'a':
618 case 'b':
619 case 'c':
620 case 'd':
621 case 'e':
622 case 'f':
623 ++c;
624 break;
625 default:
626 rv = false;
627 break;
628 }
629 }
630 return rv;
631}
632
599#if LL_WINDOWS 633#if LL_WINDOWS
600// documentation moved to header. Phoenix 2007-11-27 634// documentation moved to header. Phoenix 2007-11-27
601namespace snprintf_hack 635namespace snprintf_hack
diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h
index 61767ac..a592e2c 100644
--- a/linden/indra/llcommon/llstring.h
+++ b/linden/indra/llcommon/llstring.h
@@ -456,6 +456,8 @@ LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str);
456 456
457LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); 457LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
458 458
459LL_COMMON_API bool is_hex_string(U8* str, S32 len);
460
459 461
460#if LL_WINDOWS 462#if LL_WINDOWS
461/* @name Windows string helpers 463/* @name Windows string helpers
diff --git a/linden/indra/llimage/llimageworker.cpp b/linden/indra/llimage/llimageworker.cpp
index dc989e5..5e61f69 100644
--- a/linden/indra/llimage/llimageworker.cpp
+++ b/linden/indra/llimage/llimageworker.cpp
@@ -164,7 +164,7 @@ void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
164{ 164{
165 if (mResponder.notNull()) 165 if (mResponder.notNull())
166 { 166 {
167 bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux); 167 bool success = completed && mDecodedRaw && mDecodedImageRaw->getDataSize() && (!mNeedsAux || mDecodedAux);
168 mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux); 168 mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
169 } 169 }
170 // Will automatically be deleted 170 // Will automatically be deleted
diff --git a/linden/indra/llimagej2coj/llimagej2coj.cpp b/linden/indra/llimagej2coj/llimagej2coj.cpp
index fd92370..f003d60 100644
--- a/linden/indra/llimagej2coj/llimagej2coj.cpp
+++ b/linden/indra/llimagej2coj/llimagej2coj.cpp
@@ -152,13 +152,8 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
152 /* open a byte stream */ 152 /* open a byte stream */
153 cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); 153 cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
154 154
155 /* decode the stream and fill the image structure, also fill in an additional 155 /* decode the stream and fill the image structure */
156 structure to get the decoding result. This structure is a bit unusual in that 156 image = opj_decode(dinfo, cio);
157 it is not received through opj, but still has some dynamically allocated fields
158 that need to be cleared up at the end by calling a destroy function. */
159 opj_codestream_info_t cinfo;
160 memset(&cinfo, 0, sizeof(opj_codestream_info_t));
161 image = opj_decode_with_info(dinfo, cio, &cinfo);
162 157
163 /* close the byte stream */ 158 /* close the byte stream */
164 opj_cio_close(cio); 159 opj_cio_close(cio);
@@ -175,6 +170,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
175 if(!image) 170 if(!image)
176 { 171 {
177 LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL; 172 LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL;
173 base.decodeFailed();
178 return TRUE; // done 174 return TRUE; // done
179 } 175 }
180 176
@@ -185,51 +181,35 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
185 LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL; 181 LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL;
186 if (image) 182 if (image)
187 { 183 {
188 opj_destroy_cstr_info(&cinfo);
189 opj_image_destroy(image); 184 opj_image_destroy(image);
190 } 185 }
191 186
187 base.decodeFailed();
192 return TRUE; // done 188 return TRUE; // done
193 } 189 }
194 190
195 // sometimes we get bad data out of the cache - check to see if the decode succeeded 191 // sometimes we get bad data out of the cache - check to see if the decode succeeded
196 int decompdifference = 0; 192 for (S32 i = 0; i < img_components; i++)
197 if (cinfo.numdecompos) // sanity
198 { 193 {
199 for (int comp = 0; comp < image->numcomps; comp++) 194 if (image->comps[i].factor != base.getRawDiscardLevel())
200 { /* get maximum decomposition level difference, first field is from the COD header and the second
201 is what is actually met in the codestream, NB: if everything was ok, this calculation will
202 return what was set in the cp_reduce value! */
203 decompdifference = llmax(decompdifference, cinfo.numdecompos[comp] - image->comps[comp].resno_decoded);
204 }
205 if (decompdifference < 0) // sanity
206 { 195 {
207 decompdifference = 0; 196 // if we didn't get the discard level we're expecting, fail
197 if (image) //anyway somthing odd with the image, better check than crash
198 opj_image_destroy(image);
199 base.decodeFailed();
200 return TRUE;
208 } 201 }
209 } 202 }
210 203
211
212 /* if OpenJPEG failed to decode all requested decomposition levels
213 the difference will be greater than this level */
214 if (decompdifference > base.getRawDiscardLevel())
215 {
216 llwarns << "not enough data for requested discard level, setting mDecoding to FALSE, difference: " << (decompdifference - base.getRawDiscardLevel()) << llendl;
217 opj_destroy_cstr_info(&cinfo);
218 opj_image_destroy(image);
219 base.mDecoding = FALSE;
220 return TRUE;
221 }
222
223 if(img_components <= first_channel) 204 if(img_components <= first_channel)
224 { 205 {
225 // sanity
226 LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL; 206 LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL;
227 if (image) 207 if (image)
228 { 208 {
229 opj_destroy_cstr_info(&cinfo);
230 opj_image_destroy(image); 209 opj_image_destroy(image);
231 } 210 }
232 211
212 base.decodeFailed();
233 return TRUE; 213 return TRUE;
234 } 214 }
235 215
@@ -275,17 +255,16 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
275 else // Some rare OpenJPEG versions have this bug. 255 else // Some rare OpenJPEG versions have this bug.
276 { 256 {
277 llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl; 257 llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl;
278 opj_destroy_cstr_info(&cinfo);
279 opj_image_destroy(image); 258 opj_image_destroy(image);
280 259
260 base.decodeFailed();
281 return TRUE; // done 261 return TRUE; // done
282 } 262 }
283 } 263 }
284 264
285 /* free opj data structures */ 265 /* free image data structure */
286 if (image) 266 if (image)
287 { 267 {
288 opj_destroy_cstr_info(&cinfo);
289 opj_image_destroy(image); 268 opj_image_destroy(image);
290 } 269 }
291 270
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml
index c8ad381..bdaf8cc 100644
--- a/linden/indra/newview/app_settings/settings.xml
+++ b/linden/indra/newview/app_settings/settings.xml
@@ -138,6 +138,17 @@
138 <real>1</real> 138 <real>1</real>
139 </array> 139 </array>
140 </map> 140 </map>
141 <key>HeadFollowsMouse</key>
142 <map>
143 <key>Comment</key>
144 <string>IF your avatars head follows your mouse movements (then the extend is defined in YawFromMousePosition and PitchFromMousePosition</string>
145 <key>Persist</key>
146 <integer>1</integer>
147 <key>Type</key>
148 <string>Boolean</string>
149 <key>Value</key>
150 <integer>0</integer>
151 </map>
141 <key>HighlightOwnNameInChat</key> 152 <key>HighlightOwnNameInChat</key>
142 <map> 153 <map>
143 <key>Comment</key> 154 <key>Comment</key>
@@ -1692,7 +1703,23 @@
1692 </map> 1703 </map>
1693 1704
1694 <!-- Begin: Client Name Tag --> 1705 <!-- Begin: Client Name Tag -->
1695 1706
1707 <key>ImprudenceTagColor</key>
1708 <map>
1709 <key>Comment</key>
1710 <string>Color of Imprudence tags (displayed only locally)</string>
1711 <key>Persist</key>
1712 <integer>1</integer>
1713 <key>Type</key>
1714 <string>Color4</string>
1715 <key>Value</key>
1716 <array>
1717 <real>0.79</real>
1718 <real>0.44</real>
1719 <real>0.88</real>
1720 <real>1</real>
1721 </array>
1722 </map>
1696 <key>ShowClientColor</key> 1723 <key>ShowClientColor</key>
1697 <map> 1724 <map>
1698 <key>Comment</key> 1725 <key>Comment</key>
@@ -5865,17 +5892,6 @@
5865 <key>Value</key> 5892 <key>Value</key>
5866 <integer>1</integer> 5893 <integer>1</integer>
5867 </map> 5894 </map>
5868 <key>FirstName</key>
5869 <map>
5870 <key>Comment</key>
5871 <string>Login first name</string>
5872 <key>Persist</key>
5873 <integer>1</integer>
5874 <key>Type</key>
5875 <string>String</string>
5876 <key>Value</key>
5877 <string />
5878 </map>
5879 <key>FirstPersonAvatarVisible</key> 5895 <key>FirstPersonAvatarVisible</key>
5880 <map> 5896 <map>
5881 <key>Comment</key> 5897 <key>Comment</key>
@@ -7776,17 +7792,6 @@
7776 <key>Value</key> 7792 <key>Value</key>
7777 <string>find_all_panel</string> 7793 <string>find_all_panel</string>
7778 </map> 7794 </map>
7779 <key>LastName</key>
7780 <map>
7781 <key>Comment</key>
7782 <string>Login last name</string>
7783 <key>Persist</key>
7784 <integer>1</integer>
7785 <key>Type</key>
7786 <string>String</string>
7787 <key>Value</key>
7788 <string />
7789 </map>
7790 <key>LastPrefTab</key> 7795 <key>LastPrefTab</key>
7791 <map> 7796 <map>
7792 <key>Comment</key> 7797 <key>Comment</key>
@@ -8161,17 +8166,6 @@
8161 <key>Value</key> 8166 <key>Value</key>
8162 <integer>1</integer> 8167 <integer>1</integer>
8163 </map> 8168 </map>
8164 <key>Marker</key>
8165 <map>
8166 <key>Comment</key>
8167 <string>[NOT USED]</string>
8168 <key>Persist</key>
8169 <integer>1</integer>
8170 <key>Type</key>
8171 <string>String</string>
8172 <key>Value</key>
8173 <string />
8174 </map>
8175 <key>MaxDragDistance</key> 8169 <key>MaxDragDistance</key>
8176 <map> 8170 <map>
8177 <key>Comment</key> 8171 <key>Comment</key>
diff --git a/linden/indra/newview/floatergridmanager.cpp b/linden/indra/newview/floatergridmanager.cpp
index ad6ea05..257c210 100644
--- a/linden/indra/newview/floatergridmanager.cpp
+++ b/linden/indra/newview/floatergridmanager.cpp
@@ -47,13 +47,11 @@
47#include "llpanellogin.h" 47#include "llpanellogin.h"
48 48
49const std::string PASSWORD_FILLER = "123456789!123456"; 49const std::string PASSWORD_FILLER = "123456789!123456";
50//bool FloaterGridManager::sIsInitialLogin;
51 50
52FloaterGridManager::FloaterGridManager(const LLSD& key) 51FloaterGridManager::FloaterGridManager(const LLSD& key)
53 : 52 :
54 mState(GRID_STATE_NORMAL), 53 mState(GRID_STATE_NORMAL),
55 mCurGrid(""), 54 mCurGrid("")
56 mMungedPassword("")
57{ 55{
58 llinfos << "Opening grid manager" << llendl; 56 llinfos << "Opening grid manager" << llendl;
59 57
@@ -250,7 +248,15 @@ void FloaterGridManager::refreshGrids()
250 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setText(gridInfo->getFirstName()); 248 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setText(gridInfo->getFirstName());
251 FloaterGridManager::getInstance()->getChild<LLLineEditor>("last_name")->setText(gridInfo->getLastName()); 249 FloaterGridManager::getInstance()->getChild<LLLineEditor>("last_name")->setText(gridInfo->getLastName());
252 FloaterGridManager::getInstance()->getChild<LLLineEditor>("username")->setText(gridInfo->getUsername()); 250 FloaterGridManager::getInstance()->getChild<LLLineEditor>("username")->setText(gridInfo->getUsername());
253 FloaterGridManager::getInstance()->getChild<LLLineEditor>("avatar_password")->setText(gridInfo->getAvatarPassword()); 251
252 if (gridInfo->getPassword().empty())
253 {
254 FloaterGridManager::getInstance()->getChild<LLLineEditor>("avatar_password")->setText(LLStringExplicit(""));
255 }
256 else
257 {
258 FloaterGridManager::getInstance()->getChild<LLLineEditor>("avatar_password")->setText(PASSWORD_FILLER);
259 }
254 260
255 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setVisible(!gridInfo->isUsernameCompat()); 261 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setVisible(!gridInfo->isUsernameCompat());
256 FloaterGridManager::getInstance()->getChild<LLTextBox>("first_name_text")->setVisible(!gridInfo->isUsernameCompat()); 262 FloaterGridManager::getInstance()->getChild<LLTextBox>("first_name_text")->setVisible(!gridInfo->isUsernameCompat());
@@ -353,15 +359,13 @@ void FloaterGridManager::applyChanges()
353 359
354 // don't allow users to set their password as PASSWORD_FILLER 360 // don't allow users to set their password as PASSWORD_FILLER
355 // would be nice to get grid-specific rules on password formatting, too 361 // would be nice to get grid-specific rules on password formatting, too
356 // passwords are remembered by default 362 // passwords are remembered by default when entered in the grid manager (good default?)
357 std::string password_new = childGetValue("avatar_password").asString(); 363 std::string password_new = childGetValue("avatar_password").asString();
358 std::string password_old = grid->getAvatarPassword(); // initialized to "" 364 std::string password_old = grid->getPassword(); // initialized to ""
359 if (!password_new.empty() && password_new != PASSWORD_FILLER && password_new != password_old) 365 if (password_new != PASSWORD_FILLER && password_new != password_old)
360 { 366 {
361 // store account authentication data 367 // store account authentication data
362 std::string hashed_password; 368 grid->setPassword(password_new);
363 hashPassword(password_new, hashed_password);
364 grid->setAvatarPassword(hashed_password);
365 } 369 }
366 370
367 FloaterGridManager::getInstance()->getChild<LLScrollListCtrl>("grid_selector")->setEnabled(true); 371 FloaterGridManager::getInstance()->getChild<LLScrollListCtrl>("grid_selector")->setEnabled(true);
@@ -380,11 +384,11 @@ void FloaterGridManager::applyChanges()
380 // should this be settable? 384 // should this be settable?
381 if (grid->isUsernameCompat()) 385 if (grid->isUsernameCompat())
382 { 386 {
383 LLPanelLogin::setFields(grid->getUsername(), grid->getAvatarPassword()); 387 LLPanelLogin::setFields(grid->getUsername(), grid->getPassword());
384 } 388 }
385 else 389 else
386 { 390 {
387 LLPanelLogin::setFields(grid->getFirstName(), grid->getLastName(), grid->getAvatarPassword()); 391 LLPanelLogin::setFields(grid->getFirstName(), grid->getLastName(), grid->getPassword());
388 } 392 }
389 393
390 if (FloaterGridDefault::instanceVisible()) 394 if (FloaterGridDefault::instanceVisible())
@@ -540,6 +544,8 @@ void FloaterGridManager::apply()
540 544
541 gHippoGridManager->saveFile(); 545 gHippoGridManager->saveFile();
542 LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel()); 546 LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel());
547 LLPanelLogin::loadLoginForm();
548 LLPanelLogin::loadLoginPage();
543} 549}
544 550
545// static 551// static
@@ -697,36 +703,3 @@ BOOL FloaterGridManager::isGridComboDirty()
697// LLComboBox* combo = FloaterGridManager::getInstance()->getChild<LLComboBox>("start_location_combo"); 703// LLComboBox* combo = FloaterGridManager::getInstance()->getChild<LLComboBox>("start_location_combo");
698// location = combo->getValue().asString(); 704// location = combo->getValue().asString();
699//} 705//}
700
701std::string& FloaterGridManager::getPassword()
702{
703 return mMungedPassword;
704}
705
706void FloaterGridManager::setPassword(std::string &password)
707{
708 mMungedPassword = password;
709}
710
711bool FloaterGridManager::isSamePassword(std::string &password)
712{
713 return mMungedPassword == password;
714}
715
716void FloaterGridManager::hashPassword(const std::string& password, std::string& hashedPassword)
717{
718 // Max "actual" password length is 16 characters.
719 // Hex digests are always 32 characters.
720 if (password.length() == 32)
721 {
722 hashedPassword = password;
723 }
724 else
725 {
726 // this is a normal text password
727 LLMD5 pass((unsigned char *)password.c_str());
728 char munged_password[MD5HEX_STR_SIZE];
729 pass.hex_digest(munged_password);
730 hashedPassword = munged_password;
731 }
732}
diff --git a/linden/indra/newview/floatergridmanager.h b/linden/indra/newview/floatergridmanager.h
index b93a430..985a905 100644
--- a/linden/indra/newview/floatergridmanager.h
+++ b/linden/indra/newview/floatergridmanager.h
@@ -50,19 +50,12 @@ public:
50 50
51 void refresh(); 51 void refresh();
52 52
53 // new-style login methods
54 virtual std::string& getPassword();
55 virtual void setPassword(std::string &password);
56 virtual bool isSamePassword(std::string &password);
57
58 // clears either the loginuri fetched info or all the info in the grid manager 53 // clears either the loginuri fetched info or all the info in the grid manager
59 void clearGridInfo(bool clear_all); 54 void clearGridInfo(bool clear_all);
60 55
61 //static void getLocation(std::string &location); 56 //static void getLocation(std::string &location);
62 //void refreshLocation(bool force_visible) 57 //void refreshLocation(bool force_visible)
63 static BOOL isGridComboDirty(); 58 static BOOL isGridComboDirty();
64 //static void addServer(const std::string& server, S32 domain_name);
65 static void hashPassword(const std::string& password, std::string& hashedPassword);
66 59
67private: 60private:
68 61
@@ -75,7 +68,6 @@ private:
75 68
76 void setGridState(EGridState state) { mState = state; } 69 void setGridState(EGridState state) { mState = state; }
77 EGridState getGridState() { return mState; } 70 EGridState getGridState() { return mState; }
78 std::string mMungedPassword;
79 EGridState mState; 71 EGridState mState;
80 std::string mCurGrid; 72 std::string mCurGrid;
81 73
diff --git a/linden/indra/newview/floatervoicelicense.cpp b/linden/indra/newview/floatervoicelicense.cpp
index e8cd4f3..c780ff3 100644
--- a/linden/indra/newview/floatervoicelicense.cpp
+++ b/linden/indra/newview/floatervoicelicense.cpp
@@ -128,8 +128,16 @@ BOOL FloaterVoiceLicense::postBuild()
128 // start to observe it so we see navigate complete events 128 // start to observe it so we see navigate complete events
129 web_browser->addObserver( this ); 129 web_browser->addObserver( this );
130 130
131 gResponsePtr = LLIamHereVoice::build( this ); 131 std::string url = getString( "real_url" );
132 LLHTTPClient::get( getString( "real_url" ), gResponsePtr ); 132 if (url.substr(0,4) == "http")
133 {
134 gResponsePtr = LLIamHereVoice::build( this );
135 LLHTTPClient::get( url, gResponsePtr );
136 }
137 else
138 {
139 setSiteIsAlive(false);
140 }
133 } 141 }
134 142
135 return TRUE; 143 return TRUE;
diff --git a/linden/indra/newview/hippogridmanager.cpp b/linden/indra/newview/hippogridmanager.cpp
index 8277361..78539f8 100644
--- a/linden/indra/newview/hippogridmanager.cpp
+++ b/linden/indra/newview/hippogridmanager.cpp
@@ -41,10 +41,14 @@
41#include <llerror.h> 41#include <llerror.h>
42#include <llfile.h> 42#include <llfile.h>
43#include <llhttpclient.h> 43#include <llhttpclient.h>
44#include "llmd5.h"
44#include <llsdserialize.h> 45#include <llsdserialize.h>
46
45#include "lltrans.h" 47#include "lltrans.h"
46#include "llviewercontrol.h" 48#include "llviewercontrol.h"
49#include "llviewernetwork.h" // gMacAddress
47#include "llweb.h" 50#include "llweb.h"
51#include "llxorcipher.h" // saved password, MAC address
48 52
49#include "hipporestrequest.h" 53#include "hipporestrequest.h"
50 54
@@ -82,7 +86,7 @@ HippoGridInfo::HippoGridInfo(const std::string& gridNick) :
82 mSearchURL(LLStringUtil::null), 86 mSearchURL(LLStringUtil::null),
83 mFirstName(LLStringUtil::null), 87 mFirstName(LLStringUtil::null),
84 mLastName(LLStringUtil::null), 88 mLastName(LLStringUtil::null),
85 mAvatarPassword(LLStringUtil::null), 89 mPasswordAvatar(LLStringUtil::null),
86 mXmlState(XML_VOID), 90 mXmlState(XML_VOID),
87 mVoiceConnector("SLVoice"), 91 mVoiceConnector("SLVoice"),
88 mRenderCompat(true), 92 mRenderCompat(true),
@@ -401,6 +405,92 @@ void HippoGridInfo::formatFee(std::string &fee, S32 cost, bool showFree) const
401} 405}
402 406
403 407
408void HippoGridInfo::setPassword(const std::string& unhashed_password)
409{
410 if (unhashed_password.empty())
411 {
412 mPasswordAvatar = "";
413 return;
414 }
415
416 if (unhashed_password == mPasswordAvatar)
417 {
418 return;
419 }
420
421 std::string hashed_password("");
422
423 // Max "actual" password length is 16 characters.
424 // Hex digests are always 32 characters.
425 if (unhashed_password.length() == 32)
426 {
427 hashed_password = unhashed_password;
428 }
429 else
430 {
431 // this is a user-entered plaintext password
432 LLMD5 pass((unsigned char *)unhashed_password.c_str());
433 char munged_password[MD5HEX_STR_SIZE];
434 pass.hex_digest(munged_password);
435 hashed_password = munged_password;
436 }
437
438 // need to fix the bug in this
439 /*
440
441 // Encipher with MAC address
442 const S32 HASHED_LENGTH = 32;
443 U8 buffer[HASHED_LENGTH+1];
444
445 LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
446
447 LLXORCipher cipher(gMACAddress, 6);
448 cipher.encrypt(buffer, HASHED_LENGTH);
449
450 mPasswordAvatar.assign((char*)buffer);
451 */
452 mPasswordAvatar.assign(hashed_password);
453}
454
455
456std::string HippoGridInfo::getPassword() const
457{
458 // need to fix the bug in this
459 /*
460 if (mPasswordAvatar.empty() || mPasswordAvatar.length() == 32)
461 {
462 return mPasswordAvatar;
463 }
464
465 std::string hashed_password("");
466
467 // UUID is 16 bytes, written into ASCII is 32 characters
468 // without trailing \0
469 const S32 HASHED_LENGTH = 32;
470 U8 buffer[HASHED_LENGTH+1];
471
472 LLStringUtil::copy((char*)buffer, mPasswordAvatar.c_str(), HASHED_LENGTH+1);
473
474 // Decipher with MAC address
475 LLXORCipher cipher(gMACAddress, 6);
476 cipher.decrypt(buffer, HASHED_LENGTH);
477
478 buffer[HASHED_LENGTH] = '\0';
479
480 // Check to see if the mac address generated a bad hashed
481 // password. It should be a hex-string or else the mac adress has
482 // changed. This is a security feature to make sure that if you
483 // get someone's grid_info.xml file, you cannot hack their account.
484 if (is_hex_string(buffer, HASHED_LENGTH))
485 {
486 hashed_password.assign((char*)buffer);
487 }
488
489 return hashed_password;
490 */
491 return mPasswordAvatar;
492}
493
404// ******************************************************************** 494// ********************************************************************
405// Static Helpers 495// Static Helpers
406 496
@@ -800,7 +890,7 @@ void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer)
800 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]); 890 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]);
801 if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]); 891 if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]);
802 if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]); 892 if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]);
803 if (gridMap.has("avatarpassword")) grid->setAvatarPassword(gridMap["avatarpassword"]); 893 if (gridMap.has("avatarpassword")) grid->setPassword(gridMap["avatarpassword"]);
804 if (gridMap.has("username")) grid->setUsername(gridMap["username"]); 894 if (gridMap.has("username")) grid->setUsername(gridMap["username"]);
805 if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]); 895 if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]);
806 if (newGrid) addGrid(grid); 896 if (newGrid) addGrid(grid);
@@ -836,7 +926,7 @@ void HippoGridManager::saveFile()
836 gridInfo[i]["password"] = grid->getPasswordURL(); 926 gridInfo[i]["password"] = grid->getPasswordURL();
837 gridInfo[i]["firstname"] = grid->getFirstName(); 927 gridInfo[i]["firstname"] = grid->getFirstName();
838 gridInfo[i]["lastname"] = grid->getLastName(); 928 gridInfo[i]["lastname"] = grid->getLastName();
839 gridInfo[i]["avatarpassword"] = grid->getAvatarPassword(); 929 gridInfo[i]["avatarpassword"] = grid->getPassword();
840 930
841 gridInfo[i]["search"] = grid->getSearchURL(); 931 gridInfo[i]["search"] = grid->getSearchURL();
842 gridInfo[i]["render_compat"] = grid->isRenderCompat(); 932 gridInfo[i]["render_compat"] = grid->isRenderCompat();
diff --git a/linden/indra/newview/hippogridmanager.h b/linden/indra/newview/hippogridmanager.h
index f1b0a8e..c983c9d 100644
--- a/linden/indra/newview/hippogridmanager.h
+++ b/linden/indra/newview/hippogridmanager.h
@@ -88,7 +88,7 @@ public:
88 const std::string& getFirstName() const { return mFirstName; } 88 const std::string& getFirstName() const { return mFirstName; }
89 const std::string& getLastName() const { return mLastName; } 89 const std::string& getLastName() const { return mLastName; }
90 const std::string& getUsername() const { return mUsername; } 90 const std::string& getUsername() const { return mUsername; }
91 const std::string& getAvatarPassword() const { return mAvatarPassword; } 91 std::string getPassword() const;
92 const std::string& getVoiceConnector() const { return mVoiceConnector; } 92 const std::string& getVoiceConnector() const { return mVoiceConnector; }
93 S32 getMaxAgentGroups() const { return mMaxAgentGroups; } 93 S32 getMaxAgentGroups() const { return mMaxAgentGroups; }
94 const std::string& getCurrencySymbol() const { return mCurrencySymbol; } 94 const std::string& getCurrencySymbol() const { return mCurrencySymbol; }
@@ -114,7 +114,7 @@ public:
114 void setMaxAgentGroups(S32 max) { mMaxAgentGroups = max; } 114 void setMaxAgentGroups(S32 max) { mMaxAgentGroups = max; }
115 void setFirstName(const std::string& firstName) { mFirstName = firstName; } 115 void setFirstName(const std::string& firstName) { mFirstName = firstName; }
116 void setLastName(const std::string& lastName) { mLastName = lastName; } 116 void setLastName(const std::string& lastName) { mLastName = lastName; }
117 void setAvatarPassword(const std::string& avatarPassword) { mAvatarPassword = avatarPassword; } 117 void setPassword(const std::string& unhashed_password);
118 void setVoiceConnector(const std::string& vc) { mVoiceConnector = vc; } 118 void setVoiceConnector(const std::string& vc) { mVoiceConnector = vc; }
119 void setCurrencySymbol(const std::string& sym) { mCurrencySymbol = sym.substr(0, 3); } 119 void setCurrencySymbol(const std::string& sym) { mCurrencySymbol = sym.substr(0, 3); }
120 void setRealCurrencySymbol(const std::string& sym) { mRealCurrencySymbol = sym.substr(0, 3); } 120 void setRealCurrencySymbol(const std::string& sym) { mRealCurrencySymbol = sym.substr(0, 3); }
@@ -145,7 +145,7 @@ private:
145 std::string mVoiceConnector; 145 std::string mVoiceConnector;
146 std::string mFirstName; 146 std::string mFirstName;
147 std::string mLastName; 147 std::string mLastName;
148 std::string mAvatarPassword; 148 std::string mPasswordAvatar;
149 bool mRenderCompat; 149 bool mRenderCompat;
150 S32 mMaxAgentGroups; 150 S32 mMaxAgentGroups;
151 151
diff --git a/linden/indra/newview/linux_tools/alsoft.conf b/linden/indra/newview/linux_tools/alsoft.conf
new file mode 100644
index 0000000..7550ff0
--- /dev/null
+++ b/linden/indra/newview/linux_tools/alsoft.conf
@@ -0,0 +1,253 @@
1# OpenAL config file. Options that are not under a block or are under the
2# [general] block are for general, non-backend-specific options. Blocks may
3# appear multiple times, and duplicated options will take the last value
4# specified.
5# The system-wide settings can be put in /etc/openal/alsoft.conf and user-
6# specific override settings in ~/.alsoftrc.
7# For Windows, these settings should go into %AppData%\alsoft.ini
8# The environment variable ALSOFT_CONF can be used to specify another config
9# override
10
11# Option and block names are case-insenstive. The supplied values are only
12# hints and may not be honored (though generally it'll try to get as close as
13# possible). Note: options that are left unset may default to app- or system-
14# specified values. These are the current available settings:
15
16## format:
17# Sets the output format. Can be one of:
18# AL_FORMAT_MONO8 (8-bit mono)
19# AL_FORMAT_STEREO8 (8-bit stereo)
20# AL_FORMAT_QUAD8 (8-bit 4-channel)
21# AL_FORMAT_51CHN8 (8-bit 5.1 output)
22# AL_FORMAT_61CHN8 (8-bit 6.1 output)
23# AL_FORMAT_71CHN8 (8-bit 7.1 output)
24# AL_FORMAT_MONO16 (16-bit mono)
25# AL_FORMAT_STEREO16 (16-bit stereo)
26# AL_FORMAT_QUAD16 (16-bit 4-channel)
27# AL_FORMAT_51CHN16 (16-bit 5.1 output)
28# AL_FORMAT_61CHN16 (16-bit 6.1 output)
29# AL_FORMAT_71CHN16 (16-bit 7.1 output)
30# AL_FORMAT_MONO32 (32-bit float mono)
31# AL_FORMAT_STEREO32 (32-bit float stereo)
32# AL_FORMAT_QUAD32 (32-bit float 4-channel)
33# AL_FORMAT_51CHN32 (32-bit float 5.1 output)
34# AL_FORMAT_61CHN32 (32-bit float 6.1 output)
35# AL_FORMAT_71CHN32 (32-bit float 7.1 output)
36#format = AL_FORMAT_STEREO16
37
38## cf_level:
39# Sets the crossfeed level for stereo output. Valid values are:
40# 0 - No crossfeed
41# 1 - Low crossfeed
42# 2 - Middle crossfeed
43# 3 - High crossfeed (virtual speakers are closer to itself)
44# 4 - Low easy crossfeed
45# 5 - Middle easy crossfeed
46# 6 - High easy crossfeed
47# Users of headphones may want to try various settings. Has no effect on non-
48# stereo modes.
49#cf_level = 0
50
51## head_dampen:
52# Sets the amount of dampening on sounds emanating from behind the listener.
53# This is used to simulate the natural occlusion of the head, which is
54# typically missing with mono and stereo output, and as such, only works on
55# mono and stereo output modes. Valid values range from 0 to 1 (inclusive),
56# and higher values provide a stronger effect.
57#head_dampen = 0.25
58
59## frequency:
60# Sets the output frequency.
61#frequency = 44100
62
63## resampler:
64# Selects the resampler used when mixing sources. Valid values are:
65# 0 - None (nearest sample, no interpolation)
66# 1 - Linear (extrapolates samples using a linear slope between samples)
67# 2 - Cubic (extrapolates samples using a Catmull-Rom spline)
68# Specifying other values will result in using the default (linear).
69#resampler = 1
70
71## rt-prio:
72# Sets real-time priority for the mixing thread. Not all drivers may use this
73# (eg. PortAudio) as they already control the priority of the mixing thread.
74# 0 and negative values will disable it. Note that this may constitute a
75# security risk since a real-time priority thread can indefinitely block
76# normal-priority threads if it fails to wait. As such, the default is
77# disabled.
78#rt-prio = 0
79
80## period_size:
81# Sets the update period size, in frames. This is the number of frames needed
82# for each mixing update.
83#period_size = 1024
84
85## periods:
86# Sets the number of update periods. Higher values create a larger mix ahead,
87# which helps protect against skips when the CPU is under load, but increases
88# the delay between a sound getting mixed and being heard.
89#periods = 4
90
91## sources:
92# Sets the maximum number of allocatable sources. Lower values may help for
93# systems with apps that try to play more sounds than the CPU can handle.
94#sources = 256
95
96## stereodup:
97# Sets whether to duplicate stereo sounds on the rear and side speakers for 4+
98# channel output. This provides a "fuller" playback quality for 4+ channel
99# output modes, although each individual speaker will have a slight reduction
100# in volume to compensate for the extra output speakers. True, yes, on, and
101# non-0 values will duplicate stereo sources. 0 and anything else will cause
102# stereo sounds to only play out the front speakers. This only has an effect
103# when a suitable output format is used (ie. those that contain side and/or
104# rear speakers).
105#stereodup = true
106
107## scalemix:
108# Sets whether to scale the remixed output. When the final mix is written to
109# the device, the multi-channel data is remixed so pure-virtual channels (eg.
110# front-center on stereo output) are remixed and added to available channels
111# (eg. front-left and front-right). Scaling helps ensure that no single source
112# will put out more than 100% on a given physical channel. This can cause a
113# noticeable reduction in overall volume, however, so it is off by default.
114#scalemix = false
115
116## drivers:
117# Sets the backend driver list order, comma-seperated. Unknown backends and
118# duplicated names are ignored. Unlisted backends won't be considered for use
119# unless the list is ended with a comma (eg. 'oss,' will list OSS first
120# followed by all other available backends, while 'oss' will list OSS only).
121# Backends prepended with - won't be available for use (eg. '-oss,' will allow
122# all available backends except OSS). An empty list means the default.
123#drivers = pulse,alsa,core,oss,solaris,dsound,winmm,port,null,wave
124
125## excludefx:
126# Sets which effects to exclude, preventing apps from using them. This can
127# help for apps that try to use effects which are too CPU intensive for the
128# system to handle. Available effects are: eaxreverb,reverb,echo,modulator,
129# dedicated
130#excludefx =
131
132## slots:
133# Sets the maximum number of Auxiliary Effect Slots an app can create. A slot
134# can use a non-negligible amount of CPU time if an effect is set on it even
135# if no sources are feeding it, so this may help when apps use more than the
136# system can handle.
137#slots = 4
138
139## sends:
140# Sets the number of auxiliary sends per source. When not specified (default),
141# it allows the app to request how many it wants. The maximum value currently
142# possible is 4.
143#sends =
144
145## layout:
146# Sets the virtual speaker layout. Values are specified in degrees, where 0 is
147# straight in front, negative goes left, and positive goes right. Unspecified
148# speakers will remain at their default positions (which are dependant on the
149# output format). Available speakers are back-left(bl), side-left(sl), front-
150# left(fl), front-center(fc), front-right(fr), side-right(sr), back-right(br),
151# and back-center(bc).
152#layout =
153
154## layout_*:
155# Channel-specific layouts may be specified to override the layout option. The
156# same speakers as the layout option are available, and the default settings
157# are shown below.
158#layout_STEREO = fl=-90, fr=90
159#layout_QUAD = fl=-45, fr=45, bl=-135, br=135
160#layout_51CHN = fl=-30, fr=30, fc=0, bl=-110, br=110
161#layout_61CHN = fl=-30, fr=30, fc=0, sl=-90, sr=90, bc=180
162#layout_71CHN = fl=-30, fr=30, fc=0, sl=-90, sr=90, bl=-150, br=150
163
164##
165## ALSA backend stuff
166##
167[alsa]
168
169## device:
170# Sets the device name for the default playback device.
171#device = default
172
173## capture:
174# Sets the device name for the default capture device.
175#capture = default
176
177## mmap:
178# Sets whether to try using mmap mode (helps reduce latencies and CPU
179# consumption). If mmap isn't available, it will automatically fall back to
180# non-mmap mode. True, yes, on, and non-0 values will attempt to use mmap. 0
181# and anything else will force mmap off.
182#mmap = true
183
184##
185## OSS backend stuff
186##
187[oss]
188
189## device:
190# Sets the device name for OSS output.
191#device = /dev/dsp
192
193## capture:
194# Sets the device name for OSS capture.
195#capture = /dev/dsp
196
197##
198## Solaris backend stuff
199##
200[solaris]
201
202## device:
203# Sets the device name for Solaris output.
204#device = /dev/audio
205
206##
207## DirectSound backend stuff
208##
209[dsound]
210
211##
212## Windows Multimedia backend stuff
213##
214[winmm]
215
216##
217## PortAudio backend stuff
218##
219[port]
220
221## device:
222# Sets the device index for output. Negative values will use the default as
223# given by PortAudio itself.
224#device = -1
225
226## capture:
227# Sets the device index for capture. Negative values will use the default as
228# given by PortAudio itself.
229#capture = -1
230
231##
232## PulseAudio backend stuff
233##
234[pulse]
235
236## spawn-server:
237# Attempts to spawn a PulseAudio server when requesting to open a PulseAudio
238# device. Note that some apps may open and probe all enumerated devices on
239# startup, causing a server to spawn even if a PulseAudio device is not
240# actually selected. Setting autospawn to false in Pulse's client.conf will
241# still prevent autospawning even if this is set to true.
242#spawn-server = false
243
244##
245## Wave File Writer stuff
246##
247[wave]
248
249## file:
250# Sets the filename of the wave file to write to. An empty name prevents the
251# backend from opening, even when explicitly requested.
252# THIS WILL OVERWRITE EXISTING FILES WITHOUT QUESTION!
253#file = \ No newline at end of file
diff --git a/linden/indra/newview/linux_tools/wrapper.sh b/linden/indra/newview/linux_tools/wrapper.sh
index f6ce272..742c4fc 100755
--- a/linden/indra/newview/linux_tools/wrapper.sh
+++ b/linden/indra/newview/linux_tools/wrapper.sh
@@ -4,17 +4,26 @@
4## These options are for self-assisted troubleshooting during this beta 4## These options are for self-assisted troubleshooting during this beta
5## testing phase; you should not usually need to touch them. 5## testing phase; you should not usually need to touch them.
6 6
7## - Avoids using any OpenAL audio driver. 7## If the default configuration of openal-soft isn't working for you.
8## There are 3 places where it looks for a configuration file:
9## /etc/openal/alsoft.conf $HOME/.alsoftrc and ALSOFT_CONF
10## ALSOFT_CONF is the full path including the filename, like: /home/myuser/myconfigfile.txt
11## If none of them is set a hardcoded default is taken.
12## If you set several: ALSOFT_CONF 'wins' always, and $HOME/.alsoftrc 'wins' over /etc/openal/alsoft.conf
13#export ALSOFT_CONF="$(pwd)/alsoft.conf"
14
15## - Avoids using the OpenAL audio driver; disables any inworld sound effects.
16## NOTE: - OpenAL is not used for any streaming audio in Imprudence.
17## - Other export LL_BAD_<driver> have no effect in Imprudence.
8#export LL_BAD_OPENAL_DRIVER=x 18#export LL_BAD_OPENAL_DRIVER=x
9## - Avoids using any FMOD audio driver.
10#export LL_BAD_FMOD_DRIVER=x
11 19
12## - Avoids using the FMOD ESD audio driver. 20## If you have custom gstreamer plugins,
13#export LL_BAD_FMOD_ESD=x 21## e.g. you want to use Imprudence-1.4.x with the gstreamer plugins of Imprudence-1.3.1:
14## - Avoids using the FMOD OSS audio driver. 22## Imprudence-1.3.1-Linux-x86/lib/gstreamer-plugins
15#export LL_BAD_FMOD_OSS=x 23## respectively Imprudence-1.3.1-Linux-x86_64/lib64/gstreamer-plugins
16## - Avoids using the FMOD ALSA audio driver. 24## NOTE: *WAY* better is to install the gstreamer plugins that come with your distros package manager,
17#export LL_BAD_FMOD_ALSA=x 25## thats why Imprudence-1.4.x comes without gstreamer plugins.
26#export GST_PLUGIN_PATH="'${HOME}/Imprudence-1.3.1-Linux-x86/lib/gstreamer-plugins':'${GST_PLUGIN_PATH}'"
18 27
19## - Avoids the optional OpenGL extensions which have proven most problematic 28## - Avoids the optional OpenGL extensions which have proven most problematic
20## on some hardware. Disabling this option may cause BETTER PERFORMANCE but 29## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
@@ -48,7 +57,6 @@
48 57
49## Everything below this line is just for advanced troubleshooters. 58## Everything below this line is just for advanced troubleshooters.
50##------------------------------------------------------------------- 59##-------------------------------------------------------------------
51
52## - For advanced debugging cases, you can run the viewer under the 60## - For advanced debugging cases, you can run the viewer under the
53## control of another program, such as strace, gdb, or valgrind. If 61## control of another program, such as strace, gdb, or valgrind. If
54## you're building your own viewer, bear in mind that the executable 62## you're building your own viewer, bear in mind that the executable
@@ -127,7 +135,20 @@ if [ -n "$LL_RUN_ERR" ]; then
127 if [ "$LL_RUN_ERR" = "runerr" ]; then 135 if [ "$LL_RUN_ERR" = "runerr" ]; then
128 # generic error running the binary 136 # generic error running the binary
129 echo 'unexpected shutdown' 137 echo 'unexpected shutdown'
130
131
132 fi 138 fi
133fi 139fi
140
141LOGS_PATH="${HOME}/.imprudence/logs"
142if [ -f "${LOGS_PATH}/stack_trace.log" ]; then
143 LOG_PACKAGE_NAME="MAIL-THIS-CRASHLOG-PLEASE.$(date +%y%m%d%H%M).tar.bz2"
144 cp "${LOGS_PATH}/stack_trace.log" stack_trace.log
145 cp "${LOGS_PATH}/Imprudence.log" Imprudence.log
146 tar --numeric-owner -cjf ${LOG_PACKAGE_NAME} \
147 stack_trace.log \
148 Imprudence.log
149 rm stack_trace.log
150 rm Imprudence.log
151 echo "You find a crash log package to mail to Imprudence here:"
152 echo "${RUN_PATH}/${LOG_PACKAGE_NAME}"
153 echo "See where to send: http://wiki.kokuaviewer.org/wiki/Imprudence:Debug_Logs#Where_to_Send_Them"
154fi \ No newline at end of file
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index 88ec2ca..09d65d1 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -56,6 +56,7 @@
56#include "llsdutil.h" 56#include "llsdutil.h"
57//#include "vmath.h" 57//#include "vmath.h"
58 58
59#include "hippogridmanager.h"
59#include "imageids.h" 60#include "imageids.h"
60#include "llbox.h" 61#include "llbox.h"
61#include "llbutton.h" 62#include "llbutton.h"
@@ -2734,14 +2735,24 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
2734 } 2735 }
2735 else if (cameraThirdPerson()) 2736 else if (cameraThirdPerson())
2736 { 2737 {
2737 // range from -.5 to .5 2738 if (gSavedSettings.getBOOL("HeadFollowsMouse"))
2738 F32 x_from_center = 2739 {
2739 ((F32) mouse_x / (F32) gViewerWindow->getWindowWidth() ) - 0.5f; 2740 // range from -.5 to .5
2740 F32 y_from_center = 2741 F32 x_from_center =
2741 ((F32) mouse_y / (F32) gViewerWindow->getWindowHeight() ) - 0.5f; 2742 ((F32) mouse_x / (F32) gViewerWindow->getWindowWidth() ) - 0.5f;
2742 2743 F32 y_from_center =
2743 frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD); 2744 ((F32) mouse_y / (F32) gViewerWindow->getWindowHeight() ) - 0.5f;
2744 frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD); 2745
2746 frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition")
2747 * DEG_TO_RAD);
2748 frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition")
2749 * DEG_TO_RAD);
2750 }
2751 else
2752 {
2753 frameCamera.yaw( 0.f );
2754 frameCamera.pitch( 0.f );
2755 }
2745 lookAtType = LOOKAT_TARGET_FREELOOK; 2756 lookAtType = LOOKAT_TARGET_FREELOOK;
2746 } 2757 }
2747 2758
@@ -5590,7 +5601,7 @@ void LLAgent::getName(std::string& name)
5590 } 5601 }
5591 else 5602 else
5592 { 5603 {
5593 name = gSavedSettings.getString("FirstName") + " " + gSavedSettings.getString("LastName"); 5604 name = gHippoGridManager->getCurrentGrid()->getFirstName() + " " + gHippoGridManager->getCurrentGrid()->getLastName();
5594 } 5605 }
5595} 5606}
5596 5607
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp
index cbec717..0bb5759 100644
--- a/linden/indra/newview/llappviewer.cpp
+++ b/linden/indra/newview/llappviewer.cpp
@@ -1267,6 +1267,19 @@ bool LLAppViewer::cleanup()
1267 1267
1268 LLCalc::cleanUp(); 1268 LLCalc::cleanUp();
1269 1269
1270 // Quitting with "Remember Password" turned off should always stomp your
1271 // saved password, whether or not you successfully logged in. JC
1272 if (!gSavedSettings.getBOOL("RememberPassword"))
1273 {
1274 gHippoGridManager->getConnectedGrid()->setPassword("");
1275
1276 // kill old password.dat file if it exists. We do this to keep setting compatibility with older versions -- MC
1277 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "password.dat");
1278 LLFile::remove(filepath);
1279 }
1280
1281 gHippoGridManager->saveFile();
1282
1270 delete gHippoGridManager; 1283 delete gHippoGridManager;
1271 gHippoGridManager = NULL; 1284 gHippoGridManager = NULL;
1272 1285
@@ -1418,13 +1431,6 @@ bool LLAppViewer::cleanup()
1418 // 1431 //
1419 LLVFile::cleanupClass(); 1432 LLVFile::cleanupClass();
1420 llinfos << "VFS cleaned up" << llendflush; 1433 llinfos << "VFS cleaned up" << llendflush;
1421
1422 // Quitting with "Remember Password" turned off should always stomp your
1423 // saved password, whether or not you successfully logged in. JC
1424 if (!gSavedSettings.getBOOL("RememberPassword"))
1425 {
1426 LLStartUp::deletePasswordFromDisk();
1427 }
1428 1434
1429 // Store the time of our current logoff 1435 // Store the time of our current logoff
1430 gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); 1436 gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp
index 79dddaa..f3d71d7 100644
--- a/linden/indra/newview/llfloaterchat.cpp
+++ b/linden/indra/newview/llfloaterchat.cpp
@@ -49,6 +49,7 @@
49#include "message.h" 49#include "message.h"
50 50
51// project include 51// project include
52#include "hippogridmanager.h"
52#include "llagent.h" 53#include "llagent.h"
53#include "llbutton.h" 54#include "llbutton.h"
54#include "llcheckboxctrl.h" 55#include "llcheckboxctrl.h"
@@ -475,7 +476,7 @@ BOOL checkStringInText(const std::string &text_line, std::string textToMatch)
475 476
476BOOL LLFloaterChat::isOwnNameInText(const std::string &text_line) 477BOOL LLFloaterChat::isOwnNameInText(const std::string &text_line)
477{ 478{
478 if (checkStringInText(text_line, gSavedSettings.getString("FirstName"))) 479 if (checkStringInText(text_line, gHippoGridManager->getConnectedGrid()->getFirstName()))
479 return TRUE; 480 return TRUE;
480 481
481 for (int i=1; i<=3; i++) 482 for (int i=1; i<=3; i++)
diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp
index c99d75d..52192b8 100644
--- a/linden/indra/newview/llfloaterpreference.cpp
+++ b/linden/indra/newview/llfloaterpreference.cpp
@@ -402,6 +402,8 @@ BOOL LLFloaterPreference::postBuild()
402 402
403 mOKBtn = getChild<LLButton>("OK"); 403 mOKBtn = getChild<LLButton>("OK");
404 mOKBtn->setClickedCallback(onBtnOK, this); 404 mOKBtn->setClickedCallback(onBtnOK, this);
405
406 childSetAction("reset_btn", onClickResetPrefs, this);
405 407
406 mPreferenceCore = new LLPreferenceCore( 408 mPreferenceCore = new LLPreferenceCore(
407 getChild<LLTabContainer>("pref core"), 409 getChild<LLTabContainer>("pref core"),
diff --git a/linden/indra/newview/llloginhandler.cpp b/linden/indra/newview/llloginhandler.cpp
index c35ba04..988ef2f 100644
--- a/linden/indra/newview/llloginhandler.cpp
+++ b/linden/indra/newview/llloginhandler.cpp
@@ -131,23 +131,29 @@ bool LLLoginHandler::handle(const LLSD& tokens,
131 131
132 if (password.substr(0,3) != "$1$") 132 if (password.substr(0,3) != "$1$")
133 { 133 {
134 LLMD5 pass((unsigned char*)password.c_str()); 134 // grids we try in order: loginhandler "grid", LastConnectedGrid, grid manager
135 char md5pass[33]; /* Flawfinder: ignore */ 135 // icky that we do this here and in LLStartUp
136 pass.hex_digest(md5pass); 136 std::string grid_nick = query_map["grid"].asString();
137 std::string hashed_password = ll_safe_string(md5pass, 32); 137 if (grid_nick.empty()) grid_nick = gSavedSettings.getString("LastConnectedGrid");
138 LLStartUp::savePasswordToDisk(hashed_password); 138 if (grid_nick.empty()) grid_nick = gHippoGridManager->getCurrentGridNick();
139 HippoGridInfo* grid = gHippoGridManager->getGrid(grid_nick);
140 if (grid) grid->setPassword(password);
139 } 141 }
140 } 142 }
141 143
142 144
143 if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page 145 if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page
144 { 146 {
145 // if we ever support saving names based on grid, we'll have to support saving usernames too -- MC
146 LLPanelLogin::loadLoginForm(); 147 LLPanelLogin::loadLoginForm();
147 148
148 if (!mFirstName.empty() || !mLastName.empty()) 149 if (!mFirstName.empty() || !mLastName.empty())
149 { 150 {
150 // Fill in the name, and maybe the password 151 // Fill in the name, and the password if we can
152 if (password.empty())
153 {
154 password = gHippoGridManager->getCurrentGrid()->getPassword();
155 }
156
151 if (gHippoGridManager && gHippoGridManager->getCurrentGrid()->isUsernameCompat()) 157 if (gHippoGridManager && gHippoGridManager->getCurrentGrid()->isUsernameCompat())
152 { 158 {
153 if (mLastName == "resident" || mLastName == "Resident") 159 if (mLastName == "resident" || mLastName == "Resident")
diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp
index 1dff0cc..fd9d077 100644
--- a/linden/indra/newview/llpanellogin.cpp
+++ b/linden/indra/newview/llpanellogin.cpp
@@ -91,6 +91,7 @@
91 91
92const S32 BLACK_BORDER_HEIGHT = 160; 92const S32 BLACK_BORDER_HEIGHT = 160;
93const S32 MAX_PASSWORD = 16; 93const S32 MAX_PASSWORD = 16;
94const std::string PASSWORD_FILLER = "123456789!123456";
94 95
95LLPanelLogin *LLPanelLogin::sInstance = NULL; 96LLPanelLogin *LLPanelLogin::sInstance = NULL;
96BOOL LLPanelLogin::sCapslockDidNotification = FALSE; 97BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
@@ -174,7 +175,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
174 mLogoImage(), 175 mLogoImage(),
175 mCallback(callback), 176 mCallback(callback),
176 mCallbackData(cb_data), 177 mCallbackData(cb_data),
177 mHtmlAvailable( TRUE ) 178 mHtmlAvailable( TRUE ),
179 mActualPassword("")
178{ 180{
179 setFocusRoot(TRUE); 181 setFocusRoot(TRUE);
180 182
@@ -212,7 +214,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
212 childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace); 214 childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
213 childSetPrevalidate("username_edit", LLLineEditor::prevalidatePrintableSpace); 215 childSetPrevalidate("username_edit", LLLineEditor::prevalidatePrintableSpace);
214 216
215 childSetCommitCallback("password_edit", mungePassword); 217 childSetCommitCallback("password_edit", onPasswordChanged, this);
216 childSetKeystrokeCallback("password_edit", onPassKey, this); 218 childSetKeystrokeCallback("password_edit", onPassKey, this);
217 childSetUserData("password_edit", this); 219 childSetUserData("password_edit", this);
218 220
@@ -355,22 +357,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive )
355 } 357 }
356} 358}
357 359
358void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data)
359{
360 LLPanelLogin* self = (LLPanelLogin*)user_data;
361 LLLineEditor* editor = (LLLineEditor*)caller;
362 std::string password = editor->getText();
363
364 // Re-md5 if we've changed at all
365 if (password != self->mIncomingPassword)
366 {
367 LLMD5 pass((unsigned char *)password.c_str());
368 char munged_password[MD5HEX_STR_SIZE];
369 pass.hex_digest(munged_password);
370 self->mMungedPassword = munged_password;
371 }
372}
373
374LLPanelLogin::~LLPanelLogin() 360LLPanelLogin::~LLPanelLogin()
375{ 361{
376 LLPanelLogin::sInstance = NULL; 362 LLPanelLogin::sInstance = NULL;
@@ -596,6 +582,8 @@ void LLPanelLogin::setFields(const std::string& firstname,
596// static 582// static
597void LLPanelLogin::setPassword(const std::string& password) 583void LLPanelLogin::setPassword(const std::string& password)
598{ 584{
585 // we check for sInstance before getting here
586
599 // Max "actual" password length is 16 characters. 587 // Max "actual" password length is 16 characters.
600 // Hex digests are always 32 characters. 588 // Hex digests are always 32 characters.
601 if (password.length() == 32) 589 if (password.length() == 32)
@@ -604,21 +592,16 @@ void LLPanelLogin::setPassword(const std::string& password)
604 // We don't actually use the password input field, 592 // We don't actually use the password input field,
605 // fill it with MAX_PASSWORD characters so we get a 593 // fill it with MAX_PASSWORD characters so we get a
606 // nice row of asterixes. 594 // nice row of asterixes.
607 const std::string filler("123456789!123456"); 595 sInstance->childSetText("password_edit", PASSWORD_FILLER);
608 sInstance->childSetText("password_edit", filler);
609 sInstance->mIncomingPassword = filler;
610 sInstance->mMungedPassword = password;
611 } 596 }
612 else 597 else
613 { 598 {
614 // this is a normal text password 599 // this is a normal text password
615 sInstance->childSetText("password_edit", password); 600 sInstance->childSetText("password_edit", password);
616 sInstance->mIncomingPassword = password;
617 LLMD5 pass((unsigned char *)password.c_str());
618 char munged_password[MD5HEX_STR_SIZE];
619 pass.hex_digest(munged_password);
620 sInstance->mMungedPassword = munged_password;
621 } 601 }
602
603 // munging happens in the grid manager now
604 sInstance->mActualPassword = password;
622} 605}
623 606
624 607
@@ -714,7 +697,8 @@ void LLPanelLogin::getFields(std::string *firstname,
714 LLStringUtil::trim(*lastname); 697 LLStringUtil::trim(*lastname);
715 } 698 }
716 699
717 *password = sInstance->mMungedPassword; 700 // sent to us from LLStartUp. Saved only on an actual connect
701 *password = sInstance->mActualPassword;
718} 702}
719 703
720// static 704// static
@@ -878,10 +862,14 @@ void LLPanelLogin::loadLoginForm()
878 { 862 {
879 username_l->setText(firstname_s); 863 username_l->setText(firstname_s);
880 } 864 }
881 else 865 else if (!firstname_s.empty() && !lastname_s.empty())
882 { 866 {
883 username_l->setText(firstname_s+"."+lastname_s); 867 username_l->setText(firstname_s+"."+lastname_s);
884 } 868 }
869 else
870 {
871 username_l->clear();
872 }
885 } 873 }
886 else 874 else
887 { 875 {
@@ -889,7 +877,7 @@ void LLPanelLogin::loadLoginForm()
889 lastname_l->setText(lastname_s); 877 lastname_l->setText(lastname_s);
890 } 878 }
891 879
892 setPassword(gHippoGridManager->getCurrentGrid()->getAvatarPassword()); 880 setPassword(gHippoGridManager->getCurrentGrid()->getPassword());
893} 881}
894 882
895 883
@@ -1220,6 +1208,20 @@ void LLPanelLogin::onClickNewAccount(void*)
1220 } 1208 }
1221} 1209}
1222 1210
1211// static
1212void LLPanelLogin::onPasswordChanged(LLUICtrl* caller, void* user_data)
1213{
1214 LLPanelLogin* self = (LLPanelLogin*)user_data;
1215 LLLineEditor* editor = (LLLineEditor*)caller;
1216 std::string password = editor->getText();
1217
1218 // update if we've changed at all
1219 // is there a good way to let users know we can't let them use PASSWORD_FILLER?
1220 if (password != self->mActualPassword && password != PASSWORD_FILLER)
1221 {
1222 self->mActualPassword = password;
1223 }
1224}
1223 1225
1224// *NOTE: This function is dead as of 2008 August. I left it here in case 1226// *NOTE: This function is dead as of 2008 August. I left it here in case
1225// we suddenly decide to put the Quit button back. JC 1227// we suddenly decide to put the Quit button back. JC
diff --git a/linden/indra/newview/llpanellogin.h b/linden/indra/newview/llpanellogin.h
index 947aea6..645999c 100644
--- a/linden/indra/newview/llpanellogin.h
+++ b/linden/indra/newview/llpanellogin.h
@@ -83,7 +83,6 @@ public:
83 static void refreshLoginPage(); 83 static void refreshLoginPage();
84 static void giveFocus(); 84 static void giveFocus();
85 static void setAlwaysRefresh(bool refresh); 85 static void setAlwaysRefresh(bool refresh);
86 static void mungePassword(LLUICtrl* caller, void* user_data);
87 86
88 // inherited from LLViewerMediaObserver 87 // inherited from LLViewerMediaObserver
89 /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); 88 /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
@@ -98,6 +97,7 @@ private:
98 static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response); 97 static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response);
99 static void onClickQuit(void*); 98 static void onClickQuit(void*);
100 static void onClickVersion(void*); 99 static void onClickVersion(void*);
100 static void onPasswordChanged(LLUICtrl* caller, void* user_data);
101 static void onClickForgotPassword(void*); 101 static void onClickForgotPassword(void*);
102 static void onPassKey(LLLineEditor* caller, void* user_data); 102 static void onPassKey(LLLineEditor* caller, void* user_data);
103 static void onSelectServer(LLUICtrl*, void*); 103 static void onSelectServer(LLUICtrl*, void*);
@@ -120,8 +120,7 @@ private:
120 void (*mCallback)(S32 option, void *userdata); 120 void (*mCallback)(S32 option, void *userdata);
121 void* mCallbackData; 121 void* mCallbackData;
122 122
123 std::string mIncomingPassword; 123 std::string mActualPassword;
124 std::string mMungedPassword;
125 124
126 static LLPanelLogin* sInstance; 125 static LLPanelLogin* sInstance;
127 static BOOL sCapslockDidNotification; 126 static BOOL sCapslockDidNotification;
diff --git a/linden/indra/newview/llprefsadvanced.cpp b/linden/indra/newview/llprefsadvanced.cpp
index 89dc0b2..c3a9c0b 100644
--- a/linden/indra/newview/llprefsadvanced.cpp
+++ b/linden/indra/newview/llprefsadvanced.cpp
@@ -82,12 +82,16 @@ BOOL LLPrefsAdvanced::postBuild()
82{ 82{
83 childSetValue("disable_log_screen_check", gSavedSettings.getBOOL("DisableLoginLogoutScreens")); 83 childSetValue("disable_log_screen_check", gSavedSettings.getBOOL("DisableLoginLogoutScreens"));
84 childSetValue("disable_tp_screen_check", gSavedSettings.getBOOL("DisableTeleportScreens")); 84 childSetValue("disable_tp_screen_check", gSavedSettings.getBOOL("DisableTeleportScreens"));
85
85 static BOOL* sShowClientNameTag = rebind_llcontrol<BOOL>("ShowClientNameTag", &gSavedSettings, true); 86 static BOOL* sShowClientNameTag = rebind_llcontrol<BOOL>("ShowClientNameTag", &gSavedSettings, true);
86 childSetValue("client_name_tag_check", (*sShowClientNameTag)); 87 childSetValue("client_name_tag_check", (*sShowClientNameTag));
87 static BOOL* sShowClientColor = rebind_llcontrol<BOOL>("ShowClientColor", &gSavedSettings, true); 88 static BOOL* sShowClientColor = rebind_llcontrol<BOOL>("ShowClientColor", &gSavedSettings, true);
88 childSetValue("client_name_color_check", (*sShowClientColor)); 89 childSetValue("client_name_color_check", (*sShowClientColor));
89 childSetValue("client_name_hover_check", gSavedSettings.getBOOL("ShowClientNameHoverTip")); 90 childSetValue("client_name_hover_check", gSavedSettings.getBOOL("ShowClientNameHoverTip"));
90 childSetValue("client_name_tag_broadcast_check", gSavedSettings.getBOOL("ShowMyClientTagToOthers")); 91 childSetValue("client_name_tag_broadcast_check", gSavedSettings.getBOOL("ShowMyClientTagToOthers"));
92 getChild<LLColorSwatchCtrl>("client_tag_color")->set(gSavedSettings.getColor4("ImprudenceTagColor"));
93 mClientTagColor = gSavedSettings.getColor4("ImprudenceTagColor");
94
91 childSetValue("http_texture_check", gSavedSettings.getBOOL("ImagePipelineUseHTTP")); 95 childSetValue("http_texture_check", gSavedSettings.getBOOL("ImagePipelineUseHTTP"));
92 childSetValue("speed_rez_check", gSavedSettings.getBOOL("SpeedRez")); 96 childSetValue("speed_rez_check", gSavedSettings.getBOOL("SpeedRez"));
93 childSetValue("speed_rez_interval_spinner", (F32)gSavedSettings.getU32("SpeedRezInterval")); 97 childSetValue("speed_rez_interval_spinner", (F32)gSavedSettings.getU32("SpeedRezInterval"));
@@ -127,6 +131,9 @@ void LLPrefsAdvanced::apply()
127 gSavedSettings.setBOOL("ShowClientNameTag", childGetValue("client_name_tag_check")); 131 gSavedSettings.setBOOL("ShowClientNameTag", childGetValue("client_name_tag_check"));
128 gSavedSettings.setBOOL("ShowClientColor", childGetValue("client_name_color_check")); 132 gSavedSettings.setBOOL("ShowClientColor", childGetValue("client_name_color_check"));
129 gSavedSettings.setBOOL("ShowClientNameHoverTip", childGetValue("client_name_hover_check")); 133 gSavedSettings.setBOOL("ShowClientNameHoverTip", childGetValue("client_name_hover_check"));
134 gSavedSettings.setColor4("ImprudenceTagColor", getChild<LLColorSwatchCtrl>("client_tag_color")->get());
135 mClientTagColor = getChild<LLColorSwatchCtrl>("client_tag_color")->get();
136
130 gSavedSettings.setBOOL("ImagePipelineUseHTTP", childGetValue("http_texture_check")); 137 gSavedSettings.setBOOL("ImagePipelineUseHTTP", childGetValue("http_texture_check"));
131 gSavedSettings.setBOOL("SpeedRez", childGetValue("speed_rez_check")); 138 gSavedSettings.setBOOL("SpeedRez", childGetValue("speed_rez_check"));
132 gSavedSettings.setU32("SpeedRezInterval", childGetValue("speed_rez_interval_spinner").asReal()); 139 gSavedSettings.setU32("SpeedRezInterval", childGetValue("speed_rez_interval_spinner").asReal());
@@ -205,6 +212,7 @@ void LLPrefsAdvanced::apply()
205 212
206void LLPrefsAdvanced::cancel() 213void LLPrefsAdvanced::cancel()
207{ 214{
215 gSavedSettings.setColor4("ImprudenceTagColor", mClientTagColor);
208} 216}
209 217
210void LLPrefsAdvanced::refresh() 218void LLPrefsAdvanced::refresh()
diff --git a/linden/indra/newview/llprefsadvanced.h b/linden/indra/newview/llprefsadvanced.h
index d76e602..22236ce 100644
--- a/linden/indra/newview/llprefsadvanced.h
+++ b/linden/indra/newview/llprefsadvanced.h
@@ -59,6 +59,8 @@ private:
59 static void onSpellBaseComboBoxCommit(LLUICtrl* ctrl, void* userdata); 59 static void onSpellBaseComboBoxCommit(LLUICtrl* ctrl, void* userdata);
60 static void onAutoCorrectButton(void * data); 60 static void onAutoCorrectButton(void * data);
61 61
62 LLColor4 mClientTagColor;
63
62protected: 64protected:
63 void initHelpBtn(const std::string& name, const std::string& xml_alert); 65 void initHelpBtn(const std::string& name, const std::string& xml_alert);
64 static void onClickHelp(void* data); 66 static void onClickHelp(void* data);
diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp
index 5ac2bb2..33d9701 100644
--- a/linden/indra/newview/llprefsim.cpp
+++ b/linden/indra/newview/llprefsim.cpp
@@ -179,12 +179,12 @@ void LLPrefsIMImpl::apply()
179 if (gSavedSettings.getBOOL("UseLegacyChatLogsFolder")) 179 if (gSavedSettings.getBOOL("UseLegacyChatLogsFolder"))
180 { 180 {
181 gDirUtilp->setPerAccountChatLogsDir(LLStringUtil::null, 181 gDirUtilp->setPerAccountChatLogsDir(LLStringUtil::null,
182 gSavedSettings.getString("FirstName"), gSavedSettings.getString("LastName") ); 182 gHippoGridManager->getCurrentGrid()->getFirstName(), gHippoGridManager->getCurrentGrid()->getLastName() );
183 } 183 }
184 else 184 else
185 { 185 {
186 gDirUtilp->setPerAccountChatLogsDir(gHippoGridManager->getCurrentGridNick(), 186 gDirUtilp->setPerAccountChatLogsDir(gHippoGridManager->getCurrentGridNick(),
187 gSavedSettings.getString("FirstName"), gSavedSettings.getString("LastName") ); 187 gHippoGridManager->getCurrentGrid()->getFirstName(), gHippoGridManager->getCurrentGrid()->getLastName() );
188 } 188 }
189 LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); 189 LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
190 } 190 }
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 4028cad..e29dc5a 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -76,7 +76,6 @@
76#include "llstring.h" 76#include "llstring.h"
77#include "lluserrelations.h" 77#include "lluserrelations.h"
78#include "llvfs.h" 78#include "llvfs.h"
79#include "llxorcipher.h" // saved password, MAC address
80#include "message.h" 79#include "message.h"
81#include "v3math.h" 80#include "v3math.h"
82 81
@@ -262,7 +261,6 @@ bool LLStartUp::sLoginFailed = false;
262 261
263void login_show(); 262void login_show();
264void login_callback(S32 option, void* userdata); 263void login_callback(S32 option, void* userdata);
265bool is_hex_string(U8* str, S32 len);
266void show_first_run_dialog(); 264void show_first_run_dialog();
267bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); 265bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
268void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); 266void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
@@ -750,12 +748,13 @@ bool idle_startup()
750#endif 748#endif
751 gSavedSettings.setBOOL("AutoLogin", TRUE); 749 gSavedSettings.setBOOL("AutoLogin", TRUE);
752 } 750 }
753 else if (gSavedSettings.getBOOL("AutoLogin")) 751 else if (gSavedSettings.getBOOL("AutoLogin") && gHippoGridManager)
754 { 752 {
755 firstname = gSavedSettings.getString("FirstName"); 753 // at this point, getCurrentGrid is the last logged in grid. Should we create a new entry for this? -- MC
756 lastname = gSavedSettings.getString("LastName"); 754 firstname = gHippoGridManager->getCurrentGrid()->getFirstName();
757 password = LLStartUp::loadPasswordFromDisk(); 755 lastname = gHippoGridManager->getCurrentGrid()->getLastName();
758 gSavedSettings.setBOOL("RememberPassword", TRUE); 756 password = gHippoGridManager->getCurrentGrid()->getPassword();
757 gSavedSettings.setBOOL("RememberPassword", TRUE); // why do we do this, anyway? -- MC
759 758
760#ifdef USE_VIEWER_AUTH 759#ifdef USE_VIEWER_AUTH
761 show_connect_box = true; 760 show_connect_box = true;
@@ -766,9 +765,7 @@ bool idle_startup()
766 else 765 else
767 { 766 {
768 // if not automatically logging in, display login dialog 767 // if not automatically logging in, display login dialog
769 firstname = gSavedSettings.getString("FirstName"); 768 // name and password are now handled in STATE_LOGIN_SHOW when the login screen's shown -- MC
770 lastname = gSavedSettings.getString("LastName");
771 password = LLStartUp::loadPasswordFromDisk();
772 show_connect_box = true; 769 show_connect_box = true;
773 } 770 }
774 771
@@ -826,17 +823,19 @@ bool idle_startup()
826 823
827 // connect dialog is already shown, so fill in the names associated with the grid 824 // connect dialog is already shown, so fill in the names associated with the grid
828 // note how we always remember avatar names, but don't necessarily have to 825 // note how we always remember avatar names, but don't necessarily have to
829 // icky how usernames get bolted on here as a kind of hack -- MC 826 // icky how all this gets bolted on here as a kind of hack -- MC
830 if (gHippoGridManager) 827 if (gHippoGridManager)
831 { 828 {
832 firstname = gHippoGridManager->getCurrentGrid()->getFirstName(); 829 firstname = gHippoGridManager->getCurrentGrid()->getFirstName();
833 lastname = gHippoGridManager->getCurrentGrid()->getLastName(); 830 lastname = gHippoGridManager->getCurrentGrid()->getLastName();
834 // RememberPassword toggles this being saved 831 // RememberPassword toggles this being saved
835 password = gHippoGridManager->getCurrentGrid()->getAvatarPassword(); 832 password = gHippoGridManager->getCurrentGrid()->getPassword();
836 833
834 // empty in case we used logout
837 if (gHippoGridManager->getCurrentGrid()->isUsernameCompat()) 835 if (gHippoGridManager->getCurrentGrid()->isUsernameCompat())
838 { 836 {
839 if (lastname == "resident" || lastname == "Resident") 837 if ((lastname == "resident" || lastname == "Resident") ||
838 (firstname.empty() && lastname.empty()))
840 { 839 {
841 LLPanelLogin::setFields(firstname, password); 840 LLPanelLogin::setFields(firstname, password);
842 } 841 }
@@ -998,8 +997,8 @@ bool idle_startup()
998 997
999 if (!firstname.empty() && !lastname.empty()) 998 if (!firstname.empty() && !lastname.empty())
1000 { 999 {
1001 gSavedSettings.setString("FirstName", firstname); 1000 gHippoGridManager->getCurrentGrid()->setFirstName(firstname);
1002 gSavedSettings.setString("LastName", lastname); 1001 gHippoGridManager->getCurrentGrid()->setLastName(lastname);
1003 1002
1004 //LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << " " << password << LL_ENDL; 1003 //LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << " " << password << LL_ENDL;
1005 gDebugInfo["LoginName"] = firstname + " " + lastname; 1004 gDebugInfo["LoginName"] = firstname + " " + lastname;
@@ -1162,7 +1161,9 @@ bool idle_startup()
1162 // color init must be after saved settings loaded 1161 // color init must be after saved settings loaded
1163 init_colors(); 1162 init_colors();
1164 1163
1165 if (gSavedSettings.getBOOL("VivoxLicenseAccepted") || gHippoGridManager->getConnectedGrid()->isSecondLife()) 1164 if (!gSavedSettings.getBOOL("EnableVoiceChat") ||
1165 (gSavedSettings.getBOOL("EnableVoiceChat") && gSavedSettings.getBOOL("VivoxLicenseAccepted")) ||
1166 !gHippoGridManager->getConnectedGrid()->isSecondLife())
1166 { 1167 {
1167 // skipping over STATE_LOGIN_VOICE_LICENSE since we don't need it 1168 // skipping over STATE_LOGIN_VOICE_LICENSE since we don't need it
1168 // skipping over STATE_UPDATE_CHECK because that just waits for input 1169 // skipping over STATE_UPDATE_CHECK because that just waits for input
@@ -1306,6 +1307,21 @@ bool idle_startup()
1306 } 1307 }
1307 } 1308 }
1308 1309
1310 // We hash a temporary password for login auth. The actual stored password
1311 // is in the grid manager, and is XORed with the mac address -- MC
1312 std::string hashed_password("");
1313 if (password.length() == 32)
1314 {
1315 hashed_password = password;
1316 }
1317 else if (!password.empty())
1318 {
1319 LLMD5 pass((unsigned char *)password.c_str());
1320 char munged_password[MD5HEX_STR_SIZE];
1321 pass.hex_digest(munged_password);
1322 hashed_password = munged_password;
1323 }
1324
1309 // TODO if statement here to use web_login_key 1325 // TODO if statement here to use web_login_key
1310 if(web_login_key.isNull()){ 1326 if(web_login_key.isNull()){
1311 sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1); 1327 sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1);
@@ -1314,7 +1330,7 @@ bool idle_startup()
1314 auth_method, 1330 auth_method,
1315 firstname, 1331 firstname,
1316 lastname, 1332 lastname,
1317 password, 1333 hashed_password,
1318 //web_login_key, 1334 //web_login_key,
1319 start.str(), 1335 start.str(),
1320 gSkipOptionalUpdate, 1336 gSkipOptionalUpdate,
@@ -1573,10 +1589,8 @@ bool idle_startup()
1573 1589
1574 if(successful_login) 1590 if(successful_login)
1575 { 1591 {
1576 { 1592 std::string current_grid = gHippoGridManager->getConnectedGrid()->getGridNick();
1577 std::string current_grid = gHippoGridManager->getConnectedGrid()->getGridNick(); 1593 gSavedSettings.setString("LastConnectedGrid", current_grid);
1578 gSavedSettings.setString("LastConnectedGrid", current_grid);
1579 }
1580 1594
1581 std::string text; 1595 std::string text;
1582 text = LLUserAuth::getInstance()->getResponse("udp_blacklist"); 1596 text = LLUserAuth::getInstance()->getResponse("udp_blacklist");
@@ -1608,19 +1622,23 @@ bool idle_startup()
1608 } 1622 }
1609 text = LLUserAuth::getInstance()->getResponse("last_name"); 1623 text = LLUserAuth::getInstance()->getResponse("last_name");
1610 if(!text.empty()) lastname.assign(text); 1624 if(!text.empty()) lastname.assign(text);
1611 gSavedSettings.setString("FirstName", firstname); 1625
1612 gSavedSettings.setString("LastName", lastname); 1626 gHippoGridManager->getConnectedGrid()->setFirstName(firstname);
1627 gHippoGridManager->getConnectedGrid()->setLastName(lastname);
1613 1628
1614 if (gSavedSettings.getBOOL("RememberPassword")) 1629 if (gSavedSettings.getBOOL("RememberPassword"))
1615 { 1630 {
1616 // Successful login means the password is valid, so save it. 1631 // Successful login means the password is valid, so save it.
1617 LLStartUp::savePasswordToDisk(password); 1632 // formerly LLStartUp::savePasswordToDisk(password);
1633 // this needs to happen after gMACAddress is set -- MC
1634 gHippoGridManager->getConnectedGrid()->setPassword(password);
1618 } 1635 }
1619 else 1636 else
1620 { 1637 {
1621 // Don't leave password from previous session sitting around 1638 // Don't leave password from previous session sitting around
1622 // during this login session. 1639 // during this login session.
1623 LLStartUp::deletePasswordFromDisk(); 1640 // formerly LLStartUp::deletePasswordFromDisk(); -- MC
1641 gHippoGridManager->getConnectedGrid()->setPassword("");
1624 } 1642 }
1625 1643
1626 // this is their actual ability to access content 1644 // this is their actual ability to access content
@@ -3084,180 +3102,6 @@ void login_callback(S32 option, void *userdata)
3084} 3102}
3085 3103
3086 3104
3087// static
3088std::string LLStartUp::loadPasswordFromDisk()
3089{
3090 // Only load password if we also intend to save it (otherwise the user
3091 // wonders what we're doing behind his back). JC
3092 BOOL remember_password = gSavedSettings.getBOOL("RememberPassword");
3093 if (!remember_password)
3094 {
3095 return std::string("");
3096 }
3097
3098 std::string hashed_password("");
3099
3100 // Look for legacy "marker" password from settings.ini
3101 hashed_password = gSavedSettings.getString("Marker");
3102 if (!hashed_password.empty())
3103 {
3104 // Stomp the Marker entry.
3105 gSavedSettings.setString("Marker", "");
3106
3107 // Return that password.
3108 return hashed_password;
3109 }
3110
3111 // UUID is 16 bytes, written into ASCII is 32 characters
3112 // without trailing \0
3113 const S32 HASHED_LENGTH = 32;
3114
3115 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
3116 "password.dat");
3117 LLFILE* fp = LLFile::fopen(filepath, "rb"); /* Flawfinder: ignore */
3118 if (!fp)
3119 {
3120#if LL_DARWIN
3121 UInt32 passwordLength;
3122 char *passwordData;
3123 OSStatus stat = SecKeychainFindGenericPassword(NULL, 10, "Imprudence", 0, NULL, &passwordLength, (void**)&passwordData, NULL);
3124 if (stat == noErr)
3125 {
3126 if (passwordLength == HASHED_LENGTH)
3127 hashed_password.assign(passwordData, HASHED_LENGTH);
3128 SecKeychainItemFreeContent(NULL, passwordData);
3129 }
3130#endif
3131 return hashed_password;
3132 }
3133
3134 U8 buffer[HASHED_LENGTH+1];
3135
3136 if (1 != fread(buffer, HASHED_LENGTH, 1, fp))
3137 {
3138 return hashed_password;
3139 }
3140
3141 fclose(fp);
3142
3143 // Decipher with MAC address
3144 LLXORCipher cipher(gMACAddress, 6);
3145 cipher.decrypt(buffer, HASHED_LENGTH);
3146
3147 buffer[HASHED_LENGTH] = '\0';
3148
3149 // Check to see if the mac address generated a bad hashed
3150 // password. It should be a hex-string or else the mac adress has
3151 // changed. This is a security feature to make sure that if you
3152 // get someone's password.dat file, you cannot hack their account.
3153 if(is_hex_string(buffer, HASHED_LENGTH))
3154 {
3155 hashed_password.assign((char*)buffer);
3156 }
3157#if LL_DARWIN
3158 // we're migrating to the keychain
3159 LLFile::remove(filepath);
3160#endif
3161
3162 return hashed_password;
3163}
3164
3165
3166// static
3167void LLStartUp::savePasswordToDisk(const std::string& hashed_password)
3168{
3169#if LL_DARWIN
3170 SecKeychainItemRef keychainItem;
3171 OSStatus status = SecKeychainFindGenericPassword(NULL, 10, "Imprudence", 0, NULL, NULL, NULL, &keychainItem);
3172 if (status == noErr)
3173 {
3174 SecKeychainItemModifyAttributesAndData(keychainItem, NULL, hashed_password.length(), hashed_password.c_str());
3175 CFRelease(keychainItem);
3176 }
3177 else
3178 {
3179 SecKeychainAddGenericPassword(NULL, 10, "Imprudence", 0, NULL, hashed_password.length(), hashed_password.c_str(), NULL);
3180 }
3181#else
3182 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
3183 "password.dat");
3184 LLFILE* fp = LLFile::fopen(filepath, "wb"); /* Flawfinder: ignore */
3185 if (!fp)
3186 {
3187 return;
3188 }
3189
3190 // Encipher with MAC address
3191 const S32 HASHED_LENGTH = 32;
3192 U8 buffer[HASHED_LENGTH+1];
3193
3194 LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
3195
3196 LLXORCipher cipher(gMACAddress, 6);
3197 cipher.encrypt(buffer, HASHED_LENGTH);
3198
3199 if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1)
3200 {
3201 LL_WARNS("AppInit") << "Short write" << LL_ENDL;
3202 }
3203
3204 fclose(fp);
3205#endif
3206}
3207
3208
3209// static
3210void LLStartUp::deletePasswordFromDisk()
3211{
3212#if LL_DARWIN
3213 SecKeychainItemRef keychainItem;
3214 OSStatus status = SecKeychainFindGenericPassword(NULL, 10, "Imprudence", 0, NULL, NULL, NULL, &keychainItem);
3215 if (status == noErr)
3216 {
3217 SecKeychainItemDelete(keychainItem);
3218 CFRelease(keychainItem);
3219 }
3220#endif
3221 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
3222 "password.dat");
3223 LLFile::remove(filepath);
3224}
3225
3226
3227bool is_hex_string(U8* str, S32 len)
3228{
3229 bool rv = true;
3230 U8* c = str;
3231 while(rv && len--)
3232 {
3233 switch(*c)
3234 {
3235 case '0':
3236 case '1':
3237 case '2':
3238 case '3':
3239 case '4':
3240 case '5':
3241 case '6':
3242 case '7':
3243 case '8':
3244 case '9':
3245 case 'a':
3246 case 'b':
3247 case 'c':
3248 case 'd':
3249 case 'e':
3250 case 'f':
3251 ++c;
3252 break;
3253 default:
3254 rv = false;
3255 break;
3256 }
3257 }
3258 return rv;
3259}
3260
3261void show_first_run_dialog() 3105void show_first_run_dialog()
3262{ 3106{
3263 LLNotifications::instance().add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback); 3107 LLNotifications::instance().add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback);
diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h
index 6dc3946..5960817 100644
--- a/linden/indra/newview/llstartup.h
+++ b/linden/indra/newview/llstartup.h
@@ -106,15 +106,6 @@ public:
106 // gender_name is either "male" or "female" 106 // gender_name is either "male" or "female"
107 static void loadInitialOutfit( const std::string& outfit_folder_name, 107 static void loadInitialOutfit( const std::string& outfit_folder_name,
108 const std::string& gender_name ); 108 const std::string& gender_name );
109
110 // Load MD5 of user's password from local disk file.
111 static std::string loadPasswordFromDisk();
112
113 // Record MD5 of user's password for subsequent login.
114 static void savePasswordToDisk(const std::string& hashed_password);
115
116 // Delete the saved password local disk file.
117 static void deletePasswordFromDisk();
118 109
119 static bool dispatchURL(); 110 static bool dispatchURL();
120 // if we have a SLURL or sim string ("Ahern/123/45") that started 111 // if we have a SLURL or sim string ("Ahern/123/45") that started
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index c0ddac5..9c6d646 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -3243,7 +3243,8 @@ void LLVOAvatar::resolveClient(LLColor4& avatar_name_color, std::string& client,
3243 3243
3244 if(idx == LLUUID("cc7a030f-282f-c165-44d2-b5ee572e72bf")) 3244 if(idx == LLUUID("cc7a030f-282f-c165-44d2-b5ee572e72bf"))
3245 { 3245 {
3246 avatar_name_color = LLColor4(0.79f,0.44f,0.88f);//Imprudence 3246 // defaults to LLColor4(0.79f,0.44f,0.88f)
3247 avatar_name_color = gSavedSettings.getColor4("ImprudenceTagColor"); //Imprudence
3247 client = "Imprudence"; 3248 client = "Imprudence";
3248 3249
3249 }else if(idx == LLUUID("2a9a406c-f448-68f2-4e38-878f8c46c190") || 3250 }else if(idx == LLUUID("2a9a406c-f448-68f2-4e38-878f8c46c190") ||
@@ -3567,7 +3568,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
3567 else 3568 else
3568 { 3569 {
3569 // Set your own name to the Imprudence color -- MC 3570 // Set your own name to the Imprudence color -- MC
3570 client_color = LLColor4(0.79f,0.44f,0.88f); 3571 client_color = gSavedSettings.getColor4("ImprudenceTagColor");
3571 } 3572 }
3572 3573
3573 static BOOL* sShowClientColor = rebind_llcontrol<BOOL>("ShowClientColor", &gSavedSettings, true); 3574 static BOOL* sShowClientColor = rebind_llcontrol<BOOL>("ShowClientColor", &gSavedSettings, true);
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml
index b8f6e7d..e6d4059 100644
--- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml
@@ -24,16 +24,21 @@
24 name="client_name_tag_check" radio_style="false" width="160" /> 24 name="client_name_tag_check" radio_style="false" width="160" />
25 <check_box bottom_delta="-18" enabled="true" follows="left|top" 25 <check_box bottom_delta="-18" enabled="true" follows="left|top"
26 font="SansSerifSmall" height="16" initial_value="false" 26 font="SansSerifSmall" height="16" initial_value="false"
27 label="Show client names with color" left_delta="0" mouse_opaque="true"
28 name="client_name_color_check" radio_style="false" width="160" />
29 <check_box bottom_delta="-18" enabled="true" follows="left|top"
30 font="SansSerifSmall" height="16" initial_value="false"
31 label="Show client names in hovertip" left_delta="0" mouse_opaque="true" 27 label="Show client names in hovertip" left_delta="0" mouse_opaque="true"
32 name="client_name_hover_check" radio_style="false" width="160" /> 28 name="client_name_hover_check" radio_style="false" width="160" />
33 <check_box bottom_delta="-18" enabled="true" follows="left|top" 29 <check_box bottom_delta="-18" enabled="true" follows="left|top"
34 font="SansSerifSmall" height="16" initial_value="false" 30 font="SansSerifSmall" height="16" initial_value="false"
35 label="Show your client name to others" left_delta="0" mouse_opaque="true" 31 label="Show your client name to others" left_delta="0" mouse_opaque="true"
36 name="client_name_tag_broadcast_check" radio_style="false" width="217" /> 32 name="client_name_tag_broadcast_check" radio_style="false" width="217" />
33 <color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-122"
34 can_apply_immediately="true" color="0.79 0.44 0.88 1"
35 enabled="true" follows="left|top"
36 height="65" label="Imprudence" left="250" mouse_opaque="true"
37 name="client_tag_color" width="65" />
38 <check_box bottom_delta="-18" enabled="true" follows="left|top"
39 font="SansSerifSmall" height="16" initial_value="false"
40 label="Show client names with color" left_delta="0" mouse_opaque="true"
41 name="client_name_color_check" radio_style="false" width="160" />
37 <check_box bottom_delta="-25" enabled="true" follows="left|top" 42 <check_box bottom_delta="-25" enabled="true" follows="left|top"
38 font="SansSerifSmall" height="16" initial_value="false" 43 font="SansSerifSmall" height="16" initial_value="false"
39 label="Enable shadows (WARNING: unstable and requires Ultra graphics)" left="12" mouse_opaque="true" 44 label="Enable shadows (WARNING: unstable and requires Ultra graphics)" left="12" mouse_opaque="true"
@@ -77,6 +82,11 @@
77 tool_tip="Toggle editing animation and standing up when entering appearance mode" 82 tool_tip="Toggle editing animation and standing up when entering appearance mode"
78 label="Animate avatar when editing appearance" left="12" mouse_opaque="true" 83 label="Animate avatar when editing appearance" left="12" mouse_opaque="true"
79 name="appearance_anim_check" radio_style="false" width="217" /> 84 name="appearance_anim_check" radio_style="false" width="217" />
85 <check_box bottom_delta="-25" control_name="HeadFollowsMouse" enabled="true"
86 follows="left|top" font="SansSerifSmall" height="16"
87 label="Head follows mouse" tooltip="If your avatars head follows your mouse movements" left="12"
88 mouse_opaque="true" name="head_follows_mouse_checkbox" radio_style="false"
89 width="256" />
80 <check_box bottom_delta="-25" enabled="true" 90 <check_box bottom_delta="-25" enabled="true"
81 follows="left|top" font="SansSerifSmall" height="16" initial_value="false" 91 follows="left|top" font="SansSerifSmall" height="16" initial_value="false"
82 label="Use legacy pie menus" left="12" 92 label="Use legacy pie menus" left="12"
diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py
index 86acaea..0f129dd 100755
--- a/linden/indra/newview/viewer_manifest.py
+++ b/linden/indra/newview/viewer_manifest.py
@@ -912,6 +912,7 @@ class LinuxManifest(ViewerManifest):
912 912
913 self.path("res/imprudence_icon.png","imprudence_icon.png") 913 self.path("res/imprudence_icon.png","imprudence_icon.png")
914 if self.prefix("linux_tools", dst=""): 914 if self.prefix("linux_tools", dst=""):
915 self.path("alsoft.conf")
915 #self.path("client-readme.txt","README-linux.txt") 916 #self.path("client-readme.txt","README-linux.txt")
916 self.path("client-readme-voice.txt","README-linux-voice.txt") 917 self.path("client-readme-voice.txt","README-linux-voice.txt")
917 #self.path("client-readme-joystick.txt","README-linux-joystick.txt") 918 #self.path("client-readme-joystick.txt","README-linux-joystick.txt")
diff --git a/linden/indra/newview/viewertime.cpp b/linden/indra/newview/viewertime.cpp
index 5ed9465..9892aa5 100644
--- a/linden/indra/newview/viewertime.cpp
+++ b/linden/indra/newview/viewertime.cpp
@@ -107,7 +107,13 @@ void ViewerTime::refresh()
107 // it's daylight savings time there. 107 // it's daylight savings time there.
108 internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime); 108 internal_time = utc_to_pacific_time(utc_time, gPacificDaylightTime);
109 } 109 }
110 110
111 if(NULL == internal_time)
112 {
113 llwarns << "internal_time == NULL - Kaboom!" << llendl;
114 return;
115 }
116
111 mMinute = internal_time->tm_min; 117 mMinute = internal_time->tm_min;
112 mSecond = internal_time->tm_sec; 118 mSecond = internal_time->tm_sec;
113 S32 hour = internal_time->tm_hour; 119 S32 hour = internal_time->tm_hour;