public void StormReplayInitDataTest() { Assert.AreEqual(2079817235, _stormReplay.RandomValue); Assert.AreEqual(StormGameMode.QuickMatch, _stormReplay.GameMode); List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("KaelthasRobotVar1", player0.PlayerLoadout.SkinAndSkinTint); Assert.AreEqual("RainbowUnicornGreen", player0.PlayerLoadout.MountAndMountTint); Assert.IsFalse(player0.IsSilenced); Assert.IsFalse(player0.IsVoiceSilenced); Assert.IsFalse(player0.IsBlizzardStaff); Assert.IsFalse(player0.HasActiveBoost); Assert.AreEqual("BannerWCAllianceRare", player0.PlayerLoadout.Banner); Assert.AreEqual(6, player0.HeroMasteryTiersCount); Assert.AreEqual(PlayerType.Human, player0.PlayerType); StormPlayer player8 = players[8]; Assert.AreEqual("ZagaraInsectoidBlue", player8.PlayerLoadout.SkinAndSkinTint); Assert.AreEqual("ZagaraWings", player8.PlayerLoadout.MountAndMountTint); Assert.IsFalse(player8.IsSilenced); Assert.IsFalse(player8.IsVoiceSilenced); Assert.IsFalse(player8.IsBlizzardStaff); Assert.IsFalse(player8.HasActiveBoost); Assert.AreEqual("BannerDefault", player8.PlayerLoadout.Banner); Assert.AreEqual(1, player8.HeroMasteryTiersCount); Assert.AreEqual(PlayerType.Human, player8.PlayerType); }
public void PlayersScoreResultTest() { StormPlayer player = _stormReplay.StormPlayers.ToList()[3]; Assert.AreEqual("Kael'thas", player.PlayerHero !.HeroName); ScoreResult?scoreResult = player.ScoreResult; Assert.AreEqual(3, scoreResult !.Assists); Assert.AreEqual(0, scoreResult.ClutchHealsPerformed); Assert.AreEqual(0, scoreResult.CreepDamage); Assert.AreEqual(10462, scoreResult.DamageSoaked); Assert.AreEqual(18385, scoreResult.DamageTaken); Assert.AreEqual(new TimeSpan(0, 0, 30), scoreResult.TimeCCdEnemyHeroes); Assert.AreEqual(new TimeSpan(0, 0, 0), scoreResult.TimeRootingEnemyHeroes); Assert.AreEqual(new TimeSpan(0, 0, 0), scoreResult.TimeSilencingEnemyHeroes); Assert.AreEqual(new TimeSpan(0, 1, 23), scoreResult.TimeSpentDead); Assert.AreEqual(new TimeSpan(0, 0, 12), scoreResult.TimeStunningEnemyHeroes); Assert.AreEqual(2, scoreResult.TownKills); Assert.AreEqual(1, scoreResult.VengeancesPerformed); Assert.AreEqual(0, scoreResult.WatchTowerCaptures); Assert.AreEqual(39, scoreResult.MinionKills); Assert.AreEqual(15, scoreResult.RegenGlobes); Assert.AreEqual(1, scoreResult.Tier1Talent); Assert.AreEqual(3, scoreResult.Tier4Talent); Assert.AreEqual(1, scoreResult.Tier7Talent); Assert.AreEqual(1, scoreResult.Tier10Talent); Assert.AreEqual(2, scoreResult.Tier13Talent); Assert.AreEqual(null, scoreResult.Tier16Talent); Assert.AreEqual(null, scoreResult.Tier20Talent); }
public void StormReplayDetailsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("lavakill", player0.Name); Assert.AreEqual(1, player0.ToonHandle !.Region); Assert.AreEqual(1, player0.ToonHandle.Realm); Assert.AreEqual(1527252, player0.ToonHandle.Id); Assert.AreEqual(1869768008, player0.ToonHandle.ProgramId); Assert.AreEqual(1, player0.ToonHandle.Realm); Assert.AreEqual(StormTeam.Blue, player0.Team); Assert.IsTrue(player0.IsWinner); Assert.AreEqual("Qhira", player0.PlayerHero !.HeroName); StormPlayer player9 = players[9]; Assert.AreEqual("Player 10", player9.Name); Assert.AreEqual(0, player9.ToonHandle !.Region); Assert.AreEqual(0, player9.ToonHandle.Realm); Assert.AreEqual(0, player9.ToonHandle.Id); Assert.AreEqual(0, player9.ToonHandle.ProgramId); Assert.AreEqual("1-Hero-1-1527252", players[0].ToonHandle !.ToString()); Assert.AreEqual(StormTeam.Red, player9.Team); Assert.IsFalse(player9.IsWinner); Assert.AreEqual("Valeera", player9.PlayerHero !.HeroName); Assert.AreEqual("Dragon Shire", _stormReplay.MapInfo.MapName); Assert.AreEqual(637010888527768698, _stormReplay.Timestamp.Ticks); Assert.IsFalse(_stormReplay.HasObservers); Assert.IsTrue(_stormReplay.HasAI); }
private bool TimeSliceContains(StormPlayer result) { return(result.SpectateEvent == SpectateEvent.QuintupleKill || result.SpectateEvent == SpectateEvent.QuadKill || result.SpectateEvent == SpectateEvent.TripleKill || result.SpectateEvent == SpectateEvent.Taunt); }
public void StormReplayDetailsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("Steph", player0.Name); Assert.AreEqual(1, player0.ToonHandle !.Region); Assert.AreEqual(1, player0.ToonHandle.Realm); Assert.AreEqual(StormTeam.Blue, player0.Team); Assert.AreEqual("1-Hero-1-1182829", player0.ToonHandle.ToString()); Assert.IsFalse(player0.IsWinner); Assert.AreEqual("Greymane", player0.PlayerHero !.HeroName); Assert.AreEqual(StormRegion.US, player0.ToonHandle.StormRegion); Assert.AreEqual(StormRegion.US, _stormReplay.Region); StormPlayer player9 = players[9]; Assert.AreEqual("Pinzs", player9.Name); Assert.AreEqual(1, player9.ToonHandle !.Region); Assert.AreEqual(1, player9.ToonHandle !.Realm); Assert.AreEqual(StormTeam.Red, player9.Team); Assert.IsTrue(player9.IsWinner); Assert.AreEqual("Rehgar", player9.PlayerHero !.HeroName); Assert.AreEqual(StormTeam.Red, _stormReplay.WinningTeam); Assert.AreEqual("Volskaya Foundry", _stormReplay.MapInfo.MapName); Assert.AreEqual(637120547862521860, _stormReplay.Timestamp.Ticks); Assert.IsFalse(_stormReplay.HasAI); Assert.IsFalse(_stormReplay.HasObservers); Assert.AreEqual(0, _stormReplay.StormObservers.ToList().Count); Assert.AreEqual(0, _stormReplay.PlayersObserversCount); }
public void PlayersScoreResultTest() { StormPlayer player = _stormReplay.StormPlayers.ToList()[3]; ScoreResult?scoreResult = player.ScoreResult; Assert.IsNull(scoreResult); }
public void StormReplayInitDataTest() { Assert.AreEqual(36047320, _stormReplay.RandomValue); Assert.AreEqual(StormGameMode.Custom, _stormReplay.GameMode); List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("GreymaneDoctorVar3", player0.PlayerLoadout.SkinAndSkinTint); Assert.AreEqual("MountCloudWhimsy", player0.PlayerLoadout.MountAndMountTint); Assert.IsFalse(player0.IsSilenced); Assert.IsFalse(player0.IsVoiceSilenced); Assert.IsFalse(player0.IsBlizzardStaff); Assert.IsFalse(player0.HasActiveBoost); Assert.AreEqual("BannerDFEsportsWarChestRareDignitas", player0.PlayerLoadout.Banner); Assert.AreEqual("SprayStaticHGC2017EUDignitas", player0.PlayerLoadout.Spray); Assert.AreEqual("JainaA", player0.PlayerLoadout.AnnouncerPack); Assert.AreEqual("GreymaneBase_VoiceLine01", player0.PlayerLoadout.VoiceLine); Assert.AreEqual(15, player0.HeroMasteryTiersCount); Assert.AreEqual("Barb", player0.HeroMasteryTiers.ToList()[2].HeroAttributeId); Assert.AreEqual(1, player0.HeroMasteryTiers.ToList()[2].TierLevel); Assert.AreEqual(PlayerType.Human, player0.PlayerType); List <StormPlayer> playersWithObs = _stormReplay.StormPlayersWithObservers.ToList(); StormPlayer player8 = playersWithObs[8]; Assert.AreEqual(PlayerType.Observer, player8.PlayerType); Assert.AreEqual(PlayerDifficulty.Unknown, player8.PlayerDifficulty); }
public void StormReplayInitDataTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.IsFalse(player0.IsSilenced); Assert.IsFalse(player0.IsVoiceSilenced); Assert.IsTrue(player0.IsBlizzardStaff); Assert.IsFalse(player0.HasActiveBoost); }
public void PlayersScoreResultTest() { StormPlayer player = _stormReplay.StormPlayers.ToList()[8]; Assert.AreEqual("Malfurion", player.PlayerHero !.HeroName); ScoreResult?scoreResult = player.ScoreResult; Assert.AreEqual(8, scoreResult !.Assists); Assert.AreEqual(3, scoreResult.ClutchHealsPerformed); Assert.AreEqual(8266, scoreResult.CreepDamage); Assert.AreEqual(18772, scoreResult.DamageSoaked); Assert.AreEqual(21863, scoreResult.DamageTaken); Assert.AreEqual(1, scoreResult.Deaths); Assert.AreEqual(0, scoreResult.EscapesPerformed); Assert.AreEqual(7123, scoreResult.ExperienceContribution); Assert.AreEqual(65166, scoreResult.Healing); Assert.AreEqual(13986, scoreResult.HeroDamage); Assert.AreEqual(8, scoreResult.HighestKillStreak); Assert.AreEqual(18, scoreResult.Level); Assert.AreEqual(0, scoreResult.MercCampCaptures); Assert.AreEqual(62359, scoreResult.MetaExperience); Assert.AreEqual(12804, scoreResult.MinionDamage); Assert.AreEqual(0, scoreResult.Multikill); Assert.AreEqual(0, scoreResult.OutnumberedDeaths); Assert.AreEqual(null, scoreResult.PhysicalDamage); Assert.AreEqual(0, scoreResult.ProtectionGivenToAllies); Assert.AreEqual(0, scoreResult.SelfHealing); Assert.AreEqual(22012, scoreResult.SiegeDamage); Assert.AreEqual(0, scoreResult.SoloKills); Assert.AreEqual(null, scoreResult.SpellDamage); Assert.AreEqual(9208, scoreResult.StructureDamage); Assert.AreEqual(0, scoreResult.SummonDamage); Assert.AreEqual(8, scoreResult.Takedowns); Assert.AreEqual(12196, scoreResult.TeamfightDamageTaken); Assert.AreEqual(0, scoreResult.TeamfightEscapesPerformed); Assert.AreEqual(16378, scoreResult.TeamfightHealingDone); Assert.AreEqual(5228, scoreResult.TeamfightHeroDamage); Assert.AreEqual(new TimeSpan(0, 0, 28), scoreResult.TimeCCdEnemyHeroes); Assert.AreEqual(new TimeSpan(0, 0, 25), scoreResult.TimeRootingEnemyHeroes); Assert.AreEqual(new TimeSpan(0, 0, 0), scoreResult.TimeSilencingEnemyHeroes); Assert.AreEqual(new TimeSpan(0, 0, 56), scoreResult.TimeSpentDead); Assert.AreEqual(new TimeSpan(0, 0, 0), scoreResult.TimeStunningEnemyHeroes); Assert.AreEqual(0, scoreResult.TownKills); Assert.AreEqual(0, scoreResult.VengeancesPerformed); Assert.AreEqual(0, scoreResult.WatchTowerCaptures); Assert.AreEqual(1, scoreResult.Tier1Talent); Assert.AreEqual(3, scoreResult.Tier4Talent); Assert.AreEqual(3, scoreResult.Tier7Talent); Assert.AreEqual(1, scoreResult.Tier10Talent); Assert.AreEqual(3, scoreResult.Tier13Talent); Assert.AreEqual(2, scoreResult.Tier16Talent); Assert.AreEqual(null, scoreResult.Tier20Talent); }
public void StormReplayDetailsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("kpaxchaos", player0.Name); Assert.AreEqual(2, player0.ToonHandle !.Region); Assert.AreEqual(1, player0.ToonHandle.Realm); Assert.AreEqual(StormRegion.EU, player0.ToonHandle.StormRegion); Assert.AreEqual(StormTeam.Blue, _stormReplay.WinningTeam); }
public async Task <Uri> SaveClip(StormPlayer stormPlayer, StormReplay stormReplay) { // Limited api functionality // Cannot modify the title of the clip // Cannot modify the time of the clip from 30 to 60 seconds // When twitch allow it, modify the title to a format like: [Hero] [Map] - [Quintuple, Quad, Tripple] kill CreatedClipResponse response = await twitchAPI.Helix.Clips.CreateClipAsync(settings.TwitchBroadcasterId); GetClipResponse clip = await twitchAPI.Helix.Clips.GetClipAsync(response.CreatedClips[0].Id); return(new Uri(clip.Clips[0].Url)); }
public void StormReplayInitDataTest() { Assert.AreEqual(2143281452, _stormReplay.RandomValue); Assert.AreEqual(StormGameMode.QuickMatch, _stormReplay.GameMode); List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("BrightwingLuxMonkeyWhite", player0.PlayerLoadout.SkinAndSkinTint); Assert.AreEqual(string.Empty, player0.PlayerLoadout.MountAndMountTint); Assert.IsFalse(player0.IsSilenced); Assert.IsFalse(player0.IsVoiceSilenced); Assert.IsFalse(player0.IsBlizzardStaff); Assert.IsTrue(player0.HasActiveBoost); Assert.AreEqual("BannerD3WitchDoctorRareVar2", player0.PlayerLoadout.Banner); Assert.AreEqual("SprayStaticWinterRewardReigndeer", player0.PlayerLoadout.Spray); Assert.AreEqual("MurkyA", player0.PlayerLoadout.AnnouncerPack); Assert.AreEqual("BrightwingMonkey_VoiceLine01", player0.PlayerLoadout.VoiceLine); Assert.AreEqual(22, player0.HeroMasteryTiersCount); Assert.AreEqual("Arts", player0.HeroMasteryTiers.ToList()[2].HeroAttributeId); Assert.AreEqual(3, player0.HeroMasteryTiers.ToList()[2].TierLevel); }
public void StormReplayDetailsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("AZTDoubt", player0.Name); Assert.AreEqual(1, player0.ToonHandle !.Region); Assert.AreEqual(1, player0.ToonHandle.Realm); Assert.AreEqual(7027042, player0.ToonHandle.Id); Assert.AreEqual(1869768008, player0.ToonHandle.ProgramId); Assert.AreEqual(StormTeam.Blue, player0.Team); Assert.IsFalse(player0.IsWinner); Assert.AreEqual("Greymane", player0.PlayerHero !.HeroName); Assert.AreEqual(StormRegion.US, player0.ToonHandle.StormRegion); Assert.AreEqual(StormTeam.Red, _stormReplay.WinningTeam); StormPlayer player = players[9]; Assert.AreEqual("FiZiX", player.Name); Assert.AreEqual(1, player.ToonHandle !.Region); Assert.AreEqual(1, player.ToonHandle.Realm); Assert.AreEqual(StormTeam.Red, player.Team); Assert.IsTrue(player.IsWinner); Assert.AreEqual("Li-Ming", player.PlayerHero !.HeroName); Assert.AreEqual("Battlefield of Eternity", _stormReplay.MapInfo.MapName); Assert.AreEqual(636619794857150779, _stormReplay.Timestamp.Ticks); List <StormPlayer> playersWithObs = _stormReplay.StormPlayersWithObservers.ToList(); StormPlayer player8 = playersWithObs[8]; Assert.AreEqual(StormTeam.Observer, player8.Team); Assert.IsTrue(_stormReplay.HasObservers); Assert.IsFalse(_stormReplay.HasAI); Assert.AreEqual(1, _stormReplay.PlayersObserversCount); Assert.IsNull(_stormReplay.StormObservers.ToList()[0].PlayerHero); }
public void StormReplayInitDataTest() { Assert.AreEqual(4013533878, _stormReplay.RandomValue); Assert.AreEqual(StormGameMode.QuickMatch, _stormReplay.GameMode); List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual(string.Empty, player0.PlayerLoadout.SkinAndSkinTint); Assert.AreEqual("BattleBeastNexus", player0.PlayerLoadout.MountAndMountTint); Assert.IsFalse(player0.IsSilenced); Assert.IsFalse(player0.IsVoiceSilenced); Assert.IsFalse(player0.IsBlizzardStaff); Assert.IsFalse(player0.HasActiveBoost); Assert.AreEqual(string.Empty, player0.PlayerLoadout.Banner); Assert.AreEqual(string.Empty, player0.PlayerLoadout.Spray); Assert.AreEqual(string.Empty, player0.PlayerLoadout.AnnouncerPack); Assert.AreEqual(string.Empty, player0.PlayerLoadout.VoiceLine); Assert.AreEqual(0, player0.HeroMasteryTiersCount); Assert.IsFalse(_stormReplay.HasObservers); Assert.IsFalse(_stormReplay.HasAI); }
public void StormReplayInitDataTest() { Assert.AreEqual(1102687070, _stormReplay.RandomValue); Assert.AreEqual(StormGameMode.StormLeague, _stormReplay.GameMode); List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("GreymaneDoctorVar1", player0.PlayerLoadout.SkinAndSkinTint); Assert.AreEqual("MountCloud", player0.PlayerLoadout.MountAndMountTint); Assert.IsFalse(player0.IsSilenced); Assert.IsFalse(player0.IsVoiceSilenced); Assert.IsFalse(player0.IsBlizzardStaff); Assert.IsFalse(player0.HasActiveBoost); Assert.AreEqual("BannerOWDVaIconicRare", player0.PlayerLoadout.Banner); Assert.AreEqual("SprayStaticComicSweetChromie", player0.PlayerLoadout.Spray); Assert.AreEqual("DeckardA", player0.PlayerLoadout.AnnouncerPack); Assert.AreEqual("GreymaneBase_VoiceLine04", player0.PlayerLoadout.VoiceLine); Assert.AreEqual("Greymane", player0.PlayerHero !.HeroId); Assert.AreEqual(24, player0.HeroMasteryTiersCount); Assert.AreEqual("Auri", player0.HeroMasteryTiers.ToList()[2].HeroAttributeId); Assert.AreEqual(1, player0.HeroMasteryTiers.ToList()[2].TierLevel); }
public void StormReplayAttributeEventsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player = players[9]; Assert.AreEqual("5v5", _stormReplay.TeamSize); Assert.AreEqual(PlayerDifficulty.Elite, player.PlayerDifficulty); Assert.AreEqual(StormGameSpeed.Faster, _stormReplay.GameSpeed); Assert.AreEqual(StormGameMode.StormLeague, _stormReplay.GameMode); Assert.AreEqual("Rehg", player.PlayerHero !.HeroAttributeId); Assert.AreEqual("Reh8", player.PlayerLoadout.SkinAndSkinTintAttributeId); Assert.AreEqual(string.Empty, player.PlayerLoadout.MountAndMountTintAttributeId); Assert.AreEqual("BN03", player.PlayerLoadout.BannerAttributeId); Assert.AreEqual("SY3K", player.PlayerLoadout.SprayAttributeId); Assert.AreEqual("RE05", player.PlayerLoadout.VoiceLineAttributeId); Assert.AreEqual("DEA0", player.PlayerLoadout.AnnouncerPackAttributeId); Assert.AreEqual(20, player.PlayerHero.HeroLevel); List <string?> ban0List = _stormReplay.GetTeamBans(StormTeam.Blue).ToList(); List <string?> ban1List = _stormReplay.GetTeamBans(StormTeam.Red).ToList(); Assert.AreEqual("Garr", ban0List[1]); Assert.AreEqual("DEAT", ban1List[1]); }
public void StormReplayAttributeEventsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player = players[9]; Assert.AreEqual("5v5", _stormReplay.TeamSize); Assert.AreEqual(PlayerDifficulty.Elite, player.PlayerDifficulty); Assert.AreEqual(StormGameSpeed.Faster, _stormReplay.GameSpeed); Assert.AreEqual(StormGameMode.QuickMatch, _stormReplay.GameMode); Assert.AreEqual("Hanz", player.PlayerHero !.HeroAttributeId); Assert.AreEqual("Han2", player.PlayerLoadout.SkinAndSkinTintAttributeId); Assert.AreEqual("Arm2", player.PlayerLoadout.MountAndMountTintAttributeId); Assert.AreEqual("BNaf", player.PlayerLoadout.BannerAttributeId); Assert.AreEqual("SY96", player.PlayerLoadout.SprayAttributeId); Assert.AreEqual("HA01", player.PlayerLoadout.VoiceLineAttributeId); Assert.AreEqual("AHAN", player.PlayerLoadout.AnnouncerPackAttributeId); Assert.AreEqual(20, player.PlayerHero.HeroLevel); List <string?> ban0List = _stormReplay.GetTeamBans(StormTeam.Blue).ToList(); List <string?> ban1List = _stormReplay.GetTeamBans(StormTeam.Red).ToList(); Assert.AreEqual(string.Empty, ban0List[1]); Assert.AreEqual(string.Empty, ban1List[1]); }
public void StormReplayDetailsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player0 = players[0]; Assert.AreEqual("crazealot", player0.Name); Assert.AreEqual(1, player0.ToonHandle !.Region); Assert.AreEqual(1, player0.ToonHandle.Realm); Assert.AreEqual(StormTeam.Blue, player0.Team); Assert.IsTrue(player0.IsWinner); Assert.AreEqual("Brightwing", player0.PlayerHero !.HeroName); Assert.AreEqual(StormTeam.Blue, _stormReplay.WinningTeam); StormPlayer player1 = players[9]; Assert.AreEqual("DumbleBore", player1.Name); Assert.AreEqual(1, player1.ToonHandle !.Region); Assert.AreEqual(1, player1.ToonHandle.Realm); Assert.AreEqual(StormTeam.Red, player1.Team); Assert.IsFalse(player1.IsWinner); Assert.AreEqual("Hanzo", player1.PlayerHero !.HeroName); Assert.AreEqual("Hanamura Temple", _stormReplay.MapInfo.MapName); Assert.AreEqual(636997822244093849, _stormReplay.Timestamp.Ticks); }
public void StormReplayAttributeEventsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player = players[9]; Assert.AreEqual("5v5", _stormReplay.TeamSize); Assert.AreEqual(PlayerDifficulty.Veteran, player.PlayerDifficulty); Assert.AreEqual(StormGameSpeed.Faster, _stormReplay.GameSpeed); Assert.AreEqual(StormGameMode.Cooperative, _stormReplay.GameMode); Assert.AreEqual(string.Empty, player.PlayerHero !.HeroAttributeId); Assert.AreEqual(string.Empty, player.PlayerLoadout.SkinAndSkinTintAttributeId); Assert.AreEqual(string.Empty, player.PlayerLoadout.MountAndMountTintAttributeId); Assert.AreEqual(string.Empty, player.PlayerLoadout.BannerAttributeId); Assert.AreEqual(string.Empty, player.PlayerLoadout.SprayAttributeId); Assert.AreEqual(string.Empty, player.PlayerLoadout.VoiceLineAttributeId); Assert.AreEqual(string.Empty, player.PlayerLoadout.AnnouncerPackAttributeId); Assert.AreEqual(1, player.PlayerHero.HeroLevel); List <string?> ban0List = _stormReplay.GetTeamBans(StormTeam.Blue).ToList(); List <string?> ban1List = _stormReplay.GetTeamBans(StormTeam.Red).ToList(); Assert.AreEqual(string.Empty, ban0List[1]); Assert.AreEqual(string.Empty, ban1List[1]); }
public void StormReplayAttributeEventsTest() { List <StormPlayer> players = _stormReplay.StormPlayers.ToList(); StormPlayer player = players[9]; Assert.AreEqual("5v5", _stormReplay.TeamSize); Assert.AreEqual(PlayerDifficulty.Elite, player.PlayerDifficulty); Assert.AreEqual(StormGameSpeed.Faster, _stormReplay.GameSpeed); Assert.AreEqual(StormGameMode.Custom, _stormReplay.GameMode); Assert.AreEqual("Wiza", player.PlayerHero !.HeroAttributeId); Assert.AreEqual("WizI", player.PlayerLoadout.SkinAndSkinTintAttributeId); Assert.AreEqual("CLO0", player.PlayerLoadout.MountAndMountTintAttributeId); Assert.AreEqual("BN6d", player.PlayerLoadout.BannerAttributeId); Assert.AreEqual("SY81", player.PlayerLoadout.SprayAttributeId); Assert.AreEqual("WZ04", player.PlayerLoadout.VoiceLineAttributeId); Assert.AreEqual("AFIR", player.PlayerLoadout.AnnouncerPackAttributeId); Assert.AreEqual(20, player.PlayerHero.HeroLevel); List <string?> ban0List = _stormReplay.GetTeamBans(StormTeam.Blue).ToList(); List <string?> ban1List = _stormReplay.GetTeamBans(StormTeam.Red).ToList(); Assert.AreEqual("Diab", ban0List[1]); Assert.AreEqual("Tra0", ban1List[1]); }
private static void PlayerInfo(StormPlayer player, PartyIconColor?partyIcon) { if (player is null) { throw new ArgumentNullException(nameof(player)); } if (player.PlayerType != PlayerType.Computer) { StringBuilder stringBuilder = new(); StringBuilder playerBuilder = stringBuilder; // party if (partyIcon.HasValue) { playerBuilder.Append($"[{(int)partyIcon}]"); } else { playerBuilder.Append($"{"[-]"}"); } // battletag if (!string.IsNullOrEmpty(player.BattleTagName)) { playerBuilder.Append($" {player.BattleTagName,-22}"); } else { playerBuilder.Append($" {player.Name,-22}"); } // account level if (player.AccountLevel.HasValue && player.AccountLevel.Value > 0) { string level = $" [Level:{player.AccountLevel.Value}]"; playerBuilder.Append($"{level,-14}"); } else { playerBuilder.Append($"{" [Level:???]",-14}"); } // toon handle playerBuilder.Append($" [Toon:{player.ToonHandle}]"); Console.WriteLine(playerBuilder); } else if (player.PlayerType == PlayerType.Computer) { Console.WriteLine($"[-] {player.Name}"); } if (player.HeroMasteryTiers.ToDictionary(x => x.HeroAttributeId, x => x.TierLevel).TryGetValue(player.PlayerHero !.HeroAttributeId, out int tierLevel)) { if (tierLevel == 2 && player.PlayerHero.HeroLevel < 25) { player.PlayerHero.HeroLevel = 25; } else if (tierLevel == 3 && player.PlayerHero.HeroLevel < 50) { player.PlayerHero.HeroLevel = 50; } else if (tierLevel == 4 && player.PlayerHero.HeroLevel < 75) { player.PlayerHero.HeroLevel = 75; } else if (tierLevel == 5 && player.PlayerHero.HeroLevel < 100) { player.PlayerHero.HeroLevel = 100; } } if (player.PlayerType != PlayerType.Observer) { // hero name StringBuilder heroBuilder = new($"{player.PlayerHero!.HeroName,-16}"); // hero level if (player.IsAutoSelect) { heroBuilder.Append($"{" [Level:Auto]",-14}"); } else { string level = $" [Level:{player.PlayerHero.HeroLevel}]"; heroBuilder.Append($"{level,-14}"); } // hero unit id heroBuilder.Append($" [ID:{player.PlayerHero.HeroUnitId}]"); Console.WriteLine($" Hero: {heroBuilder}"); if (player.MatchAwards != null) { foreach (MatchAwardType matchAwardType in player.MatchAwards) { Console.WriteLine($" Award: {matchAwardType}"); } } // talents if (_showPlayerTalents) { Console.WriteLine(); Console.WriteLine("Talents"); Console.Write($"{"Level 1:",10}"); if (player.Talents.Count >= 1) { Console.WriteLine($" {player.Talents[0].TalentNameId}"); } else { Console.WriteLine(); } Console.Write($"{"Level 4:",10}"); if (player.Talents.Count >= 2) { Console.WriteLine($" {player.Talents[1].TalentNameId}"); } else { Console.WriteLine(); } Console.Write($"{"Level 7:",10}"); if (player.Talents.Count >= 3) { Console.WriteLine($" {player.Talents[2].TalentNameId}"); } else { Console.WriteLine(); } Console.Write($"{"Level 10:",10}"); if (player.Talents.Count >= 4) { Console.WriteLine($" {player.Talents[3].TalentNameId}"); } else { Console.WriteLine(); } Console.Write($"{"Level 13:",10}"); if (player.Talents.Count >= 5) { Console.WriteLine($" {player.Talents[4].TalentNameId}"); } else { Console.WriteLine(); } Console.Write($"{"Level 16:",10}"); if (player.Talents.Count >= 6) { Console.WriteLine($" {player.Talents[5].TalentNameId}"); } else { Console.WriteLine(); } Console.Write($"{"Level 20:",10}"); if (player.Talents.Count >= 7) { Console.WriteLine($" {player.Talents[6].TalentNameId}"); } else { Console.WriteLine(); } Console.WriteLine(); } // stats if (_showPlayerStats) { Console.WriteLine(); Console.WriteLine("Statistics"); if (player.ScoreResult != null) { Console.WriteLine("Combat"); Console.WriteLine($"{"Hero Kills:",_statisticsFieldWidth} {player.ScoreResult.SoloKills}"); Console.WriteLine($"{"Assists:",_statisticsFieldWidth} {player.ScoreResult.Assists}"); Console.WriteLine($"{"Takedowns:",_statisticsFieldWidth} {player.ScoreResult.Takedowns}"); Console.WriteLine($"{"Deaths:",_statisticsFieldWidth} {player.ScoreResult.Deaths}"); Console.WriteLine("Siege"); Console.WriteLine($"{"Minion Damage:",_statisticsFieldWidth} {player.ScoreResult.MinionDamage}"); Console.WriteLine($"{"Summon Damage:",_statisticsFieldWidth} {player.ScoreResult.SummonDamage}"); Console.WriteLine($"{"Structure Damage:",_statisticsFieldWidth} {player.ScoreResult.StructureDamage}"); Console.WriteLine($"{"Total Siege Damage:",_statisticsFieldWidth} {player.ScoreResult.SiegeDamage}"); Console.WriteLine("Hero"); Console.WriteLine($"{"Hero Damage:",_statisticsFieldWidth} {player.ScoreResult.HeroDamage}"); if (player.ScoreResult.DamageTaken > 0) { Console.WriteLine($"{"Damage Taken:",_statisticsFieldWidth} {player.ScoreResult.DamageTaken}"); } else { Console.WriteLine($"{"Damage Taken:",_statisticsFieldWidth}"); } if (player.ScoreResult.Healing > 0) { Console.WriteLine($"{"Healing/Shielding:",_statisticsFieldWidth} {player.ScoreResult.Healing}"); } else { Console.WriteLine($"{"Healing/Shielding:",_statisticsFieldWidth}"); } if (player.ScoreResult.SelfHealing > 0) { Console.WriteLine($"{"Self Healing:",_statisticsFieldWidth} {player.ScoreResult.SelfHealing}"); } else { Console.WriteLine($"{"Self Healing:",_statisticsFieldWidth}"); } Console.WriteLine($"{"Experience:",_statisticsFieldWidth} {player.ScoreResult.ExperienceContribution}"); Console.WriteLine("Time"); Console.WriteLine($"{"Spent Dead:",_statisticsFieldWidth} {player.ScoreResult.TimeSpentDead}"); Console.WriteLine($"{"Rooting Heroes:",_statisticsFieldWidth} {player.ScoreResult.TimeRootingEnemyHeroes}"); Console.WriteLine($"{"Silence Heroes:",_statisticsFieldWidth} {player.ScoreResult.TimeSilencingEnemyHeroes}"); Console.WriteLine($"{"Stun Heroes:",_statisticsFieldWidth} {player.ScoreResult.TimeStunningEnemyHeroes}"); Console.WriteLine($"{"CC Heroes:",_statisticsFieldWidth} {player.ScoreResult.TimeCCdEnemyHeroes}"); Console.WriteLine($"{"On Fire:",_statisticsFieldWidth} {player.ScoreResult.OnFireTimeonFire}"); Console.WriteLine("Other"); if (player.ScoreResult.SpellDamage.HasValue && player.ScoreResult.SpellDamage.Value > 0) { Console.WriteLine($"{"Spell Damage:",_statisticsFieldWidth} {player.ScoreResult.SpellDamage}"); } else { Console.WriteLine($"{"Spell Damage:",_statisticsFieldWidth}"); } if (player.ScoreResult.PhysicalDamage.HasValue && player.ScoreResult.PhysicalDamage.Value > 0) { Console.WriteLine($"{"Physical Damage:",_statisticsFieldWidth} {player.ScoreResult.PhysicalDamage}"); } else { Console.WriteLine($"{"Physical Damage:",_statisticsFieldWidth}"); } Console.WriteLine($"{"Merc Damage:",_statisticsFieldWidth} {player.ScoreResult.CreepDamage}"); Console.WriteLine($"{"Merc Camp Captures:",_statisticsFieldWidth} {player.ScoreResult.MercCampCaptures}"); Console.WriteLine($"{"Watch Tower Captures:",_statisticsFieldWidth} {player.ScoreResult.WatchTowerCaptures}"); Console.WriteLine($"{"Town Kills:",_statisticsFieldWidth} {player.ScoreResult.TownKills}"); Console.WriteLine($"{"Town Kills:",_statisticsFieldWidth} {player.ScoreResult.TownKills}"); Console.WriteLine($"{"Minion Kills:",_statisticsFieldWidth} {player.ScoreResult.MinionKills}"); Console.WriteLine($"{"Regen Globes:",_statisticsFieldWidth} {player.ScoreResult.RegenGlobes}"); } else { Console.WriteLine("(NOT AVAILABLE)"); } Console.WriteLine(); } } }
public static void Parse(StormReplay replay, ReadOnlySpan <byte> source) { BitReader bitReader = new BitReader(source, EndianType.BigEndian); uint dependenciesLength = bitReader.ReadBits(6); for (int i = 0; i < dependenciesLength; i++) { bitReader.ReadBlobAsString(10); } // s2ma cache handles uint s2maCacheHandlesLength = bitReader.ReadBits(6); for (int i = 0; i < s2maCacheHandlesLength; i++) { if (bitReader.ReadStringFromBytes(4) != "s2ma") { throw new StormParseException($"{_exceptionHeader}: s2ma cache"); } bitReader.ReadAlignedBytes(36); } /*source.ReadAlignedBytes(94); * if (source.ReadStringFromBytes(4) != "Clsd") * throw new StormParseException($"{ExceptionHeader}: Clsd"); */ // we're just going to skip all the way down to the s2mh bitReader.AlignToByte(); /*for (; ;) * { * if (source.ReadStringFromBytes(4) == "s2mh") * { * BitReader.Index -= 4; * break; * } * else * { * BitReader.Index -= 3; * } * }*/ /* * for (; ; ) * { * if (source.ReadStringFromBytes(4) == "s2mv") * { * BitReader.Index -= 4; * break; * } * else * { * BitReader.Index -= 3; * } * }*/ // first hit /* * BitReader.Index -= 1; * * uint s2mvCacheHandlesLength = source.ReadBits(8); * * for (int i = 0; i < s2mvCacheHandlesLength; i++) * { * if (source.ReadStringFromBytes(4) != "s2mv") * throw new StormParseException($"{ExceptionHeader}: s2mv cache"); * * source.ReadAlignedBytes(36); * } * * uint localeCount = source.ReadBits(5); * * for (int i = 0; i < localeCount; i++) * { * source.ReadStringFromBits(32); // locale * * uint s2mlCacheHandlesLength = source.ReadBits(6); * * for (int j = 0; j < s2mlCacheHandlesLength; j++) * { * if (source.ReadStringFromBytes(4) != "s2ml") * throw new StormParseException($"{ExceptionHeader}: s2ml cache"); * * source.ReadAlignedBytes(36); * } * } * * source.ReadAlignedBytes(16); * uint sm2vCacheBlizzLength = source.ReadBits(8); * * for (int i = 0; i < sm2vCacheBlizzLength; i++) * { * * } */ // second s2mv hit /* * for (; ; ) * { * if (source.ReadStringFromBytes(4) == "s2mv") * { * BitReader.Index -= 4; * break; * } * else * { * BitReader.Index -= 3; * } * } * for (int i = 0; i < 2; i++) * { * if (source.ReadStringFromBytes(4) != "s2mv") * throw new StormParseException($"{ExceptionHeader}: s2mv cache"); * * source.ReadAlignedBytes(36); * } * * source.ReadBits(1); * * uint region = source.ReadBits(8); // m_region * if (source.ReadStringFromBits(32) != "Hero") // m_programId * throw new StormParseException($"{ExceptionHeader}: Not Hero"); * source.ReadBits(32); // m_realm * * int blizzIdLength = (int)source.ReadBits(7); * * if (region >= 90) * { * if (source.ReadStringFromBytes(2) != "T:") * throw new StormParseException($"{ExceptionHeader}: Not blizz T:"); * source.ReadStringFromBytes(blizzIdLength); * } * else * { * source.ReadStringFromBytes(blizzIdLength); * source.ReadStringFromBytes(2); * } * * source.ReadBits(8); // m_region * if (source.ReadStringFromBits(32) != "Hero") // m_programId * throw new StormParseException($"{ExceptionHeader}: Not Hero"); * source.ReadBits(32); // m_realm * source.ReadLongBits(64); // m_id * * * int klj = (int)source.ReadBits(12); * * int sdfad = (int)source.ReadBits(12); * * * source.ReadBits(1); //temp * */ for (; ;) { if (bitReader.ReadStringFromBytes(4) == "s2mh") { bitReader.Index -= 4; break; } else { bitReader.Index -= 3; } } // source.ReadBits(???); // this depends on previous data (not byte aligned) // s2mh cache handles // uint s2mhCacheHandlesLength = source.ReadBits(6); // for (int i = 0; i < s2mhCacheHandlesLength; i++) for (int i = 0; i < s2maCacheHandlesLength; i++) { if (bitReader.ReadStringFromBytes(4) != "s2mh") { throw new StormParseException($"{_exceptionHeader}: s2mh cache"); } bitReader.ReadAlignedBytes(36); } // player collections uint collectionSize; // strings gone starting with build (ptr) 55929 if (replay.ReplayBuild >= 48027) { collectionSize = bitReader.ReadBits(16); } else { collectionSize = bitReader.ReadBits(32); } for (uint i = 0; i < collectionSize; i++) { if (replay.ReplayBuild >= 55929) { bitReader.ReadAlignedBytes(8); // most likey an identifier for the item; first six bytes are 0x00 } else { bitReader.ReadStringFromBytes(bitReader.ReadAlignedByte()); } } // use to determine if the collection item is usable by the player (owns/free to play/internet cafe) if (bitReader.ReadBits(32) != collectionSize) { throw new StormParseException($"{_exceptionHeader}: collection difference"); } for (int i = 0; i < collectionSize; i++) { // 16 is total player slots for (int j = 0; j < 16; j++) { bitReader.ReadAlignedByte(); bitReader.ReadAlignedByte(); // more likely a boolean to get the value if (replay.ReplayBuild < 55929) { // when the identifier is a string, set the value to the appropriate array index } } } // Player info if (replay.ReplayBuild <= 47479 || replay.ReplayBuild == 47801 || replay.ReplayBuild == 47903) { // Builds that are not yet supported for detailed parsing // build 47801 is a ptr build that had new data in the battletag section, the data was changed in 47944 (patch for 47801) // GetBattleTags(replay, source); return; } replay.RandomValue = bitReader.ReadBits(32); // m_randomSeed bitReader.ReadAlignedBytes(4); uint playerListLength = bitReader.ReadBits(5); if (replay.PlayersWithObserversCount != playerListLength) { throw new StormParseException($"{_exceptionHeader}: mismatch on player list length - {playerListLength} to {replay.PlayersWithObserversCount}"); } for (uint i = 0; i < playerListLength; i++) { bitReader.ReadBits(32); uint playerIndex = bitReader.ReadBits(5); // player index StormPlayer player = replay.ClientListByUserID[playerIndex]; // toon handle uint playerRegion = bitReader.ReadBits(8); // m_region bitReader.EndianType = EndianType.LittleEndian; if (bitReader.ReadBits(32) != 1869768008) // m_programId { throw new StormParseException($"{_exceptionHeader}: Not Hero"); } bitReader.EndianType = EndianType.BigEndian; uint playerRealm = bitReader.ReadBits(32); // m_realm long playerId = bitReader.ReadLongBits(64); // m_id if (player.PlayerType == PlayerType.Human) { if (player.ToonHandle !.Region != playerRegion) { throw new StormParseException($"{_exceptionHeader}: Mismatch on player region"); } if (player.ToonHandle.Realm != playerRealm) { throw new StormParseException($"{_exceptionHeader}: Mismatch on player realm"); } if (player.ToonHandle.Id != playerId) { throw new StormParseException($"{_exceptionHeader}: Mismatch on player id"); } } else if (player.PlayerType == PlayerType.Observer || player.PlayerType == PlayerType.Unknown) { // observers don't have the information carried over to the details file and sometimes not the initdata file player.ToonHandle ??= new ToonHandle(); player.ToonHandle.Region = (int)playerRegion; player.ToonHandle.ProgramId = 1869768008; player.ToonHandle.Realm = (int)playerRealm; player.ToonHandle.Id = (int)playerId; player.PlayerType = PlayerType.Observer; player.Team = StormTeam.Observer; } // toon handle again but with T_ shortcut bitReader.ReadBits(8); // m_region bitReader.EndianType = EndianType.LittleEndian; if (bitReader.ReadBits(32) != 1869768008) // m_programId (Hero) { throw new StormParseException($"{_exceptionHeader}: Not Hero"); } bitReader.EndianType = EndianType.BigEndian; bitReader.ReadBits(32); // m_realm int idLength = (int)bitReader.ReadBits(7) + 2; player.ToonHandle ??= new ToonHandle(); player.ToonHandle.ShortcutId = bitReader.ReadStringFromBytes(idLength); bitReader.ReadBits(6); if (replay.ReplayBuild <= 47479) { // toon handle repeat again with T_ shortcut bitReader.ReadBits(8); // m_region if (bitReader.ReadStringFromBits(32) != "Hero") // m_programId { throw new StormParseException($"{_exceptionHeader}: Not Hero"); } bitReader.ReadBits(32); // m_realm idLength = (int)bitReader.ReadBits(7) + 2; if (player.ToonHandle.ShortcutId != bitReader.ReadStringFromBytes(idLength)) { throw new StormParseException($"{_exceptionHeader}: Duplicate shortcut id does not match"); } bitReader.ReadBits(6); } bitReader.ReadBits(2); bitReader.ReadUnalignedBytes(25); bitReader.ReadBits(24); // ai games have 8 more bytes somewhere around here if (replay.GameMode == StormGameMode.Cooperative) { bitReader.ReadUnalignedBytes(8); } bitReader.ReadBits(7); if (!bitReader.ReadBoolean()) { // repeat of the collection section above if (replay.ReplayBuild > 51609 || replay.ReplayBuild == 47903 || replay.ReplayBuild == 47479) { bitReader.ReadBitArray(bitReader.ReadBits(12)); } else if (replay.ReplayBuild > 47219) { // each byte has a max value of 0x7F (127) bitReader.ReadUnalignedBytes((int)bitReader.ReadBits(15) * 2); } else { bitReader.ReadBitArray(bitReader.ReadBits(9)); } bitReader.ReadBoolean(); } bool isSilenced = bitReader.ReadBoolean(); // m_hasSilencePenalty if (player.PlayerType == PlayerType.Observer) { player.IsSilenced = isSilenced; } if (replay.ReplayBuild >= 61718) { bitReader.ReadBoolean(); bool isVoiceSilenced = bitReader.ReadBoolean(); // m_hasVoiceSilencePenalty if (player.PlayerType == PlayerType.Observer) { player.IsVoiceSilenced = isVoiceSilenced; } } if (replay.ReplayBuild >= 66977) { bool isBlizzardStaff = bitReader.ReadBoolean(); // m_isBlizzardStaff if (player.PlayerType == PlayerType.Observer) { player.IsBlizzardStaff = isBlizzardStaff; } } if (bitReader.ReadBoolean()) // is player in party { player.PartyValue = bitReader.ReadLongBits(64); // players in same party will have the same exact 8 bytes of data } bitReader.ReadBoolean(); string battleTagName = bitReader.ReadBlobAsString(7); int poundIndex = battleTagName.IndexOf('#'); if (!string.IsNullOrEmpty(battleTagName) && poundIndex < 0) { throw new StormParseException($"{_exceptionHeader}: Invalid battletag"); } ReadOnlySpan <char> namePart = battleTagName.AsSpan().Slice(0, poundIndex); if (!namePart.SequenceEqual(player.Name)) { throw new StormParseException($"{_exceptionHeader}: Mismatch on battletag name with player name"); } player.BattleTagName = battleTagName; if (replay.ReplayBuild >= 52860 || (replay.ReplayVersion.Major == 2 && replay.ReplayBuild >= 51978)) { player.AccountLevel = (int)bitReader.ReadBits(32); // in custom games, this is a 0 } if (replay.ReplayBuild >= 69947) { bool hasActiveBoost = bitReader.ReadBoolean(); // m_hasActiveBoost if (player.PlayerType == PlayerType.Observer) { player.HasActiveBoost = hasActiveBoost; } } } }
public static void Parse(StormReplay replay, ReadOnlySpan <byte> source) { BitReader bitReader = new BitReader(source, EndianType.LittleEndian); bitReader.ReadAlignedByte(); bitReader.ReadUInt32Aligned(); int count = bitReader.ReadInt32Aligned(); // The 'PlayerID' in attributes does not seem to match any existing player array // It almost matches the 'Replay.Player' array, except for games with less than 10 players int replayPlayersWithOpenSlotsIndex = 1; ReplayAttributeEventType attribute; int playerId; Span <char> value = stackalloc char[4]; Span <char> upperValue = stackalloc char[4]; for (int i = 0; i < count; i++) { bitReader.ReadUInt32Aligned(); // namespace attribute = (ReplayAttributeEventType)bitReader.ReadUInt32Aligned(); // attrid playerId = bitReader.ReadAlignedByte(); Encoding.UTF8.GetChars(bitReader.ReadBytes(4), value); value.Reverse(); for (int j = 0; j < value.Length; j++) { upperValue[j] = char.ToUpperInvariant(value[j]); } switch (attribute) { case ReplayAttributeEventType.PlayerTypeAttribute: { if (upperValue.SequenceEqual("COMP") || upperValue.SequenceEqual("HUMN")) { replay.PlayersWithOpenSlots[playerId - 1] = replay.Players[playerId - replayPlayersWithOpenSlotsIndex]; } if (upperValue.SequenceEqual("COMP")) { replay.PlayersWithOpenSlots[playerId - 1].PlayerType = PlayerType.Computer; } else if (upperValue.SequenceEqual("HUMN")) { replay.PlayersWithOpenSlots[playerId - 1].PlayerType = PlayerType.Human; } else if (upperValue.SequenceEqual("OPEN")) { replayPlayersWithOpenSlotsIndex++; // Less than 10 players in a Custom game } else { throw new StormParseException($"Unexpected value for PlayerTypeAttribute: {value.ToString()}"); } break; } case ReplayAttributeEventType.TeamSizeAttribute: { replay.TeamSize = value.Trim('\0').ToString(); break; } case ReplayAttributeEventType.DifficultyLevelAttribute: { StormPlayer player = replay.PlayersWithOpenSlots[playerId - 1]; player.PlayerDifficulty = value.ToString() switch { "VyEy" => PlayerDifficulty.Beginner, "Easy" => PlayerDifficulty.Recruit, "Medi" => PlayerDifficulty.Adept, "HdVH" => PlayerDifficulty.Veteran, "VyHd" => PlayerDifficulty.Elite, _ => PlayerDifficulty.Unknown, }; break; } case ReplayAttributeEventType.GameSpeedAttribute: { replay.GameSpeed = upperValue switch { Span <char> _ when upperValue.SequenceEqual("SLOR") => StormGameSpeed.Slower, Span <char> _ when upperValue.SequenceEqual("SLOW") => StormGameSpeed.Slow, Span <char> _ when upperValue.SequenceEqual("NORM") => StormGameSpeed.Normal, Span <char> _ when upperValue.SequenceEqual("FAST") => StormGameSpeed.Fast, Span <char> _ when upperValue.SequenceEqual("FASR") => StormGameSpeed.Faster, _ => StormGameSpeed.Unknown, }; break; } case ReplayAttributeEventType.GameModeAttribute: { switch (upperValue) { case Span <char> _ when upperValue.SequenceEqual("PRIV"): replay.GameMode = StormGameMode.Custom; break; case Span <char> _ when upperValue[1..4].SequenceEqual("AMM"): if (replay.ReplayBuild < 33684) { replay.GameMode = StormGameMode.QuickMatch; } break;