public void AddFrame(g_Instance frame) { // if there is no data yet, add this frame to the file header if (fileHeader == null) { fileHeader = new MilkFileHeader(frame); frames = new List <MilkFrame>(); } else { fileHeader.ConsiderNewFrame(frame); } byte[] newFrameHeader = BuildFrameHeader(frame); // if there are no frames yet, add this frame as a new milkframe // if there are other frames, check to see if the chunk size is too large and split to a new milkframe if (frames.Count == 0 || frames[frames.Count - 1].data.Count > 10000) { var milkFrame = new MilkFrame { header = newFrameHeader, data = BuildChunk(frame).ToList() }; frames.Add(milkFrame); } // else just add this echoframe as another chunk else { frames[frames.Count - 1].data.AddRange(BuildChunk(frame)); } }
private static byte[] BuildFrameHeader(g_Instance frame) { List <byte> bytes = new List <byte> { 254, 253 }; bytes.AddRange(BitConverter.GetBytes(frame.blue_points)); bytes.AddRange(BitConverter.GetBytes(frame.orange_points)); bytes.AddRange((new List <bool> { frame.blue_team_restart_request, frame.orange_team_restart_request }).GetBytes()); // add last score bytes.AddRange(BitConverter.GetBytes(frame.last_score.disc_speed)); bytes.Add((byte)Enum.Parse(typeof(g_Team.TeamColor), frame.last_score.team)); bytes.AddRange(Encoding.ASCII.GetBytes(frame.last_score.goal_type)); bytes.Add(0); bytes.AddRange(BitConverter.GetBytes(frame.last_score.point_amount)); bytes.AddRange(BitConverter.GetBytes(frame.last_score.distance_thrown)); bytes.AddRange(Encoding.ASCII.GetBytes(frame.last_score.person_scored)); bytes.Add(0); bytes.AddRange(Encoding.ASCII.GetBytes(frame.last_score.assist_scored)); bytes.Add(0); foreach (var team in frame.teams) { bytes.AddRange(BitConverter.GetBytes((byte)team.stats.points)); bytes.AddRange(BitConverter.GetBytes(team.stats.possession_time)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.interceptions)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.blocks)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.steals)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.catches)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.passes)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.saves)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.goals)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.stuns)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.assists)); bytes.AddRange(BitConverter.GetBytes((byte)team.stats.shots_taken)); foreach (var player in team.players) { bytes.AddRange(BitConverter.GetBytes((byte)player.stats.points)); bytes.AddRange(BitConverter.GetBytes(player.stats.possession_time)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.interceptions)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.blocks)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.steals)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.catches)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.passes)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.saves)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.goals)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.stuns)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.assists)); bytes.AddRange(BitConverter.GetBytes((byte)player.stats.shots_taken)); } } return(bytes.ToArray()); }
private static void SaveClip(bool setting, string player_name, g_Instance frame, string clip_name) { if (!setting) { return; } if (!IsPlayerScopeEnabled(player_name, frame)) { return; } Task.Delay((int)(Settings.Default.replayClipSecondsAfter * 1000)).ContinueWith(_ => Program.SaveReplayClip(clip_name)); }
private void SaveClip(bool setting, string player_name, g_Instance frame) { if (!instance.IsConnected) { return; } if (!setting) { return; } if (!IsPlayerScopeEnabled(player_name, frame)) { return; } Task.Delay((int)(Settings.Default.obsClipSecondsAfter * 1000)).ContinueWith(_ => instance.SaveReplayBuffer()); }
public void ConsiderNewFrame(g_Instance frame) { foreach (var team in frame.teams) { foreach (var player in team.players) { if (!userids.Contains(player.userid)) { players.Add(player.name); numbers.Add(player.number); levels.Add(player.level); userids.Add(player.userid); } } } }
internal static bool SaveHighlightMaybe(string player, g_Instance frame, string id) { string highlightGroupName = IsPlayerHighlightEnabled(player, frame); if (highlightGroupName.Length <= 0) { return(false); } Highlights.VideoHighlightParams vhp = new() { groupId = highlightGroupName, highlightId = id, startDelta = -(int)(Settings.Default.nvHighlightsSecondsBefore * 1000), endDelta = (int)(Settings.Default.nvHighlightsSecondsAfter * 1000) }; Highlights.SetVideoHighlight(vhp, videoCallback); return(true); }
private static bool IsPlayerScopeEnabled(string player_name, g_Instance frame) { try { if (string.IsNullOrEmpty(player_name) || frame.teams == null) { return(false); } // if in spectator and record-all-in-spectator is checked if (Settings.Default.replayClipSpectatorRecord && frame.client_name == player_name) { return(true); } switch (Settings.Default.replayClipPlayerScope) { // only me case 0: return(player_name == frame.client_name); // only my team case 1: return(frame.GetPlayer(frame.client_name).team.color == frame.GetPlayer(player_name).team.color); // anyone case 2: return(true); } } catch (Exception ex) { Logger.LogRow(Logger.LogType.Error, $"Something broke while checking if player highlights is enabled\n{ex}"); } return(false); }
public MilkFileHeader(g_Instance frame) { this.frame = frame; headerByte = 0; if (frame.private_match) { headerByte |= 1 << 0; } if (frame.match_type != "Echo Arena") { headerByte |= 1 << 1; } if (frame.tournament_match) { headerByte |= 1 << 2; } players = new List <string>(); numbers = new List <int>(); levels = new List <int>(); userids = new List <long>(); foreach (var team in frame.teams) { foreach (var player in team.players) { players.Add(player.name); numbers.Add(player.number); levels.Add(player.level); userids.Add(player.userid); } } }
public static void ProcessDiscordPresence(g_Instance frame) { lastDiscordPresenceTime = DateTime.Now; if (Settings.Default.discordRichPresence) { if (discordClient == null || discordClient.IsDisposed) { //InitializeDiscord(); LogRow(LogType.Error, "Discord RP client disposed while in normal thread."); } RichPresence rp = new RichPresence(); if (frame == null) { discordClient.SetPresence(null); return; } StringBuilder details = new StringBuilder(); if (frame.map_name == "mpl_arena_a") { if (frame.teams[2].players.Find(p => p.name == frame.client_name) != null) { details.Append("Spectating "); } else { details.Append("Playing "); } details.Append("Arena "); if (frame.private_match) { details.Append("pvt."); rp.WithSecrets(new Secrets { JoinSecret = "spark://c/" + frame.sessionid, SpectateSecret = "spark://s/" + frame.sessionid, }); } else { details.Append("pub."); } rp.State = "Score: " + frame.orange_points + " - " + frame.blue_points; rp.Timestamps = new Timestamps { End = frame.game_status == "post_match" ? DateTime.UtcNow : DateTime.UtcNow.AddSeconds(frame.game_clock) }; rp.WithParty(new Party { ID = frame.sessionid, Size = frame.GetAllPlayers().Count, Max = frame.private_match ? 15 : 8 }); } else if (frame.map_name == "mpl_lobby_b2") { details.Append("in EchoVR Lobby"); // how long have we been in the lobby? if (!inLobby) { inLobby = true; lobbyEntryTime = DateTime.UtcNow; } rp.Timestamps = new Timestamps { Start = lobbyEntryTime }; } else // if (frame.map_name == "whatever combat is") { details.Append("Playing Combat"); } rp.Details = details.ToString(); rp.Assets = new Assets { LargeImageKey = "echo_arena_store_icon", LargeImageText = "Rich presence from Spark" }; discordClient.SetPresence(rp); } else { if (discordClient != null && !discordClient.IsDisposed) { discordClient.Dispose(); } } }
private void Interception(g_Instance frame, g_Team team, g_Player throwPlayer, g_Player catchPlayer) { SaveClip(Settings.Default.obsClipInterception, catchPlayer.name, frame); }
private void Assist(g_Instance frame, GoalData goal) { SaveClip(Settings.Default.obsClipAssist, frame.last_score.assist_scored, frame); }
private void PlayspaceAbuse(g_Instance frame, g_Team team, g_Player player, Vector3 arg4) { SaveClip(Settings.Default.obsClipPlayspace, player.name, frame); }
private void Goal(g_Instance frame, GoalData goalData) { SaveClip(Settings.Default.obsClipGoal, frame.last_score.person_scored, frame); }
private void Save(g_Instance frame, g_Team team, g_Player player) { SaveClip(Settings.Default.obsClipSave, player.name, frame); }
private static byte[] BuildChunk(g_Instance frame) { List <byte> bytes = new List <byte> { 253, 254 }; List <bool> bools = new List <bool>(); bytes.AddRange(BitConverter.GetBytes(frame.game_clock)); // disc position, velocity, and orientation bytes.AddRange(frame.disc.position.GetBytes()); bytes.AddRange(frame.disc.left.GetBytes()); bytes.AddRange(frame.disc.up.GetBytes()); bytes.AddRange(frame.disc.forward.GetBytes()); bytes.AddRange(frame.disc.velocity.GetBytes()); // local vr player position bytes.AddRange(frame.player.vr_position.GetBytes()); bytes.AddRange(frame.player.vr_left.GetBytes()); bytes.AddRange(frame.player.vr_up.GetBytes()); bytes.AddRange(frame.player.vr_forward.GetBytes()); // game state if (string.IsNullOrEmpty(frame.game_status)) { bytes.Add(0); } else { bytes.Add((byte)(MilkGameState)Enum.Parse(typeof(MilkGameState), frame.game_status)); } // loop through all the player and add team- and player-specific info foreach (var team in frame.teams) { foreach (var player in team.players) { List <float>[] vectors = { player.velocity, player.head.position, player.head.left, player.head.up, player.head.forward, player.body.position, player.body.left, player.body.up, player.body.forward, player.lhand.pos, player.lhand.left, player.lhand.up, player.lhand.forward, player.rhand.pos, player.rhand.left, player.rhand.up, player.rhand.forward }; foreach (List <float> vector in vectors) { bytes.AddRange(vector.GetBytes()); } bytes.AddRange(BitConverter.GetBytes(player.ping)); bools.Add(player.stunned); bools.Add(player.invulnerable); bools.Add(player.possession); bools.Add(player.blocking); } } bytes.AddRange(bools.GetBytes()); return(bytes.ToArray()); }
public Milk(g_Instance frame) { AddFrame(frame); }