/// <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;
 }
示例#2
0
 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;
     }
 }
示例#3
0
        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();
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        /// <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));
        }