/// <summary> /// Initializes a new instance of the <see cref="StormReplayResult"/> class. /// </summary> /// <param name="stormReplay">The parsed <see cref="StormReplay"/>.</param> /// <param name="stormReplayParseStatus">The <see cref="StormReplayParseStatus"/>.</param> /// <param name="fileName">The file name of the replay file.</param> /// <param name="exception">The exception, if any.</param> /// <exception cref="ArgumentException"><paramref name="fileName"/> is <see langword="null"/> or emtpy.</exception> /// <exception cref="ArgumentNullException"><paramref name="fileName"/> or <paramref name="stormReplay"/> is <see langword="null"/>.</exception> internal StormReplayResult(StormReplay stormReplay, StormReplayParseStatus stormReplayParseStatus, string fileName, StormParseException?exception = null) { Replay = stormReplay ?? throw new ArgumentNullException(nameof(stormReplay)); Status = stormReplayParseStatus; FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); Exception = exception; }
private void ValidateResult(StormReplay stormReplay) { if (stormReplay.PlayersCount == 1) { _stormReplayParseResult = StormReplayParseStatus.TryMeMode; } else if (stormReplay.Players.All(x => !x.IsWinner) || stormReplay.ReplayLength.Minutes < 2) { _stormReplayParseResult = StormReplayParseStatus.Incomplete; } else if (stormReplay.Timestamp == DateTime.MinValue) { _stormReplayParseResult = StormReplayParseStatus.UnexpectedResult; } else if (stormReplay.Timestamp < new DateTime(2014, 10, 6, 0, 0, 0, DateTimeKind.Utc)) { _stormReplayParseResult = StormReplayParseStatus.PreAlphaWipe; } else if (!_parseOptions.AllowPTR && stormReplay.Players.Any(x => x.ToonHandle?.Region >= 90)) { _stormReplayParseResult = StormReplayParseStatus.PTRRegion; } else if (!(stormReplay.Players.Count(x => x.IsWinner) == 5 && stormReplay.PlayersCount == 10 && StormGameMode.AllGameModes.HasFlag(stormReplay.GameMode))) { _stormReplayParseResult = StormReplayParseStatus.UnexpectedResult; } else { _stormReplayParseResult = StormReplayParseStatus.Success; } }
private void Parse(StormReplay stormReplay) { _stormMpqArchive.AddListfileFileNames(); Span <byte> headerBuffer = stackalloc byte[MpqHeroesArchive.HeaderSize]; _stormMpqArchive.GetHeaderBytes(headerBuffer); StormReplayHeader.Parse(stormReplay, headerBuffer); if (stormReplay.ReplayBuild < 32455) { _stormReplayParseResult = StormReplayParseStatus.PreAlphaWipe; return; } ArrayPool <byte> pool = ArrayPool <byte> .Shared; ParseReplayDetails(stormReplay, pool); if (stormReplay.Players.Length != 10 || stormReplay.Players.Count(i => i.IsWinner) != 5) { // Filter out 'Try Me' games, any games without 10 players, and incomplete games return; } else if (stormReplay.Timestamp == DateTime.MinValue) { // Uncommon issue when parsing replay.details return; } else if (stormReplay.Timestamp < new DateTime(2014, 10, 6, 0, 0, 0, DateTimeKind.Utc)) { // Technical Alpha replays return; } ParseReplayInit(stormReplay, pool); ParseReplayAttributeEvents(stormReplay, pool); ParseReplayServerBattlelobby(stormReplay, pool); if (_parseOptions.ShouldParseGameEvents) { ParseReplayGameEvents(stormReplay, pool); } if (_parseOptions.ShouldParseTrackerEvents) { ParseReplayTrackerEvents(stormReplay, pool); } if (_parseOptions.ShouldParseMessageEvents) { ParseReplayMessageEvents(stormReplay, pool); } ValidateResult(stormReplay); _stormMpqArchive.Dispose(); }
private void ParseReplayServerBattlelobby(StormReplay stormReplay, ArrayPool <byte> pool) { MpqHeroesArchiveEntry entry = _stormMpqArchive.GetEntry(ReplayServerBattlelobby.FileName); int size = (int)entry.FileSize; byte[] poolBuffer = pool.Rent(size); Span <byte> buffer = new Span <byte>(poolBuffer).Slice(0, size); _stormMpqArchive.DecompressEntry(entry, buffer); ReplayServerBattlelobby.Parse(stormReplay, buffer); pool.Return(poolBuffer); }
private static StormReplay ParseStormReplay(string fileName, ParseOptions parseOptions) { StormReplay stormReplay = new StormReplay(fileName, parseOptions); try { stormReplay.Parse(stormReplay); } catch (Exception exception) { _failedReplayException = new StormParseException("An exception has occured during the parsing of the replay.", exception); _stormReplayParseResult = StormReplayParseStatus.Exception; } return(stormReplay); }
/// <summary> /// Parses a .StormReplay file. /// </summary> /// <param name="fileName">The file name which may contain the path.</param> /// <param name="parseOptions">Sets the parsing options. If <see cref="ParseOptions.AllowPTR"/> is <see langword="false"/> the result status will be <see cref="StormReplayParseStatus.PTRRegion"/> if the replay is successfully parsed.</param> /// <returns>A <see cref="StormReplayResult"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="fileName"/> is null.</exception> public static StormReplayResult Parse(string fileName, ParseOptions?parseOptions = null) { if (fileName is null) { throw new ArgumentNullException(nameof(fileName)); } if (parseOptions is null) { parseOptions = ParseOptions.DefaultParsing; } StormReplay stormReplay = ParseStormReplay(fileName, parseOptions); return(new StormReplayResult(stormReplay, _stormReplayParseResult, fileName, _failedReplayException)); }