Playback of demos with seekbar

This commit is contained in:
cidoku 2025-03-10 05:05:13 -03:00
parent 5122e83a7e
commit 237524c1d4
2 changed files with 116 additions and 27 deletions

View File

@ -15,6 +15,8 @@ self.emotedropdown.setGeometry(164 - 28, 344 + 66 + 4, 72, 20)
self.colordropdown.setGeometry(self.emotedropdown.x(), 376 + 64, 72, 20) self.colordropdown.setGeometry(self.emotedropdown.x(), 376 + 64, 72, 20)
self.posdropdown.setGeometry(self.emotedropdown.x() + self.emotedropdown.size().width() + 4, self.emotedropdown.y(), 72, 20) self.posdropdown.setGeometry(self.emotedropdown.x() + self.emotedropdown.size().width() + 4, self.emotedropdown.y(), 72, 20)
self.demoslider.setGeometry(self.icchatinput.x(), self.icchatinput.y(), VIEWPORT_W, 23)
self.flipbutton.move(self.posdropdown.x() + self.posdropdown.width() + 4, self.colordropdown.y() - 5) self.flipbutton.move(self.posdropdown.x() + self.posdropdown.width() + 4, self.colordropdown.y() - 5)
self.sfxbutton.move(self.flipbutton.x(), self.flipbutton.y() + 14) self.sfxbutton.move(self.flipbutton.x(), self.flipbutton.y() + 14)
self.nointerruptbtn.move(self.flipbutton.x() + 140, self.flipbutton.y()) self.nointerruptbtn.move(self.flipbutton.x() + 140, self.flipbutton.y())

View File

@ -3,6 +3,7 @@ from os.path import exists, basename
from ConfigParserEdit import ConfigParser from ConfigParserEdit import ConfigParser
from constants import * from constants import *
from collections import OrderedDict from collections import OrderedDict
from bisect import bisect_left
from pybass_constants import * from pybass_constants import *
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
@ -1030,6 +1031,8 @@ class gui(QtGui.QWidget):
self.areaitems = QtGui.QListWidget() self.areaitems = QtGui.QListWidget()
self.areaitems.itemDoubleClicked.connect(self.onAreaClick) self.areaitems.itemDoubleClicked.connect(self.onAreaClick)
self.demoitems = QtGui.QListWidget()
self.demoitems.itemDoubleClicked.connect(self.onDemoClick)
self.icLog = ChatLogs(self.gametab_log, 0, self.ooclog.logfile) self.icLog = ChatLogs(self.gametab_log, 0, self.ooclog.logfile)
self.icLog.setReadOnly(True) self.icLog.setReadOnly(True)
@ -1185,6 +1188,7 @@ class gui(QtGui.QWidget):
self.musicareatabs.addTab(self.gametab_music, "&Music") self.musicareatabs.addTab(self.gametab_music, "&Music")
self.musicareatabs.addTab(self.areaitems, "&Areas") self.musicareatabs.addTab(self.areaitems, "&Areas")
self.musicareatabs.addTab(self.gametab_players, 'Pla&yers') self.musicareatabs.addTab(self.gametab_players, 'Pla&yers')
self.musicareatabs.addTab(self.demoitems, "Demos")
self.icchatinput = QtGui.QLineEdit(self) self.icchatinput = QtGui.QLineEdit(self)
self.icchatinput.returnPressed.connect(self.onICreturn) self.icchatinput.returnPressed.connect(self.onICreturn)
@ -1344,6 +1348,11 @@ class gui(QtGui.QWidget):
self.pinglabel = QtGui.QLabel(self) self.pinglabel = QtGui.QLabel(self)
self.demoslider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
self.demoslider.valueChanged.connect(self.demoSeek)
self.demoslider.setVisible(False)
self.demoslider.setMinimum(0)
self.name.show() self.name.show()
self.char.show() self.char.show()
self.court.show() self.court.show()
@ -2122,6 +2131,12 @@ class gui(QtGui.QWidget):
area = item.text().split('\n')[0] area = item.text().split('\n')[0]
self.sendMC(area) self.sendMC(area)
def onDemoClick(self, item):
self.tcpthread.stop()
self.demoplayer.start(item.text())
self.demoslider.setVisible(True)
self.icchatinput.setVisible(False)
def sendMC(self, content): def sendMC(self, content):
if "cccc_ic_support" in self.features and self.showname: if "cccc_ic_support" in self.features and self.showname:
self.tcp.send('MC#' + content + '#' + str(self.mychar) + '#' + self.showname + '#%') self.tcp.send('MC#' + content + '#' + str(self.mychar) + '#' + self.showname + '#%')
@ -3501,6 +3516,9 @@ class gui(QtGui.QWidget):
if self.onscreen_timer_times == [0, 0, 0, 0, 0]: if self.onscreen_timer_times == [0, 0, 0, 0, 0]:
self.onscreen_timer.stop() self.onscreen_timer.stop()
def demoSeek(self, time):
self.demoplayer.seek(time)
def startGame(self, tcp, playerlist, charlist, musiclist, background, evidence, areas, features=[], oocjoin=[], hplist=[], webAO_bucket=""): def startGame(self, tcp, playerlist, charlist, musiclist, background, evidence, areas, features=[], oocjoin=[], hplist=[], webAO_bucket=""):
self.willDisconnect = False self.willDisconnect = False
self.mychar = -1 self.mychar = -1
@ -3587,6 +3605,7 @@ class gui(QtGui.QWidget):
self.musicitems.clear() self.musicitems.clear()
self.areaitems.clear() self.areaitems.clear()
self.demoitems.clear()
self.evidencedropdown.clear() self.evidencedropdown.clear()
for evi in evidence: for evi in evidence:
self.evidencedropdown.addItem(evi[0].strip()) self.evidencedropdown.addItem(evi[0].strip())
@ -3627,6 +3646,10 @@ class gui(QtGui.QWidget):
self.onImportEvidence(True) self.onImportEvidence(True)
for demo in os.listdir('chatlogs'):
if os.path.splitext(basename(demo))[-1].lower() == ".demo":
self.demoitems.addItem(demo)
self.tcpthread = TCP_Thread(self) self.tcpthread = TCP_Thread(self)
self.tcpthread.MS_Chat.connect(self.netmsg_ms) self.tcpthread.MS_Chat.connect(self.netmsg_ms)
self.tcpthread.newChar.connect(self.onPVPacket) self.tcpthread.newChar.connect(self.onPVPacket)
@ -3641,20 +3664,17 @@ class gui(QtGui.QWidget):
self.tcpthread.timerUpdate.connect(self.start_pause_timers) self.tcpthread.timerUpdate.connect(self.start_pause_timers)
self.tcpthread.start() self.tcpthread.start()
# self.demoplayer = DemoPlayer(self) self.demoplayer = DemoPlayer(self)
# self.demoplayer.MS_Chat.connect(self.netmsg_ms) self.demoplayer.MS_Chat.connect(self.netmsg_ms)
# self.demoplayer.newChar.connect(self.onPVPacket) self.demoplayer.newChar.connect(self.onPVPacket)
# self.demoplayer.newBackground.connect(self.setBackground) self.demoplayer.newBackground.connect(self.setBackground)
# self.demoplayer.OOC_Log.connect(self.ooclog.append) self.demoplayer.OOC_Log.connect(self.ooclog.append)
# self.demoplayer.IC_Log.connect(self.icLog.append) self.demoplayer.IC_Log.connect(self.icLog.append)
# self.demoplayer.charSlots.connect(partial(self.charselect.setCharList, self.charlist)) self.demoplayer.charSlots.connect(partial(self.charselect.setCharList, self.charlist))
# self.demoplayer.showCharSelect.connect(self.charselect.showCharSelect) self.demoplayer.allEvidence.connect(self.allEvidence)
# self.demoplayer.allEvidence.connect(self.allEvidence) self.demoplayer.updatePlayerList.connect(self.updatePlayerList)
# self.demoplayer.updatePlayerList.connect(self.updatePlayerList) self.demoplayer.rainbowColor.connect(self.text.setStyleSheet)
# self.demoplayer.rainbowColor.connect(self.text.setStyleSheet) self.demoplayer.timerUpdate.connect(self.start_pause_timers)
# self.demoplayer.timerUpdate.connect(self.start_pause_timers)
# self.demoplayer.load_demo('test.demo')
# self.demoplayer.step()
self.icchatinput.setFocus() self.icchatinput.setFocus()
@ -3674,6 +3694,7 @@ class TCP_Thread(QtCore.QThread):
send_attempts = 0 send_attempts = 0
max_attempts = 5 max_attempts = 5
stop_now = False
def __init__(self, parent): def __init__(self, parent):
super(TCP_Thread, self).__init__(parent) super(TCP_Thread, self).__init__(parent)
@ -3686,8 +3707,11 @@ class TCP_Thread(QtCore.QThread):
tempdata = "" tempdata = ""
color = QtGui.QColor() color = QtGui.QColor()
color.setHsv(rainbow, 255, 255) color.setHsv(rainbow, 255, 255)
#color.setHsv(0, 255, 255)
while True: while True:
if self.stop_now:
self.quit()
return
if self.parent.disconnectnow: if self.parent.disconnectnow:
self.parent.disconnectCommon() self.parent.disconnectCommon()
self.quit() self.quit()
@ -3739,15 +3763,16 @@ class TCP_Thread(QtCore.QThread):
handle_packets(self, total) handle_packets(self, total)
def stop(self):
self.stop_now = True
class DemoPlayer(QtCore.QObject): class DemoPlayer(QtCore.QObject):
connectionError = QtCore.pyqtSignal(str, str, str)
MS_Chat = QtCore.pyqtSignal(list) MS_Chat = QtCore.pyqtSignal(list)
newChar = QtCore.pyqtSignal(str) newChar = QtCore.pyqtSignal(str)
newBackground = QtCore.pyqtSignal(str, bool) newBackground = QtCore.pyqtSignal(str, bool)
IC_Log = QtCore.pyqtSignal(str) IC_Log = QtCore.pyqtSignal(str)
OOC_Log = QtCore.pyqtSignal(str) OOC_Log = QtCore.pyqtSignal(str)
charSlots = QtCore.pyqtSignal() charSlots = QtCore.pyqtSignal()
showCharSelect = QtCore.pyqtSignal()
allEvidence = QtCore.pyqtSignal(list) allEvidence = QtCore.pyqtSignal(list)
rainbowColor = QtCore.pyqtSignal(str) rainbowColor = QtCore.pyqtSignal(str)
updatePlayerList = QtCore.pyqtSignal(str, int, int, str) updatePlayerList = QtCore.pyqtSignal(str, int, int, str)
@ -3759,33 +3784,91 @@ class DemoPlayer(QtCore.QObject):
self.paused = False self.paused = False
self.demo = [] self.demo = []
self.demo_length = len(self.demo) self.demo_length = len(self.demo)
self.index = 0 self.time = 0
self.wait_timer = QtCore.QTimer(self) self.wait_timer = QtCore.QTimer(self)
self.wait_timer.setSingleShot(True) self.wait_timer.setSingleShot(True)
self.wait_timer.timeout.connect(self.timer_done) self.wait_timer.timeout.connect(self.timer_done)
self.mc = [] # Music changes
self.bn = [] # Background changes
self.last_music = ""
self.last_bg = ""
def start(self, file):
self.time = 0
self.demo = []
self.mc = []
self.bn = []
self.last_music = ""
self.last_bg = ""
self.load_demo(file)
self.parent.demoslider.setMaximum(self.demo_length - 1)
self.step()
def playpause(self):
self.paused = not self.paused
if not self.paused and self.time < self.demo_length:
self.step()
def step(self): def step(self):
packet = self.demo[self.index] packet = self.demo[self.time]
self.index += 1 self.parent.demoslider.blockSignals(True)
print packet self.parent.demoslider.setValue(self.time)
self.parent.demoslider.blockSignals(False)
self.time += 1
if packet[0] == "wait": if packet[0] == "wait":
self.wait_timer.start(int(packet[1])) self.wait_timer.start(int(packet[1]))
else: else:
handle_packets(self, [packet]) handle_packets(self, [packet])
if self.time < self.demo_length:
self.wait_timer.start(1)
def seek(self, time):
self.parent.inbox_timer.stop()
self.parent.inboxqueue = []
self.wait_timer.stop()
self.time = time
mc_times = [t[0] for t in self.mc]
t = bisect_left(mc_times, self.time) - 1
if t >= 0:
music = self.mc[t][1][1]
if music != self.last_music:
handle_packets(self, [self.mc[t][1]])
self.last_music = music
bn_times = [t[0] for t in self.bn]
t = bisect_left(bn_times, self.time) - 1
if t >= 0:
bg = self.bn[t][1][1]
if bg != self.last_bg:
handle_packets(self, [self.bn[t][1]])
self.last_bg = bg
self.step() self.step()
def load_demo(self, file='test.demo'): def load_demo(self, file):
last_line = "" last_line = ""
self.demo = [] time = 0
with open(file) as f: with open("chatlogs/" + file) as f:
for line in f: for line in f:
last_line = last_line + line last_line = last_line + line
if last_line.strip()[-1] == "%": if last_line.strip()[-1] == "%":
self.demo.append(last_line.split("#")[:-1]) packet = last_line.split("#")[:-1]
self.demo.append(packet)
if packet[0] == "MC":
self.mc.append((time, packet))
elif packet[0] == "BN":
self.bn.append((time, packet))
last_line = "" last_line = ""
time += 1
self.demo_length = len(self.demo) self.demo_length = len(self.demo)
def timer_done(self): def timer_done(self):
if self.paused:
return
self.step() self.step()
def handle_packets(caller, total): def handle_packets(caller, total):
@ -3796,7 +3879,11 @@ def handle_packets(caller, total):
print '[warning]', 'malformed/incomplete MS#chat (IC chat) network message was received' print '[warning]', 'malformed/incomplete MS#chat (IC chat) network message was received'
continue continue
if isinstance(network[CHATMSG], unicode):
network[CHATMSG] = decode_ao_str(network[CHATMSG])
else:
network[CHATMSG] = decode_ao_str(network[CHATMSG].decode('utf-8')) network[CHATMSG] = decode_ao_str(network[CHATMSG].decode('utf-8'))
caller.MS_Chat.emit(network) caller.MS_Chat.emit(network)
elif header == 'MC': elif header == 'MC':