public void UpdateRPC(GameObject obj, NetworkRPC rpc) { NetworkObjectServerInfo info = obj.GetComponent <NetworkObjectServerInfo>(); if (info != null) { info.UpdateRPC(rpc); } }
public bool PlayerHasAuthority(GameObject obj, NetworkPlayer player) { if (obj != null) { NetworkObjectServerInfo info = obj.GetComponent <NetworkObjectServerInfo>(); if (info != null) { return(info.HasAuthority(player)); } } return(false); }
/// <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); } } } }
/// <summary> /// Initializes any networked objects that were already in the scene /// </summary> private void InitializeNetworkedObjects() { NetworkBehaviour[] networkObjects = FindObjectsOfType <NetworkBehaviour>(); foreach (NetworkBehaviour behaviour in networkObjects) { NetworkIdentity identity = behaviour.GetComponent <NetworkIdentity>(); if (identity == null) { continue; } if (NetworkManager.Instance.GetNetworkedObject(identity.m_NetworkId) != null) { continue; } AddObjectToNetwork(behaviour.gameObject); NetworkObjectServerInfo serverInfo = behaviour.gameObject.AddComponent <NetworkObjectServerInfo>(); serverInfo.m_PrefabIndex = -2; // Lets "spawn" the object on our side real fast ELogger.Log($"Spawning pre-existing networked object: {behaviour.gameObject.name}", ELogger.LogType.Server); } }
/// <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; } }