internal static void ChangeOwnership(ulong networkId, ulong clientId) { if (!NetworkingManager.Singleton.IsServer) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("You can only change ownership from Server"); } return; } NetworkedObject netObject = SpawnManager.SpawnedObjects[networkId]; for (int i = NetworkingManager.Singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects.Count - 1; i > -1; i--) { if (NetworkingManager.Singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects[i].NetworkId == networkId) { NetworkingManager.Singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects.RemoveAt(i); } } NetworkingManager.Singleton.ConnectedClients[clientId].OwnedObjects.Add(netObject); netObject.OwnerClientId = clientId; using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(networkId); writer.WriteUInt64Packed(clientId); InternalMessageHandler.Send(MLAPIConstants.MLAPI_CHANGE_OWNER, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, netObject); } } }
internal static void RemoveOwnership(NetworkedObject netObject) { if (!NetworkingManager.Singleton.IsServer) { throw new NotServerException("Only the server can change ownership"); } if (!netObject.IsSpawned) { throw new SpawnStateException("Object is not spawned"); } for (int i = NetworkingManager.Singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects.Count - 1; i > -1; i--) { if (NetworkingManager.Singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects[i] == netObject) { NetworkingManager.Singleton.ConnectedClients[netObject.OwnerClientId].OwnedObjects.RemoveAt(i); } } netObject._ownerClientId = null; using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(netObject.NetworkId); writer.WriteUInt64Packed(netObject.OwnerClientId); InternalMessageSender.Send(MLAPIConstants.MLAPI_CHANGE_OWNER, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, netObject); } } }
public void InvokeServerRPC(RPCDelegate method, Stream messageStream, byte channel = NetworkTransport.DEFAULT_CHANNEL) { if (!isClient) { //We are only a server and not a client Debug.LogError("Tried to invoke a ServerRPC without being a client. Only a client can invoke a server RPC.", this); return; } ulong hash = HashMethod(method.Method); using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(networkID); writer.WriteUInt64Packed(hash); stream.CopyFrom(messageStream); if (isHost) { messageStream.Position = 0; //Invoke local InvokeLocalServerRPC(hash, networkManager.clientID, stream); } else { MessageSender.Send(networkManager.serverID, m_NetworkBehaviourManager.serverRPCMessageType, channel, stream); } } } }
internal static void SendSpawnCallForObject(ulong clientId, NetworkedObject netObject, Stream payload) { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(netObject.IsPlayerObject); writer.WriteUInt64Packed(netObject.NetworkId); writer.WriteUInt64Packed(netObject.OwnerClientId); if (NetworkingManager.Singleton.NetworkConfig.UsePrefabSync) { writer.WriteUInt64Packed(netObject.PrefabHash); } else { writer.WriteBool(netObject.IsSceneObject == null ? true : netObject.IsSceneObject.Value); if (netObject.IsSceneObject == null || netObject.IsSceneObject.Value) { writer.WriteUInt64Packed(netObject.NetworkedInstanceId); } else { writer.WriteUInt64Packed(netObject.PrefabHash); } } writer.WriteBool(netObject.DestroyWithScene); writer.WriteSinglePacked(netObject.transform.position.x); writer.WriteSinglePacked(netObject.transform.position.y); writer.WriteSinglePacked(netObject.transform.position.z); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.x); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.y); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.z); writer.WriteBool(payload != null); if (payload != null) { writer.WriteInt32Packed((int)payload.Length); } if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar) { netObject.WriteNetworkedVarData(stream, clientId); } if (payload != null) { stream.CopyFrom(payload); } } InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_ADD_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null); } }
/// <inheritdoc /> public void WriteField(Stream stream) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(InternalValue.clientID); //BOX writer.WriteUInt64Packed(InternalValue.networkID); } }
internal static void WriteSpawnCallForObject(MLAPI.Serialization.BitStream stream, ulong clientId, NetworkedObject netObject, Stream payload) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(netObject.IsPlayerObject); writer.WriteUInt64Packed(netObject.NetworkId); writer.WriteUInt64Packed(netObject.OwnerClientId); if (NetworkingManager.Singleton.NetworkConfig.UsePrefabSync) { writer.WriteUInt64Packed(netObject.PrefabHash); } else { writer.WriteBool(netObject.IsSceneObject == null ? true : netObject.IsSceneObject.Value); if (netObject.IsSceneObject == null || netObject.IsSceneObject.Value) { writer.WriteUInt64Packed(netObject.NetworkedInstanceId); } else { writer.WriteUInt64Packed(netObject.PrefabHash); } } writer.WriteSinglePacked(netObject.transform.position.x); writer.WriteSinglePacked(netObject.transform.position.y); writer.WriteSinglePacked(netObject.transform.position.z); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.x); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.y); writer.WriteSinglePacked(netObject.transform.rotation.eulerAngles.z); writer.WriteBool(payload != null); if (payload != null) { writer.WriteInt32Packed((int)payload.Length); } if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar) { netObject.WriteNetworkedVarData(stream, clientId); } if (payload != null) { stream.CopyFrom(payload); } } }
internal static void HandleClientRPCRequest(ulong clientId, Stream stream, string channelName, SecuritySendFlags security) { using (PooledBitReader reader = PooledBitReader.Get(stream)) { ulong networkId = reader.ReadUInt64Packed(); ushort behaviourId = reader.ReadUInt16Packed(); ulong hash = reader.ReadUInt64Packed(); ulong responseId = reader.ReadUInt64Packed(); if (SpawnManager.SpawnedObjects.ContainsKey(networkId)) { NetworkedBehaviour behaviour = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(behaviourId); if (behaviour != null) { object result = behaviour.OnRemoteClientRPC(hash, clientId, stream); using (PooledBitStream responseStream = PooledBitStream.Get()) { using (PooledBitWriter responseWriter = PooledBitWriter.Get(responseStream)) { responseWriter.WriteUInt64Packed(responseId); responseWriter.WriteObjectPacked(result); } InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_CLIENT_RPC_RESPONSE, channelName, responseStream, security, null); } } } } }
internal void SendClientRPCPerformance(ulong hash, uint clientId, Stream messageStream, string channel, SecuritySendFlags security) { if (!IsServer && IsRunning) { //We are NOT a server. if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Only clients and host can invoke ClientRPC"); } return; } using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt32Packed(NetworkId); writer.WriteUInt16Packed(NetworkedObject.GetOrderIndex(this)); writer.WriteUInt64Packed(hash); stream.CopyFrom(messageStream); if (IsHost && clientId == NetworkingManager.Singleton.LocalClientId) { messageStream.Position = 0; InvokeClientRPCLocal(hash, NetworkingManager.Singleton.LocalClientId, messageStream); } else { InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_CLIENT_RPC, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, stream, security); } } } }
/// <summary> /// Hides a object from a specific client /// </summary> /// <param name="clientId">The client to hide the object for</param> public void NetworkHide(ulong clientId) { if (!IsSpawned) { throw new SpawnStateException("Object is not spawned"); } if (!NetworkingManager.Singleton.IsServer) { throw new NotServerException("Only server can change visibility"); } if (observers.Contains(clientId) && clientId != NetworkingManager.Singleton.ServerClientId) { // Send destroy call observers.Remove(clientId); using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(NetworkId); InternalMessageSender.Send(MLAPIConstants.MLAPI_DESTROY_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null); } } } }
/// <summary> /// Sends the named message /// </summary> /// <param name="name">The message name to send</param> /// <param name="clientIds">The clients to send to, sends to everyone if null</param> /// <param name="stream">The message stream containing the data</param> /// <param name="channel">The channel to send the data on</param> /// <param name="security">The security settings to apply to the message</param> public static void SendNamedMessage(string name, List <ulong> clientIds, Stream stream, string channel = null, SecuritySendFlags security = SecuritySendFlags.None) { ulong hash = NetworkedBehaviour.HashMethodName(name); using (PooledBitStream messageStream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(messageStream)) { writer.WriteUInt64Packed(hash); } messageStream.CopyFrom(stream); if (!NetworkingManager.Singleton.IsServer) { if (NetworkLog.CurrentLogLevel <= LogLevel.Error) { NetworkLog.LogWarning("Can not send named messages to multiple users as a client"); } return; } InternalMessageSender.Send(MLAPIConstants.MLAPI_NAMED_MESSAGE, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, clientIds, messageStream, security, null); } }
/// <summary> /// Hides a object from a specific client /// </summary> /// <param name="clientId">The client to hide the object for</param> public void NetworkHide(ulong clientId) { if (!NetworkingManager.Singleton.IsServer) { if (LogHelper.CurrentLogLevel <= LogLevel.Error) { LogHelper.LogError("Can only call NetworkHide on the server"); } return; } if (observers.Contains(clientId) && clientId != NetworkingManager.Singleton.ServerClientId) { // Send destroy call observers.Remove(clientId); using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(NetworkId); InternalMessageHandler.Send(MLAPIConstants.MLAPI_DESTROY_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null); } } } }
private void DoVisibleShowWrite(PooledBitStream stream, Stream spawnPayload) { if (!isServer) { throw new NotServerException("Only the server can change visibility of a Network Behaviour."); } if (!isNetworkSpawned) { throw new NetworkException("This Network Behaviour is not spawned on the network. Make sure this Network Behaviour is spawned using the NetworkBehaviour.SpawnOnNetwork function before changing it's visiblity."); } //Do message using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { //Write behaviour info and type writer.WriteUInt64Packed(networkID); writer.WriteUInt64Packed(ownerID); writer.WriteUInt64Packed(RPCTypeDefinition.GetHashFromType(GetType())); if (string.IsNullOrWhiteSpace(uniqueID)) { writer.WriteBool(false); } else { writer.WriteBool(true); writer.WriteUInt64Packed(m_UniqueHash); } writer.WriteBool(ownerCanUnspawn); writer.WriteBool(destroyOnUnspawn); //Write payload writer.WriteBool(spawnPayload != null); if (spawnPayload != null) { spawnPayload.Position = 0; writer.WriteInt32Packed((int)spawnPayload.Length); stream.CopyFrom(spawnPayload); } if (networkManager.enableLogging) { Debug.Log("Sending to clients the new behaviour " + GetType()); } } }
/// <summary> /// Gets a SHA256 hash of parts of the NetworkingConfiguration instance /// </summary> /// <param name="cache"></param> /// <returns></returns> public ulong GetConfig(bool cache = true) { if (ConfigHash != null && cache) { return(ConfigHash.Value); } Sort(); using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed(ProtocolVersion); writer.WriteString(MLAPIConstants.MLAPI_PROTOCOL_VERSION); for (int i = 0; i < Channels.Count; i++) { writer.WriteString(Channels[i].Name); writer.WriteByte((byte)Channels[i].Type); } if (EnableSceneSwitching) { for (int i = 0; i < RegisteredScenes.Count; i++) { writer.WriteString(RegisteredScenes[i]); } } if (HandleObjectSpawning && ForceSamePrefabs) { List <NetworkedPrefab> sortedPrefabList = NetworkedPrefabs.OrderBy(x => x.hash).ToList(); for (int i = 0; i < sortedPrefabList.Count; i++) { writer.WriteUInt64Packed(sortedPrefabList[i].hash); } } writer.WriteBool(ForceSamePrefabs); writer.WriteBool(HandleObjectSpawning); writer.WriteBool(EnableEncryption); writer.WriteBool(EnableSceneSwitching); writer.WriteBool(SignKeyExchange); writer.WriteBits((byte)RpcHashSize, 3); writer.WriteBits((byte)PrefabHashSize, 3); stream.PadStream(); if (cache) { ConfigHash = stream.ToArray().GetStableHash64(); return(ConfigHash.Value); } return(stream.ToArray().GetStableHash64()); } } }
public void InvokeClientRPC(RPCDelegate method, ulong clientID, Stream messageStream, byte channel = NetworkTransport.DEFAULT_CHANNEL) { if (!isServer) { //We are only a client Debug.LogError("Tried to invoke a ClientRPC without being the server. Only the server can invoke a client RPC.", this); return; } ulong hash = HashMethod(method.Method); using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(networkID); writer.WriteUInt64Packed(hash); stream.CopyFrom(messageStream); if (isHost && clientID == networkManager.clientID) { messageStream.Position = 0; //Invoke local InvokeLocalClientRPC(hash, networkManager.clientID, messageStream); } else { if (!IsNetworkVisibleTo(clientID)) { if (IsClientPendingSpawn(clientID)) { Debug.LogError("The target client ID '" + clientID + "' is still a pending observer and cannot invoke remote RPCs on it until this Network Behaviour is network visible to that client.", this); } else { Debug.LogError("The target client ID '" + clientID + "' is not an observer of this Network Behaviour.", this); } return; } MessageSender.Send(clientID, m_NetworkBehaviourManager.clientRPCMessageType, channel, stream); } } } }
public void InvokeClientRPCAllExcept(RPCDelegate method, ulong clientIDToIgnore, Stream messageStream, byte channel = NetworkTransport.DEFAULT_CHANNEL) { if (!isServer) { //We are only a client Debug.LogError("Tried to invoke a ClientRPC without being the server. Only the server can invoke a client RPC.", this); return; } ulong hash = HashMethod(method.Method); using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(networkID); writer.WriteUInt64Packed(hash); stream.CopyFrom(messageStream); using (HashSet <ulong> .Enumerator observers = GetObservers()) { while (observers.MoveNext()) { if (observers.Current == clientIDToIgnore) { continue; } if (observers.Current == networkManager.clientID && isHost) { //Invoke local messageStream.Position = 0; InvokeLocalClientRPC(hash, networkManager.clientID, messageStream); } //Send to remote observer MessageSender.Send(observers.Current, m_NetworkBehaviourManager.clientRPCMessageType, channel, stream); } } } } }
internal static void HandleClientRPCRequest(ulong clientId, Stream stream, string channelName, SecuritySendFlags security, Action <ulong> bufferCallback) { using (PooledBitReader reader = PooledBitReader.Get(stream)) { ulong networkId = reader.ReadUInt64Packed(); ushort behaviourId = reader.ReadUInt16Packed(); ulong hash = reader.ReadUInt64Packed(); ulong responseId = reader.ReadUInt64Packed(); if (SpawnManager.SpawnedObjects.ContainsKey(networkId)) { NetworkedBehaviour behaviour = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(behaviourId); if (behaviour == null) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("ClientRPCRequest message recieved for a non existant behaviour. NetworkId: " + networkId + ", behaviourIndex: " + behaviourId); } } else { object result = behaviour.OnRemoteClientRPC(hash, clientId, stream); using (PooledBitStream responseStream = PooledBitStream.Get()) { using (PooledBitWriter responseWriter = PooledBitWriter.Get(responseStream)) { responseWriter.WriteUInt64Packed(responseId); responseWriter.WriteObjectPacked(result); } InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_CLIENT_RPC_RESPONSE, channelName, responseStream, security, null); } } } else if (NetworkingManager.Singleton.IsServer || !NetworkingManager.Singleton.NetworkConfig.EnableMessageBuffering) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("ClientRPCRequest message recieved for a non existant object with id: " + networkId + ". This message is lost."); } } else { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("ClientRPCRequest message recieved for a non existant object with id: " + networkId + ". This message will be buffered and might be recovered."); } bufferCallback(networkId); } } }
/// <summary> /// Gets a SHA256 hash of parts of the NetworkingConfiguration instance /// </summary> /// <param name="cache"></param> /// <returns></returns> public ulong GetConfig(bool cache = true) { if (ConfigHash != null && cache) { return(ConfigHash.Value); } Sort(); using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed(ProtocolVersion); writer.WriteString(MLAPIConstants.MLAPI_PROTOCOL_VERSION); if (EnableSceneManagement && !AllowRuntimeSceneChanges) { for (int i = 0; i < RegisteredScenes.Count; i++) { writer.WriteString(RegisteredScenes[i]); } } if (ForceSamePrefabs) { List <NetworkedPrefab> sortedPrefabList = NetworkedPrefabs.OrderBy(x => x.Hash).ToList(); for (int i = 0; i < sortedPrefabList.Count; i++) { writer.WriteUInt64Packed(sortedPrefabList[i].Hash); } } writer.WriteBool(EnableNetworkedVar); writer.WriteBool(ForceSamePrefabs); writer.WriteBool(UsePrefabSync); writer.WriteBool(EnableSceneManagement); writer.WriteBool(EnsureNetworkedVarLengthSafety); writer.WriteBool(EnableEncryption); writer.WriteBool(SignKeyExchange); writer.WriteBits((byte)RpcHashSize, 2); stream.PadStream(); if (cache) { ConfigHash = stream.ToArray().GetStableHash64(); return(ConfigHash.Value); } return(stream.ToArray().GetStableHash64()); } } }
private void DoOwnershipWrite(PooledBitStream stream, ulong newOwner) { //Do message using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { //Write behaviour info and type writer.WriteUInt64Packed(networkID); writer.WriteUInt64Packed(newOwner); writer.WriteBool(ownerCanUnspawn); if (networkManager.enableLogging) { if (isServer) { Debug.Log("Sending to clients the ownership change."); } else { Debug.Log("Sending to the server the ownership change."); } } } }
private void SendConnectionRequest() { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(config.GetConfig()); //if (NetworkConfig.ConnectionApproval) // writer.WriteByteArray(NetworkConfig.ConnectionData); } MessageSender.Send(serverID, MessageType.NETWORK_CONNECTION_REQUEST, networkInternalChannel, stream); } }
public void Write(Stream stream) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBit(HasStarted); writer.WritePadBits(); writer.WriteInt32Packed(TeamWithPossession); writer.WriteUInt64Packed(PlayerWithBall); foreach (TeamData team in Teams) { team.Write(stream); } } }
public void Write(PooledBitWriter writer) { writer.WriteSinglePacked(timestamp); writer.WriteSinglePacked(position.x); writer.WriteSinglePacked(position.y); writer.WriteSinglePacked(position.z); writer.WriteSinglePacked(rotation.eulerAngles.x); writer.WriteSinglePacked(rotation.eulerAngles.y); writer.WriteSinglePacked(rotation.eulerAngles.z); writer.WriteUInt64Packed(parentId); writer.WriteInt32Packed(movingObjectId); }
/// <summary> /// Sends a named message /// </summary> /// <param name="name">The message name to send</param> /// <param name="clientId">The client to send the message to</param> /// <param name="stream">The message stream containing the data</param> /// <param name="channel">The channel tos end the data on</param> /// <param name="security">The security settings to apply to the message</param> public static void SendNamedMessage(string name, ulong clientId, Stream stream, string channel = null, SecuritySendFlags security = SecuritySendFlags.None) { ulong hash = NetworkedBehaviour.HashMethodName(name); using (PooledBitStream messageStream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(messageStream)) { writer.WriteUInt64Packed(hash); } messageStream.CopyFrom(stream); InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_NAMED_MESSAGE, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, messageStream, security, null); } }
public void WriteSyncTeamSlots() { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteInt32Packed(id); writer.WriteInt32Packed(teamSlots.Count); foreach (var pair in teamSlots) { writer.WriteInt32Packed(pair.Key); writer.WriteUInt64Packed(pair.Value.NetworkId); } GameManager.Singleton.InvokeClientRpcOnEveryone(GameManager.Singleton.ClientSyncTeamSlots, stream); } } }
internal static void HandleServerRPCRequest(ulong clientId, Stream stream, string channelName, SecuritySendFlags security) { using (PooledBitReader reader = PooledBitReader.Get(stream)) { ulong networkId = reader.ReadUInt64Packed(); ushort behaviourId = reader.ReadUInt16Packed(); ulong hash = reader.ReadUInt64Packed(); ulong responseId = reader.ReadUInt64Packed(); if (SpawnManager.SpawnedObjects.ContainsKey(networkId)) { NetworkedBehaviour behaviour = SpawnManager.SpawnedObjects[networkId].GetBehaviourAtOrderIndex(behaviourId); if (behaviour == null) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("ServerRPCRequest message recieved for a non existant behaviour. NetworkId: " + networkId + ", behaviourIndex: " + behaviourId); } } else { object result = behaviour.OnRemoteServerRPC(hash, clientId, stream); using (PooledBitStream responseStream = PooledBitStream.Get()) { using (PooledBitWriter responseWriter = PooledBitWriter.Get(responseStream)) { responseWriter.WriteUInt64Packed(responseId); responseWriter.WriteObjectPacked(result); } InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_SERVER_RPC_RESPONSE, channelName, responseStream, security, SpawnManager.SpawnedObjects[networkId]); } } } else { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("ServerRPCRequest message recieved for a non existant object with id: " + networkId + ". This message is lost."); } } } }
/// <summary> /// Hides a list of objects from a client /// </summary> /// <param name="networkedObjects">The objects to hide</param> /// <param name="clientId">The client to hide the objects from</param> public static void NetworkHide(List <NetworkedObject> networkedObjects, ulong clientId) { if (!NetworkingManager.Singleton.IsServer) { throw new NotServerException("Only server can change visibility"); } if (clientId == NetworkingManager.Singleton.ServerClientId) { throw new VisibilityChangeException("Cannot hide an object from the server"); } // Do the safety loop first to prevent putting the MLAPI in an invalid state. for (int i = 0; i < networkedObjects.Count; i++) { if (!networkedObjects[i].IsSpawned) { throw new SpawnStateException("Object is not spawned"); } if (!networkedObjects[i].observers.Contains(clientId)) { throw new VisibilityChangeException("NetworkedObject with NetworkId: " + networkedObjects[i].NetworkId + " is already hidden"); } } using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed((ushort)networkedObjects.Count); for (int i = 0; i < networkedObjects.Count; i++) { // Send destroy call networkedObjects[i].observers.Remove(clientId); writer.WriteUInt64Packed(networkedObjects[i].NetworkId); } } InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_DESTROY_OBJECTS, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null); } }
public void PongPerformance(ulong clientId, Stream stream) { ulong serverClientId = 0; using (PooledBitReader reader = PooledBitReader.Get(stream)) { serverClientId = reader.ReadUInt64Packed(); } using (PooledBitStream responseStream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(responseStream)) { writer.WriteUInt64Packed(serverClientId); InvokeServerRpcPerformance(ServerRPCPerformance, responseStream); } } Debug.Log("serverClientId: " + serverClientId + " clientId: " + clientId); // InvokeServerRpc(ServerRPC, clientId); }
//Unity SceneManager load event callback private void OnSceneLoad(Scene scene, LoadSceneMode loadSceneMode) { if (networkManager.isServer) { if (!networkManager.config.serverSendSceneEvents) { return; } using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(true); //Is Loading writer.WriteBool(loadSceneMode == LoadSceneMode.Additive); //Is Additive? writer.WriteUInt64Packed(scene.name.GetStableHash(NetworkManager.Get().config.rpcHashSize)); MessageSender.SendToAll(sceneChangeMessageType, networkManager.networkInternalChannel, stream); } } } else if (networkManager.isClient) { if (!networkManager.config.clientSendSceneEvents) { return; } using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(true); //Is Loading writer.WriteBool(loadSceneMode == LoadSceneMode.Additive); //Is Additive? writer.WriteUInt64Packed(scene.name.GetStableHash(NetworkManager.Get().config.rpcHashSize)); MessageSender.Send(networkManager.serverID, sceneChangeMessageType, networkManager.networkInternalChannel, stream); } } } }
private void ExecutePing() { foreach (NetworkedClient client in NetworkingManager.Singleton.ConnectedClientsList) { if (client.ClientId != NetworkingManager.Singleton.ServerClientId) { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(client.ClientId); InvokeClientRpcOnClientPerformance(PongPerformance, client.ClientId, stream); } } sendTimes.Add(client.ClientId, stopwatch.ElapsedMilliseconds); // InvokeClientRpcOnClient(Pong, client.ClientId, client.ClientId); } } currentPingRound++; }
///<summary> /// Called when the client successfully connects Network Behaviours. Involves switching pending Network Behaviours to active and sending the server a success message. /// Client only. ///</summary> private void OnObjectConnectSuccess(NetworkBehaviourReference behaviourReference, ulong networkID, ulong ownerID, bool ownerCanUnspawn, bool destroyOnUnspawn, Stream spawnPayload) { m_NetworkBehaviours.Add(behaviourReference); m_NetworkBehaviourDictionary.Add(networkID, behaviourReference); //Send confirm connection using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(networkID); if (networkManager.enableLogging) { Debug.Log("Sending success of add object with Network ID: " + networkID); } } MessageSender.Send(networkManager.serverID, objectSuccessMessageType, networkManager.networkInternalChannel, stream); } //Let our local behaviour know behaviourReference.connectedClientCallback.Invoke(networkID, ownerID, ownerCanUnspawn, destroyOnUnspawn, spawnPayload); }
private void DoVisibleHideWrite(PooledBitStream stream) { if (!isServer) { throw new NotServerException("Only the server can change visibility of a Network Behaviour."); } if (!isNetworkSpawned) { throw new NetworkException("This Network Behaviour is not spawned on the network. Make sure this Network Behaviour is spawned using the NetworkBehaviour.SpawnOnNetwork function before changing it's visiblity."); } //Do message using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt64Packed(networkID); writer.WriteBool(destroyOnUnspawn); if (networkManager.enableLogging) { Debug.Log("Sending to clients an unspawn message for '" + GetType() + "'."); } } }