public override GGPOErrorCode AddLocalInput(int playerHandle, byte[] values)
        {
            GGPOErrorCode result;

            if (sync.InRollback)
            {
                return(GGPOErrorCode.InRollback);
            }
            if (isSynchronizing)
            {
                return(GGPOErrorCode.NotSynchronized);
            }

            result = PlayerHandleToQueue(playerHandle, out int queue);
            if (result != GGPOErrorCode.Success)
            {
                return(result);
            }

            var input = new GameInput(GameInput.NullFrame, values, (uint)values.Length);

            // Feed the input for the current frame into the synchronzation layer.
            if (!sync.AddLocalInput(queue, ref input))
            {
                return(GGPOErrorCode.PredictionThreshold);
            }

            if (input.frame != GameInput.NullFrame)
            {
                // xxx: <- comment why this is the case
                // Update the local connect status state to indicate that we've got a
                // confirmed local frame for this player.  this must come first so it
                // gets incorporated into the next packet we send.

                Log($"setting local connect status for local queue {queue} to {input.frame}");
                localConnectStatus[queue].LastFrame = input.frame;

                // Send the input to all the remote players.
                for (int i = 0; i < numPlayers; i++)
                {
                    if (endpoints[i].IsInitialized)
                    {
                        endpoints[i].SendInput(ref input);
                    }
                }
            }

            return(GGPOErrorCode.OK);
        }