1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "login_patch.h"
29 #include "nel/misc/common.h"
30 #include "nel/misc/debug.h"
31 #include "nel/misc/path.h"
32 #include "nel/misc/thread.h"
33 #include "nel/misc/big_file.h"
34 #include "nel/misc/system_utils.h"
35 #include "nel/misc/streamed_package_manager.h"
37 #include "nel/net/tcp_sock.h"
38 #include "nel/3d/u_driver.h"
39 #include "nel/misc/big_file.h"
41 #include "interface_v3/interface_manager.h"
42 #include "interface_v3/input_handler_manager.h"
43 #include "nel/gui/group_editbox.h"
44 #include "interface_v3/group_quick_help.h"
45 #include "nel/gui/view_text.h"
46 #include "nel/gui/ctrl_button.h"
47 #include "nel/gui/ctrl_text_button.h"
48 #include "nel/gui/dbgroup_combo_box.h"
49 #include "sound_manager.h"
52 #include "actions_client.h"
53 #include "time_client.h"
54 #include "client_cfg.h"
57 #include "nel/gui/libwww.h"
58 #include "nel/web/http_client_curl.h"
59 #include "login_progress_post_thread.h"
63 #include "bg_downloader_access.h"
65 #include "game_share/crypt.h"
66 #include "game_share/bg_downloader_msg.h"
69 #include "user_agent.h"
71 void ConnectToShard();
73 // ***************************************************************************
75 using namespace NLMISC
;
76 using namespace NLWEB
;
77 using namespace NLNET
;
85 // ***************************************************************************
87 extern bool SetMousePosFirstTime
;
89 vector
<CShard
> Shards
;
91 string LoginLogin
, LoginPassword
, ClientApp
, Salt
, LoginCustomParameters
;
92 uint32 LoginShardId
= 0xFFFFFFFF;
95 // Completed only after that ryzom downloader has run its 'check' task :
96 // It is a bitfield indexed by BGDownloader::TDownloadID that indicate the parts that are available for patch
97 uint32 AvailablePatchs
= 0;
98 // next wanted patch for the background downloader
99 BGDownloader::TDownloadID BGDownloaderWantedPatch
= BGDownloader::DownloadID_RoS
;
103 // R2 mode var ---------------
105 /// domain server version for patch
106 string R2ServerVersion
;
107 /// name of the version (used to alias many version under the same name),
108 /// the value is used to get the release not if not empty
110 /// Backup patch server to use in case of failure of all other servers
111 string R2BackupPatchURL
;
112 /// a list of patch server to use randomly
113 vector
<string
> R2PatchURLs
;
116 #define CTRL_EDITBOX_LOGIN "ui:login:checkpass:content:eb_login:eb"
117 #define CTRL_EDITBOX_PASSWORD "ui:login:checkpass:content:eb_password:eb"
118 #define GROUP_LIST_SHARD "ui:login:sharddisp:content:shard_list"
119 #define CTRL_BUTTON_CONNECT "ui:login:sharddisp:content:but_con"
120 #define GROUP_LIST_CAT "ui:login:catdisp:content:cat_list"
121 #define CTRL_BUTTON_CLOSE_PATCH "ui:login:patching:content:but_close"
122 #define VIEW_TOTAL_SIZE "ui:login:catdisp:content:global_patch:size"
123 #define VIEW_NON_OPTIONAL_SIZE "ui:login:catdisp:content:nonopt_patch:size"
124 #define VIEW_TOTAL_SIZE_PATCH "ui:login:patching:content:global_patch:size"
125 #define CTRL_BUTTON_BACKTOLOGIN "ui:login:webstart:content:back_to_login"
126 #define CTRL_BUTTON_RELOADTESTPAGE "ui:login:webstart:content:reload_test_page"
127 #define CTRL_EDITBOX_CREATEACCOUNT_LOGIN "ui:login:create_account:content:submit_gr:eb_login:eb"
128 #define CTRL_EDITBOX_CREATEACCOUNT_PASSWORD "ui:login:create_account:content:submit_gr:eb_password:eb"
129 #define CTRL_EDITBOX_CREATEACCOUNT_CONFIRMPASSWORD "ui:login:create_account:content:submit_gr:eb_confirm_password:eb"
130 #define CTRL_EDITBOX_CREATEACCOUNT_EMAIL "ui:login:create_account:content:submit_gr:eb_email:eb"
132 #define UI_VARIABLES_SCREEN_CHECKPASS 0
133 #define UI_VARIABLES_SCREEN_SHARDDISP 1
134 #define UI_VARIABLES_SCREEN_CHECKING 2
135 #define UI_VARIABLES_SCREEN_CATDISP 3
136 #define UI_VARIABLES_SCREEN_PATCHING 4
137 #define UI_VARIABLES_SCREEN_REBOOT 5
138 #define UI_VARIABLES_SCREEN_EULA 6
139 #define UI_VARIABLES_SCREEN_DATASCAN 7
140 #define UI_VARIABLES_SCREEN_CREATE_ACCOUNT 9
143 // ***************************************************************************
144 // ***************************************************************************
145 // ***************************************************************************
147 // ***************************************************************************
148 // ***************************************************************************
149 // ***************************************************************************
151 bool loginFinished
= false;
152 bool loginOK
= false;
153 sint32 ShardSelected
= -1;
154 CPatchManager::SPatchInfo InfoOnPatch
;
155 uint32 TotalPatchSize
;
157 CLoginStateMachine LoginSM
;
159 // TODO : nico : put this in an external file, this way it isn't included by the background downloader
160 #ifndef RY_BG_DOWNLOADER
162 bool CStartupHttpClient::connectToLogin()
164 bool checkConnect
= connect(ClientCfg
.ConfigFile
.getVar("StartupHost").asString(0));
166 if (ClientCfg
.ConfigFile
.exists("StartupVerify"))
167 checkConnect
= checkConnect
&& verifyServer(ClientCfg
.ConfigFile
.getVar("StartupVerify").asBool(0));
172 CStartupHttpClient HttpClient
;
173 #endif // RY_BG_DOWNLOADER
176 // ***************************************************************************
177 #define WIN_COMBO_BOX_SELECT_MENU "ui:interface:combo_box_select_menu"
178 #define WIN_COMBO_BOX_MEASURE_MENU "ui:interface:combo_box_measure_menu"
179 #define WIN_COMBO_BOX_SELECT_MENU_OUTGAME "ui:outgame:combo_box_select_menu"
180 #define WIN_COMBO_BOX_SELECT_MENU_LOGIN "ui:login:combo_box_select_menu"
181 #define WIN_COMBO_BOX_MEASURE_MENU_LOGIN "ui:login:combo_box_measure_menu"
183 bool isLoginFinished()
185 return loginFinished
;
188 void setLoginFinished( bool f
)
193 CDBGroupComboBox::measureMenu
.assign( WIN_COMBO_BOX_MEASURE_MENU
);
194 CDBGroupComboBox::selectMenu
.assign( WIN_COMBO_BOX_SELECT_MENU
);
198 CDBGroupComboBox::measureMenu
.assign( WIN_COMBO_BOX_MEASURE_MENU_LOGIN
);
199 CDBGroupComboBox::selectMenu
.assign( WIN_COMBO_BOX_SELECT_MENU_LOGIN
);
204 // ***************************************************************************
205 // Pop a fatal error message box, giving the option to 'quit' the client, plus a help button
206 static void fatalMessageBox(const std::string
&msg
)
208 CInterfaceManager
*im
= CInterfaceManager::getInstance();
209 im
->messageBoxWithHelp(msg
, "ui:login", "login_quit");
212 // ***************************************************************************
213 // Pop an error message box, giving the option to go back to main menu, plus a help button
214 static void errorMessageBox(const std::string
&msg
)
216 CInterfaceManager
*im
= CInterfaceManager::getInstance();
217 im
->messageBoxWithHelp(msg
, "ui:login", "on_back_to_login");
220 // ***************************************************************************
221 void createOptionalCatUI()
223 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
224 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT
));
227 nlwarning("element " GROUP_LIST_CAT
" not found probably bad login_main.xml");
231 // Update optional categories
233 CInterfaceGroup
*pPrevLine
= NULL
;
234 for(uint i
= 0; i
< InfoOnPatch
.OptCat
.size(); i
++)
236 vector
< pair
< string
, string
> > params
;
238 params
.push_back(pair
<string
,string
>("id", "c"+toString(i
)));
240 params
.push_back(pair
<string
,string
>("posref", "BL TL"));
242 CInterfaceGroup
*pNewLine
= CWidgetManager::getInstance()->getParser()->createGroupInstance("t_cat", GROUP_LIST_CAT
, params
);
243 if (pNewLine
!= NULL
)
245 CViewText
*pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("name"));
246 if (pVT
!= NULL
) pVT
->setText(InfoOnPatch
.OptCat
[i
].Name
);
247 pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("size"));
250 pVT
->setText(BGDownloader::getWrittenSize(InfoOnPatch
.OptCat
[i
].Size
));
254 pNewLine
->setParent(pList
);
255 pNewLine
->setParentSize(pList
);
256 pNewLine
->setParentPos(pPrevLine
);
257 pList
->addGroup(pNewLine
);
259 pPrevLine
= pNewLine
;
262 pList
->invalidateCoords();
265 // ***************************************************************************
268 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
269 if (!ClientCfg
.SkipEULA
&& CFile::fileExists(getLogDirectory() + "show_eula"))
271 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_EULA
);
273 // if we display the eula, it means we make a patch so we clean the cache directory
274 // (clear cache after each patch)
275 nlinfo("Deleting cached files");
276 vector
<string
> cached
;
277 CPath::getPathContent("cache", true, false, true, cached
);
278 for(uint i
= 0; i
< cached
.size(); i
++)
279 CFile::deleteFile(cached
[i
]);
283 CAHManager::getInstance()->runActionHandler("accept_eula", NULL
);
287 // ***************************************************************************
288 static void setDataScanLog(const std::string
&text
)
290 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
291 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:datascan:content:log_txt:log"));
298 // ***************************************************************************
299 static void setDataScanState(const std::string
&text
, const std::string
&progress
= string())
301 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
302 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:datascan:content:state"));
303 if (pVT
!= NULL
) pVT
->setText(text
);
305 pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:datascan:content:progress"));
306 if (pVT
!= NULL
) pVT
->setText(progress
);
309 void initCatDisplay()
311 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
312 CPatchManager
*pPM
= CPatchManager::getInstance();
314 // Check is good now ask the player if he wants to apply the patch
315 pPM
->getInfoToDisp(InfoOnPatch
);
317 if ((!InfoOnPatch
.NonOptCat
.empty()) ||
318 (!InfoOnPatch
.OptCat
.empty()) ||
319 (!InfoOnPatch
.ReqCat
.empty()))
321 createOptionalCatUI();
322 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CATDISP
);
326 LoginSM
.pushEvent(CLoginStateMachine::ev_run_patch
);
327 // CAHManager::getInstance()->runActionHandler("login_patch", NULL);
333 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
334 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_REBOOT
);
338 // ***************************************************************************
339 static void setPatcherStateText(const std::string
&baseUIPath
, const std::string
&str
)
341 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
342 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(baseUIPath
+ ":content:state"));
349 // ***************************************************************************
350 static void setPatcherProgressText(const std::string
&baseUIPath
, const std::string
&str
)
352 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
353 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(baseUIPath
+ ":content:progress"));
360 // ***************************************************************************
361 static void updatePatchingInfoText(const std::string
&baseUIPath
)
363 CPatchManager
*pPM
= CPatchManager::getInstance();
364 #ifdef RYZOM_BG_DOWNLOADER
365 CBGDownloaderAccess
&bgDownloader
= CBGDownloaderAccess::getInstance();
366 if (isBGDownloadEnabled())
368 bgDownloader
.update();
369 if (bgDownloader
.getDownloadThreadPriority() == BGDownloader::ThreadPriority_Paused
)
371 setPatcherStateText(baseUIPath
, CI18N::get("uiBGD_Paused"));
372 setPatcherProgressText(baseUIPath
, string());
376 setPatcherStateText(baseUIPath
, bgDownloader
.getCurrentMessage());
377 if (bgDownloader
.getTotalFilesToGet() != 0)
379 setPatcherProgressText(baseUIPath
, toString("%d/%d", (int) bgDownloader
.getCurrentFilesToGet(), (int) bgDownloader
.getTotalFilesToGet()));
383 setPatcherProgressText(baseUIPath
, string());
392 if(pPM
->getThreadState(state
, log
))
394 setPatcherStateText(baseUIPath
, state
);
395 if (pPM
->getTotalFilesToGet() != 0)
397 setPatcherProgressText(baseUIPath
, toString("%d/%d", pPM
->getCurrentFilesToGet(), pPM
->getTotalFilesToGet()));
401 setPatcherProgressText(baseUIPath
, string());
407 // ***************************************************************************
408 // Main loop of the login step
411 CDBGroupComboBox::selectMenuOut
.assign( WIN_COMBO_BOX_SELECT_MENU_OUTGAME
);
412 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
413 CPatchManager
*pPM
= CPatchManager::getInstance();
415 #ifdef RYZOM_BG_DOWNLOADER
416 CBGDownloaderAccess
&bgDownloader
= CBGDownloaderAccess::getInstance();
419 bool windowBlinkDone
= false;
420 bool fatalMessageBoxShown
= false;
422 while (LoginSM
.getCurrentState() != CLoginStateMachine::st_connect
423 && LoginSM
.getCurrentState() != CLoginStateMachine::st_end
424 && LoginSM
.getCurrentState() != CLoginStateMachine::st_ingame
)
425 // while (loginFinished == false)
427 IngameDbMngr
.flushObserverCalls();
428 NLGUI::CDBManager::getInstance()->flushObserverCalls();
430 // Update the DT T0 and T1 global variables
435 CInputHandlerManager::getInstance()->pumpEvents();
436 Driver
->clearBuffers(CRGBA::Black
);
437 Driver
->setMatrixMode2D11();
440 if (SoundMngr
!= NULL
)
443 // Interface handling & displaying
444 pIM
->updateFrameEvents();
445 pIM
->updateFrameViews(NULL
);
446 IngameDbMngr
.flushObserverCalls();
447 NLGUI::CDBManager::getInstance()->flushObserverCalls();
451 // if (::GetAsyncKeyState(VK_SPACE))
453 // pIM->displayUIViewBBoxs("");
454 // pIM->displayUICtrlBBoxs("");
455 // pIM->displayUIGroupBBoxs("");
458 // Force the client to sleep a bit.
459 if(ClientCfg
.Sleep
>= 0)
461 nlSleep(ClientCfg
.Sleep
);
464 Driver
->swapBuffers();
466 // sint32 screen = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->getValue32();
467 if (LoginSM
.getCurrentState() == CLoginStateMachine::st_check_patch
)
468 // if (screen == UI_VARIABLES_SCREEN_CHECKING) // If we are in checking mode
470 nlSleep(10); // For the checking thread
472 BGDownloader::TTaskResult taskResult
= BGDownloader::TaskResult_Unknown
;
473 bool finished
= false;
474 #ifdef RYZOM_BG_DOWNLOADER
475 string bgDownloaderError
;
476 if (isBGDownloadEnabled())
478 finished
= bgDownloader
.isTaskEnded(taskResult
, bgDownloaderError
);
483 finished
= pPM
->isCheckThreadEnded(res
);
488 setPatcherStateText("ui:login:checking", string());
489 setPatcherProgressText("ui:login:checking", string());
491 #ifdef RYZOM_BG_DOWNLOADER
492 if (isBGDownloadEnabled())
494 AvailablePatchs
= bgDownloader
.getAvailablePatchs();
498 HWND hWnd
= Driver
->getDisplay();
500 // Show the window, unless it has been minimized, in
501 // which case we don't pop it unexpectedly
502 if (!windowBlinkDone
)
504 bgDownloader
.hideDownloader();
505 ShowWindow (hWnd
, SW_RESTORE
);
506 windowBlinkDone
= true;
513 case BGDownloader::TaskResult_Success
:
514 if (AvailablePatchs
& (1 << BGDownloaderWantedPatch
)) // is there a patch for what we want now ?
516 LoginSM
.pushEvent(CLoginStateMachine::ev_patch_needed
);
520 LoginSM
.pushEvent(CLoginStateMachine::ev_no_patch
);
523 case BGDownloader::TaskResult_Error
:
525 if (!fatalMessageBoxShown
)
527 fatalMessageBox(bgDownloaderError
);
528 fatalMessageBoxShown
= true;
533 if (!fatalMessageBoxShown
)
535 fatalMessageBox(CI18N::get("uiErrChecking"));
536 fatalMessageBoxShown
= true;
547 // Check is good now ask the player if he wants to apply the patch
548 pPM
->getInfoToDisp(InfoOnPatch
);
550 AvailablePatchs
= InfoOnPatch
.getAvailablePatchsBitfield();
552 if ((!InfoOnPatch
.NonOptCat
.empty()) ||
553 (!InfoOnPatch
.OptCat
.empty()) ||
554 (!InfoOnPatch
.ReqCat
.empty()))
556 LoginSM
.pushEvent(CLoginStateMachine::ev_patch_needed
);
557 // createOptionalCatUI();
558 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CATDISP);
562 LoginSM
.pushEvent(CLoginStateMachine::ev_no_patch
);
563 // CAHManager::getInstance()->runActionHandler("login_patch", NULL);
568 string errMsg
= CI18N::get("uiErrChecking");
569 if (!pPM
->getLastErrorMessage().empty())
571 errMsg
= pPM
->getLastErrorMessage();
573 if (!fatalMessageBoxShown
)
575 fatalMessageBox(errMsg
);
576 fatalMessageBoxShown
= true;
583 // update interface content
584 updatePatchingInfoText("ui:login:checking");
587 // else if (screen == UI_VARIABLES_SCREEN_DATASCAN) // If we are in ScanData mode
588 else if (LoginSM
.getCurrentState() == CLoginStateMachine::st_scan_data
)
590 nlSleep(10); // For the checking thread
593 if (pPM
->isScanDataThreadEnded(res
))
595 // if interface consider it was running before
596 if(NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->getValue32()!=0)
599 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->setValue32(0);
603 // touch any file with checksum error, and get their number
604 uint numFiles
= pPM
->applyScanDataResult();
608 setDataScanState(CI18N::get("uiScanDataSucess"));
611 string fmt
= CI18N::get("uiScanDataErrors");
612 strFindReplace(fmt
, "%d", toString(numFiles
));
613 setDataScanState(fmt
);
618 string errMsg
= CI18N::get("uiErrDataScanning");
619 if (!pPM
->getLastErrorMessage().empty())
621 errMsg
= pPM
->getLastErrorMessage();
623 pIM
->messageBoxWithHelp(errMsg
, "ui:login");
626 // the log may have changed
628 if(pPM
->getDataScanLog(dsLog
))
629 setDataScanLog(dsLog
);
634 // update inteface content
638 if(pPM
->getThreadState(state
, log
))
641 setDataScanState(state
, toString("%d/%d", pPM
->getCurrentFilesToGet(), pPM
->getTotalFilesToGet()));
643 // set special data scan log
645 if(pPM
->getDataScanLog(dsLog
))
646 setDataScanLog(dsLog
);
649 // else if (screen == UI_VARIABLES_SCREEN_PATCHING) // If we are in patching mode
650 else if (LoginSM
.getCurrentState() == CLoginStateMachine::st_patch
)
652 nlSleep(30); // For the patching thread
654 int currentPatchingSize
;
657 #ifdef RYZOM_BG_DOWNLOADER
658 if (isBGDownloadEnabled())
660 currentPatchingSize
= bgDownloader
.getPatchingSize();
661 totalPatchSize
= bgDownloader
.getTotalSize();
662 BGDownloader::TTaskResult taskResult
;
663 bool finished
= false;
664 string bgDownloaderError
;
665 finished
= bgDownloader
.isTaskEnded(taskResult
, bgDownloaderError
);
668 //bgDownloader.hideDownloader();
669 // restore the search paths (all bnp files were removed from CPath to allows
670 // the patcher to overwrite them)
672 // create a file to prompt eula next time
673 CFile::createEmptyFile(getLogDirectory() + "show_eula");
675 if (taskResult
== BGDownloader::TaskResult_Error
)
677 setPatcherStateText("ui:login:patching", string());
678 setPatcherProgressText("ui:login:patching", string());
680 if (!fatalMessageBoxShown
)
682 fatalMessageBox(bgDownloaderError
);
683 fatalMessageBoxShown
= true;
688 bgDownloader
.getPatchCompletionFlag(true /* clear flag */);
689 LoginSM
.pushEvent(CLoginStateMachine::ev_close_patch
);
694 updatePatchingInfoText("ui:login:patching");
700 totalPatchSize
= TotalPatchSize
;
701 currentPatchingSize
= pPM
->getPatchingSize();
703 if (pPM
->isPatchThreadEnded(res
))
707 LoginSM
.pushEvent(CLoginStateMachine::ev_close_patch
);
711 string errMsg
= CI18N::get("uiErrPatchApply");
712 if (!pPM
->getLastErrorMessage().empty())
714 errMsg
= pPM
->getLastErrorMessage();
716 if (!fatalMessageBoxShown
)
718 fatalMessageBox(errMsg
);
719 fatalMessageBoxShown
= true;
725 updatePatchingInfoText("ui:login:patching");
729 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(VIEW_TOTAL_SIZE_PATCH
));
731 sTmp
= BGDownloader::getWrittenSize(currentPatchingSize
);
732 sTmp
+= " / " + BGDownloader::getWrittenSize(totalPatchSize
);
733 if (pVT
!= NULL
) pVT
->setText(sTmp
);
735 // else if (screen == UI_VARIABLES_SCREEN_CATDISP) // If we are displaying patch info
736 else if (LoginSM
.getCurrentState() == CLoginStateMachine::st_display_cat
)
738 // Non optional stuff (non opt cat and req cat)
740 // Add req cat size : given the optional cat we determines the required cat
741 uint32 nNonOptSize
= 0;
743 vector
<sint32
> ReqCat
;
744 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT
));
747 for(uint i
= 0; i
< InfoOnPatch
.OptCat
.size(); i
++)
749 CInterfaceGroup
*pLine
= pList
->getGroup("c"+toString(i
));
752 CCtrlButton
*pCB
= dynamic_cast<CCtrlButton
*>(pLine
->getCtrl("on_off"));
753 if ((pCB
!= NULL
) && (pCB
->getPushed()))
755 TotalPatchSize
+= InfoOnPatch
.OptCat
[i
].Size
;
756 if (InfoOnPatch
.OptCat
[i
].Req
!= -1)
759 for (j
= 0; j
< ReqCat
.size(); ++j
)
760 if (ReqCat
[j
] == InfoOnPatch
.OptCat
[i
].Req
)
762 // Add just once the req cat size to the non optional size
763 if (j
== ReqCat
.size())
765 ReqCat
.push_back(InfoOnPatch
.OptCat
[i
].Req
);
766 nNonOptSize
+= InfoOnPatch
.ReqCat
[InfoOnPatch
.OptCat
[i
].Req
].Size
;
774 // Add non optional cats
775 for (uint32 i
= 0; i
< InfoOnPatch
.NonOptCat
.size(); ++i
)
776 nNonOptSize
+= InfoOnPatch
.NonOptCat
[i
].Size
;
778 TotalPatchSize
+= nNonOptSize
;
779 // Total size of the patches is optional cats + required cat (f(optCat)) + non opt cat
781 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(VIEW_TOTAL_SIZE
));
782 if (pVT
!= NULL
) pVT
->setText(BGDownloader::getWrittenSize(TotalPatchSize
));
784 pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(VIEW_NON_OPTIONAL_SIZE
));
785 if (pVT
!= NULL
) pVT
->setText(BGDownloader::getWrittenSize(nNonOptSize
));
790 void initLoginScreen()
792 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
793 CPatchManager
*pPM
= CPatchManager::getInstance();
794 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS
);
795 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DISPLAY_ACCOUNT_BUTTONS")->setValue32(ClientCfg
.DisplayAccountButtons
);
798 Actions
.enable(true);
799 EditActions
.enable(true);
801 if(ClientCfg
.ConfigFile
.exists("VerboseLog"))
802 pPM
->setVerboseLog(ClientCfg
.ConfigFile
.getVar("VerboseLog").asInt() == 1);
803 if(pPM
->isVerboseLog()) nlinfo("Using verbose log mode");
805 ClientApp
= ClientCfg
.ConfigFile
.getVar("Application").asString(0);
809 if (ClientApp
.find("ryzom_") != string::npos
)
810 ext
= " (" + ClientApp
.substr(6) + ")";
812 CViewText
*pV
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:ver_value"));
814 pV
->setHardText(getDisplayVersion() + (ext
.empty() ? "" : ext
));
816 // give priority to login specified as argument
817 string l
= !LoginLogin
.empty() ? LoginLogin
:ClientCfg
.LastLogin
;
821 CGroupEditBox
*pGEB
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
822 if (pGEB
!= NULL
&& (pGEB
->getInputString().empty()))
824 pGEB
->setInputString(l
);
826 CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL
, "target=" CTRL_EDITBOX_PASSWORD
"|select_all=false");
830 CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL
, "target=" CTRL_EDITBOX_LOGIN
"|select_all=false");
834 CCtrlTextButton
*pCB
= dynamic_cast<CCtrlTextButton
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CONNECT
));
835 if (pCB
!= NULL
) pCB
->setActive(false);
837 setLoginFinished( false );
843 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
844 CGroupEditBox
*pGEBLog
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
845 CGroupEditBox
*pGEBPwd
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD
));
846 pGEBLog
->setInputString(LoginLogin
);
847 pGEBPwd
->setInputString(LoginPassword
);
848 CAHManager::getInstance()->runActionHandler("on_login", NULL
, "");
850 /* if (ClientCfg.R2Mode)
852 LoginSM.pushEvent(CLoginStateMachine::ev_login_ok);
858 for (uint32 i = 0; i < Shards.size(); ++i)
860 if (Shards[i].ShardId == LoginShardId)
867 if (ShardSelected == -1)
869 pIM->messageBoxWithHelp(CI18N::get("uiErrServerLost"), "ui:login");
870 LoginSM.pushEvent(CLoginStateMachine::ev_quit);
875 LoginSM.pushEvent(CLoginStateMachine::ev_login_ok);
876 // CAHManager::getInstance()->runActionHandler("login_connect_2", NULL);
884 // Check the alt param
885 if (!LoginCustomParameters
.empty() && LoginCustomParameters
!= "&dbg=1")
887 // don't use login and password for alternate login
888 string res
= checkLogin("", "", ClientApp
, LoginCustomParameters
);
891 if (ClientCfg
.R2Mode
)
893 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
899 for (uint32 i
= 0; i
< Shards
.size(); ++i
)
901 if (Shards
[i
].ShardId
== LoginShardId
)
908 if (ShardSelected
== -1)
910 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
911 pIM
->messageBoxWithHelp(CI18N::get("uiErrServerLost"), "ui:login");
912 LoginSM
.pushEvent(CLoginStateMachine::ev_quit
);
916 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
924 // close the socket in case of error
925 HttpClient
.disconnect();
928 LoginSM
.pushEvent(CLoginStateMachine::ev_login_not_alt
);
932 // ***************************************************************************
933 // Called from client.cpp
936 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_LoginScreen
, "login_step_login_screen"));
938 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
939 CPatchManager
*pPM
= CPatchManager::getInstance();
941 if (LoginLogin
.empty())
945 IngameDbMngr
.flushObserverCalls();
946 NLGUI::CDBManager::getInstance()->flushObserverCalls();
948 SetMousePosFirstTime
= true;
949 InitMouseWithCursor(false);
950 Driver
->showCursor (false);
952 SetMouseCursor (false);
953 SetMouseSpeed (ClientCfg
.CursorSpeed
);
954 SetMouseAcceleration (ClientCfg
.CursorAcceleration
);
955 SetMousePosFirstTime
= true;
956 InitMouseWithCursor (ClientCfg
.HardwareCursor
&& !StereoDisplayAttached
);
958 // if (ClientCfg.TestBrowser)
960 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_WEBSTART);
962 // // hide 'back to login' button
963 // CInterfaceElement *backToLogin = CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_BACKTOLOGIN);
965 // backToLogin->setActive(false);
967 // // show 'reload test page' button
968 // CInterfaceElement *reloadTest = CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_RELOADTESTPAGE);
970 // reloadTest->setActive(true);
972 // // start the browser
973 // CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId(GROUP_BROWSER));
975 // pGH->browse(ClientCfg.TestBrowserUrl.c_str());
980 //// NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
981 //// NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DISPLAY_ACCOUNT_BUTTONS")->setValue32(ClientCfg.DisplayAccountButtons);
985 Actions
.enable(true);
986 EditActions
.enable(true);
988 if(ClientCfg
.ConfigFile
.exists("VerboseLog"))
989 pPM
->setVerboseLog(ClientCfg
.ConfigFile
.getVar("VerboseLog").asInt() == 1);
990 if(pPM
->isVerboseLog()) nlinfo("Using verbose log mode");
992 ClientApp
= ClientCfg
.ConfigFile
.getVar("Application").asString(0);
994 // string l = getRegKeyValue("Login").c_str();
998 // CGroupEditBox *pGEB = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN));
1000 // pGEB->setInputString(l);
1001 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_PASSWORD "|select_all=false");
1005 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_LOGIN "|select_all=false");
1009 // CCtrlTextButton *pCB = dynamic_cast<CCtrlTextButton*>(CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CONNECT));
1010 // if (pCB != NULL) pCB->setActive(false);
1012 // setLoginFinished( false );
1013 // loginFinished = false;
1016 // Comes from a current patch
1017 // if (!LoginLogin.empty())
1019 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
1020 // CGroupEditBox *pGEBLog = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN));
1021 // CGroupEditBox *pGEBPwd = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD));
1022 // pGEBLog->setInputString(LoginLogin);
1023 // pGEBPwd->setInputString(LoginPassword);
1024 // CAHManager::getInstance()->runActionHandler("on_login", NULL, "");
1025 // // Select good shard
1026 // ShardSelected = -1;
1027 // for (uint32 i = 0; i < Shards.size(); ++i)
1029 // if (Shards[i].ShardId == LoginShardId)
1031 // ShardSelected = i;
1036 // if (ShardSelected == -1)
1037 // pIM->messageBox(CI18N::get("uiErrServerLost"), "ui:login");
1039 // CAHManager::getInstance()->runActionHandler("login_connect_2", NULL);
1042 // start the login state machine
1043 LoginSM
.pushEvent(CLoginStateMachine::ev_init_done
);
1045 // run the main loop
1052 Actions
.enable(false);
1053 EditActions
.enable(false);
1058 // ***************************************************************************
1059 // INTERFACE HELPERS
1060 // ***************************************************************************
1062 // ***************************************************************************
1063 void removeSpace(string
&s
)
1072 if (i
>= s
.size()) break;
1076 // ***************************************************************************
1077 static void getPatchParameters(std::string
&url
, std::string
&ver
, std::vector
<std::string
> &patchURIs
)
1079 if (ClientCfg
.R2Mode
)
1081 url
= ClientCfg
.PatchUrl
;
1082 ver
= ClientCfg
.PatchVersion
;
1084 // if PatchUrl is forced, don't use URLs returned by server
1087 patchURIs
= R2PatchURLs
;
1088 url
= R2BackupPatchURL
;
1089 ver
= R2ServerVersion
;
1094 nlassert(ShardSelected
!= -1);
1095 patchURIs
= Shards
[ShardSelected
].PatchURIs
;
1096 url
= Shards
[ShardSelected
].EmergencyPatchURL
;
1097 ver
= Shards
[ShardSelected
].Version
;
1099 if (!ClientCfg
.PatchUrl
.empty())
1100 url
= ClientCfg
.PatchUrl
;
1102 if (!ClientCfg
.PatchVersion
.empty())
1103 ver
= ClientCfg
.PatchVersion
;
1107 // ***************************************************************************
1108 std::string
getBGDownloaderCommandLine()
1111 CConfigFile::CVar
*bgdCommandLine
= ClientCfg
.ConfigFile
.getVarPtr("BackgroundDownloaderCommandLine");
1112 if (bgdCommandLine
!= NULL
&& !bgdCommandLine
->asString().empty())
1114 return bgdCommandLine
->asString();
1119 std::vector
<std::string
> patchURIs
;
1120 getPatchParameters(url
, ver
, patchURIs
);
1121 std::string commandLine
= /*R2ServerVersion + " " + VersionName + " " + */ url
+ " " + ver
;
1122 for (uint i
= 0; i
< patchURIs
.size(); ++i
)
1124 commandLine
+= " " + patchURIs
[i
];
1129 // ***************************************************************************
1130 void initPatchCheck()
1132 // start the patching system
1133 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1134 CPatchManager
*pPM
= CPatchManager::getInstance();
1138 std::vector
<std::string
> patchURIs
;
1140 if (!ClientCfg
.R2Mode
)
1142 // nb Nico : refactored this code.
1143 // In previous code, the following was not set in R2Mode, possible bug ?...let as before anyway ...
1144 // store the selected shard for restarting after patch
1145 LoginShardId
= Shards
[ShardSelected
].ShardId
;
1148 #ifdef RYZOM_BG_DOWNLOADER
1149 if (!isBGDownloadEnabled())
1152 getPatchParameters(url
, ver
, patchURIs
);
1153 pPM
->init(patchURIs
, url
, ver
);
1154 pPM
->startCheckThread(true /* include background patchs */);
1156 #ifdef RYZOM_BG_DOWNLOADER
1159 BGDownloader::CTaskDesc
taskDesc(BGDownloader::DLState_CheckPatch
);
1160 CBGDownloaderAccess::getInstance().requestDownloadThreadPriority(BGDownloader::ThreadPriority_Normal
, false);
1161 CBGDownloaderAccess::getInstance().startTask(taskDesc
, getBGDownloaderCommandLine(), true /* showDownloader */);
1164 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKING
);
1166 setPatcherStateText("ui:login:checking", string());
1167 setPatcherProgressText("ui:login:checking", string());
1170 void initShardDisplay()
1172 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1173 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_SHARDDISP
);
1175 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD
));
1178 nlwarning("element " GROUP_LIST_SHARD
" not found probably bad login_main.xml");
1181 /* // To test more servers
1182 for (uint fff = 0; fff < 20; ++fff)
1184 CShard s ( toString("%05d",fff), fff%3, fff+32, toString("%s%d","pipo",fff),
1185 32*fff%46546, "32.32.32.32", "http://www.ryzom.com" );
1186 Shards.push_back(s);
1189 CInterfaceGroup
*pPrevLine
= NULL
;
1190 for(uint i
= 0; i
< Shards
.size(); i
++)
1192 vector
< pair
< string
, string
> > params
;
1194 params
.push_back(pair
<string
,string
>("id", "s"+toString(i
)));
1196 params
.push_back(pair
<string
,string
>("posref", "BL TL"));
1198 CInterfaceGroup
*pNewLine
= CWidgetManager::getInstance()->getParser()->createGroupInstance("t_shard", GROUP_LIST_SHARD
, params
);
1199 if (pNewLine
!= NULL
)
1201 CViewText
*pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("name"));
1202 if (pVT
!= NULL
) pVT
->setText(Shards
[i
].Name
);
1204 pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("version"));
1205 if (pVT
!= NULL
) pVT
->setText(Shards
[i
].Version
);
1207 CViewBase
*pVBon
= pNewLine
->getView("online");
1208 CViewBase
*pVBoff
= pNewLine
->getView("offline");
1209 if ((pVBon
!= NULL
) && (pVBoff
!= NULL
))
1211 pVBon
->setActive (Shards
[i
].Online
);
1212 pVBoff
->setActive (!Shards
[i
].Online
);
1215 pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("nbplayer"));
1216 if (pVT
!= NULL
) pVT
->setText(toString(Shards
[i
].NbPlayers
));
1220 pNewLine
->setParent(pList
);
1221 pNewLine
->setParentSize(pList
);
1222 pNewLine
->setParentPos(pPrevLine
);
1223 pList
->addGroup(pNewLine
);
1225 pPrevLine
= pNewLine
;
1229 if (!Shards
.empty())
1231 CCtrlButton
*pCB
= dynamic_cast<CCtrlButton
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD
":s0:but"));
1234 pCB
->setPushed(true);
1235 CAHManager::getInstance()->runActionHandler(pCB
->getActionOnLeftClick(), pCB
, pCB
->getParamsOnLeftClick());
1238 pList
->invalidateCoords();
1241 // ***************************************************************************
1243 void onlogin(bool vanishScreen
= true)
1245 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1247 // Remove space before and after each string login & password
1248 removeSpace(LoginLogin
);
1249 removeSpace(LoginPassword
);
1251 if(!LoginLogin
.empty())
1253 ClientCfg
.LastLogin
= LoginLogin
;
1254 ClientCfg
.writeString("LastLogin", ClientCfg
.LastLogin
, true);
1258 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(-1);
1260 // Check the login/pass
1262 // main menu page for r2mode
1263 string res
= checkLogin(LoginLogin
, LoginPassword
, ClientApp
, LoginCustomParameters
);
1266 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
1270 // close the socket in case of error
1271 HttpClient
.disconnect();
1273 pIM
->messageBoxWithHelp("Error : " + res
, "ui:login");
1275 LoginSM
.pushEvent(CLoginStateMachine::ev_bad_login
);
1279 class CAHOnLogin
: public IActionHandler
1281 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1283 //nlinfo("CAHOnLogin called");
1285 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1287 CGroupEditBox
*pGEBLog
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
1288 CGroupEditBox
*pGEBPwd
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD
));
1289 if ((pGEBLog
== NULL
) || (pGEBPwd
== NULL
))
1291 nlwarning("element " CTRL_EDITBOX_LOGIN
" or " CTRL_EDITBOX_PASSWORD
" not found probably bad login_main.xml");
1295 LoginLogin
= pGEBLog
->getInputString();
1296 LoginPassword
= pGEBPwd
->getInputString();
1301 REGISTER_ACTION_HANDLER (CAHOnLogin
, "on_login");
1304 // ***************************************************************************
1305 class CAHOnGameConfiguration
: public IActionHandler
1307 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1309 nlinfo("CAHOnGameConfiguration called");
1311 static string Configurator
= "ryzom_configuration_rd.exe";
1313 if (CFile::fileExists (Configurator
))
1315 // launch the ryzom configurator
1316 launchProgram(Configurator
, "");
1317 setLoginFinished( true );
1320 LoginSM
.pushEvent(CLoginStateMachine::ev_quit
);
1324 nlwarning("<CAHOnGameConfiguration::execute> can't find ryzom configurator : %s",Configurator
.c_str());
1328 REGISTER_ACTION_HANDLER (CAHOnGameConfiguration
, "on_game_configuration");
1331 // ***************************************************************************
1332 class CAHLoginQuit
: public IActionHandler
1334 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1336 nlinfo("CAHLoginQuit called");
1338 setLoginFinished( true );
1341 LoginSM
.pushEvent(CLoginStateMachine::ev_quit
);
1344 REGISTER_ACTION_HANDLER (CAHLoginQuit
, "login_quit");
1347 // ***************************************************************************
1348 class CAHLoginTab
: public IActionHandler
1350 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1352 nlinfo("CAHLoginTab called");
1354 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1356 if (NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->getValue32() == UI_VARIABLES_SCREEN_CHECKPASS
)
1358 CCtrlBase
*pCB
= CWidgetManager::getInstance()->getCaptureKeyboard();
1362 string sID
= pCB
->getId();
1363 if (sID
== CTRL_EDITBOX_LOGIN
)
1364 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD
));
1366 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
1367 CWidgetManager::getInstance()->setCaptureKeyboard(pNewCB
);
1370 else if (NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->getValue32() == UI_VARIABLES_SCREEN_CREATE_ACCOUNT
)
1372 CCtrlBase
*pCB
= CWidgetManager::getInstance()->getCaptureKeyboard();
1376 string sID
= pCB
->getId();
1377 if (sID
== CTRL_EDITBOX_CREATEACCOUNT_LOGIN
)
1378 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_PASSWORD
));
1379 else if (sID
== CTRL_EDITBOX_CREATEACCOUNT_PASSWORD
)
1380 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_CONFIRMPASSWORD
));
1381 else if (sID
== CTRL_EDITBOX_CREATEACCOUNT_CONFIRMPASSWORD
)
1382 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_EMAIL
));
1384 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_LOGIN
));
1385 CWidgetManager::getInstance()->setCaptureKeyboard(pNewCB
);
1390 REGISTER_ACTION_HANDLER (CAHLoginTab
, "login_tab");
1393 // ***************************************************************************
1394 class CAHShardSelect
: public IActionHandler
1396 virtual void execute (CCtrlBase
*pCaller
, const string
&/* Params */)
1398 nlinfo("CAHShardSelect called");
1400 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1402 CCtrlButton
*pCB
= NULL
;
1404 if (ShardSelected
!= -1)
1406 pCB
= dynamic_cast<CCtrlButton
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD
":s"+toString(ShardSelected
)+":but"));
1408 pCB
->setPushed(false);
1411 pCB
= dynamic_cast<CCtrlButton
*>(pCaller
);
1414 string name
= pCB
->getId();
1415 name
= name
.substr(0,name
.rfind(':'));
1416 name
= name
.substr(name
.rfind(':')+2,name
.size());
1417 fromString(name
, ShardSelected
);
1419 pCB
->setPushed(true);
1422 CCtrlTextButton
*pCTB
= dynamic_cast<CCtrlTextButton
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CONNECT
));
1424 pCTB
->setActive(true);
1427 REGISTER_ACTION_HANDLER (CAHShardSelect
, "shard_select");
1429 // ***************************************************************************
1430 void ConnectToShard()
1432 //nlinfo("ConnectToShard called");
1434 if (ClientCfg
.R2Mode
)
1437 setLoginFinished( true );
1440 LoginSM
.pushEvent(CLoginStateMachine::ev_enter_game
);
1445 nlassert(ShardSelected
!= -1);
1447 string res
= selectShard(Shards
[ShardSelected
].ShardId
, Cookie
, FSAddr
);
1451 setLoginFinished( true );
1454 LoginSM
.pushEvent(CLoginStateMachine::ev_enter_game
);
1458 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1459 pIM
->messageBoxWithHelp("Error :" + res
, "ui:login");
1461 LoginSM
.pushEvent(CLoginStateMachine::ev_conn_failed
);
1468 // ***************************************************************************
1469 class CAHLoginConnect
: public IActionHandler
1471 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1473 nlinfo("CAHLoginConnect called");
1475 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1477 if (ShardSelected
== -1)
1480 if (!Shards
[ShardSelected
].Online
)
1482 pIM
->messageBoxWithHelp(CI18N::get("uiErrOffLineShard"), "ui:login");
1486 LoginSM
.pushEvent(CLoginStateMachine::ev_shard_selected
);
1488 // std::vector<std::string> patchURIs = Shards[ShardSelected].PatchURIs;
1489 // string url = Shards[ShardSelected].EmergencyPatchURL;
1490 // string ver = Shards[ShardSelected].Version;
1492 // if (!ClientCfg.PatchUrl.empty())
1493 // url = ClientCfg.PatchUrl;
1495 // if (!ClientCfg.PatchVersion.empty())
1496 // ver = ClientCfg.PatchVersion;
1498 // pPM->init(patchURIs, url, ver);
1500 // LoginShardId = Shards[ShardSelected].ShardId;
1502 // if (ClientCfg.PatchWanted)
1504 // pPM->startCheckThread();
1505 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKING);
1509 // CAHManager::getInstance()->runActionHandler("login_patch",NULL);
1513 REGISTER_ACTION_HANDLER (CAHLoginConnect
, "login_connect");
1515 // ***************************************************************************
1516 // Can be called after a patching process (ryzom relaunch and call this AH to
1517 // see if we have to continue patching or directly go ingame)
1518 class CAHLoginConnect2
: public IActionHandler
1520 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1522 nlinfo("CAHLoginConnect2 called");
1523 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1525 if (Shards
[ShardSelected
].PatchURIs
.empty() && Shards
[ShardSelected
].EmergencyPatchURL
.empty())
1527 pIM
->messageBoxWithHelp(CI18N::get("uiErrCantPatch"), "ui:login");
1531 LoginSM
.pushEvent(CLoginStateMachine::ev_shard_selected
);
1533 // std::vector<std::string> patchURIs = Shards[ShardSelected].PatchURIs;
1534 // string url = Shards[ShardSelected].EmergencyPatchURL;
1535 // string ver = Shards[ShardSelected].Version;
1537 // if (!ClientCfg.PatchUrl.empty())
1538 // url = ClientCfg.PatchUrl;
1540 // if (!ClientCfg.PatchVersion.empty())
1541 // ver = ClientCfg.PatchVersion;
1543 // pPM->init(patchURIs, url, ver);
1545 // if ((ClientCfg.PatchWanted) &&
1546 // (!Shards[ShardSelected].Version.empty()) &&
1547 // (Shards[ShardSelected].Version != pPM->getClientVersion()))
1549 // pPM->startCheckThread();
1550 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKING);
1554 // // Version is good, eula then connect and launch the client
1559 REGISTER_ACTION_HANDLER (CAHLoginConnect2
, "login_connect_2");
1563 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1564 CPatchManager
*pPM
= CPatchManager::getInstance();
1566 #ifdef RYZOM_BG_DOWNLOADER
1567 if (!isBGDownloadEnabled())
1570 // Get the list of optional categories to patch
1571 vector
<string
> vCategories
;
1573 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT
));
1576 nlwarning("element " GROUP_LIST_CAT
" not found probably bad login_main.xml");
1580 for(uint i
= 0; i
< InfoOnPatch
.OptCat
.size(); i
++)
1582 // Ok for the moment all optional categories must be patched even if the player
1583 // does not want it. Because we cant detect that a continent have to be patched ingame.
1584 vCategories
.push_back(InfoOnPatch
.OptCat
[i
].Name
);
1587 // Code to check if the player wants an optional category or not
1588 CInterfaceGroup *pLine = pList->getGroup("c"+toString(i));
1591 CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(pLine->getCtrl("on_off"));
1594 if (pCB->getPushed())
1595 vCategories.push_back(rAllCats[i]);
1601 pPM
->startPatchThread(vCategories
, true);
1603 #ifdef RYZOM_BG_DOWNLOADER
1606 // NB : here we only do a part of the download each time
1607 BGDownloader::CTaskDesc
taskDesc(BGDownloader::DLState_GetAndApplyPatch
, (1 << BGDownloaderWantedPatch
));
1608 CBGDownloaderAccess::getInstance().startTask(taskDesc
, string(), true /* showDownloader */); // no command line since bg downloader should already be started
1609 // release lock on bnp, so that they can be written
1610 NLMISC::CBigFile::getInstance().removeAll();
1611 NLMISC::CStreamedPackageManager::getInstance().unloadAll();
1614 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_PATCHING
);
1616 CInterfaceElement
*closeBtn
= CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CLOSE_PATCH
);
1618 closeBtn
->setActive(false);
1620 setPatcherStateText("ui:login:patching", string());
1621 setPatcherProgressText("ui:login:patching", string());
1624 // ***************************************************************************
1625 // Called after the check has been done. The page is full of optional categories that must be selected for patching
1626 class CAHLoginPatch
: public IActionHandler
1628 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1630 nlinfo("CAHLoginPatch called");
1632 LoginSM
.pushEvent(CLoginStateMachine::ev_run_patch
);
1634 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
1635 // CPatchManager *pPM = CPatchManager::getInstance();
1637 // // Get the list of optional categories to patch
1638 // vector<string> vCategories;
1640 // CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT));
1641 // if (pList == NULL)
1643 // nlwarning("element "GROUP_LIST_CAT" not found probably bad login_main.xml");
1647 // for(uint i = 0; i < InfoOnPatch.OptCat.size(); i++)
1649 // // Ok for the moment all optional categories must be patched even if the player
1650 // // does not want it. Because we cant detect that a continent have to be patched ingame.
1651 // vCategories.push_back(InfoOnPatch.OptCat[i].Name);
1654 // // Code to check if the player wants an optional category or not
1655 // CInterfaceGroup *pLine = pList->getGroup("c"+toString(i));
1656 // if (pLine != NULL)
1658 // CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(pLine->getCtrl("on_off"));
1661 // if (pCB->getPushed())
1662 // vCategories.push_back(rAllCats[i]);
1668 // // Start patching
1669 // if (ClientCfg.PatchWanted)
1671 // pPM->startPatchThread(vCategories);
1672 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_PATCHING);
1676 // ConnectToShard();
1680 REGISTER_ACTION_HANDLER (CAHLoginPatch
, "login_patch");
1682 // ***************************************************************************
1683 // Called after the check has been done. The page is full of optional categories that must be selected for patching
1684 class CAHClosePatch
: public IActionHandler
1686 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1688 nlinfo("CAHClosePatch called");
1690 LoginSM
.pushEvent(CLoginStateMachine::ev_close_patch
);
1693 REGISTER_ACTION_HANDLER (CAHClosePatch
, "close_patch");
1696 // ***************************************************************************
1697 // Called after pushing the read note at the opening of the modal window
1698 class CAHSetReleaseNote
: public IActionHandler
1700 virtual void execute (CCtrlBase
* /* pCaller */, const string
&sParams
)
1702 nlinfo("CAHSetReleaseNote called");
1704 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1706 string sShard
= getParam(sParams
, "shard");
1707 string sGroupHtml
= getParam(sParams
, "group");
1709 CGroupHTML
*pQH
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId(sGroupHtml
));
1714 if (ClientCfg
.R2Mode
)
1716 // ring release note
1717 sURL
= ClientCfg
.RingReleaseNotePath
+
1718 "?version=" + (VersionName
.empty() ? R2ServerVersion
: VersionName
)+
1719 "&lang=" + ClientCfg
.LanguageCode
+
1720 "&ca=" + ClientCfg
.ConfigFile
.getVar("Application").asString(0);
1721 "&startPage="+RingMainURL
;
1725 // legacy ryzom release note
1727 if (sShard
== "selected")
1728 nShardId
= ShardSelected
;
1730 fromString(sShard
.substr(1), nShardId
);
1732 sURL
= ClientCfg
.ReleaseNotePath
+
1733 "?version=" + Shards
[nShardId
].Version
+
1734 "&lang=" + ClientCfg
.LanguageCode
+
1735 "&id=" + toString(Shards
[nShardId
].ShardId
) +
1736 "&ca=" + ClientCfg
.ConfigFile
.getVar("Application").asString(0);
1740 pQH
->browse(sURL
.c_str());
1743 REGISTER_ACTION_HANDLER (CAHSetReleaseNote
, "set_release_note");
1745 // ***************************************************************************
1746 // Called after pushing the read note at the opening of the modal window
1747 class CAHReboot
: public IActionHandler
1749 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
1751 nlinfo("CAHReboot called");
1753 // create a file to prompt eula next time
1754 CFile::createEmptyFile(getLogDirectory() + "show_eula");
1756 CInterfaceManager
*im
= CInterfaceManager::getInstance();
1759 #ifdef RYZOM_BG_DOWNLOADER
1760 if (isBGDownloadEnabled())
1762 CBGDownloaderAccess::getInstance().reboot();
1767 CPatchManager::getInstance()->reboot();
1769 LoginSM
.pushEvent(CLoginStateMachine::ev_reboot
);
1771 catch (const NLMISC::EDiskFullError
&)
1773 im
->messageBoxWithHelp(CI18N::get("uiPatchDiskFull"), "ui:login");
1775 catch (const NLMISC::EWriteError
&)
1777 im
->messageBoxWithHelp(CI18N::get("uiPatchWriteError"), "ui:login");
1779 catch (const std::exception
&e
)
1781 im
->messageBoxWithHelp(e
.what(), "ui:login", "login_quit");
1785 REGISTER_ACTION_HANDLER (CAHReboot
, "reboot");
1789 // ***************************************************************************
1790 class CAHAcceptEula
: public IActionHandler
1792 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
1794 //nlinfo("CAHAcceptEula called");
1795 if(CFile::fileExists(getLogDirectory() + "show_eula"))
1796 CFile::deleteFile(getLogDirectory() + "show_eula");
1797 LoginSM
.pushEvent(CLoginStateMachine::ev_accept_eula
);
1799 // if (ClientCfg.R2Mode)
1801 // // open web browser
1802 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
1803 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_WEBSTART);
1805 // // start the browser
1806 // CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId(GROUP_BROWSER));
1808 // pGH->browse(RingMainURL.c_str());
1812 // ConnectToShard();
1816 REGISTER_ACTION_HANDLER (CAHAcceptEula
, "accept_eula");
1818 // ***************************************************************************
1819 class CAHOpenURL
: public IActionHandler
1821 virtual void execute (CCtrlBase
* /* pCaller */, const string
&sParams
)
1823 nlinfo("CAHOpenURL called");
1829 #ifdef NL_OS_WINDOWS
1831 // Check for special install tag
1832 const char *KeyName
= "InstallTag";
1834 installTag
= CSystemUtils::getRegKey(KeyName
);
1836 if (installTag
.length() > 1)
1838 nldebug("Found install tag '%s'", url
.c_str());
1842 // Process any inserts in lpMsgBuf.
1844 // Display the string.
1845 nlwarning("RegQueryValue for '%s' : %s", KeyName
, NLMISC::formatErrorMessage(0).c_str());
1848 // TODO: for Linux and Mac OS
1850 if (sParams
== "cfg_CreateAccountURL")
1852 url
= ClientCfg
.CreateAccountURL
;
1854 else if (sParams
== "cfg_EditAccountURL")
1856 url
= ClientCfg
.EditAccountURL
;
1858 else if (sParams
== "cfg_BetaAccountURL")
1860 url
= ClientCfg
.BetaAccountURL
;
1862 else if (sParams
== "cfg_ForgetPwdURL")
1864 url
= ClientCfg
.ForgetPwdURL
;
1866 else if (sParams
== "cfg_LoginSupportURL")
1868 url
= ClientCfg
.LoginSupportURL
;
1870 else if (sParams
== "cfg_FreeTrialURL")
1872 url
= ClientCfg
.FreeTrialURL
;
1874 if (!installTag
.empty())
1876 url
+= string("&from=")+installTag
;
1879 else if (sParams
== "cfg_ConditionsTermsURL")
1881 url
= ClientCfg
.ConditionsTermsURL
;
1883 else if (sParams
== "cfg_NamingPolicyURL")
1885 url
= ClientCfg
.NamingPolicyURL
;
1892 if(sParams
!= "cfg_ConditionsTermsURL" && sParams
!= "cfg_NamingPolicyURL")
1894 // modify existing languages
1897 string::size_type pos_lang
= url
.find("/en/");
1900 if (pos_lang
== string::npos
)
1901 pos_lang
= url
.find("=en#");
1903 if (pos_lang
!= string::npos
)
1905 url
.replace(pos_lang
+ 1, 2, ClientCfg
.getHtmlLanguageCode());
1910 if (url
.find('?') != string::npos
)
1915 url
+= "language=" + ClientCfg
.LanguageCode
;
1917 if (!LoginCustomParameters
.empty())
1918 url
+= LoginCustomParameters
;
1924 nlinfo("openURL %s", url
.c_str());
1927 REGISTER_ACTION_HANDLER (CAHOpenURL
, "open_url");
1929 static vector
<UDriver::CMode
> VideoModes
;
1930 vector
<string
> StringModeList
;
1931 vector
<string
> StringPresetList
;
1932 vector
< pair
<string
, bool> > CfgPresetList
;
1933 sint CurrentMode
= -1;
1934 sint CurrentPreset
= -1;
1936 // ***************************************************************************
1937 class CAHInitResLod
: public IActionHandler
1939 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
1941 //nlinfo("CAHInitResLod called");
1942 if (Driver
== NULL
) return;
1945 StringModeList
.clear();
1947 std::vector
<std::string
> stringFreqList
;
1950 getRyzomModes(VideoModes
, StringModeList
, stringFreqList
, CurrentMode
, currentFreq
);
1952 // getRyzomModes() expects empty list, so we need to insert 'Windowed' after mode list is filled
1953 StringModeList
.insert(StringModeList
.begin(), "uiConfigWindowed");
1955 // If the client is in windowed mode, still in windowed mode and do not change anything
1956 if (ClientCfg
.Windowed
)
1958 // If we have not found the mode so it can be an error or machine change, so propose the first available
1959 else if (CurrentMode
== -1)
1961 // We inserted 'Windowed' as first mode, so index needs to move too
1965 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1966 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
1968 pVT
->setHardText(StringModeList
[CurrentMode
]);
1970 StringPresetList
.clear();
1971 StringPresetList
.push_back("uiLodValueLow");
1972 StringPresetList
.push_back("uiLodValueMedium");
1973 StringPresetList
.push_back("uiLodValueNormal");
1974 StringPresetList
.push_back("uiLodValueHigh");
1975 StringPresetList
.push_back("uiLodValueCustom");
1976 CurrentPreset
= 4; // CInterfaceDDX::CustomPreset
1978 // first indicates the preset-able cfg-variable
1979 // second indicates if its a double variable (else it's an int)
1980 CfgPresetList
.clear();
1981 CfgPresetList
.push_back(pair
<string
,bool>("LandscapeTileNear", true));
1982 CfgPresetList
.push_back(pair
<string
,bool>("LandscapeThreshold", true));
1983 CfgPresetList
.push_back(pair
<string
,bool>("Vision", true));
1984 CfgPresetList
.push_back(pair
<string
,bool>("MicroVeget", false));
1985 CfgPresetList
.push_back(pair
<string
,bool>("MicroVegetDensity", true));
1986 CfgPresetList
.push_back(pair
<string
,bool>("FxNbMaxPoly", false));
1987 CfgPresetList
.push_back(pair
<string
,bool>("Cloud", false));
1988 CfgPresetList
.push_back(pair
<string
,bool>("CloudQuality", true));
1989 CfgPresetList
.push_back(pair
<string
,bool>("CloudUpdate", false));
1990 CfgPresetList
.push_back(pair
<string
,bool>("Shadows", false));
1991 CfgPresetList
.push_back(pair
<string
,bool>("SkinNbMaxPoly", false));
1992 CfgPresetList
.push_back(pair
<string
,bool>("NbMaxSkeletonNotCLod", false));
1993 CfgPresetList
.push_back(pair
<string
,bool>("CharacterFarClip", true));
1995 CfgPresetList
.push_back(pair
<string
,bool>("FXAA", false));
1996 CfgPresetList
.push_back(pair
<string
,bool>("Bloom", false));
1997 CfgPresetList
.push_back(pair
<string
,bool>("SquareBloom", false));
1998 CfgPresetList
.push_back(pair
<string
,bool>("DensityBloom", true));
2000 // Check if all the preset-able cfg-variable are in a preset mode
2002 for (uint32 i
= 0; i
< CfgPresetList
.size(); ++i
)
2004 CConfigFile::CVar
*cfgVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(CfgPresetList
[i
].first
);
2005 if (cfgVarPtr
== NULL
) continue;
2006 // Get the preset of the variable i
2007 sint nVarPreset
= 0;
2008 for (uint32 j
= 0; j
< 4; ++j
) // CInterfaceDDX::NumPreset
2010 string sPresetName
= CfgPresetList
[i
].first
+ "_ps" + toString(j
);
2011 CConfigFile::CVar
*presetVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(sPresetName
);
2014 if (CfgPresetList
[i
].second
) // Is it a double ?
2016 if (cfgVarPtr
->asDouble() == presetVarPtr
->asDouble())
2017 nVarPreset
|= (1 << j
);
2021 if (cfgVarPtr
->asInt() == presetVarPtr
->asInt())
2022 nVarPreset
|= (1 << j
);
2028 nPreset
= nVarPreset
;
2030 nPreset
&= nVarPreset
;
2038 if (nPreset
&1) CurrentPreset
= 0;
2039 else if (nPreset
&2) CurrentPreset
= 1;
2040 else if (nPreset
&4) CurrentPreset
= 2;
2041 else if (nPreset
&8) CurrentPreset
= 3;
2044 pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2046 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2049 REGISTER_ACTION_HANDLER (CAHInitResLod
, "init_res_lod");
2051 // ***************************************************************************
2052 class CAHMoreRes
: public IActionHandler
2054 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2056 nlinfo("CAHMoreRes called");
2057 if (CurrentMode
< ((sint
)StringModeList
.size()-1))
2059 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2060 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
2062 pVT
->setHardText(StringModeList
[CurrentMode
]);
2065 REGISTER_ACTION_HANDLER (CAHMoreRes
, "more_res");
2067 // ***************************************************************************
2068 class CAHLessRes
: public IActionHandler
2070 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2072 nlinfo("CAHLessRes called");
2073 if (CurrentMode
> 0)
2075 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2076 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
2078 pVT
->setHardText(StringModeList
[CurrentMode
]);
2081 REGISTER_ACTION_HANDLER (CAHLessRes
, "less_res");
2083 // ***************************************************************************
2084 class CAHMoreLod
: public IActionHandler
2086 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2088 nlinfo("CAHMoreLod called");
2089 if (CurrentPreset
< ((sint
)StringPresetList
.size()-1))
2091 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2092 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2094 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2097 REGISTER_ACTION_HANDLER (CAHMoreLod
, "more_lod");
2099 // ***************************************************************************
2100 class CAHLessLod
: public IActionHandler
2102 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2104 nlinfo("CAHMoreLod called");
2105 if (CurrentPreset
> 0)
2107 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2108 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2110 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2113 REGISTER_ACTION_HANDLER (CAHLessLod
, "less_lod");
2115 // ***************************************************************************
2116 // TODO: remove resolution change from login screen
2117 class CAHUninitResLod
: public IActionHandler
2119 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2121 //nlinfo("CAHUninitResLod called");
2123 // If the mode requested is a windowed mode do nothnig
2124 if (CurrentMode
== 0)
2126 ClientCfg
.Windowed
= true;
2127 ClientCfg
.writeBool("FullScreen", false);
2131 ClientCfg
.Windowed
= false;
2133 uint16 w
= 0, h
= 0;
2135 string vidModeStr
= StringModeList
[CurrentMode
];
2136 string tmp
= vidModeStr
.substr(0,vidModeStr
.find('x')-1);
2138 tmp
= vidModeStr
.substr(vidModeStr
.find('x')+2,vidModeStr
.size());
2141 ClientCfg
.Width
= w
;
2142 ClientCfg
.Height
= h
;
2144 ClientCfg
.writeBool("FullScreen", true);
2145 ClientCfg
.writeInt("Width", w
);
2146 ClientCfg
.writeInt("Height", h
);
2149 if (CurrentPreset
!= 4) // CInterfaceDDX::CustomPreset
2151 for (uint32 i
= 0; i
< CfgPresetList
.size(); ++i
)
2153 CConfigFile::CVar
*cfgVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(CfgPresetList
[i
].first
);
2154 if (cfgVarPtr
== NULL
) continue;
2156 string sPresetName
= CfgPresetList
[i
].first
+ "_ps" + toString(CurrentPreset
);
2157 CConfigFile::CVar
*presetVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(sPresetName
);
2160 if (CfgPresetList
[i
].second
) // Is it a double ?
2161 cfgVarPtr
->setAsDouble(presetVarPtr
->asDouble());
2163 cfgVarPtr
->setAsInt(presetVarPtr
->asInt());
2168 // **** Save the config
2169 if (ClientCfg
.SaveConfig
)
2170 ClientCfg
.ConfigFile
.save ();
2171 ClientCfg
.IsInvalidated
= true;
2174 REGISTER_ACTION_HANDLER (CAHUninitResLod
, "uninit_res_lod");
2179 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2180 CPatchManager
*pPM
= CPatchManager::getInstance();
2183 setDataScanLog(string());
2186 pPM
->startScanDataThread();
2187 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_DATASCAN
);
2188 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->setValue32(1);
2191 // ***************************************************************************
2192 // Called after the check has been done. The page is full of optional categories that must be selected for patching
2193 class CAHOnScanDataStart
: public IActionHandler
2195 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2197 nlinfo("CAHOnScanDataStart called");
2199 LoginSM
.pushEvent(CLoginStateMachine::ev_data_scan
);
2203 REGISTER_ACTION_HANDLER (CAHOnScanDataStart
, "on_scan_data_start");
2205 // ***************************************************************************
2206 // Called when the user cancel the scan
2207 class CAHOnScanDataClose
: public IActionHandler
2209 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2211 nlinfo("CAHOnScanDataClose called");
2212 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2213 CPatchManager
*pPM
= CPatchManager::getInstance();
2215 // if the scan is still running
2216 if(NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->getValue32()!=0)
2218 // request to stop the thread
2219 pPM
->askForStopScanDataThread();
2222 setDataScanState(CI18N::get("uiCancelingScanData"));
2226 LoginSM
.pushEvent(CLoginStateMachine::ev_close_data_scan
);
2227 // Come Back to Login Screen.
2228 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
2230 // // Give focus to password if some login entered
2232 // CGroupEditBox *pGEB = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN));
2234 // loginEB= pGEB->getInputStringAsStdString();
2235 // // if none entered
2236 // if (loginEB.empty())
2237 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_LOGIN "|select_all=false");
2239 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_PASSWORD "|select_all=false");
2243 REGISTER_ACTION_HANDLER (CAHOnScanDataClose
, "on_scan_data_close");
2245 // ***************************************************************************
2247 inline string
parseTooltip(const string
& initString
, const string
& tagName
)
2251 string::size_type tooltipPos
= initString
.find(tagName
);
2252 if(tooltipPos
!= string::npos
)
2254 tooltip
= initString
.substr(tooltipPos
);
2257 tooltip
= tooltip
.substr(tooltip
.find(">")+1);
2260 tooltip
= tooltip
.substr(0, tooltip
.find("<"));
2266 inline string
parseCommentError(const string
& initString
, const string
& tagName
)
2270 string::size_type errorPos
= initString
.find(tagName
);
2271 if(errorPos
!= string::npos
)
2273 error
= initString
.substr(errorPos
);
2276 error
= error
.substr(error
.find(">")+1);
2279 error
= error
.substr(0, error
.find("<"));
2285 bool initCreateAccount()
2287 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2290 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2293 // show "submit interface", hide "login interface"
2294 CInterfaceGroup
* grSubmit
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("submit_gr"));
2296 grSubmit
->setActive(true);
2298 CInterfaceGroup
* grLogin
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("login_gr"));
2300 grLogin
->setActive(false);
2303 std::vector
< std::string
> editBoxes(4);
2304 editBoxes
[0] = "eb_login";
2305 editBoxes
[1] = "eb_password";
2306 editBoxes
[2] = "eb_confirm_password";
2307 editBoxes
[3] = "eb_email";
2309 for(uint i
=0; i
<editBoxes
.size(); i
++)
2311 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId(editBoxes
[i
] + ":eb"));
2313 eb
->setInputString(std::string());
2316 // conditions button
2317 CCtrlBaseButton
* but
= dynamic_cast<CCtrlBaseButton
*>(createAccountUI
->findFromShortId("accept_cond"));
2319 but
->setPushed(true);
2321 // get rules from url
2322 string url
= ClientCfg
.CreateAccountURL
;
2323 CPatchManager
*pPM
= CPatchManager::getInstance();
2325 if (!CurlHttpClient
.connect(url
))
2327 nlwarning("Can't connect");
2331 std::string lang
= ClientCfg
.LanguageCode
;
2332 if(lang
=="wk") lang
= "uk";
2334 CurlHttpClient
.verifyServer(true); // set this to false if you need to connect to the test environment
2336 std::string params
= "language=" + lang
;
2338 if (!LoginCustomParameters
.empty())
2339 params
+= LoginCustomParameters
;
2341 if(!CurlHttpClient
.sendGet(url
, params
, pPM
->isVerboseLog()))
2343 string
errorMessage("Can't send (error code 60)");
2344 errorMessageBox(errorMessage
);
2345 nlwarning(errorMessage
.c_str());
2350 if(!CurlHttpClient
.receive(res
, pPM
->isVerboseLog()))
2352 string
errorMessage("Can't receive (error code 61)");
2353 errorMessageBox(errorMessage
);
2354 nlwarning(errorMessage
.c_str());
2360 string
errorMessage("Empty result (error code 13)");
2361 errorMessageBox(errorMessage
);
2362 nlwarning(errorMessage
.c_str());
2366 CurlHttpClient
.disconnect();
2368 // initialize rules in interface
2369 std::vector
< std::pair
< std::string
, std::string
> > rules(5);
2370 rules
[0] = std::pair
<std::string
, std::string
>("rules_login", "id=tooltip-Username");
2371 rules
[1] = std::pair
<std::string
, std::string
>("rules_password", "id=tooltip-Password");
2372 rules
[2] = std::pair
<std::string
, std::string
>("rules_password_conf", "id=tooltip-ConfirmPass");
2373 rules
[3] = std::pair
<std::string
, std::string
>("rules_email", "id=tooltip-Email");
2374 rules
[4] = std::pair
<std::string
, std::string
>("rules_conditions", "id=tooltip-TaC");
2376 for(uint i
=0; i
<rules
.size(); i
++)
2378 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId(rules
[i
].first
));
2381 string tooltip
= parseTooltip(res
, rules
[i
].second
);
2382 text
->setHardText(tooltip
);
2383 text
->setActive(false);
2388 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("errors_list"));
2391 text
->setHardText(toString(CI18N::get("uiCreateAccountWelcome")));
2392 text
->setColor(CRGBA(255, 255, 255, 255));
2394 CInterfaceGroup
* group
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("erros_txt"));
2397 group
->updateCoords();
2399 CInterfaceGroup
* groupScroll
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("err_back_scrollbar"));
2400 if(groupScroll
) groupScroll
->setActive(group
->getHReal() > group
->getMaxHReal());
2401 CCtrlScroll
* scroll
= dynamic_cast<CCtrlScroll
*>(createAccountUI
->findFromShortId("err_scroll_bar"));
2403 scroll
->setTrackPos(scroll
->getHReal());
2408 CInterfaceGroup
* rulesGr
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("rules_gr"));
2410 rulesGr
->setActive(false);
2412 // must be done after hide rules
2413 CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL
, "target=" CTRL_EDITBOX_CREATEACCOUNT_LOGIN
"|select_all=false");
2417 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CREATE_ACCOUNT
);
2422 // ***************************************************************************
2423 // Called when the user focus one of the edit boxes during the account creation
2424 class CAHCreateAccountRules
: public IActionHandler
2426 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
2428 nlinfo("CAHCreateAccountRules called");
2430 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2431 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2434 CInterfaceGroup
* rulesGr
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("rules_gr"));
2436 rulesGr
->setActive(false);
2438 std::vector
< std::string
> rules(4);
2439 rules
[0] = "rules_login";
2440 rules
[1] = "rules_password";
2441 rules
[2] = "rules_password_conf";
2442 rules
[3] = "rules_email";
2444 for(uint i
=0; i
<rules
.size(); i
++)
2446 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId(rules
[i
]));
2449 text
->setActive(Params
==rules
[i
]);
2450 if(Params
==rules
[i
])
2453 rulesGr
->setActive(!text
->getText().empty());
2460 REGISTER_ACTION_HANDLER (CAHCreateAccountRules
, "create_account_rules");
2462 // ***************************************************************************
2463 // Called when the user choose the account creation
2464 class CAHOnCreateAccount
: public IActionHandler
2466 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2468 nlinfo("CAHOnCreateAccount called");
2470 LoginSM
.pushEvent(CLoginStateMachine::ev_create_account
);
2473 REGISTER_ACTION_HANDLER (CAHOnCreateAccount
, "on_create_account");
2475 // ***************************************************************************
2476 // Called when the user submit the account creation
2477 class CAHOnCreateAccountSubmit
: public IActionHandler
2479 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2481 nlinfo("CAHOnCreateAccountSubmit called");
2483 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2485 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2488 // recover data from UI
2489 std::vector
< std::string
> editBoxes(4);
2490 editBoxes
[0] = "eb_login";
2491 editBoxes
[1] = "eb_password";
2492 editBoxes
[2] = "eb_confirm_password";
2493 editBoxes
[3] = "eb_email";
2494 std::vector
< std::string
> results(4);
2496 for(uint i
=0; i
<editBoxes
.size(); i
++)
2498 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId(editBoxes
[i
] + ":eb"));
2500 results
[i
] = eb
->getInputString();
2504 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("email_adress"));
2506 text
->setHardText(results
[3]);
2508 // conditions button
2509 bool conditionsPushed
= false;
2510 CCtrlBaseButton
* but
= dynamic_cast<CCtrlBaseButton
*>(createAccountUI
->findFromShortId("accept_cond"));
2512 conditionsPushed
= !but
->getPushed();
2514 string url
= ClientCfg
.CreateAccountURL
;
2515 CPatchManager
*pPM
= CPatchManager::getInstance();
2517 if (!CurlHttpClient
.connect(url
))
2519 string
errorMessage("Can't connect");
2520 errorMessageBox(errorMessage
);
2521 nlwarning(errorMessage
.c_str());
2525 std::string params
= "Username=" + results
[0] + "&Password=" + results
[1]
2526 + "&ConfirmPass=" + results
[2] + "&Email=" + results
[3];
2528 if(conditionsPushed
)
2531 if (!LoginCustomParameters
.empty())
2532 params
+= LoginCustomParameters
;
2534 std::string md5
= results
[0] + results
[1] + "" + results
[3];
2535 md5
= NLMISC::getMD5((uint8
*)md5
.data(), (uint32
)md5
.size()).toString();
2537 params
+= "&SC=" + md5
;
2538 std::string lang
= ClientCfg
.LanguageCode
;
2539 if(lang
=="wk") lang
= "uk";
2540 params
+= "&Language=" + lang
;
2542 CurlHttpClient
.verifyServer(true); // set this to false if you need to connect to the test environment
2544 if(!CurlHttpClient
.sendPost(url
, params
, pPM
->isVerboseLog()))
2546 string
errorMessage("Can't send (error code 60)");
2547 errorMessageBox(errorMessage
);
2548 nlwarning(errorMessage
.c_str());
2553 if(!CurlHttpClient
.receive(res
, pPM
->isVerboseLog()))
2555 string
errorMessage("Can't receive (error code 61)");
2556 errorMessageBox(errorMessage
);
2557 nlwarning(errorMessage
.c_str());
2563 string
errorMessage("Empty result (error code 13)");
2564 errorMessageBox(errorMessage
);
2565 nlwarning(errorMessage
.c_str());
2569 CurlHttpClient
.disconnect();
2572 string::size_type okPos
= res
.find("email_sent");
2573 if(okPos
!= string::npos
)
2575 // show "submit interface", hide "login interface"
2576 CInterfaceGroup
* grSubmit
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("submit_gr"));
2578 grSubmit
->setActive(false);
2580 CInterfaceGroup
* grLogin
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("login_gr"));
2582 grLogin
->setActive(true);
2586 // initialize error comments in interface
2587 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("errors_list"));
2590 text
->setColor(CRGBA(250, 30, 30, 255));
2592 std::vector
< std::string
> errors(5);
2593 errors
[0] = "id=\"comment-Username\"";
2594 errors
[1] = "id=\"comment-Password\"";
2595 errors
[2] = "id=\"comment-ConfirmPass\"";
2596 errors
[3] = "id=\"comment-Email\"";
2597 errors
[4] = "id=\"comment-TaC\"";
2600 for(uint i
=0; i
<errors
.size(); i
++)
2602 string comment
= parseCommentError(res
, errors
[i
]);
2603 if(!comment
.empty())
2604 error
+= "- " + comment
+ "\n";
2607 text
->setHardText(error
);
2609 CInterfaceGroup
* group
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("erros_txt"));
2612 group
->updateCoords();
2614 CInterfaceGroup
* groupScroll
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("err_back_scrollbar"));
2615 if(groupScroll
) groupScroll
->setActive(group
->getHReal() > group
->getMaxHReal());
2616 CCtrlScroll
* scroll
= dynamic_cast<CCtrlScroll
*>(createAccountUI
->findFromShortId("err_scroll_bar"));
2618 scroll
->setTrackPos(scroll
->getHReal());
2625 REGISTER_ACTION_HANDLER (CAHOnCreateAccountSubmit
, "on_create_account_submit");
2627 // ***************************************************************************
2628 // Called when the user cancel the account creation
2629 class CAHOnCreateAccountClose
: public IActionHandler
2631 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2633 nlinfo("CAHOnCreateAccountClose called");
2635 LoginSM
.pushEvent(CLoginStateMachine::ev_close_create_account
);
2638 REGISTER_ACTION_HANDLER (CAHOnCreateAccountClose
, "on_create_account_close");
2640 // ***************************************************************************
2641 class CAHCreateAccountLogin
: public IActionHandler
2643 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2645 nlinfo("CAHCreateAccountLogin called");
2647 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2649 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2652 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId("eb_login:eb"));
2654 LoginLogin
= eb
->getInputString();
2656 eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId("eb_password:eb"));
2658 LoginPassword
= eb
->getInputString();
2664 REGISTER_ACTION_HANDLER (CAHCreateAccountLogin
, "create_account_login");
2666 // ***************************************************************************
2667 // Called by html embeded lua script
2668 class CAHOnConnectToShard
: public IActionHandler
2670 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
2672 // warning : pCaller is null when event come from lua scrip embeded in HTML
2673 Cookie
= getParam(Params
, "cookie");
2674 FSAddr
= getParam(Params
, "fsAddr");
2676 // replace the '_' with '|' in the cookie string
2677 for (uint i
=0; i
<Cookie
.size(); ++i
)
2679 if (Cookie
[i
] == '_')
2683 setLoginFinished( true );
2686 LoginSM
.pushEvent(CLoginStateMachine::ev_connect
);
2689 REGISTER_ACTION_HANDLER (CAHOnConnectToShard
, "on_connect_to_shard");
2691 // ***************************************************************************
2692 // Called to return to login screen in case of error
2693 class CAHOnBackToLogin
: public IActionHandler
2695 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2697 setLoginFinished( false );
2699 LoginSM
.pushEvent(CLoginStateMachine::ev_relog
);
2701 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
2702 // // need to reset password and current screen
2703 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
2706 REGISTER_ACTION_HANDLER (CAHOnBackToLogin
, "on_back_to_login");
2708 // ***************************************************************************
2709 // ***************************************************************************
2710 // ***************************************************************************
2711 // NETWORK CONNECTION
2712 // ***************************************************************************
2713 // ***************************************************************************
2714 // ***************************************************************************
2717 // ***************************************************************************
2718 string
checkLogin(const string
&login
, const string
&password
, const string
&clientApp
, const std::string
&customParameters
)
2720 CPatchManager
*pPM
= CPatchManager::getInstance();
2723 if(ClientCfg
.ConfigFile
.exists("VerboseLog"))
2724 pPM
->setVerboseLog(ClientCfg
.ConfigFile
.getVar("VerboseLog").asInt() == 1);
2725 if(pPM
->isVerboseLog()) nlinfo("Using verbose log mode");
2727 if(!HttpClient
.connectToLogin())
2728 return "Can't connect (error code 1)";
2730 if(pPM
->isVerboseLog()) nlinfo("Connected");
2734 std::string url
= ClientCfg
.ConfigFile
.getVar("StartupHost").asString() + ClientCfg
.ConfigFile
.getVar("StartupPage").asString();
2736 // don't use login with alt method
2739 // ask server for salt
2740 if(!HttpClient
.sendGet(url
+ "?cmd=ask&cp=2&login=" + login
+ "&lg=" + ClientCfg
.LanguageCode
, "", pPM
->isVerboseLog()))
2741 return std::string("Can't send (error code 60) ") + HttpClient
.lastError();
2743 if(pPM
->isVerboseLog()) nlinfo("Sent request for password salt");
2745 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2746 return "Can't receive (error code 61)";
2748 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2751 return "Empty answer from server (error code 62)";
2753 size_t first
= res
.find("\n\n");
2754 if (first
== std::string::npos
)
2756 first
= res
.find("\r\r");
2757 if (first
== std::string::npos
)
2759 first
= res
.find("\r\n\r\n");
2760 if (first
!= std::string::npos
)
2762 res
= res
.substr(first
+ 4);
2767 res
= res
.substr(first
+ 2);
2772 res
= res
.substr(first
+ 2);
2775 nldebug("res1: %s", res
.c_str());
2779 nlwarning("missing response body: %s", res
.c_str());
2780 return "missing response body (error code 64)";
2782 else if(res
[0] == '0')
2784 // server returns an error
2785 nlwarning("server error: %s", res
.substr(2).c_str());
2786 return res
.substr(2);
2788 else if(res
[0] == '1')
2790 Salt
= res
.substr(2);
2794 // server returns ???
2795 nlwarning("%s", res
.c_str());
2799 // send login + crypted password + client app and cp=2 (as crypted password)
2800 if(!HttpClient
.connectToLogin())
2801 return "Can't connect (error code 63)";
2803 if(pPM
->isVerboseLog()) nlinfo("Connected");
2806 if (ClientCfg
.R2Mode
)
2808 // R2 login sequence
2812 std::string cryptedPassword
= CCrypt::crypt(password
, Salt
);
2814 if(!HttpClient
.sendGet(url
+ "?cmd=login&login=" + login
+ "&password=" + cryptedPassword
+ "&clientApplication=" + clientApp
+ "&cp=2" + "&lg=" + ClientCfg
.LanguageCode
+ customParameters
))
2815 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2819 // don't send login and password if empty
2820 if(!HttpClient
.sendGet(url
+ "?cmd=login&clientApplication=" + clientApp
+ "&cp=2" + "&lg=" + ClientCfg
.LanguageCode
+ customParameters
))
2821 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2824 // the response should contains the result code and the cookie value
2825 if(pPM
->isVerboseLog()) nlinfo("Sent request login check");
2827 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2828 return "Can't receive (error code 3)";
2830 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2833 return "Empty answer from server (error code 4)";
2835 size_t first
= res
.find("\n\n");
2836 if (first
== std::string::npos
)
2838 first
= res
.find("\r\r");
2839 if (first
== std::string::npos
)
2841 first
= res
.find("\r\n\r\n");
2842 if (first
!= std::string::npos
)
2844 res
= res
.substr(first
+ 4);
2849 res
= res
.substr(first
+ 2);
2854 res
= res
.substr(first
+ 2);
2857 nldebug("res2: %s", res
.c_str());
2861 nlwarning("missing response body: %s", res
.c_str());
2862 return "missing response body (error code 65)";
2864 else if(res
[0] == '0')
2866 // server returns an error
2867 nlwarning("server error: %s", res
.substr(2).c_str());
2868 return res
.substr(2);
2870 else if(res
[0] == '1')
2872 //nlwarning(res.c_str());
2873 vector
<string
> lines
;
2874 explode(res
, std::string("\n"), lines
, false);
2875 if (lines
.size() != 2)
2877 return toString("Invalid server return, found %u lines, want 2", lines
.size());
2880 vector
<string
> parts
;
2881 explode(lines
[0], std::string("#"), parts
, false);
2882 if (parts
.size() < 5)
2883 return "Invalid server return, missing cookie and/or Ring URLs";
2885 // server returns ok, we have the cookie
2887 // store the cookie value and FS address for next page request
2888 CurrentCookie
= parts
[1];
2889 Cookie
= CurrentCookie
;
2892 // store the ring startup page
2893 RingMainURL
= parts
[3];
2894 FarTP
.setURLBase(parts
[4]);
2896 if(parts
.size() >= 6 && parts
[5] == "1")
2899 extern bool startStat
;
2903 // parse the second line (contains the domain info)
2905 explode(lines
[1], std::string("#"), parts
, false);
2906 if (parts
.size() < 3)
2907 return "Invalid server return, missing patch URLs";
2909 R2ServerVersion
= parts
[0].c_str();
2910 R2BackupPatchURL
= parts
[1];
2911 explode(parts
[2], std::string(" "), R2PatchURLs
, true);
2915 // unexpected content
2917 string ret
= toString("DEV : Invalid server return, missing return code in \n%s", res
.c_str());
2920 return "Invalid server return, missing return code";
2927 // standard ryzom login sequence
2928 std::string cryptedPassword
= CCrypt::crypt(password
, Salt
);
2930 if(!HttpClient
.sendGet(url
+ "?login=" + login
+ "&password=" + cryptedPassword
+ "&clientApplication=" + clientApp
+ "&cp=2"))
2931 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2933 if(!send(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
2934 return "Can't send (error code 2)";
2936 if(pPM
->isVerboseLog()) nlinfo("Sent request login check");
2938 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2939 return "Can't receive (error code 3)";
2941 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2944 return "Empty answer from server (error code 4)";
2946 size_t first
= res
.find("\n\n");
2947 if (first
== std::string::npos
)
2949 first
= res
.find("\r\r");
2950 if (first
== std::string::npos
)
2952 first
= res
.find("\r\n\r\n");
2953 if (first
!= std::string::npos
)
2955 res
= res
.substr(first
+ 4);
2960 res
= res
.substr(first
+ 2);
2965 res
= res
.substr(first
+ 2);
2968 nldebug("res2: %s", res
.c_str());
2972 nlwarning("missing response body: %s", res
.c_str());
2973 return "missing response body (error code 66)";
2975 else if(res
[0] == '0')
2977 // server returns an error
2978 nlwarning("server error: %s", res
.substr(2).c_str());
2979 return res
.substr(2);
2981 else if(res
[0] == '1')
2983 // server returns ok, we have the list of shard
2985 fromString(res
.substr(2), nbs
);
2986 vector
<string
> lines
;
2988 explode(res
, std::string("\n"), lines
, true);
2990 if(pPM
->isVerboseLog())
2992 nlinfo ("Exploded, with nl, %u res", (uint
)lines
.size());
2993 /* for (uint i = 0; i < lines.size(); i++)
2995 nlinfo (" > '%s'", lines[i].c_str());
2999 if(lines
.size() != nbs
+1)
3001 nlwarning("bad shard lines number %u != %d", (uint
)lines
.size(), nbs
+1);
3002 nlwarning("'%s'", res
.c_str());
3003 return "bad lines numbers (error code 5)";
3006 for(uint i
= 1; i
< lines
.size(); i
++)
3009 explode(lines
[i
], std::string("|"), res
);
3011 if(pPM
->isVerboseLog())
3013 nlinfo ("Exploded with '%s', %u res", "|", (uint
)res
.size());
3014 /* for (uint i = 0; i < res.size(); i++)
3016 nlinfo (" > '%s'", res[i].c_str());
3020 if (res
.size() < 7 && res
.size() > 8)
3022 nlwarning("bad | numbers %u != %d", (uint
)res
.size(), 8);
3023 nlwarning("'%s'", lines
[i
].c_str());
3024 return "bad pipe numbers (error code 6)";
3027 fromString(res
[1], online
);
3029 fromString(res
[2], shardId
);
3031 fromString(res
[4], nbPlayers
);
3032 Shards
.push_back(CShard(res
[0], online
, shardId
, res
[3], nbPlayers
, res
[5], res
[6]));
3033 nlinfo("Shard %u, addr = %s, id = %u, name = %s, PatchURIs = %s", i
, res
[5].c_str(), shardId
, res
[3].c_str(), res
[6].c_str());
3034 if (res
.size() == 8)
3036 explode(res
[7], std::string(" "), Shards
.back().PatchURIs
);
3042 // server returns ???
3043 nlwarning("%s", res
.c_str());
3051 // ***************************************************************************
3052 string
selectShard(uint32 shardId
, string
&cookie
, string
&addr
)
3057 if(!HttpClient
.connectToLogin()) return "Can't connect (error code 7)";
3059 if(LoginLogin
.empty()) return "Empty Login (error code 8)";
3060 if(LoginPassword
.empty()) return "Empty Password (error code 9)";
3061 if(ClientApp
.empty()) return "Empty Client Application (error code 10)";
3063 // send login + crypted password + client app and cp=2 (as crypted password)
3064 std::string cryptedPassword
= CCrypt::crypt(LoginPassword
, Salt
);
3066 std::string url
= ClientCfg
.ConfigFile
.getVar("StartupHost").asString() + ClientCfg
.ConfigFile
.getVar("StartupPage").asString();
3068 if(!HttpClient
.sendGet(url
+ "?cmd=login&shardid=" + toString(shardId
) + "&login=" + LoginLogin
+ "&password=" + cryptedPassword
+ "&clientApplication=" + ClientApp
+ "&cp=2"))
3069 return "Can't send (error code 11)";
3073 CPatchManager
*pPM
= CPatchManager::getInstance();
3074 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
3075 return "Can't receive (error code 12)";
3078 return "Empty result (error code 13)";
3080 size_t first
= res
.find("\n\n");
3081 if (first
== std::string::npos
)
3083 first
= res
.find("\r\r");
3084 if (first
== std::string::npos
)
3086 first
= res
.find("\r\n\r\n");
3087 if (first
!= std::string::npos
)
3089 res
= res
.substr(first
+ 4);
3094 res
= res
.substr(first
+ 2);
3099 res
= res
.substr(first
+ 2);
3102 nldebug("res2: %s", res
.c_str());
3106 nlwarning("missing response body: %s", res
.c_str());
3107 return "missing response body (error code 66)";
3109 else if(res
[0] == '0')
3111 // server returns an error
3112 nlwarning("server error: %s", res
.substr(2).c_str());
3113 return res
.substr(2);
3115 else if(res
[0] == '1')
3117 // server returns ok, we have the access
3119 vector
<string
> line
;
3120 explode(res
, std::string(" "), line
, true);
3122 if (line
.size() < 2 || line
.size() > 3)
3124 nlwarning("bad launch lines number %d != %d", line
.size(), 2);
3125 return "bad launch line number (error code 14)";
3128 cookie
= line
[0].substr(2);
3131 std::vector
<std::string
> patchURIs
;
3133 CShard
* shard
= NULL
;
3135 for (i
=0; i
<Shards
.size(); ++i
)
3137 if (Shards
[i
].ShardId
== shardId
)
3144 if (shard != NULL && line.size() >= 3)
3146 explode(line[2], "|", shard->PatchURIs, true);
3148 nlinfo("received %d main patch server URIs:", shard->PatchURIs.size());
3150 for (i=0; i<shard->PatchURIs.size(); ++i)
3151 nlinfo("%d: '%s'", i, shard->PatchURIs[i].c_str());
3157 // server returns ???
3158 nlwarning("%s", res
.c_str());
3166 /*void mainLandPatch()
3168 if (!AvailablePatchs) return;
3169 nlassert(AvailablePatchs & (1 << BGDownloader::DownloadID_MainLand)); // only handled case for now
3171 BGDownloaderWantedPatch = BGDownloader::DownloadID_MainLand;
3172 CInterfaceManager *im = CInterfaceManager::getInstance();
3174 // login machine should be in the 'end' state !!
3175 nlassert(LoginSM.getCurrentState() == CLoginStateMachine::st_end);
3176 LoginSM.pushEvent(CLoginStateMachine::ev_mainland_patch);
3177 loginMainLoop(); // patch is handled in the login mainloop
3178 // there should have been a reboot there, so quit if something went wrong...
3186 // ***************************************************************************
3187 // ***************************************************************************
3189 // ***************************************************************************
3190 // ***************************************************************************
3192 #include "init_main_loop.h"
3194 bool loginIntroSkip
;
3198 // Display of nevrax logo is done at init time (see init.cpp) just before addSearchPath (second one)
3199 for (uint i
= 0; i
< 1; i
++) // previously display nevrax then nvidia
3203 beginLoading(IntroNVidia
);
3205 ProgressBar
.newMessage (nmsg
);
3208 Driver
->AsyncListener
.reset();
3210 CInputHandlerManager::getInstance()->pumpEventsNoIM();
3213 loginIntroSkip
= false;
3215 sint64 CurTime
= T0
;
3217 while (loginIntroSkip
== false)
3220 if ((T0
- CurTime
) > 5000) // 5s before quiting
3223 CInputHandlerManager::getInstance()->pumpEventsNoIM();
3226 if (Driver
->AsyncListener
.isKeyPushed (KeyESCAPE
) || Driver
->AsyncListener
.isKeyPushed (KeyRETURN
) ||
3227 Driver
->AsyncListener
.isKeyPushed (KeySPACE
))
3230 const string
nmsg("");
3231 ProgressBar
.newMessage (nmsg
);
3232 IngameDbMngr
.flushObserverCalls();
3233 NLGUI::CDBManager::getInstance()->flushObserverCalls();
3236 beginLoading(StartBackground
);
3237 ProgressBar
.finish();