From dce90aa87201e42dcc64e5bc4641884fa41d0620 Mon Sep 17 00:00:00 2001 From: cidoku Date: Tue, 14 Oct 2025 16:31:51 -0300 Subject: [PATCH] music: add currently playing song to private list --- README.md | 4 ++-- gameview.py | 48 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6a0e57e..6fa4482 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ Features added since the last commit of - Exporting/importing evidence to/from a file - Timers - Slide animations (work in progress) -- Compatiblity with AO2 themes (pre-2.11, work in progress) +- Compatiblity with AO2 themes (pre-2.11, work in progress but mostly working) - Player, area, and background lists -- Search boxes on music list and character select +- Search boxes on music list, background list and character select - Join a server automatically on launch - Pick a character and join an area automatically on join - Demo recording and playback with a seekbar, no need to send messages to OOC diff --git a/gameview.py b/gameview.py index c17692e..537fc16 100644 --- a/gameview.py +++ b/gameview.py @@ -110,7 +110,7 @@ def mockString(text): class MusicDownloadThread(QtCore.QThread): # Part of the evil HTTPS music download hack for XP systems - finished_signal = QtCore.pyqtSignal(int) + finished_signal = QtCore.pyqtSignal(int, str) def __init__(self, caller, url): super(MusicDownloadThread, self).__init__() @@ -169,7 +169,7 @@ class MusicDownloadThread(QtCore.QThread): if not self.exiting: self.caller.stream = create_string_buffer(stream) - self.finished_signal.emit(file_length) + self.finished_signal.emit(file_length, self.url) else: print "[audio] Stream is empty, aborting..." self.quit() @@ -1386,6 +1386,9 @@ class GUI(QtGui.QWidget): self.actMusicCopy = QtGui.QAction(QtGui.QIcon(AO2XPpath + "icons/" + "page_copy.png"), "&Copy selected song name", self.tabMusic) self.actMusicCopy.triggered.connect(self.onActMusicCopyTriggered) self.actMusicCopy.setDisabled(True) + self.actMusicAddCurrent = QtGui.QAction(QtGui.QIcon(AO2XPpath + "icons/" + "add.png"), "Add current song to private list", self.tabMusic) + self.actMusicAddCurrent.triggered.connect(self.onActMusicAddCurrentTriggered) + self.actMusicAddCurrent.setDisabled(True) self.actMusicSeparator = QtGui.QAction(self.tabMusic) self.actMusicSeparator.setSeparator(True) self.actMusicAdd = QtGui.QAction(QtGui.QIcon(AO2XPpath + "icons/" + "add.png"), "&Add new entry", self.tabMusic) @@ -1413,6 +1416,7 @@ class GUI(QtGui.QWidget): self.mnuMusicOptions = QtGui.QMenu(self.tabMusic) self.mnuMusicOptions.addAction(self.actMusicRandom) self.mnuMusicOptions.addAction(self.actMusicCopy) + self.mnuMusicOptions.addAction(self.actMusicAddCurrent) self.mnuMusicOptions.addAction(self.actMusicSeparator) self.mnuMusicOptions.addAction(self.actMusicAdd) self.mnuMusicOptions.addAction(self.actMusicEdit) @@ -1717,6 +1721,7 @@ class GUI(QtGui.QWidget): self.demoPlaying = False self.musicList = {} self.pickedMusicItem = False + self.currentMusicURL = None self.slideEnabled = getOption("General", "slide", False) == 'True' self.slideAvailable = False @@ -2339,6 +2344,14 @@ class GUI(QtGui.QWidget): with open(AO2XPpath + "music.ini", "ab") as f: f.write(("\n" + title + " = " + url).toUtf8()) self.onActMusicRefreshTriggered() + + def onActMusicAddCurrentTriggered(self): + title, ok = QtGui.QInputDialog.getText(self, "Add currently playing song", "Please enter a title for the song.") + if title and ok: + with open(AO2XPpath + "music.ini", "ab") as f: + f.write(("\n" + title + " = " + self.currentMusicURL).toUtf8()) + if self.privateMusicSelected: + self.onActMusicRefreshTriggered() def onActMusicEditTriggered(self): pass @@ -2988,6 +3001,7 @@ class GUI(QtGui.QWidget): self.OOCLogin.setText("Lo&gin") self.login = False self.privateInventorySelected = False + self.setCurrentMusicURL(None) if self.tcp: self.tcp.close() if self.demoPlayer: @@ -4254,6 +4268,7 @@ class GUI(QtGui.QWidget): def playMusic(self, mus): self.stopMusic() if mus == "~stop.mp3" or not mus: + self.setCurrentMusicURL(None) return _musicList = self.musicListPrivate if self.privateMusicSelected else self.musicList @@ -4289,6 +4304,7 @@ class GUI(QtGui.QWidget): if self.music: audio.setHandleAttr(self.music, BASS_ATTRIB_VOL, self.sliMusicVolume.value() / 100.0) audio.playHandle(self.music, True) + self.setCurrentMusicURL(mus) if self.sliMusicVolume.value() == 0: audio.pauseHandle(self.music) else: @@ -4308,20 +4324,23 @@ class GUI(QtGui.QWidget): if self.music: audio.setHandleAttr(self.music, BASS_ATTRIB_VOL, self.sliMusicVolume.value() / 100.0) audio.playHandle(self.music, True) + self.setCurrentMusicURL(mus) if self.sliMusicVolume.value() == 0: audio.pauseHandle(self.music) else: + # Evil HTTPS hack for XP systems error = audio.getBassError() - #print "[audio] Couldn't play music. Error", error - # Here comes the evil HTTPS hack for XP systems, but it also allows us to download and play modules, because, why not? musext = os.path.splitext(basename(musl))[-1] if musext in ['.xm', '.mod', '.mo3', '.it', '.s3m', '.mtm', '.umx']: + # BASS can play modules, so might as well support them self.specialStream = True if (musl.startswith("https") and error == 2) or self.specialStream: print "[audio] Downloading music with urllib2" self.downloadThread = MusicDownloadThread(self, mus.replace(" ", "%20")) self.downloadThread.finished_signal.connect(self.playDownloadedMusic) self.downloadThread.start() + else: + print "[audio] Couldn't play music. Error", error def stopMusic(self): if self.music: @@ -4337,20 +4356,27 @@ class GUI(QtGui.QWidget): if self.downloadThread: self.downloadThread.stop() - #self.downloadThread.wait() self.downloadThread = None - def playDownloadedMusic(self, file_length): + def playDownloadedMusic(self, file_length, url): # Part of the evil HTTPS music download hack for XP systems - print "[audio] Done downloading; playing stream" if self.specialStream: self.music = audio.loadMOD(True, self.stream, 0, file_length, BASS_SAMPLE_LOOP) else: self.music = audio.loadHandle(True, self.stream, 0, file_length, BASS_SAMPLE_LOOP) - audio.setHandleAttr(self.music, BASS_ATTRIB_VOL, self.sliMusicVolume.value() / 100.0) - audio.playHandle(self.music, True) - if self.sliMusicVolume.value() == 0: - audio.pauseHandle(self.music) + if self.music: + print "[audio] Done downloading; playing stream" + audio.setHandleAttr(self.music, BASS_ATTRIB_VOL, self.sliMusicVolume.value() / 100.0) + audio.playHandle(self.music, True) + self.setCurrentMusicURL(url) + if self.sliMusicVolume.value() == 0: + audio.pauseHandle(self.music) + else: + print "[audio] Done downloading, but the stream couldn't be played. Error", audio.getBassError() + + def setCurrentMusicURL(self, url): + self.currentMusicURL = url + self.actMusicAddCurrent.setDisabled(url is None) def loadAllMusic(self): _musicList = self.musicListPrivate if self.privateMusicSelected else self.musicList