예제 #1
0
파일: MILK.cs 프로젝트: xiangweizheng/Spark
        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));
            }
        }
예제 #2
0
파일: MILK.cs 프로젝트: xiangweizheng/Spark
        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());
        }
예제 #3
0
 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));
 }
예제 #4
0
 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());
 }
예제 #5
0
파일: MILK.cs 프로젝트: xiangweizheng/Spark
 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);
             }
         }
     }
 }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
파일: MILK.cs 프로젝트: xiangweizheng/Spark
            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);
                    }
                }
            }
예제 #9
0
        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();
                }
            }
        }
예제 #10
0
 private void Interception(g_Instance frame, g_Team team, g_Player throwPlayer, g_Player catchPlayer)
 {
     SaveClip(Settings.Default.obsClipInterception, catchPlayer.name, frame);
 }
예제 #11
0
 private void Assist(g_Instance frame, GoalData goal)
 {
     SaveClip(Settings.Default.obsClipAssist, frame.last_score.assist_scored, frame);
 }
예제 #12
0
 private void PlayspaceAbuse(g_Instance frame, g_Team team, g_Player player, Vector3 arg4)
 {
     SaveClip(Settings.Default.obsClipPlayspace, player.name, frame);
 }
예제 #13
0
 private void Goal(g_Instance frame, GoalData goalData)
 {
     SaveClip(Settings.Default.obsClipGoal, frame.last_score.person_scored, frame);
 }
예제 #14
0
 private void Save(g_Instance frame, g_Team team, g_Player player)
 {
     SaveClip(Settings.Default.obsClipSave, player.name, frame);
 }
예제 #15
0
파일: MILK.cs 프로젝트: xiangweizheng/Spark
        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());
        }
예제 #16
0
파일: MILK.cs 프로젝트: xiangweizheng/Spark
 public Milk(g_Instance frame)
 {
     AddFrame(frame);
 }