1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2012-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "bg_downloader_access.h"
23 #ifdef RYZOM_BG_DOWNLOADER
26 #include "login_patch.h"
28 #include "nel/misc/shared_memory.h"
29 #include "nel/misc/i18n.h"
30 #include "nel/misc/win_thread.h"
31 #include "nel/misc/big_file.h"
33 #include "game_share/bg_downloader_msg.h"
38 #include "nel/misc/win_thread.h"
44 using namespace BGDownloader
;
45 using namespace NLMISC
;
47 extern HINSTANCE HInstance
;
49 // exception used by the download coroutine to signal an error
50 class EDownloadException
: public NLMISC::Exception
53 EDownloadException(const std::string
&reason
) : Exception(reason
) {}
56 class EDownloadTerminationRequested
: public NLMISC::Exception
59 EDownloadTerminationRequested() : Exception("Download termination requested") {}
62 class EWaitMessageTimeoutException
: public NLMISC::Exception
65 EWaitMessageTimeoutException() : Exception("Download timeout message") {}
68 //=====================================================
69 CBGDownloaderAccess::CBGDownloaderAccess()
71 _DownloadCoTask
= new CDownloadCoTask
;
72 _DownloadCoTask
->Parent
= this;
74 _TaskResult
= BGDownloader::TaskResult_Unknown
;
76 clearCurrentMessage();
77 _MustLaunchBatFile
= false;
78 _ShowDownloader
= false;
79 _DownloadThreadPriority
= ThreadPriority_Low
;
81 _PatchCompletionFlag
= false;
82 _RyzomInstPIDPtr
= NULL
;
83 _WaitBalloonDisplay
= false;
84 _CurrentFileProgress
= 0.f
;
87 //=====================================================
88 void CBGDownloaderAccess::clearCurrentMessage()
90 _CurrentMessage
= ucstring(); // OLD
91 _CurrentFilesToGet
= 0;
95 _CurrentFileProgress
= 0.f
;
98 //=====================================================
99 CBGDownloaderAccess::~CBGDownloaderAccess()
101 delete _DownloadCoTask
;
104 //=====================================================
105 void CBGDownloaderAccess::init()
110 //=====================================================
111 void CBGDownloaderAccess::release()
113 _DownloaderMsgQueue
.release();
114 if (_DownloadCoTask
->isStarted())
116 _DownloadCoTask
->requestTerminate();
117 while (_DownloadCoTask
->isFinished())
122 if (_RyzomInstPIDPtr
)
124 NLMISC::CSharedMemory::closeSharedMemory(_RyzomInstPIDPtr
);
125 _RyzomInstPIDPtr
= NULL
;
130 //=====================================================
131 void CBGDownloaderAccess::update()
133 /*nlwarning("In msg queue = %d, out msg queue = %d",
134 (int) _DownloaderMsgQueue.getReceiveQueueSize(),
135 (int) _DownloaderMsgQueue.getSendQueueSize());*/
139 nlassert(!_DownloadCoTask
->isStarted());
142 if (_WaitBalloonDisplay
)
144 nlassert(_DownloadCoTask
->isStarted());
145 _DownloadCoTask
->resume();
149 if (_DownloadCoTask
->isStarted())
156 // Avoid task collision here : this may happen during the tp main loop, and
157 // would lead to a freeze
158 if (NLMISC::CCoTask::getCurrentTask() == NULL
)
160 _DownloadCoTask
->resume();
162 if (_State
== State_Finished
&& !_WaitBalloonDisplay
)
173 //=====================================================
174 void CBGDownloaderAccess::resetDownloadTask()
176 delete _DownloadCoTask
;
177 _DownloadCoTask
= new CDownloadCoTask
;
178 _DownloadCoTask
->Parent
= this;
179 nlassert(!_DownloadCoTask
->isStarted());
182 //=====================================================
183 void CBGDownloaderAccess::startTask(const BGDownloader::CTaskDesc
&taskDesc
, const std::string
&commandLine
, bool showDownloader
)
185 nlassert(_State
!= State_Patching
); // patching already started
186 nlassert(!_DownloadCoTask
->isStarted());
187 _CurrentFilesToGet
= 0;
188 _TotalFilesToGet
= 0;
191 _CommandLine
= commandLine
;
192 _State
= State_Patching
;
193 _TaskResult
= BGDownloader::TaskResult_Unknown
;
194 _WantedTask
= taskDesc
;
196 _ShowDownloader
= showDownloader
;
199 //=====================================================
200 bool CBGDownloaderAccess::isTaskEnded(BGDownloader::TTaskResult
&result
, ucstring
&errorMsg
) const // OLD
202 if (_State
== State_Finished
)
204 result
= _TaskResult
;
205 errorMsg
= _ErrorMsg
;
211 //=====================================================
212 void CBGDownloaderAccess::resumeBackgroundDownload()
214 nlassert(0); // not handled yet
215 //_DownloadCoTask->setDownloaderMode(DownloaderMode_Autonomous);
218 ////////////////////////
219 // DOWNLOAD COROUTINE //
220 ////////////////////////
223 //=====================================================
224 void CBGDownloaderAccess::CDownloadCoTask::run()
226 Parent
->_ErrorMsg
.clear();
229 // don't restart downloader before
230 if (Parent
->_WantedTask
.State
== DLState_GetAndApplyPatch
)
232 // this is a continuation of the check task, so ensure
233 // that the downloader is still running and in slave mode
234 if (!isDownloaderProcessRunning() && getDownloaderMode() != DownloaderMode_Slave
)
236 throw EDownloadException(CI18N::get("uiBGD_DownloaderStopped"));
241 // should be executed only once for the check
244 setDownloaderVerbosity(true);
245 setDownloaderMode(DownloaderMode_Slave
);
246 doTask(Parent
->_WantedTask
);
247 setDownloaderVerbosity(false);
248 // clear display info, else they would remain for a brief time when arriving on patch screen
249 Parent
->clearCurrentMessage();
251 getTaskResult(Parent
->_TaskResult
, Parent
->_AvailablePatchs
, Parent
->_MustLaunchBatFile
, Parent
->_ErrorMsg
);
253 Parent
->_PatchCompletionFlag
= false;
254 if (Parent
->_TaskResult
== BGDownloader::TaskResult_Success
)
256 if (Parent
->_WantedTask
== DLState_CheckPatch
)
260 if (!Parent
->_AvailablePatchs
)
262 Parent
->_WaitBalloonDisplay
= true;
263 Parent
->_State
= State_Finished
;
264 // because the downloader may pop a notification balloon here, wait some more before shutting it down
266 sleep(2500); // at this time, may last longer because the client starts a loading phase
267 Parent
->_WaitBalloonDisplay
= false;
268 // no patch, just stop the downloader
269 shutdownDownloader();
272 bool rosPatch
= (Parent
->_AvailablePatchs
& (1 << BGDownloader::DownloadID_RoS
)) != 0;
273 bool mainlandPatch
= (Parent
->_AvailablePatchs
& (1 << BGDownloader::DownloadID_MainLand
)) != 0;
275 if (Parent
->_MustLaunchBatFile
&& !rosPatch
) // let be superstitious, should always be true ...
277 // no patch but must rebbot ? may happen only if some 'unpacked' file needed by RoS have been deleted
278 shutdownDownloader();
283 // if mainland patch isn't completed yet, remove the searchpaths
284 // to the .bnp that are going to be patched
286 //sint64 startTime = NLMISC::CTime::getLocalTime();
287 const CBNPCategorySet
&bnpCatSet
= Parent
->_DescFile
.getCategories();
288 std::vector
<std::string
> bigFiles
;
289 for (uint catIndex
= 0; catIndex
< bnpCatSet
.categoryCount(); ++catIndex
)
291 const CBNPCategory
&cat
= bnpCatSet
.getCategory(catIndex
);
292 if (cat
.isOptional()) // NB : 'optional' flag meaning has changed : it now means 'Mainland Patch'
293 // until an enum is added
295 for (uint f
= 0; f
< cat
.fileCount(); ++f
)
297 bigFiles
.push_back(cat
.getFile(f
));
301 NLMISC::CPath::removeBigFiles(bigFiles
);
302 //sint64 endTime = NLMISC::CTime::getLocalTime();
303 //nlinfo("%.2f s to remove paths", (endTime - startTime) / 1000.f);
307 if (Parent
->_WantedTask
.State
== DLState_GetAndApplyPatch
)
309 Parent
->_PatchCompletionFlag
= true;
310 if (Parent
->_WantedTask
.DownloadBitfield
& (1 << BGDownloader::DownloadID_RoS
))
312 if (Parent
->_MustLaunchBatFile
) // let be superstitious, should always be true ...
314 Parent
->_WaitBalloonDisplay
= true;
315 Parent
->_State
= State_Finished
;
316 // because the downloader may pop a notification balloon here, wait some more before shutting it down
319 Parent
->_WaitBalloonDisplay
= false;
320 // because a reboot is required, just stop now ...
321 shutdownDownloader();
325 if (Parent
->_WantedTask
.DownloadBitfield
& (1 << BGDownloader::DownloadID_MainLand
))
327 bool memoryCompressed
= CPath::isMemoryCompressed();
328 if (memoryCompressed
)
330 CPath::memoryUncompress();
332 // and redo 'addSearchPath' on data, because of the new bnp files that have just been added
333 NLMISC::CPath::addSearchPath("data/", true, false, NULL
);
334 if (memoryCompressed
)
336 CPath::memoryCompress();
338 Parent
->_WaitBalloonDisplay
= true;
339 Parent
->_State
= State_Finished
;
340 // because the downloader may pop a notification balloon here, wait some more before shutting it down
342 Parent
->_WaitBalloonDisplay
= false;
343 // stop after the mainland download (hardcoded, but should suffice for now)
344 shutdownDownloader();
349 catch(const EDownloadException
&e
)
351 //shutdownDownloader();
352 Parent
->_TaskResult
= TaskResult_Error
;
353 Parent
->_ErrorMsg
.fromUtf8(e
.what());
354 Parent
->_DownloadThreadPriority
= ThreadPriority_DownloaderError
;
356 catch(const EDownloadTerminationRequested
&e
)
358 shutdownDownloader();
359 Parent
->_TaskResult
= TaskResult_Error
;
360 Parent
->_ErrorMsg
= ucstring(e
.what()); // OLD
361 Parent
->_DownloadThreadPriority
= ThreadPriority_DownloaderError
;
363 catch(const NLMISC::EStream
&e
)
365 shutdownDownloader();
366 Parent
->_TaskResult
= TaskResult_Error
;
367 nlwarning("BG DOWNLOADER PROTOCOL ERROR ! Stream error");
368 Parent
->_ErrorMsg
= CI18N::get("uiBGD_ProtocolError") + ucstring(" : ") + ucstring(e
.what()); // OLD
369 Parent
->_DownloadThreadPriority
= ThreadPriority_DownloaderError
;
371 catch (const EWaitMessageTimeoutException
&e
)
373 shutdownDownloader();
374 Parent
->_TaskResult
= TaskResult_Error
;
375 nlwarning("BG DOWNLOADER PROTOCOL ERROR ! Message timeout");
376 Parent
->_ErrorMsg
= CI18N::get("uiBGD_ProtocolError") + ucstring(" : ") + ucstring(e
.what()); // OLD
377 Parent
->_DownloadThreadPriority
= ThreadPriority_DownloaderError
;
379 Parent
->_State
= State_Finished
;
382 //=====================================================
383 bool CBGDownloaderAccess::getPatchCompletionFlag(bool clearFlag
)
385 bool flag
= _PatchCompletionFlag
;
388 _PatchCompletionFlag
= false;
393 //=====================================================
394 bool CBGDownloaderAccess::CDownloadCoTask::isDownloaderProcessRunning()
396 // the downloader creates a system-wide mutex, so if present, assume that the downloader is running
398 HANDLE mutex
= CreateMutexW (NULL
, FALSE
, BGDownloader::DownloaderMutexName
);
401 if (GetLastError() == ERROR_ALREADY_EXISTS
)
411 // launch the process and wait until completion
412 #if defined (NL_DEBUG)
413 static const char *BGDownloaderName
= "client_background_downloader_d.exe";
414 #elif defined (NL_RELEASE)
415 static const char *BGDownloaderName
= "client_background_downloader_r.exe";
417 # error "Unknown bg downloader exe name";
421 //=====================================================
422 void CBGDownloaderAccess::CDownloadCoTask::createDownloaderProcess()
424 bool manualLaunch
= false;
425 CConfigFile::CVar
*manualLaunchVar
= ClientCfg
.ConfigFile
.getVarPtr("BackgroundDownloaderManualLaunch");
428 manualLaunch
= (manualLaunchVar
->asInt() != 0);
432 BOOL ok
= NLMISC::launchProgram(BGDownloaderName
, Parent
->_CommandLine
);
435 throw EDownloadException(CI18N::get("uiBGD_LaunchError"));
440 nlwarning(Parent
->_CommandLine
.c_str());
444 //=====================================================
445 void CBGDownloaderAccess::CDownloadCoTask::restartDownloader()
447 // if another ryzom client is running, try stopping it first
450 void *ryzomInstPIDPtr
= NLMISC::CSharedMemory::accessSharedMemory(NLMISC::toSharedMemId(RYZOM_PID_SHM_ID
));
451 if (!ryzomInstPIDPtr
) break; // only instance running is us
452 // try to terminate the other instance
454 while (*(DWORD
*) ryzomInstPIDPtr
== 0)
456 // the other process didn't write its pid into shared mem yet (shared memory is initially filled with zero's)
457 // so wait a bit (very unlikely case !!)
462 nlwarning("CBGDownloaderAccess::CDownloadCoTask : detected shared memory segment, with NULL pid");
463 // some problem here ...
464 throw EDownloadException(CI18N::get("uiBGD_MultipleRyzomInstance"));
467 bool ok
= NLMISC::CWinProcess::terminateProcess(*(DWORD
*) ryzomInstPIDPtr
);
468 CSharedMemory::closeSharedMemory(ryzomInstPIDPtr
);
471 nlwarning("CBGDownloaderAccess::CDownloadCoTask : detected shared memory segment, with good pid, but couldn't stop the process");
472 // couldn't stop the other client ...
473 throw EDownloadException(CI18N::get("uiBGD_MultipleRyzomInstance"));
476 // write our pid into shared mem
477 Parent
->_RyzomInstPIDPtr
= CSharedMemory::createSharedMemory(NLMISC::toSharedMemId(RYZOM_PID_SHM_ID
), sizeof(uint32
));
478 if (!Parent
->_RyzomInstPIDPtr
)
480 // really, really bad luck ...
481 throw EDownloadException(CI18N::get("uiBGD_MultipleRyzomInstance"));
483 *(uint32
*) Parent
->_RyzomInstPIDPtr
= (uint32
) GetCurrentProcessId();
485 HWND hWnd
= Driver
->getDisplay();
487 // for safety, stop any running downloader
488 if (isDownloaderProcessRunning())
490 Parent
->_DownloaderMsgQueue
.init(hWnd
, BGDownloader::ClientWndID
, BGDownloader::DownloaderWndID
);
492 shutdownDownloader();
493 Parent
->_DownloaderMsgQueue
.release();
499 nlwarning("Launching downloader: try number %u", tryCounter
++);
500 // now we can create the message queue because we are sure that it will reach the good app
501 Parent
->_DownloaderMsgQueue
.init(HInstance
, BGDownloader::ClientWndID
, BGDownloader::DownloaderWndID
);
504 Parent
->_CurrentMessage
= CI18N::get("uiBGD_Launching");
506 #ifndef BG_DOWNLOADER_MANUAL_LAUNCH
507 createDownloaderProcess();
509 while (!Parent
->_DownloaderMsgQueue
.connected())
513 // try probe/ack test for safety
516 uint32 waitTime
= 500;
517 const uint32 totalTries
= 7;
518 while (waitTime
<= 32000)
520 Parent
->_CurrentMessage
.fromUtf8(toString(CI18N::get("uiBGD_HandShaking").c_str(), tryIndex
, totalTries
));
522 sendSimpleMsg(CL_Probe
);
523 NLMISC::CMemStream dummyMsg
;
526 waitMsg(BGD_Ack
, dummyMsg
, waitTime
/* max milliseconds */);
530 catch (const EWaitMessageTimeoutException
&)
532 // no-op, just continue the loop for another try
538 if (isDownloaderProcessRunning())
540 shutdownDownloader();
543 Parent
->_DownloaderMsgQueue
.release();
546 nlwarning("Downloader launched successfully");
547 if (Parent
->_ShowDownloader
)
549 Parent
->showDownloader();
553 //=====================================================
554 void CBGDownloaderAccess::CDownloadCoTask::yieldDownload()
557 if (isTerminationRequested())
559 throw EDownloadTerminationRequested();
563 //=====================================================
564 void CBGDownloaderAccess::sendSimpleMsg(BGDownloader::TMsgType msgType
)
566 CMemStream
outMsg(false /* output stream */);
567 outMsg
.serialEnum(msgType
);
568 _DownloaderMsgQueue
.sendMessage(outMsg
);
571 //=====================================================
572 void CBGDownloaderAccess::showDownloader()
574 sendSimpleMsg(CL_Show
);
577 //=====================================================
578 void CBGDownloaderAccess::hideDownloader()
580 sendSimpleMsg(CL_Hide
);
584 //=====================================================
585 CTaskDesc
CBGDownloaderAccess::CDownloadCoTask::getDownloaderState()
587 sendSimpleMsg(CL_GetState
);
588 CMemStream
inMsg(true /* input stream */);
589 waitMsg(BGD_State
, inMsg
);
591 inMsg
.serial(result
);
595 //=====================================================
596 void CBGDownloaderAccess::CDownloadCoTask::getDescFile()
598 sendSimpleMsg(CL_GetDescFile
);
599 CMemStream
inMsg(true /* input stream */);
600 waitMsg(BGD_DescFile
, inMsg
);
601 inMsg
.serial(Parent
->_DescFile
);
605 //=====================================================
606 TDownloaderMode
CBGDownloaderAccess::CDownloadCoTask::getDownloaderMode()
608 sendSimpleMsg(CL_GetMode
);
609 CMemStream
inMsg(true /* input stream */);
610 waitMsg(BGD_Mode
, inMsg
);
611 TDownloaderMode mode
= DownloaderMode_Unknown
;
612 inMsg
.serialEnum(mode
);
616 //=====================================================
617 void CBGDownloaderAccess::CDownloadCoTask::getTaskResult(TTaskResult
&result
,
618 uint32
&availablePatchs
,
619 bool &mustLaunchBatFile
,
620 ucstring
&errorMsg
// OLD
623 sendSimpleMsg(CL_GetTaskResult
);
624 CMemStream
inMsg(true /* input stream */);
625 waitMsg(BGD_TaskResult
, inMsg
);
626 inMsg
.serialEnum(result
);
627 inMsg
.serial(availablePatchs
);
628 inMsg
.serial(mustLaunchBatFile
);
629 inMsg
.serial(errorMsg
); // OLD
632 //=====================================================
633 void CBGDownloaderAccess::CDownloadCoTask::doTask(const CTaskDesc
&taskDesc
)
635 CTaskDesc downloaderTask
= getDownloaderState();
636 if (downloaderTask
.State
!= DLState_Idle
&& downloaderTask
!= taskDesc
)
638 // if not the wanted task, ask to stop current task, and wait until completion
643 if (downloaderTask
.State
== DLState_Idle
)
647 // else, good task already started, just wait
651 //=====================================================
652 void CBGDownloaderAccess::CDownloadCoTask::startTask(const CTaskDesc
&taskDesc
)
654 CMemStream
outMsg(false /* output stream */);
655 TMsgType msgType
= CL_StartTask
;
656 outMsg
.serialEnum(msgType
);
657 CTaskDesc mutableTaskDesc
= taskDesc
;
658 outMsg
.serial(mutableTaskDesc
);
663 //=====================================================
664 void CBGDownloaderAccess::CDownloadCoTask::stopTask()
666 sendSimpleMsg(CL_Stop
);
670 //=====================================================
671 void CBGDownloaderAccess::CDownloadCoTask::shutdownDownloader()
673 const uint32 SHUTDOWN_TIMEOUT
= 6; // seconds until we consider the downloader is hung, and try to shut it down
674 sendSimpleMsg(CL_Shutdown
);
675 uint32 startTime
= NLMISC::CTime::getSecondsSince1970();
676 setDownloaderVerbosity(false);
677 while (isDownloaderProcessRunning())
679 Parent
->_CurrentMessage
= CI18N::get("uiBGD_ShuttingDown");
681 if ((NLMISC::CTime::getSecondsSince1970() - startTime
) >= SHUTDOWN_TIMEOUT
)
683 Parent
->_CurrentMessage
= CI18N::get("uiBGD_ForciblyShutdown");
685 if (!CWinProcess::terminateProcessFromModuleName(BGDownloaderName
))
687 Parent
->_CurrentMessage
= CI18N::get("uiBGD_ShutdownFailed");
692 CWinProcess::terminateProcessFromModuleName(BGDownloaderName
); // for safety
693 Parent
->_CurrentMessage
= ucstring(); // OLD
696 //=====================================================
697 void CBGDownloaderAccess::CDownloadCoTask::setDownloaderMode(TDownloaderMode mode
)
699 CMemStream
outMsg(false /* output stream */);
700 TMsgType msgType
= CL_SetMode
;
701 outMsg
.serialEnum(msgType
);
702 outMsg
.serialEnum(mode
);
706 //=====================================================
707 void CBGDownloaderAccess::CDownloadCoTask::setDownloaderVerbosity(bool verbose
)
709 CMemStream
outMsg(false /* output stream */);
710 TMsgType msgType
= CL_SetVerbose
;
711 outMsg
.serialEnum(msgType
);
712 outMsg
.serial(verbose
);
716 //=====================================================
717 void CBGDownloaderAccess::CDownloadCoTask::waitIdle()
721 CTaskDesc downloaderTask
= getDownloaderState();
722 if (downloaderTask
.State
== DLState_Idle
) break;
726 //=====================================================
727 void CBGDownloaderAccess::CDownloadCoTask::waitMsg(BGDownloader::TMsgType wantedMsgType
, NLMISC::CMemStream
&msg
, NLMISC::TTime timeOutInMs
)
729 NLMISC::TTime startTime
= NLMISC::CTime::getLocalTime();
730 BGDownloader::TMsgType msgType
= (BGDownloader::TMsgType
) ~0;
733 while (!Parent
->_DownloaderMsgQueue
.pumpMessage(msg
))
736 CConfigFile::CVar
*manualLaunchVar
= ClientCfg
.ConfigFile
.getVarPtr("BackgroundDownloaderManualLaunch");
737 if (!manualLaunchVar
|| manualLaunchVar
->asInt() == 0)
740 if (NLMISC::CTime::getLocalTime() - startTime
> timeOutInMs
)
742 nlwarning("Time out exceeded while waiting for message of type %d", (int) wantedMsgType
);
746 throw EWaitMessageTimeoutException();
749 checkDownloaderAlive();
752 nlassert (msg
.isReading());
753 msg
.serialEnum(msgType
);
754 if (msgType
== wantedMsgType
) return;
755 if (!defaultMessageHandling(msgType
, msg
))
757 //nlwarning("##CLIENT RCV message of type : %s", toString(msg).c_str());
761 if (msgType
!= wantedMsgType
)
763 nlwarning("BG DOWNLOADER PROTOCOL ERROR ! Bad message type received. Expected type is '%d', received type is '%d'", (int) wantedMsgType
, (int) msgType
);
764 throw EDownloadException(CI18N::get("uiBGD_ProtocolError"));
769 //=====================================================
770 bool CBGDownloaderAccess::CDownloadCoTask::defaultMessageHandling(BGDownloader::TMsgType msgType
, NLMISC::CMemStream
&msg
)
772 nlassert(msg
.isReading());
777 BGDownloader::TThreadPriority tp
;
779 if (tp
!= Parent
->_DownloadThreadPriority
)
781 Parent
->_DownloadThreadPriority
= tp
; // TMP, for debug
786 case BGD_UpdateStatusString
:
788 msg
.serial(Parent
->_CurrentMessage
);
789 msg
.serial(Parent
->_CurrentFilesToGet
);
790 msg
.serial(Parent
->_TotalFilesToGet
);
791 msg
.serial(Parent
->_PatchingSize
);
792 msg
.serial(Parent
->_TotalSize
);
793 msg
.serial(Parent
->_CurrentFileProgress
);
794 //nlinfo(Parent->_CurrentMessage.toString().c_str());
800 Parent
->_TaskResult
= TaskResult_Error
;
801 ucstring errorMsg
; // OLD
802 msg
.serial(errorMsg
);
803 throw EDownloadException(errorMsg
.toUtf8());
817 //=====================================================
818 void CBGDownloaderAccess::CDownloadCoTask::checkDownloaderAlive()
820 if (!Parent
->_DownloaderMsgQueue
.connected() || !isDownloaderProcessRunning())
822 throw EDownloadException(CI18N::get("uiBGD_DownloaderDisconnected"));
827 //=====================================================
828 void CBGDownloaderAccess::CDownloadCoTask::sendMsg(NLMISC::CMemStream
&msg
)
830 Parent
->_DownloaderMsgQueue
.sendMessage(msg
);
833 //=====================================================
834 void CBGDownloaderAccess::CDownloadCoTask::sendSimpleMsg(BGDownloader::TMsgType msgType
)
836 //nlwarning("##CLIENT SEND simple message of type : %s", toString(msgType).c_str());
837 Parent
->sendSimpleMsg(msgType
);
840 //=====================================================
841 void CBGDownloaderAccess::reboot()
843 CPatchManager
*pm
= CPatchManager::getInstance();
844 pm
->createBatchFile(_DescFile
);
845 pm
->executeBatchFile();
848 //=====================================================
849 void CBGDownloaderAccess::requestDownloadThreadPriority(BGDownloader::TThreadPriority newPriority
, bool freezeUI
)
851 nlassert((uint
) newPriority
< BGDownloader::ThreadPriority_Count
);
852 CMemStream
outMsg(false /* output stream */);
853 TMsgType msgType
= CL_SetPriority
;
854 outMsg
.serialEnum(msgType
);
855 outMsg
.serialEnum(newPriority
);
856 outMsg
.serial(freezeUI
);
857 _DownloaderMsgQueue
.sendMessage(outMsg
);
858 _FrozenUI
= freezeUI
;
865 //=====================================================
866 CBGDownloaderAccess::CBGDownloaderAccess()
871 //=====================================================
872 CBGDownloaderAccess::~CBGDownloaderAccess()
877 //=====================================================
878 bool CBGDownloaderAccess::getPatchCompletionFlag(bool clearFlag
)
884 //=====================================================
885 void CBGDownloaderAccess::startTask(const BGDownloader::CTaskDesc
&taskDesc
, const std::string
&commandLine
, bool showDownloader
)
890 //=====================================================
891 bool CBGDownloaderAccess::isTaskEnded(BGDownloader::TTaskResult
&result
, ucstring
&errorMsg
) const // OLD
897 //=====================================================
898 void CBGDownloaderAccess::update()
903 //=====================================================
904 void CBGDownloaderAccess::release()
909 //=====================================================
910 void CBGDownloaderAccess::requestDownloadThreadPriority(BGDownloader::TThreadPriority newPriority
, bool freezeUI
)
915 //=====================================================
916 void CBGDownloaderAccess::reboot()
920 // not supported on other os
921 //#error IMPLEMENT ME PLEASE !!
926 bool isBGDownloadEnabled()
928 return ClientCfg
.BackgroundDownloader
&& !ClientCfg
.Local
&& ClientCfg
.PatchWanted
;
932 static BGDownloader::TThreadPriority DownloaderPriorityBackup
= BGDownloader::ThreadPriority_Low
;
933 static bool DownloaderUIFrozen
= false;
934 static bool DownloaderPaused
= false;
937 // ------------------------------------------------------------------------------------------------
938 void pauseBGDownloader()
940 if (isBGDownloadEnabled() && !DownloaderPaused
)
942 CBGDownloaderAccess
&downloader
= CBGDownloaderAccess::getInstance();
943 DownloaderPriorityBackup
= downloader
.getDownloadThreadPriority();
944 DownloaderUIFrozen
= downloader
.isDownloaderUIFrozen();
945 downloader
.requestDownloadThreadPriority(BGDownloader::ThreadPriority_Paused
, true);
946 DownloaderPaused
= true;
950 // ------------------------------------------------------------------------------------------------
951 void unpauseBGDownloader()
953 if (isBGDownloadEnabled() && DownloaderPaused
)
955 if (DownloaderPriorityBackup
!= BGDownloader::ThreadPriority_DownloaderError
)
957 CBGDownloaderAccess::getInstance().requestDownloadThreadPriority(DownloaderPriorityBackup
, DownloaderUIFrozen
);
959 DownloaderPaused
= false;