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 return connect(ClientCfg
.ConfigFile
.getVar("StartupHost").asString(0))
165 && verifyServer(ClientCfg
.ConfigFile
.getVar("StartupVerify").asBool(0));
168 CStartupHttpClient HttpClient
;
169 #endif // RY_BG_DOWNLOADER
172 // ***************************************************************************
173 #define WIN_COMBO_BOX_SELECT_MENU "ui:interface:combo_box_select_menu"
174 #define WIN_COMBO_BOX_MEASURE_MENU "ui:interface:combo_box_measure_menu"
175 #define WIN_COMBO_BOX_SELECT_MENU_OUTGAME "ui:outgame:combo_box_select_menu"
176 #define WIN_COMBO_BOX_SELECT_MENU_LOGIN "ui:login:combo_box_select_menu"
177 #define WIN_COMBO_BOX_MEASURE_MENU_LOGIN "ui:login:combo_box_measure_menu"
179 bool isLoginFinished()
181 return loginFinished
;
184 void setLoginFinished( bool f
)
189 CDBGroupComboBox::measureMenu
.assign( WIN_COMBO_BOX_MEASURE_MENU
);
190 CDBGroupComboBox::selectMenu
.assign( WIN_COMBO_BOX_SELECT_MENU
);
194 CDBGroupComboBox::measureMenu
.assign( WIN_COMBO_BOX_MEASURE_MENU_LOGIN
);
195 CDBGroupComboBox::selectMenu
.assign( WIN_COMBO_BOX_SELECT_MENU_LOGIN
);
200 // ***************************************************************************
201 // Pop a fatal error message box, giving the option to 'quit' the client, plus a help button
202 static void fatalMessageBox(const std::string
&msg
)
204 CInterfaceManager
*im
= CInterfaceManager::getInstance();
205 im
->messageBoxWithHelp(msg
, "ui:login", "login_quit");
208 // ***************************************************************************
209 // Pop an error message box, giving the option to go back to main menu, plus a help button
210 static void errorMessageBox(const std::string
&msg
)
212 CInterfaceManager
*im
= CInterfaceManager::getInstance();
213 im
->messageBoxWithHelp(msg
, "ui:login", "on_back_to_login");
216 // ***************************************************************************
217 void createOptionalCatUI()
219 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
220 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT
));
223 nlwarning("element " GROUP_LIST_CAT
" not found probably bad login_main.xml");
227 // Update optional categories
229 CInterfaceGroup
*pPrevLine
= NULL
;
230 for(uint i
= 0; i
< InfoOnPatch
.OptCat
.size(); i
++)
232 vector
< pair
< string
, string
> > params
;
234 params
.push_back(pair
<string
,string
>("id", "c"+toString(i
)));
236 params
.push_back(pair
<string
,string
>("posref", "BL TL"));
238 CInterfaceGroup
*pNewLine
= CWidgetManager::getInstance()->getParser()->createGroupInstance("t_cat", GROUP_LIST_CAT
, params
);
239 if (pNewLine
!= NULL
)
241 CViewText
*pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("name"));
242 if (pVT
!= NULL
) pVT
->setText(InfoOnPatch
.OptCat
[i
].Name
);
243 pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("size"));
246 pVT
->setText(BGDownloader::getWrittenSize(InfoOnPatch
.OptCat
[i
].Size
));
250 pNewLine
->setParent(pList
);
251 pNewLine
->setParentSize(pList
);
252 pNewLine
->setParentPos(pPrevLine
);
253 pList
->addGroup(pNewLine
);
255 pPrevLine
= pNewLine
;
258 pList
->invalidateCoords();
261 // ***************************************************************************
264 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
265 if (!ClientCfg
.SkipEULA
&& CFile::fileExists(getLogDirectory() + "show_eula"))
267 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_EULA
);
269 // if we display the eula, it means we make a patch so we clean the cache directory
270 // (clear cache after each patch)
271 nlinfo("Deleting cached files");
272 vector
<string
> cached
;
273 CPath::getPathContent("cache", true, false, true, cached
);
274 for(uint i
= 0; i
< cached
.size(); i
++)
275 CFile::deleteFile(cached
[i
]);
279 CAHManager::getInstance()->runActionHandler("accept_eula", NULL
);
283 // ***************************************************************************
284 static void setDataScanLog(const std::string
&text
)
286 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
287 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:datascan:content:log_txt:log"));
294 // ***************************************************************************
295 static void setDataScanState(const std::string
&text
, const std::string
&progress
= string())
297 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
298 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:datascan:content:state"));
299 if (pVT
!= NULL
) pVT
->setText(text
);
301 pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:datascan:content:progress"));
302 if (pVT
!= NULL
) pVT
->setText(progress
);
305 void initCatDisplay()
307 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
308 CPatchManager
*pPM
= CPatchManager::getInstance();
310 // Check is good now ask the player if he wants to apply the patch
311 pPM
->getInfoToDisp(InfoOnPatch
);
313 if ((!InfoOnPatch
.NonOptCat
.empty()) ||
314 (!InfoOnPatch
.OptCat
.empty()) ||
315 (!InfoOnPatch
.ReqCat
.empty()))
317 createOptionalCatUI();
318 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CATDISP
);
322 LoginSM
.pushEvent(CLoginStateMachine::ev_run_patch
);
323 // CAHManager::getInstance()->runActionHandler("login_patch", NULL);
329 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
330 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_REBOOT
);
334 // ***************************************************************************
335 static void setPatcherStateText(const std::string
&baseUIPath
, const std::string
&str
)
337 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
338 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(baseUIPath
+ ":content:state"));
345 // ***************************************************************************
346 static void setPatcherProgressText(const std::string
&baseUIPath
, const std::string
&str
)
348 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
349 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(baseUIPath
+ ":content:progress"));
356 // ***************************************************************************
357 static void updatePatchingInfoText(const std::string
&baseUIPath
)
359 CPatchManager
*pPM
= CPatchManager::getInstance();
360 #ifdef RYZOM_BG_DOWNLOADER
361 CBGDownloaderAccess
&bgDownloader
= CBGDownloaderAccess::getInstance();
362 if (isBGDownloadEnabled())
364 bgDownloader
.update();
365 if (bgDownloader
.getDownloadThreadPriority() == BGDownloader::ThreadPriority_Paused
)
367 setPatcherStateText(baseUIPath
, CI18N::get("uiBGD_Paused"));
368 setPatcherProgressText(baseUIPath
, string());
372 setPatcherStateText(baseUIPath
, bgDownloader
.getCurrentMessage());
373 if (bgDownloader
.getTotalFilesToGet() != 0)
375 setPatcherProgressText(baseUIPath
, toString("%d/%d", (int) bgDownloader
.getCurrentFilesToGet(), (int) bgDownloader
.getTotalFilesToGet()));
379 setPatcherProgressText(baseUIPath
, string());
388 if(pPM
->getThreadState(state
, log
))
390 setPatcherStateText(baseUIPath
, state
);
391 if (pPM
->getTotalFilesToGet() != 0)
393 setPatcherProgressText(baseUIPath
, toString("%d/%d", pPM
->getCurrentFilesToGet(), pPM
->getTotalFilesToGet()));
397 setPatcherProgressText(baseUIPath
, string());
403 // ***************************************************************************
404 // Main loop of the login step
407 CDBGroupComboBox::selectMenuOut
.assign( WIN_COMBO_BOX_SELECT_MENU_OUTGAME
);
408 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
409 CPatchManager
*pPM
= CPatchManager::getInstance();
411 #ifdef RYZOM_BG_DOWNLOADER
412 CBGDownloaderAccess
&bgDownloader
= CBGDownloaderAccess::getInstance();
415 bool windowBlinkDone
= false;
416 bool fatalMessageBoxShown
= false;
418 while (LoginSM
.getCurrentState() != CLoginStateMachine::st_connect
419 && LoginSM
.getCurrentState() != CLoginStateMachine::st_end
420 && LoginSM
.getCurrentState() != CLoginStateMachine::st_ingame
)
421 // while (loginFinished == false)
423 IngameDbMngr
.flushObserverCalls();
424 NLGUI::CDBManager::getInstance()->flushObserverCalls();
426 // Update the DT T0 and T1 global variables
431 CInputHandlerManager::getInstance()->pumpEvents();
432 Driver
->clearBuffers(CRGBA::Black
);
433 Driver
->setMatrixMode2D11();
436 if (SoundMngr
!= NULL
)
439 // Interface handling & displaying
440 pIM
->updateFrameEvents();
441 pIM
->updateFrameViews(NULL
);
442 IngameDbMngr
.flushObserverCalls();
443 NLGUI::CDBManager::getInstance()->flushObserverCalls();
447 // if (::GetAsyncKeyState(VK_SPACE))
449 // pIM->displayUIViewBBoxs("");
450 // pIM->displayUICtrlBBoxs("");
451 // pIM->displayUIGroupBBoxs("");
454 // Force the client to sleep a bit.
455 if(ClientCfg
.Sleep
>= 0)
457 nlSleep(ClientCfg
.Sleep
);
460 Driver
->swapBuffers();
462 // sint32 screen = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->getValue32();
463 if (LoginSM
.getCurrentState() == CLoginStateMachine::st_check_patch
)
464 // if (screen == UI_VARIABLES_SCREEN_CHECKING) // If we are in checking mode
466 nlSleep(10); // For the checking thread
468 BGDownloader::TTaskResult taskResult
= BGDownloader::TaskResult_Unknown
;
469 bool finished
= false;
470 #ifdef RYZOM_BG_DOWNLOADER
471 string bgDownloaderError
;
472 if (isBGDownloadEnabled())
474 finished
= bgDownloader
.isTaskEnded(taskResult
, bgDownloaderError
);
479 finished
= pPM
->isCheckThreadEnded(res
);
484 setPatcherStateText("ui:login:checking", string());
485 setPatcherProgressText("ui:login:checking", string());
487 #ifdef RYZOM_BG_DOWNLOADER
488 if (isBGDownloadEnabled())
490 AvailablePatchs
= bgDownloader
.getAvailablePatchs();
494 HWND hWnd
= Driver
->getDisplay();
496 // Show the window, unless it has been minimized, in
497 // which case we don't pop it unexpectedly
498 if (!windowBlinkDone
)
500 bgDownloader
.hideDownloader();
501 ShowWindow (hWnd
, SW_RESTORE
);
502 windowBlinkDone
= true;
509 case BGDownloader::TaskResult_Success
:
510 if (AvailablePatchs
& (1 << BGDownloaderWantedPatch
)) // is there a patch for what we want now ?
512 LoginSM
.pushEvent(CLoginStateMachine::ev_patch_needed
);
516 LoginSM
.pushEvent(CLoginStateMachine::ev_no_patch
);
519 case BGDownloader::TaskResult_Error
:
521 if (!fatalMessageBoxShown
)
523 fatalMessageBox(bgDownloaderError
);
524 fatalMessageBoxShown
= true;
529 if (!fatalMessageBoxShown
)
531 fatalMessageBox(CI18N::get("uiErrChecking"));
532 fatalMessageBoxShown
= true;
543 // Check is good now ask the player if he wants to apply the patch
544 pPM
->getInfoToDisp(InfoOnPatch
);
546 AvailablePatchs
= InfoOnPatch
.getAvailablePatchsBitfield();
548 if ((!InfoOnPatch
.NonOptCat
.empty()) ||
549 (!InfoOnPatch
.OptCat
.empty()) ||
550 (!InfoOnPatch
.ReqCat
.empty()))
552 LoginSM
.pushEvent(CLoginStateMachine::ev_patch_needed
);
553 // createOptionalCatUI();
554 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CATDISP);
558 LoginSM
.pushEvent(CLoginStateMachine::ev_no_patch
);
559 // CAHManager::getInstance()->runActionHandler("login_patch", NULL);
564 string errMsg
= CI18N::get("uiErrChecking");
565 if (!pPM
->getLastErrorMessage().empty())
567 errMsg
= pPM
->getLastErrorMessage();
569 if (!fatalMessageBoxShown
)
571 fatalMessageBox(errMsg
);
572 fatalMessageBoxShown
= true;
579 // update interface content
580 updatePatchingInfoText("ui:login:checking");
583 // else if (screen == UI_VARIABLES_SCREEN_DATASCAN) // If we are in ScanData mode
584 else if (LoginSM
.getCurrentState() == CLoginStateMachine::st_scan_data
)
586 nlSleep(10); // For the checking thread
589 if (pPM
->isScanDataThreadEnded(res
))
591 // if interface consider it was running before
592 if(NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->getValue32()!=0)
595 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->setValue32(0);
599 // touch any file with checksum error, and get their number
600 uint numFiles
= pPM
->applyScanDataResult();
604 setDataScanState(CI18N::get("uiScanDataSucess"));
607 string fmt
= CI18N::get("uiScanDataErrors");
608 strFindReplace(fmt
, "%d", toString(numFiles
));
609 setDataScanState(fmt
);
614 string errMsg
= CI18N::get("uiErrDataScanning");
615 if (!pPM
->getLastErrorMessage().empty())
617 errMsg
= pPM
->getLastErrorMessage();
619 pIM
->messageBoxWithHelp(errMsg
, "ui:login");
622 // the log may have changed
624 if(pPM
->getDataScanLog(dsLog
))
625 setDataScanLog(dsLog
);
630 // update inteface content
634 if(pPM
->getThreadState(state
, log
))
637 setDataScanState(state
, toString("%d/%d", pPM
->getCurrentFilesToGet(), pPM
->getTotalFilesToGet()));
639 // set special data scan log
641 if(pPM
->getDataScanLog(dsLog
))
642 setDataScanLog(dsLog
);
645 // else if (screen == UI_VARIABLES_SCREEN_PATCHING) // If we are in patching mode
646 else if (LoginSM
.getCurrentState() == CLoginStateMachine::st_patch
)
648 nlSleep(30); // For the patching thread
650 int currentPatchingSize
;
653 #ifdef RYZOM_BG_DOWNLOADER
654 if (isBGDownloadEnabled())
656 currentPatchingSize
= bgDownloader
.getPatchingSize();
657 totalPatchSize
= bgDownloader
.getTotalSize();
658 BGDownloader::TTaskResult taskResult
;
659 bool finished
= false;
660 string bgDownloaderError
;
661 finished
= bgDownloader
.isTaskEnded(taskResult
, bgDownloaderError
);
664 //bgDownloader.hideDownloader();
665 // restore the search paths (all bnp files were removed from CPath to allows
666 // the patcher to overwrite them)
668 // create a file to prompt eula next time
669 CFile::createEmptyFile(getLogDirectory() + "show_eula");
671 if (taskResult
== BGDownloader::TaskResult_Error
)
673 setPatcherStateText("ui:login:patching", string());
674 setPatcherProgressText("ui:login:patching", string());
676 if (!fatalMessageBoxShown
)
678 fatalMessageBox(bgDownloaderError
);
679 fatalMessageBoxShown
= true;
684 bgDownloader
.getPatchCompletionFlag(true /* clear flag */);
685 LoginSM
.pushEvent(CLoginStateMachine::ev_close_patch
);
690 updatePatchingInfoText("ui:login:patching");
696 totalPatchSize
= TotalPatchSize
;
697 currentPatchingSize
= pPM
->getPatchingSize();
699 if (pPM
->isPatchThreadEnded(res
))
703 LoginSM
.pushEvent(CLoginStateMachine::ev_close_patch
);
707 string errMsg
= CI18N::get("uiErrPatchApply");
708 if (!pPM
->getLastErrorMessage().empty())
710 errMsg
= pPM
->getLastErrorMessage();
712 if (!fatalMessageBoxShown
)
714 fatalMessageBox(errMsg
);
715 fatalMessageBoxShown
= true;
721 updatePatchingInfoText("ui:login:patching");
725 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(VIEW_TOTAL_SIZE_PATCH
));
727 sTmp
= BGDownloader::getWrittenSize(currentPatchingSize
);
728 sTmp
+= " / " + BGDownloader::getWrittenSize(totalPatchSize
);
729 if (pVT
!= NULL
) pVT
->setText(sTmp
);
731 // else if (screen == UI_VARIABLES_SCREEN_CATDISP) // If we are displaying patch info
732 else if (LoginSM
.getCurrentState() == CLoginStateMachine::st_display_cat
)
734 // Non optional stuff (non opt cat and req cat)
736 // Add req cat size : given the optional cat we determines the required cat
737 uint32 nNonOptSize
= 0;
739 vector
<sint32
> ReqCat
;
740 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT
));
743 for(uint i
= 0; i
< InfoOnPatch
.OptCat
.size(); i
++)
745 CInterfaceGroup
*pLine
= pList
->getGroup("c"+toString(i
));
748 CCtrlButton
*pCB
= dynamic_cast<CCtrlButton
*>(pLine
->getCtrl("on_off"));
749 if ((pCB
!= NULL
) && (pCB
->getPushed()))
751 TotalPatchSize
+= InfoOnPatch
.OptCat
[i
].Size
;
752 if (InfoOnPatch
.OptCat
[i
].Req
!= -1)
755 for (j
= 0; j
< ReqCat
.size(); ++j
)
756 if (ReqCat
[j
] == InfoOnPatch
.OptCat
[i
].Req
)
758 // Add just once the req cat size to the non optional size
759 if (j
== ReqCat
.size())
761 ReqCat
.push_back(InfoOnPatch
.OptCat
[i
].Req
);
762 nNonOptSize
+= InfoOnPatch
.ReqCat
[InfoOnPatch
.OptCat
[i
].Req
].Size
;
770 // Add non optional cats
771 for (uint32 i
= 0; i
< InfoOnPatch
.NonOptCat
.size(); ++i
)
772 nNonOptSize
+= InfoOnPatch
.NonOptCat
[i
].Size
;
774 TotalPatchSize
+= nNonOptSize
;
775 // Total size of the patches is optional cats + required cat (f(optCat)) + non opt cat
777 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(VIEW_TOTAL_SIZE
));
778 if (pVT
!= NULL
) pVT
->setText(BGDownloader::getWrittenSize(TotalPatchSize
));
780 pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId(VIEW_NON_OPTIONAL_SIZE
));
781 if (pVT
!= NULL
) pVT
->setText(BGDownloader::getWrittenSize(nNonOptSize
));
786 void initLoginScreen()
788 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
789 CPatchManager
*pPM
= CPatchManager::getInstance();
790 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS
);
791 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DISPLAY_ACCOUNT_BUTTONS")->setValue32(ClientCfg
.DisplayAccountButtons
);
794 Actions
.enable(true);
795 EditActions
.enable(true);
797 if(ClientCfg
.ConfigFile
.exists("VerboseLog"))
798 pPM
->setVerboseLog(ClientCfg
.ConfigFile
.getVar("VerboseLog").asInt() == 1);
799 if(pPM
->isVerboseLog()) nlinfo("Using verbose log mode");
801 ClientApp
= ClientCfg
.ConfigFile
.getVar("Application").asString(0);
805 if (ClientApp
.find("ryzom_") != string::npos
)
806 ext
= " (" + ClientApp
.substr(6) + ")";
808 CViewText
*pV
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:ver_value"));
810 pV
->setHardText(getDisplayVersion() + (ext
.empty() ? "" : ext
));
812 // give priority to login specified as argument
813 string l
= !LoginLogin
.empty() ? LoginLogin
:ClientCfg
.LastLogin
;
817 CGroupEditBox
*pGEB
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
818 if (pGEB
!= NULL
&& (pGEB
->getInputString().empty()))
820 pGEB
->setInputString(l
);
822 CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL
, "target=" CTRL_EDITBOX_PASSWORD
"|select_all=false");
826 CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL
, "target=" CTRL_EDITBOX_LOGIN
"|select_all=false");
830 CCtrlTextButton
*pCB
= dynamic_cast<CCtrlTextButton
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CONNECT
));
831 if (pCB
!= NULL
) pCB
->setActive(false);
833 setLoginFinished( false );
839 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
840 CGroupEditBox
*pGEBLog
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
841 CGroupEditBox
*pGEBPwd
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD
));
842 pGEBLog
->setInputString(LoginLogin
);
843 pGEBPwd
->setInputString(LoginPassword
);
844 CAHManager::getInstance()->runActionHandler("on_login", NULL
, "");
846 if (ClientCfg
.R2Mode
)
848 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
854 for (uint32 i
= 0; i
< Shards
.size(); ++i
)
856 if (Shards
[i
].ShardId
== LoginShardId
)
863 if (ShardSelected
== -1)
865 pIM
->messageBoxWithHelp(CI18N::get("uiErrServerLost"), "ui:login");
866 LoginSM
.pushEvent(CLoginStateMachine::ev_quit
);
870 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
871 // CAHManager::getInstance()->runActionHandler("login_connect_2", NULL);
878 // Check the alt param
879 if (!LoginCustomParameters
.empty() && LoginCustomParameters
!= "&dbg=1")
881 // don't use login and password for alternate login
882 string res
= checkLogin("", "", ClientApp
, LoginCustomParameters
);
885 if (ClientCfg
.R2Mode
)
887 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
893 for (uint32 i
= 0; i
< Shards
.size(); ++i
)
895 if (Shards
[i
].ShardId
== LoginShardId
)
902 if (ShardSelected
== -1)
904 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
905 pIM
->messageBoxWithHelp(CI18N::get("uiErrServerLost"), "ui:login");
906 LoginSM
.pushEvent(CLoginStateMachine::ev_quit
);
910 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
918 // close the socket in case of error
919 HttpClient
.disconnect();
922 LoginSM
.pushEvent(CLoginStateMachine::ev_login_not_alt
);
926 // ***************************************************************************
927 // Called from client.cpp
930 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_LoginScreen
, "login_step_login_screen"));
932 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
933 CPatchManager
*pPM
= CPatchManager::getInstance();
935 if (LoginLogin
.empty())
939 IngameDbMngr
.flushObserverCalls();
940 NLGUI::CDBManager::getInstance()->flushObserverCalls();
942 SetMousePosFirstTime
= true;
943 InitMouseWithCursor(false);
944 Driver
->showCursor (false);
946 SetMouseCursor (false);
947 SetMouseSpeed (ClientCfg
.CursorSpeed
);
948 SetMouseAcceleration (ClientCfg
.CursorAcceleration
);
949 SetMousePosFirstTime
= true;
950 InitMouseWithCursor (ClientCfg
.HardwareCursor
&& !StereoDisplayAttached
);
952 // if (ClientCfg.TestBrowser)
954 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_WEBSTART);
956 // // hide 'back to login' button
957 // CInterfaceElement *backToLogin = CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_BACKTOLOGIN);
959 // backToLogin->setActive(false);
961 // // show 'reload test page' button
962 // CInterfaceElement *reloadTest = CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_RELOADTESTPAGE);
964 // reloadTest->setActive(true);
966 // // start the browser
967 // CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId(GROUP_BROWSER));
969 // pGH->browse(ClientCfg.TestBrowserUrl.c_str());
974 //// NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
975 //// NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DISPLAY_ACCOUNT_BUTTONS")->setValue32(ClientCfg.DisplayAccountButtons);
979 Actions
.enable(true);
980 EditActions
.enable(true);
982 if(ClientCfg
.ConfigFile
.exists("VerboseLog"))
983 pPM
->setVerboseLog(ClientCfg
.ConfigFile
.getVar("VerboseLog").asInt() == 1);
984 if(pPM
->isVerboseLog()) nlinfo("Using verbose log mode");
986 ClientApp
= ClientCfg
.ConfigFile
.getVar("Application").asString(0);
988 // string l = getRegKeyValue("Login").c_str();
992 // CGroupEditBox *pGEB = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN));
994 // pGEB->setInputString(l);
995 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_PASSWORD "|select_all=false");
999 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_LOGIN "|select_all=false");
1003 // CCtrlTextButton *pCB = dynamic_cast<CCtrlTextButton*>(CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CONNECT));
1004 // if (pCB != NULL) pCB->setActive(false);
1006 // setLoginFinished( false );
1007 // loginFinished = false;
1010 // Comes from a current patch
1011 // if (!LoginLogin.empty())
1013 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
1014 // CGroupEditBox *pGEBLog = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN));
1015 // CGroupEditBox *pGEBPwd = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD));
1016 // pGEBLog->setInputString(LoginLogin);
1017 // pGEBPwd->setInputString(LoginPassword);
1018 // CAHManager::getInstance()->runActionHandler("on_login", NULL, "");
1019 // // Select good shard
1020 // ShardSelected = -1;
1021 // for (uint32 i = 0; i < Shards.size(); ++i)
1023 // if (Shards[i].ShardId == LoginShardId)
1025 // ShardSelected = i;
1030 // if (ShardSelected == -1)
1031 // pIM->messageBox(CI18N::get("uiErrServerLost"), "ui:login");
1033 // CAHManager::getInstance()->runActionHandler("login_connect_2", NULL);
1036 // start the login state machine
1037 LoginSM
.pushEvent(CLoginStateMachine::ev_init_done
);
1039 // run the main loop
1046 Actions
.enable(false);
1047 EditActions
.enable(false);
1052 // ***************************************************************************
1053 // INTERFACE HELPERS
1054 // ***************************************************************************
1056 // ***************************************************************************
1057 void removeSpace(string
&s
)
1066 if (i
>= s
.size()) break;
1070 // ***************************************************************************
1071 static void getPatchParameters(std::string
&url
, std::string
&ver
, std::vector
<std::string
> &patchURIs
)
1073 if (ClientCfg
.R2Mode
)
1075 url
= ClientCfg
.PatchUrl
;
1076 ver
= ClientCfg
.PatchVersion
;
1078 // if PatchUrl is forced, don't use URLs returned by server
1081 patchURIs
= R2PatchURLs
;
1082 url
= R2BackupPatchURL
;
1083 ver
= R2ServerVersion
;
1088 nlassert(ShardSelected
!= -1);
1089 patchURIs
= Shards
[ShardSelected
].PatchURIs
;
1090 url
= Shards
[ShardSelected
].EmergencyPatchURL
;
1091 ver
= Shards
[ShardSelected
].Version
;
1093 if (!ClientCfg
.PatchUrl
.empty())
1094 url
= ClientCfg
.PatchUrl
;
1096 if (!ClientCfg
.PatchVersion
.empty())
1097 ver
= ClientCfg
.PatchVersion
;
1101 // ***************************************************************************
1102 std::string
getBGDownloaderCommandLine()
1105 CConfigFile::CVar
*bgdCommandLine
= ClientCfg
.ConfigFile
.getVarPtr("BackgroundDownloaderCommandLine");
1106 if (bgdCommandLine
!= NULL
&& !bgdCommandLine
->asString().empty())
1108 return bgdCommandLine
->asString();
1113 std::vector
<std::string
> patchURIs
;
1114 getPatchParameters(url
, ver
, patchURIs
);
1115 std::string commandLine
= /*R2ServerVersion + " " + VersionName + " " + */ url
+ " " + ver
;
1116 for (uint i
= 0; i
< patchURIs
.size(); ++i
)
1118 commandLine
+= " " + patchURIs
[i
];
1123 // ***************************************************************************
1124 void initPatchCheck()
1126 // start the patching system
1127 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1128 CPatchManager
*pPM
= CPatchManager::getInstance();
1132 std::vector
<std::string
> patchURIs
;
1134 if (!ClientCfg
.R2Mode
)
1136 // nb Nico : refactored this code.
1137 // In previous code, the following was not set in R2Mode, possible bug ?...let as before anyway ...
1138 // store the selected shard for restarting after patch
1139 LoginShardId
= Shards
[ShardSelected
].ShardId
;
1142 #ifdef RYZOM_BG_DOWNLOADER
1143 if (!isBGDownloadEnabled())
1146 getPatchParameters(url
, ver
, patchURIs
);
1147 pPM
->init(patchURIs
, url
, ver
);
1148 pPM
->startCheckThread(true /* include background patchs */);
1150 #ifdef RYZOM_BG_DOWNLOADER
1153 BGDownloader::CTaskDesc
taskDesc(BGDownloader::DLState_CheckPatch
);
1154 CBGDownloaderAccess::getInstance().requestDownloadThreadPriority(BGDownloader::ThreadPriority_Normal
, false);
1155 CBGDownloaderAccess::getInstance().startTask(taskDesc
, getBGDownloaderCommandLine(), true /* showDownloader */);
1158 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKING
);
1160 setPatcherStateText("ui:login:checking", string());
1161 setPatcherProgressText("ui:login:checking", string());
1164 void initShardDisplay()
1166 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1167 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_SHARDDISP
);
1169 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD
));
1172 nlwarning("element " GROUP_LIST_SHARD
" not found probably bad login_main.xml");
1175 /* // To test more servers
1176 for (uint fff = 0; fff < 20; ++fff)
1178 CShard s ( toString("%05d",fff), fff%3, fff+32, toString("%s%d","pipo",fff),
1179 32*fff%46546, "32.32.32.32", "http://www.ryzom.com" );
1180 Shards.push_back(s);
1183 CInterfaceGroup
*pPrevLine
= NULL
;
1184 for(uint i
= 0; i
< Shards
.size(); i
++)
1186 vector
< pair
< string
, string
> > params
;
1188 params
.push_back(pair
<string
,string
>("id", "s"+toString(i
)));
1190 params
.push_back(pair
<string
,string
>("posref", "BL TL"));
1192 CInterfaceGroup
*pNewLine
= CWidgetManager::getInstance()->getParser()->createGroupInstance("t_shard", GROUP_LIST_SHARD
, params
);
1193 if (pNewLine
!= NULL
)
1195 CViewText
*pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("name"));
1196 if (pVT
!= NULL
) pVT
->setText(Shards
[i
].Name
);
1198 pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("version"));
1199 if (pVT
!= NULL
) pVT
->setText(Shards
[i
].Version
);
1201 CViewBase
*pVBon
= pNewLine
->getView("online");
1202 CViewBase
*pVBoff
= pNewLine
->getView("offline");
1203 if ((pVBon
!= NULL
) && (pVBoff
!= NULL
))
1205 pVBon
->setActive (Shards
[i
].Online
);
1206 pVBoff
->setActive (!Shards
[i
].Online
);
1209 pVT
= dynamic_cast<CViewText
*>(pNewLine
->getView("nbplayer"));
1210 if (pVT
!= NULL
) pVT
->setText(toString(Shards
[i
].NbPlayers
));
1214 pNewLine
->setParent(pList
);
1215 pNewLine
->setParentSize(pList
);
1216 pNewLine
->setParentPos(pPrevLine
);
1217 pList
->addGroup(pNewLine
);
1219 pPrevLine
= pNewLine
;
1223 if (!Shards
.empty())
1225 CCtrlButton
*pCB
= dynamic_cast<CCtrlButton
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD
":s0:but"));
1228 pCB
->setPushed(true);
1229 CAHManager::getInstance()->runActionHandler(pCB
->getActionOnLeftClick(), pCB
, pCB
->getParamsOnLeftClick());
1232 pList
->invalidateCoords();
1235 // ***************************************************************************
1237 void onlogin(bool vanishScreen
= true)
1239 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1241 // Remove space before and after each string login & password
1242 removeSpace(LoginLogin
);
1243 removeSpace(LoginPassword
);
1245 if(!LoginLogin
.empty())
1247 ClientCfg
.LastLogin
= LoginLogin
;
1248 ClientCfg
.writeString("LastLogin", ClientCfg
.LastLogin
, true);
1252 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(-1);
1254 // Check the login/pass
1256 // main menu page for r2mode
1257 string res
= checkLogin(LoginLogin
, LoginPassword
, ClientApp
, LoginCustomParameters
);
1260 // if not in auto login, push login ok event
1261 if (LoginSM
.getCurrentState() != CLoginStateMachine::st_auto_login
)
1262 LoginSM
.pushEvent(CLoginStateMachine::ev_login_ok
);
1265 // Ok there is something ! Display next window
1267 if (ClientCfg
.R2Mode
)
1269 // if (ClientCfg.PatchWanted)
1271 // // start the patching system
1272 // CPatchManager *pPM = CPatchManager::getInstance();
1274 // pPM->init(R2PatchURLs, R2BackupPatchURL, R2ServerVersion);
1276 // pPM->startCheckThread();
1277 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKING);
1281 // // go directly to web browser
1282 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_WEBSTART);
1284 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
1285 // // start the browser
1286 // CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId(GROUP_BROWSER));
1288 // pGH->browse(RingMainURL.c_str());
1294 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_SHARDDISP);
1297 // CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD));
1298 // if (pList == NULL)
1300 // nlwarning("element "GROUP_LIST_SHARD" not found probably bad login_main.xml");
1303 // /* // To test more servers
1304 // for (uint fff = 0; fff < 20; ++fff)
1306 // CShard s ( toString("%05d",fff), fff%3, fff+32, toString("%s%d","pipo",fff),
1307 // 32*fff%46546, "32.32.32.32", "http://www.ryzom.com" );
1308 // Shards.push_back(s);
1311 // CInterfaceGroup *pPrevLine = NULL;
1312 // for(uint i = 0; i < Shards.size(); i++)
1314 // vector< pair < string, string > > params;
1316 // params.push_back(pair<string,string>("id", "s"+toString(i)));
1318 // params.push_back(pair<string,string>("posref", "BL TL"));
1320 // CInterfaceGroup *pNewLine =pIM->createGroupInstance("t_shard", GROUP_LIST_SHARD, params);
1321 // if (pNewLine != NULL)
1323 // CViewText *pVT = dynamic_cast<CViewText*>(pNewLine->getView("name"));
1324 // if (pVT != NULL) pVT->setText(Shards[i].Name);
1326 // pVT = dynamic_cast<CViewText*>(pNewLine->getView("version"));
1327 // if (pVT != NULL) pVT->setText(Shards[i].Version);
1329 // CViewBase *pVBon = pNewLine->getView("online");
1330 // CViewBase *pVBoff = pNewLine->getView("offline");
1331 // if ((pVBon != NULL) && (pVBoff != NULL))
1333 // pVBon->setActive (Shards[i].Online);
1334 // pVBoff->setActive (!Shards[i].Online);
1337 // pVT = dynamic_cast<CViewText*>(pNewLine->getView("nbplayer"));
1338 // if (pVT != NULL) pVT->setText(toString(Shards[i].NbPlayers));
1341 // // Add to the list
1342 // pNewLine->setParent(pList);
1343 // pNewLine->setParentSize(pList);
1344 // pNewLine->setParentPos(pPrevLine);
1345 // pList->addGroup(pNewLine);
1347 // pPrevLine = pNewLine;
1351 // if (!Shards.empty())
1353 // CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD ":s0:but"));
1355 // pCB->setPushed(true);
1356 // CAHManager::getInstance()->runActionHandler (pCB->getActionOnLeftClick(), pCB, pCB->getParamsOnLeftClick());
1359 // pList->invalidateCoords();
1363 // close the socket in case of error
1364 HttpClient
.disconnect();
1366 pIM
->messageBoxWithHelp("Error : " + res
, "ui:login");
1368 LoginSM
.pushEvent(CLoginStateMachine::ev_bad_login
);
1369 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
1371 // if (LoginLogin.empty())
1372 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_LOGIN "|select_all=false");
1374 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_PASSWORD "|select_all=false");
1379 class CAHOnLogin
: public IActionHandler
1381 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1383 //nlinfo("CAHOnLogin called");
1385 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1387 CGroupEditBox
*pGEBLog
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
1388 CGroupEditBox
*pGEBPwd
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD
));
1389 if ((pGEBLog
== NULL
) || (pGEBPwd
== NULL
))
1391 nlwarning("element " CTRL_EDITBOX_LOGIN
" or " CTRL_EDITBOX_PASSWORD
" not found probably bad login_main.xml");
1395 LoginLogin
= pGEBLog
->getInputString();
1396 LoginPassword
= pGEBPwd
->getInputString();
1401 REGISTER_ACTION_HANDLER (CAHOnLogin
, "on_login");
1404 // ***************************************************************************
1405 class CAHOnGameConfiguration
: public IActionHandler
1407 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1409 nlinfo("CAHOnGameConfiguration called");
1411 static string Configurator
= "ryzom_configuration_rd.exe";
1413 if (CFile::fileExists (Configurator
))
1415 // launch the ryzom configurator
1416 launchProgram(Configurator
, "");
1417 setLoginFinished( true );
1420 LoginSM
.pushEvent(CLoginStateMachine::ev_quit
);
1424 nlwarning("<CAHOnGameConfiguration::execute> can't find ryzom configurator : %s",Configurator
.c_str());
1428 REGISTER_ACTION_HANDLER (CAHOnGameConfiguration
, "on_game_configuration");
1431 // ***************************************************************************
1432 class CAHLoginQuit
: public IActionHandler
1434 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1436 nlinfo("CAHLoginQuit called");
1438 setLoginFinished( true );
1441 LoginSM
.pushEvent(CLoginStateMachine::ev_quit
);
1444 REGISTER_ACTION_HANDLER (CAHLoginQuit
, "login_quit");
1447 // ***************************************************************************
1448 class CAHLoginTab
: public IActionHandler
1450 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1452 nlinfo("CAHLoginTab called");
1454 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1456 if (NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->getValue32() == UI_VARIABLES_SCREEN_CHECKPASS
)
1458 CCtrlBase
*pCB
= CWidgetManager::getInstance()->getCaptureKeyboard();
1462 string sID
= pCB
->getId();
1463 if (sID
== CTRL_EDITBOX_LOGIN
)
1464 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_PASSWORD
));
1466 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN
));
1467 CWidgetManager::getInstance()->setCaptureKeyboard(pNewCB
);
1470 else if (NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->getValue32() == UI_VARIABLES_SCREEN_CREATE_ACCOUNT
)
1472 CCtrlBase
*pCB
= CWidgetManager::getInstance()->getCaptureKeyboard();
1476 string sID
= pCB
->getId();
1477 if (sID
== CTRL_EDITBOX_CREATEACCOUNT_LOGIN
)
1478 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_PASSWORD
));
1479 else if (sID
== CTRL_EDITBOX_CREATEACCOUNT_PASSWORD
)
1480 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_CONFIRMPASSWORD
));
1481 else if (sID
== CTRL_EDITBOX_CREATEACCOUNT_CONFIRMPASSWORD
)
1482 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_EMAIL
));
1484 pNewCB
= dynamic_cast<CCtrlBase
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_CREATEACCOUNT_LOGIN
));
1485 CWidgetManager::getInstance()->setCaptureKeyboard(pNewCB
);
1490 REGISTER_ACTION_HANDLER (CAHLoginTab
, "login_tab");
1493 // ***************************************************************************
1494 class CAHShardSelect
: public IActionHandler
1496 virtual void execute (CCtrlBase
*pCaller
, const string
&/* Params */)
1498 nlinfo("CAHShardSelect called");
1500 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1502 CCtrlButton
*pCB
= NULL
;
1504 if (ShardSelected
!= -1)
1506 pCB
= dynamic_cast<CCtrlButton
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_SHARD
":s"+toString(ShardSelected
)+":but"));
1508 pCB
->setPushed(false);
1511 pCB
= dynamic_cast<CCtrlButton
*>(pCaller
);
1514 string name
= pCB
->getId();
1515 name
= name
.substr(0,name
.rfind(':'));
1516 name
= name
.substr(name
.rfind(':')+2,name
.size());
1517 fromString(name
, ShardSelected
);
1519 pCB
->setPushed(true);
1522 CCtrlTextButton
*pCTB
= dynamic_cast<CCtrlTextButton
*>(CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CONNECT
));
1524 pCTB
->setActive(true);
1527 REGISTER_ACTION_HANDLER (CAHShardSelect
, "shard_select");
1529 // ***************************************************************************
1530 void ConnectToShard()
1532 //nlinfo("ConnectToShard called");
1534 if (ClientCfg
.R2Mode
)
1537 setLoginFinished( true );
1540 LoginSM
.pushEvent(CLoginStateMachine::ev_enter_game
);
1545 nlassert(ShardSelected
!= -1);
1547 string res
= selectShard(Shards
[ShardSelected
].ShardId
, Cookie
, FSAddr
);
1551 setLoginFinished( true );
1554 LoginSM
.pushEvent(CLoginStateMachine::ev_enter_game
);
1558 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1559 pIM
->messageBoxWithHelp("Error :" + res
, "ui:login");
1561 LoginSM
.pushEvent(CLoginStateMachine::ev_conn_failed
);
1568 // ***************************************************************************
1569 class CAHLoginConnect
: public IActionHandler
1571 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1573 nlinfo("CAHLoginConnect called");
1575 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1577 if (ShardSelected
== -1)
1580 if (!Shards
[ShardSelected
].Online
)
1582 pIM
->messageBoxWithHelp(CI18N::get("uiErrOffLineShard"), "ui:login");
1586 LoginSM
.pushEvent(CLoginStateMachine::ev_shard_selected
);
1588 // std::vector<std::string> patchURIs = Shards[ShardSelected].PatchURIs;
1589 // string url = Shards[ShardSelected].EmergencyPatchURL;
1590 // string ver = Shards[ShardSelected].Version;
1592 // if (!ClientCfg.PatchUrl.empty())
1593 // url = ClientCfg.PatchUrl;
1595 // if (!ClientCfg.PatchVersion.empty())
1596 // ver = ClientCfg.PatchVersion;
1598 // pPM->init(patchURIs, url, ver);
1600 // LoginShardId = Shards[ShardSelected].ShardId;
1602 // if (ClientCfg.PatchWanted)
1604 // pPM->startCheckThread();
1605 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKING);
1609 // CAHManager::getInstance()->runActionHandler("login_patch",NULL);
1613 REGISTER_ACTION_HANDLER (CAHLoginConnect
, "login_connect");
1615 // ***************************************************************************
1616 // Can be called after a patching process (ryzom relaunch and call this AH to
1617 // see if we have to continue patching or directly go ingame)
1618 class CAHLoginConnect2
: public IActionHandler
1620 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1622 nlinfo("CAHLoginConnect2 called");
1623 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1625 if (Shards
[ShardSelected
].PatchURIs
.empty() && Shards
[ShardSelected
].EmergencyPatchURL
.empty())
1627 pIM
->messageBoxWithHelp(CI18N::get("uiErrCantPatch"), "ui:login");
1631 LoginSM
.pushEvent(CLoginStateMachine::ev_shard_selected
);
1633 // std::vector<std::string> patchURIs = Shards[ShardSelected].PatchURIs;
1634 // string url = Shards[ShardSelected].EmergencyPatchURL;
1635 // string ver = Shards[ShardSelected].Version;
1637 // if (!ClientCfg.PatchUrl.empty())
1638 // url = ClientCfg.PatchUrl;
1640 // if (!ClientCfg.PatchVersion.empty())
1641 // ver = ClientCfg.PatchVersion;
1643 // pPM->init(patchURIs, url, ver);
1645 // if ((ClientCfg.PatchWanted) &&
1646 // (!Shards[ShardSelected].Version.empty()) &&
1647 // (Shards[ShardSelected].Version != pPM->getClientVersion()))
1649 // pPM->startCheckThread();
1650 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKING);
1654 // // Version is good, eula then connect and launch the client
1659 REGISTER_ACTION_HANDLER (CAHLoginConnect2
, "login_connect_2");
1663 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1664 CPatchManager
*pPM
= CPatchManager::getInstance();
1666 #ifdef RYZOM_BG_DOWNLOADER
1667 if (!isBGDownloadEnabled())
1670 // Get the list of optional categories to patch
1671 vector
<string
> vCategories
;
1673 CInterfaceGroup
*pList
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT
));
1676 nlwarning("element " GROUP_LIST_CAT
" not found probably bad login_main.xml");
1680 for(uint i
= 0; i
< InfoOnPatch
.OptCat
.size(); i
++)
1682 // Ok for the moment all optional categories must be patched even if the player
1683 // does not want it. Because we cant detect that a continent have to be patched ingame.
1684 vCategories
.push_back(InfoOnPatch
.OptCat
[i
].Name
);
1687 // Code to check if the player wants an optional category or not
1688 CInterfaceGroup *pLine = pList->getGroup("c"+toString(i));
1691 CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(pLine->getCtrl("on_off"));
1694 if (pCB->getPushed())
1695 vCategories.push_back(rAllCats[i]);
1701 pPM
->startPatchThread(vCategories
, true);
1703 #ifdef RYZOM_BG_DOWNLOADER
1706 // NB : here we only do a part of the download each time
1707 BGDownloader::CTaskDesc
taskDesc(BGDownloader::DLState_GetAndApplyPatch
, (1 << BGDownloaderWantedPatch
));
1708 CBGDownloaderAccess::getInstance().startTask(taskDesc
, string(), true /* showDownloader */); // no command line since bg downloader should already be started
1709 // release lock on bnp, so that they can be written
1710 NLMISC::CBigFile::getInstance().removeAll();
1711 NLMISC::CStreamedPackageManager::getInstance().unloadAll();
1714 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_PATCHING
);
1716 CInterfaceElement
*closeBtn
= CWidgetManager::getInstance()->getElementFromId(CTRL_BUTTON_CLOSE_PATCH
);
1718 closeBtn
->setActive(false);
1720 setPatcherStateText("ui:login:patching", string());
1721 setPatcherProgressText("ui:login:patching", string());
1724 // ***************************************************************************
1725 // Called after the check has been done. The page is full of optional categories that must be selected for patching
1726 class CAHLoginPatch
: public IActionHandler
1728 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1730 nlinfo("CAHLoginPatch called");
1732 LoginSM
.pushEvent(CLoginStateMachine::ev_run_patch
);
1734 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
1735 // CPatchManager *pPM = CPatchManager::getInstance();
1737 // // Get the list of optional categories to patch
1738 // vector<string> vCategories;
1740 // CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CAT));
1741 // if (pList == NULL)
1743 // nlwarning("element "GROUP_LIST_CAT" not found probably bad login_main.xml");
1747 // for(uint i = 0; i < InfoOnPatch.OptCat.size(); i++)
1749 // // Ok for the moment all optional categories must be patched even if the player
1750 // // does not want it. Because we cant detect that a continent have to be patched ingame.
1751 // vCategories.push_back(InfoOnPatch.OptCat[i].Name);
1754 // // Code to check if the player wants an optional category or not
1755 // CInterfaceGroup *pLine = pList->getGroup("c"+toString(i));
1756 // if (pLine != NULL)
1758 // CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(pLine->getCtrl("on_off"));
1761 // if (pCB->getPushed())
1762 // vCategories.push_back(rAllCats[i]);
1768 // // Start patching
1769 // if (ClientCfg.PatchWanted)
1771 // pPM->startPatchThread(vCategories);
1772 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_PATCHING);
1776 // ConnectToShard();
1780 REGISTER_ACTION_HANDLER (CAHLoginPatch
, "login_patch");
1782 // ***************************************************************************
1783 // Called after the check has been done. The page is full of optional categories that must be selected for patching
1784 class CAHClosePatch
: public IActionHandler
1786 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
1788 nlinfo("CAHClosePatch called");
1790 LoginSM
.pushEvent(CLoginStateMachine::ev_close_patch
);
1793 REGISTER_ACTION_HANDLER (CAHClosePatch
, "close_patch");
1796 // ***************************************************************************
1797 // Called after pushing the read note at the opening of the modal window
1798 class CAHSetReleaseNote
: public IActionHandler
1800 virtual void execute (CCtrlBase
* /* pCaller */, const string
&sParams
)
1802 nlinfo("CAHSetReleaseNote called");
1804 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1806 string sShard
= getParam(sParams
, "shard");
1807 string sGroupHtml
= getParam(sParams
, "group");
1809 CGroupHTML
*pQH
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId(sGroupHtml
));
1814 if (ClientCfg
.R2Mode
)
1816 // ring release note
1817 sURL
= ClientCfg
.RingReleaseNotePath
+
1818 "?version=" + (VersionName
.empty() ? R2ServerVersion
: VersionName
)+
1819 "&lang=" + ClientCfg
.LanguageCode
+
1820 "&ca=" + ClientCfg
.ConfigFile
.getVar("Application").asString(0);
1821 "&startPage="+RingMainURL
;
1825 // legacy ryzom release note
1827 if (sShard
== "selected")
1828 nShardId
= ShardSelected
;
1830 fromString(sShard
.substr(1), nShardId
);
1832 sURL
= ClientCfg
.ReleaseNotePath
+
1833 "?version=" + Shards
[nShardId
].Version
+
1834 "&lang=" + ClientCfg
.LanguageCode
+
1835 "&id=" + toString(Shards
[nShardId
].ShardId
) +
1836 "&ca=" + ClientCfg
.ConfigFile
.getVar("Application").asString(0);
1840 pQH
->browse(sURL
.c_str());
1843 REGISTER_ACTION_HANDLER (CAHSetReleaseNote
, "set_release_note");
1845 // ***************************************************************************
1846 // Called after pushing the read note at the opening of the modal window
1847 class CAHReboot
: public IActionHandler
1849 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
1851 nlinfo("CAHReboot called");
1853 // create a file to prompt eula next time
1854 CFile::createEmptyFile(getLogDirectory() + "show_eula");
1856 CInterfaceManager
*im
= CInterfaceManager::getInstance();
1859 #ifdef RYZOM_BG_DOWNLOADER
1860 if (isBGDownloadEnabled())
1862 CBGDownloaderAccess::getInstance().reboot();
1867 CPatchManager::getInstance()->reboot();
1869 LoginSM
.pushEvent(CLoginStateMachine::ev_reboot
);
1871 catch (const NLMISC::EDiskFullError
&)
1873 im
->messageBoxWithHelp(CI18N::get("uiPatchDiskFull"), "ui:login");
1875 catch (const NLMISC::EWriteError
&)
1877 im
->messageBoxWithHelp(CI18N::get("uiPatchWriteError"), "ui:login");
1879 catch (const std::exception
&e
)
1881 im
->messageBoxWithHelp(e
.what(), "ui:login", "login_quit");
1885 REGISTER_ACTION_HANDLER (CAHReboot
, "reboot");
1889 // ***************************************************************************
1890 class CAHAcceptEula
: public IActionHandler
1892 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
1894 //nlinfo("CAHAcceptEula called");
1895 if(CFile::fileExists(getLogDirectory() + "show_eula"))
1896 CFile::deleteFile(getLogDirectory() + "show_eula");
1897 LoginSM
.pushEvent(CLoginStateMachine::ev_accept_eula
);
1899 // if (ClientCfg.R2Mode)
1901 // // open web browser
1902 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
1903 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_WEBSTART);
1905 // // start the browser
1906 // CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId(GROUP_BROWSER));
1908 // pGH->browse(RingMainURL.c_str());
1912 // ConnectToShard();
1916 REGISTER_ACTION_HANDLER (CAHAcceptEula
, "accept_eula");
1918 // ***************************************************************************
1919 class CAHOpenURL
: public IActionHandler
1921 virtual void execute (CCtrlBase
* /* pCaller */, const string
&sParams
)
1923 nlinfo("CAHOpenURL called");
1929 #ifdef NL_OS_WINDOWS
1931 // Check for special install tag
1932 const char *KeyName
= "InstallTag";
1934 installTag
= CSystemUtils::getRegKey(KeyName
);
1936 if (installTag
.length() > 1)
1938 nldebug("Found install tag '%s'", url
.c_str());
1942 // Process any inserts in lpMsgBuf.
1944 // Display the string.
1945 nlwarning("RegQueryValue for '%s' : %s", KeyName
, NLMISC::formatErrorMessage(0).c_str());
1948 // TODO: for Linux and Mac OS
1951 if (sParams
== "cfg_EditAccountURL")
1953 url
= ClientCfg
.EditAccountURL
;
1955 else if (sParams
== "cfg_BetaAccountURL")
1957 url
= ClientCfg
.BetaAccountURL
;
1959 else if (sParams
== "cfg_ForgetPwdURL")
1961 url
= ClientCfg
.ForgetPwdURL
;
1963 else if (sParams
== "cfg_LoginSupportURL")
1965 url
= ClientCfg
.LoginSupportURL
;
1967 else if (sParams
== "cfg_FreeTrialURL")
1969 url
= ClientCfg
.FreeTrialURL
;
1971 if (!installTag
.empty())
1973 url
+= string("&from=")+installTag
;
1976 else if (sParams
== "cfg_ConditionsTermsURL")
1978 url
= ClientCfg
.ConditionsTermsURL
;
1980 else if (sParams
== "cfg_NamingPolicyURL")
1982 url
= ClientCfg
.NamingPolicyURL
;
1986 nlwarning("no URL found");
1990 // modify existing languages
1993 string::size_type pos_lang
= url
.find("/en/");
1996 if (pos_lang
== string::npos
)
1997 pos_lang
= url
.find("=en#");
1999 if (pos_lang
!= string::npos
)
2001 url
.replace(pos_lang
+ 1, 2, ClientCfg
.getHtmlLanguageCode());
2006 if (url
.find('?') != string::npos
)
2011 url
+= "language=" + ClientCfg
.LanguageCode
;
2013 if (!LoginCustomParameters
.empty())
2014 url
+= LoginCustomParameters
;
2019 nlinfo("openURL %s", url
.c_str());
2022 REGISTER_ACTION_HANDLER (CAHOpenURL
, "open_url");
2024 static vector
<UDriver::CMode
> VideoModes
;
2025 vector
<string
> StringModeList
;
2026 vector
<string
> StringPresetList
;
2027 vector
< pair
<string
, bool> > CfgPresetList
;
2028 sint CurrentMode
= -1;
2029 sint CurrentPreset
= -1;
2031 // ***************************************************************************
2032 class CAHInitResLod
: public IActionHandler
2034 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2036 //nlinfo("CAHInitResLod called");
2037 if (Driver
== NULL
) return;
2040 StringModeList
.clear();
2042 std::vector
<std::string
> stringFreqList
;
2045 getRyzomModes(VideoModes
, StringModeList
, stringFreqList
, CurrentMode
, currentFreq
);
2047 // getRyzomModes() expects empty list, so we need to insert 'Windowed' after mode list is filled
2048 StringModeList
.insert(StringModeList
.begin(), "uiConfigWindowed");
2050 // If the client is in windowed mode, still in windowed mode and do not change anything
2051 if (ClientCfg
.Windowed
)
2053 // If we have not found the mode so it can be an error or machine change, so propose the first available
2054 else if (CurrentMode
== -1)
2056 // We inserted 'Windowed' as first mode, so index needs to move too
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
]);
2065 StringPresetList
.clear();
2066 StringPresetList
.push_back("uiLodValueLow");
2067 StringPresetList
.push_back("uiLodValueMedium");
2068 StringPresetList
.push_back("uiLodValueNormal");
2069 StringPresetList
.push_back("uiLodValueHigh");
2070 StringPresetList
.push_back("uiLodValueCustom");
2071 CurrentPreset
= 4; // CInterfaceDDX::CustomPreset
2073 // first indicates the preset-able cfg-variable
2074 // second indicates if its a double variable (else it's an int)
2075 CfgPresetList
.clear();
2076 CfgPresetList
.push_back(pair
<string
,bool>("LandscapeTileNear", true));
2077 CfgPresetList
.push_back(pair
<string
,bool>("LandscapeThreshold", true));
2078 CfgPresetList
.push_back(pair
<string
,bool>("Vision", true));
2079 CfgPresetList
.push_back(pair
<string
,bool>("MicroVeget", false));
2080 CfgPresetList
.push_back(pair
<string
,bool>("MicroVegetDensity", true));
2081 CfgPresetList
.push_back(pair
<string
,bool>("FxNbMaxPoly", false));
2082 CfgPresetList
.push_back(pair
<string
,bool>("Cloud", false));
2083 CfgPresetList
.push_back(pair
<string
,bool>("CloudQuality", true));
2084 CfgPresetList
.push_back(pair
<string
,bool>("CloudUpdate", false));
2085 CfgPresetList
.push_back(pair
<string
,bool>("Shadows", false));
2086 CfgPresetList
.push_back(pair
<string
,bool>("SkinNbMaxPoly", false));
2087 CfgPresetList
.push_back(pair
<string
,bool>("NbMaxSkeletonNotCLod", false));
2088 CfgPresetList
.push_back(pair
<string
,bool>("CharacterFarClip", true));
2090 CfgPresetList
.push_back(pair
<string
,bool>("FXAA", false));
2091 CfgPresetList
.push_back(pair
<string
,bool>("Bloom", false));
2092 CfgPresetList
.push_back(pair
<string
,bool>("SquareBloom", false));
2093 CfgPresetList
.push_back(pair
<string
,bool>("DensityBloom", true));
2095 // Check if all the preset-able cfg-variable are in a preset mode
2097 for (uint32 i
= 0; i
< CfgPresetList
.size(); ++i
)
2099 CConfigFile::CVar
*cfgVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(CfgPresetList
[i
].first
);
2100 if (cfgVarPtr
== NULL
) continue;
2101 // Get the preset of the variable i
2102 sint nVarPreset
= 0;
2103 for (uint32 j
= 0; j
< 4; ++j
) // CInterfaceDDX::NumPreset
2105 string sPresetName
= CfgPresetList
[i
].first
+ "_ps" + toString(j
);
2106 CConfigFile::CVar
*presetVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(sPresetName
);
2109 if (CfgPresetList
[i
].second
) // Is it a double ?
2111 if (cfgVarPtr
->asDouble() == presetVarPtr
->asDouble())
2112 nVarPreset
|= (1 << j
);
2116 if (cfgVarPtr
->asInt() == presetVarPtr
->asInt())
2117 nVarPreset
|= (1 << j
);
2123 nPreset
= nVarPreset
;
2125 nPreset
&= nVarPreset
;
2133 if (nPreset
&1) CurrentPreset
= 0;
2134 else if (nPreset
&2) CurrentPreset
= 1;
2135 else if (nPreset
&4) CurrentPreset
= 2;
2136 else if (nPreset
&8) CurrentPreset
= 3;
2139 pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2141 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2144 REGISTER_ACTION_HANDLER (CAHInitResLod
, "init_res_lod");
2146 // ***************************************************************************
2147 class CAHMoreRes
: public IActionHandler
2149 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2151 nlinfo("CAHMoreRes called");
2152 if (CurrentMode
< ((sint
)StringModeList
.size()-1))
2154 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2155 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
2157 pVT
->setHardText(StringModeList
[CurrentMode
]);
2160 REGISTER_ACTION_HANDLER (CAHMoreRes
, "more_res");
2162 // ***************************************************************************
2163 class CAHLessRes
: public IActionHandler
2165 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2167 nlinfo("CAHLessRes called");
2168 if (CurrentMode
> 0)
2170 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2171 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value"));
2173 pVT
->setHardText(StringModeList
[CurrentMode
]);
2176 REGISTER_ACTION_HANDLER (CAHLessRes
, "less_res");
2178 // ***************************************************************************
2179 class CAHMoreLod
: public IActionHandler
2181 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2183 nlinfo("CAHMoreLod called");
2184 if (CurrentPreset
< ((sint
)StringPresetList
.size()-1))
2186 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2187 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2189 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2192 REGISTER_ACTION_HANDLER (CAHMoreLod
, "more_lod");
2194 // ***************************************************************************
2195 class CAHLessLod
: public IActionHandler
2197 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2199 nlinfo("CAHMoreLod called");
2200 if (CurrentPreset
> 0)
2202 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2203 CViewText
*pVT
= dynamic_cast<CViewText
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:lod_value"));
2205 pVT
->setHardText(StringPresetList
[CurrentPreset
]);
2208 REGISTER_ACTION_HANDLER (CAHLessLod
, "less_lod");
2210 // ***************************************************************************
2211 // TODO: remove resolution change from login screen
2212 class CAHUninitResLod
: public IActionHandler
2214 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* sParams */)
2216 //nlinfo("CAHUninitResLod called");
2218 // If the mode requested is a windowed mode do nothnig
2219 if (CurrentMode
== 0)
2221 ClientCfg
.Windowed
= true;
2222 ClientCfg
.writeBool("FullScreen", false);
2226 ClientCfg
.Windowed
= false;
2228 uint16 w
= 0, h
= 0;
2230 string vidModeStr
= StringModeList
[CurrentMode
];
2231 string tmp
= vidModeStr
.substr(0,vidModeStr
.find('x')-1);
2233 tmp
= vidModeStr
.substr(vidModeStr
.find('x')+2,vidModeStr
.size());
2236 ClientCfg
.Width
= w
;
2237 ClientCfg
.Height
= h
;
2239 ClientCfg
.writeBool("FullScreen", true);
2240 ClientCfg
.writeInt("Width", w
);
2241 ClientCfg
.writeInt("Height", h
);
2244 if (CurrentPreset
!= 4) // CInterfaceDDX::CustomPreset
2246 for (uint32 i
= 0; i
< CfgPresetList
.size(); ++i
)
2248 CConfigFile::CVar
*cfgVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(CfgPresetList
[i
].first
);
2249 if (cfgVarPtr
== NULL
) continue;
2251 string sPresetName
= CfgPresetList
[i
].first
+ "_ps" + toString(CurrentPreset
);
2252 CConfigFile::CVar
*presetVarPtr
= ClientCfg
.ConfigFile
.getVarPtr(sPresetName
);
2255 if (CfgPresetList
[i
].second
) // Is it a double ?
2256 cfgVarPtr
->setAsDouble(presetVarPtr
->asDouble());
2258 cfgVarPtr
->setAsInt(presetVarPtr
->asInt());
2263 // **** Save the config
2264 if (ClientCfg
.SaveConfig
)
2265 ClientCfg
.ConfigFile
.save ();
2266 ClientCfg
.IsInvalidated
= true;
2269 REGISTER_ACTION_HANDLER (CAHUninitResLod
, "uninit_res_lod");
2274 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2275 CPatchManager
*pPM
= CPatchManager::getInstance();
2278 setDataScanLog(string());
2281 pPM
->startScanDataThread();
2282 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_DATASCAN
);
2283 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->setValue32(1);
2286 // ***************************************************************************
2287 // Called after the check has been done. The page is full of optional categories that must be selected for patching
2288 class CAHOnScanDataStart
: public IActionHandler
2290 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2292 nlinfo("CAHOnScanDataStart called");
2294 LoginSM
.pushEvent(CLoginStateMachine::ev_data_scan
);
2298 REGISTER_ACTION_HANDLER (CAHOnScanDataStart
, "on_scan_data_start");
2300 // ***************************************************************************
2301 // Called when the user cancel the scan
2302 class CAHOnScanDataClose
: public IActionHandler
2304 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2306 nlinfo("CAHOnScanDataClose called");
2307 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2308 CPatchManager
*pPM
= CPatchManager::getInstance();
2310 // if the scan is still running
2311 if(NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:DATASCAN_RUNNING")->getValue32()!=0)
2313 // request to stop the thread
2314 pPM
->askForStopScanDataThread();
2317 setDataScanState(CI18N::get("uiCancelingScanData"));
2321 LoginSM
.pushEvent(CLoginStateMachine::ev_close_data_scan
);
2322 // Come Back to Login Screen.
2323 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
2325 // // Give focus to password if some login entered
2327 // CGroupEditBox *pGEB = dynamic_cast<CGroupEditBox*>(CWidgetManager::getInstance()->getElementFromId(CTRL_EDITBOX_LOGIN));
2329 // loginEB= pGEB->getInputStringAsStdString();
2330 // // if none entered
2331 // if (loginEB.empty())
2332 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_LOGIN "|select_all=false");
2334 // CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_PASSWORD "|select_all=false");
2338 REGISTER_ACTION_HANDLER (CAHOnScanDataClose
, "on_scan_data_close");
2340 // ***************************************************************************
2342 inline string
parseTooltip(const string
& initString
, const string
& tagName
)
2346 string::size_type tooltipPos
= initString
.find(tagName
);
2347 if(tooltipPos
!= string::npos
)
2349 tooltip
= initString
.substr(tooltipPos
);
2352 tooltip
= tooltip
.substr(tooltip
.find(">")+1);
2355 tooltip
= tooltip
.substr(0, tooltip
.find("<"));
2361 inline string
parseCommentError(const string
& initString
, const string
& tagName
)
2365 string::size_type errorPos
= initString
.find(tagName
);
2366 if(errorPos
!= string::npos
)
2368 error
= initString
.substr(errorPos
);
2371 error
= error
.substr(error
.find(">")+1);
2374 error
= error
.substr(0, error
.find("<"));
2380 bool initCreateAccount()
2382 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2385 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2388 // show "submit interface", hide "login interface"
2389 CInterfaceGroup
* grSubmit
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("submit_gr"));
2391 grSubmit
->setActive(true);
2393 CInterfaceGroup
* grLogin
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("login_gr"));
2395 grLogin
->setActive(false);
2398 std::vector
< std::string
> editBoxes(4);
2399 editBoxes
[0] = "eb_login";
2400 editBoxes
[1] = "eb_password";
2401 editBoxes
[2] = "eb_confirm_password";
2402 editBoxes
[3] = "eb_email";
2404 for(uint i
=0; i
<editBoxes
.size(); i
++)
2406 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId(editBoxes
[i
] + ":eb"));
2408 eb
->setInputString(std::string());
2411 // conditions button
2412 CCtrlBaseButton
* but
= dynamic_cast<CCtrlBaseButton
*>(createAccountUI
->findFromShortId("accept_cond"));
2414 but
->setPushed(true);
2416 // get rules from url
2417 string url
= ClientCfg
.CreateAccountURL
;
2418 CPatchManager
*pPM
= CPatchManager::getInstance();
2420 if (!CurlHttpClient
.connect(url
))
2422 nlwarning("Can't connect");
2426 std::string lang
= ClientCfg
.LanguageCode
;
2427 if(lang
=="wk") lang
= "uk";
2429 CurlHttpClient
.verifyServer(true); // set this to false if you need to connect to the test environment
2431 std::string params
= "language=" + lang
;
2433 if (!LoginCustomParameters
.empty())
2434 params
+= LoginCustomParameters
;
2436 if(!CurlHttpClient
.sendGet(url
, params
, pPM
->isVerboseLog()))
2438 string
errorMessage("Can't send (error code 60)");
2439 errorMessageBox(errorMessage
);
2440 nlwarning(errorMessage
.c_str());
2445 if(!CurlHttpClient
.receive(res
, pPM
->isVerboseLog()))
2447 string
errorMessage("Can't receive (error code 61)");
2448 errorMessageBox(errorMessage
);
2449 nlwarning(errorMessage
.c_str());
2455 string
errorMessage("Empty result (error code 13)");
2456 errorMessageBox(errorMessage
);
2457 nlwarning(errorMessage
.c_str());
2461 CurlHttpClient
.disconnect();
2463 // initialize rules in interface
2464 std::vector
< std::pair
< std::string
, std::string
> > rules(5);
2465 rules
[0] = std::pair
<std::string
, std::string
>("rules_login", "id=tooltip-Username");
2466 rules
[1] = std::pair
<std::string
, std::string
>("rules_password", "id=tooltip-Password");
2467 rules
[2] = std::pair
<std::string
, std::string
>("rules_password_conf", "id=tooltip-ConfirmPass");
2468 rules
[3] = std::pair
<std::string
, std::string
>("rules_email", "id=tooltip-Email");
2469 rules
[4] = std::pair
<std::string
, std::string
>("rules_conditions", "id=tooltip-TaC");
2471 for(uint i
=0; i
<rules
.size(); i
++)
2473 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId(rules
[i
].first
));
2476 string tooltip
= parseTooltip(res
, rules
[i
].second
);
2477 text
->setHardText(tooltip
);
2478 text
->setActive(false);
2483 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("errors_list"));
2486 text
->setHardText(toString(CI18N::get("uiCreateAccountWelcome")));
2487 text
->setColor(CRGBA(255, 255, 255, 255));
2489 CInterfaceGroup
* group
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("erros_txt"));
2492 group
->updateCoords();
2494 CInterfaceGroup
* groupScroll
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("err_back_scrollbar"));
2495 if(groupScroll
) groupScroll
->setActive(group
->getHReal() > group
->getMaxHReal());
2496 CCtrlScroll
* scroll
= dynamic_cast<CCtrlScroll
*>(createAccountUI
->findFromShortId("err_scroll_bar"));
2498 scroll
->setTrackPos(scroll
->getHReal());
2503 CInterfaceGroup
* rulesGr
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("rules_gr"));
2505 rulesGr
->setActive(false);
2507 // must be done after hide rules
2508 CAHManager::getInstance()->runActionHandler("set_keyboard_focus", NULL
, "target=" CTRL_EDITBOX_CREATEACCOUNT_LOGIN
"|select_all=false");
2512 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CREATE_ACCOUNT
);
2517 // ***************************************************************************
2518 // Called when the user focus one of the edit boxes during the account creation
2519 class CAHCreateAccountRules
: public IActionHandler
2521 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
2523 nlinfo("CAHCreateAccountRules called");
2525 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2526 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2529 CInterfaceGroup
* rulesGr
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("rules_gr"));
2531 rulesGr
->setActive(false);
2533 std::vector
< std::string
> rules(4);
2534 rules
[0] = "rules_login";
2535 rules
[1] = "rules_password";
2536 rules
[2] = "rules_password_conf";
2537 rules
[3] = "rules_email";
2539 for(uint i
=0; i
<rules
.size(); i
++)
2541 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId(rules
[i
]));
2544 text
->setActive(Params
==rules
[i
]);
2545 if(Params
==rules
[i
])
2548 rulesGr
->setActive(!text
->getText().empty());
2555 REGISTER_ACTION_HANDLER (CAHCreateAccountRules
, "create_account_rules");
2557 // ***************************************************************************
2558 // Called when the user choose the account creation
2559 class CAHOnCreateAccount
: public IActionHandler
2561 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2563 nlinfo("CAHOnCreateAccount called");
2565 LoginSM
.pushEvent(CLoginStateMachine::ev_create_account
);
2568 REGISTER_ACTION_HANDLER (CAHOnCreateAccount
, "on_create_account");
2570 // ***************************************************************************
2571 // Called when the user submit the account creation
2572 class CAHOnCreateAccountSubmit
: public IActionHandler
2574 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2576 nlinfo("CAHOnCreateAccountSubmit called");
2578 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2580 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2583 // recover data from UI
2584 std::vector
< std::string
> editBoxes(4);
2585 editBoxes
[0] = "eb_login";
2586 editBoxes
[1] = "eb_password";
2587 editBoxes
[2] = "eb_confirm_password";
2588 editBoxes
[3] = "eb_email";
2589 std::vector
< std::string
> results(4);
2591 for(uint i
=0; i
<editBoxes
.size(); i
++)
2593 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId(editBoxes
[i
] + ":eb"));
2595 results
[i
] = eb
->getInputString();
2599 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("email_adress"));
2601 text
->setHardText(results
[3]);
2603 // conditions button
2604 bool conditionsPushed
= false;
2605 CCtrlBaseButton
* but
= dynamic_cast<CCtrlBaseButton
*>(createAccountUI
->findFromShortId("accept_cond"));
2607 conditionsPushed
= !but
->getPushed();
2609 string url
= ClientCfg
.CreateAccountURL
;
2610 CPatchManager
*pPM
= CPatchManager::getInstance();
2612 if (!CurlHttpClient
.connect(url
))
2614 string
errorMessage("Can't connect");
2615 errorMessageBox(errorMessage
);
2616 nlwarning(errorMessage
.c_str());
2620 std::string params
= "Username=" + results
[0] + "&Password=" + results
[1]
2621 + "&ConfirmPass=" + results
[2] + "&Email=" + results
[3];
2623 if(conditionsPushed
)
2626 if (!LoginCustomParameters
.empty())
2627 params
+= LoginCustomParameters
;
2629 std::string md5
= results
[0] + results
[1] + "" + results
[3];
2630 md5
= NLMISC::getMD5((uint8
*)md5
.data(), (uint32
)md5
.size()).toString();
2632 params
+= "&SC=" + md5
;
2633 std::string lang
= ClientCfg
.LanguageCode
;
2634 if(lang
=="wk") lang
= "uk";
2635 params
+= "&Language=" + lang
;
2637 CurlHttpClient
.verifyServer(true); // set this to false if you need to connect to the test environment
2639 if(!CurlHttpClient
.sendPost(url
, params
, pPM
->isVerboseLog()))
2641 string
errorMessage("Can't send (error code 60)");
2642 errorMessageBox(errorMessage
);
2643 nlwarning(errorMessage
.c_str());
2648 if(!CurlHttpClient
.receive(res
, pPM
->isVerboseLog()))
2650 string
errorMessage("Can't receive (error code 61)");
2651 errorMessageBox(errorMessage
);
2652 nlwarning(errorMessage
.c_str());
2658 string
errorMessage("Empty result (error code 13)");
2659 errorMessageBox(errorMessage
);
2660 nlwarning(errorMessage
.c_str());
2664 CurlHttpClient
.disconnect();
2667 string::size_type okPos
= res
.find("email_sent");
2668 if(okPos
!= string::npos
)
2670 // show "submit interface", hide "login interface"
2671 CInterfaceGroup
* grSubmit
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("submit_gr"));
2673 grSubmit
->setActive(false);
2675 CInterfaceGroup
* grLogin
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("login_gr"));
2677 grLogin
->setActive(true);
2681 // initialize error comments in interface
2682 CViewText
* text
= dynamic_cast<CViewText
*>(createAccountUI
->findFromShortId("errors_list"));
2685 text
->setColor(CRGBA(250, 30, 30, 255));
2687 std::vector
< std::string
> errors(5);
2688 errors
[0] = "id=\"comment-Username\"";
2689 errors
[1] = "id=\"comment-Password\"";
2690 errors
[2] = "id=\"comment-ConfirmPass\"";
2691 errors
[3] = "id=\"comment-Email\"";
2692 errors
[4] = "id=\"comment-TaC\"";
2695 for(uint i
=0; i
<errors
.size(); i
++)
2697 string comment
= parseCommentError(res
, errors
[i
]);
2698 if(!comment
.empty())
2699 error
+= "- " + comment
+ "\n";
2702 text
->setHardText(error
);
2704 CInterfaceGroup
* group
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("erros_txt"));
2707 group
->updateCoords();
2709 CInterfaceGroup
* groupScroll
= dynamic_cast<CInterfaceGroup
*>(createAccountUI
->findFromShortId("err_back_scrollbar"));
2710 if(groupScroll
) groupScroll
->setActive(group
->getHReal() > group
->getMaxHReal());
2711 CCtrlScroll
* scroll
= dynamic_cast<CCtrlScroll
*>(createAccountUI
->findFromShortId("err_scroll_bar"));
2713 scroll
->setTrackPos(scroll
->getHReal());
2720 REGISTER_ACTION_HANDLER (CAHOnCreateAccountSubmit
, "on_create_account_submit");
2722 // ***************************************************************************
2723 // Called when the user cancel the account creation
2724 class CAHOnCreateAccountClose
: public IActionHandler
2726 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2728 nlinfo("CAHOnCreateAccountClose called");
2730 LoginSM
.pushEvent(CLoginStateMachine::ev_close_create_account
);
2733 REGISTER_ACTION_HANDLER (CAHOnCreateAccountClose
, "on_create_account_close");
2735 // ***************************************************************************
2736 class CAHCreateAccountLogin
: public IActionHandler
2738 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2740 nlinfo("CAHCreateAccountLogin called");
2742 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2744 CInterfaceGroup
*createAccountUI
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:login:create_account"));
2747 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId("eb_login:eb"));
2749 LoginLogin
= eb
->getInputString();
2751 eb
= dynamic_cast<CGroupEditBox
*>(createAccountUI
->findFromShortId("eb_password:eb"));
2753 LoginPassword
= eb
->getInputString();
2759 REGISTER_ACTION_HANDLER (CAHCreateAccountLogin
, "create_account_login");
2761 // ***************************************************************************
2762 // Called by html embeded lua script
2763 class CAHOnConnectToShard
: public IActionHandler
2765 virtual void execute (CCtrlBase
* /* pCaller */, const string
&Params
)
2767 // warning : pCaller is null when event come from lua scrip embeded in HTML
2768 Cookie
= getParam(Params
, "cookie");
2769 FSAddr
= getParam(Params
, "fsAddr");
2771 // replace the '_' with '|' in the cookie string
2772 for (uint i
=0; i
<Cookie
.size(); ++i
)
2774 if (Cookie
[i
] == '_')
2778 setLoginFinished( true );
2781 LoginSM
.pushEvent(CLoginStateMachine::ev_connect
);
2784 REGISTER_ACTION_HANDLER (CAHOnConnectToShard
, "on_connect_to_shard");
2786 // ***************************************************************************
2787 // Called to return to login screen in case of error
2788 class CAHOnBackToLogin
: public IActionHandler
2790 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
2792 setLoginFinished( false );
2794 LoginSM
.pushEvent(CLoginStateMachine::ev_relog
);
2796 // CInterfaceManager *pIM = CInterfaceManager::getInstance();
2797 // // need to reset password and current screen
2798 // NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_CHECKPASS);
2801 REGISTER_ACTION_HANDLER (CAHOnBackToLogin
, "on_back_to_login");
2803 // ***************************************************************************
2804 // ***************************************************************************
2805 // ***************************************************************************
2806 // NETWORK CONNECTION
2807 // ***************************************************************************
2808 // ***************************************************************************
2809 // ***************************************************************************
2812 // ***************************************************************************
2813 string
checkLogin(const string
&login
, const string
&password
, const string
&clientApp
, const std::string
&customParameters
)
2815 CPatchManager
*pPM
= CPatchManager::getInstance();
2818 if(ClientCfg
.ConfigFile
.exists("VerboseLog"))
2819 pPM
->setVerboseLog(ClientCfg
.ConfigFile
.getVar("VerboseLog").asInt() == 1);
2820 if(pPM
->isVerboseLog()) nlinfo("Using verbose log mode");
2822 if(!HttpClient
.connectToLogin())
2823 return "Can't connect (error code 1)";
2825 if(pPM
->isVerboseLog()) nlinfo("Connected");
2829 std::string url
= ClientCfg
.ConfigFile
.getVar("StartupHost").asString() + ClientCfg
.ConfigFile
.getVar("StartupPage").asString();
2831 // don't use login with alt method
2834 // ask server for salt
2835 if(!HttpClient
.sendGet(url
+ "?cmd=ask&cp=2&login=" + login
+ "&lg=" + ClientCfg
.LanguageCode
, "", pPM
->isVerboseLog()))
2836 return std::string("Can't send (error code 60) ") + HttpClient
.lastError();
2838 if(pPM
->isVerboseLog()) nlinfo("Sent request for password salt");
2840 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2841 return "Can't receive (error code 61)";
2843 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2846 return "Empty answer from server (error code 62)";
2848 size_t first
= res
.find("\n\n");
2849 if (first
== std::string::npos
)
2851 first
= res
.find("\r\r");
2852 if (first
== std::string::npos
)
2854 first
= res
.find("\r\n\r\n");
2855 if (first
!= std::string::npos
)
2857 res
= res
.substr(first
+ 4);
2862 res
= res
.substr(first
+ 2);
2867 res
= res
.substr(first
+ 2);
2870 nldebug("res1: %s", res
.c_str());
2874 nlwarning("missing response body: %s", res
.c_str());
2875 return "missing response body (error code 64)";
2877 else if(res
[0] == '0')
2879 // server returns an error
2880 nlwarning("server error: %s", res
.substr(2).c_str());
2881 return res
.substr(2);
2883 else if(res
[0] == '1')
2885 Salt
= res
.substr(2);
2889 // server returns ???
2890 nlwarning("%s", res
.c_str());
2894 // send login + crypted password + client app and cp=2 (as crypted password)
2895 if(!HttpClient
.connectToLogin())
2896 return "Can't connect (error code 63)";
2898 if(pPM
->isVerboseLog()) nlinfo("Connected");
2901 if (ClientCfg
.R2Mode
)
2903 // R2 login sequence
2907 std::string cryptedPassword
= CCrypt::crypt(password
, Salt
);
2909 if(!HttpClient
.sendGet(url
+ "?cmd=login&login=" + login
+ "&password=" + cryptedPassword
+ "&clientApplication=" + clientApp
+ "&cp=2" + "&lg=" + ClientCfg
.LanguageCode
+ customParameters
))
2910 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2914 // don't send login and password if empty
2915 if(!HttpClient
.sendGet(url
+ "?cmd=login&clientApplication=" + clientApp
+ "&cp=2" + "&lg=" + ClientCfg
.LanguageCode
+ customParameters
))
2916 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
2919 // the response should contains the result code and the cookie value
2920 if(pPM
->isVerboseLog()) nlinfo("Sent request login check");
2922 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
2923 return "Can't receive (error code 3)";
2925 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
2928 return "Empty answer from server (error code 4)";
2930 size_t first
= res
.find("\n\n");
2931 if (first
== std::string::npos
)
2933 first
= res
.find("\r\r");
2934 if (first
== std::string::npos
)
2936 first
= res
.find("\r\n\r\n");
2937 if (first
!= std::string::npos
)
2939 res
= res
.substr(first
+ 4);
2944 res
= res
.substr(first
+ 2);
2949 res
= res
.substr(first
+ 2);
2952 nldebug("res2: %s", res
.c_str());
2956 nlwarning("missing response body: %s", res
.c_str());
2957 return "missing response body (error code 65)";
2959 else if(res
[0] == '0')
2961 // server returns an error
2962 nlwarning("server error: %s", res
.substr(2).c_str());
2963 return res
.substr(2);
2965 else if(res
[0] == '1')
2967 //nlwarning(res.c_str());
2968 vector
<string
> lines
;
2969 explode(res
, std::string("\n"), lines
, false);
2970 if (lines
.size() != 2)
2972 return toString("Invalid server return, found %u lines, want 2", lines
.size());
2975 vector
<string
> parts
;
2976 explode(lines
[0], std::string("#"), parts
, false);
2977 if (parts
.size() < 5)
2978 return "Invalid server return, missing cookie and/or Ring URLs";
2980 // server returns ok, we have the cookie
2982 // store the cookie value and FS address for next page request
2983 CurrentCookie
= parts
[1];
2984 Cookie
= CurrentCookie
;
2987 // store the ring startup page
2988 RingMainURL
= parts
[3];
2989 FarTP
.setURLBase(parts
[4]);
2991 if(parts
.size() >= 6 && parts
[5] == "1")
2994 extern bool startStat
;
2998 // parse the second line (contains the domain info)
3000 explode(lines
[1], std::string("#"), parts
, false);
3001 if (parts
.size() < 3)
3002 return "Invalid server return, missing patch URLs";
3004 R2ServerVersion
= parts
[0].c_str();
3005 R2BackupPatchURL
= parts
[1];
3006 explode(parts
[2], std::string(" "), R2PatchURLs
, true);
3010 // unexpected content
3012 string ret
= toString("DEV : Invalid server return, missing return code in \n%s", res
.c_str());
3015 return "Invalid server return, missing return code";
3022 // standard ryzom login sequence
3023 std::string cryptedPassword
= CCrypt::crypt(password
, Salt
);
3025 if(!HttpClient
.sendGet(url
+ "?login=" + login
+ "&password=" + cryptedPassword
+ "&clientApplication=" + clientApp
+ "&cp=2"))
3026 return std::string("Can't send (error code 2) ") + HttpClient
.lastError();
3028 if(!send(ClientCfg.ConfigFile.getVar("StartupPage").asString()+"?login="+login+"&password="+password+"&clientApplication="+clientApp))
3029 return "Can't send (error code 2)";
3031 if(pPM
->isVerboseLog()) nlinfo("Sent request login check");
3033 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
3034 return "Can't receive (error code 3)";
3036 if(pPM
->isVerboseLog()) nlinfo("Received request login check");
3039 return "Empty answer from server (error code 4)";
3041 size_t first
= res
.find("\n\n");
3042 if (first
== std::string::npos
)
3044 first
= res
.find("\r\r");
3045 if (first
== std::string::npos
)
3047 first
= res
.find("\r\n\r\n");
3048 if (first
!= std::string::npos
)
3050 res
= res
.substr(first
+ 4);
3055 res
= res
.substr(first
+ 2);
3060 res
= res
.substr(first
+ 2);
3063 nldebug("res2: %s", res
.c_str());
3067 nlwarning("missing response body: %s", res
.c_str());
3068 return "missing response body (error code 66)";
3070 else if(res
[0] == '0')
3072 // server returns an error
3073 nlwarning("server error: %s", res
.substr(2).c_str());
3074 return res
.substr(2);
3076 else if(res
[0] == '1')
3078 // server returns ok, we have the list of shard
3080 fromString(res
.substr(2), nbs
);
3081 vector
<string
> lines
;
3083 explode(res
, std::string("\n"), lines
, true);
3085 if(pPM
->isVerboseLog())
3087 nlinfo ("Exploded, with nl, %u res", (uint
)lines
.size());
3088 /* for (uint i = 0; i < lines.size(); i++)
3090 nlinfo (" > '%s'", lines[i].c_str());
3094 if(lines
.size() != nbs
+1)
3096 nlwarning("bad shard lines number %u != %d", (uint
)lines
.size(), nbs
+1);
3097 nlwarning("'%s'", res
.c_str());
3098 return "bad lines numbers (error code 5)";
3101 for(uint i
= 1; i
< lines
.size(); i
++)
3104 explode(lines
[i
], std::string("|"), res
);
3106 if(pPM
->isVerboseLog())
3108 nlinfo ("Exploded with '%s', %u res", "|", (uint
)res
.size());
3109 /* for (uint i = 0; i < res.size(); i++)
3111 nlinfo (" > '%s'", res[i].c_str());
3115 if (res
.size() < 7 && res
.size() > 8)
3117 nlwarning("bad | numbers %u != %d", (uint
)res
.size(), 8);
3118 nlwarning("'%s'", lines
[i
].c_str());
3119 return "bad pipe numbers (error code 6)";
3122 fromString(res
[1], online
);
3124 fromString(res
[2], shardId
);
3126 fromString(res
[4], nbPlayers
);
3127 Shards
.push_back(CShard(res
[0], online
, shardId
, res
[3], nbPlayers
, res
[5], res
[6]));
3128 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());
3129 if (res
.size() == 8)
3131 explode(res
[7], std::string(" "), Shards
.back().PatchURIs
);
3137 // server returns ???
3138 nlwarning("%s", res
.c_str());
3146 // ***************************************************************************
3147 string
selectShard(uint32 shardId
, string
&cookie
, string
&addr
)
3152 if(!HttpClient
.connectToLogin()) return "Can't connect (error code 7)";
3154 if(LoginLogin
.empty()) return "Empty Login (error code 8)";
3155 if(LoginPassword
.empty()) return "Empty Password (error code 9)";
3156 if(ClientApp
.empty()) return "Empty Client Application (error code 10)";
3158 // send login + crypted password + client app and cp=2 (as crypted password)
3159 std::string cryptedPassword
= CCrypt::crypt(LoginPassword
, Salt
);
3161 std::string url
= ClientCfg
.ConfigFile
.getVar("StartupHost").asString() + ClientCfg
.ConfigFile
.getVar("StartupPage").asString();
3163 if(!HttpClient
.sendGet(url
+ "?cmd=login&shardid=" + toString(shardId
) + "&login=" + LoginLogin
+ "&password=" + cryptedPassword
+ "&clientApplication=" + ClientApp
+ "&cp=2"))
3164 return "Can't send (error code 11)";
3168 CPatchManager
*pPM
= CPatchManager::getInstance();
3169 if(!HttpClient
.receive(res
, pPM
->isVerboseLog()))
3170 return "Can't receive (error code 12)";
3173 return "Empty result (error code 13)";
3175 size_t first
= res
.find("\n\n");
3176 if (first
== std::string::npos
)
3178 first
= res
.find("\r\r");
3179 if (first
== std::string::npos
)
3181 first
= res
.find("\r\n\r\n");
3182 if (first
!= std::string::npos
)
3184 res
= res
.substr(first
+ 4);
3189 res
= res
.substr(first
+ 2);
3194 res
= res
.substr(first
+ 2);
3197 nldebug("res2: %s", res
.c_str());
3201 nlwarning("missing response body: %s", res
.c_str());
3202 return "missing response body (error code 66)";
3204 else if(res
[0] == '0')
3206 // server returns an error
3207 nlwarning("server error: %s", res
.substr(2).c_str());
3208 return res
.substr(2);
3210 else if(res
[0] == '1')
3212 // server returns ok, we have the access
3214 vector
<string
> line
;
3215 explode(res
, std::string(" "), line
, true);
3217 if (line
.size() < 2 || line
.size() > 3)
3219 nlwarning("bad launch lines number %d != %d", line
.size(), 2);
3220 return "bad launch line number (error code 14)";
3223 cookie
= line
[0].substr(2);
3226 std::vector
<std::string
> patchURIs
;
3228 CShard
* shard
= NULL
;
3230 for (i
=0; i
<Shards
.size(); ++i
)
3232 if (Shards
[i
].ShardId
== shardId
)
3239 if (shard != NULL && line.size() >= 3)
3241 explode(line[2], "|", shard->PatchURIs, true);
3243 nlinfo("received %d main patch server URIs:", shard->PatchURIs.size());
3245 for (i=0; i<shard->PatchURIs.size(); ++i)
3246 nlinfo("%d: '%s'", i, shard->PatchURIs[i].c_str());
3252 // server returns ???
3253 nlwarning("%s", res
.c_str());
3261 /*void mainLandPatch()
3263 if (!AvailablePatchs) return;
3264 nlassert(AvailablePatchs & (1 << BGDownloader::DownloadID_MainLand)); // only handled case for now
3266 BGDownloaderWantedPatch = BGDownloader::DownloadID_MainLand;
3267 CInterfaceManager *im = CInterfaceManager::getInstance();
3269 // login machine should be in the 'end' state !!
3270 nlassert(LoginSM.getCurrentState() == CLoginStateMachine::st_end);
3271 LoginSM.pushEvent(CLoginStateMachine::ev_mainland_patch);
3272 loginMainLoop(); // patch is handled in the login mainloop
3273 // there should have been a reboot there, so quit if something went wrong...
3281 // ***************************************************************************
3282 // ***************************************************************************
3284 // ***************************************************************************
3285 // ***************************************************************************
3287 #include "init_main_loop.h"
3289 bool loginIntroSkip
;
3293 // Display of nevrax logo is done at init time (see init.cpp) just before addSearchPath (second one)
3295 for (uint i
= 0; i
< 1; i
++) // previously display nevrax then nvidia
3299 beginLoading(IntroNVidia
);
3301 ProgressBar
.newMessage (nmsg
);
3304 Driver
->AsyncListener
.reset();
3306 CInputHandlerManager::getInstance()->pumpEventsNoIM();
3309 loginIntroSkip
= false;
3311 sint64 CurTime
= T0
;
3313 while (loginIntroSkip
== false)
3316 if ((T0
- CurTime
) > 5000) // 5s before quiting
3319 CInputHandlerManager::getInstance()->pumpEventsNoIM();
3322 if (Driver
->AsyncListener
.isKeyPushed (KeyESCAPE
) || Driver
->AsyncListener
.isKeyPushed (KeyRETURN
) ||
3323 Driver
->AsyncListener
.isKeyPushed (KeySPACE
))
3326 const string
nmsg("");
3327 ProgressBar
.newMessage (nmsg
);
3328 IngameDbMngr
.flushObserverCalls();
3329 NLGUI::CDBManager::getInstance()->flushObserverCalls();
3333 beginLoading(StartBackground
);
3334 ProgressBar
.finish();