diff --git a/.gitignore b/.gitignore index bed84f6..263e872 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,7 @@ config.ini file_version_info.txt lamo-watcher.exe lamo-launcher.exe -logs/ \ No newline at end of file +logs/ +index.build/ +index.dist/ +index.onefile-build \ No newline at end of file diff --git a/README.md b/README.md index cba77ad..8e1d58d 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ Audio files from [MixKit](https://mixkit.co/) ### Changelog +### 1.2.6.2 +- Update VolumeController threadsafe +- Fix watcher update operation + ### 1.2.4.1 - Update and relaunch procedure rework diff --git a/compile.py b/compile.py index b540b15..7bc5df4 100644 --- a/compile.py +++ b/compile.py @@ -1,16 +1,10 @@ -import PyInstaller.__main__ - +import os from modules.config import Config -import pyinstaller_versionfile -pyinstaller_versionfile.create_versionfile_from_input_file( - output_file="file_version_info.txt", - input_file="metadata.yml", - version=Config().version -) +Config().version -PyInstaller.__main__.run([ - 'compile.spec', - '--clean' -]) \ No newline at end of file +if Config().debug: + os.system(f'python -m nuitka --standalone --windows-icon-from-ico=assets/icons/favicon.ico --enable-plugin=pyside6 --include-data-dir=assets=assets --follow-imports --onefile --windows-file-version={Config().version} --windows-product-version={Config().version} --windows-company-name="Lost Ark Market Online" --windows-product-name="Lost Ark Market Online Launcher App" --windows-file-description="Lost Ark Market Online Launcher App" -o lamo-launcher-debug.exe index.py') +else: + os.system(f'python -m nuitka --standalone --windows-icon-from-ico=assets/icons/favicon.ico --enable-plugin=pyside6 --include-data-dir=assets=assets --follow-imports --onefile --windows-disable-console --windows-file-version={Config().version} --windows-product-version={Config().version} --windows-company-name="Lost Ark Market Online" --windows-product-name="Lost Ark Market Online Launcher App" --windows-file-description="Lost Ark Market Online Launcher App" -o lamo-launcher.exe index.py') \ No newline at end of file diff --git a/compile.spec b/compile.spec deleted file mode 100644 index 8e07b7f..0000000 --- a/compile.spec +++ /dev/null @@ -1,46 +0,0 @@ -# -*- mode: python ; coding: utf-8 -*- - - -block_cipher = None - - -a = Analysis( - ['index.py'], - pathex=['.env/Lib/site-packages'], - binaries=[], - datas=[('assets', 'assets')], - hiddenimports=[], - hookspath=[], - hooksconfig={}, - runtime_hooks=[], - excludes=[], - win_no_prefer_redirects=False, - win_private_assemblies=False, - cipher=block_cipher, - noarchive=False, -) -pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) - -exe = EXE( - pyz, - a.scripts, - a.binaries, - a.zipfiles, - a.datas, - [], - name='lamo-launcher', - debug=False, - bootloader_ignore_signals=False, - strip=False, - upx=True, - upx_exclude=[], - runtime_tmpdir=None, - console=False, - disable_windowed_traceback=False, - argv_emulation=False, - target_arch=None, - codesign_identity=None, - entitlements_file=None, - icon='assets\\icons\\favicon.ico', - version='file_version_info.txt' -) diff --git a/compile_release.sh b/compile_release.sh index d0d6a48..c4061c8 100644 --- a/compile_release.sh +++ b/compile_release.sh @@ -1 +1 @@ -pyinstaller release.spec \ No newline at end of file +python -m nuitka --standalone --windows-icon-from-ico=assets/icons/favicon.ico --enable-plugin=pyside6 --include-data-dir=assets=assets --follow-imports --onefile --windows-disable-console --windows-file-version=1.2.4.1 --windows-product-version=1.2.4.1 --windows-company-name="Lost Ark Market Online" --windows-product-name="Lost Ark Market Online Launcher App" -o lamo-launcher.exe index.py \ No newline at end of file diff --git a/file_version_info.txt b/file_version_info.txt deleted file mode 100644 index 2fe6a52..0000000 --- a/file_version_info.txt +++ /dev/null @@ -1,44 +0,0 @@ -# UTF-8 -# -# For more details about fixed file info 'ffi' see: -# http://msdn.microsoft.com/en-us/library/ms646997.aspx - -VSVersionInfo( - ffi=FixedFileInfo( - # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4) - # Set not needed items to zero 0. Must always contain 4 elements. - filevers=(1,2,3,1), - prodvers=(1,2,3,1), - # Contains a bitmask that specifies the valid bits 'flags'r - mask=0x3f, - # Contains a bitmask that specifies the Boolean attributes of the file. - flags=0x0, - # The operating system for which this file was designed. - # 0x4 - NT and there is no need to change it. - OS=0x40004, - # The general type of file. - # 0x1 - the file is an application. - fileType=0x1, - # The function of the file. - # 0x0 - the function is not defined for this fileType - subtype=0x0, - # Creation date and time stamp. - date=(0, 0) - ), - kids=[ - StringFileInfo( - [ - StringTable( - u'040904B0', - [StringStruct(u'CompanyName', u'Lost Ark Market Online'), - StringStruct(u'FileDescription', u'Lost Ark Market Online Launcher App'), - StringStruct(u'FileVersion', u'1.2.3.1'), - StringStruct(u'InternalName', u'Launcher App'), - StringStruct(u'LegalCopyright', u'© Lost Ark Market Online'), - StringStruct(u'OriginalFilename', u'lamo-launcher.exe'), - StringStruct(u'ProductName', u'Lost Ark Market Online Launcher App'), - StringStruct(u'ProductVersion', u'1.2.3.1')]) - ]), - VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) - ] -) \ No newline at end of file diff --git a/index.py b/index.py index bb6ebfa..74c6ffc 100644 --- a/index.py +++ b/index.py @@ -1,3 +1,4 @@ +from time import sleep from modules.logging import AppLogger from modules.messagebox import MessageBoxHandler import modules.single_instance @@ -87,12 +88,13 @@ def login_success(self): # Watcher Version Check def check_config(self): Config().check_watcher_version() + print(f"Needs watcher update: {Config().watcher_needs_update}") if Config().watcher_needs_update == True: playUpdateDetected() self.download = LostArkMarketLauncherDownload({ "url": f'https://github.com/gogodr/LostArk-Market-Watcher/releases/download/{Config().watcher_version}/{Config().watcher_file}.exe', "title": f'New version of the Lost Ark Market Watcher Found: v{Config().watcher_version}', - "file": f'{Config().watcher_file}.exe' + "file": f'{Config().watcher_file}.exe.new' }) self.download.launch.connect(self.launch_watcher) self.download.finished_download.connect(self.watcher_downloaded) @@ -106,13 +108,18 @@ def watcher_downloaded(self): self.launch_watcher() def launch_watcher(self): + sleep(2) + if os.path.exists(f"{Config().watcher_file}.exe.new") == True: + if os.path.exists(f"{Config().watcher_file}.exe") == True: + os.system(f"del /f {Config().watcher_file}.exe") + os.system(f"rename {Config().watcher_file}.exe.new {Config().watcher_file}.exe") + sleep(2) playSuccess() si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call(f"{Config().watcher_file}.exe") sys.exit() - if __name__ == "__main__": try: Config() diff --git a/modules/config.py b/modules/config.py index da3fcd4..46d7d66 100644 --- a/modules/config.py +++ b/modules/config.py @@ -7,7 +7,7 @@ class Config(metaclass=Singleton): - version = "1.2.4.1" + version = "1.2.6.2" debug = False id_token: str = None refresh_token: str = None @@ -47,7 +47,6 @@ def load_config(self): "Watcher", "play_audio") == 'True' else: self.play_audio = True - changes = True if self._config.has_option("Watcher", "volume"): self.volume = float(self._config.get( @@ -120,6 +119,7 @@ def HIWORD(dword): curr_version = version.parse( f"{HIWORD(ms)}.{LOWORD(ms)}.{HIWORD(ls)}.{LOWORD(ls)}") latest_version = version.parse(self.launcher_version) + pe.close() if latest_version > curr_version: self.launcher_needs_update = True @@ -148,6 +148,7 @@ def HIWORD(dword): curr_version = version.parse( f"{HIWORD(ms)}.{LOWORD(ms)}.{HIWORD(ls)}.{LOWORD(ls)}") latest_version = version.parse(self.watcher_version) + pe.close() if latest_version > curr_version: - self.needs_update = True + self.watcher_needs_update = True diff --git a/modules/sound.py b/modules/sound.py index 90b6870..ed2e612 100644 --- a/modules/sound.py +++ b/modules/sound.py @@ -1,10 +1,13 @@ import sys from threading import Thread +import threading +from time import sleep import simpleaudio as sa import os from pycaw.pycaw import AudioUtilities from modules.common.singleton import Singleton from modules.config import Config +from modules.logging import AppLogger class PlaySoundThread(Thread): @@ -43,25 +46,49 @@ def playDownloadComplete(): class VolumeController(metaclass=Singleton): + sessions = None audio = None volume = 1.0 + lock = threading.Lock() def __init__(self): - self.searchProcess() + self.sessions = AudioUtilities.GetAllSessions() + spt = Thread(target=self.searchProcess) + spt.start() - def searchProcess(self): - sessions = AudioUtilities.GetAllSessions() - file_name = os.path.basename(sys.executable) + def searchProcess(self, retries = 0): + if self.lock.locked() or self.audio: + return + file_name = os.path.basename(sys.argv[0]) + self.lock.acquire() + try: + self.sessions = AudioUtilities.GetAllSessions() + AppLogger().info(f"VolumeController - FileName: {file_name} - retry: {retries}") + for session in self.sessions: + if session.Process and session.Process.name() == file_name: + AppLogger().info(f"VolumeController - FileName: {file_name} - Found") + self.audio = session.SimpleAudioVolume + self.volume = self.audio.GetMasterVolume() + self.setVolume(Config().volume/100) + break + except Exception as ex: + AppLogger().exception(ex) - for session in sessions: - if session.Process and session.Process.name() == file_name: - self.audio = session.SimpleAudioVolume - self.volume = self.audio.GetMasterVolume() - self.setVolume(Config().volume/100) - break + if(self.audio is None): + if retries < 3: + sleep(2) + if self.lock.locked(): + self.lock.release() + self.searchProcess(retries+1) + else: + AppLogger().error(f"VolumeController - FileName: {file_name} - Not Found") + if self.lock.locked(): + self.lock.release() def setVolume(self, volume): if self.audio: self.audio.SetMasterVolume(volume, None) else: - self.searchProcess() + self.sessions = AudioUtilities.GetAllSessions() + spt = Thread(target=self.searchProcess) + spt.start()