def thread(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect(PARSER_SERVER_ADDR) except: prnt("Failed to connect:") prnt(traceback.format_exc()) wx.CallAfter(failureFunc) return stream = ByteStream() stream.writeByte(pkt.GET_KEY) stream.writeString(vanityKey) sock.send(stream.toString()) data = sock.recv(1024) sock.close() stream = ByteStream(data) success = stream.readByte() == 1 if success: key = stream.readString() wx.CallAfter(successFunc, key) else: wx.CallAfter(failureFunc)
def sendRaidUpdate(self): prnt("RaidServer: Sending raid update...") stream = fuzion.ByteStream() stream.writeByte(pkt.RAID_UPDATE) playerList = [] for client in self.clientList: playerInfo = client['playerInfo'] if playerInfo == None: continue playerList.append(playerInfo) stream.writeByte(len(playerList)) for player in playerList: stream.writeString(player['name']) stream.writeString(player['connType']) stream.writeInt(player['totalDamage']) stream.writeInt(player['totalDamageTaken']) stream.writeFloat(player['avgDps']) stream.writeInt(player['totalHealing']) stream.writeInt(player['totalHealingReceived']) stream.writeFloat(player['avgHps']) stream.writeInt(player['totalThreat']) stream.writeByte(player['tfbOrb']) for client in self.clientList: conn = client['conn'] conn.send(stream)
def resetOverlays(): prnt("Resetting overlays...") for overlay in overlayList: if overlay['name'] == '-': continue config.remove("overlay_%s_pos"%overlay['class'].__name__) config.remove("overlay_%s_size"%overlay['class'].__name__)
def processPlayerUpdate(self, client, stream): name = stream.readString() totalDamage = stream.readInt() totalDamageTaken = stream.readInt() avgDps = stream.readFloat() totalHealing = stream.readInt() totalHealingReceived = stream.readInt() avgHps = stream.readFloat() totalThreat = stream.readInt() tfbOrb = stream.readByte() prnt("RaidServer: Got player update from %s!" % name) conn = client['conn'] connType = 'T' if conn.loopback: connType = 'L' elif conn.relay: connType = 'R' client['playerInfo'] = { 'name': name, 'connType': connType, 'totalDamage': totalDamage, 'totalDamageTaken': totalDamageTaken, 'avgDps': avgDps, 'totalHealing': totalHealing, 'totalHealingReceived': totalHealingReceived, 'avgHps': avgHps, 'totalThreat': totalThreat, 'tfbOrb': tfbOrb } self.lastRaidUpdatePoke = time()
def analyzerMain(self): prnt("Analyzer: Starting...") self.ready = False lastUpdate = 0 try: while not self.stopEvent.isSet(): if not self.parser.ready: time.sleep(0.1) continue now = time.time() if now - lastUpdate >= 1 or self.updatePing.isSet(): lastUpdate = now self.updatePing.clear() for fight in self.parser.fights: if fight not in self.historicFights and fight != self.parser.fight: self.historicFights[fight] = self.analyzeFight(fight) # FIXME: Move this to an analysis variable instead? self.__dict__ = dict(self.__dict__.items() + self.analyzeFight(realtime=True).__dict__.items()) if not self.ready: self.ready = True self.notifyFrames() time.sleep(0.01) except: print traceback.format_exc() return False prnt("Analyzer: Exiting normally...") return True
def processPlayerUpdate(self, client, stream): name = stream.readString() totalDamage = stream.readInt() totalDamageTaken = stream.readInt() avgDps = stream.readFloat() totalHealing = stream.readInt() totalHealingReceived = stream.readInt() avgHps = stream.readFloat() totalThreat = stream.readInt() tfbOrb = stream.readByte() prnt("RaidServer: Got player update from %s!"%name) conn = client['conn'] connType = 'T' if conn.loopback: connType = 'L' elif conn.relay: connType = 'R' client['playerInfo'] = { 'name': name, 'connType': connType, 'totalDamage': totalDamage, 'totalDamageTaken': totalDamageTaken, 'avgDps': avgDps, 'totalHealing': totalHealing, 'totalHealingReceived': totalHealingReceived, 'avgHps': avgHps, 'totalThreat': totalThreat, 'tfbOrb': tfbOrb } self.lastRaidUpdatePoke = time()
def killOverlay(name): global openOverlays if not (name in openOverlays.keys()): prnt("ERROR: Overlay '%s' not open."%name) return overlay = openOverlays[name] overlay.Destroy() del openOverlays[name]
def onNodeDisconnected(): global currentKey if currentKey != None: prnt("Raid: Fuzion node disconnected, dropping server and pausing client.") if raidClient != None: raidClient.pause() if raidServer != None: raidServer.stop()
def run(self): crashCounter = 0 while crashCounter < 6: self.running = True if not self.analyzerMain(): prnt("AnalyzerThread: Analyzer has crashed! Restarting... counter=%d"%crashCounter) crashCounter += 1 else: break self.running = False
def onNodeDisconnected(): global currentKey if currentKey != None: prnt( "Raid: Fuzion node disconnected, dropping server and pausing client." ) if raidClient != None: raidClient.pause() if raidServer != None: raidServer.stop()
def run(self): self.stopEvent = threading.Event() self.parser = Parser() crashCounter = 0 while crashCounter < 6: self.running = True if not self.parser.run(self.stopEvent): prnt("ParserThread: Parser has crashed! Restarting... counter=%d"%crashCounter) crashCounter += 1 else: break self.running = False
def run(self): crashCounter = 0 while crashCounter < 6: self.running = True if not self.analyzerMain(): prnt( "AnalyzerThread: Analyzer has crashed! Restarting... counter=%d" % crashCounter) crashCounter += 1 else: break self.running = False
def checkForUpdates(frame): prnt("Checking for updates...") try: url = urlopen(UPDATES_URL) data = url.read() url.close() info = json.loads(data) #print info except HTTPError, e: prnt("ERROR: %s"%e.reason) wx.CallAfter(frame.errorGettingInfo) return
def spawnOverlay(name): global overlayList, openOverlays class_ = None for overlay in overlayList: if overlay['name'] == '-': continue if overlay['name'] == name: class_ = overlay['class'] break if class_ == None: prnt("ERROR: No such overlay as '%s'"%name) return inst = class_() inst.Show() openOverlays[name] = inst
def load(): global settings prnt("Loading settings...") # Setup a save on exit. atexit.register(save) if not os.path.exists('settings.json'): return try: f = open('settings.json', 'r') data = json.loads(f.read()) f.close() except Exception, e: prnt(traceback.format_exc())
def downloadUpdate(frame, info): url = info['url'] prnt("Downloading update from %s"%url) conn = None outputFile = None try: conn = urlopen(url) meta = conn.info() fileSize = int(meta.getheaders("Content-Length")[0]) total = "%0.2f KiB"%(fileSize / 1024.0) # Start downloading the file blockSize = 8196 bytesReceived = 0 outputFile = open("tmp.zip", "wb") while True: buffer = conn.read(blockSize) if not buffer: break bytesReceived += len(buffer) outputFile.write(buffer) current = "%0.2f KiB"%(bytesReceived / 1024.0) prnt("Downloaded %s out of %s \r"%(current, total)) wx.CallAfter(frame.setProgress, float(bytesReceived) / float(fileSize)) outputFile.close() conn.close() prnt() # clear return prnt("Download complete!") wx.CallAfter(frame.informApplying) applyUpdate(frame, info) except HTTPError, e: if conn != None: conn.close() if outputFile != None: outputFile.close() prnt("ERROR: %s"%e.reason) wx.CallAfter(frame.errorDownloading) return
def __init__(self, rawName): self.rawName = rawName self.player = None self.companion = None self.mob = None self.entity = 0 self.instance = 0 result = Entity.NAME_REGEX.match(rawName) if not result: prnt("Entity: Regex failed! rawName=" + rawName) else: self.player = result.group('player') self.companion = result.group('companion') self.mob = result.group('mob') self.entity = result.group('entity') self.instance = result.group('instance')
def init(): global node fuzion.setDebug(lambda *x: prnt("Fuzion:", *x)) node = fuzion.Node() node.bindDisconnect(onNodeDisconnected) node.bindReconnect(onNodeReconnected) node.setNodeServer(NODE_SERVER_ADDR)
def sendPlayerUpdate(self): prnt("RaidClient: Sending update...") analyzer = log_analyzer.get() stream = fuzion.ByteStream() stream.writeByte(pkt.PLAYER_UPDATE) if analyzer.parser.me: # TODO: Transition to sending only the name stream.writeString("@" + analyzer.parser.me.name) else: stream.writeString("@NoPlayer") stream.writeInt(analyzer.totalDamage) stream.writeInt(analyzer.totalDamageTaken) stream.writeFloat(analyzer.avgDps) stream.writeInt(analyzer.totalHealing) stream.writeInt(analyzer.totalHealingReceived) stream.writeFloat(analyzer.avgHps) stream.writeInt(analyzer.totalThreat) # Mechanics stream.writeByte(analyzer.tfbOrb) self.conn.send(stream)
def thread(): global currentKey, raidServer, raidClient net.node.waitForNS() # Connect to server... sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) try: sock.connect(PARSER_SERVER_ADDR) except: prnt("Failed to connect:") prnt(traceback.format_exc()) wx.CallAfter(failureFunc, "connect_failed") return # Write data stream = ByteStream() stream.writeByte(pkt.JOIN_RAID) stream.writeByte(VERSION_INT) stream.writeString(key) stream.writeString(net.node.getId()) sock.send(stream.toString()) # Read data data = sock.recv(1024) stream = ByteStream(data) # Process data success = stream.readBoolean() if success: currentKey = key isHost = stream.readBoolean() serverNode = net.node.getId() if isHost: prnt("Raid: Joined raid, became host") raidServer = RaidServer(sock) raidServer.start() else: prnt("Raid: Joined raid, didn't become host") serverNode = stream.readString() sock.close() raidClient = RaidClient(serverNode, failureFunc, successFunc) raidClient.start() else: reason = stream.readString() wx.CallAfter(failureFunc, reason) sock.close()
def analyzerMain(self): prnt("Analyzer: Starting...") self.ready = False lastUpdate = 0 try: while not self.stopEvent.isSet(): if not self.parser.ready: time.sleep(0.1) continue now = time.time() if now - lastUpdate >= 1 or self.updatePing.isSet(): lastUpdate = now self.updatePing.clear() for fight in self.parser.fights: if fight not in self.historicFights and fight != self.parser.fight: self.historicFights[fight] = self.analyzeFight( fight) # FIXME: Move this to an analysis variable instead? self.__dict__ = dict(self.__dict__.items() + self.analyzeFight( realtime=True).__dict__.items()) if not self.ready: self.ready = True self.notifyFrames() time.sleep(0.01) except: print traceback.format_exc() return False prnt("Analyzer: Exiting normally...") return True
def applyUpdate(frame, info): z = None if not os.path.exists('pending'): os.mkdir('pending') try: z = ZipFile("tmp.zip") nameList = z.namelist() current = 0 total = len(nameList) for f in nameList: # Installed and zipped use different manifests if f in ('swap.exe.manifest', 'updater.exe.manifest'): continue prnt("Extracting %s"%f) if f.endswith('/'): if not os.path.isdir(f): os.mkdir(f) continue if f in ('updater.py', 'updater.exe'): z.extract(f, "pending") continue if os.path.exists(f): if os.path.exists(f + '.old'): os.remove(f + '.old') os.rename(f, f + '.old') z.extract(f) current += 1 wx.CallAfter(frame.setProgress, float(current) / float(total)) z.close() except Exception, e: prnt(traceback.format_exc()) if z != None: z.close() os.remove("tmp.zip") wx.CallAfter(frame.launch) return
def gotRaidUpdate(self, stream): prnt("RaidClient: Got raid update.") playerCount = stream.readByte() playerList = [] for i in range(0, playerCount): player = {} player['name'] = stream.readString() player['connType'] = stream.readString() player['totalDamage'] = stream.readInt() player['totalDamageTaken'] = stream.readInt() player['avgDps'] = stream.readFloat() player['totalHealing'] = stream.readInt() player['totalHealingReceived'] = stream.readInt() player['avgHps'] = stream.readFloat() player['totalThreat'] = stream.readInt() # Mechanics player['tfbOrb'] = stream.readByte() playerList.append(player) raid.playerData = playerList log_analyzer.get().notifyFrames()
def launch(self): self.Destroy() prnt("") prnt("Launching SWAP...") prnt("-"*20) if IS_FROZEN: subprocess.Popen(["swap.exe", "--from-updater"], close_fds=True) else: subprocess.Popen(["python", "swap.py"], close_fds=True)
def run(self): prnt("RaidServer: Booting up...") self.port = net.node.bind("swap:raid") self.centralSock.setblocking(False) while not self.stoppedEvent.isSet(): now = time() # Central server r, w, e = select([self.centralSock], [self.centralSock], [], 0) if r: data = self.centralSock.recv(1024) stream = ByteStream(data) packetType = stream.readByte() if self.port.connectionPending(): conn = self.port.accept() self.clientList.append({'conn': conn, 'playerInfo': None}) for client in self.clientList: conn = client['conn'] if conn.recvPending(): data = conn.recv() if data == None: playerName = client['playerInfo']['name'] if client[ 'playerInfo'] else "<NoInfo>" prnt("Client (%s) left raid, reason=%s" % (playerName, fuzion.formatError( conn.closedReason))) self.lastRaidUpdatePoke = time() self.clientList.remove(client) continue packetType = data.readByte() if packetType == pkt.PLAYER_UPDATE: self.processPlayerUpdate(client, data) if now - self.lastRaidUpdateSent > 2 and now - self.lastRaidUpdatePoke < 5: self.sendRaidUpdate() self.lastRaidUpdateSent = now sleep(0.1) self.port.close() for client in self.clientList: conn = client['conn'] conn.close() self.centralSock.close() prnt("RaidServer: Shutting down...")
def run(self): prnt("RaidServer: Booting up...") self.port = net.node.bind("swap:raid") self.centralSock.setblocking(False) while not self.stoppedEvent.isSet(): now = time() # Central server r, w, e = select([self.centralSock], [self.centralSock], [], 0) if r: data = self.centralSock.recv(1024) stream = ByteStream(data) packetType = stream.readByte() if self.port.connectionPending(): conn = self.port.accept() self.clientList.append({ 'conn': conn, 'playerInfo': None }) for client in self.clientList: conn = client['conn'] if conn.recvPending(): data = conn.recv() if data == None: playerName = client['playerInfo']['name'] if client['playerInfo'] else "<NoInfo>" prnt("Client (%s) left raid, reason=%s"%(playerName, fuzion.formatError(conn.closedReason))) self.lastRaidUpdatePoke = time() self.clientList.remove(client) continue packetType = data.readByte() if packetType == pkt.PLAYER_UPDATE: self.processPlayerUpdate(client, data) if now - self.lastRaidUpdateSent > 2 and now - self.lastRaidUpdatePoke < 5: self.sendRaidUpdate() self.lastRaidUpdateSent = now sleep(0.1) self.port.close() for client in self.clientList: conn = client['conn'] conn.close() self.centralSock.close() prnt("RaidServer: Shutting down...")
def getNewServerNode(): global currentKey, raidServer # Connect to server... sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect(PARSER_SERVER_ADDR) except: prnt("Failed to connect:") prnt(traceback.format_exc()) return # Write data stream = ByteStream() stream.writeByte(pkt.JOIN_RAID) stream.writeByte(VERSION_INT) stream.writeString(currentKey) stream.writeString(net.node.getId()) sock.send(stream.toString()) # Read data data = sock.recv(1024) stream = ByteStream(data) # Process data success = stream.readBoolean() if success: isHost = stream.readBoolean() serverNode = net.node.getId() if isHost: prnt("Raid: Became host") raidServer = RaidServer(sock) raidServer.start() else: prnt("Raid: Didn't become host") serverNode = stream.readString() sock.close() return serverNode return None
def t(): try: prnt("Sending SWAP log...") f = open("debug-swap.log", "r") log = f.read() f.close() request = urllib2.Request(LOG_SEND_URL) request.add_data(urlencode({"u": log})) urllib2.urlopen(request).close() prnt("Sent.") except: prnt(traceback.format_exc())
def checkForUpdates(frame): prnt("Checking for updates...") try: url = urlopen(UPDATES_URL) data = url.read() url.close() info = json.loads(data) #print info except HTTPError, e: prnt("ERROR: %s"%e.reason) wx.CallAfter(frame.errorGettingInfo) return prnt("Latest version is %s, running %s"%(info['version'], VERSION)) if info['versionInt'] > VERSION_INT: newVersion = info['versionInt'] prnt("New version!") if IS_FROZEN: wx.CallAfter(frame.informUpdate, info['version']) downloadUpdate(frame, info) else: wx.CallAfter(frame.launch) prnt("Not downloading update because not SWAP is not compiled.") else: wx.CallAfter(frame.launch) def downloadUpdate(frame, info):
def run(self): prnt("RaidClient: Booting up...") self.conn = net.node.connect(self.serverNode, "swap:raid") if not self.conn or self.conn.state != fuzion.CS_CONNECTED: raid.leaveRaid() wx.CallAfter(self.failureFunc, "node_connect_failed") prnt("RaidClient: Connection failed, shutting down...") return # Inform the UI of raid join success. wx.CallAfter(self.successFunc) while not self.stoppedEvent.isSet(): if self.pausedEvent.isSet(): sleep(0.4) continue if self.conn.recvPending(): data = self.conn.recv() if data == None: if self.conn.closedReason != 0: # If we're paused, we don't want to reconnect yet. if self.pausedEvent.isSet(): continue prnt("RaidClient: Connection lost, reason=%s" % fuzion.formatError(self.conn.closedReason)) # Fetch new raid info self.serverNode = None self.conn = None while self.serverNode == None or self.conn == None: prnt("RaidClient: Reconnecting...") self.serverNode = raid.getNewServerNode() if self.serverNode == None: prnt( "RaidClient: Failed to get new server node..." ) sleep(2) continue conn = net.node.connect(self.serverNode, "swap:raid") if conn.state == fuzion.CS_CONNECTED: self.conn = conn self.lastTicks = 2 continue else: prnt( "RaidClient: Failed to connect to new node! Connection state = %d" % conn.state) sleep(2) continue packet = data.readByte() if packet == pkt.RAID_UPDATE: self.gotRaidUpdate(data) now = time() if now - self.lastUpdateSent >= 2 and (log_parser.get().inCombat or self.lastTicks >= 1): if not log_parser.get().inCombat: self.lastTicks -= 1 else: self.lastTicks = 2 self.sendPlayerUpdate() self.lastUpdateSent = now sleep(0.1) self.conn.close() prnt("RaidClient: Shutting down...")
def killAllOverlays(): prnt("Closing overlays...") global openOverlays for name, overlay in openOverlays.iteritems(): overlay.Destroy() openOverlays = {}
def onNodeReconnected(): global currentKey if currentKey != None: prnt("Raid: Fuzion node reconnected, resuming client.") if raidClient != None: raidClient.resume()
def run(self): prnt("RaidClient: Booting up...") self.conn = net.node.connect(self.serverNode, "swap:raid") if not self.conn or self.conn.state != fuzion.CS_CONNECTED: raid.leaveRaid() wx.CallAfter(self.failureFunc, "node_connect_failed") prnt("RaidClient: Connection failed, shutting down...") return # Inform the UI of raid join success. wx.CallAfter(self.successFunc) while not self.stoppedEvent.isSet(): if self.pausedEvent.isSet(): sleep(0.4) continue if self.conn.recvPending(): data = self.conn.recv() if data == None: if self.conn.closedReason != 0: # If we're paused, we don't want to reconnect yet. if self.pausedEvent.isSet(): continue prnt("RaidClient: Connection lost, reason=%s"%fuzion.formatError(self.conn.closedReason)) # Fetch new raid info self.serverNode = None self.conn = None while self.serverNode == None or self.conn == None: prnt("RaidClient: Reconnecting...") self.serverNode = raid.getNewServerNode() if self.serverNode == None: prnt("RaidClient: Failed to get new server node...") sleep(2) continue conn = net.node.connect(self.serverNode, "swap:raid") if conn.state == fuzion.CS_CONNECTED: self.conn = conn self.lastTicks = 2 continue else: prnt("RaidClient: Failed to connect to new node! Connection state = %d"%conn.state) sleep(2) continue packet = data.readByte() if packet == pkt.RAID_UPDATE: self.gotRaidUpdate(data) now = time() if now - self.lastUpdateSent >= 2 and (log_parser.get().inCombat or self.lastTicks >= 1): if not log_parser.get().inCombat: self.lastTicks -= 1 else: self.lastTicks = 2 self.sendPlayerUpdate() self.lastUpdateSent = now sleep(0.1) self.conn.close() prnt("RaidClient: Shutting down...")
if not os.path.exists('settings.json'): return try: f = open('settings.json', 'r') data = json.loads(f.read()) f.close() except Exception, e: prnt(traceback.format_exc()) else: settings = data # Convert from old format bg = get("overlayBgColor") if isinstance(bg, basestring): prnt("Legacy overlay colors found, converting...") bg = int(bg[1:], 16) set("overlayBgColor", bg) fg = get("overlayFgColor") fg = int(fg[1:], 16) set("overlayFgColor", fg) def save(): f = open('settings.json', 'w') json.dump(settings, f, indent=4, sort_keys=True) f.close() def get(name): global settings if name in settings.keys():
tParser.start() try: tParser.waitTillUp() parser = tParser.getParser() while tParser.isRunning(): totalDamage = 0 wasInCombat = False endTime = 0 startTime = 0 for ev in reversed(parser.events): if endTime == 0 and (ev.type == evt.EXIT_COMBAT or parser.events[-1].inCombat): wasInCombat = True endTime = ev.time if ev.type == evt.ENTER_COMBAT: startTime = ev.time break if ev.inCombat and ev.type == evt.DAMAGE: totalDamage += ev.damage wasInCombat = True tx = (endTime - startTime) / 1000.0 if tx != 0: prnt("Damage dealt: %d, time: %d"%(totalDamage,tx)) prnt("DPS: %d"%round(totalDamage / tx, 1)) time.sleep(.01) except: prnt(traceback.format_exc()) tParser.stop() tParser.join()
if not os.path.exists('settings.json'): return try: f = open('settings.json', 'r') data = json.loads(f.read()) f.close() except Exception, e: prnt(traceback.format_exc()) else: settings = data # Convert from old format bg = get("overlayBgColor") if isinstance(bg, basestring): prnt("Legacy overlay colors found, converting...") bg = int(bg[1:], 16) set("overlayBgColor", bg) fg = get("overlayFgColor") fg = int(fg[1:], 16) set("overlayFgColor", fg) def save(): f = open('settings.json', 'w') json.dump(settings, f, indent=4, sort_keys=True) f.close() def get(name):
def run(self, hasStopped): prnt("Parser: Starting...") log = None try: if self.logLocation == None: raise Exception("No log location set. Did you forget to call getDocs?") logInfo = self.getNewestLog() if logInfo == None: prnt("Parser: Waiting for log...") while not hasStopped.isSet(): logInfo = self.getNewestLog() if logInfo != None: break time.sleep(0.4) if hasStopped.isSet(): return True (logFile, logPath) = logInfo log = open(logPath, 'r') self.inCombat = False self.fights = [] self.fight = None self.ready = False self.disappearEvent = None self._entityLookup = {} inUpdate = False logCursor = 0 logDay = self.getMidnightTimestampForFile(logPath) logLastActionTime = 0 prnt("Parser: Began parsing %s"%logFile) prnt("Parser: Log day is %s"%datetime.datetime.fromtimestamp(logDay)) lastLogFileCheck = time.time() while not hasStopped.isSet(): if time.time() - lastLogFileCheck > 1: if logFile != self.getNewestLog(onlyFilename=True): (logFile, logPath) = self.getNewestLog() prnt("Parser: Switched to parsing %s"%logFile) # Close previous log, and open new one. log.close() log = open(logPath, 'r') # Reset vars self.inCombat = False self.fights = [] self.fight = None self.ready = False self.me = None self.disappearEvent = None self._entityLookup = {} inUpdate = False logCursor = 0 logDay = self.getMidnightTimestampForFile(logPath) logLastActionTime = 0 prnt("Parser: Log day is %s"%datetime.datetime.fromtimestamp(logDay)) self.notifyEvent(Parser.EVENT_NEW_LOG) lastLogFileCheck = time.time() logCursor = log.tell() line = log.readline() if line == "": # Once we reach EOF mark us as ready for analyzation. if not self.ready: self.ready = True self.notifyEvent(Parser.EVENT_READY) if inUpdate: inUpdate = False analyzer = log_analyzer.get() analyzer.updatePing.set() time.sleep(.25) continue inUpdate = True res = self.linePat.match(line) if res: hour = int(res.group('hour')) minute = int(res.group('minute')) second = int(res.group('second')) ms = int(res.group('ms')) actor = res.group('actor') target = res.group('target') ability = res.group('ability') abilityId = res.group('abilityid') action = res.group('action') actionId = res.group('actionid') actionType = res.group('actiontype') actionTypeId = res.group('actiontypeid') result = res.group('result') threat = int(res.group('threat')) if res.group('threat') else 0 actionTime = logDay + (hour * 3600) + (minute * 60) + second + (ms / 1000.0) # Check for date rollover. if actionTime < logLastActionTime and logLastActionTime - actionTime > 43200: logDay += 86400 actionTime += 86400 prnt("Parser: Rollover, day is now %s"%datetime.datetime.fromtimestamp(logDay)) logLastActionTime = actionTime for entity in (actor, target): if entity not in self._entityLookup: ent = Entity(entity) self._entityLookup[entity] = ent else: ent = self._entityLookup[entity] if self.fight and ent not in self.fight.entities: self.fight.entities.append(ent) actor = self._entityLookup[actor] target = self._entityLookup[target] # Serious introspection here, man if (self.me == None and actor == target and not actor.companion and not actor.mob): prnt("Parser: Identified %s as me"%actor.name) self.me = actor self.notifyEvent(Parser.EVENT_PLAYER_IDENTIFIED) event = GameEvent() event.type = self.resolveEventType(actionId, actionTypeId) event.actor = actor event.target = target event.ability = abilityId event.abilityName = ability event.actionType = actionTypeId event.actionTypeName = actionType event.inCombat = self.inCombat event.time = actionTime event.readTime = time.time() event.threat = threat event.enterEvent = False event.exitEvent = False event.recent = self.ready if event.type == evt.ENTER_COMBAT: event.enterEvent = True elif event.type == evt.EXIT_COMBAT: event.exitEvent = True elif event.type == evt.DEATH and self.inCombat and event.target == self.me: event.exitEvent = True elif event.type == evt.APPLY_BUFF and event.actionType == '973870949466372' and self.inCombat: # Safe Login Immunity event.exitEvent = True # Detect disappear if self.fights and event.type == evt.ABILITY_ACTIVATE and event.ability in abl.DISAPPEAR: lastFight = self.fights[-1] exitBluff = False # Look back for exit combat. for e in reversed(lastFight.events): if e.exitEvent: e.exitEvent = False exitBluff = True break if event.time - e.time > 0.100: break if exitBluff: self.disappearEvent = event # Clear disappear flag if out of grace period if self.disappearEvent and event.time - self.disappearEvent.time > DISAPPEAR_GRACE: self.disappearEvent = None if event.enterEvent: newFight = True if self.disappearEvent: # Continue fight if within grace period if event.time - self.disappearEvent.time <= DISAPPEAR_GRACE: self.fight = self.fights[-1] self.inCombat = True newFight = False self.disappearEvent = None if newFight: fight = Fight() fight.enterEvent = event fight.enterTime = event.time self.fights.append(fight) self.fight = fight self.inCombat = True if self.ready: self.notifyEvent(Parser.EVENT_FIGHT_BEGIN) elif event.exitEvent: self.inCombat = False if event.type == evt.DAMAGE: sp = result.split(' ') if len(sp) > 2: dmg = sp[0] dmgType = sp[1] dmgTypeId = sp[2] if dmg.endswith('*'): dmg = dmg[:-1] dmg = int(dmg) if len(sp) == 6: fourth = sp[3] fifth = sp[4] sixth = sp[5] if fifth == 'absorbed' and event.target == self.me: absorbAmount = int(fourth[1:]) dmg -= absorbAmount else: dmg = 0 event.damage = dmg if event.type == evt.HEAL: heal = result if heal.endswith('*'): heal = heal[:-1] event.healing = int(heal) if self.fight: for entity in (event.actor, event.target): if entity == self.me or entity.companion: continue priority = event.damage + event.threat if not priority: continue if entity in self.fight.priorityTargets: self.fight.priorityTargets[entity] += priority continue self.fight.priorityTargets[entity] = priority if self.fight != None: self.fight.events.append(event) if event.exitEvent and self.fight: self.fight.exitEvent = event self.fight.exitTime = event.time self.fight = None if self.ready: self.notifyEvent(Parser.EVENT_FIGHT_END) elif line[-1] != '\n' and line[-1] != '\r': log.seek(logCursor) time.sleep(0.25) time.sleep(.0001) except Exception: if log != None: log.close() prnt(traceback.format_exc()) return False log.close() prnt("Parser: Exiting normally...") return True