Git Product home page Git Product logo

hampalyzer's People

Contributors

bananahampster avatar lighttreason avatar nomad7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

hampalyzer's Issues

Feature request: allow user-submitted metadata

For games where HLTV was recorded it would be awesome to be able to associate the HLTV demo with the match logs.
Adding file hosting to hampalyzer doesn't seem practical, but perhaps we could have a comment field where people could post the links to the HLTVs - or say "gg" or congratulate Nomad on getting airshot so many times in 1 round, etc.

Congestus logs broken

L0612005.log
L0612006.log

Attempting to submit these logs results in an error:

There was an error parsing the logs. More info: «no additional info»

Hamp sent me the error (healing a tranq effect) before I finished submitting this ticket but I'll post it here for the record:

Failed to parse line number 3791: "Features-<4><STEAM_0:0:92298>" triggered "Medic_Cured_Tranquilisation" against "Doug<8><STEAM_0:1:5622>"

(removing this line allowed the logs to be uploaded and parsed successfully)

Feature request: save/favorite logs

This may be redundant depending on the resolution of #26 but if I had a particularly good game or got an unlikely MVP or something similarly brag-worthy, it might be neat if I could flag particular logs for myself and be able to view my list of favorite/saved logs somehow.

Add support for flag returns with no team specified

Currently flag returns appear to be tracked based on the team name indicated in the message that's triggered on the return, for example:

                                case "Blue Flag Returned Message":
                                case "Red Flag Returned Message":
                                    eventType = EventType.FlagReturn;
                                    data.team = Event.parseTeam(nonPlayerDataParts[2].split(" ")[0]);
                                    break;

However, in some (ADL) maps this information may not be present, for example this is what triggers on Magelli:

L 08/10/2022 - 04:47:12: World triggered "Flag has returned Info"
L 08/10/2022 - 04:47:12: World triggered "#dustbowl_flag_returned"

Magelli may be an edge case due to the number of helper entities used in the map, most of which have custom names, but I believe a similar issue affects other one-flag type maps as well. I am happy to add the various customized versions of these flag return messages as they come up, but currently the attempt to parse the team based on the message content results in an error. For example, using the Magelli trigger above:

Failed to parse line number 603: World triggered "Flag has returned Info"

file:///[...]/hampalyzer/dist/parser.js:827
                throw error;
                ^
Waiting for the debugger to disconnect...
unknown team: flag

Flag Touches not tracked properly on proton_l

In most maps the number of times each player touches the flag is calculated and shown correctly. On proton_l this calculation (or the trigger?) seems to be broken.

See http://app.hampalyzer.com/parsedlogs/Coach%27s-2021-Jul-14-18-13 (coachsouz in https://discord.gg/2AuUCZYnKv may be able to retrieve actual logs if needed).

Edit: coach apparently saw this and provided the full logs already, here's some pastebin links since it looks like I can't attach them directly:
Round 1: https://pastebin.com/f88SCzCH
Round 2: https://pastebin.com/5xH7Gmys

Feature request: include chat logs

Blarghalyzer has a feature which allows viewing of mm1 and mm2 chat - there may be an argument for hiding mm2 but being able to see mm1 messages (and timestamps) is super handy for finding the moment a thing happened that made everyone stop and type about it. :)

Determine if a set of logs are valid

Determine on parse if a set of logs is valid (e.g., more than 50% of the player pool overlaps, same map on both logs, nearly same time on both logs, identical logs already exist in DB [same server, players, map, play time]).

If so, error and return HTTP 400 with descriptive error message.

Add a new parameter to force-parse logs anyway.

Augment logs DB with the following column: is_valid boolean DEFAULT FALSE to support saving this state in the database.

haste_r logs broken

It looks like there may be multiple issues with this - with the following line in place:
L 05/03/2022 - 12:44:31: "hello? Nomad [BOISY] pls<5><STEAM_0:1:5107>" committed suicide with "door_rotating" (world)
the result is "There was an error parsing the logs. More info: «no additional info»"

If I manually change that suicide from "door_rotating" to "worldspawn" instead, the result is a 403 error: http://app.hampalyzer.com/parsedlogs/Unknown-2022-May-3-12-36-t46aa/

hellopickupmay3haster1b.log
hellopickupmay3haster2b.log

Support for mapLocation hydration (xyz to named map location)

Should probably use PostGIS (see ST_Within and 3D functions).

For any event that contains xyz coordinates, check the DB if the map exists and do a spatial query to find the named region. Add the named region to the extraData field of the event.

Insert spatial 3D regions into a database like the following:

MAPLOCATIONS table (table is new)

name type values notes
locationId auto-increment, NOT NULL
map string NOT NULL, add index
name string user-provided name/callout
geom geometry will be POLYGON Z, typ.
SELECT name 
  FROM mapLocations 
WHERE ST_3DIntersects(
    geom,
    'POINT Z($x, $y, $z)'::geometry
)
LIMIT 1;

This requires updating the debian version of the hampalyzer VM to bullseye to update apt packages to include the PostGIS extension. This is probably good housekeeping anyway...

Count totals for all available fields for both teams

Currently, while per-player data for each team appears to be calculated correctly, the Total calculations for some fields are only done for one team, not the other. This works fine for OvD CTF games, but for ADL games it would make sense to sum all available fields.

I think this is the relevant code from templateUtils.ts:

// offense summary
        Handlebars.registerHelper('offenseSummary', function(this: OffenseTeamStats, damageStatsExist: boolean, teamId: string, players?: OutputPlayer[]) {
            const isComparison = teamId === 'Comp'; // first parameter can sometimes be object??
            return `
                <tr ${isComparison && 'class="comp"'}>
                    <td class="team">${TemplateUtils.getTeamName(teamId, players)}</td>
                    ${TemplateUtils.getRow(this.frags, isComparison, "kills-total")}
                    ${TemplateUtils.getRow(this.kills, isComparison, "kills")}
                    ${TemplateUtils.getRow(this.team_kills, isComparison, "team-kills")}
                    ${TemplateUtils.getRow(this.conc_kills, isComparison, "conc-kills")}
                    ${TemplateUtils.getRow(this.sg_kills, isComparison, "sentry-kills")}` +
                    (damageStatsExist ? `
                    ${TemplateUtils.getRow(this.damage_enemy, isComparison, "damage-enemy")}
                    ${TemplateUtils.getRow(this.damage_team, isComparison, "damage-team")}` : "") + `
                    ${TemplateUtils.getRow(this.deaths, isComparison, "deaths-total")}
                    ${TemplateUtils.getRow(this.d_enemy, isComparison, "deaths")}
                    ${TemplateUtils.getRow(this.d_self, isComparison, "suicides")}
                    ${TemplateUtils.getRow(this.d_team, isComparison, "team-deaths")}
                    ${TemplateUtils.getRow(this.concs, isComparison, "concs")}
                    ${TemplateUtils.getRow(this.caps, isComparison, "flag-captures")}
                    ${TemplateUtils.getRow(this.touches, isComparison, "flag-touches")}
                    ${TemplateUtils.getRow(this.toss_percent, isComparison, "flag-toss-percentage")}
                    ${TemplateUtils.getRow(this.flag_time, isComparison, "flag-time")}
                </tr>`;
        });

        Handlebars.registerHelper('defenseSummary', function(this: DefenseTeamStats, damageStatsExist: boolean, teamId: string, players?: OutputPlayer[]) {
            const isComparison = teamId === 'Comp'; // first parameter can sometimes be object??
            return `
                <tr ${isComparison && 'class="comp"'}>
                    <td class="team">${TemplateUtils.getTeamName(teamId, players)}</td>
                    ${TemplateUtils.getRow(this.frags, isComparison, "kills-total")}
                    ${TemplateUtils.getRow(this.kills, isComparison, "kills")}
                    ${TemplateUtils.getRow(this.team_kills, isComparison, "team-kills")}
                    ${TemplateUtils.getRow(this.conc_kills, isComparison, "conc-kills")}` +
                    (damageStatsExist ? `
                    ${TemplateUtils.getRow(this.damage_enemy, isComparison, "damage-enemy")}
                    ${TemplateUtils.getRow(this.damage_team, isComparison, "damage-team")}` : "") + `
                    ${TemplateUtils.getRow(this.deaths, isComparison, "deaths-total")}
                    ${TemplateUtils.getRow(this.d_enemy, isComparison, "deaths")}
                    ${TemplateUtils.getRow(this.d_self, isComparison, "suicides")}
                    ${TemplateUtils.getRow(this.d_team, isComparison, "team-deaths")}
                    ${TemplateUtils.getRow(this.airshots, isComparison, "airshots")}
                </tr>`;
        });

Several data points are totalled for blue but not for red, but looks like the only data that's unique to red team is ${TemplateUtils.getRow(this.airshots, isComparison, "airshots")}
Can these summations be merged so that no matter what team plays offense or defense, the data totals are counted?

Add support for Baconbowl

Baconbowl's cap 3 poses an interesting challenge because it doesn't appear to have any player trigger, just a world trigger.

The i_t_g for both cap 1 and cap 2 have "netname" "Capture Point 1" which is weird but at least it shows up as the appropriate player trigger in the logs, for example:
L 08/30/2022 - 10:32:28: "hello? Nomad [BOISY] pls<3><STEAM_0:1:5107><#Dustbowl_team1>" triggered "Capture Point 1"

Cap 1 and cap 2 also have b_b values which are logged as world triggers, for example:
L 08/30/2022 - 10:32:28: World triggered "#dustbowl_blue_secures_two"

However, the cap 3 i_t_g does not have a netname and doesn't log any player triggers.
Cap 3 has "target" "cap3" which is a multi_manager, which has... "win_message" "1"
The info_tfgoal with "targetname" "win_message" has "b_b" "#dustbowl_blue_caps" which is the only thing we see in the log when someone captures point 3, for example:
L 08/30/2022 - 10:34:50: World triggered "#dustbowl_blue_caps"

It's possible I am just dumb, but it seems to me like this problem shouldn't exist if the map entities were fixed, and maybe an entity edit is the ideal solution.

With that said, is it possible to solve this problem in hampalyzer?
Is there a better way than waiting for that #dustbowl_blue_caps" world trigger, then looking back at who triggered "Flag 3" most recently?

Example games:
http://app.hampalyzer.com/parsedlogs/OldSchool-2022-Aug-27-06-24/ (no cap 3 because red successfully defended)
http://app.hampalyzer.com/parsedlogs/OldSchool-2022-Aug-27-06-51/ (Suicide_Kid captures point 3 but the only indication of this in the log is World triggered "#dustbowl_blue_caps")

Example log files:
baconbowl_r-R1-L0827017.log
baconbowl_r-R2-L0827019.log
L0830046.log (log from me finishing the map by myself in an empty server)

Entity definitions:
baconbowl_r.ent.txt

Feature Request: Add MVP

Be interesting discussion point after matches, especially if players DON'T know how MVP is calculated. A fair weighted MVP_score formula would be:

MVP_score() = 0.7(kills) + 2.8(sg_kills) + 1.4(touches) + 2.2(touches_initial) - (team_kills) + 5(caps_bonus [coast to coast caps])

The formula equally weights offense and defense performance, while rewarding plays that benefit the team and contribute to winning the most, without solely focusing on kills.

The player with the highest MVP score at the end of the match is named MVP, with one exception:

if {{name}} == "doug" OR "Doug" {
MVP_score == MVP_score / 2
}

For Doug's MVP score only.

Update DB schema and insert data

Add DB insertion of individual events: change DB structure and insert into DB on parse.

On reparse, truncate event table and restart eventId increment.

Use the following DB schema;

EVENT table (table is new)

name type values notes
eventId auto-increment, NOT NULL
logId log table id ref, NOT NULL
isFirstLog bool default true
eventType enum 0-71 NOT NULL
rawLine string NOT NULL
lineNumber number NOT NULL
timestamp datetime NOT NULL
gameTime number seconds NOT NULL
extraData string (prefer json format?)
playerFrom player table id ref
playerFromClass short 0-9
playerTo player table id ref
playerToClass short 0-9
withWeapon short 0-39
playerFromFlag bool default false
playerToFlag bool default false

PLAYER table (table is new)

name type desc notes
playerId auto-increment, NOT NULL
playerName string NOT NULL
playerAlias string
steamId number see SteamID doc

LOGS table (* are new columns)

name type values notes
* logId auto-increment, NOT NULL
parsedlog string output URI slug
log_file1 string matches name in uploads/
log_file2 string matches name in uploads/
date_parsed datetime initial upload time
date_match datetime reported in local time
map string can be ""
server string
num_players int
* is_valid bool default false

PARSEDLOGS table (table is new)

name type values notes
logId auto-increment, NOT NULL
jsonSummary varchar(MAX) full json

Feature request: show total kills by each weapon

Blarghalyzer has a feature which breaks down kills by weapon used, which I enjoy referencing for at-a-glance to see how truly useless my shotgun is.

It would really be awesome to see total damage dealt (not just kills) but I believe that requires a plugin?

Feature request: Search past logs

Currently there's a Search field at the top of the screen when viewing an individual log, but it doesn't seem to do anything :)

It would be cool to be able to find parsed logs by searching for things like...

  • map name
  • player name
  • steam id
  • game date (range?)

What I'd really love to be able to do is search for games where [player] played [class] on [map] but that may be too greedy :p

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.