Esempio n. 1
0
    private void ActOnMatching()
    {
        byte[] buf = DeserializeFrame(matchingState0, matchingState1);
        if (buf.Length < 5)
        {
            return;
        }
        int n = 0;

        int newMatchingDuration = 0;

        newMatchingDuration |= (int)buf[n++] << 8;
        newMatchingDuration |= (int)buf[n++];

        MatchingDurationSeconds = newMatchingDuration;

        int time = 0;

        time |= (int)buf[n++] << 24;
        time |= (int)buf[n++] << 16;
        time |= (int)buf[n++] << 8;
        time |= (int)buf[n++];
        lastSeenMatchingServerTimeMillis = time;
        int matchCount = buf[n++];

        lastSeenMatchCount = matchCount;

        int[] matching = new int[matchCount * 2];
        for (int i = 0; i < matchCount; i++)
        {
            int player1 = 0;
            player1        |= (int)buf[n++] << 8;
            player1        |= (int)buf[n++];
            matching[i * 2] = player1;

            int player2 = 0;
            player2            |= (int)buf[n++] << 8;
            player2            |= (int)buf[n++];
            matching[i * 2 + 1] = player2;
        }
        lastSeenMatching = matching;

        Log($"Deserialized new matching at {lastSeenMatchingServerTimeMillis}, with {matchCount}\n" +
            $"matchings: [{join(matching)}]");

        VRCPlayerApi[] players    = MatchingTracker.GetActivePlayers();
        int            myPlayerId = Networking.LocalPlayer.playerId;

        for (int i = 0; i < matchCount; i++)
        {
            if (matching[i * 2] == myPlayerId || matching[i * 2 + 1] == myPlayerId)
            {
                var          other       = matching[i * 2] == myPlayerId ? matching[i * 2 + 1] : matching[i * 2];
                VRCPlayerApi otherPlayer = null;
                foreach (var pl in players)
                {
                    if (pl.playerId == other)
                    {
                        otherPlayer = pl;
                        break;
                    }
                }
                if (otherPlayer == null)
                {
                    Log($"found local player id={myPlayerId} matched with {other}, but {other} seems to have left, aborting..");
                    return;
                }

                // we're matched, teleport to the ith unoccupied room
                // divided by 2 since there are two people per match
                Log($"found local player id={myPlayerId} matched with id={other} name={otherPlayer.displayName}, teleporting to room {i}");
                var p = privateRooms[i];

                // record
                MatchingTracker.SetLocallyMatchedWith(otherPlayer, true);

                Vector3 adjust = matching[i * 2] == myPlayerId ? Vector3.forward : Vector3.back;
                // look at the center of the room
                Quaternion rotation = Quaternion.LookRotation(adjust * -1);
                // avoid lerping (apparently on by default)
                Networking.LocalPlayer.TeleportTo(adjust + p.transform.position, rotation,
                                                  VRC_SceneDescriptor.SpawnOrientation.AlignPlayerWithSpawnPoint, lerpOnRemote: false);

                // teleport timer to location as visual
                if (CooldownBetweenMatchingSeconds > 0)
                {
                    // make countdown slightly shorter than round time
                    PrivateRoomTimer.StartCountdown((float)(MatchingDurationSeconds - CooldownBetweenMatchingSeconds));
                    PrivateRoomTimer.teleportAtCountdown = true;
                }
                else
                {
                    // dont' teleport, and just let the code below teleport out once the new mathcing comes.
                    PrivateRoomTimer.StartCountdown(MatchingDurationSeconds);
                    PrivateRoomTimer.teleportAtCountdown = false;
                }
                PrivateRoomTimer.transform.position = p.transform.position;
                return;
            }
        }

        Log($"Local player id={myPlayerId} was not in the matching, teleporting out if they were in a room previously");
        // if the player was previously in a room, the privateroomtimer is there with them and will teleport them out.
        PrivateRoomTimer.TeleportOut();
    }
Esempio n. 2
0
    private void UpdateCanvas()
    {
        if (!MatchingTracker.started)
        {
            return;
        }
        if ((updateCooldown -= Time.deltaTime) > 0)
        {
            return;
        }
        updateCooldown = 1f;

        // show indication if player hasn't got ownership yet
        if (MatchingTracker.localPlayerState == null)
        {
            title.text = "Initializing, please wait warmly\n(If this persists, try rejoining.)";
            return;
        }

        var matchesRemaining = 0;

        for (int i = 0; i < 80; i++)
        {
            MatchingTrackerPlayerState state = MatchingTracker.playerStates[i];
            VRCPlayerApi p = state.GetExplicitOwner();
            if (p == null || Networking.LocalPlayer == p)
            {
                toggles[i].gameObject.SetActive(false);
                activePlayerLastUpdate[i] = null;
                continue;
            }

            toggles[i].gameObject.SetActive(true);
            var wasMatchedWith = MatchingTracker.GetLocallyMatchedWith(p);
            var matchedWithUs  = state.matchedWithLocalPlayer;

            if (wasMatchedWith)
            {
                texts[i].text = MatchingTracker.GetDisplayName(p);
                var seconds = Time.time - MatchingTracker.GetLastMatchedWith(p);
                var minutes = seconds / 60f;
                var hours   = minutes / 60f;
                texts[i].text = $"{MatchingTracker.GetDisplayName(p)} (matched " +
                                (hours > 1 ? $"{Mathf.FloorToInt(hours):D2}:{Mathf.FloorToInt(minutes):D2} ago)" :
                                 minutes > 1 ? $"{Mathf.FloorToInt(minutes):##} minutes ago)" :
                                 $"{Mathf.FloorToInt(seconds):##} seconds ago)");
            }
            else if (matchedWithUs)
            {
                texts[i].text = $"{MatchingTracker.GetDisplayName(p)} (matched with you on their end)";
            }
            else if (!state.matchingEnabled)
            {
                texts[i].text = $"{MatchingTracker.GetDisplayName(p)} (taking a break from matching)";
            }
            else
            {
                texts[i].text = MatchingTracker.GetDisplayName(p);
                matchesRemaining++;
            }
            if (activePlayerLastUpdate[i] == MatchingTracker.GetDisplayName(p))
            {
                // if player changed state in ui (doesn't match our internal state)
                if (toggles[i].isOn != lastSeenToggle[i])
                {
                    MatchingTracker.SetLocallyMatchedWith(p, toggles[i].isOn);
                }
                else
                {
                    // set UI from tracker state
                    toggles[i].isOn = wasMatchedWith;
                }
                lastSeenToggle[i] = toggles[i].isOn;
            }
            else
            {
                // wasn't the same player before
                activePlayerLastUpdate[i] = MatchingTracker.GetDisplayName(p);
                // set the UI state ignoring what it was
                toggles[i].isOn   = wasMatchedWith;
                lastSeenToggle[i] = wasMatchedWith;
            }
        }
        title.text = $"Player Checklist ({matchesRemaining} matches remaining)";
    }