From 39b4ea653f3b4da3c9600391857539f1413637c6 Mon Sep 17 00:00:00 2001 From: Jan-Eric Nitschke <47750513+JanEricNitschke@users.noreply.github.com> Date: Wed, 30 Aug 2023 07:38:18 +0200 Subject: [PATCH 1/2] Added option to treat parserate as relative to 128 demo tick rate. --- awpy/parser/demoparser.py | 31 +++++++++++++++++++++++++++++++ awpy/parser/parse_demo.go | 11 +++++++++++ awpy/types.py | 4 ++++ 3 files changed, 46 insertions(+) diff --git a/awpy/parser/demoparser.py b/awpy/parser/demoparser.py index 847782160..e43977b65 100644 --- a/awpy/parser/demoparser.py +++ b/awpy/parser/demoparser.py @@ -65,6 +65,10 @@ class DemoParser: parse_rate (int, optional): One of 128, 64, 32, 16, 8, 4, 2, or 1. The lower the value, the more frames are collected. Indicates spacing between parsed demo frames in ticks. Default is 128. + parse_relative (bool): Whether the parse rate should be corrected to match + a demo tickrate of 128. This would mean that a parse rate of 128 + would always record 1 frame per second and a rate of 64 would record + one every two seconds, etc. parse_frames (bool): Flag if you want to parse frames (trajectory data) or not. Default is True parse_kill_frames (bool): Flag if you want to parse frames on kills. @@ -121,6 +125,12 @@ def __init__( The lower the value, the more frames are collected. Indicates spacing between parsed demo frames in ticks. Default is 128. + parse_relative (bool): Whether the parse rate should be corrected to + match a demo tickrate of 128. + This would mean that a parse rate of 128 + would always record 1 frame per second and a rate of 64 would record + one every two seconds, etc. + Default is False. parse_frames (bool, optional): Flag if you want to parse frames (trajectory data) or not. Default is True @@ -170,6 +180,7 @@ def __init__( self.parser_args: FullParserArgs = { "parse_rate": 128, + "parse_relative": False, "trade_time": 5, "parse_frames": True, "parse_kill_frames": False, @@ -397,6 +408,24 @@ def parse_rate(self, parse_rate: ParseRate) -> None: """ self.parser_args["parse_rate"] = parse_rate + @property + def parse_relative(self) -> bool: + """parse_relative getter. + + Returns: + bool: Current parse_relative value. + """ + return self.parser_args["parse_relative"] + + @parse_relative.setter + def parse_relative(self, parse_relative: bool) -> None: + """parse_relative setter. + + Args: + parse_relative (bool): parse_relative to use. + """ + self.parser_args["parse_relative"] = parse_relative + def _check_parse_rate(self) -> None: """Check that parse rate is not too high or low.""" # Handle parse rate. If the parse rate is less than 64, likely to be slow @@ -513,6 +542,8 @@ def parse_demo(self) -> None: parser_cmd.append("--jsonindentation") if self.parse_chat: parser_cmd.append("--parsechat") + if self.parse_relative: + parser_cmd.append("--parserelative") self.logger.debug(parser_cmd) with subprocess.Popen( parser_cmd, # noqa: S603 diff --git a/awpy/parser/parse_demo.go b/awpy/parser/parse_demo.go index 1ef41401d..1148ff2cd 100644 --- a/awpy/parser/parse_demo.go +++ b/awpy/parser/parse_demo.go @@ -29,6 +29,7 @@ type Game struct { ClientName string `json:"clientName"` Map string `json:"mapName"` TickRate int64 `json:"tickRate"` + FrameRate int64 `json:"frameRate"` PlaybackTicks int64 `json:"playbackTicks"` PlaybackFrames int64 `json:"playbackFramesCount"` ParsedToFrame int64 `json:"parsedToFrameIdx"` @@ -44,6 +45,7 @@ type Game struct { // ParserOpts holds the parameters passed to the parser. type ParserOpts struct { ParseRate int `json:"parseRate"` + ParseRelative bool `json:"parseRelative"` ParseFrames bool `json:"parseFrames"` ParseKillFrames bool `json:"parseKillFrames"` TradeTime int64 `json:"tradeTime"` @@ -2598,6 +2600,7 @@ func main() { fl := new(flag.FlagSet) demoPathPtr := fl.String("demo", "", "Demo file `path`") parseRatePtr := fl.Int("parserate", 128, "Parse rate, indicates spacing between ticks") + parseRelativePtr := fl.Bool("parserelative", false, "Parse frames relative to a tickrate of 128") parseFramesPtr := fl.Bool("parseframes", false, "Parse frames") parseKillFramesPtr := fl.Bool("parsekillframes", false, "Parse kill frames") tradeTimePtr := fl.Int("tradetime", 5, "Trade time frame (in seconds)") @@ -2613,6 +2616,7 @@ func main() { demPath := *demoPathPtr parseRate := *parseRatePtr + parseRelative := *parseRelativePtr parseFrames := *parseFramesPtr parseKillFrames := *parseKillFramesPtr tradeTime := int64(*tradeTimePtr) @@ -2655,6 +2659,12 @@ func main() { } else { currentGame.TickRate = int64(math.Round(p.TickRate())) // Rounds to 127 instead } + currentGame.FrameRate = int64(math.Round(header.FrameRate())) + + parseRate *= int(math.Round(float64(currentGame.FrameRate) / 128)) + if parseRate < 1 { + parseRate = 1 + } currentGame.PlaybackTicks = int64(header.PlaybackTicks) currentGame.PlaybackFrames = int64(header.PlaybackFrames) currentGame.ClientName = header.ClientName @@ -2665,6 +2675,7 @@ func main() { // Set parsing options parsingOpts := ParserOpts{} parsingOpts.ParseRate = parseRate + parsingOpts.ParseRelative = parseRelative parsingOpts.ParseFrames = parseFrames parsingOpts.ParseKillFrames = parseKillFrames parsingOpts.TradeTime = tradeTime diff --git a/awpy/types.py b/awpy/types.py index ec2de03c9..c9685f5a3 100644 --- a/awpy/types.py +++ b/awpy/types.py @@ -143,6 +143,7 @@ class ParserOpts(TypedDict): """ParserOpts holds the parameters passed to the parser.""" parseRate: int + parseRelative: bool parseFrames: bool parseKillFrames: bool tradeTime: int @@ -163,6 +164,7 @@ class FullParserArgs(TypedDict): """TypedDict for total parser **kwargs.""" parse_rate: ParseRate + parse_relative: bool parse_frames: bool parse_kill_frames: bool trade_time: int @@ -177,6 +179,7 @@ class ParserArgs(TypedDict, total=False): """Non total parser **kwargs.""" parse_rate: ParseRate + parse_relative: bool parse_frames: bool parse_kill_frames: bool trade_time: int @@ -609,6 +612,7 @@ class Game(TypedDict): clientName: str mapName: str tickRate: int + frameRate: int playbackTicks: int playbackFramesCount: int parsedToFrameIdx: int From 508d74115a1766016f8e7f5483dfb5856f719241 Mon Sep 17 00:00:00 2001 From: Jan-Eric Nitschke <47750513+JanEricNitschke@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:31:48 +0200 Subject: [PATCH 2/2] Properly hide relative parse rate behinds its toggle. --- awpy/parser/parse_demo.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/awpy/parser/parse_demo.go b/awpy/parser/parse_demo.go index 1148ff2cd..20915d5b7 100644 --- a/awpy/parser/parse_demo.go +++ b/awpy/parser/parse_demo.go @@ -2661,9 +2661,11 @@ func main() { } currentGame.FrameRate = int64(math.Round(header.FrameRate())) - parseRate *= int(math.Round(float64(currentGame.FrameRate) / 128)) - if parseRate < 1 { - parseRate = 1 + if parseRelative { + parseRate *= int(math.Round(float64(currentGame.FrameRate) / 128)) + if parseRate < 1 { + parseRate = 1 + } } currentGame.PlaybackTicks = int64(header.PlaybackTicks) currentGame.PlaybackFrames = int64(header.PlaybackFrames)