@@ -167,6 +167,10 @@ async def __aenter__(self):
167167 # check Python-version
168168 self .log .info (f'- Python version { platform .python_version ()} detected.' )
169169
170+ # check UAC
171+ if utils .is_uac_enabled ():
172+ self .log .warning ('- You need to disable User Access Control (UAC) to allow some commands to run.' )
173+
170174 # install plugins
171175 await self ._install_plugins ()
172176
@@ -629,40 +633,115 @@ def run_subprocess() -> int:
629633 message = _ ('Server is going down for a DCS update in {}!' )
630634 ):
631635 self .log .info (f"Updating { self .installation } ..." )
632- # call before update hooks
636+ # call before_update hooks
633637 for callback in self .before_update .values ():
634638 await callback ()
635- old_branch , old_version = await self .get_dcs_branch_and_version ()
636- if not branch :
637- branch = old_branch
638- if not version :
639- version = await self .get_latest_version (branch )
640- rc = await do_update (branch , version )
641- if rc in [0 , 350 ]:
642- self .dcs_branch = self .dcs_version = None
643- dcs_branch , dcs_version = await self .get_dcs_branch_and_version ()
644- # if only the updater updated itself, run the update again
645- if old_branch == dcs_branch and old_version == dcs_version :
646- self .log .info ("dcs_updater.exe updated to the latest version, now updating DCS World ..." )
647- rc = await do_update (branch , version )
639+ try :
640+ old_branch , old_version = await self .get_dcs_branch_and_version ()
641+ if not branch :
642+ branch = old_branch
643+ if not version :
644+ version = await self .get_latest_version (branch )
645+ rc = await do_update (branch , version )
646+ if rc in [0 , 350 ]:
648647 self .dcs_branch = self .dcs_version = None
649- await self .get_dcs_branch_and_version ()
650- if rc not in [0 , 350 ]:
651- return rc
652- # Patch DCS files
653- if not self .locals ['DCS' ].get ('cloud' , False ) or self .master :
654- if self .locals ['DCS' ].get ('desanitize' , True ):
655- utils .desanitize (self )
656- # init profanity filter, if needed
657- if any (
658- instance .server .locals .get ('profanity_filter' , False )
659- for instance in self .instances if instance .server
660- ):
661- utils .init_profanity_filter (self )
662- # call after update hooks
648+ dcs_branch , dcs_version = await self .get_dcs_branch_and_version ()
649+ # if only the updater updated itself, run the update again
650+ if old_branch == dcs_branch and old_version == dcs_version :
651+ self .log .info ("dcs_updater.exe updated to the latest version, now updating DCS World ..." )
652+ rc = await do_update (branch , version )
653+ self .dcs_branch = self .dcs_version = None
654+ await self .get_dcs_branch_and_version ()
655+ if rc not in [0 , 350 ]:
656+ return rc
657+ # Patch DCS files
658+ if not self .locals ['DCS' ].get ('cloud' , False ) or self .master :
659+ if self .locals ['DCS' ].get ('desanitize' , True ):
660+ utils .desanitize (self )
661+ # init profanity filter, if needed
662+ if any (
663+ instance .server .locals .get ('profanity_filter' , False )
664+ for instance in self .instances if instance .server
665+ ):
666+ utils .init_profanity_filter (self )
667+ self .log .info (f"{ self .installation } updated to version { dcs_version } ." )
668+ return rc
669+ finally :
670+ # call after_update hooks
671+ for callback in self .after_update .values ():
672+ await callback ()
673+ self .update_pending = False
674+
675+ async def dcs_repair (self , warn_times : list [int ] = None , slow : bool | None = False ,
676+ check_extra_files : bool | None = False ):
677+
678+ async def do_repair () -> int :
679+ def run_subprocess () -> int :
680+ if sys .platform != 'win32' :
681+ raise NotImplementedError ("DCS repair is not yet supported on Linux" )
682+
683+ if utils .is_uac_enabled ():
684+ raise PermissionError ("You need to disable UAC to run a DCS repair." )
685+
686+ args = [
687+ "core/utils/updater_wrapper.py" ,
688+ "-d" , os .path .normpath (self .installation ),
689+ ]
690+ if slow :
691+ args .append ("-s" )
692+ if check_extra_files :
693+ args .append ("-c" )
694+ cmdline = subprocess .list2cmdline (args )
695+ return utils .run_elevated (
696+ sys .executable ,
697+ os .getcwd (),
698+ cmdline
699+ )
700+
701+ # check if there is an update / repair running already
702+ proc = next (utils .find_process ("DCS_updater.exe" ), None )
703+ if proc :
704+ self .log .info ("- DCS Update / repair in progress, waiting ..." )
705+ while proc .is_running ():
706+ await asyncio .sleep (1 )
707+
708+ return await asyncio .to_thread (run_subprocess )
709+
710+ self .update_pending = True
711+ async with ServerMaintenanceManager (
712+ self .node ,
713+ warn_times = warn_times ,
714+ message = _ ('Server is going down for maintenance in {}!' )
715+ ):
716+ self .log .info (f"Repairing { self .installation } ..." )
717+ # call before_update hooks
718+ for callback in self .before_update .values ():
719+ await callback ()
720+ try :
721+ rc = await do_repair ()
722+ if rc == 0 :
723+ # Patch DCS files
724+ if not self .locals ['DCS' ].get ('cloud' , False ) or self .master :
725+ if self .locals ['DCS' ].get ('desanitize' , True ):
726+ utils .desanitize (self )
727+ # init profanity filter, if needed
728+ if any (
729+ instance .server .locals .get ('profanity_filter' , False )
730+ for instance in self .instances if instance .server
731+ ):
732+ utils .init_profanity_filter (self )
733+ self .log .info (f"{ self .installation } repaired." )
734+ else :
735+ self .log .error (f"Repair of { self .installation } failed with code { rc } ." )
736+ except PermissionError :
737+ raise
738+ except OSError as ex :
739+ self .log .error (f"Repair of { self .installation } failed with code { ex .errno } ." )
740+ return ex .errno
741+ finally :
742+ # call after_update hooks
663743 for callback in self .after_update .values ():
664744 await callback ()
665- self .log .info (f"{ self .installation } updated to version { dcs_version } ." )
666745 self .update_pending = False
667746 return rc
668747
0 commit comments