예제 #1
0
        public void Init(INetworkPlayer player, IShard shard, IPacketSender s)
        {
            Player          = player;
            NetClientStatus = Status.Connecting;
            AssignedShard   = shard;

            NetChans = Channel.GetChannels(this, s).ToImmutableDictionary();
            NetChans[ChannelType.Control].PacketAvailable       += Control_PacketAvailable;
            NetChans[ChannelType.Matrix].PacketAvailable        += Matrix_PacketAvailable;
            NetChans[ChannelType.ReliableGss].PacketAvailable   += GSS_PacketAvailable;
            NetChans[ChannelType.UnreliableGss].PacketAvailable += GSS_PacketAvailable;
        }
예제 #2
0
        void FindLocalTank()
        {
            INetworkPlayer player = NetworkManager.Client.Player;

            // Check to see if the player object is loaded in yet
            if (!player.HasCharacter)
            {
                return;
            }

            LocalPlayer = player.Identity.GetComponent <Tank>();
        }
예제 #3
0
 /// <summary>
 /// Removes the player object from the connection
 /// </summary>
 /// <param name="player">The connection of the client to remove from</param>
 /// <param name="destroyServerObject">Indicates whether the server object should be destroyed</param>
 /// <exception cref="InvalidOperationException">Received remove player message but connection has no player</exception>
 public void RemovePlayerForConnection(INetworkPlayer player, bool destroyServerObject = false)
 {
     if (player.Identity != null)
     {
         Destroy(player.Identity.gameObject, destroyServerObject);
         player.Identity = null;
     }
     else
     {
         throw new InvalidOperationException("Received remove player message but connection has no player");
     }
 }
예제 #4
0
        public override void OnClientAuthenticate(INetworkPlayer player)
        {
            player.RegisterHandler <AuthResponseMessage>(OnAuthResponseMessage);

            var authRequestMessage = new AuthRequestMessage
            {
                AuthUsername = Username,
                AuthPassword = Password
            };

            player.Send(authRequestMessage);
        }
예제 #5
0
        internal void SendRemoveAuthorityMessage(NetworkIdentity identity, INetworkPlayer previousOwner)
        {
            if (logger.LogEnabled())
            {
                logger.Log($"Server SendRemoveAuthorityMessage: name={identity.name} sceneId={identity.SceneId:X} netId={identity.NetId}");
            }

            previousOwner.Send(new RemoveAuthorityMessage
            {
                netId = identity.NetId,
            });
        }
예제 #6
0
        private void OnCreatePlayer(INetworkPlayer player, CreateCharacterMessage createCharacterMessage)
        {
            // create a gameobject using the name supplied by client
            var playergo = Instantiate(playerPrefab).gameObject;

            playergo.GetComponent <Player>().playerName = createCharacterMessage.name;

            // set it as the player
            ServerObjectManager.AddCharacter(player, playergo);

            chatWindow.gameObject.SetActive(true);
        }
예제 #7
0
        // you can send the message here if you already know
        // everything about the character at the time of player
        // or at a later time when the user submits his preferences
        private void OnClientAuthenticated(INetworkPlayer player)
        {
            var mmoCharacter = new CreateMMOCharacterMessage
            {
                // populate the message with your data
                name      = "player name",
                race      = Race.Human,
                eyeColor  = Color.red,
                hairColor = Color.black,
            };

            player.Send(mmoCharacter);
        }
예제 #8
0
        void OnClientConnected(INetworkPlayer player)
        {
            RegisterSpawnPrefabs();

            if (Client.IsLocalClient)
            {
                RegisterHostHandlers();
            }
            else
            {
                RegisterMessageHandlers();
            }
        }
예제 #9
0
        internal void InternalReplacePlayerForConnection(INetworkPlayer player, GameObject character, bool keepAuthority)
        {
            NetworkIdentity identity = character.GetComponent <NetworkIdentity>();

            if (identity is null)
            {
                throw new ArgumentException("ReplacePlayer: playerGameObject has no NetworkIdentity. Please add a NetworkIdentity to " + character);
            }

            if (identity.ConnectionToClient != null && identity.ConnectionToClient != player)
            {
                throw new ArgumentException("Cannot replace player for connection. New player is already owned by a different connection" + character);
            }

            //NOTE: there can be an existing player
            logger.Log("NetworkServer ReplacePlayer");

            NetworkIdentity previousPlayer = player.Identity;

            player.Identity = identity;

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(player);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (player == Server.LocalPlayer)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Player.Identity = identity;
            }

            // add connection to observers AFTER the playerController was set.
            // by definition, there is nothing to observe if there is no player
            // controller.
            //
            // IMPORTANT: do this in AddCharacter & ReplaceCharacter!
            SpawnObserversForConnection(player);

            if (logger.LogEnabled())
            {
                logger.Log("Replacing playerGameObject object netId: " + character.GetComponent <NetworkIdentity>().NetId + " asset ID " + character.GetComponent <NetworkIdentity>().AssetId);
            }

            Respawn(identity);

            if (!keepAuthority)
            {
                previousPlayer.RemoveClientAuthority();
            }
        }
예제 #10
0
        /// <summary>
        ///     Check whether or not the player is in a specific scene or not.
        /// </summary>
        /// <param name="scene">The scene we want to check in.</param>
        /// <param name="player">The player we want to check for.</param>
        /// <returns>Returns true or false if the player is in the scene specified.</returns>
        public bool IsPlayerInScene(Scene scene, INetworkPlayer player)
        {
            if (!scene.IsValid())
            {
                throw new ArgumentException("Scene is not valid", nameof(scene));
            }

            if (!ServerSceneData.TryGetValue(scene, out var players))
            {
                throw new KeyNotFoundException($"Could not find player list for scene:{scene}");
            }

            return(players.Contains(player));
        }
        /// <inheritdoc />
        public NetworkPlayerCommandMessageContext(INetworkPlayer remote, INetworkPlayer local)
        {
            if (remote == null)
            {
                throw new ArgumentNullException(nameof(remote));
            }
            if (local == null)
            {
                throw new ArgumentNullException(nameof(local));
            }

            RemotePlayer = remote;
            LocalPlayer  = local;
        }
예제 #12
0
        /// <summary>
        /// called by LocalClient to add itself. dont call directly.
        /// </summary>
        /// <param name="client">The local client</param>
        /// <param name="tconn">The connection to the client</param>
        internal void SetLocalConnection(NetworkClient client, IConnection tconn)
        {
            if (LocalPlayer != null)
            {
                throw new InvalidOperationException("Local Connection already exists");
            }

            INetworkPlayer player = GetNewPlayer(tconn);

            LocalPlayer = player;
            LocalClient = client;

            ConnectionAcceptedAsync(player).Forget();
        }
예제 #13
0
 public IPlayer GetPlayer(INetworkPlayer networkPlayer)
 {
     foreach (ITeam team in teams)
     {
         foreach (IPlayer player in team.Players)
         {
             if (player.NetworkPlayer.Equals(networkPlayer))
             {
                 return(player);
             }
         }
     }
     return(null);
 }
예제 #14
0
        void OnClientConnected(INetworkPlayer player)
        {
            syncVarReceiver = new SyncVarReceiver(Client, Client.World);
            RegisterSpawnPrefabs();

            if (Client.IsLocalClient)
            {
                RegisterHostHandlers();
            }
            else
            {
                RegisterMessageHandlers();
            }
        }
예제 #15
0
파일: Shard.cs 프로젝트: FallenAvatar/PIN
        public bool MigrateIn(INetworkPlayer player)
        {
            if (Clients.ContainsKey(player.SocketID))
            {
                return(true);
            }

            player.Init(this, NetServer);

            Clients.Add(player.SocketID, player);
            //Entities.Add(player.CharacterEntity.EntityID, player.CharacterEntity);

            return(true);
        }
예제 #16
0
        public async Task MovementInput(INetworkPlayer player, IShard shard, ulong EntityID, Packets.GamePacket packet)
        {
            if (packet.BytesRemaining < 64)
            {
                return;
            }

            var pkt = packet.Read <MovementInput>();

            if (player == null || player.CharacterEntity == null || !player.CharacterEntity.Alive)
            {
                return;
            }

            player.CharacterEntity.Position      = pkt.Position;
            player.CharacterEntity.Rotation      = pkt.Rotation;
            player.CharacterEntity.Velocity      = pkt.Velocity;
            player.CharacterEntity.AimDirection  = pkt.AimDirection;
            player.CharacterEntity.MovementState = (Entities.Character.CharMovement)pkt.State;

            if (player.CharacterEntity.LastJumpTime == null)
            {
                player.CharacterEntity.LastJumpTime = pkt.LastJumpTimer;
            }

            //Program.Logger.Warning( "Movement Unk1: {0:X4} {1:X4} {2:X4} {3:X4} {4:X4}", pkt.UnkUShort1, pkt.UnkUShort2, pkt.UnkUShort3, pkt.UnkUShort4, pkt.LastJumpTimer );

            var resp = new ConfirmedPoseUpdate {
                ShortTime     = pkt.ShortTime,
                UnkByte1      = 1,
                UnkByte2      = 0,
                Position      = player.CharacterEntity.Position,
                Rotation      = player.CharacterEntity.Rotation,
                State         = (ushort)player.CharacterEntity.MovementState,
                Velocity      = player.CharacterEntity.Velocity,
                UnkUShort1    = pkt.UnkUShort3,
                UnkUShort2    = pkt.UnkUShort4,                 // Somehow affects gravity
                LastJumpTimer = pkt.LastJumpTimer,
                UnkByte3      = 0,
                NextShortTime = unchecked ((ushort)(pkt.ShortTime + 90))
            };

            _ = await shard.SendGSSTo(player, ChannelType.UnreliableGss, resp, player.EntityID);

            if (player.CharacterEntity.LastJumpTime.HasValue && pkt.LastJumpTimer > player.CharacterEntity.LastJumpTime.Value)
            {
                player.Jump();
            }
        }
예제 #17
0
        /// <inheritdoc />
        public override Task HandleMessage(IPeerMessageContext <PSOBBGamePacketPayloadClient> context, BlockOtherPlayerLeaveGameEventPayload payload)
        {
            //TODO: We can't check that we have this spawned, so we should address that.
            INetworkPlayer player = PlayerRegistry.RemoveEntity(payload.Identifier);

            if (player == null)
            {
                Logger.Warn($"Recieved GameLeave for unknown Client: {payload.Identifier}.");
                return(Task.CompletedTask);
            }

            player.Despawn();

            return(Task.CompletedTask);
        }
예제 #18
0
        public async Task ScheduleUpdateRequest(INetworkPlayer player, IShard shard, ulong EntityID, GamePacket packet)
        {
            var req = packet.Read <Packets.GSS.Generic.ScheduleUpdateRequest>();

            player.LastRequestedUpdate = shard.CurrentTime;
            player.RequestedClientTime = Math.Max(req.requestClientTime, player.RequestedClientTime);

            if (!player.FirstUpdateRequested)
            {
                player.FirstUpdateRequested = true;
                player.Respawn();
            }

            //Program.Logger.Error( "Update scheduled" );
        }
예제 #19
0
        // executed at the server when we receive a ping message
        // reply with a pong containing the time from the client
        // and time from the server
        internal void OnServerPing(INetworkPlayer player, NetworkPingMessage msg)
        {
            if (logger.LogEnabled())
            {
                logger.Log("OnPingServerMessage  conn=" + player);
            }

            var pongMsg = new NetworkPongMessage
            {
                clientTime = msg.clientTime,
                serverTime = LocalTime()
            };

            player.Send(pongMsg, Channel.Unreliable);
        }
예제 #20
0
        public override void OnServerAddPlayer(INetworkPlayer player)
        {
            // add player at correct spawn position
            Transform       start     = Server.NumberOfPlayers == 0 ? leftRacketSpawn : rightRacketSpawn;
            NetworkIdentity character = Instantiate(PlayerPrefab, start.position, start.rotation);

            ServerObjectManager.AddCharacter(player, character.gameObject);

            // spawn ball if two players
            if (Server.NumberOfPlayers == 2)
            {
                ball = Instantiate(ballPrefab);
                ServerObjectManager.Spawn(ball);
            }
        }
예제 #21
0
        async UniTaskVoid ConnectionAcceptedAsync(INetworkPlayer player)
        {
            if (logger.LogEnabled())
            {
                logger.Log("Server accepted client:" + player);
            }

            //Only allow host client to connect when not Listening for new connections
            if (!Listening && player != LocalPlayer)
            {
                return;
            }

            // are more connections allowed? if not, kick
            // (it's easier to handle this in Mirage, so Transports can have
            //  less code and third party transport might not do that anyway)
            // (this way we could also send a custom 'tooFull' message later,
            //  Transport can't do that)
            if (Players.Count >= MaxConnections)
            {
                player.Connection?.Disconnect();
                if (logger.WarnEnabled())
                {
                    logger.LogWarning("Server full, kicked client:" + player);
                }
                return;
            }

            // add connection
            AddConnection(player);

            // let everyone know we just accepted a connection
            Connected?.Invoke(player);

            // now process messages until the connection closes
            try
            {
                await player.ProcessMessagesAsync();
            }
            catch (Exception ex)
            {
                logger.LogException(ex);
            }
            finally
            {
                OnDisconnected(player);
            }
        }
        public void SetUp()
        {
            networkServerGameObject = new GameObject();
            server = networkServerGameObject.AddComponent <NetworkServer>();
            serverObjectManager        = networkServerGameObject.AddComponent <ServerObjectManager>();
            serverObjectManager.Server = server;
            client = networkServerGameObject.AddComponent <NetworkClient>();

            gameObject      = new GameObject();
            identity        = gameObject.AddComponent <NetworkIdentity>();
            identity.Server = server;
            identity.ServerObjectManager = serverObjectManager;

            player1 = Substitute.For <INetworkPlayer>();
            player2 = Substitute.For <INetworkPlayer>();
        }
예제 #23
0
 private void OnServerRpcReply(INetworkPlayer player, ServerRpcReply reply)
 {
     // find the callback that was waiting for this and invoke it.
     if (callbacks.TryGetValue(reply.replyId, out Action <NetworkReader> action))
     {
         callbacks.Remove(replyId);
         using (PooledNetworkReader reader = NetworkReaderPool.GetReader(reply.payload))
         {
             action(reader);
         }
     }
     else
     {
         throw new MethodAccessException("Received reply but no handler was registered");
     }
 }
예제 #24
0
        private void OnServerAddPlayerInternal(INetworkPlayer player, AddCharacterMessage msg)
        {
            logger.Log("CharacterSpawner.OnServerAddPlayer");

            if (player.HasCharacter)
            {
                // player already has character on server, but client asked for it
                // so we respawn it here so that client recieves it again
                // this can happen when client loads normally, but server addititively
                ServerObjectManager.Spawn(player.Identity);
            }
            else
            {
                OnServerAddPlayer(player);
            }
        }
예제 #25
0
        public void HideForConnection()
        {
            // add connection

            INetworkPlayer player = Substitute.For <INetworkPlayer>();

            NetworkIdentity identity = new GameObject().AddComponent <NetworkIdentity>();

            serverObjectManager.HideForConnection(identity, player);

            player.Received().Send(Arg.Is <ObjectHideMessage>(msg => msg.netId == identity.NetId));

            // destroy GO after shutdown, otherwise isServer is true in OnDestroy and it tries to call
            // GameObject.Destroy (but we need DestroyImmediate in Editor)
            Object.Destroy(identity.gameObject);
        }
예제 #26
0
        public void SetUp()
        {
            networkServerGameObject = new GameObject();
            server = networkServerGameObject.AddComponent <NetworkServer>();
            serverObjectManager        = networkServerGameObject.AddComponent <ServerObjectManager>();
            serverObjectManager.Server = server;
            networkServerGameObject.AddComponent <NetworkClient>();

            gameObject      = new GameObject($"Test go {TestContext.CurrentContext.Test.Name}");
            identity        = gameObject.AddComponent <NetworkIdentity>();
            identity.Server = server;
            identity.ServerObjectManager = serverObjectManager;

            player1 = Substitute.For <INetworkPlayer>();
            player2 = Substitute.For <INetworkPlayer>();
        }
예제 #27
0
        /// <summary>
        /// Sets a player as not ready and removes all visible objects
        /// <para>Players that are not ready will not be sent spawn message or state updates.</para>
        /// <para>Players that are not ready do not receive spawned objects or state synchronization updates. They client can be made ready again by calling SetClientReady().</para>
        /// </summary>
        /// <param name="player">The player to make not ready.</param>
        public void SetClientNotReady(INetworkPlayer player)
        {
            ThrowIfNotServer();

            if (player.SceneIsReady)
            {
                if (logger.LogEnabled())
                {
                    logger.Log("PlayerNotReady " + player);
                }
                player.SceneIsReady = false;
                player.RemoveAllVisibleObjects();

                player.Send(new SceneNotReadyMessage());
            }
        }
예제 #28
0
 private void OnAuthResponseMessage(INetworkPlayer player, AuthResponseMessage msg)
 {
     if (msg.success)
     {
         if (logger.LogEnabled())
         {
             logger.LogFormat(LogType.Log, "Authentication Success: {0}", msg.message);
         }
         ClientAccept(player);
     }
     else
     {
         logger.LogFormat(LogType.Error, "Authentication Fail: {0}", msg.message);
         ClientReject(player);
     }
 }
예제 #29
0
        /// <summary>
        /// This replaces the player object for a connection with a different player object. The old player object is not destroyed.
        /// <para>If a connection already has a player object, this can be used to replace that object with a different player object. This does NOT change the ready state of the connection, so it can safely be used while changing scenes.</para>
        /// </summary>
        /// <param name="player">Connection which is adding the player.</param>
        /// <param name="identity">Player object spawned for the player.</param>
        /// <param name="keepAuthority">Does the previous player remain attached to this connection?</param>
        /// <returns></returns>
        public void ReplaceCharacter(INetworkPlayer player, NetworkIdentity identity, bool keepAuthority = false)
        {
            if (identity.Owner != null && identity.Owner != player)
            {
                throw new ArgumentException($"Cannot replace player for connection. New player is already owned by a different connection {identity}");
            }
            if (!player.HasCharacter)
            {
                throw new InvalidOperationException($"ReplaceCharacter can only be called if Player already has a charater");
            }

            //NOTE: there can be an existing player
            logger.Log("NetworkServer ReplacePlayer");

            var previousCharacter = player.Identity;

            player.Identity = identity;

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(player);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (player == Server.LocalPlayer)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Player.Identity = identity;
            }

            // add connection to observers AFTER the playerController was set.
            // by definition, there is nothing to observe if there is no player
            // controller.
            //
            // IMPORTANT: do this in AddCharacter & ReplaceCharacter!
            SpawnVisibleObjectForPlayer(player);

            if (logger.LogEnabled())
            {
                logger.Log($"Replacing playerGameObject object netId: {identity.NetId} asset ID {identity.PrefabHash:X}");
            }

            Respawn(identity);

            if (!keepAuthority)
            {
                previousCharacter.RemoveClientAuthority();
            }
        }
예제 #30
0
        /// <summary>
        /// <para>When an <see cref="AddCharacterMessage"/> message handler has received a request from a player, the server calls this to associate the player object with the connection.</para>
        /// <para>When a player is added for a connection, the client for that connection is made ready automatically. The player object is automatically spawned, so you do not need to call NetworkServer.Spawn for that object. This function is used for "adding" a player, not for "replacing" the player on a connection. If there is already a player on this playerControllerId for this connection, this will fail.</para>
        /// </summary>
        /// <param name="player">Connection which is adding the player.</param>
        /// <param name="client">Client associated to the player.</param>
        /// <param name="character">Player object spawned for the player.</param>
        /// <returns></returns>
        public bool AddCharacter(INetworkPlayer player, GameObject character)
        {
            NetworkIdentity identity = character.GetComponent <NetworkIdentity>();

            if (identity is null)
            {
                logger.Log("AddPlayer: playerGameObject has no NetworkIdentity. Please add a NetworkIdentity to " + character);
                return(false);
            }

            // cannot have a player object in "Add" version
            if (player.Identity != null)
            {
                logger.Log("AddPlayer: player object already exists");
                return(false);
            }

            // make sure we have a controller before we call SetClientReady
            // because the observers will be rebuilt only if we have a controller
            player.Identity = identity;

            // set server to the NetworkIdentity
            identity.Server = Server;
            identity.ServerObjectManager = this;
            identity.Client = Server.LocalClient;

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(player);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (player == Server.LocalPlayer)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Player.Identity = identity;
            }

            // set ready if not set yet
            SetClientReady(player);

            if (logger.LogEnabled())
            {
                logger.Log("Adding new playerGameObject object netId: " + identity.NetId + " asset ID " + identity.AssetId);
            }

            Respawn(identity);
            return(true);
        }