示例#1
0
    def test_q3_to_ql_process_user_info_twice_change_team(self):
        data = (
            r"0.2 ClientUserinfoChanged: 2 "
            r"n\Bartoszer\t\3\model\xaero/default\hmodel\xaero/default"
            r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        data2 = (
            r"0.2 ClientUserinfoChanged: 2 "
            r"n\Bartoszer\t\0\model\sarge/default\hmodel\xaero/default"
            r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        transformer = quake3.Q3toQL([])
        transformer.time_offset = 0.1
        transformer.server_domain = "mydomain"
        transformer.match_guid = 'dummy'
        transformer.process_raw_event(data)

        assert transformer.players
        player_info = list(transformer.players.values())[0]
        assert player_info['name'] == 'Bartoszer'
        assert player_info['model'] == r'xaero/default'

        events = transformer.process_raw_event(data2)
        assert len(events) == 1
        ev = events[0]
        assert ev['TYPE'] == 'PLAYER_SWITCHTEAM'
        assert ev['DATA']['TIME'] == 0.1
        assert ev['DATA']['WARMUP'] is False
        assert ev['DATA']['MATCH_GUID'] == 'dummy'
        assert ev['DATA']['KILLER']['NAME'] == 'Bartoszer'
        assert ev['DATA']['KILLER']['STEAM_ID']
        assert ev['DATA']['KILLER']['OLD_TEAM'] == 'SPECTATOR'
        assert ev['DATA']['KILLER']['TEAM'] == 'FREE'
示例#2
0
 def test_q3_to_ql_process_warmup(self):
     data = "15.6 Warmup:"
     transformer = quake3.Q3toQL([])
     result = transformer.result
     assert not result['warmup']
     transformer.process_raw_event(data)
     assert result['warmup']
示例#3
0
    def test_q3_to_ql_process_user_info_twice_same_team(self):
        data = (
            r"0.2 ClientUserinfoChanged: 2 "
            r"n\Bartoszer\t\0\model\xaero/default\hmodel\xaero/default"
            r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        data2 = (
            r"0.2 ClientUserinfoChanged: 2 "
            r"n\Bartoszer\t\0\model\sarge/default\hmodel\xaero/default"
            r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        transformer = quake3.Q3toQL([])
        transformer.time_offset = 0.1
        transformer.server_domain = "mydomain"
        transformer.match_guid = 'dummy'
        transformer.process_raw_event(data)

        assert transformer.players
        player_info = list(transformer.players.values())[0]
        assert player_info['name'] == 'Bartoszer'
        assert player_info['model'] == r'xaero/default'

        events = transformer.process_raw_event(data2)
        assert events == []

        assert len(transformer.players) == 1
        player_info = list(transformer.players.values())[0]
        assert player_info['model'] == r'sarge/default'
示例#4
0
def test_quake3_feed_preprocess(q3_dump):
    feeder = quake3.Q3MatchFeeder()
    matches = []
    for line in q3_dump.splitlines():
        try:
            feeder.feed(line)
        except dataprovider.FeedFull:
            matches.append(feeder.consume())

    for match in matches:
        transformer = quake3.Q3toQL(match['EVENTS'])
        transformer.process()
        result = transformer.result
        preprocessor = dataprovider.MatchPreprocessor()

        preprocessor.process_events(result['events'])

        for ev in preprocessor.events:
            assert not ev['DATA'].get('WARMUP', False)

        assert preprocessor.match_guid
        assert preprocessor.events

        if preprocessor.finished:
            assert preprocessor.duration
示例#5
0
    def test_q3_to_ql_process_exit(self):
        transformer = quake3.Q3toQL([])
        transformer.server_domain = "mydomain"
        transformer.match_guid = 'dummy'
        data = (
            r'10.0 InitGame: \dmflags\0\fraglimit\200\timelimit\15'
            r'\sv_hostname\MY Q3\sv_maxclients\32\sv_minRate\0\sv_maxRate\0'
            r'\sv_dlRate\100\sv_minPing\0\sv_maxPing\0\sv_floodProtect\0'
            r'\sv_allowDownload\1\sv_dlURL\http://10.40.3.11:8000/\capturelimit\8'
            r'\version\ioq31.36+u20160616+dfsg1-1/'
            r'Ubuntu linux-x86_64 Jun 27 2016\com_gamename\Quake3Arena'
            r'\com_protocol\71\g_gametype\0\mapname\nodm9\sv_privateClients\0'
            r'\server_ospauth\0\gamename\osp\gameversion\OSP v1.03a'
            r'\Players_Active\1 2 3 4 5 6 7 8 \server_promode\0\g_needpass\0\server_freezetag\0'
        )
        data1 = (
            "15.6 ServerTime:    20170623124301  12:43:01 (23 Jun 2017)")
        data2 = (
            r'915.6 Exit: Timelimit hit.')
        transformer.process_raw_event(data)
        assert transformer.time_offset == 10
        assert transformer.match_report_event is None
        transformer.process_raw_event(data1)
        assert transformer.result['start_date']

        transformer.process_raw_event(data2)
        ev = transformer.match_report_event
        assert ev
        assert ev['TYPE'] == 'MATCH_REPORT'
        assert ev['DATA']['MAP'] == 'nodm9'
        assert ev['DATA']['GAME_LENGTH'] == 905.6
        assert ev['DATA']['GAME_TYPE'] == 'FFA'
        assert ev['DATA']['EXIT_MSG'] == 'Timelimit hit.'
        assert transformer.result['finish_date']
示例#6
0
    def test_q3_to_ql_process_user_info(self):
        data = (
            r"0.2 ClientUserinfoChanged: 2 "
            r"n\Bartoszer\t\0\model\xaero/default\hmodel\xaero/default"
            r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        transformer = quake3.Q3toQL([])
        transformer.time_offset = 0.1
        transformer.server_domain = "mydomain"
        transformer.match_guid = 'dummy'
        result = transformer.process_raw_event(data)

        assert transformer.players
        player_info = list(transformer.players.values())[0]
        assert player_info['name'] == 'Bartoszer'
        assert player_info['model'] == r'xaero/default'

        player_id = transformer.client_player_map['2']
        assert player_id
        assert transformer.players[player_id] is player_info

        ev = result[0]
        assert ev['TYPE'] == 'PLAYER_CONNECT'
        evd = ev['DATA']
        assert evd['MATCH_GUID'] == 'dummy'
        assert evd['NAME'] == 'Bartoszer'
        assert evd['STEAM_ID']
        assert evd['TIME'] == 0.1
        assert evd['WARMUP'] is False

        ev = result[1]
        assert ev['TYPE'] == 'PLAYER_SWITCHTEAM'
        assert ev['DATA']['KILLER']['NAME'] == 'Bartoszer'
        assert ev['DATA']['KILLER']['OLD_TEAM'] == 'SPECTATOR'
        assert ev['DATA']['KILLER']['TEAM'] == 'FREE'
示例#7
0
def api2_admin_rebuild():
    if not auth(flask.request.form['token']):
        return 'Bye'

    data_store().prepare_for_rebuild()

    # TODO Server Domain is not saved
    data_dir = app.config['RAW_DATA_DIR']
    if data_dir:
        for f in listdir(data_dir):
            with open(path.join(data_dir, f)) as fh:
                data = fh.read()
                match = {
                    'EVENTS': data.splitlines()
                }

                server_domain = app.config['SERVER_DOMAIN']
                source_type = 'Q3'
                transformer = quake3.Q3toQL(match['EVENTS'])
                transformer.server_domain = server_domain

                try:
                    transformer.process()

                except Exception as e:
                    # TODO save for investigation if error
                    logger.exception(e)
                    continue

                results = transformer.result

                # PREPROCESS
                preprocessor = dataprovider.MatchPreprocessor()
                preprocessor.process_events(results['events'])

                if not preprocessor.finished:
                    continue

                fmi = dataprovider.FullMatchInfo(
                    events=preprocessor.events,
                    match_guid=preprocessor.match_guid,
                    duration=preprocessor.duration,
                    start_date=results['start_date'],
                    finish_date=results['finish_date'],
                    server_domain=server_domain,
                    source=source_type)

                analyzer = analyze.Analyzer()
                report = analyzer.analyze(fmi)
                data_store().store_analysis_report(report)

        data_store().post_rebuild()
        return 'OK'

    return 'No Data'
示例#8
0
    def test_q3_to_ql_ts2match_time(self):
        transformer = quake3.Q3toQL([])
        with pytest.raises(AssertionError):
            transformer.ts2match_time(10)

        transformer.time_offset = 10
        res = transformer.ts2match_time(15)
        assert res == 5

        with pytest.raises(AssertionError):
            transformer.ts2match_time(5)
示例#9
0
def api2_admin_match_import():
    """
    Import q3 match log previously stored in RAW_DATA_DIR
    The log file should contain single match events, excluding
    match delimiter (-----)
    """
    if not auth(flask.request.form['token']):
        return 'Bye'

    # TODO this code should be rewritten
    if 'file' not in flask.request.files:
        raise Exception("No Files")

    req_file = flask.request.files['file']
    data = req_file.read().decode("utf-8")
    match = {
        'EVENTS': data.splitlines()
    }

    server_domain = app.config['SERVER_DOMAIN']
    source_type = 'Q3'
    transformer = quake3.Q3toQL(match['EVENTS'])
    transformer.server_domain = server_domain

    try:
        transformer.process()

    except Exception as e:
        # TODO save for investigation if error
        logger.exception(e)
        return 'Failed'

    results = transformer.result

    # PREPROCESS
    preprocessor = dataprovider.MatchPreprocessor()
    preprocessor.process_events(results['events'])

    if not preprocessor.finished:
        return 'Match not finished'

    fmi = dataprovider.FullMatchInfo(
        events=preprocessor.events,
        match_guid=preprocessor.match_guid,
        duration=preprocessor.duration,
        start_date=results['start_date'],
        finish_date=results['finish_date'],
        server_domain=server_domain,
        source=source_type)

    analyzer = analyze.Analyzer()
    report = analyzer.analyze(fmi)
    data_store().store_analysis_report(report)
    return 'OK'
示例#10
0
    def test_q3_to_ql(self, q3_full_match):
        feeder = Q3MatchFeeder()
        matches = []
        for line in q3_full_match.splitlines():
            try:
                feeder.feed(line)
            except FeedFull:
                match = feeder.consume()
                matches.append(match)

        game = matches[-1]

        transformer = quake3.Q3toQL(game['EVENTS'])
        transformer.process()
示例#11
0
    def test_q3_to_ql_extract(self):
        data = "15.6 ServerTime:    20170623124300  12:43:00 (23 Jun 2017)"

        transformer = quake3.Q3toQL([])
        ts, name, args = transformer.extract(data)
        assert ts == 15.6
        assert name == "ServerTime"
        assert args == "20170623124300  12:43:00 (23 Jun 2017)"

        data = "15.7 Game End:"
        ts, name, args = transformer.extract(data)
        assert ts == 15.7
        assert name == "Game End"
        assert args == ""
示例#12
0
    def test_q3_to_ql_player_disconnected(self):
        data1 = (r"0.2 ClientUserinfoChanged: 1 "
                 r"n\Bartoszer\t\3\model\xaero/default\hmodel\xaero/default"
                 r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        data2 = (r'712.9 ClientDisconnect: 1')

        transformer = quake3.Q3toQL([])
        transformer.time_offset = 0.1
        transformer.server_domain = "mydomain"
        transformer.match_guid = 'dummy'

        transformer.process_raw_event(data1)
        ev = transformer.process_raw_event(data2)
        assert ev
        assert ev['TYPE'] == 'PLAYER_DISCONNECT'
        assert ev['DATA']['NAME'] == 'Bartoszer'
        assert ev['DATA']['STEAM_ID']
        assert ev['DATA']['TIME'] == 712.8
        assert ev['DATA']['WARMUP'] is False
        assert ev['DATA']['MATCH_GUID'] == 'dummy'
示例#13
0
    def test_q3_to_ql_process_client_info_changed_same_nick(self):
        # This test is not incorrect at the moment
        # multiple clients may be present the same,
        # unique id is assigned during connection and
        # changed later
        data = (r"0.2 ClientUserinfoChanged: 2 "
                r"n\Bartoszer\t\3\model\xaero/default\hmodel\xaero/default"
                r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        data2 = (r"0.2 ClientUserinfoChanged: 3 "
                 r"n\Bartoszer\t\0\model\sarge/default\hmodel\xaero/default"
                 r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")

        transformer = quake3.Q3toQL([])
        transformer.time_offset = 0.1
        transformer.server_domain = "mydomain"
        transformer.match_guid = 'dummy'

        transformer.process_raw_event(data)
        with pytest.raises(AssertionError):
            transformer.process_raw_event(data2)
示例#14
0
    def test_q3_to_ql_process_kill(self):
        data = (
            r"0.2 ClientUserinfoChanged: 2 "
            r"n\Bartoszer\t\3\model\xaero/default\hmodel\xaero/default"
            r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        data2 = (
            r"0.2 ClientUserinfoChanged: 3 "
            r"n\Bolek\t\0\model\sarge/default\hmodel\xaero/default"
            r"\c1\4\c2\5\hc\100\w\0\l\0\rt\0\st\0")
        data3 = (
            r"884.3 Kill: 2 3 7: Bartoszer killed Bolek by MOD_ROCKET_SPLASH 5")

        transformer = quake3.Q3toQL([])
        transformer.time_offset = 0.1
        transformer.server_domain = "mydomain"
        transformer.match_guid = 'dummy'

        transformer.process_raw_event(data)
        transformer.process_raw_event(data2)

        events = transformer.process_raw_event(data3)
        ev = events[0]
        assert ev['TYPE'] == 'PLAYER_KILL'
        assert ev['DATA']['MATCH_GUID'] == 'dummy'
        assert ev['DATA']['MOD'] == 'ROCKET_SPLASH'
        assert int(ev['DATA']['TIME']) == 884

        assert ev['DATA']['KILLER']['NAME'] == 'Bartoszer'
        assert ev['DATA']['KILLER']['STEAM_ID']
        assert ev['DATA']['KILLER']['TEAM'] == '3'

        assert ev['DATA']['VICTIM']['NAME'] == 'Bolek'
        assert ev['DATA']['VICTIM']['STEAM_ID']
        assert ev['DATA']['VICTIM']['TEAM'] == '0'

        evd = events[1]
        assert evd['TYPE'] == 'PLAYER_DEATH'
        assert evd['DATA'] == ev['DATA']
示例#15
0
    def test_q3_to_ql_process_server_time(self):
        data = "15.6 ServerTime:    20170623124301  12:43:01 (23 Jun 2017)"
        transformer = quake3.Q3toQL([])
        si = transformer.result['server_info']
        si['gametype'] = 'FFA'
        si['timelimit'] = 15
        si['fraglimit'] = 200
        si['capturelimit'] = 8
        si['mapname'] = 'q3dm6'
        si['sv_hostname'] = 'MyServ'
        event = transformer.process_raw_event(data)
        result = transformer.result

        assert result['start_date'] == datetime.datetime(2017, 6, 23, 12, 43, 1)

        assert event['TYPE'] == 'MATCH_STARTED'
        evd = event['DATA']
        assert evd['GAME_TYPE'] == 'FFA'
        assert evd['TIME_LIMIT'] == 15
        assert evd['FRAG_LIMIT'] == 200
        assert evd['CAPTURE_LIMIT'] == 8
        assert evd['MAP'] == 'q3dm6'
        assert evd['SERVER_TITLE'] == 'MyServ'
示例#16
0
def test_quake3_analyze(q3_dump):
    feeder = quake3.Q3MatchFeeder()
    matches = []
    for line in q3_dump.splitlines():
        try:
            feeder.feed(line)
        except dataprovider.FeedFull:
            matches.append(feeder.consume())

    for match in matches[-1:]:
        transformer = quake3.Q3toQL(match['EVENTS'])
        transformer.process()
        result = transformer.result
        preprocessor = dataprovider.MatchPreprocessor()

        preprocessor.process_events(result['events'])

        if not preprocessor.finished:
            continue

        fmi = dataprovider.FullMatchInfo.from_preprocessor(
            preprocessor, transformer.result['start_date'],
            transformer.result['finish_date'], 'serv-domain', 'Q3')

        analyzer = analyze.Analyzer()
        result = analyzer.analyze(fmi)

        assert result.match_metadata.duration == 900
        assert result.match_metadata.frag_limit == 200
        assert result.match_metadata.map_name == 'nodm9'
        assert result.match_metadata.match_guid
        assert result.match_metadata.server_domain == 'serv-domain'
        assert result.match_metadata.server_name == 'MY Q3'
        assert result.match_metadata.time_limit == 15

        assert result.final_scores['291b0ba5fdf78b268369a9d7'][0] == 0
        assert result.final_scores['6a018beb6405ef59ce1471b0'][0] == 27
        assert result.final_scores['7ee3d47a164c6544ea50fee6'][0] == 37
        assert result.final_scores['88fdc96e8804eaa084d740f8'][0] == 33
        assert result.final_scores['9ac5682eefa9134bbfe3c481'][0] == 42
        assert result.final_scores['a126a35a25eab0623f504183'][0] == 41
        assert result.final_scores['d37928942982cc79e7e0fe12'][0] == 85
        assert result.final_scores['e0fbefd04b9203526e6f22b8'][0] == 45
        assert result.final_scores['q3-world'][0] == 16

        assert len(result.team_switches) == 10
        assert result.team_switches[-1] == (697.3, '291b0ba5fdf78b268369a9d7',
                                            None, 'DISCONNECTED')

        assert result.players[
            '291b0ba5fdf78b268369a9d7'].name == 'Turbo Wpierdol'
        assert result.players['6a018beb6405ef59ce1471b0'].name == 'MACIEK'
        assert result.players['7ee3d47a164c6544ea50fee6'].name == 'n0npax'
        assert result.players['88fdc96e8804eaa084d740f8'].name == 'darkside'
        assert result.players['9ac5682eefa9134bbfe3c481'].name == 'BOLEK'
        assert result.players[
            'a126a35a25eab0623f504183'].name == 'killer clown'
        assert result.players['d37928942982cc79e7e0fe12'].name == 'Bartoszer'
        assert result.players['e0fbefd04b9203526e6f22b8'].name == 'Stefan'

        assert result.kills[-1] == (897.1, 'd37928942982cc79e7e0fe12',
                                    'd37928942982cc79e7e0fe12',
                                    'ROCKET_SPLASH')

        assert result.server_info.server_name == 'MY Q3'
        assert result.server_info.server_domain == 'serv-domain'
        assert result.server_info.server_type == 'Q3'

        assert result.special_scores['GAUNTLET_KILL'][3] == (
            150.4, 'd37928942982cc79e7e0fe12', 'e0fbefd04b9203526e6f22b8', 1)

        assert result.special_scores['KILLING_SPREE'][2] == (
            64.9, 'd37928942982cc79e7e0fe12', '9ac5682eefa9134bbfe3c481', 1)
示例#17
0
feeder = quake3.Q3MatchFeeder()

raw_matches = []
for line in data.splitlines():
    try:
        feeder.feed(line)
    except quake3.FeedFull:
        raw_matches.append(feeder.consume())
        feeder.feed(line)

raw_matches.append(feeder.consume())

final_results = []

for match in raw_matches:
    transformer = quake3.Q3toQL(match['EVENTS'])
    transformer.server_domain = SERVER_DOMAIN

    try:
        transformer.process()
    except Exception as e:
        print(e)
        continue

    results = transformer.result

    # PREPROCESS
    preprocessor = dataprovider.MatchPreprocessor()
    preprocessor.process_events(results['events'])

    if not preprocessor.finished:
示例#18
0
def api2_upload():
    if not auth(flask.request.form['token']):
        return 'Bye'

    # TODO this code should be rewritten
    if 'file' not in flask.request.files:
        raise Exception("No Files")

    req_file = flask.request.files['file']
    data = req_file.read().decode("utf-8")
    server_domain = app.config['SERVER_DOMAIN']
    source_type = 'Q3'
    feeder = quake3.Q3MatchFeeder()
    matches = []

    for line in data.splitlines():
        try:
            feeder.feed(line)
        except quake3.FeedFull:
            matches.append(feeder.consume())
            feeder.feed(line)

    final_results = []
    errors = 0
    for match in matches:
        # TRANSFORM TO QL
        transformer = quake3.Q3toQL(match['EVENTS'])
        transformer.server_domain = server_domain

        try:
            transformer.process()

        except Exception as e:
            # TODO save for investigation if error
            errors += 1
            logger.exception(e)
            continue

        results = transformer.result

        # PREPROCESS
        preprocessor = dataprovider.MatchPreprocessor()
        preprocessor.process_events(results['events'])

        if not preprocessor.finished:
            continue

        if app.config['RAW_DATA_DIR']:
            base = app.config['RAW_DATA_DIR']
            preprocessor.match_guid
            p = path.join(base, "{}.log".format(preprocessor.match_guid))
            with open(p, 'w') as fh:
                for line in match['EVENTS']:
                    fh.write(line)
                    fh.write('\n')

        final_results.append(dataprovider.FullMatchInfo(
            events=preprocessor.events,
            match_guid=preprocessor.match_guid,
            duration=preprocessor.duration,
            start_date=results['start_date'],
            finish_date=results['finish_date'],
            server_domain=server_domain,
            source=source_type))

        fmi = final_results[-1]
        analyzer = analyze.Analyzer()
        report = analyzer.analyze(fmi)
        data_store().store_analysis_report(report)

    return flask.jsonify({
        "ACCEPTED_MATCHES": [
            r.get_summary() for r in final_results],
        "ERRORS": errors
    })