public static async Task <bool> Announce(HostedGameData announce)
        {
            var payload = announce.ToJson();

            var isDupeRequest       = (_lastPayloadSent != null && _lastPayloadSent == payload);
            var enoughTimeHasPassed = (_lastSentAt == null ||
                                       (DateTime.Now - _lastSentAt.Value).TotalMinutes >= ANNOUNCE_INTERVAL_MINS);

            if (isDupeRequest && !enoughTimeHasPassed)
            {
                // An identical payload was already sent out!
                // Do not send a dupe unless enough time has passed
                return(true);
            }

            Plugin.Log?.Info($"Sending host announcement [{announce.Describe()}] for code {announce.ServerCode}");

            _lastPayloadSent = payload;
            _lastSentAt      = DateTime.Now;

            var responseOk = await PerformWebRequest("POST", "/announce", payload) != null;

            if (!responseOk)
            {
                // Request failed, allow immediate retry
                _lastPayloadSent = null;
                _lastSentAt      = null;
            }

            return(responseOk);
        }
        private static HostedGameData GenerateAnnounce()
        {
            var sessionManager   = MpSession.SessionManager;
            var localPlayer      = sessionManager.localPlayer;
            var connectedPlayers = sessionManager.connectedPlayers;

            if (_mpExVersion == null)
            {
                _mpExVersion = MpExHelper.GetInstalledVersion();

                if (_mpExVersion != null)
                {
                    Plugin.Log?.Info($"Detected MultiplayerExtensions, version {_mpExVersion}");
                }
            }

            var lobbyAnnounce = new HostedGameData()
            {
                ServerCode       = _lobbyCode,
                GameName         = MpSession.GetHostGameName(),
                OwnerId          = localPlayer.userId,
                OwnerName        = localPlayer.userName,
                PlayerCount      = MpSession.GetPlayerCount(),
                PlayerLimit      = MpSession.GetPlayerLimit(),
                IsModded         = localPlayer.HasState("modded") || localPlayer.HasState("customsongs") || _mpExVersion != null,
                LobbyState       = MpLobbyStatePatch.LobbyState,
                LevelId          = _level?.levelID,
                SongName         = _level?.songName,
                SongAuthor       = _level?.songAuthorName,
                Difficulty       = _difficulty,
                Platform         = MpLocalPlayer.PlatformId,
                MasterServerHost = MpConnect.LastUsedMasterServer != null ? MpConnect.LastUsedMasterServer.hostName : null,
                MasterServerPort = MpConnect.LastUsedMasterServer != null ? MpConnect.LastUsedMasterServer.port : MpConnect.DEFAULT_MASTER_PORT,
                MpExVersion      = _mpExVersion
            };

            lobbyAnnounce.Players = new List <HostedGamePlayer>();
            lobbyAnnounce.Players.Add(new HostedGamePlayer()
            {
                SortIndex = localPlayer.sortIndex,
                UserId    = localPlayer.userId,
                UserName  = localPlayer.userName,
                IsHost    = localPlayer.isConnectionOwner,
                Latency   = localPlayer.currentLatency
            });
            foreach (var connectedPlayer in connectedPlayers)
            {
                lobbyAnnounce.Players.Add(new HostedGamePlayer()
                {
                    SortIndex = connectedPlayer.sortIndex,
                    UserId    = connectedPlayer.userId,
                    UserName  = connectedPlayer.userName,
                    IsHost    = connectedPlayer.isConnectionOwner,
                    Latency   = connectedPlayer.currentLatency
                });
            }

            return(lobbyAnnounce);
        }
        public static async Task <bool> UnAnnounce(HostedGameData announce)
        {
            Plugin.Log?.Info($"Cancelling host announcement: {announce.GameName}, {announce.ServerCode}");

            _lastPayloadSent = null;

            var responseOk = await PerformWebRequest("POST", $"/unannounce?serverCode={announce.ServerCode}&ownerId={announce.OwnerId}") != null;

            return(responseOk);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Ensures that any host announcements made by us are removed:
        ///  - If a previous announcement was made, a DELETE request is sent to the master server, removing it.
        ///  - If no previous announcement was made, or it was already deleted, this is a no-op.
        /// </summary>
        public static async Task UnAnnounce()
        {
            if (_lastCompleteAnnounce != null && !_sentUnAnnounce)
            {
                _sentUnAnnounce = true;

                if (await BSSBMasterAPI.UnAnnounce(_lastCompleteAnnounce))
                {
                    Plugin.Log?.Info($"Host announcement was deleted OK!");

                    _didAnnounce          = false;
                    _lastCompleteAnnounce = null;
                }
                else
                {
                    _sentUnAnnounce = false;
                }
            }
        }
Exemplo n.º 5
0
        private static async Task DoAnnounce(HostedGameData announce)
        {
            _sentUnAnnounce = false;

            if (await BSSBMasterAPI.Announce(announce))
            {
                _didAnnounce          = true;
                _lastCompleteAnnounce = announce;

                StatusText = $"Players can now join from the browser!\r\n{announce.Describe()}";
                HasErrored = false;
            }
            else
            {
                _didAnnounce          = false;
                _lastCompleteAnnounce = null;

                StatusText = $"Could not announce to master server!";
                HasErrored = true;
            }

            LobbyConfigPanel.UpdatePanelInstance();
        }
Exemplo n.º 6
0
        public static void HandleUpdate()
        {
#pragma warning disable CS4014
            var sessionManager = MpSession.SessionManager;

            if (sessionManager == null ||
                !MpLobbyConnectionTypePatch.IsPartyMultiplayer ||
                !MpLobbyConnectionTypePatch.IsPartyHost ||
                !MpLobbyStatePatch.IsValidMpState)
            {
                // We are not in a party lobby, or we are not the host
                // Make sure any previous host announcements by us are cancelled and bail
                StatusText = "You must be the host of a custom multiplayer game.";
                HasErrored = true;

                UnAnnounce();

                LobbyConfigPanel.UpdatePanelInstance();
                return;
            }

            if (Plugin.Config.LobbyAnnounceToggle)
            {
                // Toggle is on, ensure state is synced
                if (!_didSetLocalPlayerState.HasValue || _didSetLocalPlayerState.Value == false)
                {
                    _didSetLocalPlayerState = true;
                    sessionManager.SetLocalPlayerState("lobbyannounce", true); // NB: this calls another update
                }
            }
            else
            {
                // Toggle is off, ensure state is synced & do not proceed with announce
                StatusText = "Lobby announces are toggled off.";
                HasErrored = true;

                UnAnnounce();

                if (!_didSetLocalPlayerState.HasValue || _didSetLocalPlayerState.Value == true)
                {
                    _didSetLocalPlayerState = false;
                    sessionManager.SetLocalPlayerState("lobbyannounce", false); // NB: this calls another update
                }

                LobbyConfigPanel.UpdatePanelInstance();
                return;
            }

            if (String.IsNullOrEmpty(_lobbyCode) || !sessionManager.isConnectionOwner ||
                sessionManager.localPlayer == null || !sessionManager.isConnected ||
                sessionManager.maxPlayerCount == 1)
            {
                // We do not (yet) have the Server Code, or we're at an in-between state where things aren't ready yet
                StatusText = "Can't send announcement (invalid lobby state).";
                HasErrored = true;

                UnAnnounce();

                LobbyConfigPanel.UpdatePanelInstance();
                return;
            }

            string finalGameName = $"{sessionManager.localPlayer.userName}'s game";

            if (!String.IsNullOrEmpty(_customGameName))
            {
                finalGameName = _customGameName;
            }
            else if (!String.IsNullOrEmpty(Plugin.Config.CustomGameName))
            {
                finalGameName = Plugin.Config.CustomGameName;
            }

            var lobbyAnnounce = new HostedGameData()
            {
                ServerCode       = _lobbyCode,
                GameName         = finalGameName,
                OwnerId          = sessionManager.localPlayer.userId,
                OwnerName        = sessionManager.localPlayer.userName,
                PlayerCount      = MpSession.GetPlayerCount(),
                PlayerLimit      = MpSession.GetPlayerLimit(),
                IsModded         = sessionManager.localPlayer.HasState("modded") && sessionManager.localPlayer.HasState("customsongs"),
                LobbyState       = MpLobbyStatePatch.LobbyState,
                LevelId          = _level?.levelID,
                SongName         = _level?.songName,
                SongAuthor       = _level?.songAuthorName,
                Difficulty       = _difficulty,
                Platform         = Plugin.PlatformId,
                MasterServerHost = MpConnect.LastUsedMasterServer != null ? MpConnect.LastUsedMasterServer.hostName : null,
                MasterServerPort = MpConnect.LastUsedMasterServer != null ? MpConnect.LastUsedMasterServer.port : MpConnect.DEFAULT_MASTER_PORT
            };

            StatusText = "Announcing your game to the world...\r\n" + lobbyAnnounce.Describe();
            HasErrored = false;

            LobbyConfigPanel.UpdatePanelInstance();

            DoAnnounce(lobbyAnnounce);
#pragma warning restore CS4014
        }