Exemple #1
0
def load_state():
    try:
        with open(config.SAVE_STATE_FILE, 'r') as ssfp:
            json_state = json.load(ssfp, cls=JSONDecoder)
        for key, value in json_state.items():
            # Handle conversion of history data prior to v1.14
            if key == 'PLAYER_AFFILIATIONS':
                key = 'LAST_WHO_SNAPSHOT'
                value = {
                    name: models.Player(name, guild=guild)
                    for name, guild in value.items()
                }
            elif key == 'HISTORICAL_AFFILIATIONS':
                key = 'PLAYER_DB'
                value = {
                    name: models.Player(name, guild=guild)
                    for name, guild in value.items()
                }
            elif key == 'WHO_LOG':
                key = 'ATTENDANCE_LOGS'
                for entry in value:
                    entry.log = {
                        name: models.Player(name, guild=guild)
                        for name, guild in entry.log.items()
                    }

            setattr(config, key, value)
        LOG.info("Loaded state.")
    except FileNotFoundError:
        LOG.info("Failed to load state, no state file found.")
    except json.JSONDecodeError:
        LOG.exception("Failed to load state, couldn't parse JSON.")
    except Exception:
        LOG.exception("Failed to load state, unknown exception.")
    def test_handle_who(self, mock_post_event, mock_store_state):
        # Empty List, full /who
        config.LAST_WHO_SNAPSHOT = {}
        for line in base.SAMPLE_ATTENDANCE_LOGS.splitlines():
            match = config.MATCH_WHO.match(line)
            if match:
                message_handlers.handle_who(match, 'window')
        self.assertEqual(25, len(config.LAST_WHO_SNAPSHOT))
        self.assertEqual(25, mock_post_event.call_count)
        mock_post_event.reset_mock()

        # Member changed from ANONYMOUS/Unguilded to Guilded
        config.LAST_WHO_SNAPSHOT = {
            'Jim': models.Player('Jim', None, None, None)
        }
        line = '[Sun Aug 16 22:46:32 2020] [ANONYMOUS] Jim (Gnome) <Guild>'
        match = config.MATCH_WHO.match(line)
        message_handlers.handle_who(match, 'window')
        self.assertEqual(1, len(config.LAST_WHO_SNAPSHOT))
        self.assertEqual('Guild', config.LAST_WHO_SNAPSHOT['Jim'].guild)
        mock_post_event.assert_called_once_with(
            'window', models.WhoEvent('Jim', 'ANONYMOUS', '??', 'Guild'))
        mock_post_event.reset_mock()

        # Member changed guilds
        config.LAST_WHO_SNAPSHOT = {
            'Jim': models.Player('Jim', None, None, 'Guild')
        }
        line = '[Sun Aug 16 22:46:32 2020] [ANONYMOUS] Jim (Gnome) <Other>'
        match = config.MATCH_WHO.match(line)
        message_handlers.handle_who(match, 'window')
        self.assertEqual(1, len(config.LAST_WHO_SNAPSHOT))
        self.assertEqual('Other', config.LAST_WHO_SNAPSHOT['Jim'].guild)
        mock_post_event.assert_called_once_with(
            'window', models.WhoEvent('Jim', 'ANONYMOUS', '??', 'Other'))
        mock_post_event.reset_mock()

        # Member left their guild
        config.LAST_WHO_SNAPSHOT = {
            'Jim': models.Player('Jim', None, None, 'Guild')
        }
        line = '[Sun Aug 16 22:46:32 2020] [50 Cleric] Jim (Gnome)'
        match = config.MATCH_WHO.match(line)
        message_handlers.handle_who(match, 'window')
        self.assertEqual(1, len(config.LAST_WHO_SNAPSHOT))
        self.assertIsNone(config.LAST_WHO_SNAPSHOT['Jim'].guild)
        mock_post_event.assert_called_once_with(
            'window', models.WhoEvent('Jim', 'Cleric', '50', None))
        mock_post_event.reset_mock()
Exemple #3
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
Exemple #4
0
def handle_who(match: re.Match, window: wx.Frame, skip_store=False) -> bool:
    name = match.group("name")
    guild = match.group("guild")
    pclass = match.group("class") or ""
    if pclass in extra_data.CLASS_TITLES:
        pclass = extra_data.CLASS_TITLES[pclass]
    level = (match.group("level") or "??").strip()
    if name not in config.PLAYER_DB:
        LOG.info("Adding player history for %s as guild %s", name, guild)
        config.PLAYER_DB[name] = models.Player(name, pclass, level, guild)
    elif pclass != "ANONYMOUS":
        LOG.info("Updating player history for %s from %s to %s", name,
                 config.PLAYER_DB[name].guild, guild)
        config.PLAYER_DB[name].pclass = pclass
        try:
            config.PLAYER_DB[name].level = int(level)
        except (ValueError, TypeError):
            LOG.exception("Couldn't parse level to int: %s", level)
            config.PLAYER_DB[name].level = 0
        config.PLAYER_DB[name].guild = guild
    elif guild:
        LOG.info("Updating player history for RP %s from %s to %s", name,
                 config.PLAYER_DB[name].guild, guild)
        config.PLAYER_DB[name].guild = guild

    LOG.info("Adding player record for %s as guild %s", name,
             config.PLAYER_DB[name].guild)
    config.LAST_WHO_SNAPSHOT[name] = config.PLAYER_DB[name]
    wx.PostEvent(window, models.WhoEvent(name, pclass, level, guild))
    return True
Exemple #5
0
    def test_Player_model(self):
        player = models.Player("Jim", constants.CLERIC, 50, "Guild")

        # Should be JSON Encodable
        player_json = json.dumps(player, cls=utils.JSONEncoder)

        # Should be JSON Decodable
        loaded_player = json.loads(player_json, cls=utils.JSONDecoder)
        self.assertEqual(player, loaded_player)
    def test_handle_start_who(self, mock_post_event, mock_store_state):
        # Empty List, full /who
        config.LAST_WHO_SNAPSHOT = {}
        for line in base.SAMPLE_ATTENDANCE_LOGS.splitlines():
            match = config.MATCH_WHO.match(line)
            if match:
                message_handlers.handle_who(match, 'window')
        self.assertEqual(25, len(config.LAST_WHO_SNAPSHOT))
        self.assertEqual(25, mock_post_event.call_count)
        mock_post_event.reset_mock()

        # Peter and Fred should be marked as guildless
        self.assertIsNone(config.LAST_WHO_SNAPSHOT['Peter'].guild)
        self.assertIsNone(config.LAST_WHO_SNAPSHOT['Fred'].guild)

        # Mark Peter and Fred as historically belonging to Kingdom
        config.PLAYER_DB['Peter'] = models.Player('Peter', None, None,
                                                  'Kingdom')
        config.PLAYER_DB['Fred'] = models.Player('Fred', None, None, 'Kingdom')

        # Trigger New Who
        message_handlers.handle_start_who(None, 'window')
        mock_post_event.assert_called_once_with('window',
                                                models.ClearWhoEvent())
        mock_post_event.reset_mock()

        # Run the full who-list again
        for line in base.SAMPLE_ATTENDANCE_LOGS.splitlines():
            match = config.MATCH_WHO.match(line)
            if match:
                message_handlers.handle_who(match, 'window')
        self.assertEqual(25, len(config.LAST_WHO_SNAPSHOT))

        # Peter should be marked as Kingdom, and Fred as guildless
        self.assertEqual('Kingdom', config.LAST_WHO_SNAPSHOT['Peter'].guild)
        self.assertIsNone(config.LAST_WHO_SNAPSHOT['Fred'].guild)

        # It should have picked up Tom in Freya's Chariot
        self.assertEqual("Freya's Chariot",
                         config.LAST_WHO_SNAPSHOT['Tom'].guild)
Exemple #7
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()
    def test_handle_bid(self, mock_post_event, mock_store_state):
        config.LAST_WHO_SNAPSHOT = {
            'Jim': models.Player('Jim', None, None, 'Venerate'),
            'Pim': models.Player('Pim', None, None, 'Castle'),
            'Tim': models.Player('Tim', None, None, 'Kingdom'),
            'Dan': models.Player('Dan', None, None, 'Dial a Daniel'),
        }
        item_name = 'Copper Disc'
        itemdrop = models.ItemDrop(item_name, "Jim", "timestamp")
        disc_auction = models.DKPAuction(itemdrop, 'VCR')
        config.ACTIVE_AUCTIONS = {itemdrop.uuid: disc_auction}

        # FILTER ON - Someone in the alliance bids on an inactive item
        config.RESTRICT_BIDS = True
        line = ("[Sun Aug 16 22:47:31 2020] Jim auctions, "
                "'Platinum Disc 10 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertFalse(result)
        self.assertListEqual([], disc_auction.highest())
        self.assertEqual(1, len(config.ACTIVE_AUCTIONS))
        mock_post_event.assert_not_called()

        # FILTER ON - Someone outside the alliance bids on an active item
        line = ("[Sun Aug 16 22:47:31 2020] Dan auctions, "
                "'Copper Disc 10 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertFalse(result)
        self.assertEqual([], disc_auction.highest())
        mock_post_event.assert_not_called()

        # FILTER OFF - Someone in the alliance bids on an inactive item
        config.RESTRICT_BIDS = False
        line = ("[Sun Aug 16 22:47:31 2020] Jim auctions, "
                "'Platinum Disc 10 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertFalse(result)
        self.assertListEqual([], disc_auction.highest())
        self.assertEqual(1, len(config.ACTIVE_AUCTIONS))
        mock_post_event.assert_not_called()

        # FILTER ON - Someone outside the alliance bids on an active item
        config.RESTRICT_BIDS = True
        line = ("[Sun Aug 16 22:47:31 2020] Dan auctions, "
                "'Copper Disc 10 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertFalse(result)
        self.assertEqual([], disc_auction.highest())
        mock_post_event.assert_not_called()

        # Someone in the alliance says random stuff with a number
        line = ("[Sun Aug 16 22:47:31 2020] Tim auctions, "
                "'I am 12 and what channel is this'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertFalse(result)
        self.assertListEqual([], disc_auction.highest())
        mock_post_event.assert_not_called()

        # Someone in the alliance bids on two items at once
        line = ("[Sun Aug 16 22:47:31 2020] Jim auctions, "
                "'Copper Disc 10 DKP Platinum Disc'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertFalse(result)
        self.assertListEqual([], disc_auction.highest())
        mock_post_event.assert_not_called()

        # Someone we haven't seen bids on an active item
        line = ("[Sun Aug 16 22:47:31 2020] Paul auctions, "
                "'Copper Disc 5 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertTrue(result)
        self.assertListEqual([('Paul', 5)], disc_auction.highest())
        mock_post_event.assert_called_once_with('window',
                                                models.BidEvent(disc_auction))
        mock_post_event.reset_mock()

        # Someone in the alliance bids on an active item
        line = ("[Sun Aug 16 22:47:31 2020] Jim auctions, "
                "'Copper Disc 10 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertTrue(result)
        self.assertIn(('Jim', 10), disc_auction.highest())
        mock_post_event.assert_called_once_with('window',
                                                models.BidEvent(disc_auction))
        mock_post_event.reset_mock()

        # Someone in the alliance bids on an active item with wrong case
        line = ("[Sun Aug 16 22:47:31 2020] Pim auctions, "
                "'copper DISC 11 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertTrue(result)
        self.assertIn(('Pim', 11), disc_auction.highest())
        mock_post_event.assert_called_once_with('window',
                                                models.BidEvent(disc_auction))
        mock_post_event.reset_mock()

        # Someone in the alliance bids on an active item for their 2nd main
        # This would trigger a bug with "2nd" being read as "2 DKP"
        line = ("[Sun Aug 16 22:47:31 2020] Jim auctions, "
                "'Copper Disc 2nd main 12dkp'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertTrue(result)
        self.assertIn(('Jim', 12), disc_auction.highest())
        mock_post_event.assert_called_once_with('window',
                                                models.BidEvent(disc_auction))
        mock_post_event.reset_mock()

        # Someone in the alliance avoids bidding using ~
        line = ("[Sun Aug 16 22:47:31 2020] Jim auctions, "
                "'~Copper Disc 14 DKP'")
        match = config.MATCH_BID[1].match(line)
        result = message_handlers.handle_bid(match, 'window')
        self.assertFalse(result)
        self.assertListEqual([('Jim', 12)], disc_auction.highest())
        mock_post_event.assert_not_called()

        config.ACTIVE_AUCTIONS.clear()
    def test_handle_drop(self, mock_post_event, mock_store_state):
        config.LAST_WHO_SNAPSHOT = {
            'Jim': models.Player('Jim', None, None, 'Force of Will'),
            'James': models.Player('James', None, None, 'Kingdom'),
            'Dan': models.Player('Dan', None, None, 'Dial a Daniel'),
        }
        config.PENDING_AUCTIONS = list()
        config.ACTIVE_AUCTIONS = {}
        # # FILTER OFF - Item linked by a non-federation guild member
        # config.RESTRICT_BIDS = False
        # line = ("[Sun Aug 16 22:47:31 2020] Dan says out of character, "
        #         "'Belt of Iniquity'")
        # match = config.MATCH_DROP.match(line)
        # items = message_handlers.handle_drop(match, 'window')
        # self.assertEqual(1, len(items))
        # self.assertEqual(1, len(config.PENDING_AUCTIONS))
        # mock_post_event.assert_called_once_with(
        #     'window', models.DropEvent())
        # mock_post_event.reset_mock()

        # config.PENDING_AUCTIONS = list()
        # # FILTER ON - Item linked by a non-federation guild member
        # config.RESTRICT_BIDS = True
        # line = ("[Sun Aug 16 22:47:31 2020] Dan says out of character, "
        #         "'Belt of Iniquity'")
        # match = config.MATCH_DROP.match(line)
        # items = message_handlers.handle_drop(match, 'window')
        # self.assertEqual(0, len(items))
        # self.assertEqual(0, len(config.PENDING_AUCTIONS))
        # mock_post_event.assert_not_called()

        # Item linked by a federation guild member

        # NODROP filter on, droppable item
        config.NODROP_ONLY = True
        line = ("[Sun Aug 16 22:47:31 2020] Jim says out of character, "
                "'Copper Disc'")
        jim_disc_1_uuid = "jim_disc_1_uuid"
        jim_disc_1 = models.ItemDrop('Copper Disc',
                                     'Jim',
                                     'Sun Aug 16 22:47:31 2020',
                                     uuid=jim_disc_1_uuid)
        match = config.MATCH_DROP_OOC.match(line)
        items = list(message_handlers.handle_drop(match, 'window'))
        self.assertEqual(1, len(items))
        self.assertIn('Copper Disc', items)
        self.assertEqual(0, len(config.PENDING_AUCTIONS))
        mock_post_event.assert_not_called()
        mock_post_event.reset_mock()
        self.mock_playsound.assert_not_called()
        self.mock_playsound.reset_mock()

        # NODROP filter on, NODROP item
        line = ("[Sun Aug 16 22:47:31 2020] Jim says, " "'Belt of Iniquity'")
        jim_belt_1_uuid = "jim_belt_1_uuid"
        jim_belt_1 = models.ItemDrop('Belt of Iniquity',
                                     'Jim',
                                     'Sun Aug 16 22:47:31 2020',
                                     uuid=jim_belt_1_uuid)
        match = config.MATCH_DROP_SAY.match(line)
        with mock.patch('uuid.uuid4') as mock_uuid4:
            mock_uuid4.return_value = jim_belt_1_uuid
            items = list(message_handlers.handle_drop(match, 'window'))
        self.assertEqual(1, len(items))
        self.assertIn('Belt of Iniquity', items)
        self.assertEqual(1, len(config.PENDING_AUCTIONS))
        self.assertListEqual([jim_belt_1], config.PENDING_AUCTIONS)
        mock_post_event.assert_called_once_with('window', models.DropEvent())
        mock_post_event.reset_mock()
        self.mock_playsound.assert_called_once()
        self.mock_playsound.reset_mock()

        # NODROP filter off, droppable item
        config.NODROP_ONLY = False
        line = ("[Sun Aug 16 22:47:31 2020] Jim tells the guild, "
                "'Copper Disc'")
        match = config.MATCH_DROP_GU.match(line)
        with mock.patch('uuid.uuid4') as mock_uuid4:
            mock_uuid4.return_value = jim_disc_1_uuid
            items = list(message_handlers.handle_drop(match, 'window'))
        self.assertEqual(1, len(items))
        self.assertIn('Copper Disc', items)
        self.assertEqual(2, len(config.PENDING_AUCTIONS))
        self.assertListEqual([jim_belt_1, jim_disc_1], config.PENDING_AUCTIONS)
        mock_post_event.assert_called_once_with('window', models.DropEvent())
        mock_post_event.reset_mock()
        self.mock_playsound.assert_called_once()
        self.mock_playsound.reset_mock()

        # Two items linked by a federation guild member, plus chat
        line = ("[Sun Aug 16 22:47:41 2020] James tells the guild, "
                "'Platinum Disc and Golden Amber Earring woo'")
        james_disc_uuid = "james_disc_uuid"
        james_earring_uuid = "james_earring_uuid"
        james_disc = models.ItemDrop('Platinum Disc',
                                     'James',
                                     'Sun Aug 16 22:47:41 2020',
                                     uuid=james_disc_uuid)
        james_earring = models.ItemDrop('Golden Amber Earring',
                                        'James',
                                        'Sun Aug 16 22:47:41 2020',
                                        uuid=james_earring_uuid)
        match = config.MATCH_DROP_GU.match(line)
        with mock.patch('uuid.uuid4') as mock_uuid4:
            mock_uuid4.side_effect = [james_disc_uuid, james_earring_uuid]
            items = list(message_handlers.handle_drop(match, 'window'))
        self.assertEqual(2, len(items))
        self.assertListEqual(['Platinum Disc', 'Golden Amber Earring'], items)
        self.assertListEqual(
            [jim_belt_1, jim_disc_1, james_disc, james_earring],
            config.PENDING_AUCTIONS)
        mock_post_event.assert_called_once_with('window', models.DropEvent())
        mock_post_event.reset_mock()
        self.mock_playsound.assert_called_once()
        self.mock_playsound.reset_mock()

        # Random chatter by federation guild member
        line = ("[Sun Aug 16 22:47:31 2020] Jim tells the guild, "
                "'four score and seven years ago, we wanted pixels'")
        match = config.MATCH_DROP_GU.match(line)
        items = list(message_handlers.handle_drop(match, 'window'))
        self.assertEqual(0, len(items))
        self.assertListEqual(
            [jim_belt_1, jim_disc_1, james_disc, james_earring],
            config.PENDING_AUCTIONS)
        mock_post_event.assert_not_called()
        self.mock_playsound.assert_not_called()

        # Someone reports they looted an item
        line = ("[Sun Aug 16 22:47:31 2020] Jim tells the guild, "
                "'looted Belt of Iniquity'")
        match = config.MATCH_DROP_GU.match(line)
        items = list(message_handlers.handle_drop(match, 'window'))
        self.assertEqual(0, len(items))
        self.assertListEqual(
            [jim_belt_1, jim_disc_1, james_disc, james_earring],
            config.PENDING_AUCTIONS)
        mock_post_event.assert_not_called()
        self.mock_playsound.assert_not_called()

        # Bid message doesn't register as a drop
        config.ACTIVE_AUCTIONS.clear()
        jerkin_1 = models.ItemDrop('Shiverback-hide Jerkin', 'Jim',
                                   'Sun Aug 16 22:47:31 2020')
        config.PENDING_AUCTIONS.append(jerkin_1)
        auction1 = utils.start_auction_dkp(jerkin_1, 'VCR')
        self.assertEqual(config.ACTIVE_AUCTIONS.get(auction1.item.uuid),
                         auction1)
        config.PENDING_AUCTIONS.clear()
        line = ("[Sun Aug 16 22:47:31 2020] Jim tells the guild, "
                "'Shiverback-hide Jerkin'")
        match = config.MATCH_DROP_GU.match(line)
        items = list(message_handlers.handle_drop(match, 'window'))
        # One item should be found
        self.assertListEqual(['Shiverback-hide Jerkin'], items)
        self.assertListEqual([], config.PENDING_AUCTIONS)
        mock_post_event.assert_not_called()
        self.mock_playsound.assert_not_called()

        # A gratss message from another app should not register as a drop
        bid_line = ("[Sun Aug 16 22:47:31 2020] Toald tells the guild, "
                    "'Shiverback-hide Jerkin 1 main'")
        config.RESTRICT_BIDS = False
        bid_match = config.MATCH_BID_GU.match(bid_line)
        message_handlers.handle_bid(bid_match, 'window')
        config.HISTORICAL_AUCTIONS[auction1.item.uuid] = (
            config.ACTIVE_AUCTIONS.pop(auction1.item.uuid))
        line = ("[Sun Aug 16 22:47:31 2020] Jim tells the guild, "
                "'~Gratss Toald on [Shiverback-hide Jerkin] (1 DKP)!'")
        match = config.MATCH_DROP_GU.match(line)
        items = list(message_handlers.handle_drop(match, 'window'))
        self.assertListEqual([], items)

        # Ignore items if a number is present, it's probably a bid
        match = config.MATCH_DROP_GU.match(bid_line)
        items = list(message_handlers.handle_drop(match, 'window'))
        self.assertListEqual([], items)

        # second same drop shouldn't record if it is within cooldown time
        jerkin_2 = models.ItemDrop(
            'Shiverback-hide Jerkin', 'Jim',
            utils.datetime_to_eq_format(datetime.datetime.now()))
        config.PENDING_AUCTIONS.append(jerkin_2)
        line = ("[{}] Jim tells the guild, 'Shiverback-hide Jerkin'".format(
            utils.datetime_to_eq_format(datetime.datetime.now())))
        match = config.MATCH_DROP_GU.match(line)
        self.assertEqual([jerkin_2], config.PENDING_AUCTIONS)
        items = list(message_handlers.handle_drop(match, 'window'))
        self.assertListEqual([jerkin_2.name], items)
        self.assertEqual([jerkin_2], config.PENDING_AUCTIONS)

        # second same drop should record if it is past cooldown time
        jerkin_2.timestamp = utils.datetime_to_eq_format(
            datetime.datetime.now() -
            datetime.timedelta(seconds=config.DROP_COOLDOWN))
        self.assertEqual(1, len(config.PENDING_AUCTIONS))
        items = list(message_handlers.handle_drop(match, 'window'))
        self.assertListEqual([jerkin_2.name], items)
        self.assertEqual(2, len(config.PENDING_AUCTIONS))
Exemple #10
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
 def OnWho(self, e: models.WhoEvent):
     player = models.Player(e.name, e.pclass, e.level, e.guild)
     self.player_affiliations.append(player)
     self.population_list.SetObjects(self.player_affiliations)
Exemple #12
0
    def setUp(self) -> None:
        super(TestRaidgroups, self).setUp()
        self.master_player_dict = {
            'War60a': models.Player('War60a', c.WARRIOR, 60, 'FoW'),
            'War60b': models.Player('War60b', c.WARRIOR, 60, 'FoW'),
            'War59a': models.Player('War59a', c.WARRIOR, 59, 'FoW'),
            'War59b': models.Player('War59b', c.WARRIOR, 59, 'FoW'),
            'Pal60': models.Player('Pal60', c.PALADIN, 60, 'FoW'),
            'Shd60': models.Player('Shd60', c.SHADOW_KNIGHT, 60, 'FoW'),
            'Enc60': models.Player('Enc60', c.ENCHANTER, 60, 'FoW'),
            'Enc59': models.Player('Enc59', c.ENCHANTER, 59, 'FoW'),
            'Enc58': models.Player('Enc58', c.ENCHANTER, 58, 'FoW'),
            'Mag60': models.Player('Mag60', c.MAGICIAN, 60, 'FoW'),
            'Nec60': models.Player('Nec60', c.NECROMANCER, 60, 'FoW'),
            'Wiz60': models.Player('Wiz60', c.WIZARD, 60, 'FoW'),
            'Clr60': models.Player('Clr60', c.CLERIC, 60, 'FoW'),
            'Dru60': models.Player('Dru60', c.DRUID, 60, 'FoW'),
            'Shm60': models.Player('Shm60', c.SHAMAN, 60, 'FoW'),
            'Shm60torp': models.Player('Shm60torp', c.SHAMAN, 60, 'FoW'),
            'Shm59': models.Player('Shm59', c.SHAMAN, 59, 'FoW'),
            'Brd60': models.Player('Brd60', c.BARD, 60, 'FoW'),
            'Brd59': models.Player('Brd59', c.BARD, 59, 'FoW'),
            'Brd57': models.Player('Brd57', c.BARD, 57, 'FoW'),
            'Mnk60': models.Player('Mnk60', c.MONK, 60, 'FoW'),
            'Rng60': models.Player('Rng60', c.RANGER, 60, 'FoW'),
            'Rog60': models.Player('Rog60', c.ROGUE, 60, 'FoW'),
            'xWar60a': models.Player('xWar60a', c.WARRIOR, 60, 'FoW'),
            'xWar60b': models.Player('xWar60b', c.WARRIOR, 60, 'FoW'),
            'xWar59a': models.Player('xWar59a', c.WARRIOR, 59, 'FoW'),
            'xWar59b': models.Player('xWar59b', c.WARRIOR, 59, 'FoW'),
            'xPal60': models.Player('xPal60', c.PALADIN, 60, 'FoW'),
            'xShd60': models.Player('xShd60', c.SHADOW_KNIGHT, 60, 'FoW'),
            'xEnc60': models.Player('xEnc60', c.ENCHANTER, 60, 'FoW'),
            'xEnc59': models.Player('xEnc59', c.ENCHANTER, 59, 'FoW'),
            'xEnc58': models.Player('xEnc58', c.ENCHANTER, 58, 'FoW'),
            'xMag60': models.Player('xMag60', c.MAGICIAN, 60, 'FoW'),
            'xNec60': models.Player('xNec60', c.NECROMANCER, 60, 'FoW'),
            'xWiz60': models.Player('xWiz60', c.WIZARD, 60, 'FoW'),
            'xClr60': models.Player('xClr60', c.CLERIC, 60, 'FoW'),
            'xDru60': models.Player('xDru60', c.DRUID, 60, 'FoW'),
            'xShm60': models.Player('xShm60', c.SHAMAN, 60, 'FoW'),
            'xShm60torp': models.Player('xShm60torp', c.SHAMAN, 60, 'fw'),
            'xShm59': models.Player('xShm59', c.SHAMAN, 59, 'FoW'),
            'xBrd60': models.Player('xBrd60', c.BARD, 60, 'FoW'),
            'xBrd59': models.Player('xBrd59', c.BARD, 59, 'FoW'),
            'xBrd57': models.Player('xBrd57', c.BARD, 57, 'FoW'),
            'xMnk60': models.Player('xMnk60', c.MONK, 60, 'FoW'),
            'xRng60': models.Player('xRng60', c.RANGER, 60, 'FoW'),
            'xRog60': models.Player('xRog60', c.ROGUE, 60, 'FoW'),
            'aClr60': models.Player('aClr60', c.CLERIC, 60, 'FoW'),
            'bClr60': models.Player('bClr60', c.CLERIC, 60, 'FoW'),
            'cClr60': models.Player('cClr60', c.CLERIC, 60, 'FoW'),
            'dClr60': models.Player('dClr60', c.CLERIC, 60, 'FoW'),
            'eClr60': models.Player('eClr60', c.CLERIC, 60, 'FoW'),
            'fClr60': models.Player('fClr60', c.CLERIC, 60, 'FoW'),
            'gClr60': models.Player('gClr60', c.CLERIC, 60, 'FoW'),
            'hClr60': models.Player('hClr60', c.CLERIC, 60, 'FoW'),
            'iClr60': models.Player('iClr60', c.CLERIC, 60, 'FoW'),
            'jClr60': models.Player('jClr60', c.CLERIC, 60, 'FoW')
        }

        self.assertEqual(56, len(self.master_player_dict))
Exemple #13
0
from ninjalooter import models

SAMPLE_ALLIANCES = {
    'BL': ('Black Lotus', ),
    'Kingdom': ('Kingdom', 'Karens of Karana'),
    'Seal Team': ('Seal Team', ),
    'VCR': ('Venerate', 'Castle', 'Reconstructed', 'Force of Will'),
}
SAMPLE_ALLIANCE_MAP = dict()
for alliance, guilds in SAMPLE_ALLIANCES.items():
    for guild in guilds:
        SAMPLE_ALLIANCE_MAP[guild] = alliance

SAMPLE_LAST_WHO_SNAPSHOT = {
    # 6 VC
    'Bill': models.Player('Bill', None, None, 'Reconstructed'),
    'Ted': models.Player('Ted', None, None, 'Castle'),
    'James': models.Player('James', None, None, 'Castle'),
    'John': models.Player('John', None, None, 'Venerate'),
    'Fred': models.Player('Fred', None, None, 'Venerate'),
    'Gail': models.Player('Gail', None, None, 'Venerate'),
    # 4 BL
    'Tim': models.Player('Tim', None, None, 'Black Lotus'),
    'Tom': models.Player('Tom', None, None, 'Black Lotus'),
    'Jim': models.Player('Jim', None, None, 'Black Lotus'),
    'Han': models.Player('Han', None, None, 'Black Lotus'),
    # 5 Kingdom
    'Joe': models.Player('Joe', None, None, 'Kingdom'),
    'Jill': models.Player('Jill', None, None, 'Kingdom'),
    'Peter': models.Player('Peter', None, None, 'Kingdom'),
    'Paul': models.Player('Paul', None, None, 'Kingdom'),