예제 #1
0
        private async void GetLevelEntitlement(IConnectedPlayer player)
        {
            if (entitlementCts != null)
            {
                entitlementCts.Cancel();
            }
            entitlementCts = new CancellationTokenSource();

            string?levelId = _playersDataModel.GetPlayerBeatmapLevel(_playersDataModel.hostUserId)?.levelID;

            if (levelId == null)
            {
                return;
            }

            lastLevelId = levelId;

            bool needsRpc = false;
            Task <EntitlementsStatus> entitlement = player.isMe ?
                                                    _entitlementChecker.GetEntitlementStatus(levelId) :
                                                    _entitlementChecker.GetTcsTaskCanPlayerPlayLevel(player, levelId, entitlementCts.Token, out needsRpc);

            if (needsRpc)
            {
                _menuRpcManager.GetIsEntitledToLevel(levelId);
            }
            SetLevelEntitlement(player, await entitlement);
        }
예제 #2
0
 private void HandlePlayerStateChanged(IConnectedPlayer player)
 {
     if (player.isConnectionOwner)
     {
         MPState.CustomSongsEnabled = player.HasState("customsongs");
     }
 }
        private void OnPlayerDisconnected(IConnectedPlayer player)
        {
            Plugin.Log?.Info($"Player '{player.userId}' disconnected");
            var extendedPlayer = _players[player.userId];

            _players.Remove(player.userId);
        }
예제 #4
0
        public static void UpdateColor(IConnectedPlayer connectedPlayer, ILobbyPlayerDataModel playerDataModel, GameServerPlayerTableCell __instance)
        {
            Image background = __instance.GetField <Image>("_localPlayerBackgroundImage");

            if (playerDataModel.beatmapLevel != null)
            {
                background.enabled = true;
                PreviewBeatmapManager.GetPopulatedPreview(playerDataModel.beatmapLevel.levelID).ContinueWith(r =>
                {
                    PreviewBeatmapStub preview = r.Result;
                    float transparency         = connectedPlayer.isMe ? 0.4f : 0.1f;
                    Color color = connectedPlayer.HasState("bmlocal") ? green : connectedPlayer.HasState("bmcloud") ? yellow : red;
                    color.a     = transparency;

                    HMMainThreadDispatcher.instance.Enqueue(() =>
                    {
                        background.color = color;
                    });
                });
            }
            else
            {
                background.color = normal;
            }
        }
 private void HandlePlayerConnected(IConnectedPlayer player)
 {
     if (localBeatmap != null)
     {
         _packetManager.Send(localBeatmap);
     }
 }
 private void HandlePlayerStateChanged(IConnectedPlayer player)
 {
     if (player.HasState("beatmap_downloaded"))
     {
         this.NotifyModelChange(player.userId);
     }
 }
        private void HandlePlayerPacket(ExtendedPlayerPacket packet, IConnectedPlayer player)
        {
            Plugin.Log?.Info($"Received 'ExtendedPlayerPacket' from '{player.userId}' with '{packet.platformID}'");
            var extendedPlayer = _players[player.userId];

            extendedPlayer.platformID = packet.platformID;
        }
 private void OnPlayerDisconnected(IConnectedPlayer player)
 {
     if (PlayerReceivers.TryRemove(player.userId, out VoipReceiver receiver) && receiver != null)
     {
         GameObject.Destroy(receiver);
     }
 }
        private void HandleVoipDataPacket(VoipDataPacket packet, IConnectedPlayer player)
        {
            try
            {
#if DEBUG
                Plugin.Log?.Debug($"Received a packet {player.userName} ({player.userId}). '{packet.Data?.Length}' | {packet.DataLength}");
#endif
                if (PlayerReceivers.TryGetValue(player.userId, out VoipReceiver receiver))
                {
                    if (receiver != null)
                    {
                        receiver.HandleAudioDataReceived(this, packet);
                    }
                    else
                    {
                        Plugin.Log?.Error($"VoipReceiver is null");
                    }
                }
                else
                {
                    Plugin.Log?.Debug($"Received a Voip packet from {player.userId} ({player.userName}), but they weren't in the receiver dictionary.");
                }
            }
            catch (Exception ex)
            {
                Plugin.Log?.Error($"Error handling VoipDataPacket: {ex.Message}");
                Plugin.Log?.Debug(ex);
            }
            finally
            {
                packet.Release();
            }
        }
예제 #10
0
        static void Postfix(ref IReadOnlyList <IConnectedPlayer> __result)
        {
            StackTrace stackTrace = new StackTrace();
            string     methodName = stackTrace.GetFrame(2).GetMethod().Name;

            if (methodName == "BindTimeline")
            {
                if (__result.Any(player => player.isMe))
                {
                    List <IConnectedPlayer> nonLocalPlayers = __result.Where(player => !player.isMe).ToList();
                    IConnectedPlayer        localPlayer     = __result.First(player => player.isMe);
                    __result = nonLocalPlayers.Skip((IntroAnimationPatch.targetIterations - 1) * 4).Take(4).ToList();
                    if (IntroAnimationPatch.targetIterations == 1)
                    {
                        __result = __result.AddItem(localPlayer).ToList();
                    }
                }
                else
                {
                    __result = __result.Skip((IntroAnimationPatch.targetIterations - 1) * 4).Take(4).ToList();
                }
            }
            else if (methodName == "BindOutroTimeline")
            {
                __result = __result.Take(4).ToList();
            }
        }
예제 #11
0
        private void OnAvatarReceived(IConnectedPlayer player, CustomAvatarData avatar)
        {
            if (player.userId != _connectedPlayer.userId)
            {
                return;
            }

            if (avatar == null)
            {
                return;
            }

            if (avatar.hash == new CustomAvatarData().hash)
            {
                return;
            }

            avatarData = avatar;
            _avatarProvider.FetchAvatarByHash(avatar.hash, CancellationToken.None).ContinueWith(a =>
            {
                if (!a.IsFaulted && a.Result is AvatarPrefab)
                {
                    HMMainThreadDispatcher.instance.Enqueue(() =>
                    {
                        CreateAvatar(a.Result);
                    });
                }
            });
        }
예제 #12
0
 public void Construct(AvatarSpawner avatarSpawner, IAvatarProvider <AvatarPrefab> avatarProvider, [InjectOptional] IConnectedPlayer connectedPlayer, CustomAvatarManager customAvatarManager)
 {
     _avatarSpawner       = avatarSpawner;
     _avatarProvider      = avatarProvider;
     _connectedPlayer     = connectedPlayer;
     _customAvatarManager = customAvatarManager;
 }
예제 #13
0
        public static void UpdateColor(IConnectedPlayer player)
        {
            GameServerPlayerTableCell cell  = cells[player.userId];
            ILobbyPlayerDataModel     model = models[player.userId];

            UpdateColor(player, model, cell);
        }
예제 #14
0
        internal static void Prefix(ref GameplayCoreInstaller __instance, ref IConnectedPlayer ____connectedPlayer, ref GameplayCoreSceneSetupData ____sceneSetupData)
        {
            var mib       = __instance as MonoInstallerBase;
            var Container = SiraUtil.Accessors.GetDiContainer(ref mib);

            ExtendedPlayerManager exPlayerManager = Container.Resolve <ExtendedPlayerManager>();
            ExtendedPlayer?       exPlayer        = exPlayerManager.GetExtendedPlayer(____connectedPlayer);
            ExtendedPlayer?       hostPlayer      = exPlayerManager.GetExtendedPlayer(Container.Resolve <IMultiplayerSessionManager>().connectionOwner);

            GameplayModifiers?newModifiers;

            if (____connectedPlayer.HasState("modded") && MPState.FreeModEnabled && exPlayer?.mpexVersion >= _minVersionFreeMod)
            {
                newModifiers = exPlayer.lastModifiers;
            }
            else
            {
                newModifiers = hostPlayer?.lastModifiers;
            }

            if (newModifiers != null)
            {
                ____sceneSetupData = new GameplayCoreSceneSetupData(
                    ____sceneSetupData.difficultyBeatmap,
                    ____sceneSetupData.previewBeatmapLevel,
                    newModifiers,
                    ____sceneSetupData.playerSpecificSettings,
                    ____sceneSetupData.practiceSettings,
                    ____sceneSetupData.useTestNoteCutSoundEffects,
                    ____sceneSetupData.environmentInfo,
                    ____sceneSetupData.colorScheme
                    );
            }
        }
        private bool IsPlayerReady(IConnectedPlayer player)
        {
            if (player.HasState("start_primed"))
            {
                return(true);
            }

            // player is not modded: always assume ready
            if (!player.HasState("modded"))
            {
                return(true);
            }

            var extendedPlayer = _extendedPlayerManager.GetExtendedPlayer(player);

            // did not receive mpexVersion from player or the version is too old: assume the player is ready to prevent getting stuck at "Loading..." screen
            if (extendedPlayer == null)
            {
                return(true);
            }
            if (extendedPlayer.mpexVersion == null || extendedPlayer.mpexVersion < _minVersionStartPrimed)
            {
                return(true);
            }

            return(false);
        }
예제 #16
0
        public LobbyAvatarPlaceLighting GetConnectedPlayerPlace(IConnectedPlayer player)
        {
            int     sortIndex = _lobbyStateDataModel.localPlayer.sortIndex;
            float   outerCirclePositionAngleForPlayer = MultiplayerPlayerPlacement.GetOuterCirclePositionAngleForPlayer(player.sortIndex, sortIndex, angleBetweenPlayersWithEvenAdjustment);
            Vector3 playerWorldPosition = MultiplayerPlayerPlacement.GetPlayerWorldPosition(outerCircleRadius, outerCirclePositionAngleForPlayer, MultiplayerPlayerLayout.Circle);

            return(Array.Find(avatarPlaces, place => place.transform.position == playerWorldPosition && place.isActiveAndEnabled));
        }
예제 #17
0
 public ExtendedPlayer(IConnectedPlayer player, string platformID, Platform platform, SemVer.Version mpexVersion, Color playerColor)
 {
     _connectedPlayer = player;
     this.platformID  = platformID;
     this.platform    = platform;
     this.mpexVersion = mpexVersion;
     this.playerColor = playerColor;
 }
        private void OnPlayerConnected(IConnectedPlayer player)
        {
            Plugin.Log?.Info($"Player '{player.userId}' joined");
            var extendedPlayer = new ExtendedPlayer(player);

            _players[player.userId] = extendedPlayer;
            SendLocalPlayerPacket();
        }
예제 #19
0
 static void Postfix(IConnectedPlayer player)
 {
     if (player.isConnectionOwner)
     {
         UI.GameplaySetupPanel.instance.SetCustomSongs(player.HasState("customsongs"));
         UI.GameplaySetupPanel.instance.SetEnforceMods(player.HasState("enforcemods"));
     }
 }
        private void HandlePlayerDisconnected(IConnectedPlayer player)
        {
            Plugin.Log?.Info($"Player '{player.userId}' disconnected");
            var extendedPlayer = players[player.userId];

            playerDisconnectedEvent?.Invoke(extendedPlayer);
            players.Remove(player.userId);
        }
        private void HandlePlayerConnected(IConnectedPlayer player)
        {
            Plugin.Log?.Info($"Player '{player.userId}' joined");
            var extendedPlayer = new ExtendedPlayer(player);

            players[player.userId] = extendedPlayer;
            playerConnectedEvent?.Invoke(extendedPlayer);
        }
예제 #22
0
        public void SetPlayerPlaceColor(IConnectedPlayer player, Color color)
        {
            LobbyAvatarPlaceLighting place = GetConnectedPlayerPlace(player);

            if (place != null)
            {
                place.SetColor(color, false);
            }
        }
        private void HandlePlayerConnected(IConnectedPlayer player)
        {
            ExtendedPlayer?exPlayer = _playerManager.GetExtendedPlayer(player);

            if (exPlayer != null)
            {
                _placeManager.SetPlayerPlaceColor(player, exPlayer.playerColor);
            }
        }
        static void Postfix(List <IConnectedPlayer> sortedPlayers, ILobbyPlayersDataModel lobbyPlayersDataModel, GameServerPlayersTableView __instance)
        {
            IPreviewBeatmapLevel hostBeatmap = lobbyPlayersDataModel.GetPlayerBeatmapLevel(lobbyPlayersDataModel.hostUserId);

            if (hostBeatmap != null && hostBeatmap is PreviewBeatmapStub hostBeatmapStub)
            {
                TableView tableView = __instance.GetField <TableView, GameServerPlayersTableView>("_tableView");
                foreach (TableCell cell in tableView.visibleCells)
                {
                    if (cell is GameServerPlayerTableCell playerCell)
                    {
                        Image             background      = playerCell.GetField <Image, GameServerPlayerTableCell>("_localPlayerBackgroundImage");
                        CurvedTextMeshPro emptySuggestion = playerCell.GetField <CurvedTextMeshPro, GameServerPlayerTableCell>("_emptySuggestedLevelText");
                        CurvedTextMeshPro suggestion      = playerCell.GetField <CurvedTextMeshPro, GameServerPlayerTableCell>("_suggestedLevelText");
                        IConnectedPlayer  player          = sortedPlayers[playerCell.idx];
                        Color             backgroundColor = new Color();

                        if (player.isConnectionOwner)
                        {
                            suggestion.gameObject.SetActive(false);
                            emptySuggestion.gameObject.SetActive(true);
                            emptySuggestion.text = "Loading...";
                            hostBeatmapStub.isDownloadable.ContinueWith(r =>
                            {
                                HMMainThreadDispatcher.instance.Enqueue(() =>
                                {
                                    suggestion.gameObject.SetActive(true);
                                    emptySuggestion.gameObject.SetActive(false);
                                });
                            });
                        }
                        // TODO: check merge
                        background.enabled = true;
                        if (player.HasState("beatmap_downloaded") || player.HasState("start_primed"))
                        {
                            backgroundColor   = green;
                            backgroundColor.a = player.isMe ? 0.4f : 0.1f;
                            background.color  = backgroundColor;
                        }
                        else
                        {
                            hostBeatmapStub.isDownloadable.ContinueWith(r =>
                            {
                                bool downloadable = r.Result;
                                backgroundColor   = downloadable ? yellow : red;
                                backgroundColor.a = player.isMe ? 0.4f : 0.1f;
                                HMMainThreadDispatcher.instance.Enqueue(() =>
                                {
                                    background.color = backgroundColor;
                                });
                            });
                        }
                    }
                }
            }
        }
예제 #25
0
 public override void SetData(IConnectedPlayer connectedPlayer, ILobbyPlayerDataModel playerDataModel, bool isHost, Task <AdditionalContentModel.EntitlementStatus> getLevelEntitlementTask)
 {
     if (getLevelEntitlementTask != null)
     {
         getLevelEntitlementTask = getLevelEntitlementTask.ContinueWith <AdditionalContentModel.EntitlementStatus>(r => AdditionalContentModel.EntitlementStatus.Owned);
     }
     base.SetData(connectedPlayer, playerDataModel, isHost, getLevelEntitlementTask);
     GetLevelEntitlement(connectedPlayer);
     lastPlayer = connectedPlayer;
 }
            public void MaybeLogException(IConnectedPlayer p, Exception ex)
            {
                int exCount = Exceptions.AddOrUpdate(ex.Message, 0, (msg, old) => old + 1);

                if (exCount % 20 == 0)
                {
                    Plugin.Log?.Warn($"An exception was thrown processing a packet from player '{p?.userName ?? "<NULL>"}|{p?.userId ?? " < NULL > "}' ({exCount + 1}): {ex.Message}");
                    Plugin.Log?.Debug(ex);
                }
            }
 public void Initialize(IConnectedPlayer player, IDecoder decoder)
 {
     Player  = player;
     enabled = false;
     _voipFragQueue.Flush();
     _voipDelayCounter = 0;
     Decoder           = decoder;
     Plugin.Log?.Debug($"{name} initialized at {decoder.Channels}x{decoder.SampleRate}Hz");
     enabled = true;
 }
        static void Postfix(IConnectedPlayer connectedPlayer, ILobbyPlayerDataModel playerDataModel, GameServerPlayerTableCell __instance)
        {
            cells[connectedPlayer.userId] = __instance;
            SessionTracker?tracker = SessionTracker;

            if (tracker != null)
            {
                tracker.SetTableCellData(connectedPlayer.userId, __instance);
            }
        }
예제 #29
0
 private void HandlePlayerStateChanged(IConnectedPlayer player)
 {
     if (player.userId != _sessionManager.localPlayer.userId)
     {
         if (player.isConnectionOwner)
         {
             UI.GameplaySetupPanel.instance.SetCustomSongs(player.HasState("customsongs"));
             UI.GameplaySetupPanel.instance.SetEnforceMods(player.HasState("enforcemods"));
         }
     }
 }
 private void OnPlayerStateChanged(IConnectedPlayer player)
 {
     if (starting)
     {
         if (_multiplayerSessionManager.connectedPlayers.All(IsPlayerReady) && _multiplayerSessionManager.LocalPlayerHasState("start_primed"))
         {
             Plugin.Log.Debug("All players ready, starting game.");
             StartLevel();
         }
     }
 }