aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/hippoGridManager.cpp
diff options
context:
space:
mode:
authorArmin Weatherwax2009-06-26 09:39:58 +0200
committerArmin Weatherwax2009-07-11 13:42:35 +0200
commit7067b31a6114089217e482bfecc58fd56bed4272 (patch)
treee0bb99a42c64cdb75e9ca15a38bc1171377c7739 /linden/indra/newview/hippoGridManager.cpp
parentUpdated URL for Mac OpenAL libs package. (diff)
downloadmeta-impy-7067b31a6114089217e482bfecc58fd56bed4272.zip
meta-impy-7067b31a6114089217e482bfecc58fd56bed4272.tar.gz
meta-impy-7067b31a6114089217e482bfecc58fd56bed4272.tar.bz2
meta-impy-7067b31a6114089217e482bfecc58fd56bed4272.tar.xz
BROKEN logoff/relog crashing inconsistently on various startup states.
Diffstat (limited to 'linden/indra/newview/hippoGridManager.cpp')
-rw-r--r--linden/indra/newview/hippoGridManager.cpp597
1 files changed, 597 insertions, 0 deletions
diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippoGridManager.cpp
new file mode 100644
index 0000000..8415adb
--- /dev/null
+++ b/linden/indra/newview/hippoGridManager.cpp
@@ -0,0 +1,597 @@
1
2
3#include "hippoGridManager.h"
4
5#include <cctype>
6
7#include <stdtypes.h>
8#include <lldir.h>
9#include <lleconomy.h>
10#include <llerror.h>
11#include <llfile.h>
12#include <llhttpclient.h>
13#include <llsdserialize.h>
14#include "llviewercontrol.h"
15#include "llweb.h"
16
17#include "hippoRestRequest.h"
18
19
20// ********************************************************************
21// Global Variables
22
23HippoGridManager *gHippoGridManager = 0;
24
25HippoGridInfo HippoGridInfo::FALLBACK_GRIDINFO("");
26
27
28
29// ********************************************************************
30// ********************************************************************
31// HippoGridInfo
32// ********************************************************************
33// ********************************************************************
34
35
36// ********************************************************************
37// Initialize
38
39HippoGridInfo::HippoGridInfo(const std::string &gridNick) :
40 mPlatform(PLATFORM_OTHER),
41 mGridNick(gridNick),
42 mRenderCompat(true),
43 mCurrencySymbol("OS$"),
44 mRealCurrencySymbol("US$"),
45 mDirectoryFee(30)
46{
47 cleanUpGridNick(mGridNick);
48}
49
50
51void HippoGridInfo::setPlatform(Platform platform)
52{
53 mPlatform = platform;
54 mCurrencySymbol = (mPlatform == PLATFORM_SECONDLIFE)? "L$": "OS$";
55}
56
57
58void HippoGridInfo::setPlatform(const std::string &platform)
59{
60 std::string tmp = platform;
61 for (unsigned i=0; i<platform.size(); i++)
62 tmp[i] = tolower(tmp[i]);
63
64 if (tmp == "opensim") {
65 setPlatform(PLATFORM_OPENSIM);
66 } else if (tmp == "secondlife") {
67 setPlatform(PLATFORM_SECONDLIFE);
68 } else {
69 setPlatform(PLATFORM_OTHER);
70 llwarns << "Unknown platform '" << platform << "'." << llendl;
71 }
72}
73
74
75// ********************************************************************
76// Grid Info
77
78std::string HippoGridInfo::getSearchUrl(SearchType ty) const
79{
80 if ((mPlatform == PLATFORM_SECONDLIFE) || mSearchUrl.empty()) {
81 // Second Life defaults
82 if (ty == SEARCH_ALL_EMPTY) {
83 return gSavedSettings.getString("SearchURLDefault");
84 } else if (ty == SEARCH_ALL_QUERY) {
85 return gSavedSettings.getString("SearchURLQuery");
86 } else if (ty == SEARCH_ALL_TEMPLATE) {
87 return gSavedSettings.getString("SearchURLSuffix2");
88 } else {
89 llinfos << "Illegal search URL type " << ty << llendl;
90 return "";
91 }
92 } else {
93 // OpenSim and other
94 if (ty == SEARCH_ALL_EMPTY) {
95 return (mSearchUrl + "panel=All&");
96 } else if (ty == SEARCH_ALL_QUERY) {
97 return (mSearchUrl + "q=[QUERY]&s=[COLLECTION]&");
98 } else if (ty == SEARCH_ALL_TEMPLATE) {
99 return "lang=[LANG]&m=[MATURE]&t=[TEEN]&region=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]";
100 } else {
101 llinfos << "Illegal search URL type " << ty << llendl;
102 return "";
103 }
104 }
105}
106
107
108//static
109void HippoGridInfo::onXmlElementStart(void *userData, const XML_Char *name, const XML_Char **atts)
110{
111 HippoGridInfo *self = (HippoGridInfo*)userData;
112 if (strcasecmp(name, "gridnick") == 0)
113 self->mXmlState = XML_GRIDNICK;
114 else if (strcasecmp(name, "gridname") == 0)
115 self->mXmlState = XML_GRIDNAME;
116 else if (strcasecmp(name, "platform") == 0)
117 self->mXmlState = XML_PLATFORM;
118 else if ((strcasecmp(name, "login") == 0) || (strcasecmp(name, "loginuri") == 0))
119 self->mXmlState = XML_LOGINURI;
120 else if ((strcasecmp(name, "welcome") == 0) || (strcasecmp(name, "loginpage") == 0))
121 self->mXmlState = XML_LOGINPAGE;
122 else if ((strcasecmp(name, "economy") == 0) || (strcasecmp(name, "helperuri") == 0))
123 self->mXmlState = XML_HELPERURI;
124 else if ((strcasecmp(name, "about") == 0) || (strcasecmp(name, "website") == 0))
125 self->mXmlState = XML_WEBSITE;
126 else if ((strcasecmp(name, "help") == 0) || (strcasecmp(name, "support") == 0))
127 self->mXmlState = XML_SUPPORT;
128 else if ((strcasecmp(name, "register") == 0) || (strcasecmp(name, "account") == 0))
129 self->mXmlState = XML_REGISTER;
130 else if (strcasecmp(name, "password") == 0)
131 self->mXmlState = XML_PASSWORD;
132 //else if (strcasecmp(name, "search") == 0)
133 //self->mXmlState = XML_SEARCH;
134}
135
136//static
137void HippoGridInfo::onXmlElementEnd(void *userData, const XML_Char *name)
138{
139 HippoGridInfo *self = (HippoGridInfo*)userData;
140 self->mXmlState = XML_VOID;
141}
142
143//static
144void HippoGridInfo::onXmlCharacterData(void *userData, const XML_Char *s, int len)
145{
146 HippoGridInfo *self = (HippoGridInfo*)userData;
147 switch (self->mXmlState) {
148
149 case XML_GRIDNICK:
150 if (self->mGridNick == "") self->mGridNick.assign(s, len);
151 cleanUpGridNick(self->mGridNick);
152 break;
153
154 case XML_PLATFORM: {
155 std::string platform(s, len);
156 self->setPlatform(platform);
157 break;
158 }
159
160 case XML_LOGINURI:
161 self->mLoginUri.assign(s, len);
162 cleanUpUri(self->mLoginUri);
163 break;
164
165 case XML_HELPERURI:
166 self->mHelperUri.assign(s, len);
167 cleanUpUri(self->mHelperUri);
168 break;
169
170 case XML_SEARCH:
171 //self->mSearchUrl.assign(s, len);
172 //cleanUpQueryUrl(mSearchUrl);
173 break;
174
175 case XML_GRIDNAME: self->mGridName.assign(s, len); break;
176 case XML_LOGINPAGE: self->mLoginPage.assign(s, len); break;
177 case XML_WEBSITE: self->mWebSite.assign(s, len); break;
178 case XML_SUPPORT: self->mSupportUrl.assign(s, len); break;
179 case XML_REGISTER: self->mRegisterUrl.assign(s, len); break;
180 case XML_PASSWORD: self->mPasswordUrl.assign(s, len); break;
181
182 case XML_VOID: break;
183 }
184}
185
186
187bool HippoGridInfo::retrieveGridInfo()
188{
189 if (mLoginUri == "") return false;
190
191 std::string reply;
192 int result = HippoRestRequest::getBlocking(mLoginUri + "get_grid_info", &reply);
193 if (result != 200) return false;
194
195 llinfos << "Received: " << reply << llendl;
196
197 bool success = true;
198 XML_Parser parser = XML_ParserCreate(0);
199 XML_SetUserData(parser, this);
200 XML_SetElementHandler(parser, onXmlElementStart, onXmlElementEnd);
201 XML_SetCharacterDataHandler(parser, onXmlCharacterData);
202 mXmlState = XML_VOID;
203 if (!XML_Parse(parser, reply.data(), reply.size(), TRUE)) {
204 llwarns << "XML Parse Error: " << XML_ErrorString(XML_GetErrorCode(parser)) << llendl;
205 success = false;
206 }
207 XML_ParserFree(parser);
208
209 return success;
210}
211
212
213std::string HippoGridInfo::getUploadFee() const
214{
215 std::string fee;
216 formatFee(fee, LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(), true);
217 return fee;
218}
219
220std::string HippoGridInfo::getGroupCreationFee() const
221{
222 std::string fee;
223 formatFee(fee, LLGlobalEconomy::Singleton::getInstance()->getPriceGroupCreate(), false);
224 return fee;
225}
226
227std::string HippoGridInfo::getDirectoryFee() const
228{
229 std::string fee;
230 formatFee(fee, mDirectoryFee, true);
231 if (fee != "free") fee += "/week";
232 return fee;
233}
234
235void HippoGridInfo::formatFee(std::string &fee, int cost, bool showFree) const
236{
237 if (showFree && (cost == 0)) {
238 fee = "free";
239 } else {
240 fee = llformat("%s%d", getCurrencySymbol().c_str(), cost);
241 }
242}
243
244
245// ********************************************************************
246// Static Helpers
247
248// static
249const char *HippoGridInfo::getPlatformString(Platform platform)
250{
251 static const char *platformStrings[PLATFORM_LAST] = {
252 "Other", "OpenSim", "SecondLife"
253 };
254
255 if ((platform < PLATFORM_OTHER) || (platform >= PLATFORM_LAST))
256 platform = PLATFORM_OTHER;
257 return platformStrings[platform];
258}
259
260
261// static
262void HippoGridInfo::cleanUpGridNick(std::string &gridnick)
263{
264 std::string tmp;
265 int size = gridnick.size();
266 for (int i=0; i<size; i++) {
267 char c = gridnick[i];
268 if ((c == '_') || isalnum(c)) {
269 tmp += tolower(c);
270 } else if (isspace(c)) {
271 tmp += "_";
272 }
273 }
274 gridnick = tmp;
275}
276
277// static
278void HippoGridInfo::cleanUpUri(std::string &uri)
279{
280 std::string::size_type n = uri.rfind('/');
281 if ((n == std::string::npos) || (n < 10))
282 uri += '/';
283}
284
285
286void HippoGridInfo::initFallback()
287{
288 FALLBACK_GRIDINFO.mGridNick = "secondlife";
289 FALLBACK_GRIDINFO.setPlatform(PLATFORM_SECONDLIFE);
290 FALLBACK_GRIDINFO.setGridName("Second Life");
291 FALLBACK_GRIDINFO.setLoginUri("https://login.agni.lindenlab.com/cgi-bin/login.cgi");
292 FALLBACK_GRIDINFO.setLoginPage("http://secondlife.com/app/login/");
293 FALLBACK_GRIDINFO.setHelperUri("https://secondlife.com/helpers/");
294 FALLBACK_GRIDINFO.setWebSite("http://secondlife.com/");
295}
296
297
298
299// ********************************************************************
300// ********************************************************************
301// HippoGridManager
302// ********************************************************************
303// ********************************************************************
304
305
306// ********************************************************************
307// Initialize
308
309HippoGridManager::HippoGridManager() :
310 mConnectedGrid(0),
311 mDefaultGridsVersion(0)
312{
313}
314
315HippoGridManager::~HippoGridManager()
316{
317 cleanup();
318}
319
320
321void HippoGridManager::cleanup()
322{
323 std::map<std::string, HippoGridInfo*>::iterator it, end = mGridInfo.end();
324 for (it=mGridInfo.begin(); it != end; ++it) {
325 delete it->second;
326 }
327 mGridInfo.clear();
328}
329
330
331void HippoGridManager::init()
332{
333 HippoGridInfo::initFallback();
334 loadFromFile();
335
336 // !!!### gSavedSettings.getControl("CmdLineLoginURI");
337 // !!!### gSavedSettings.getString("CmdLineLoginPage");
338 // !!!### gSavedSettings.getString("CmdLineHelperURI");
339 // !!!### LLString::compareInsensitive(gGridInfo[grid_index].mLabel, grid_name.c_str()))
340}
341
342
343void HippoGridManager::discardAndReload()
344{
345 cleanup();
346 loadFromFile();
347}
348
349
350// ********************************************************************
351// Public Access
352
353HippoGridInfo *HippoGridManager::getGrid(const std::string &grid) const
354{
355 std::map<std::string, HippoGridInfo*>::const_iterator it;
356 it = mGridInfo.find(grid);
357 if (it != mGridInfo.end()) {
358 return it->second;
359 } else {
360 return 0;
361 }
362}
363
364
365HippoGridInfo *HippoGridManager::getCurrentGrid() const
366{
367 HippoGridInfo *grid = getGrid(mCurrentGrid);
368 if (grid) {
369 return grid;
370 } else {
371 return &HippoGridInfo::FALLBACK_GRIDINFO;
372 }
373}
374
375
376void HippoGridManager::addGrid(HippoGridInfo *grid)
377{
378 if (!grid) return;
379 const std::string &nick = grid->getGridNick();
380 if (nick == "") {
381 llwarns << "Ignoring to try adding grid with empty nick." << llendl;
382 delete grid;
383 return;
384 }
385 if (mGridInfo.find(nick) != mGridInfo.end()) {
386 llwarns << "Ignoring to try adding existing grid " << nick << '.' << llendl;
387 delete grid;
388 return;
389 }
390 mGridInfo[nick] = grid;
391}
392
393
394void HippoGridManager::deleteGrid(const std::string &grid)
395{
396 GridIterator it = mGridInfo.find(grid);
397 if (it == mGridInfo.end()) {
398 llwarns << "Trying to delete non-existing grid " << grid << '.' << llendl;
399 return;
400 }
401 mGridInfo.erase(it);
402 llinfos << "Number of grids now: " << mGridInfo.size() << llendl;
403 if (mGridInfo.empty()) llinfos << "Grid info map is empty." << llendl;
404 if (grid == mDefaultGrid)
405 setDefaultGrid(""); // sets first grid, if map not empty
406 if (grid == mCurrentGrid)
407 mCurrentGrid = mDefaultGrid;
408}
409
410
411void HippoGridManager::setDefaultGrid(const std::string &grid)
412{
413 GridIterator it = mGridInfo.find(grid);
414 if (it != mGridInfo.end()) {
415 mDefaultGrid = grid;
416 } else if (mGridInfo.find("secondlife") != mGridInfo.end()) {
417 mDefaultGrid = "secondlife";
418 } else if (!mGridInfo.empty()) {
419 mDefaultGrid = mGridInfo.begin()->first;
420 } else {
421 mDefaultGrid = "";
422 }
423}
424
425
426void HippoGridManager::setCurrentGrid(const std::string &grid)
427{
428 GridIterator it = mGridInfo.find(grid);
429 if (it != mGridInfo.end()) {
430 mCurrentGrid = grid;
431 } else if (!mGridInfo.empty()) {
432 llwarns << "Unknown grid '" << grid << "'. Setting to default grid." << llendl;
433 mCurrentGrid = mDefaultGrid;
434 }
435}
436
437
438// ********************************************************************
439// Persistent Store
440
441void HippoGridManager::loadFromFile()
442{
443 mDefaultGridsVersion = 0;
444 // load user grid info
445 parseFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml"), false);
446 // merge default grid info, if newer. Force load, if list of grids is empty.
447 parseFile(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml"), !mGridInfo.empty());
448 // merge grid info from web site, if newer. Force load, if list of grids is empty.
449 if (gSavedSettings.getBOOL("CheckForGridUpdates"))
450 parseUrl("http://opensim-viewer.sourceforge.net/db/grids.php", !mGridInfo.empty());
451
452 setDefaultGrid(gSavedSettings.getString("DefaultGrid"));
453 setCurrentGrid(gSavedSettings.getString("CmdLineGridChoice"));
454}
455
456
457void HippoGridManager::parseUrl(const char *url, bool mergeIfNewer)
458{
459 llinfos << "Loading grid info from '" << url << "'." << llendl;
460
461 // query update server
462 std::string escaped_url = LLWeb::escapeURL(url);
463 LLSD response = LLHTTPClient::blockingGet(url);
464
465 // check response, return on error
466 S32 status = response["status"].asInteger();
467 if ((status != 200) || !response["body"].isArray()) {
468 llinfos << "GridInfo Update failed (" << status << "): "
469 << (response["body"].isString()? response["body"].asString(): "<unknown error>")
470 << llendl;
471 return;
472 }
473
474 LLSD gridInfo = response["body"];
475 parseData(gridInfo, mergeIfNewer);
476}
477
478void HippoGridManager::parseFile(const std::string &fileName, bool mergeIfNewer)
479{
480 llifstream infile;
481 infile.open(fileName.c_str());
482 if(!infile.is_open()) {
483 llwarns << "Cannot find grid info file " << fileName << " to load." << llendl;
484 return;
485 }
486
487 LLSD gridInfo;
488 if (LLSDSerialize::fromXML(gridInfo, infile) <= 0) {
489 llwarns << "Unable to parse grid info file " << fileName << '.' << llendl;
490 return;
491 }
492
493 llinfos << "Loading grid info file " << fileName << '.' << llendl;
494 parseData(gridInfo, mergeIfNewer);
495}
496
497
498void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer)
499{
500 if (mergeIfNewer) {
501 LLSD::array_const_iterator it, end = gridInfo.endArray();
502 for (it = gridInfo.beginArray(); it != end; ++it) {
503 LLSD gridMap = *it;
504 if (gridMap.has("default_grids_version")) {
505 int version = gridMap["default_grids_version"];
506 if (version <= mDefaultGridsVersion) return;
507 else break;
508 }
509 }
510 if (it == end) {
511 llwarns << "Grid data has no version number." << llendl;
512 return;
513 }
514 }
515
516 llinfos << "Loading grid data." << llendl;
517
518 LLSD::array_const_iterator it, end = gridInfo.endArray();
519 for (it = gridInfo.beginArray(); it != end; ++it) {
520 LLSD gridMap = *it;
521 if (gridMap.has("default_grids_version")) {
522 mDefaultGridsVersion = gridMap["default_grids_version"];
523 } else if (gridMap.has("gridnick") && gridMap.has("loginuri")) {
524 std::string gridnick = gridMap["gridnick"];
525 HippoGridInfo *grid;
526 GridIterator it = mGridInfo.find(gridnick);
527 bool newGrid = (it == mGridInfo.end());
528 if (newGrid) {
529 // create new grid info
530 grid = new HippoGridInfo(gridnick);
531 } else {
532 // update existing grid info
533 grid = it->second;
534 }
535 grid->setLoginUri(gridMap["loginuri"]);
536 if (gridMap.has("platform")) grid->setPlatform(gridMap["platform"]);
537 if (gridMap.has("gridname")) grid->setGridName(gridMap["gridname"]);
538 if (gridMap.has("loginpage")) grid->setLoginPage(gridMap["loginpage"]);
539 if (gridMap.has("helperuri")) grid->setHelperUri(gridMap["helperuri"]);
540 if (gridMap.has("website")) grid->setWebSite(gridMap["website"]);
541 if (gridMap.has("support")) grid->setSupportUrl(gridMap["support"]);
542 if (gridMap.has("register")) grid->setRegisterUrl(gridMap["register"]);
543 if (gridMap.has("password")) grid->setPasswordUrl(gridMap["password"]);
544 //if (gridMap.has("search")) grid->setSearchUrl(gridMap["search"]);
545 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]);
546 if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]);
547 if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]);
548 if (gridMap.has("avatarpassword")) grid->setAvatarPassword(gridMap["avatarpassword"]);
549 if (newGrid) addGrid(grid);
550 }
551 }
552}
553
554
555void HippoGridManager::saveFile()
556{
557 // save default grid to client settings
558 gSavedSettings.setString("DefaultGrid", mDefaultGrid);
559
560 // build LLSD
561 LLSD gridInfo;
562 gridInfo[0]["default_grids_version"] = mDefaultGridsVersion;
563
564 // add grids
565 S32 i = 1;
566 GridIterator it, end = mGridInfo.end();
567 for (it = mGridInfo.begin(); it != end; ++it, i++) {
568 HippoGridInfo *grid = it->second;
569 gridInfo[i]["gridnick"] = grid->getGridNick();
570 gridInfo[i]["platform"] = HippoGridInfo::getPlatformString(grid->getPlatform());
571 gridInfo[i]["gridname"] = grid->getGridName();
572 gridInfo[i]["loginuri"] = grid->getLoginUri();
573 gridInfo[i]["loginpage"] = grid->getLoginPage();
574 gridInfo[i]["helperuri"] = grid->getHelperUri();
575 gridInfo[i]["website"] = grid->getWebSite();
576 gridInfo[i]["support"] = grid->getSupportUrl();
577 gridInfo[i]["register"] = grid->getRegisterUrl();
578 gridInfo[i]["firstname"] = grid->getFirstName();
579 gridInfo[i]["lastname"] = grid->getLastName();
580 gridInfo[i]["avatarpassword"] = grid->getAvatarPassword();
581
582 //gridInfo[i]["search"] = grid->getSearchUrl();
583 gridInfo[i]["render_compat"] = grid->isRenderCompat();
584 }
585
586 // write client grid info file
587 std::string fileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml");
588 llofstream file;
589 file.open(fileName.c_str());
590 if (file.is_open()) {
591 LLSDSerialize::toPrettyXML(gridInfo, file);
592 file.close();
593 llinfos << "Saved grids to " << fileName << llendl;
594 } else {
595 llerrs << "Unable to open grid info file: " << fileName << llendl;
596 }
597}