Exemple #1
0
        void MyMultiplayerLobby_ClientLeft(ulong userId, ChatMemberStateChangeEnum stateChange)
        {
            Peer2Peer.CloseSession(userId);

            MySandboxGame.Log.WriteLineAndConsole("Player left: " + GetMemberName(userId) + " (" + userId + ")");
            MyTrace.Send(TraceWindow.Multiplayer, "Player left: " + stateChange.ToString());
        }
Exemple #2
0
        private bool ReceiveOne()
        {
            uint length;

            if ((MySteam.IsActive || MySteam.Server != null) && Peer2Peer.IsPacketAvailable(out length, Channel))
            {
                ulong sender;
                var   msg = GetMessage((int)length);
                if (Peer2Peer.ReadPacket(msg.Data, out length, out sender, Channel))
                {
                    if (m_timestampProvider != null)
                    {
                        msg.Timestamp = m_timestampProvider();
                    }

                    msg.ReceiveTime = Stopwatch.GetTimestamp();
                    msg.Length      = (int)length;
                    msg.UserId      = sender;

                    m_receiveQueue.Enqueue(msg);
                    return(true);
                }
                else
                {
                    m_messagePool.Return(msg);
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Exemple #3
0
        private void CloseClient()
        {
            MyTrace.Send(TraceWindow.Multiplayer, "Multiplayer client closed");

            if (m_clientJoined)
            {
                MyControlDisconnectedMsg msg = new MyControlDisconnectedMsg();
                msg.Client = MySteam.UserId;

                SendControlMessage(ServerId, ref msg);
            }
            OnJoin = null;

            //TODO: Any better way? P2P needs to be closed from both sides. If closed right after Send, message
            //can stay not sent.
            Thread.Sleep(200);

            //WARN: If closed here, previous control message probably not come
            Peer2Peer.CloseSession(ServerId);

            CloseMemberSessions();

            Peer2Peer.ConnectionFailed -= Peer2Peer_ConnectionFailed;
            Peer2Peer.SessionRequest   -= Peer2Peer_SessionRequest;
        }
Exemple #4
0
        void MyMultiplayerClient_ClientLeft(ulong user, ChatMemberStateChangeEnum stateChange)
        {
            if (user == ServerId)
            {
                RaiseHostLeft();
                return;
            }

            if (m_members.Contains(user))
            {
                m_members.Remove(user);

                MySandboxGame.Log.WriteLineAndConsole("Player disconnected: " + MySteam.API.Friends.GetPersonaName(user) + " (" + user + ")");

                MyTrace.Send(TraceWindow.Multiplayer, "Player disconnected: " + stateChange.ToString());

                if (MySandboxGame.IsGameReady && MySteam.UserId != user)
                {
                    var clientLeft = new MyHudNotification(MySpaceTexts.NotificationClientDisconnected, 5000, level: MyNotificationLevel.Important);
                    clientLeft.SetTextFormatArguments(MySteam.API.Friends.GetPersonaName(user));
                    MyHud.Notifications.Add(clientLeft);
                }

                Peer2Peer.CloseSession(user);
            }

            m_memberData.Remove(user);
        }
        protected void SendControlMessage <T>(ulong user, ref T message) where T : struct
        {
            ITransportCallback   handler;
            MyControlMessageEnum messageEnum;

            m_controlMessageTypes.TryGetValue(typeof(T), out messageEnum);
            m_controlMessageHandlers.TryGetValue((int)messageEnum, out handler);

            var callback = ((MyControlMessageCallback <T>)handler);

            if (!MySyncLayer.CheckSendPermissions(user, callback.Permission))
            {
                return;
            }


            m_controlSendStream.Position = 0;
            m_controlSendStream.WriteUShort((ushort)messageEnum);
            callback.Write(m_controlSendStream, ref message);

            if (!Peer2Peer.SendPacket(user, m_controlSendStream.Data, (int)m_controlSendStream.Position, P2PMessageEnum.Reliable, MyMultiplayer.ControlChannel))
            {
                System.Diagnostics.Debug.Fail("P2P packet not sent");
            }

            // Peer2Peer.SendPacket(user, (byte*)&msg, sizeof(ControlMessageStruct), P2PMessageEnum.Reliable, MyMultiplayer.ControlChannel);
        }
Exemple #6
0
 static void SendHandler(ulong remoteUser, byte[] data, int byteCount, P2PMessageEnum msgType, int channel)
 {
     if (!Peer2Peer.SendPacket(remoteUser, data, byteCount, msgType, channel))
     {
         System.Diagnostics.Debug.Fail("P2P packet send fail");
     }
 }
Exemple #7
0
        public static unsafe bool SendPreemble(ulong sendTo, int channel)
        {
            bool ok   = true;
            byte data = PREEMBLE_HEADER;

            ok &= Peer2Peer.SendPacket(sendTo, &data, 1, P2PMessageEnum.Reliable, channel);
            return(ok);
        }
        void Peer2Peer_SessionRequest(ulong remoteUserId)
        {
            if (IsClientKickedOrBanned(remoteUserId))
            {
                return;
            }

            Peer2Peer.AcceptSession(remoteUserId);
        }
        void Matchmaking_LobbyChatUpdate(Lobby lobby, ulong changedUser, ulong makingChangeUser, ChatMemberStateChangeEnum stateChange)
        {
            //System.Diagnostics.Debug.Assert(MySession.Static != null);

            if (lobby.LobbyId == Lobby.LobbyId)
            {
                if (stateChange == ChatMemberStateChangeEnum.Entered)
                {
                    MySandboxGame.Log.WriteLineAndConsole("Player entered: " + MySteam.API.Friends.GetPersonaName(changedUser) + " (" + changedUser + ")");
                    MyTrace.Send(TraceWindow.Multiplayer, "Player entered");
                    Peer2Peer.AcceptSession(changedUser);

                    RaiseClientJoined(changedUser);

                    if (MySandboxGame.IsGameReady && changedUser != ServerId)
                    {
                        var playerJoined = new MyHudNotification(MySpaceTexts.NotificationClientConnected, 5000, level: MyNotificationLevel.Important);
                        playerJoined.SetTextFormatArguments(MySteam.API.Friends.GetPersonaName(changedUser));
                        MyHud.Notifications.Add(playerJoined);
                    }
                }
                else
                {
                    // Kicked client can be already removed from Clients
                    if (Sync.Clients.HasClient(changedUser))
                    {
                        RaiseClientLeft(changedUser, stateChange);
                    }

                    if (changedUser == ServerId)
                    {
                        MyTrace.Send(TraceWindow.Multiplayer, "Host left: " + stateChange.ToString());
                        RaiseHostLeft();

                        MyGuiScreenMainMenu.UnloadAndExitToMenu();
                        MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
                                                   messageCaption: MyTexts.Get(MySpaceTexts.MessageBoxCaptionError),
                                                   messageText: MyTexts.Get(MySpaceTexts.MultiplayerErrorServerHasLeft)));

                        // Set new server
                        //ServerId = Lobby.GetOwner();

                        //if (ServerId == Sync.MyId)
                        //{
                        //    Lobby.SetLobbyData(HostNameTag, Sync.MyName);
                        //}
                    }
                    else if (MySandboxGame.IsGameReady)
                    {
                        var playerLeft = new MyHudNotification(MySpaceTexts.NotificationClientDisconnected, 5000, level: MyNotificationLevel.Important);
                        playerLeft.SetTextFormatArguments(MySteam.API.Friends.GetPersonaName(changedUser));
                        MyHud.Notifications.Add(playerLeft);
                    }
                }
            }
        }
        private void CloseSession()
        {
            OnJoin = null;

            //WARN: If closed here, previous control message probably not come
            Peer2Peer.CloseSession(ServerId);

            Peer2Peer.ConnectionFailed -= Peer2Peer_ConnectionFailed;
            Peer2Peer.SessionRequest   -= Peer2Peer_SessionRequest;
        }
 private void AcceptMemberSessions()
 {
     for (int i = 0; i < Lobby.MemberCount; i++)
     {
         var member = Lobby.GetLobbyMemberByIndex(i);
         if (member != MySteam.UserId)
         {
             Peer2Peer.AcceptSession(member);
         }
     }
 }
        unsafe private void SendHeader()
        {
            int   headerSize = sizeof(byte) + sizeof(int) + sizeof(int) + sizeof(int);
            byte *block      = stackalloc byte[headerSize]; // First byte is header

            block[0] = MyMultipartMessage.START_HEADER;
            ((int *)(&block[1]))[0] = m_blockCount;
            ((int *)(&block[1]))[1] = m_blockSize;
            ((int *)(&block[1]))[2] = m_dataLength;
            Peer2Peer.SendPacket(m_sendTo, block, headerSize, P2PMessageEnum.ReliableWithBuffering, m_channel);
        }
Exemple #13
0
 protected void CloseMemberSessions()
 {
     for (int i = 0; i < MemberCount; i++)
     {
         var member = GetMemberByIndex(i);
         if (member != Sync.MyId && member == ServerId)
         {
             Peer2Peer.CloseSession(member);
         }
     }
 }
Exemple #14
0
 private void AcceptMemberSessions()
 {
     for (int i = 0; i < Lobby.MemberCount; i++)
     {
         var member = Lobby.GetLobbyMemberByIndex(i);
         if (member != Sync.MyId && member == ServerId)
         {
             Peer2Peer.AcceptSession(member);
         }
     }
 }
 protected void CloseMemberSessions()
 {
     for (int i = 0; i < MemberCount; i++)
     {
         var member = GetMemberByIndex(i);
         if (member != MySteam.UserId)
         {
             Peer2Peer.CloseSession(member);
         }
     }
 }
Exemple #16
0
        public void GetIP(ulong steamId = 0)
        {
            var state = new P2PSessionState();

            if (steamId == 0)
            {
                steamId = Context.Player.SteamUserId;
            }
            Peer2Peer.GetSessionState(steamId, ref state);
            var ip = new IPAddress(BitConverter.GetBytes(state.RemoteIP).Reverse().ToArray());

            Context.Respond($"Your IP is {ip}");
        }
        void SendHandler(ulong remoteUser, byte[] data, int byteCount, P2PMessageEnum msgType, int channel)
        {
            if (msgType == P2PMessageEnum.ReliableWithBuffering)
            {
                m_pendingFlushes.Add(remoteUser);
            }

            ByteCountSent += byteCount;
            if (!Peer2Peer.SendPacket(remoteUser, data, byteCount, msgType, channel))
            {
                System.Diagnostics.Debug.Fail("P2P packet send fail");
            }
        }
Exemple #18
0
        //Largely copied from SE
        private void ValidateAuthTicketResponse(ulong steamId, JoinResult response, ulong steamOwner)
        {
            var state = new P2PSessionState();

            Peer2Peer.GetSessionState(steamId, ref state);
            var ip = state.GetRemoteIP();

            _log.Debug($"ValidateAuthTicketResponse(user={steamId}, response={response}, owner={steamOwner})");

            _log.Info($"Connection attempt by {steamId} from {ip}");
            // TODO implement IP bans
            var config = (TorchConfig)Torch.Config;

            if (config.EnableWhitelist && !config.Whitelist.Contains(steamId))
            {
                _log.Warn($"Rejecting user {steamId} because they are not whitelisted in Torch.cfg.");
                UserRejected(steamId, JoinResult.NotInGroup);
            }
            else if (Torch.CurrentSession.KeenSession.OnlineMode == MyOnlineModeEnum.OFFLINE &&
                     !Torch.CurrentSession.KeenSession.IsUserAdmin(steamId))
            {
                _log.Warn($"Rejecting user {steamId}, world is set to offline and user is not admin.");
                UserRejected(steamId, JoinResult.TicketCanceled);
            }
            else if (MySandboxGame.ConfigDedicated.GroupID == 0uL)
            {
                RunEvent(new ValidateAuthTicketEvent(steamId, steamOwner, response, 0, true, false));
            }
            else if (_getServerAccountType(MySandboxGame.ConfigDedicated.GroupID) != MyGameServiceAccountType.Clan)
            {
                UserRejected(steamId, JoinResult.GroupIdInvalid);
            }
            else if (MyGameService.GameServer.RequestGroupStatus(steamId, MySandboxGame.ConfigDedicated.GroupID))
            {
                lock (_waitingForGroupLocal)
                {
                    if (_waitingForGroupLocal.Count >= _waitListSize)
                    {
                        _waitingForGroupLocal.RemoveAt(0);
                    }
                    _waitingForGroupLocal.Add(new WaitingForGroup(steamId, response, steamOwner));
                }
            }
            else
            {
                UserRejected(steamId, JoinResult.SteamServersOffline);
            }
        }
        public unsafe void Tick()
        {
            foreach (var steamId in m_pendingFlushes)
            {
                byte data = 0;
                if (!Peer2Peer.SendPacket(steamId, &data, 0, P2PMessageEnum.Reliable, m_channel))
                {
                    System.Diagnostics.Debug.Fail("P2P packet send fail (flush)");
                }
            }
            m_pendingFlushes.Clear();

            int totalSum = 0;

            NetProfiler.Begin("Avg per frame (60 frames window)");
            for (int i = 0; i < MessageTypeCount; i++)
            {
                var window = m_slidingWindows[i];
                window.Enqueue(m_thisFrameTraffic[i]);
                m_thisFrameTraffic[i] = 0;

                while (window.Count > 60)
                {
                    window.Dequeue();
                }

                int sum = 0;
                foreach (var item in window)
                {
                    sum += item;
                }
                if (sum > 0)
                {
                    NetProfiler.Begin(MyEnum <MyMessageId> .GetName((MyMessageId)i));
                    NetProfiler.End(sum / 60.0f, sum / 1024.0f, "{0} KB/s");
                }
                totalSum += sum;
            }
            NetProfiler.End(totalSum / 60.0f, totalSum / 1024.0f, "{0} KB/s");
        }
        void MyDedicatedServer_ClientLeft(ulong user, ChatMemberStateChangeEnum arg2)
        {
            Peer2Peer.CloseSession(user);
            MyLog.Default.WriteLineAndConsole("User left " + GetMemberName(user));
            if (m_members.Contains(user))
            {
                m_members.Remove(user);
            }

            if (m_pendingMembers.ContainsKey(user))
            {
                m_pendingMembers.Remove(user);
            }

            if (m_waitingForGroup.Contains(user))
            {
                m_waitingForGroup.Remove(user);
            }

            if (arg2 != ChatMemberStateChangeEnum.Kicked && arg2 != ChatMemberStateChangeEnum.Banned)
            {
                foreach (var member in m_members)
                {
                    if (member != ServerId)
                    {
                        MyControlDisconnectedMsg msg = new MyControlDisconnectedMsg();
                        msg.Client = user;
                        SendControlMessage(member, ref msg);
                    }
                }
            }

            SteamSDK.SteamServerAPI.Instance.GameServer.SendUserDisconnect(user);

            m_memberData.Remove(user);
        }
Exemple #21
0
 private void SendVoice(ulong user, byte[] data, uint dataSize)
 {
     Peer2Peer.SendPacket(user, data, (int)dataSize, P2PMessageEnum.UnreliableNoDelay, MyMultiplayer.VoiceChatChannel);
 }
Exemple #22
0
        private static void DownloadWorld(MyGuiScreenProgress progress, MyMultiplayerBase multiplayer)
        {
            if (progress.Text != null)
            {
                progress.Text.Clear();
                progress.Text.Append(MyTexts.Get(MySpaceTexts.MultiplayerStateConnectingToServer));
            }

            MyLog.Default.WriteLine("World requested");

            const float worldRequestTimeout = 40; // in seconds
            Stopwatch   worldRequestTime    = Stopwatch.StartNew();

            ulong serverId  = multiplayer.GetOwner();
            bool  connected = false;

            progress.Tick += () =>
            {
                P2PSessionState state = default(P2PSessionState);
                Peer2Peer.GetSessionState(multiplayer.ServerId, ref state);

                if (!connected && state.ConnectionActive)
                {
                    MyLog.Default.WriteLine("World requested - connection alive");
                    connected = true;
                    if (progress.Text != null)
                    {
                        progress.Text.Clear();
                        progress.Text.Append(MyTexts.Get(MySpaceTexts.MultiplayerStateWaitingForServer));
                    }
                }

                //progress.Text.Clear();
                //progress.Text.AppendLine("Connecting: " + state.Connecting);
                //progress.Text.AppendLine("ConnectionActive: " + state.ConnectionActive);
                //progress.Text.AppendLine("Relayed: " + state.UsingRelay);
                //progress.Text.AppendLine("Bytes queued: " + state.BytesQueuedForSend);
                //progress.Text.AppendLine("Packets queued: " + state.PacketsQueuedForSend);
                //progress.Text.AppendLine("Last session error: " + state.LastSessionError);
                //progress.Text.AppendLine("Original server: " + serverId);
                //progress.Text.AppendLine("Current server: " + multiplayer.Lobby.GetOwner());
                //progress.Text.AppendLine("Game version: " + multiplayer.AppVersion);

                if (serverId != multiplayer.GetOwner())
                {
                    MyLog.Default.WriteLine("World requested - failed, server changed");
                    progress.Cancel();
                    MyGuiSandbox.Show(MySpaceTexts.MultiplayerErrorServerHasLeft);
                    multiplayer.Dispose();
                }

                if (worldRequestTime.IsRunning && worldRequestTime.Elapsed.TotalSeconds > worldRequestTimeout)
                {
                    MyLog.Default.WriteLine("World requested - failed, server changed");
                    progress.Cancel();
                    MyGuiSandbox.Show(MySpaceTexts.MultiplaterJoin_ServerIsNotResponding);
                    multiplayer.Dispose();
                }
            };

            var downloadResult = multiplayer.DownloadWorld();

            downloadResult.ProgressChanged += (result) =>
            {
                worldRequestTime.Stop();
                OnDownloadProgressChanged(progress, result, multiplayer);
            };

            progress.ProgressCancelled += () =>
            {
                downloadResult.Cancel();
                multiplayer.Dispose();
                //var joinScreen = MyScreenManager.GetScreenWithFocus() as MyGuiScreenJoinGame;
                //if (joinScreen != null)
                //  joinScreen.ReloadList();
            };
        }
Exemple #23
0
        void Matchmaking_LobbyChatUpdate(Lobby lobby, ulong changedUser, ulong makingChangeUser, ChatMemberStateChangeEnum stateChange)
        {
            //System.Diagnostics.Debug.Assert(MySession.Static != null);

            if (lobby.LobbyId == Lobby.LobbyId)
            {
                if (stateChange == ChatMemberStateChangeEnum.Entered)
                {
                    MySandboxGame.Log.WriteLineAndConsole("Player entered: " + MySteam.API.Friends.GetPersonaName(changedUser) + " (" + changedUser + ")");
                    MyTrace.Send(TraceWindow.Multiplayer, "Player entered");
                    Peer2Peer.AcceptSession(changedUser);

                    // When some clients connect at the same time then some of them can have already added clients
                    // (see function MySyncLayer.RegisterClientEvents which registers all Members in Lobby).
                    if (Sync.Clients == null || !Sync.Clients.HasClient(changedUser))
                    {
                        RaiseClientJoined(changedUser);
                    }

                    if (MySandboxGame.IsGameReady && changedUser != ServerId)
                    {
                        // Player is able to connect to the battle which already started - player is then kicked and we do not want to show connected message in HUD.
                        bool showMsg = true;
                        if (MyFakes.ENABLE_BATTLE_SYSTEM && MySession.Static != null && MySession.Static.Battle && !BattleCanBeJoined)
                        {
                            showMsg = false;
                        }

                        if (showMsg)
                        {
                            var playerJoined = new MyHudNotification(MyCommonTexts.NotificationClientConnected, 5000, level: MyNotificationLevel.Important);
                            playerJoined.SetTextFormatArguments(MySteam.API.Friends.GetPersonaName(changedUser));
                            MyHud.Notifications.Add(playerJoined);
                        }
                    }
                }
                else
                {
                    // Kicked client can be already removed from Clients
                    if (Sync.Clients == null || Sync.Clients.HasClient(changedUser))
                    {
                        RaiseClientLeft(changedUser, stateChange);
                    }

                    if (changedUser == ServerId)
                    {
                        MyTrace.Send(TraceWindow.Multiplayer, "Host left: " + stateChange.ToString());
                        RaiseHostLeft();

                        MySessionLoader.UnloadAndExitToMenu();
                        MyGuiSandbox.AddScreen(MyGuiSandbox.CreateMessageBox(
                                                   messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionError),
                                                   messageText: MyTexts.Get(MyCommonTexts.MultiplayerErrorServerHasLeft)));

                        // Set new server
                        //ServerId = Lobby.GetOwner();

                        //if (ServerId == Sync.MyId)
                        //{
                        //    Lobby.SetLobbyData(HostNameTag, Sync.MyName);
                        //}
                    }
                    else if (MySandboxGame.IsGameReady)
                    {
                        var playerLeft = new MyHudNotification(MyCommonTexts.NotificationClientDisconnected, 5000, level: MyNotificationLevel.Important);
                        playerLeft.SetTextFormatArguments(MySteam.API.Friends.GetPersonaName(changedUser));
                        MyHud.Notifications.Add(playerLeft);
                    }
                }
            }
        }