/// <summary> /// Updates a player to the most recent entity list /// </summary> private void UpdatePlayer(NetworkPlayer player) { if (IsPlayerServer(player)) { return; } foreach (var pair in NetworkManager.Instance.GetNetworkedObjects()) { GameObject obj = pair.Value; if (obj == null) { continue; } NetworkObjectServerInfo info = obj.GetComponent <NetworkObjectServerInfo>(); NetworkIdentity identity = obj.GetComponent <NetworkIdentity>(); NetworkSpawnRPC spawnRPC = new NetworkSpawnRPC(info.m_PrefabIndex, false, identity.m_NetworkId); SendRPC(spawnRPC, player); // Spawn it if (!info.HasAuthority(player) && !IsPlayerServer(player)) { NetworkAuthorizationRPC authRPC = new NetworkAuthorizationRPC( true, false, false, identity.m_NetworkId ); SendRPC(authRPC, player); } foreach (var type in info.m_RPCTypes) // Update any extra RPC's the object may have { NetworkRPC rpc = info.GetRPC(type); if (rpc != null) { SendRPC(rpc, player); } } } }
public override void OnReceiveData(NetworkFrame frame, IPEndPoint point, byte[] bytes) { base.OnReceiveData(frame, point, bytes); NetworkPlayer player = NetworkManager.Instance.GetPlayer(frame.m_SenderId); if (!IsUserAuthorized(frame.m_SenderId) && frame.m_Type != NetworkFrame.NetworkFrameType.Authentication) { return; } switch (frame.m_Type) { case NetworkFrame.NetworkFrameType.Handshake: { NetworkHandshakeFrame handshake = NetworkFrame.Parse <NetworkHandshakeFrame>(bytes); player = NetworkManager.Instance.AddPlayer(handshake.m_SenderId, new NetworkPlayer() { m_Id = handshake.m_SenderId, m_Name = handshake.m_DisplayName }); NetworkSpawnRPC spawnRpc = new NetworkSpawnRPC(-1, true); OnRPCCommand(player, spawnRpc.ToString()); UpdatePlayer(player); } break; case NetworkFrame.NetworkFrameType.Authentication: // TODO: Clean this? Its terrible lol { NetworkAuthenticationFrame authenticationFrame = NetworkFrame.Parse <NetworkAuthenticationFrame>(bytes); if (m_Password != "" && m_Password != null && authenticationFrame.m_Password != m_Password) { Debug.Log(m_Password); authenticationFrame.m_Response = NetworkAuthenticationFrame.NetworkAuthenticationResponse.IncorrectPassword; } else if (NetworkManager.Instance.GetPlayerCount() == NetworkManager.Instance.m_Settings.m_MaxPlayers && NetworkManager.Instance.m_Settings.m_MaxPlayers > 0) { authenticationFrame.m_Response = NetworkAuthenticationFrame.NetworkAuthenticationResponse.LobbyFull; } else { Debug.Log("bop"); m_AuthorizedUsers.Add(frame.m_SenderId); authenticationFrame.m_Response = NetworkAuthenticationFrame.NetworkAuthenticationResponse.Connected; } authenticationFrame.m_TargetId = authenticationFrame.m_SenderId; authenticationFrame.m_SenderId = "server"; QueueFrame(authenticationFrame); } break; case NetworkFrame.NetworkFrameType.Ping: { NetworkFrame pingFrame = new NetworkFrame(NetworkFrame.NetworkFrameType.Ping, "server", frame.m_SenderId); QueueFrame(pingFrame); } break; case NetworkFrame.NetworkFrameType.RPC: { NetworkRPCFrame rpcFrame = NetworkFrame.Parse <NetworkRPCFrame>(bytes); OnRPCCommand(player, rpcFrame.m_RPC); } break; case NetworkFrame.NetworkFrameType.Heartbeat: { if (m_Heartbeats.ContainsKey(frame.m_SenderId)) { m_Heartbeats[frame.m_SenderId] = 0; } else { m_Heartbeats.Add(frame.m_SenderId, 0); } } break; } }
/// <summary> /// Triggers an RPC command on the server /// </summary> /// <param name="command">The raw json command</param> public virtual void OnRPCCommand(NetworkPlayer player, string command) { NetworkRPC rpc = NetworkRPC.FromString(command); switch (rpc.m_Type) { case NetworkRPCType.RPC_LIB_SPAWN: // TODO: Clean this up if at all possible? { NetworkSpawnRPC spawnRPC = NetworkRPC.Parse <NetworkSpawnRPC>(command); GameObject spawnPrefab = NetworkManager.Instance.GetObjectByIndex(spawnRPC.m_PrefabIndex); GameObject prefab = Instantiate(spawnPrefab); NetworkBehaviour networkBehaviour = prefab.GetComponent <NetworkBehaviour>(); NetworkObjectServerInfo serverInfo = prefab.AddComponent <NetworkObjectServerInfo>(); int id = AddObjectToNetwork(prefab); spawnRPC.m_NetworkId = id; networkBehaviour.m_Spawner = (spawnRPC.m_PrefabIndex == -1) ? id : player.m_NetworkId; serverInfo.m_PrefabIndex = spawnRPC.m_PrefabIndex; SendRPC(spawnRPC, player); if (spawnRPC.m_PrefabIndex == -1) { player.m_NetworkId = id; NetworkPlayerConnectRPC connectRPC = new NetworkPlayerConnectRPC(player, -1); SendRPCAll(connectRPC); OnPlayerConnected(player); } if (spawnRPC.m_RequestAuthority) { serverInfo.AddAuthority(player); } NetworkAuthorizationRPC authRPC = new NetworkAuthorizationRPC(true, IsPlayerServer(player), spawnRPC.m_RequestAuthority, id); SendRPC(authRPC, player); OnNetworkObjectCreated(prefab, player); } break; case NetworkRPCType.RPC_LIB_DESTROY: { GameObject obj = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (PlayerHasAuthority(obj, player)) { OnNetworkObjectDestroyed(obj, player); Destroy(obj); SendRPCAll(rpc); } } break; case NetworkRPCType.RPC_LIB_TRANSFORM: { NetworkTransformRPC transformRPC = NetworkRPC.Parse <NetworkTransformRPC>(command); GameObject obj = NetworkManager.Instance.GetNetworkedObject(transformRPC.m_NetworkId); if (PlayerHasAuthority(obj, player)) { // Do any checks on the data here, such as being out of bounds, etc if (!IsPlayerServer(player)) // We dont need to update info we already have { obj.transform.position = transformRPC.m_Position; obj.transform.eulerAngles = transformRPC.m_Rotation; obj.transform.localScale = transformRPC.m_Scale; } UpdateRPC(obj, transformRPC); SendRPCAll(transformRPC, new List <string>() { player.m_Id }); // Probably should add a exclude to this so we dont send it to ourselves? Idk } } break; case NetworkRPCType.RPC_LIB_DISCONNECTED: { NetworkPlayerDisconnctRPC disconnctRPC = NetworkRPC.Parse <NetworkPlayerDisconnctRPC>(command); if (disconnctRPC.m_Player.m_Id == player.m_Id) { // Disconnection checks? RemovePlayer(player, disconnctRPC.m_Reason, disconnctRPC.m_DisconnectType, true); } else { // Authoratative admin checks later : TODO // This is literally terrible, this would just kick the player who is trying to kick. // Make a proper "kick" rpc or add some property into the disconnect rpc RemovePlayer(player, $"Kicked by: {player.m_Name}", NetworkDisconnectType.Kick, true); } } break; } }
public void OnFireGun() { NetworkSpawnRPC spawnRPC = new NetworkSpawnRPC(0); NetworkClient.Instance.SendRPC(spawnRPC); }
/// <summary> /// Send a RPC command to a specified network id /// </summary> /// <param name="rpc">The RPC being sent throughout the network</param> public void OnRPCCommand(string content) { NetworkRPC rpc = NetworkRPC.FromString(content); switch (rpc.m_Type) // If a type is handled here its because it needs to be here, or the networking wont function properly { case NetworkRPCType.RPC_LIB_SPAWN: { if (NetworkManager.Instance.IsMixed()) { break; // We already have it spawned for us } NetworkSpawnRPC spawnRPC = NetworkRPC.Parse <NetworkSpawnRPC>(content); if (NetworkManager.Instance.GetNetworkedObject(spawnRPC.m_NetworkId) != null) { break; } GameObject spawnPrefab = NetworkManager.Instance.GetObjectByIndex(spawnRPC.m_PrefabIndex); if (spawnPrefab == null) { break; } GameObject prefab = Instantiate(spawnPrefab); NetworkBehaviour networkBehaviour = prefab.GetComponent <NetworkBehaviour>(); networkBehaviour.m_IsServer = false; networkBehaviour.m_HasAuthority = false; networkBehaviour.m_IsClient = true; prefab.GetComponent <NetworkIdentity>().m_NetworkId = spawnRPC.m_NetworkId; NetworkManager.Instance.AddObject(spawnRPC.m_NetworkId, prefab); } break; case NetworkRPCType.RPC_LIB_OBJECT_NETAUTH: { NetworkAuthorizationRPC authorizationRPC = NetworkRPC.Parse <NetworkAuthorizationRPC>(content); GameObject gameObject = NetworkManager.Instance.GetNetworkedObject(authorizationRPC.m_NetworkId); if (gameObject != null) { NetworkBehaviour networkBehaviour = gameObject.GetComponent <NetworkBehaviour>(); networkBehaviour.m_IsClient = authorizationRPC.m_LocalSet; networkBehaviour.m_HasAuthority = authorizationRPC.m_LocalAuthSet; networkBehaviour.m_IsServer = authorizationRPC.m_ServerSet; gameObject.GetComponent <NetworkIdentity>().m_NetworkId = authorizationRPC.m_NetworkId; networkBehaviour.OnAuthorityChanged(networkBehaviour.m_HasAuthority); } } break; case NetworkRPCType.RPC_LIB_DESTROY: { GameObject gameObject = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (gameObject != null) { Destroy(gameObject); } } break; case NetworkRPCType.RPC_LIB_TRANSFORM: { if (NetworkManager.Instance.IsMixed()) { break; // We are sort of server, so we have most up to date value } NetworkTransformRPC transformRPC = NetworkRPC.Parse <NetworkTransformRPC>(content); GameObject obj = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (obj != null) { obj.transform.position = transformRPC.m_Position; obj.transform.eulerAngles = transformRPC.m_Rotation; obj.transform.localScale = transformRPC.m_Scale; } } break; case NetworkRPCType.RPC_LIB_CONNECTED: { NetworkPlayerConnectRPC connectRPC = NetworkRPC.Parse <NetworkPlayerConnectRPC>(content); ELogger.Log($"Player Connected: {connectRPC.m_Player.m_Name}", ELogger.LogType.Client); NetworkManager.Instance.AddPlayer(connectRPC.m_Player.m_Id, connectRPC.m_Player); foreach (var networkPair in NetworkManager.Instance.GetNetworkedObjects()) { if (networkPair.Value != null) { NetworkBehaviour networkBehaviour = networkPair.Value.GetComponent <NetworkBehaviour>(); if (networkBehaviour != null) { networkBehaviour.OnPlayerJoined(connectRPC.m_Player); } } } } break; case NetworkRPCType.RPC_LIB_DISCONNECTED: { NetworkPlayerDisconnctRPC disconnectRPC = NetworkRPC.Parse <NetworkPlayerDisconnctRPC>(content); NetworkManager.Instance.RemovePlayer(disconnectRPC.m_Player.m_Id); foreach (var networkPair in NetworkManager.Instance.GetNetworkedObjects()) { if (networkPair.Value != null) { NetworkBehaviour networkBehaviour = networkPair.Value.GetComponent <NetworkBehaviour>(); if (networkBehaviour != null) { networkBehaviour.OnPlayerDisconnected(disconnectRPC.m_Player, disconnectRPC.m_DisconnectType, disconnectRPC.m_Reason); } } } if (disconnectRPC.m_Player.m_Id == GetUniqueIndentifier()) { ELogger.Log($"We were disconnected for reason '{disconnectRPC.m_Reason}' with type {disconnectRPC.m_Type}|{disconnectRPC.m_DisconnectType}", ELogger.LogType.Client); Clean(); UnityEditor.EditorApplication.isPlaying = false; } else { ELogger.Log($"Player Disonnected: {disconnectRPC.m_Player.m_Name}", ELogger.LogType.Client); } } break; default: { GameObject obj = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (obj != null) { NetworkBehaviour behaviour = obj.GetComponent <NetworkBehaviour>(); if (behaviour != null) { behaviour.OnRPCCommand(content); } } } break; } }