import ini, packets import os, time from PyQt4 import QtCore from bisect import bisect_left class DemoPlayer(QtCore.QObject): MS_Chat = QtCore.pyqtSignal(list) newChar = QtCore.pyqtSignal(str) newBackground = QtCore.pyqtSignal(str, bool) IC_Log = QtCore.pyqtSignal(str) OOC_Log = QtCore.pyqtSignal(str) charSlots = QtCore.pyqtSignal() allEvidence = QtCore.pyqtSignal(list) rainbowColor = QtCore.pyqtSignal(str) updatePlayerList = QtCore.pyqtSignal(str, int, int, str) timerUpdate = QtCore.pyqtSignal(int, int, int) def __init__(self, parent): super(DemoPlayer, self).__init__(parent) self.parent = parent self.paused = False self.demo = [] self.demo_length = len(self.demo) self.time = 0 self.demo_length_ms = 0 self.wait_timer = QtCore.QTimer(self) self.wait_timer.setSingleShot(True) 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.wait_timer.stop() self.time = 0 self.demo_length_ms = 0 self.demo = [] self.mc = [] self.bn = [] self.last_music = "" self.last_bg = "" self.load_demo(file) print "[client] Started demo playback (%s commands)" % self.demo_length self.parent.demoslider.setMaximum(self.demo_length - 1) self.OOC_Log.emit("Demo playback started.") secs = self.demo_length_ms / 1000 mins = secs / 60 hours = mins / 60 self.OOC_Log.emit("Approximate duration: %02d:%02d:%02d." % (hours, mins % 60, secs % 60)) self.OOC_Log.emit("") 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, skip_wait=False): if self.time >= self.demo_length: self.time = 0 return packet = self.demo[self.time] self.parent.demoslider.blockSignals(True) self.parent.demoslider.setValue(self.time) self.parent.demoslider.blockSignals(False) self.time += 1 if packet[0] == "wait": if skip_wait: self.time += 1 else: self.wait_timer.start(int(packet[1])) return packets.handle_packets(self, [packet], False) if self.time < self.demo_length: self.wait_timer.start(1) else: self.OOC_Log.emit("Demo playback finished.") 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: packets.handle_packets(self, [self.mc[t][1]], False) 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: packets.handle_packets(self, [self.bn[t][1]], False) self.last_bg = bg self.step(True) def load_demo(self, file): last_line = "" time = 0 with open("logs/" + file) as f: for line in f: last_line = last_line + line if last_line.strip()[-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)) elif packet[0] == "wait": self.demo_length_ms += int(packet[1]) last_line = "" time += 1 self.demo_length = len(self.demo) def timer_done(self): if self.paused: return self.step() class DemoRecorder(): def __init__(self): self.demofile = None self.lasttime = 0 def start(self): if not os.path.exists("logs"): os.mkdir("logs") currtime = time.localtime() self.lasttime = time.time() * 1000 self.demofile = "logs/%d-%02d-%02d %02d.%02d.%02d.demo" % (currtime[0], currtime[1], currtime[2], currtime[3], currtime[4], currtime[5]) def record(self, packet, encode=False): if packet[0][0] in ["FM", "ARUP", "CharsCheck"]: return #print packet[0][0] with open(self.demofile, "a") as demofile: currtime = time.time() * 1000 diff = currtime - self.lasttime self.lasttime = currtime demofile.write(("wait#%d#%%" % diff) + "\n") line = "#".join(packet[0]) + "#%\n" if encode: line = line.encode('utf-8') demofile.write(line)