diff options
Diffstat (limited to 'linden/indra/newview/hippoGridManager.cpp')
-rw-r--r-- | linden/indra/newview/hippoGridManager.cpp | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippoGridManager.cpp new file mode 100644 index 0000000..71e3a95 --- /dev/null +++ b/linden/indra/newview/hippoGridManager.cpp | |||
@@ -0,0 +1,819 @@ | |||
1 | |||
2 | |||
3 | #include "llviewerprecompiledheaders.h" | ||
4 | |||
5 | #include "hippoGridManager.h" | ||
6 | |||
7 | #include <cctype> | ||
8 | |||
9 | #include <stdtypes.h> | ||
10 | #include <lldir.h> | ||
11 | #include <lleconomy.h> | ||
12 | #include <llerror.h> | ||
13 | #include <llfile.h> | ||
14 | #include <llhttpclient.h> | ||
15 | #include <llsdserialize.h> | ||
16 | #include "llviewercontrol.h" | ||
17 | #include "llweb.h" | ||
18 | |||
19 | #include "hippoRestRequest.h" | ||
20 | |||
21 | |||
22 | // ******************************************************************** | ||
23 | // Global Variables | ||
24 | |||
25 | HippoGridManager *gHippoGridManager = 0; | ||
26 | |||
27 | HippoGridInfo HippoGridInfo::FALLBACK_GRIDINFO(""); | ||
28 | |||
29 | |||
30 | |||
31 | // ******************************************************************** | ||
32 | // ******************************************************************** | ||
33 | // HippoGridInfo | ||
34 | // ******************************************************************** | ||
35 | // ******************************************************************** | ||
36 | |||
37 | |||
38 | // ******************************************************************** | ||
39 | // Initialize | ||
40 | |||
41 | HippoGridInfo::HippoGridInfo(const std::string &gridNick) : | ||
42 | mPlatform(PLATFORM_OTHER), | ||
43 | mRenderCompat(true), | ||
44 | mCurrencySymbol("OS$"), | ||
45 | mRealCurrencySymbol("US$"), | ||
46 | mDirectoryFee(30) | ||
47 | { | ||
48 | std::string nick = gridNick; | ||
49 | mGridNick = sanitizeGridNick( nick ); | ||
50 | } | ||
51 | |||
52 | |||
53 | // ******************************************************************** | ||
54 | // Getters | ||
55 | |||
56 | HippoGridInfo::Platform HippoGridInfo::getPlatform() | ||
57 | { | ||
58 | return mPlatform; | ||
59 | } | ||
60 | |||
61 | bool HippoGridInfo::isOpenSimulator() const | ||
62 | { | ||
63 | return (mPlatform == HippoGridInfo::PLATFORM_OPENSIM); | ||
64 | } | ||
65 | |||
66 | bool HippoGridInfo::isSecondLife() const | ||
67 | { | ||
68 | return (mPlatform == HippoGridInfo::PLATFORM_SECONDLIFE); | ||
69 | } | ||
70 | |||
71 | const std::string& HippoGridInfo::getGridNick() const | ||
72 | { | ||
73 | return mGridNick; | ||
74 | } | ||
75 | |||
76 | const std::string& HippoGridInfo::getGridName() const | ||
77 | { | ||
78 | return mGridName; | ||
79 | } | ||
80 | |||
81 | const std::string& HippoGridInfo::getLoginUri() const | ||
82 | { | ||
83 | return mLoginUri; | ||
84 | } | ||
85 | |||
86 | const std::string& HippoGridInfo::getLoginPage() const | ||
87 | { | ||
88 | return mLoginPage; | ||
89 | } | ||
90 | |||
91 | const std::string& HippoGridInfo::getHelperUri() const | ||
92 | { | ||
93 | return mHelperUri; | ||
94 | } | ||
95 | |||
96 | const std::string& HippoGridInfo::getWebSite() const | ||
97 | { | ||
98 | return mWebSite; | ||
99 | } | ||
100 | |||
101 | const std::string& HippoGridInfo::getSupportUrl() const | ||
102 | { | ||
103 | return mSupportUrl; | ||
104 | } | ||
105 | |||
106 | const std::string& HippoGridInfo::getRegisterUrl() const | ||
107 | { | ||
108 | return mRegisterUrl; | ||
109 | } | ||
110 | |||
111 | const std::string& HippoGridInfo::getPasswordUrl() const | ||
112 | { | ||
113 | return mPasswordUrl; | ||
114 | } | ||
115 | |||
116 | const std::string& HippoGridInfo::getSearchUrl() const | ||
117 | { | ||
118 | return mSearchUrl; | ||
119 | } | ||
120 | |||
121 | const std::string& HippoGridInfo::getFirstName() const | ||
122 | { | ||
123 | return mFirstName; | ||
124 | } | ||
125 | |||
126 | const std::string& HippoGridInfo::getLastName() const | ||
127 | { | ||
128 | return mLastName; | ||
129 | } | ||
130 | |||
131 | const std::string& HippoGridInfo::getAvatarPassword() const | ||
132 | { | ||
133 | return mAvatarPassword; | ||
134 | } | ||
135 | |||
136 | bool HippoGridInfo::isRenderCompat() const | ||
137 | { | ||
138 | return mRenderCompat; | ||
139 | } | ||
140 | |||
141 | const std::string& HippoGridInfo::getCurrencySymbol() const | ||
142 | { | ||
143 | return mCurrencySymbol; | ||
144 | } | ||
145 | |||
146 | const std::string& HippoGridInfo::getRealCurrencySymbol() const | ||
147 | { | ||
148 | return mRealCurrencySymbol; | ||
149 | } | ||
150 | |||
151 | |||
152 | |||
153 | // ******************************************************************** | ||
154 | // Setters | ||
155 | |||
156 | void HippoGridInfo::setPlatform(Platform platform) | ||
157 | { | ||
158 | mPlatform = platform; | ||
159 | mCurrencySymbol = (mPlatform == PLATFORM_SECONDLIFE)? "L$": "OS$"; | ||
160 | } | ||
161 | |||
162 | |||
163 | void HippoGridInfo::setPlatform(const std::string &platform) | ||
164 | { | ||
165 | std::string tmp = platform; | ||
166 | for (unsigned i=0; i<platform.size(); i++) | ||
167 | tmp[i] = tolower(tmp[i]); | ||
168 | |||
169 | if (tmp == "opensim") { | ||
170 | setPlatform(PLATFORM_OPENSIM); | ||
171 | } else if (tmp == "secondlife") { | ||
172 | setPlatform(PLATFORM_SECONDLIFE); | ||
173 | } else { | ||
174 | setPlatform(PLATFORM_OTHER); | ||
175 | llwarns << "Unknown platform '" << platform << "'." << llendl; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | void HippoGridInfo::setGridName(const std::string &gridName) | ||
180 | { | ||
181 | mGridName = gridName; | ||
182 | } | ||
183 | |||
184 | void HippoGridInfo::setLoginUri(const std::string &loginUri) | ||
185 | { | ||
186 | std::string uri = loginUri; | ||
187 | mLoginUri = sanitizeUri(uri); | ||
188 | } | ||
189 | |||
190 | void HippoGridInfo::setLoginPage(const std::string &loginPage) | ||
191 | { | ||
192 | mLoginPage = loginPage; | ||
193 | } | ||
194 | |||
195 | void HippoGridInfo::setHelperUri(const std::string &helperUri) | ||
196 | { | ||
197 | std::string uri = helperUri; | ||
198 | mHelperUri = sanitizeUri(uri); | ||
199 | } | ||
200 | |||
201 | void HippoGridInfo::setWebSite(const std::string &website) | ||
202 | { | ||
203 | mWebSite = website; | ||
204 | } | ||
205 | |||
206 | void HippoGridInfo::setSupportUrl(const std::string &url) | ||
207 | { | ||
208 | mSupportUrl = url; | ||
209 | } | ||
210 | |||
211 | void HippoGridInfo::setRegisterUrl(const std::string &url) | ||
212 | { | ||
213 | mRegisterUrl = url; | ||
214 | } | ||
215 | |||
216 | void HippoGridInfo::setPasswordUrl(const std::string &url) | ||
217 | { | ||
218 | mPasswordUrl = url; | ||
219 | } | ||
220 | |||
221 | void HippoGridInfo::setSearchUrl(const std::string &url) | ||
222 | { | ||
223 | mSearchUrl = url; | ||
224 | } | ||
225 | |||
226 | void HippoGridInfo::setFirstName(const std::string &firstName) | ||
227 | { | ||
228 | mFirstName = firstName; | ||
229 | } | ||
230 | |||
231 | void HippoGridInfo::setLastName(const std::string &lastName) | ||
232 | { | ||
233 | mLastName = lastName; | ||
234 | } | ||
235 | |||
236 | void HippoGridInfo::setAvatarPassword(const std::string &avatarPassword) | ||
237 | { | ||
238 | mAvatarPassword = avatarPassword; | ||
239 | } | ||
240 | |||
241 | void HippoGridInfo::setRenderCompat(bool compat) | ||
242 | { | ||
243 | mRenderCompat = compat; | ||
244 | } | ||
245 | |||
246 | void HippoGridInfo::setCurrencySymbol(const std::string &sym) | ||
247 | { | ||
248 | mCurrencySymbol = sym.substr(0, 3); | ||
249 | } | ||
250 | |||
251 | void HippoGridInfo::setRealCurrencySymbol(const std::string &sym) | ||
252 | { | ||
253 | mRealCurrencySymbol = sym.substr(0, 3); | ||
254 | } | ||
255 | |||
256 | void HippoGridInfo::setDirectoryFee(int fee) | ||
257 | { | ||
258 | mDirectoryFee = fee; | ||
259 | } | ||
260 | |||
261 | |||
262 | |||
263 | // ******************************************************************** | ||
264 | // Grid Info | ||
265 | |||
266 | std::string HippoGridInfo::getSearchUrl(SearchType ty) const | ||
267 | { | ||
268 | if ((mPlatform == PLATFORM_SECONDLIFE) || mSearchUrl.empty()) { | ||
269 | // Second Life defaults | ||
270 | if (ty == SEARCH_ALL_EMPTY) { | ||
271 | return gSavedSettings.getString("SearchURLDefault"); | ||
272 | } else if (ty == SEARCH_ALL_QUERY) { | ||
273 | return gSavedSettings.getString("SearchURLQuery"); | ||
274 | } else if (ty == SEARCH_ALL_TEMPLATE) { | ||
275 | return gSavedSettings.getString("SearchURLSuffix2"); | ||
276 | } else { | ||
277 | llinfos << "Illegal search URL type " << ty << llendl; | ||
278 | return ""; | ||
279 | } | ||
280 | } else { | ||
281 | // OpenSim and other | ||
282 | if (ty == SEARCH_ALL_EMPTY) { | ||
283 | return (mSearchUrl + "panel=All&"); | ||
284 | } else if (ty == SEARCH_ALL_QUERY) { | ||
285 | return (mSearchUrl + "q=[QUERY]&s=[COLLECTION]&"); | ||
286 | } else if (ty == SEARCH_ALL_TEMPLATE) { | ||
287 | return "lang=[LANG]&m=[MATURE]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]"; | ||
288 | } else { | ||
289 | llinfos << "Illegal search URL type " << ty << llendl; | ||
290 | return ""; | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | |||
296 | //static | ||
297 | void HippoGridInfo::onXmlElementStart(void *userData, const XML_Char *name, const XML_Char **atts) | ||
298 | { | ||
299 | HippoGridInfo *self = (HippoGridInfo*)userData; | ||
300 | if (strcasecmp(name, "gridnick") == 0) | ||
301 | self->mXmlState = XML_GRIDNICK; | ||
302 | else if (strcasecmp(name, "gridname") == 0) | ||
303 | self->mXmlState = XML_GRIDNAME; | ||
304 | else if (strcasecmp(name, "platform") == 0) | ||
305 | self->mXmlState = XML_PLATFORM; | ||
306 | else if ((strcasecmp(name, "login") == 0) || (strcasecmp(name, "loginuri") == 0)) | ||
307 | self->mXmlState = XML_LOGINURI; | ||
308 | else if ((strcasecmp(name, "welcome") == 0) || (strcasecmp(name, "loginpage") == 0)) | ||
309 | self->mXmlState = XML_LOGINPAGE; | ||
310 | else if ((strcasecmp(name, "economy") == 0) || (strcasecmp(name, "helperuri") == 0)) | ||
311 | self->mXmlState = XML_HELPERURI; | ||
312 | else if ((strcasecmp(name, "about") == 0) || (strcasecmp(name, "website") == 0)) | ||
313 | self->mXmlState = XML_WEBSITE; | ||
314 | else if ((strcasecmp(name, "help") == 0) || (strcasecmp(name, "support") == 0)) | ||
315 | self->mXmlState = XML_SUPPORT; | ||
316 | else if ((strcasecmp(name, "register") == 0) || (strcasecmp(name, "account") == 0)) | ||
317 | self->mXmlState = XML_REGISTER; | ||
318 | else if (strcasecmp(name, "password") == 0) | ||
319 | self->mXmlState = XML_PASSWORD; | ||
320 | //else if (strcasecmp(name, "search") == 0) | ||
321 | //self->mXmlState = XML_SEARCH; | ||
322 | } | ||
323 | |||
324 | //static | ||
325 | void HippoGridInfo::onXmlElementEnd(void *userData, const XML_Char *name) | ||
326 | { | ||
327 | HippoGridInfo *self = (HippoGridInfo*)userData; | ||
328 | self->mXmlState = XML_VOID; | ||
329 | } | ||
330 | |||
331 | //static | ||
332 | void HippoGridInfo::onXmlCharacterData(void *userData, const XML_Char *s, int len) | ||
333 | { | ||
334 | HippoGridInfo *self = (HippoGridInfo*)userData; | ||
335 | switch (self->mXmlState) { | ||
336 | |||
337 | case XML_GRIDNICK: { | ||
338 | if (self->mGridNick == "") self->mGridNick.assign(s, len); | ||
339 | self->mGridNick = sanitizeGridNick(self->mGridNick); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | case XML_PLATFORM: { | ||
344 | std::string platform(s, len); | ||
345 | self->setPlatform(platform); | ||
346 | break; | ||
347 | } | ||
348 | |||
349 | case XML_LOGINURI: { | ||
350 | std::string loginuri(s, len); | ||
351 | self->mLoginUri = sanitizeUri( loginuri ); | ||
352 | break; | ||
353 | } | ||
354 | |||
355 | case XML_HELPERURI: { | ||
356 | std::string helperuri(s, len); | ||
357 | self->mHelperUri = sanitizeUri( helperuri ); | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | case XML_SEARCH: { | ||
362 | //self->mSearchUrl.assign(s, len); | ||
363 | //sanitizeQueryUrl(mSearchUrl); | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | case XML_GRIDNAME: self->mGridName.assign(s, len); break; | ||
368 | case XML_LOGINPAGE: self->mLoginPage.assign(s, len); break; | ||
369 | case XML_WEBSITE: self->mWebSite.assign(s, len); break; | ||
370 | case XML_SUPPORT: self->mSupportUrl.assign(s, len); break; | ||
371 | case XML_REGISTER: self->mRegisterUrl.assign(s, len); break; | ||
372 | case XML_PASSWORD: self->mPasswordUrl.assign(s, len); break; | ||
373 | |||
374 | case XML_VOID: break; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | |||
379 | bool HippoGridInfo::retrieveGridInfo() | ||
380 | { | ||
381 | if (mLoginUri == "") return false; | ||
382 | |||
383 | std::string reply; | ||
384 | int result = HippoRestRequest::getBlocking(mLoginUri + "get_grid_info", &reply); | ||
385 | if (result != 200) return false; | ||
386 | |||
387 | llinfos << "Received: " << reply << llendl; | ||
388 | |||
389 | bool success = true; | ||
390 | XML_Parser parser = XML_ParserCreate(0); | ||
391 | XML_SetUserData(parser, this); | ||
392 | XML_SetElementHandler(parser, onXmlElementStart, onXmlElementEnd); | ||
393 | XML_SetCharacterDataHandler(parser, onXmlCharacterData); | ||
394 | mXmlState = XML_VOID; | ||
395 | if (!XML_Parse(parser, reply.data(), reply.size(), TRUE)) { | ||
396 | llwarns << "XML Parse Error: " << XML_ErrorString(XML_GetErrorCode(parser)) << llendl; | ||
397 | success = false; | ||
398 | } | ||
399 | XML_ParserFree(parser); | ||
400 | |||
401 | return success; | ||
402 | } | ||
403 | |||
404 | |||
405 | std::string HippoGridInfo::getUploadFee() const | ||
406 | { | ||
407 | std::string fee; | ||
408 | formatFee(fee, LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(), true); | ||
409 | return fee; | ||
410 | } | ||
411 | |||
412 | std::string HippoGridInfo::getGroupCreationFee() const | ||
413 | { | ||
414 | std::string fee; | ||
415 | formatFee(fee, LLGlobalEconomy::Singleton::getInstance()->getPriceGroupCreate(), false); | ||
416 | return fee; | ||
417 | } | ||
418 | |||
419 | std::string HippoGridInfo::getDirectoryFee() const | ||
420 | { | ||
421 | std::string fee; | ||
422 | formatFee(fee, mDirectoryFee, true); | ||
423 | if (fee != "free") fee += "/week"; | ||
424 | return fee; | ||
425 | } | ||
426 | |||
427 | void HippoGridInfo::formatFee(std::string &fee, int cost, bool showFree) const | ||
428 | { | ||
429 | if (showFree && (cost == 0)) { | ||
430 | fee = "free"; | ||
431 | } else { | ||
432 | fee = llformat("%s%d", getCurrencySymbol().c_str(), cost); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | |||
437 | // ******************************************************************** | ||
438 | // Static Helpers | ||
439 | |||
440 | // static | ||
441 | const char *HippoGridInfo::getPlatformString(Platform platform) | ||
442 | { | ||
443 | static const char *platformStrings[PLATFORM_LAST] = { | ||
444 | "Other", "OpenSim", "SecondLife" | ||
445 | }; | ||
446 | |||
447 | if ((platform < PLATFORM_OTHER) || (platform >= PLATFORM_LAST)) | ||
448 | platform = PLATFORM_OTHER; | ||
449 | return platformStrings[platform]; | ||
450 | } | ||
451 | |||
452 | |||
453 | // static | ||
454 | std::string HippoGridInfo::sanitizeGridNick(std::string &gridnick) | ||
455 | { | ||
456 | std::string tmp; | ||
457 | int size = gridnick.size(); | ||
458 | for (int i=0; i<size; i++) { | ||
459 | char c = gridnick[i]; | ||
460 | if ((c == '_') || isalnum(c)) { | ||
461 | tmp += tolower(c); | ||
462 | } else if (isspace(c)) { | ||
463 | tmp += "_"; | ||
464 | } | ||
465 | } | ||
466 | return tmp; | ||
467 | } | ||
468 | |||
469 | // static | ||
470 | std::string HippoGridInfo::sanitizeUri(std::string &uri) | ||
471 | { | ||
472 | // if (uri.empty()) { | ||
473 | // return ""; | ||
474 | // } | ||
475 | |||
476 | // // If last character in uri is not "/" | ||
477 | // // NOTE: This wrongly assumes that all URIs should end with "/"! | ||
478 | // if (uri.compare(uri.length()-1, 1, "/") != 0) { | ||
479 | // return uri + '/'; | ||
480 | // } | ||
481 | |||
482 | return uri; | ||
483 | } | ||
484 | |||
485 | |||
486 | void HippoGridInfo::initFallback() | ||
487 | { | ||
488 | FALLBACK_GRIDINFO.mGridNick = "secondlife"; | ||
489 | FALLBACK_GRIDINFO.setPlatform(PLATFORM_SECONDLIFE); | ||
490 | FALLBACK_GRIDINFO.setGridName("Second Life"); | ||
491 | FALLBACK_GRIDINFO.setLoginUri("https://login.agni.lindenlab.com/cgi-bin/login.cgi"); | ||
492 | FALLBACK_GRIDINFO.setLoginPage("http://secondlife.com/app/login/"); | ||
493 | FALLBACK_GRIDINFO.setHelperUri("https://secondlife.com/helpers/"); | ||
494 | FALLBACK_GRIDINFO.setWebSite("http://secondlife.com/"); | ||
495 | } | ||
496 | |||
497 | |||
498 | |||
499 | // ******************************************************************** | ||
500 | // ******************************************************************** | ||
501 | // HippoGridManager | ||
502 | // ******************************************************************** | ||
503 | // ******************************************************************** | ||
504 | |||
505 | |||
506 | // ******************************************************************** | ||
507 | // Initialize | ||
508 | |||
509 | HippoGridManager::HippoGridManager() : | ||
510 | mConnectedGrid(0), | ||
511 | mDefaultGridsVersion(0) | ||
512 | { | ||
513 | } | ||
514 | |||
515 | HippoGridManager::~HippoGridManager() | ||
516 | { | ||
517 | cleanup(); | ||
518 | } | ||
519 | |||
520 | |||
521 | void HippoGridManager::cleanup() | ||
522 | { | ||
523 | std::map<std::string, HippoGridInfo*>::iterator it, end = mGridInfo.end(); | ||
524 | for (it=mGridInfo.begin(); it != end; ++it) { | ||
525 | delete it->second; | ||
526 | } | ||
527 | mGridInfo.clear(); | ||
528 | } | ||
529 | |||
530 | |||
531 | void HippoGridManager::init() | ||
532 | { | ||
533 | HippoGridInfo::initFallback(); | ||
534 | loadFromFile(); | ||
535 | |||
536 | // !!!### gSavedSettings.getControl("CmdLineLoginURI"); | ||
537 | // !!!### gSavedSettings.getString("CmdLineLoginPage"); | ||
538 | // !!!### gSavedSettings.getString("CmdLineHelperURI"); | ||
539 | // !!!### LLString::compareInsensitive(gGridInfo[grid_index].mLabel, grid_name.c_str())) | ||
540 | } | ||
541 | |||
542 | |||
543 | void HippoGridManager::discardAndReload() | ||
544 | { | ||
545 | cleanup(); | ||
546 | loadFromFile(); | ||
547 | } | ||
548 | |||
549 | |||
550 | // ******************************************************************** | ||
551 | // Public Access | ||
552 | |||
553 | HippoGridInfo* HippoGridManager::getGrid(const std::string &grid) const | ||
554 | { | ||
555 | std::map<std::string, HippoGridInfo*>::const_iterator it; | ||
556 | it = mGridInfo.find(grid); | ||
557 | if (it != mGridInfo.end()) { | ||
558 | return it->second; | ||
559 | } else { | ||
560 | return 0; | ||
561 | } | ||
562 | } | ||
563 | |||
564 | |||
565 | HippoGridInfo* HippoGridManager::getConnectedGrid() const | ||
566 | { | ||
567 | return (mConnectedGrid)? mConnectedGrid: getCurrentGrid(); | ||
568 | } | ||
569 | |||
570 | |||
571 | HippoGridInfo* HippoGridManager::getCurrentGrid() const | ||
572 | { | ||
573 | HippoGridInfo *grid = getGrid(mCurrentGrid); | ||
574 | if (grid) { | ||
575 | return grid; | ||
576 | } else { | ||
577 | return &HippoGridInfo::FALLBACK_GRIDINFO; | ||
578 | } | ||
579 | } | ||
580 | |||
581 | const std::string& HippoGridManager::getDefaultGridNick() const | ||
582 | { | ||
583 | return mDefaultGrid; | ||
584 | } | ||
585 | |||
586 | const std::string& HippoGridManager::getCurrentGridNick() const | ||
587 | { | ||
588 | return mCurrentGrid; | ||
589 | } | ||
590 | |||
591 | void HippoGridManager::setCurrentGridAsConnected() | ||
592 | { | ||
593 | mConnectedGrid = getCurrentGrid(); | ||
594 | } | ||
595 | |||
596 | |||
597 | void HippoGridManager::addGrid(HippoGridInfo *grid) | ||
598 | { | ||
599 | if (!grid) return; | ||
600 | const std::string &nick = grid->getGridNick(); | ||
601 | if (nick == "") { | ||
602 | llwarns << "Ignoring to try adding grid with empty nick." << llendl; | ||
603 | delete grid; | ||
604 | return; | ||
605 | } | ||
606 | if (mGridInfo.find(nick) != mGridInfo.end()) { | ||
607 | llwarns << "Ignoring to try adding existing grid " << nick << '.' << llendl; | ||
608 | delete grid; | ||
609 | return; | ||
610 | } | ||
611 | mGridInfo[nick] = grid; | ||
612 | } | ||
613 | |||
614 | |||
615 | void HippoGridManager::deleteGrid(const std::string &grid) | ||
616 | { | ||
617 | GridIterator it = mGridInfo.find(grid); | ||
618 | if (it == mGridInfo.end()) { | ||
619 | llwarns << "Trying to delete non-existing grid " << grid << '.' << llendl; | ||
620 | return; | ||
621 | } | ||
622 | mGridInfo.erase(it); | ||
623 | llinfos << "Number of grids now: " << mGridInfo.size() << llendl; | ||
624 | if (mGridInfo.empty()) llinfos << "Grid info map is empty." << llendl; | ||
625 | if (grid == mDefaultGrid) | ||
626 | setDefaultGrid(""); // sets first grid, if map not empty | ||
627 | if (grid == mCurrentGrid) | ||
628 | mCurrentGrid = mDefaultGrid; | ||
629 | } | ||
630 | |||
631 | |||
632 | void HippoGridManager::setDefaultGrid(const std::string &grid) | ||
633 | { | ||
634 | GridIterator it = mGridInfo.find(grid); | ||
635 | if (it != mGridInfo.end()) { | ||
636 | mDefaultGrid = grid; | ||
637 | } else if (mGridInfo.find("secondlife") != mGridInfo.end()) { | ||
638 | mDefaultGrid = "secondlife"; | ||
639 | } else if (!mGridInfo.empty()) { | ||
640 | mDefaultGrid = mGridInfo.begin()->first; | ||
641 | } else { | ||
642 | mDefaultGrid = ""; | ||
643 | } | ||
644 | } | ||
645 | |||
646 | |||
647 | void HippoGridManager::setCurrentGrid(const std::string &grid) | ||
648 | { | ||
649 | GridIterator it = mGridInfo.find(grid); | ||
650 | if (it != mGridInfo.end()) { | ||
651 | mCurrentGrid = grid; | ||
652 | } else if (!mGridInfo.empty()) { | ||
653 | llwarns << "Unknown grid '" << grid << "'. Setting to default grid." << llendl; | ||
654 | mCurrentGrid = mDefaultGrid; | ||
655 | } | ||
656 | } | ||
657 | |||
658 | |||
659 | // ******************************************************************** | ||
660 | // Persistent Store | ||
661 | |||
662 | void HippoGridManager::loadFromFile() | ||
663 | { | ||
664 | mDefaultGridsVersion = 0; | ||
665 | // load user grid info | ||
666 | parseFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml"), false); | ||
667 | // merge default grid info, if newer. Force load, if list of grids is empty. | ||
668 | parseFile(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml"), !mGridInfo.empty()); | ||
669 | // merge grid info from web site, if newer. Force load, if list of grids is empty. | ||
670 | if (gSavedSettings.getBOOL("CheckForGridUpdates")) | ||
671 | parseUrl("http://imprudenceviewer.org/app/grids/", !mGridInfo.empty()); | ||
672 | |||
673 | setDefaultGrid(gSavedSettings.getString("DefaultGrid")); | ||
674 | setCurrentGrid(gSavedSettings.getString("DefaultGrid")); | ||
675 | } | ||
676 | |||
677 | |||
678 | void HippoGridManager::parseUrl(const char *url, bool mergeIfNewer) | ||
679 | { | ||
680 | llinfos << "Loading grid info from '" << url << "'." << llendl; | ||
681 | |||
682 | // query update server | ||
683 | std::string escaped_url = LLWeb::escapeURL(url); | ||
684 | LLSD response = LLHTTPClient::blockingGet(url); | ||
685 | |||
686 | // check response, return on error | ||
687 | S32 status = response["status"].asInteger(); | ||
688 | if ((status != 200) || !response["body"].isArray()) { | ||
689 | llinfos << "GridInfo Update failed (" << status << "): " | ||
690 | << (response["body"].isString()? response["body"].asString(): "<unknown error>") | ||
691 | << llendl; | ||
692 | return; | ||
693 | } | ||
694 | |||
695 | LLSD gridInfo = response["body"]; | ||
696 | parseData(gridInfo, mergeIfNewer); | ||
697 | } | ||
698 | |||
699 | void HippoGridManager::parseFile(const std::string &fileName, bool mergeIfNewer) | ||
700 | { | ||
701 | llifstream infile; | ||
702 | infile.open(fileName.c_str()); | ||
703 | if(!infile.is_open()) { | ||
704 | llwarns << "Cannot find grid info file " << fileName << " to load." << llendl; | ||
705 | return; | ||
706 | } | ||
707 | |||
708 | LLSD gridInfo; | ||
709 | if (LLSDSerialize::fromXML(gridInfo, infile) <= 0) { | ||
710 | llwarns << "Unable to parse grid info file " << fileName << '.' << llendl; | ||
711 | return; | ||
712 | } | ||
713 | |||
714 | llinfos << "Loading grid info file " << fileName << '.' << llendl; | ||
715 | parseData(gridInfo, mergeIfNewer); | ||
716 | } | ||
717 | |||
718 | |||
719 | void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer) | ||
720 | { | ||
721 | if (mergeIfNewer) { | ||
722 | LLSD::array_const_iterator it, end = gridInfo.endArray(); | ||
723 | for (it = gridInfo.beginArray(); it != end; ++it) { | ||
724 | LLSD gridMap = *it; | ||
725 | if (gridMap.has("default_grids_version")) { | ||
726 | int version = gridMap["default_grids_version"]; | ||
727 | if (version <= mDefaultGridsVersion) return; | ||
728 | else break; | ||
729 | } | ||
730 | } | ||
731 | if (it == end) { | ||
732 | llwarns << "Grid data has no version number." << llendl; | ||
733 | return; | ||
734 | } | ||
735 | } | ||
736 | |||
737 | llinfos << "Loading grid data." << llendl; | ||
738 | |||
739 | LLSD::array_const_iterator it, end = gridInfo.endArray(); | ||
740 | for (it = gridInfo.beginArray(); it != end; ++it) { | ||
741 | LLSD gridMap = *it; | ||
742 | if (gridMap.has("default_grids_version")) { | ||
743 | mDefaultGridsVersion = gridMap["default_grids_version"]; | ||
744 | } else if (gridMap.has("gridnick") && gridMap.has("loginuri")) { | ||
745 | std::string gridnick = gridMap["gridnick"]; | ||
746 | HippoGridInfo *grid; | ||
747 | GridIterator it = mGridInfo.find(gridnick); | ||
748 | bool newGrid = (it == mGridInfo.end()); | ||
749 | if (newGrid) { | ||
750 | // create new grid info | ||
751 | grid = new HippoGridInfo(gridnick); | ||
752 | } else { | ||
753 | // update existing grid info | ||
754 | grid = it->second; | ||
755 | } | ||
756 | grid->setLoginUri(gridMap["loginuri"]); | ||
757 | if (gridMap.has("platform")) grid->setPlatform(gridMap["platform"]); | ||
758 | if (gridMap.has("gridname")) grid->setGridName(gridMap["gridname"]); | ||
759 | if (gridMap.has("loginpage")) grid->setLoginPage(gridMap["loginpage"]); | ||
760 | if (gridMap.has("helperuri")) grid->setHelperUri(gridMap["helperuri"]); | ||
761 | if (gridMap.has("website")) grid->setWebSite(gridMap["website"]); | ||
762 | if (gridMap.has("support")) grid->setSupportUrl(gridMap["support"]); | ||
763 | if (gridMap.has("register")) grid->setRegisterUrl(gridMap["register"]); | ||
764 | if (gridMap.has("password")) grid->setPasswordUrl(gridMap["password"]); | ||
765 | //if (gridMap.has("search")) grid->setSearchUrl(gridMap["search"]); | ||
766 | if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]); | ||
767 | // if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]); | ||
768 | // if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]); | ||
769 | // if (gridMap.has("avatarpassword")) grid->setAvatarPassword(gridMap["avatarpassword"]); | ||
770 | if (newGrid) addGrid(grid); | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
775 | |||
776 | void HippoGridManager::saveFile() | ||
777 | { | ||
778 | // save default grid to client settings | ||
779 | gSavedSettings.setString("DefaultGrid", mDefaultGrid); | ||
780 | |||
781 | // build LLSD | ||
782 | LLSD gridInfo; | ||
783 | gridInfo[0]["default_grids_version"] = mDefaultGridsVersion; | ||
784 | |||
785 | // add grids | ||
786 | S32 i = 1; | ||
787 | GridIterator it, end = mGridInfo.end(); | ||
788 | for (it = mGridInfo.begin(); it != end; ++it, i++) { | ||
789 | HippoGridInfo *grid = it->second; | ||
790 | gridInfo[i]["gridnick"] = grid->getGridNick(); | ||
791 | gridInfo[i]["platform"] = HippoGridInfo::getPlatformString(grid->getPlatform()); | ||
792 | gridInfo[i]["gridname"] = grid->getGridName(); | ||
793 | gridInfo[i]["loginuri"] = grid->getLoginUri(); | ||
794 | gridInfo[i]["loginpage"] = grid->getLoginPage(); | ||
795 | gridInfo[i]["helperuri"] = grid->getHelperUri(); | ||
796 | gridInfo[i]["website"] = grid->getWebSite(); | ||
797 | gridInfo[i]["support"] = grid->getSupportUrl(); | ||
798 | gridInfo[i]["register"] = grid->getRegisterUrl(); | ||
799 | gridInfo[i]["password"] = grid->getPasswordUrl(); | ||
800 | // gridInfo[i]["firstname"] = grid->getFirstName(); | ||
801 | // gridInfo[i]["lastname"] = grid->getLastName(); | ||
802 | // gridInfo[i]["avatarpassword"] = grid->getAvatarPassword(); | ||
803 | |||
804 | //gridInfo[i]["search"] = grid->getSearchUrl(); | ||
805 | gridInfo[i]["render_compat"] = grid->isRenderCompat(); | ||
806 | } | ||
807 | |||
808 | // write client grid info file | ||
809 | std::string fileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml"); | ||
810 | llofstream file; | ||
811 | file.open(fileName.c_str()); | ||
812 | if (file.is_open()) { | ||
813 | LLSDSerialize::toPrettyXML(gridInfo, file); | ||
814 | file.close(); | ||
815 | llinfos << "Saved grids to " << fileName << llendl; | ||
816 | } else { | ||
817 | llerrs << "Unable to open grid info file: " << fileName << llendl; | ||
818 | } | ||
819 | } | ||