aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/hippoGridManager.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-09-25 22:15:49 -0500
committerJacek Antonelli2009-09-25 22:15:49 -0500
commit5ff1687542240fe9b00d4c217b764770fc369c06 (patch)
treebc5a1dbc882c19120ca00efb9914d70059cd79cb /linden/indra/newview/hippoGridManager.cpp
parentMerge remote branch 'mccabe/1.2.0-next' into next (diff)
parentRemoved grid stuff from World Map (for now). (diff)
downloadmeta-impy-5ff1687542240fe9b00d4c217b764770fc369c06.zip
meta-impy-5ff1687542240fe9b00d4c217b764770fc369c06.tar.gz
meta-impy-5ff1687542240fe9b00d4c217b764770fc369c06.tar.bz2
meta-impy-5ff1687542240fe9b00d4c217b764770fc369c06.tar.xz
Merge branch 'gridmanager' into next
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/hippoGridManager.cpp603
1 files changed, 603 insertions, 0 deletions
diff --git a/linden/indra/newview/hippoGridManager.cpp b/linden/indra/newview/hippoGridManager.cpp
new file mode 100644
index 0000000..2143a40
--- /dev/null
+++ b/linden/indra/newview/hippoGridManager.cpp
@@ -0,0 +1,603 @@
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 if (uri.empty()) {
281 return;
282 }
283
284 // If last character in uri is not "/"
285 if (uri.compare(uri.length()-1, 1, "/") != 0) {
286 uri += '/';
287 }
288}
289
290
291void HippoGridInfo::initFallback()
292{
293 FALLBACK_GRIDINFO.mGridNick = "secondlife";
294 FALLBACK_GRIDINFO.setPlatform(PLATFORM_SECONDLIFE);
295 FALLBACK_GRIDINFO.setGridName("Second Life");
296 FALLBACK_GRIDINFO.setLoginUri("https://login.agni.lindenlab.com/cgi-bin/login.cgi");
297 FALLBACK_GRIDINFO.setLoginPage("http://secondlife.com/app/login/");
298 FALLBACK_GRIDINFO.setHelperUri("https://secondlife.com/helpers/");
299 FALLBACK_GRIDINFO.setWebSite("http://secondlife.com/");
300}
301
302
303
304// ********************************************************************
305// ********************************************************************
306// HippoGridManager
307// ********************************************************************
308// ********************************************************************
309
310
311// ********************************************************************
312// Initialize
313
314HippoGridManager::HippoGridManager() :
315 mConnectedGrid(0),
316 mDefaultGridsVersion(0)
317{
318}
319
320HippoGridManager::~HippoGridManager()
321{
322 cleanup();
323}
324
325
326void HippoGridManager::cleanup()
327{
328 std::map<std::string, HippoGridInfo*>::iterator it, end = mGridInfo.end();
329 for (it=mGridInfo.begin(); it != end; ++it) {
330 delete it->second;
331 }
332 mGridInfo.clear();
333}
334
335
336void HippoGridManager::init()
337{
338 HippoGridInfo::initFallback();
339 loadFromFile();
340
341 // !!!### gSavedSettings.getControl("CmdLineLoginURI");
342 // !!!### gSavedSettings.getString("CmdLineLoginPage");
343 // !!!### gSavedSettings.getString("CmdLineHelperURI");
344 // !!!### LLString::compareInsensitive(gGridInfo[grid_index].mLabel, grid_name.c_str()))
345}
346
347
348void HippoGridManager::discardAndReload()
349{
350 cleanup();
351 loadFromFile();
352}
353
354
355// ********************************************************************
356// Public Access
357
358HippoGridInfo *HippoGridManager::getGrid(const std::string &grid) const
359{
360 std::map<std::string, HippoGridInfo*>::const_iterator it;
361 it = mGridInfo.find(grid);
362 if (it != mGridInfo.end()) {
363 return it->second;
364 } else {
365 return 0;
366 }
367}
368
369
370HippoGridInfo *HippoGridManager::getCurrentGrid() const
371{
372 HippoGridInfo *grid = getGrid(mCurrentGrid);
373 if (grid) {
374 return grid;
375 } else {
376 return &HippoGridInfo::FALLBACK_GRIDINFO;
377 }
378}
379
380
381void HippoGridManager::addGrid(HippoGridInfo *grid)
382{
383 if (!grid) return;
384 const std::string &nick = grid->getGridNick();
385 if (nick == "") {
386 llwarns << "Ignoring to try adding grid with empty nick." << llendl;
387 delete grid;
388 return;
389 }
390 if (mGridInfo.find(nick) != mGridInfo.end()) {
391 llwarns << "Ignoring to try adding existing grid " << nick << '.' << llendl;
392 delete grid;
393 return;
394 }
395 mGridInfo[nick] = grid;
396}
397
398
399void HippoGridManager::deleteGrid(const std::string &grid)
400{
401 GridIterator it = mGridInfo.find(grid);
402 if (it == mGridInfo.end()) {
403 llwarns << "Trying to delete non-existing grid " << grid << '.' << llendl;
404 return;
405 }
406 mGridInfo.erase(it);
407 llinfos << "Number of grids now: " << mGridInfo.size() << llendl;
408 if (mGridInfo.empty()) llinfos << "Grid info map is empty." << llendl;
409 if (grid == mDefaultGrid)
410 setDefaultGrid(""); // sets first grid, if map not empty
411 if (grid == mCurrentGrid)
412 mCurrentGrid = mDefaultGrid;
413}
414
415
416void HippoGridManager::setDefaultGrid(const std::string &grid)
417{
418 GridIterator it = mGridInfo.find(grid);
419 if (it != mGridInfo.end()) {
420 mDefaultGrid = grid;
421 } else if (mGridInfo.find("secondlife") != mGridInfo.end()) {
422 mDefaultGrid = "secondlife";
423 } else if (!mGridInfo.empty()) {
424 mDefaultGrid = mGridInfo.begin()->first;
425 } else {
426 mDefaultGrid = "";
427 }
428}
429
430
431void HippoGridManager::setCurrentGrid(const std::string &grid)
432{
433 GridIterator it = mGridInfo.find(grid);
434 if (it != mGridInfo.end()) {
435 mCurrentGrid = grid;
436 } else if (!mGridInfo.empty()) {
437 llwarns << "Unknown grid '" << grid << "'. Setting to default grid." << llendl;
438 mCurrentGrid = mDefaultGrid;
439 }
440}
441
442
443// ********************************************************************
444// Persistent Store
445
446void HippoGridManager::loadFromFile()
447{
448 mDefaultGridsVersion = 0;
449 // load user grid info
450 parseFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml"), false);
451 // merge default grid info, if newer. Force load, if list of grids is empty.
452 parseFile(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml"), !mGridInfo.empty());
453 // merge grid info from web site, if newer. Force load, if list of grids is empty.
454 if (gSavedSettings.getBOOL("CheckForGridUpdates"))
455 parseUrl("http://imprudenceviewer.org/app/grids/", !mGridInfo.empty());
456
457 setDefaultGrid(gSavedSettings.getString("DefaultGrid"));
458 setCurrentGrid(gSavedSettings.getString("DefaultGrid"));
459}
460
461
462void HippoGridManager::parseUrl(const char *url, bool mergeIfNewer)
463{
464 llinfos << "Loading grid info from '" << url << "'." << llendl;
465
466 // query update server
467 std::string escaped_url = LLWeb::escapeURL(url);
468 LLSD response = LLHTTPClient::blockingGet(url);
469
470 // check response, return on error
471 S32 status = response["status"].asInteger();
472 if ((status != 200) || !response["body"].isArray()) {
473 llinfos << "GridInfo Update failed (" << status << "): "
474 << (response["body"].isString()? response["body"].asString(): "<unknown error>")
475 << llendl;
476 return;
477 }
478
479 LLSD gridInfo = response["body"];
480 parseData(gridInfo, mergeIfNewer);
481}
482
483void HippoGridManager::parseFile(const std::string &fileName, bool mergeIfNewer)
484{
485 llifstream infile;
486 infile.open(fileName.c_str());
487 if(!infile.is_open()) {
488 llwarns << "Cannot find grid info file " << fileName << " to load." << llendl;
489 return;
490 }
491
492 LLSD gridInfo;
493 if (LLSDSerialize::fromXML(gridInfo, infile) <= 0) {
494 llwarns << "Unable to parse grid info file " << fileName << '.' << llendl;
495 return;
496 }
497
498 llinfos << "Loading grid info file " << fileName << '.' << llendl;
499 parseData(gridInfo, mergeIfNewer);
500}
501
502
503void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer)
504{
505 if (mergeIfNewer) {
506 LLSD::array_const_iterator it, end = gridInfo.endArray();
507 for (it = gridInfo.beginArray(); it != end; ++it) {
508 LLSD gridMap = *it;
509 if (gridMap.has("default_grids_version")) {
510 int version = gridMap["default_grids_version"];
511 if (version <= mDefaultGridsVersion) return;
512 else break;
513 }
514 }
515 if (it == end) {
516 llwarns << "Grid data has no version number." << llendl;
517 return;
518 }
519 }
520
521 llinfos << "Loading grid data." << llendl;
522
523 LLSD::array_const_iterator it, end = gridInfo.endArray();
524 for (it = gridInfo.beginArray(); it != end; ++it) {
525 LLSD gridMap = *it;
526 if (gridMap.has("default_grids_version")) {
527 mDefaultGridsVersion = gridMap["default_grids_version"];
528 } else if (gridMap.has("gridnick") && gridMap.has("loginuri")) {
529 std::string gridnick = gridMap["gridnick"];
530 HippoGridInfo *grid;
531 GridIterator it = mGridInfo.find(gridnick);
532 bool newGrid = (it == mGridInfo.end());
533 if (newGrid) {
534 // create new grid info
535 grid = new HippoGridInfo(gridnick);
536 } else {
537 // update existing grid info
538 grid = it->second;
539 }
540 grid->setLoginUri(gridMap["loginuri"]);
541 if (gridMap.has("platform")) grid->setPlatform(gridMap["platform"]);
542 if (gridMap.has("gridname")) grid->setGridName(gridMap["gridname"]);
543 if (gridMap.has("loginpage")) grid->setLoginPage(gridMap["loginpage"]);
544 if (gridMap.has("helperuri")) grid->setHelperUri(gridMap["helperuri"]);
545 if (gridMap.has("website")) grid->setWebSite(gridMap["website"]);
546 if (gridMap.has("support")) grid->setSupportUrl(gridMap["support"]);
547 if (gridMap.has("register")) grid->setRegisterUrl(gridMap["register"]);
548 if (gridMap.has("password")) grid->setPasswordUrl(gridMap["password"]);
549 //if (gridMap.has("search")) grid->setSearchUrl(gridMap["search"]);
550 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]);
551 // if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]);
552 // if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]);
553 // if (gridMap.has("avatarpassword")) grid->setAvatarPassword(gridMap["avatarpassword"]);
554 if (newGrid) addGrid(grid);
555 }
556 }
557}
558
559
560void HippoGridManager::saveFile()
561{
562 // save default grid to client settings
563 gSavedSettings.setString("DefaultGrid", mDefaultGrid);
564
565 // build LLSD
566 LLSD gridInfo;
567 gridInfo[0]["default_grids_version"] = mDefaultGridsVersion;
568
569 // add grids
570 S32 i = 1;
571 GridIterator it, end = mGridInfo.end();
572 for (it = mGridInfo.begin(); it != end; ++it, i++) {
573 HippoGridInfo *grid = it->second;
574 gridInfo[i]["gridnick"] = grid->getGridNick();
575 gridInfo[i]["platform"] = HippoGridInfo::getPlatformString(grid->getPlatform());
576 gridInfo[i]["gridname"] = grid->getGridName();
577 gridInfo[i]["loginuri"] = grid->getLoginUri();
578 gridInfo[i]["loginpage"] = grid->getLoginPage();
579 gridInfo[i]["helperuri"] = grid->getHelperUri();
580 gridInfo[i]["website"] = grid->getWebSite();
581 gridInfo[i]["support"] = grid->getSupportUrl();
582 gridInfo[i]["register"] = grid->getRegisterUrl();
583 gridInfo[i]["password"] = grid->getPasswordUrl();
584 // gridInfo[i]["firstname"] = grid->getFirstName();
585 // gridInfo[i]["lastname"] = grid->getLastName();
586 // gridInfo[i]["avatarpassword"] = grid->getAvatarPassword();
587
588 //gridInfo[i]["search"] = grid->getSearchUrl();
589 gridInfo[i]["render_compat"] = grid->isRenderCompat();
590 }
591
592 // write client grid info file
593 std::string fileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grid_info.xml");
594 llofstream file;
595 file.open(fileName.c_str());
596 if (file.is_open()) {
597 LLSDSerialize::toPrettyXML(gridInfo, file);
598 file.close();
599 llinfos << "Saved grids to " << fileName << llendl;
600 } else {
601 llerrs << "Unable to open grid info file: " << fileName << llendl;
602 }
603}