예제 #1
0
def handle_end_who(match: re.Match,
                   window: wx.Frame,
                   skip_store=False) -> bool:
    who_time = match.group('time')
    zone = match.group('zone')
    if zone.lower() == "everquest":
        zone = None
    parsed_time = dateutil.parser.parse(who_time)
    raidtick_was = parsed_time - config.LAST_RAIDTICK
    raidtick_who = False
    if raidtick_was <= datetime.timedelta(seconds=3):
        raidtick_who = True
        # Handle reminder alerts
        if config.RAIDTICK_ALERT_TIMER:
            config.RAIDTICK_ALERT_TIMER.cancel()
        config.RAIDTICK_REMINDER_COUNT = 0
        config.RAIDTICK_ALERT_TIMER = threading.Timer(60 * 60,
                                                      raidtick_reminder_alert)
        config.RAIDTICK_ALERT_TIMER.start()
    log_entry = models.WhoLog(parsed_time, copy.copy(config.LAST_WHO_SNAPSHOT),
                              raidtick_who, zone)
    if raidtick_who:
        # Give audio confirmation of the RaidTick detection
        utils.alert_sound(config.NEW_RAIDTICK_SOUND)
        utils.alert_message(
            "RaidTick Recorded",
            "Recorded a new RaidTick with %d player(s), %d of which are in "
            "your alliance." %
            (len(log_entry.log), log_entry.alliance_count()))
    config.ATTENDANCE_LOGS.append(log_entry)
    wx.PostEvent(window, models.WhoHistoryEvent())
    wx.PostEvent(window, models.WhoEndEvent())
    if not skip_store:
        utils.store_state()
    return True
예제 #2
0
def handle_drop(match: re.Match, window: wx.Frame, skip_store=False) -> list:
    timestamp = match.group("time")
    name = match.group("name")
    text = match.group("text")
    guild = config.LAST_WHO_SNAPSHOT.get(name, models.Player(name)).guild
    if text.lower().startswith("looted"):
        LOG.info("Ignoring drop message starting with 'looted'")
        return list()
    if AWARD_MESSAGE_MATCHER.match(text):
        LOG.info("Ignoring drop message that matches Gratss")
        return list()
    if NUMBER_MATCHER.match(text):
        # line contains a number, it's probably a bid, ignore it
        LOG.info("Ignoring drop message with a number, probably a bid")
        return list()
    if config.RESTRICT_BIDS and guild and guild not in config.ALLIANCE_MAP:
        # Some other guild is talking, discard line
        LOG.info("Ignoring ooc from guild %s", guild)
        return list()

    # Handle text to return a list of items linked
    found_items = utils.get_items_from_text(text)
    used_found_items = []
    now = datetime.datetime.now()
    skip = False
    for item in found_items:
        if item.lower() in utils.get_active_item_names():
            LOG.debug("Skipping drop %s because it is already up for auction.")
            continue
        for pending in config.PENDING_AUCTIONS:
            pending_time = dateutil.parser.parse(pending.timestamp)
            if (item.lower() == pending.name.lower()
                    and (now - pending_time).seconds < config.DROP_COOLDOWN):
                skip = True
                LOG.debug("Skipping drop %s because of DROP_COOLDOWN config.",
                          item)
                break
        if skip:
            skip = False
            continue
        drop = models.ItemDrop(item, name, timestamp)
        if (config.NODROP_ONLY and item in extra_data.EXTRA_ITEM_DATA
                and not extra_data.EXTRA_ITEM_DATA[item].get('nodrop', True)):
            config.IGNORED_AUCTIONS.append(drop)
            LOG.info("Added droppable item to IGNORED AUCTIONS: %s", drop)
        else:
            config.PENDING_AUCTIONS.append(drop)
            LOG.info("Added item to PENDING AUCTIONS: %s", drop)
            used_found_items.append(item)
    if not found_items:
        return list()
    if used_found_items:
        wx.PostEvent(window, models.DropEvent())
        utils.alert_message(
            "New Drops Detected",
            '\n'.join(["\u00A0\u2022 %s" % drop for drop in used_found_items]))
        utils.alert_sound(config.NEW_DROP_SOUND)
    if not skip_store:
        utils.store_state()
    return found_items
예제 #3
0
 def OnMarkRaidtick(self, e: wx.EVT_RIGHT_DCLICK):
     selected_object = self.attendance_list.GetSelectedObject()
     if not selected_object:
         return
     selected_object.raidtick = not selected_object.raidtick
     self.OnRaidtickOnly(e)
     self.attendance_list.SelectObject(selected_object)
     utils.store_state()
예제 #4
0
    def OnRemovePlayer(self, e: wx.EVT_BUTTON):
        selected_player = self.attendance_record.GetSelectedObject()
        if not selected_player:
            return

        self.item.log.pop(selected_player.name)
        self.attendance_record.RemoveObject(selected_player)
        self.Update()
        utils.store_state()
예제 #5
0
def handle_kill(match: re.Match, window: wx.Frame, skip_store=False) -> bool:
    time = match.group('time')
    victim = match.group('victim')
    # if victim in extra_data.TIMER_MOBS:
    kt_obj = models.KillTimer(time, victim)
    config.KILL_TIMERS.append(kt_obj)
    wx.PostEvent(window, models.KillEvent())
    if not skip_store:
        utils.store_state()
    return True
예제 #6
0
 def OnIgnoreGratss(self, e: wx.Event):
     selected_object = self.gratss_list.GetSelectedObject()
     selected_index = self.gratss_list.GetFirstSelected()
     if not selected_object:
         return
     config.GRATSS_LOG.remove(selected_object)
     self.gratss_list.SetObjects(config.GRATSS_LOG)
     item_count = self.gratss_list.GetItemCount()
     if item_count > 0:
         self.gratss_list.Select(min(selected_index, item_count - 1))
     utils.store_state()
예제 #7
0
 def OnIgnoreCreditt(self, e: wx.Event):
     selected_object = self.creditt_list.GetSelectedObject()
     selected_index = self.creditt_list.GetFirstSelected()
     if not selected_object:
         return
     config.CREDITT_LOG.remove(selected_object)
     self.creditt_list.SetObjects(config.CREDITT_LOG)
     item_count = self.creditt_list.GetItemCount()
     if item_count > 0:
         self.creditt_list.Select(min(selected_index, item_count - 1))
     utils.store_state()
예제 #8
0
 def OnClearApp(self, e: wx.MenuEvent):
     dlg = wx.MessageDialog(self,
                            "Are you sure you want to clear all data?",
                            "Confirm Clear",
                            wx.OK | wx.CANCEL | wx.ICON_QUESTION)
     result = dlg.ShowModal()
     dlg.Destroy()
     if result == wx.ID_OK:
         utils.store_state(backup=True)
         wx.PostEvent(self.GetParent(), models.AppClearEvent())
         utils.clear_alerts()
예제 #9
0
 def UndoStart(self, e: wx.Event):
     selected_object = self.active_list.GetSelectedObject()
     if not selected_object:
         return
     selected_object.cancel()
     config.PENDING_AUCTIONS.append(selected_object.item)
     config.ACTIVE_AUCTIONS.pop(selected_object.item.uuid)
     self.pending_list.SetObjects(config.PENDING_AUCTIONS)
     self.active_list.SetObjects(
         list(config.ACTIVE_AUCTIONS.values()))
     self.pending_list.SelectObject(selected_object.item)
     utils.store_state()
예제 #10
0
 def OnIgnorePending(self, e: wx.Event):
     selected_object = self.pending_list.GetSelectedObject()
     selected_index = self.pending_list.GetFirstSelected()
     if not selected_object:
         return
     utils.ignore_pending_item(selected_object)
     self.pending_list.SetObjects(config.PENDING_AUCTIONS)
     item_count = self.pending_list.GetItemCount()
     if item_count > 0:
         self.pending_list.Select(min(selected_index, item_count - 1))
     utils.store_state()
     wx.PostEvent(self.GetGrandParent(), models.IgnoreEvent())
예제 #11
0
 def OnClose(self, e: wx.Event):
     dlg = wx.MessageDialog(
         self,
         "Do you really want to close this application?",
         "Confirm Exit", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
     result = dlg.ShowModal()
     dlg.Destroy()
     if result == wx.ID_OK:
         utils.clear_alerts()
         config.WX_TASKBAR_ICON.Destroy()
         self.parser_thread.abort()
         utils.store_state()
         self.Destroy()
예제 #12
0
 def UndoComplete(self, e: wx.Event):
     selected_object = self.history_list.GetSelectedObject()
     if not selected_object:
         return
     config.ACTIVE_AUCTIONS[selected_object.item.uuid] = (
         selected_object)
     config.HISTORICAL_AUCTIONS.pop(selected_object.item.uuid)
     self.active_list.SetObjects(
         list(config.ACTIVE_AUCTIONS.values()))
     self.history_list.SetObjects(
         list(config.HISTORICAL_AUCTIONS.values()))
     self.active_list.SelectObject(selected_object)
     utils.store_state()
예제 #13
0
 def StartAuctionRandom(self, e: wx.Event):
     selected_object = self.pending_list.GetSelectedObject()
     if not selected_object:
         return
     auc = utils.start_auction_random(selected_object)
     if not auc:
         self.DialogDuplicate()
         return
     self.pending_list.SetObjects(config.PENDING_AUCTIONS)
     self.active_list.SetObjects(
         list(config.ACTIVE_AUCTIONS.values()))
     self.active_list.SelectObject(auc)
     self.CopyBidText(e)
     utils.store_state()
예제 #14
0
 def CompleteAuction(self, e: wx.Event):
     selected_object = self.active_list.GetSelectedObject()
     if not selected_object:
         return
     selected_object.complete()
     config.HISTORICAL_AUCTIONS[selected_object.item.uuid] = (
         selected_object)
     config.ACTIVE_AUCTIONS.pop(selected_object.item.uuid)
     self.active_list.SetObjects(
         list(config.ACTIVE_AUCTIONS.values()))
     self.history_list.SetObjects(
         list(config.HISTORICAL_AUCTIONS.values()))
     self.OnHideRot(None)
     self.history_list.SelectObject(selected_object)
     self.CopyWinText(e)
     utils.store_state()
예제 #15
0
    def OnAddPlayer(self, e: wx.EVT_BUTTON):
        name_dialog = wx.TextEntryDialog(self, "Player name:", "Add Player")
        result = name_dialog.ShowModal()
        player_name = name_dialog.GetValue().capitalize()
        name_dialog.Destroy()
        if result != wx.ID_OK or not player_name:
            return

        player_guild = config.ALLIANCES[config.DEFAULT_ALLIANCE][0]
        player_record = models.Player(player_name, None, None, player_guild)
        if player_name in config.PLAYER_DB:
            player_record = config.PLAYER_DB[player_name]

        self.item.log[player_name] = player_record
        self.attendance_record.AddObject(player_record)
        self.attendance_record.Update()
        utils.store_state()
예제 #16
0
def handle_rand2(match: re.Match, window: wx.Frame, skip_store=False) -> bool:
    name = match.group('name')
    rand_from = int(match.group('from'))
    rand_to = int(match.group('to'))
    rand_result = int(match.group('result'))
    for item_obj in config.ACTIVE_AUCTIONS.values():
        if (isinstance(item_obj, models.RandomAuction)
                and item_obj.number == rand_to):
            if rand_from > 0:
                LOG.info("%s rolled from %d instead of 0, not counting it.",
                         name, rand_from)
                return False
            item_obj.add(rand_result, name)
            wx.PostEvent(window, models.BidEvent(item_obj))
            if not skip_store:
                utils.store_state()
            return True
    LOG.info("%s rolled %d-%d but that doesn't apply to an active auction.",
             name, rand_from, rand_to)
    return False
예제 #17
0
def replay_logs(replay_lines, progress_dialog):
    old_charname = config.PLAYER_NAME
    total_picked_lines = len(replay_lines)
    last_rand_player = None
    for idx, line in enumerate(replay_lines):
        keep_going, _ = progress_dialog.Update(
            idx, newmsg="Now parsing line %s of %s..." %
                        (idx, total_picked_lines))
        if not keep_going:
            LOG.debug("User cancelled log replay.")
            break

        line = line.strip()
        if last_rand_player:
            line = line + last_rand_player
            last_rand_player = None
        result = None
        for matcher in SELF_MESSAGE_MATCHERS:
            match = matcher.match(line)
            if match:
                match_func = SELF_MESSAGE_MATCHERS[matcher]
                try:
                    result = match_func(match, progress_dialog.Parent, True)
                except Exception:
                    LOG.exception("Failed to parse SELF line: %s", line)
        if result:
            LOG.debug("Handled SELF line: %s", line)
            continue

        for matcher in logparse.LOG_MATCHERS:
            match = matcher.match(line)
            if match:
                match_func = logparse.LOG_MATCHERS[matcher]
                result = match_func(match, progress_dialog.Parent, True)
                if matcher == config.MATCH_RAND1:
                    last_rand_player = result
        if result:
            LOG.debug("Handled line: %s", line)
    LOG.info("Finished log replay!")
    config.PLAYER_NAME = old_charname
    utils.store_state()
예제 #18
0
def handle_bid(match: re.Match, window: wx.Frame, skip_store=False) -> bool:
    name = match.group("name")
    if name == "You":
        name = config.PLAYER_NAME
    guild = config.LAST_WHO_SNAPSHOT.get(name, models.Player(name)).guild
    alliance = config.ALLIANCE_MAP.get(guild)
    text = match.group("text")
    bid = int(match.group("bid"))

    if text.startswith("~"):
        return False

    found_items = utils.get_items_from_text(text)
    if not found_items:
        # No item found in auction
        LOG.info("%s might have attempted to bid but no item name found: %s",
                 name, text)
        return False
    if len(found_items) > 1:
        # Can't bid on two items at once
        LOG.info("%s attempted to bid for two items at once: %s", name,
                 found_items)
        return False
    item = found_items[0]

    for auc_item in config.ACTIVE_AUCTIONS.values():
        if item.lower() == auc_item.name().lower():
            if not isinstance(auc_item, models.DKPAuction):
                LOG.info(
                    "Ignoring bid by %s because `%s` is a random auction.",
                    name, item)
                return False
            if (config.RESTRICT_BIDS and guild
                    and alliance != auc_item.alliance):
                # Player is not in the correct alliance
                LOG.info(
                    "%s attempted to bid for %s, but is in the wrong "
                    "guild/alliance: %s/%s", name, item, guild, alliance)
                return False
            result = auc_item.add(bid, name)
            wx.PostEvent(window, models.BidEvent(auc_item))
            # pylint: disable=protected-access
            if (config.SECOND_MAIN_REMINDER_DKP
                    and bid > config.SECOND_MAIN_REMINDER_DKP
                    and not auc_item._second_main_cap_alerted):
                utils.alert_message(
                    "%d DKP is above the Second-Main Cap" % bid,
                    "%s's bid for %s is above the cap for second-mains. "
                    "Please verify bidders are aware of this." % (name, item),
                    msec=8000)
                auc_item._second_main_cap_alerted = True
            elif (config.ALT_REMINDER_DKP and bid > config.ALT_REMINDER_DKP
                  and not auc_item._alt_cap_alerted):
                utils.alert_message(
                    "%d DKP is above the Alt Bid Cap" % bid,
                    "%s's bid for %s is above the cap for alts. "
                    "Please verify bidders are aware of this." % (name, item),
                    msec=8000)
                auc_item._alt_cap_alerted = True
            if not skip_store:
                utils.store_state()
            return result
    LOG.info("%s attempted to bid for %s but it isn't active", name, item)
    return False
예제 #19
0
 def OnClose(self, e: wx.EVT_CLOSE):
     self.item.raidtick = self.raidtick_checkbox.IsChecked()
     self.item.tick_name = self.name_textbox.GetValue()
     self.GetParent().RefreshList()
     utils.store_state()
     self.Destroy()