def __init__(self): BaseListOverlay.__init__(self, title="Raid Damage", size=(300, 150)) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnClose) analyzer = log_analyzer.get() analyzer.registerFrame(self) self.onAnalyzerTick(analyzer)
def __init__(self): BaseOverlay.__init__(self, title="Healing Done") self.Bind(wx.EVT_WINDOW_DESTROY, self.OnClose) analyzer = log_analyzer.get() analyzer.registerFrame(self) self.onAnalyzerTick(analyzer)
def __init__(self): BaseOverlay.__init__(self, title="Rolling DPS") self.Bind(wx.EVT_WINDOW_DESTROY, self.OnClose) analyzer = log_analyzer.get() analyzer.registerFrame(self) self.onAnalyzerTick(analyzer)
def __init__(self): BaseListOverlay.__init__(self, title="Operator IX", size=(300, 150)) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnClose) analyzer = log_analyzer.get() analyzer.registerFrame(self) self.onAnalyzerTick(analyzer)
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 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 OnClose(self, event): if event.GetEventObject() == self: log_analyzer.get().unregisterFrame(self)
def onClose(self, event): if raid.isInRaid(): raid.leaveRaid() log_analyzer.get().unregisterFrame(self) overlays.killAllOverlays() self.Destroy()
def OnClose(self, event): log_analyzer.get().unregisterFrame(self)
def onFightBegin(self): self.fightSelector.SetSelection(0) self.dashboardFight = None self.onAnalyzerTick(log_analyzer.get())
def __init__(self): wx.Frame.__init__(self, None, title="SWAP %s"%VERSION, size=(900, 520)) if not util.isCombatLoggingEnabled(): dlg = wx.MessageDialog(self, MSG_COMBAT_LOGGING_DISABLED_TEXT, MSG_COMBAT_LOGGING_DISABLED_TITLE, wx.OK | wx.CANCEL | wx.ICON_ERROR) result = dlg.ShowModal() dlg.Destroy() if result == wx.ID_OK: util.enableCombatLogging() # Check for changelog try: f = open('_changelog.txt', 'r') except IOError: pass else: with f: changelog = f.read() changelogDialog = ChangelogDialog(changelog) changelogDialog.ShowModal() changelogDialog.Destroy() os.remove('_changelog.txt') self.SetMinSize((900, 520)) if IS_FROZEN: self.SetIcon(wx.Icon('swap.exe', wx.BITMAP_TYPE_ICO)) else: self.SetIcon(wx.Icon('../etc/app.ico', wx.BITMAP_TYPE_ICO)) # Setup menu bar menuBar = wx.MenuBar() self.SetMenuBar(menuBar) # File menu = wx.Menu() menuBar.Append(menu, "&File") m_exit = menu.Append(MENU_ID_EXIT, MENU_TITLE_EXIT, MENU_TIP_EXIT) self.Bind(wx.EVT_MENU, self.onClose, id=MENU_ID_EXIT) # Tools menu = wx.Menu() menuBar.Append(menu, "&Tools") m_preferences = menu.Append(MENU_ID_PREFERENCES, MENU_TITLE_PREFERENCES, MENU_TIP_PREFERENCES) self.Bind(wx.EVT_MENU, self.onPreferences, id=MENU_ID_PREFERENCES) menu.AppendSeparator() m_enrageTime = menu.Append(MENU_ID_ENRAGE_TIME, MENU_TITLE_ENRAGE_TIME, MENU_TIP_ENRAGE_TIME) self.Bind(wx.EVT_MENU, self.onSetEnrageTime, id=MENU_ID_ENRAGE_TIME) # Overlay menu = wx.Menu() menuBar.Append(menu, "&Overlay") categoryMenus = {} for category in overlays.getOverlayCategoryList(): name = category['name'] title = category['title'] categoryMenus[name] = subMenu = wx.Menu() menu.AppendSubMenu(subMenu, title, "") self.m_overlays = {} for overlay in overlays.getOverlayList(): targetMenu = menu if overlay['category'] != None: targetMenu = categoryMenus[overlay['category']] if overlay['name'] == '-': targetMenu.AppendSeparator() continue id = wx.NewId() self.m_overlays[id] = targetMenu.AppendCheckItem(id, overlay['title'], MENU_TIP_OVERLAY_SELECT) self.Bind(wx.EVT_MENU, (lambda n: lambda e: overlays.toggleOverlay(n))(overlay['name']), id=id) menu.AppendSeparator() m_dark = menu.AppendCheckItem(MENU_ID_OVERLAY_DARK, MENU_TITLE_OVERLAY_DARK, MENU_TIP_OVERLAY_DARK) m_dark.Check(overlays.isDarkTheme()) self.Bind(wx.EVT_MENU, lambda e: overlays.toggleDarkTheme(), id=MENU_ID_OVERLAY_DARK) m_sizeToGrid = menu.AppendCheckItem(MENU_ID_OVERLAY_SIZE_TO_GRID, MENU_TITLE_OVERLAY_SIZE_TO_GRID, MENU_TIP_OVERLAY_SIZE_TO_GRID) m_sizeToGrid.Check(config.get("overlaySizeToGrid") == True) self.Bind(wx.EVT_MENU, lambda e: config.set("overlaySizeToGrid", m_sizeToGrid.IsChecked()), id=MENU_ID_OVERLAY_SIZE_TO_GRID) m_snapOverlays = menu.AppendCheckItem(MENU_ID_OVERLAY_SNAP, MENU_TITLE_OVERLAY_SNAP, MENU_TIP_OVERLAY_SNAP) m_snapOverlays.Check(config.get("overlaySnap") == True) self.Bind(wx.EVT_MENU, lambda e: config.set("overlaySnap", m_snapOverlays.IsChecked()), id=MENU_ID_OVERLAY_SNAP) m_clickThrough = menu.AppendCheckItem(MENU_ID_OVERLAY_CLICK_THROUGH, MENU_TITLE_OVERLAY_CLICK_THROUGH, MENU_TIP_OVERLAY_CLICK_THROUGH) m_clickThrough.Check(config.get("overlayClickThrough") == True) self.Bind(wx.EVT_MENU, lambda e: config.set("overlayClickThrough", m_clickThrough.IsChecked()), id=MENU_ID_OVERLAY_CLICK_THROUGH) menu.AppendSeparator() m_reset = menu.Append(MENU_ID_OVERLAY_RESET, MENU_TITLE_OVERLAY_RESET, MENU_TIP_OVERLAY_RESET) self.Bind(wx.EVT_MENU, self.onResetOverlays, id=MENU_ID_OVERLAY_RESET) m_close = menu.Append(MENU_ID_OVERLAY_CLOSE, MENU_TITLE_OVERLAY_CLOSE, MENU_TIP_OVERLAY_CLOSE) self.Bind(wx.EVT_MENU, self.onCloseOverlays, id=MENU_ID_OVERLAY_CLOSE) # Help menu = wx.Menu() menuBar.Append(menu, "&Help") m_checkUpdates = menu.Append(MENU_ID_HELP_UPDATES, MENU_TITLE_HELP_UPDATES, MENU_TIP_HELP_UPDATES) m_openLog = menu.Append(MENU_ID_HELP_LOG, MENU_TITLE_HELP_LOG, MENU_TIP_HELP_LOG) m_sendLog = menu.Append(MENU_ID_HELP_SEND_LOG, MENU_TITLE_HELP_SEND_LOG, MENU_TIP_HELP_SEND_LOG) menu.AppendSeparator() m_about = menu.Append(MENU_ID_HELP_ABOUT, MENU_TITLE_HELP_ABOUT, MENU_TIP_HELP_ABOUT) self.Bind(wx.EVT_MENU, self.onCheckUpdates, id=MENU_ID_HELP_UPDATES) self.Bind(wx.EVT_MENU, self.onOpenLog, id=MENU_ID_HELP_LOG) self.Bind(wx.EVT_MENU, self.onSendLog, id=MENU_ID_HELP_SEND_LOG) self.Bind(wx.EVT_MENU, self.onAbout, id=MENU_ID_HELP_ABOUT) # UI self.panel = wx.Panel(self) self.panel.SetDoubleBuffered(True) self.horzBox = wx.BoxSizer(wx.HORIZONTAL) self.box = wx.BoxSizer(wx.VERTICAL) self.horzBox.Add(self.box, 1, wx.EXPAND) # ----------------------------------- # Header # ----------------------------------- headerBox = wx.BoxSizer(wx.HORIZONTAL) self.keyText = wx.StaticText(self.panel, -1, "Key:") self.keyBox = wx.TextCtrl(self.panel, -1, "", size=(150, -1)) lastRaidKey = config.get("lastRaidKey") if lastRaidKey: self.keyBox.SetValue(lastRaidKey) self.keyGenerateButton = wx.Button(self.panel, -1, "Generate") self.keyGenerateButton.Bind(wx.EVT_BUTTON, self.onGenerateButton) self.keyJoinButton = wx.Button(self.panel, -1, "Join Raid") self.keyJoinButton.Bind(wx.EVT_BUTTON, self.onJoinRaidButton) self.keyVanityCheck = wx.CheckBox(self.panel, -1, "Generate Vanity Key") self.keyStatus = wx.StaticText(self.panel, -1, "") self.fightSelector = wx.Choice(self.panel, -1) self.fightSelector.Append("Latest Fight", None) self.fightSelector.SetSelection(0) self.fightSelector.Bind(wx.EVT_CHOICE, self.onFightSelected) log_parser.get().registerObserver(log_parser.Parser.EVENT_FIGHT_BEGIN, util.wxFunc(self.onFightBegin)) log_parser.get().registerObserver(log_parser.Parser.EVENT_FIGHT_END, util.wxFunc(self.onFightEnd)) log_parser.get().registerObserver(log_parser.Parser.EVENT_NEW_LOG, util.wxFunc(self.onNewLog)) log_parser.get().registerObserver(log_parser.Parser.EVENT_READY, util.wxFunc(self.onParserReady)) if log_parser.get().ready: self.onParserReady() self.dashboardFight = None self.historicRaidFights = {} headerBox.Add(self.keyText, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10) headerBox.Add(self.keyBox, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10) headerBox.Add(self.keyGenerateButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5) headerBox.Add(self.keyJoinButton, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10) headerBox.Add(self.keyVanityCheck, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT) headerBox.Add(self.keyStatus, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 10) headerBox.Add(self.fightSelector, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10) self.box.Add(headerBox, 0, wx.EXPAND | wx.ALL, 10) # ----------------------------------- # Tabs # ----------------------------------- self.tabs = wx.Notebook(self.panel) # Create Overview tab self.overviewPanel = wx.Panel(self.tabs) self.overviewSizer = wx.BoxSizer(wx.VERTICAL) self.overviewPanel.SetSizer(self.overviewSizer) self.overviewPanel.Layout() self.createOverviewView(self.overviewSizer, self.overviewPanel) self.tabs.AddPage(self.overviewPanel, "Overview") # Create Report tab self.reportPanel = wx.Panel(self.tabs) self.reportSizer = wx.BoxSizer(wx.VERTICAL) self.reportPanel.SetSizer(self.reportSizer) self.reportPanel.Layout() self.createReportView(self.reportSizer, self.reportPanel) self.tabs.AddPage(self.reportPanel, "Report") # Create Raid tab self.raidPanel = wx.Panel(self.tabs) self.raidSizer = wx.BoxSizer(wx.VERTICAL) self.raidPanel.SetSizer(self.raidSizer) self.raidPanel.Layout() self.createRaidView(self.raidSizer, self.raidPanel) self.tabs.AddPage(self.raidPanel, "Raid") # Create Ability tab self.abilityPanel = wx.Panel(self.tabs) self.abilitySizer = wx.BoxSizer(wx.VERTICAL) self.abilityPanel.SetSizer(self.abilitySizer) self.abilityPanel.Layout() self.createAbilityView(self.abilitySizer, self.abilityPanel) self.tabs.AddPage(self.abilityPanel, "By Ability") # Create Targets tab self.targetsPanel = wx.Panel(self.tabs) self.targetsSizer = wx.BoxSizer(wx.VERTICAL) self.targetsPanel.SetSizer(self.targetsSizer) self.targetsPanel.Layout() self.createTargetsView(self.targetsSizer, self.targetsPanel) self.tabs.AddPage(self.targetsPanel, "By Target") self.box.Add(self.tabs, 1, wx.EXPAND | wx.ALL & ~wx.TOP, 10) # ----------------------------------- # Console # ----------------------------------- self.console = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE | wx.TE_READONLY, size=(200, -1)) self.console.SetFont(wx.Font(7, wx.DEFAULT, wx.NORMAL, wx.NORMAL)) self.horzBox.Add(self.console, 0, wx.EXPAND | wx.ALL & ~wx.LEFT, 10) self.panel.SetSizer(self.horzBox) self.panel.Layout() # Events self.Bind(wx.EVT_CLOSE, self.onClose) log_analyzer.get().registerFrame(self) self.addToConsole("SWAP %s started."%(VERSION))
def onFightSelected(self, event): self.dashboardFight = self.fightSelector.GetClientData(self.fightSelector.GetSelection()) self.onAnalyzerTick(log_analyzer.get())
def onNewLog(self): for i in range(1, self.fightSelector.GetCount()): self.fightSelector.Delete(1) self.fightSelector.SetSelection(0) self.dashboardFight = None self.onAnalyzerTick(log_analyzer.get())
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