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
;
1889 nlwarning("no URL found");
1893 if(sParams
!= "cfg_ConditionsTermsURL" && sParams
!= "cfg_NamingPolicyURL")
1895 // modify existing languages
1898 string::size_type pos_lang
= url
.find("/en/");
1901 if (pos_lang
== string::npos
)
1902 pos_lang
= url
.find("=en#");
1904 if (pos_lang
!= string::npos
)
1906 url
.replace(pos_lang
+ 1, 2, ClientCfg
.getHtmlLanguageCode());
1911 if (url
.find('?') != string::npos
)
1916 url
+= "language=" + ClientCfg
.LanguageCode
;
1918 if (!LoginCustomParameters
.empty())
1919 url
+= LoginCustomParameters
;
1925 nlinfo("openURL %s", url
.c_str());
1928 REGISTER_ACTION_HANDLER (CAHOpenURL
, "open_url");
1930 static vector
<UDriver::CMode
> VideoModes
;
1931 vector
<string
> StringModeList
;
1932 vector
<string
> StringPresetList
;
1933 vector
< pair
<string
, bool> > CfgPresetList
;
1934 sint CurrentMode
= -1;
1935 sint CurrentPreset
= -1;
1937 // ***************************************************************************
1938 class CAHInitResLod
: public IActionHandler
1940 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
1942 //nlinfo("CAHInitResLod called");
1943 if (Driver
== NULL
) return;
1946 StringModeList
.clear();
1948 std::vector
<std::string
> stringFreqList
;
1951 getRyzomModes(VideoModes
, StringModeList
, stringFreqList
, CurrentMode
, currentFreq
);
1953 // getRyzomModes() expects empty list, so we need to insert 'Windowed' after mode list is filled
1954 StringModeList
.insert(StringModeList
.begin(), "uiConfigWindowed");
1956 // If the client is in windowed mode, still in windowed mode and do not change anything
1957 if (ClientCfg
.Windowed
)
1959 // If we have not found the mode so it can be an error or machine change, so propose the first available
1960 else if (CurrentMode
== -1)
1962 // We inserted 'Windowed' as first mode, so index needs to move too
1966 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1967 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
1969 pVT
->setHardText(StringModeList
[CurrentMode
]);
1971 StringPresetList
.clear();
1972 StringPresetList
.push_back("uiLodValueLow");
1973 StringPresetList
.push_back("uiLodValueMedium");
1974 StringPresetList
.push_back("uiLodValueNormal");
1975 StringPresetList
.push_back("uiLodValueHigh");
1976 StringPresetList
.push_back("uiLodValueCustom");
1977 CurrentPreset
= 4; // CInterfaceDDX::CustomPreset
1979 // first indicates the preset-able cfg-variable
1980 // second indicates if its a double variable (else it's an int)
1981 CfgPresetList
.clear();
1982 CfgPresetList
.push_back(pair
<string
,bool>("LandscapeTileNear", true));
1983 CfgPresetList
.push_back(pair
<string
,bool>("LandscapeThreshold", true));
1984 CfgPresetList
.push_back(pair
<string
,bool>("Vision", true));
1985 CfgPresetList
.push_back(pair
<string
,bool>("MicroVeget", false));
1986 CfgPresetList
.push_back(pair
<string
,bool>("MicroVegetDensity", true));
1987 CfgPresetList
.push_back(pair
<string
,bool>("FxNbMaxPoly", false));
1988 CfgPresetList
.push_back(pair
<string
,bool>("Cloud", false));
1989 CfgPresetList
.push_back(pair
<string
,bool>("CloudQuality", true));
1990 CfgPresetList
.push_back(pair
<string
,bool>("CloudUpdate", false));
1991 CfgPresetList
.push_back(pair
<string
,bool>("Shadows", false));
1992 CfgPresetList
.push_back(pair
<string
,bool>("SkinNbMaxPoly", false));
1993 CfgPresetList
.push_back(pair
<string
,bool>("NbMaxSkeletonNotCLod", false));
1994 CfgPresetList
.push_back(pair
<string
,bool>("CharacterFarClip", true));
1996 CfgPresetList
.push_back(pair
<string
,bool>("FXAA", false));
1997 CfgPresetList
.push_back(pair
<string
,bool>("Bloom", false));
1998 CfgPresetList
.push_back(pair
<string
,bool>("SquareBloom", false));
1999 CfgPresetList
.push_back(pair
<string
,bool>("DensityBloom", true));
2001 // Check if all the preset-able cfg-variable are in a preset mode
2003 for (uint32 i
= 0; i
< CfgPresetList
.size(); ++i
)
2005 CConfigFile::CVar
*cfgVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(CfgPresetList
[i
].first
);
2006 if (cfgVarPtr
== NULL
) continue;
2007 // Get the preset of the variable i
2008 sint nVarPreset
= 0;
2009 for (uint32 j
= 0; j
< 4; ++j
) // CInterfaceDDX::NumPreset
2011 string sPresetName
= CfgPresetList
[i
].first
+ "_ps" + toString(j
);
2012 CConfigFile::CVar
*presetVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(sPresetName
);
2015 if (CfgPresetList
[i
].second
) // Is it a double ?
2017 if (cfgVarPtr
->asDouble() == presetVarPtr
->asDouble())
2018 nVarPreset
|= (1 << j
);
2022 if (cfgVarPtr
->asInt() == presetVarPtr
->asInt())
2023 nVarPreset
|= (1 << j
);
2029 nPreset
= nVarPreset
;
2031 nPreset
&= nVarPreset
;
2039 if (nPreset
&1) CurrentPreset
= 0;
2040 else if (nPreset
&2) CurrentPreset
= 1;
2041 else if (nPreset
&4) CurrentPreset
= 2;
2042 else if (nPreset
&8) CurrentPreset
= 3;
2045 pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2047 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2050 REGISTER_ACTION_HANDLER (CAHInitResLod
, "init_res_lod");
2052 // ***************************************************************************
2053 class CAHMoreRes
: public IActionHandler
2055 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2057 nlinfo("CAHMoreRes called");
2058 if (CurrentMode
< ((sint
)StringModeList
.size()-1))
2060 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2061 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
2063 pVT
->setHardText(StringModeList
[CurrentMode
]);
2066 REGISTER_ACTION_HANDLER (CAHMoreRes
, "more_res");
2068 // ***************************************************************************
2069 class CAHLessRes
: public IActionHandler
2071 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2073 nlinfo("CAHLessRes called");
2074 if (CurrentMode
> 0)
2076 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2077 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
2079 pVT
->setHardText(StringModeList
[CurrentMode
]);
2082 REGISTER_ACTION_HANDLER (CAHLessRes
, "less_res");
2084 // ***************************************************************************
2085 class CAHMoreLod
: public IActionHandler
2087 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2089 nlinfo("CAHMoreLod called");
2090 if (CurrentPreset
< ((sint
)StringPresetList
.size()-1))
2092 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2093 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2095 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2098 REGISTER_ACTION_HANDLER (CAHMoreLod
, "more_lod");
2100 // ***************************************************************************
2101 class CAHLessLod
: public IActionHandler
2103 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2105 nlinfo("CAHMoreLod called");
2106 if (CurrentPreset
> 0)
2108 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2109 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2111 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2114 REGISTER_ACTION_HANDLER (CAHLessLod
, "less_lod");
2116 // ***************************************************************************
2117 // TODO: remove resolution change from login screen
2118 class CAHUninitResLod
: public IActionHandler
2120 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2122 //nlinfo("CAHUninitResLod called");
2124 // If the mode requested is a windowed mode do nothnig
2125 if (CurrentMode
== 0)
2127 ClientCfg
.Windowed
= true;
2128 ClientCfg
.writeBool("FullScreen", false);
2132 ClientCfg
.Windowed
= false;
2134 uint16 w
= 0, h
= 0;
2136 string vidModeStr
= StringModeList
[CurrentMode
];
2137 string tmp
= vidModeStr
.substr(0,vidModeStr
.find('x')-1);
2139 tmp
= vidModeStr
.substr(vidModeStr
.find('x')+2,vidModeStr
.size());
2142 ClientCfg
.Width
= w
;
2143 ClientCfg
.Height
= h
;
2145 ClientCfg
.writeBool("FullScreen", true);
2146 ClientCfg
.writeInt("Width", w
);
2147 ClientCfg
.writeInt("Height", h
);
2150 if (CurrentPreset
!= 4) // CInterfaceDDX::CustomPreset
2152 for (uint32 i
= 0; i
< CfgPresetList
.size(); ++i
)
2154 CConfigFile::CVar
*cfgVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(CfgPresetList
[i
].first
);
2155 if (cfgVarPtr
== NULL
) continue;
2157 string sPresetName
= CfgPresetList
[i
].first
+ "_ps" + toString(CurrentPreset
);
2158 CConfigFile::CVar
*presetVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(sPresetName
);
2161 if (CfgPresetList
[i
].second
) // Is it a double ?
2162 cfgVarPtr
->setAsDouble(presetVarPtr
->asDouble());
2164 cfgVarPtr
->setAsInt(presetVarPtr
->asInt());
2169 // **** Save the config
2170 if (ClientCfg
.SaveConfig
)
2171 ClientCfg
.ConfigFile
.save ();
2172 ClientCfg
.IsInvalidated
= true;
2175 REGISTER_ACTION_HANDLER (CAHUninitResLod
, "uninit_res_lod");
2180 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2181 CPatchManager
*pPM
= CPatchManager::getInstance();
2184 setDataScanLog(string());
2187 pPM
->startScanDataThread();
2188 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_DATASCAN
);
2189 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->setValue32(1);
2192 // ***************************************************************************
2193 // Called after the check has been done. The page is full of optional categories that must be selected for patching
2194 class CAHOnScanDataStart
: public IActionHandler
2196 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2198 nlinfo("CAHOnScanDataStart called");
2200 LoginSM
.pushEvent(CLoginStateMachine::ev_data_scan
);
2204 REGISTER_ACTION_HANDLER (CAHOnScanDataStart
, "on_scan_data_start");
2206 // ***************************************************************************
2207 // Called when the user cancel the scan
2208 class CAHOnScanDataClose
: public IActionHandler
2210 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2212 nlinfo("CAHOnScanDataClose called");
2213 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2214 CPatchManager
*pPM
= CPatchManager::getInstance();
2216 // if the scan is still running
2217 if(NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->getValue32()!=0)
2219 // request to stop the thread
2220 pPM
->askForStopScanDataThread();
2223 setDataScanState(CI18N::get("uiCancelingScanData"));
2227 LoginSM
.pushEvent(CLoginStateMachine::ev_close_data_scan
);
2228 // Come Back to Login Screen.
2229 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
2231 // // Give focus to password if some login entered
2233 // CGroupEditBox *pGEB = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN));
2235 // loginEB= pGEB->getInputStringAsStdString();
2236 // // if none entered
2237 // if (loginEB.empty())
2238 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_LOGIN "|select_all=false");
2240 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_PASSWORD "|select_all=false");
2244 REGISTER_ACTION_HANDLER (CAHOnScanDataClose
, "on_scan_data_close");
2246 // ***************************************************************************
2248 inline string
parseTooltip(const string
& initString
, const string
& tagName
)
2252 string::size_type tooltipPos
= initString
.find(tagName
);
2253 if(tooltipPos
!= string::npos
)
2255 tooltip
= initString
.substr(tooltipPos
);
2258 tooltip
= tooltip
.substr(tooltip
.find(">")+1);
2261 tooltip
= tooltip
.substr(0, tooltip
.find("<"));
2267 inline string
parseCommentError(const string
& initString
, const string
& tagName
)
2271 string::size_type errorPos
= initString
.find(tagName
);
2272 if(errorPos
!= string::npos
)
2274 error
= initString
.substr(errorPos
);
2277 error
= error
.substr(error
.find(">")+1);
2280 error
= error
.substr(0, error
.find("<"));
2286 bool initCreateAccount()
2288 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2291 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2294 // show "submit interface", hide "login interface"
2295 CInterfaceGroup
* grSubmit
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("submit_gr"));
2297 grSubmit
->setActive(true);
2299 CInterfaceGroup
* grLogin
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("login_gr"));
2301 grLogin
->setActive(false);
2304 std::vector
< std::string
> editBoxes(4);
2305 editBoxes
[0] = "eb_login";
2306 editBoxes
[1] = "eb_password";
2307 editBoxes
[2] = "eb_confirm_password";
2308 editBoxes
[3] = "eb_email";
2310 for(uint i
=0; i
<editBoxes
.size(); i
++)
2312 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId(editBoxes
[i
] + ":eb"));
2314 eb
->setInputString(std::string());
2317 // conditions button
2318 CCtrlBaseButton
* but
= dynamic_cast<CCtrlBaseButton
*>(createAccountUI
->findFromShortId("accept_cond"));
2320 but
->setPushed(true);
2322 // get rules from url
2323 string url
= ClientCfg
.CreateAccountURL
;
2324 CPatchManager
*pPM
= CPatchManager::getInstance();
2326 if (!CurlHttpClient
.connect(url
))
2328 nlwarning("Can't connect");
2332 std::string lang
= ClientCfg
.LanguageCode
;
2333 if(lang
=="wk") lang
= "uk";
2335 CurlHttpClient
.verifyServer(true); // set this to false if you need to connect to the test environment
2337 std::string params
= "language=" + lang
;
2339 if (!LoginCustomParameters
.empty())
2340 params
+= LoginCustomParameters
;
2342 if(!CurlHttpClient
.sendGet(url
, params
, pPM
->isVerboseLog()))
2344 string
errorMessage("Can't send (error code 60)");
2345 errorMessageBox(errorMessage
);
2346 nlwarning(errorMessage
.c_str());
2351 if(!CurlHttpClient
.receive(res
, pPM
->isVerboseLog()))
2353 string
errorMessage("Can't receive (error code 61)");
2354 errorMessageBox(errorMessage
);
2355 nlwarning(errorMessage
.c_str());
2361 string
errorMessage("Empty result (error code 13)");
2362 errorMessageBox(errorMessage
);
2363 nlwarning(errorMessage
.c_str());
2367 CurlHttpClient
.disconnect();
2369 // initialize rules in interface
2370 std::vector
< std::pair
< std::string
, std::string
> > rules(5);
2371 rules
[0] = std::pair
<std::string
, std::string
>("rules_login", "id=tooltip-Username");
2372 rules
[1] = std::pair
<std::string
, std::string
>("rules_password", "id=tooltip-Password");
2373 rules
[2] = std::pair
<std::string
, std::string
>("rules_password_conf", "id=tooltip-ConfirmPass");
2374 rules
[3] = std::pair
<std::string
, std::string
>("rules_email", "id=tooltip-Email");
2375 rules
[4] = std::pair
<std::string
, std::string
>("rules_conditions", "id=tooltip-TaC");
2377 for(uint i
=0; i
<rules
.size(); i
++)
2379 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId(rules
[i
].first
));
2382 string tooltip
= parseTooltip(res
, rules
[i
].second
);
2383 text
->setHardText(tooltip
);
2384 text
->setActive(false);
2389 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("errors_list"));
2392 text
->setHardText(toString(CI18N::get("uiCreateAccountWelcome")));
2393 text
->setColor(CRGBA(255, 255, 255, 255));
2395 CInterfaceGroup
* group
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("erros_txt"));
2398 group
->updateCoords();
2400 CInterfaceGroup
* groupScroll
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("err_back_scrollbar"));
2401 if(groupScroll
) groupScroll
->setActive(group
->getHReal() > group
->getMaxHReal());
2402 CCtrlScroll
* scroll
= dynamic_cast<CCtrlScroll
*>(createAccountUI
->findFromShortId("err_scroll_bar"));
2404 scroll
->setTrackPos(scroll
->getHReal());
2409 CInterfaceGroup
* rulesGr
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("rules_gr"));
2411 rulesGr
->setActive(false);
2413 // must be done after hide rules
2414 CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL
, "target=" CTRL_EDITBOX_CREATEACCOUNT_LOGIN
"|select_all=false");
2418 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CREATE_ACCOUNT
);
2423 // ***************************************************************************
2424 // Called when the user focus one of the edit boxes during the account creation
2425 class CAHCreateAccountRules
: public IActionHandler
2427 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
2429 nlinfo("CAHCreateAccountRules called");
2431 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2432 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2435 CInterfaceGroup
* rulesGr
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("rules_gr"));
2437 rulesGr
->setActive(false);
2439 std::vector
< std::string
> rules(4);
2440 rules
[0] = "rules_login";
2441 rules
[1] = "rules_password";
2442 rules
[2] = "rules_password_conf";
2443 rules
[3] = "rules_email";
2445 for(uint i
=0; i
<rules
.size(); i
++)
2447 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId(rules
[i
]));
2450 text
->setActive(Params
==rules
[i
]);
2451 if(Params
==rules
[i
])
2454 rulesGr
->setActive(!text
->getText().empty());
2461 REGISTER_ACTION_HANDLER (CAHCreateAccountRules
, "create_account_rules");
2463 // ***************************************************************************
2464 // Called when the user choose the account creation
2465 class CAHOnCreateAccount
: public IActionHandler
2467 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2469 nlinfo("CAHOnCreateAccount called");
2471 LoginSM
.pushEvent(CLoginStateMachine::ev_create_account
);
2474 REGISTER_ACTION_HANDLER (CAHOnCreateAccount
, "on_create_account");
2476 // ***************************************************************************
2477 // Called when the user submit the account creation
2478 class CAHOnCreateAccountSubmit
: public IActionHandler
2480 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2482 nlinfo("CAHOnCreateAccountSubmit called");
2484 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2486 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2489 // recover data from UI
2490 std::vector
< std::string
> editBoxes(4);
2491 editBoxes
[0] = "eb_login";
2492 editBoxes
[1] = "eb_password";
2493 editBoxes
[2] = "eb_confirm_password";
2494 editBoxes
[3] = "eb_email";
2495 std::vector
< std::string
> results(4);
2497 for(uint i
=0; i
<editBoxes
.size(); i
++)
2499 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId(editBoxes
[i
] + ":eb"));
2501 results
[i
] = eb
->getInputString();
2505 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("email_adress"));
2507 text
->setHardText(results
[3]);
2509 // conditions button
2510 bool conditionsPushed
= false;
2511 CCtrlBaseButton
* but
= dynamic_cast<CCtrlBaseButton
*>(createAccountUI
->findFromShortId("accept_cond"));
2513 conditionsPushed
= !but
->getPushed();
2515 string url
= ClientCfg
.CreateAccountURL
;
2516 CPatchManager
*pPM
= CPatchManager::getInstance();
2518 if (!CurlHttpClient
.connect(url
))
2520 string
errorMessage("Can't connect");
2521 errorMessageBox(errorMessage
);
2522 nlwarning(errorMessage
.c_str());
2526 std::string params
= "Username=" + results
[0] + "&Password=" + results
[1]
2527 + "&ConfirmPass=" + results
[2] + "&Email=" + results
[3];
2529 if(conditionsPushed
)
2532 if (!LoginCustomParameters
.empty())
2533 params
+= LoginCustomParameters
;
2535 std::string md5
= results
[0] + results
[1] + "" + results
[3];
2536 md5
= NLMISC::getMD5((uint8
*)md5
.data(), (uint32
)md5
.size()).toString();
2538 params
+= "&SC=" + md5
;
2539 std::string lang
= ClientCfg
.LanguageCode
;
2540 if(lang
=="wk") lang
= "uk";
2541 params
+= "&Language=" + lang
;
2543 CurlHttpClient
.verifyServer(true); // set this to false if you need to connect to the test environment
2545 if(!CurlHttpClient
.sendPost(url
, params
, pPM
->isVerboseLog()))
2547 string
errorMessage("Can't send (error code 60)");
2548 errorMessageBox(errorMessage
);
2549 nlwarning(errorMessage
.c_str());
2554 if(!CurlHttpClient
.receive(res
, pPM
->isVerboseLog()))
2556 string
errorMessage("Can't receive (error code 61)");
2557 errorMessageBox(errorMessage
);
2558 nlwarning(errorMessage
.c_str());
2564 string
errorMessage("Empty result (error code 13)");
2565 errorMessageBox(errorMessage
);
2566 nlwarning(errorMessage
.c_str());
2570 CurlHttpClient
.disconnect();
2573 string::size_type okPos
= res
.find("email_sent");
2574 if(okPos
!= string::npos
)
2576 // show "submit interface", hide "login interface"
2577 CInterfaceGroup
* grSubmit
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("submit_gr"));
2579 grSubmit
->setActive(false);
2581 CInterfaceGroup
* grLogin
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("login_gr"));
2583 grLogin
->setActive(true);
2587 // initialize error comments in interface
2588 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("errors_list"));
2591 text
->setColor(CRGBA(250, 30, 30, 255));
2593 std::vector
< std::string
> errors(5);
2594 errors
[0] = "id=\"comment-Username\"";
2595 errors
[1] = "id=\"comment-Password\"";
2596 errors
[2] = "id=\"comment-ConfirmPass\"";
2597 errors
[3] = "id=\"comment-Email\"";
2598 errors
[4] = "id=\"comment-TaC\"";
2601 for(uint i
=0; i
<errors
.size(); i
++)
2603 string comment
= parseCommentError(res
, errors
[i
]);
2604 if(!comment
.empty())
2605 error
+= "- " + comment
+ "\n";
2608 text
->setHardText(error
);
2610 CInterfaceGroup
* group
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("erros_txt"));
2613 group
->updateCoords();
2615 CInterfaceGroup
* groupScroll
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("err_back_scrollbar"));
2616 if(groupScroll
) groupScroll
->setActive(group
->getHReal() > group
->getMaxHReal());
2617 CCtrlScroll
* scroll
= dynamic_cast<CCtrlScroll
*>(createAccountUI
->findFromShortId("err_scroll_bar"));
2619 scroll
->setTrackPos(scroll
->getHReal());
2626 REGISTER_ACTION_HANDLER (CAHOnCreateAccountSubmit
, "on_create_account_submit");
2628 // ***************************************************************************
2629 // Called when the user cancel the account creation
2630 class CAHOnCreateAccountClose
: public IActionHandler
2632 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2634 nlinfo("CAHOnCreateAccountClose called");
2636 LoginSM
.pushEvent(CLoginStateMachine::ev_close_create_account
);
2639 REGISTER_ACTION_HANDLER (CAHOnCreateAccountClose
, "on_create_account_close");
2641 // ***************************************************************************
2642 class CAHCreateAccountLogin
: public IActionHandler
2644 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2646 nlinfo("CAHCreateAccountLogin called");
2648 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2650 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2653 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId("eb_login:eb"));
2655 LoginLogin
= eb
->getInputString();
2657 eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId("eb_password:eb"));
2659 LoginPassword
= eb
->getInputString();
2665 REGISTER_ACTION_HANDLER (CAHCreateAccountLogin
, "create_account_login");
2667 // ***************************************************************************
2668 // Called by html embeded lua script
2669 class CAHOnConnectToShard
: public IActionHandler
2671 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
2673 // warning : pCaller is null when event come from lua scrip embeded in HTML
2674 Cookie
= getParam(Params
, "cookie");
2675 FSAddr
= getParam(Params
, "fsAddr");
2677 // replace the '_' with '|' in the cookie string
2678 for (uint i
=0; i
<Cookie
.size(); ++i
)
2680 if (Cookie
[i
] == '_')
2684 setLoginFinished( true );
2687 LoginSM
.pushEvent(CLoginStateMachine::ev_connect
);
2690 REGISTER_ACTION_HANDLER (CAHOnConnectToShard
, "on_connect_to_shard");
2692 // ***************************************************************************
2693 // Called to return to login screen in case of error
2694 class CAHOnBackToLogin
: public IActionHandler
2696 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2698 setLoginFinished( false );
2700 LoginSM
.pushEvent(CLoginStateMachine::ev_relog
);
2702 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
2703 // // need to reset password and current screen
2704 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
2707 REGISTER_ACTION_HANDLER (CAHOnBackToLogin
, "on_back_to_login");
2709 // ***************************************************************************
2710 // ***************************************************************************
2711 // ***************************************************************************
2712 // NETWORK CONNECTION
2713 // ***************************************************************************
2714 // ***************************************************************************
2715 // ***************************************************************************
2718 // ***************************************************************************
2719 string
checkLogin(const string
&login
, const string
&password
, const string
&clientApp
, const std::string
&customParameters
)
2721 CPatchManager
*pPM
= CPatchManager::getInstance();
2724 if(ClientCfg
.ConfigFile
.exists("VerboseLog"))
2725 pPM
->setVerboseLog(ClientCfg
.ConfigFile
.getVar("VerboseLog").asInt() == 1);
2726 if(pPM
->isVerboseLog()) nlinfo("Using verbose log mode");
2728 if(!HttpClient
.connectToLogin())
2729 return "Can't connect (error code 1)";
2731 if(pPM
->isVerboseLog()) nlinfo("Connected");
2735 std::string url
= ClientCfg
.ConfigFile
.getVar("StartupHost").asString() + ClientCfg
.ConfigFile
.getVar("StartupPage").asString();
2737 // don't use login with alt method
2740 // ask server for salt
2741 if(!HttpClient
.sendGet(url
+ "?cmd=ask&cp=2&login=" + login
+ "&lg=" + ClientCfg
.LanguageCode
, "", pPM
->isVerboseLog()))
2742 return std::string("Can't send (error code 60) ") + HttpClient
.lastError();
2744 if(pPM
->isVerboseLog()) nlinfo("Sent request for password salt");
2746 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2747 return "Can't receive (error code 61)";
2749 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2752 return "Empty answer from server (error code 62)";
2754 size_t first
= res
.find("\n\n");
2755 if (first
== std::string::npos
)
2757 first
= res
.find("\r\r");
2758 if (first
== std::string::npos
)
2760 first
= res
.find("\r\n\r\n");
2761 if (first
!= std::string::npos
)
2763 res
= res
.substr(first
+ 4);
2768 res
= res
.substr(first
+ 2);
2773 res
= res
.substr(first
+ 2);
2776 nldebug("res1: %s", res
.c_str());
2780 nlwarning("missing response body: %s", res
.c_str());
2781 return "missing response body (error code 64)";
2783 else if(res
[0] == '0')
2785 // server returns an error
2786 nlwarning("server error: %s", res
.substr(2).c_str());
2787 return res
.substr(2);
2789 else if(res
[0] == '1')
2791 Salt
= res
.substr(2);
2795 // server returns ???
2796 nlwarning("%s", res
.c_str());
2800 // send login + crypted password + client app and cp=2 (as crypted password)
2801 if(!HttpClient
.connectToLogin())
2802 return "Can't connect (error code 63)";
2804 if(pPM
->isVerboseLog()) nlinfo("Connected");
2807 if (ClientCfg
.R2Mode
)
2809 // R2 login sequence
2813 std::string cryptedPassword
= CCrypt::crypt(password
, Salt
);
2815 if(!HttpClient
.sendGet(url
+ "?cmd=login&login=" + login
+ "&password=" + cryptedPassword
+ "&clientApplication=" + clientApp
+ "&cp=2" + "&lg=" + ClientCfg
.LanguageCode
+ customParameters
))
2816 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2820 // don't send login and password if empty
2821 if(!HttpClient
.sendGet(url
+ "?cmd=login&clientApplication=" + clientApp
+ "&cp=2" + "&lg=" + ClientCfg
.LanguageCode
+ customParameters
))
2822 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2825 // the response should contains the result code and the cookie value
2826 if(pPM
->isVerboseLog()) nlinfo("Sent request login check");
2828 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2829 return "Can't receive (error code 3)";
2831 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2834 return "Empty answer from server (error code 4)";
2836 size_t first
= res
.find("\n\n");
2837 if (first
== std::string::npos
)
2839 first
= res
.find("\r\r");
2840 if (first
== std::string::npos
)
2842 first
= res
.find("\r\n\r\n");
2843 if (first
!= std::string::npos
)
2845 res
= res
.substr(first
+ 4);
2850 res
= res
.substr(first
+ 2);
2855 res
= res
.substr(first
+ 2);
2858 nldebug("res2: %s", res
.c_str());
2862 nlwarning("missing response body: %s", res
.c_str());
2863 return "missing response body (error code 65)";
2865 else if(res
[0] == '0')
2867 // server returns an error
2868 nlwarning("server error: %s", res
.substr(2).c_str());
2869 return res
.substr(2);
2871 else if(res
[0] == '1')
2873 //nlwarning(res.c_str());
2874 vector
<string
> lines
;
2875 explode(res
, std::string("\n"), lines
, false);
2876 if (lines
.size() != 2)
2878 return toString("Invalid server return, found %u lines, want 2", lines
.size());
2881 vector
<string
> parts
;
2882 explode(lines
[0], std::string("#"), parts
, false);
2883 if (parts
.size() < 5)
2884 return "Invalid server return, missing cookie and/or Ring URLs";
2886 // server returns ok, we have the cookie
2888 // store the cookie value and FS address for next page request
2889 CurrentCookie
= parts
[1];
2890 Cookie
= CurrentCookie
;
2893 // store the ring startup page
2894 RingMainURL
= parts
[3];
2895 FarTP
.setURLBase(parts
[4]);
2897 if(parts
.size() >= 6 && parts
[5] == "1")
2900 extern bool startStat
;
2904 // parse the second line (contains the domain info)
2906 explode(lines
[1], std::string("#"), parts
, false);
2907 if (parts
.size() < 3)
2908 return "Invalid server return, missing patch URLs";
2910 R2ServerVersion
= parts
[0].c_str();
2911 R2BackupPatchURL
= parts
[1];
2912 explode(parts
[2], std::string(" "), R2PatchURLs
, true);
2916 // unexpected content
2918 string ret
= toString("DEV : Invalid server return, missing return code in \n%s", res
.c_str());
2921 return "Invalid server return, missing return code";
2928 // standard ryzom login sequence
2929 std::string cryptedPassword
= CCrypt::crypt(password
, Salt
);
2931 if(!HttpClient
.sendGet(url
+ "?login=" + login
+ "&password=" + cryptedPassword
+ "&clientApplication=" + clientApp
+ "&cp=2"))
2932 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2934 if(!send(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
2935 return "Can't send (error code 2)";
2937 if(pPM
->isVerboseLog()) nlinfo("Sent request login check");
2939 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2940 return "Can't receive (error code 3)";
2942 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2945 return "Empty answer from server (error code 4)";
2947 size_t first
= res
.find("\n\n");
2948 if (first
== std::string::npos
)
2950 first
= res
.find("\r\r");
2951 if (first
== std::string::npos
)
2953 first
= res
.find("\r\n\r\n");
2954 if (first
!= std::string::npos
)
2956 res
= res
.substr(first
+ 4);
2961 res
= res
.substr(first
+ 2);
2966 res
= res
.substr(first
+ 2);
2969 nldebug("res2: %s", res
.c_str());
2973 nlwarning("missing response body: %s", res
.c_str());
2974 return "missing response body (error code 66)";
2976 else if(res
[0] == '0')
2978 // server returns an error
2979 nlwarning("server error: %s", res
.substr(2).c_str());
2980 return res
.substr(2);
2982 else if(res
[0] == '1')
2984 // server returns ok, we have the list of shard
2986 fromString(res
.substr(2), nbs
);
2987 vector
<string
> lines
;
2989 explode(res
, std::string("\n"), lines
, true);
2991 if(pPM
->isVerboseLog())
2993 nlinfo ("Exploded, with nl, %u res", (uint
)lines
.size());
2994 /* for (uint i = 0; i < lines.size(); i++)
2996 nlinfo (" > '%s'", lines[i].c_str());
3000 if(lines
.size() != nbs
+1)
3002 nlwarning("bad shard lines number %u != %d", (uint
)lines
.size(), nbs
+1);
3003 nlwarning("'%s'", res
.c_str());
3004 return "bad lines numbers (error code 5)";
3007 for(uint i
= 1; i
< lines
.size(); i
++)
3010 explode(lines
[i
], std::string("|"), res
);
3012 if(pPM
->isVerboseLog())
3014 nlinfo ("Exploded with '%s', %u res", "|", (uint
)res
.size());
3015 /* for (uint i = 0; i < res.size(); i++)
3017 nlinfo (" > '%s'", res[i].c_str());
3021 if (res
.size() < 7 && res
.size() > 8)
3023 nlwarning("bad | numbers %u != %d", (uint
)res
.size(), 8);
3024 nlwarning("'%s'", lines
[i
].c_str());
3025 return "bad pipe numbers (error code 6)";
3028 fromString(res
[1], online
);
3030 fromString(res
[2], shardId
);
3032 fromString(res
[4], nbPlayers
);
3033 Shards
.push_back(CShard(res
[0], online
, shardId
, res
[3], nbPlayers
, res
[5], res
[6]));
3034 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());
3035 if (res
.size() == 8)
3037 explode(res
[7], std::string(" "), Shards
.back().PatchURIs
);
3043 // server returns ???
3044 nlwarning("%s", res
.c_str());
3052 // ***************************************************************************
3053 string
selectShard(uint32 shardId
, string
&cookie
, string
&addr
)
3058 if(!HttpClient
.connectToLogin()) return "Can't connect (error code 7)";
3060 if(LoginLogin
.empty()) return "Empty Login (error code 8)";
3061 if(LoginPassword
.empty()) return "Empty Password (error code 9)";
3062 if(ClientApp
.empty()) return "Empty Client Application (error code 10)";
3064 // send login + crypted password + client app and cp=2 (as crypted password)
3065 std::string cryptedPassword
= CCrypt::crypt(LoginPassword
, Salt
);
3067 std::string url
= ClientCfg
.ConfigFile
.getVar("StartupHost").asString() + ClientCfg
.ConfigFile
.getVar("StartupPage").asString();
3069 if(!HttpClient
.sendGet(url
+ "?cmd=login&shardid=" + toString(shardId
) + "&login=" + LoginLogin
+ "&password=" + cryptedPassword
+ "&clientApplication=" + ClientApp
+ "&cp=2"))
3070 return "Can't send (error code 11)";
3074 CPatchManager
*pPM
= CPatchManager::getInstance();
3075 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
3076 return "Can't receive (error code 12)";
3079 return "Empty result (error code 13)";
3081 size_t first
= res
.find("\n\n");
3082 if (first
== std::string::npos
)
3084 first
= res
.find("\r\r");
3085 if (first
== std::string::npos
)
3087 first
= res
.find("\r\n\r\n");
3088 if (first
!= std::string::npos
)
3090 res
= res
.substr(first
+ 4);
3095 res
= res
.substr(first
+ 2);
3100 res
= res
.substr(first
+ 2);
3103 nldebug("res2: %s", res
.c_str());
3107 nlwarning("missing response body: %s", res
.c_str());
3108 return "missing response body (error code 66)";
3110 else if(res
[0] == '0')
3112 // server returns an error
3113 nlwarning("server error: %s", res
.substr(2).c_str());
3114 return res
.substr(2);
3116 else if(res
[0] == '1')
3118 // server returns ok, we have the access
3120 vector
<string
> line
;
3121 explode(res
, std::string(" "), line
, true);
3123 if (line
.size() < 2 || line
.size() > 3)
3125 nlwarning("bad launch lines number %d != %d", line
.size(), 2);
3126 return "bad launch line number (error code 14)";
3129 cookie
= line
[0].substr(2);
3132 std::vector
<std::string
> patchURIs
;
3134 CShard
* shard
= NULL
;
3136 for (i
=0; i
<Shards
.size(); ++i
)
3138 if (Shards
[i
].ShardId
== shardId
)
3145 if (shard != NULL && line.size() >= 3)
3147 explode(line[2], "|", shard->PatchURIs, true);
3149 nlinfo("received %d main patch server URIs:", shard->PatchURIs.size());
3151 for (i=0; i<shard->PatchURIs.size(); ++i)
3152 nlinfo("%d: '%s'", i, shard->PatchURIs[i].c_str());
3158 // server returns ???
3159 nlwarning("%s", res
.c_str());
3167 /*void mainLandPatch()
3169 if (!AvailablePatchs) return;
3170 nlassert(AvailablePatchs & (1 << BGDownloader::DownloadID_MainLand)); // only handled case for now
3172 BGDownloaderWantedPatch = BGDownloader::DownloadID_MainLand;
3173 CInterfaceManager *im = CInterfaceManager::getInstance();
3175 // login machine should be in the 'end' state !!
3176 nlassert(LoginSM.getCurrentState() == CLoginStateMachine::st_end);
3177 LoginSM.pushEvent(CLoginStateMachine::ev_mainland_patch);
3178 loginMainLoop(); // patch is handled in the login mainloop
3179 // there should have been a reboot there, so quit if something went wrong...
3187 // ***************************************************************************
3188 // ***************************************************************************
3190 // ***************************************************************************
3191 // ***************************************************************************
3193 #include "init_main_loop.h"
3195 bool loginIntroSkip
;
3199 // Display of nevrax logo is done at init time (see init.cpp) just before addSearchPath (second one)
3200 for (uint i
= 0; i
< 1; i
++) // previously display nevrax then nvidia
3204 beginLoading(IntroNVidia
);
3206 ProgressBar
.newMessage (nmsg
);
3209 Driver
->AsyncListener
.reset();
3211 CInputHandlerManager::getInstance()->pumpEventsNoIM();
3214 loginIntroSkip
= false;
3216 sint64 CurTime
= T0
;
3218 while (loginIntroSkip
== false)
3221 if ((T0
- CurTime
) > 5000) // 5s before quiting
3224 CInputHandlerManager::getInstance()->pumpEventsNoIM();
3227 if (Driver
->AsyncListener
.isKeyPushed (KeyESCAPE
) || Driver
->AsyncListener
.isKeyPushed (KeyRETURN
) ||
3228 Driver
->AsyncListener
.isKeyPushed (KeySPACE
))
3231 const string
nmsg("");
3232 ProgressBar
.newMessage (nmsg
);
3233 IngameDbMngr
.flushObserverCalls();
3234 NLGUI::CDBManager::getInstance()->flushObserverCalls();
3237 beginLoading(StartBackground
);
3238 ProgressBar
.finish();