/// <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; using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteString(protocalVersion); writer.WriteBool(enableNetworkedVar); writer.WriteBool(ensureNetworkedVarLengthSafety); writer.WriteBits((byte)rpcHashSize, 3); stream.PadStream(); if (cache) { ConfigHash = stream.ToArray().GetStableHash64(); return ConfigHash.Value; } return stream.ToArray().GetStableHash64(); } } }
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); } }
/// <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()); } } }
/// <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 && RequireNetworkedPrefabsAreSyncronized) { for (int i = 0; i < NetworkedPrefabs.Count; i++) { writer.WriteString(NetworkedPrefabs[i].name); } } writer.WriteBool(HandleObjectSpawning); writer.WriteBool(EnableEncryption); writer.WriteBool(EnableSceneSwitching); writer.WriteBool(SignKeyExchange); writer.WriteBits((byte)AttributeMessageMode, 3); // Returns a 160 bit / 20 byte / 5 int checksum of the config if (cache) { ConfigHash = stream.ToArray().GetStableHash64(); return(ConfigHash.Value); } return(stream.ToArray().GetStableHash64()); } } }
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); } } }
private void OnLog(string condition, string stackTrace, LogType logType) { //DO NOT CALL Debug.Log in this function or it will cause an infinite loop! //Wait until this network is ready to log. if (!sendLogEvents || !networkManager.isRunning || (!networkManager.isServer && !networkManager.isConnected)) { return; } using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteString(condition); writer.WriteBool(includeStacktrace); if (includeStacktrace) { writer.WriteString(stackTrace); } writer.WriteByte((byte)logType); if (networkManager.isServer) { //Send to all clients that are expecting it. MessageSender.SendToSpecific(m_ClientsReceivingLogEvents, networkLogMessageType, "NETWORK_INTERNAL", stream); } else { //Send to server MessageSender.Send(networkManager.serverID, networkLogMessageType, networkManager.networkInternalChannel, stream); } } } }
//private void FixedUpdate() //{ //} private void Fire() { Vector3 firePosition = m_cameraFOV.transform.position; Vector3 fireDirection = m_cameraFOV.transform.forward; // Do server side hit detection only when there is a hit on client side. Just to save some server performance bool shouldVerifyHitOnServer = true; if (IVGameManager.Instance.m_useHitScan) { shouldVerifyHitOnServer = FireHitScan(firePosition, fireDirection); } else { shouldVerifyHitOnServer = InstantiateBullet(firePosition, fireDirection); // Instantiate bullet immediately on the client who is firing } using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(shouldVerifyHitOnServer); writer.WriteVector3Packed(firePosition); writer.WriteVector3Packed(fireDirection); InvokeServerRpcPerformance(FireOnServer, stream); } } }
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> /// Returns a base64 encoded version of the config /// </summary> /// <returns></returns> public string ToBase64() { NetworkConfig config = this; using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed(config.ProtocolVersion); writer.WriteUInt16Packed((ushort)config.RegisteredScenes.Count); for (int i = 0; i < config.RegisteredScenes.Count; i++) { writer.WriteString(config.RegisteredScenes[i]); } writer.WriteInt32Packed(config.ReceiveTickrate); writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate); writer.WriteInt32Packed(config.SendTickrate); writer.WriteInt32Packed(config.EventTickrate); writer.WriteInt32Packed(config.ClientConnectionBufferTimeout); writer.WriteBool(config.ConnectionApproval); writer.WriteInt32Packed(config.SecondsHistory); writer.WriteBool(config.EnableEncryption); writer.WriteBool(config.SignKeyExchange); writer.WriteInt32Packed(config.LoadSceneTimeOut); writer.WriteBool(config.EnableTimeResync); writer.WriteBool(config.EnsureNetworkedVarLengthSafety); writer.WriteBits((byte)config.RpcHashSize, 3); writer.WriteBool(ForceSamePrefabs); writer.WriteBool(UsePrefabSync); writer.WriteBool(RecycleNetworkIds); writer.WriteSinglePacked(NetworkIdRecycleDelay); writer.WriteBool(EnableNetworkedVar); writer.WriteBool(AllowRuntimeSceneChanges); stream.PadStream(); return(Convert.ToBase64String(stream.ToArray())); } } }
/// <summary> /// Writes the TickEvent data to the stream /// </summary> /// <param name="stream">The stream to write the TickEvent data to</param> public void SerializeToStream(Stream stream) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteByte((byte)EventType); writer.WriteUInt32Packed(Bytes); writer.WriteStringPacked(ChannelName); writer.WriteStringPacked(MessageType); writer.WriteBool(Closed); } }
//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); } } } }
/// <summary> /// Returns a base64 encoded version of the config /// </summary> /// <returns></returns> public string ToBase64() { NetworkConfig config = this; using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed(config.ProtocolVersion); writer.WriteBits((byte)config.Transport, 5); writer.WriteUInt16Packed((ushort)config.Channels.Count); for (int i = 0; i < config.Channels.Count; i++) { writer.WriteString(config.Channels[i].Name); writer.WriteBits((byte)config.Channels[i].Type, 5); } writer.WriteUInt16Packed((ushort)config.RegisteredScenes.Count); for (int i = 0; i < config.RegisteredScenes.Count; i++) { writer.WriteString(config.RegisteredScenes[i]); } writer.WriteUInt16Packed((ushort)config.NetworkedPrefabs.Count); for (int i = 0; i < config.NetworkedPrefabs.Count; i++) { writer.WriteBool(config.NetworkedPrefabs[i].playerPrefab); writer.WriteString(config.NetworkedPrefabs[i].name); } writer.WriteInt32Packed(config.MessageBufferSize); writer.WriteInt32Packed(config.ReceiveTickrate); writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate); writer.WriteInt32Packed(config.SendTickrate); writer.WriteInt32Packed(config.EventTickrate); writer.WriteInt32Packed(config.MaxConnections); writer.WriteInt32Packed(config.ConnectPort); writer.WriteString(config.ConnectAddress); writer.WriteInt32Packed(config.ClientConnectionBufferTimeout); writer.WriteBool(config.ConnectionApproval); writer.WriteInt32Packed(config.SecondsHistory); writer.WriteBool(config.HandleObjectSpawning); writer.WriteBool(config.EnableEncryption); writer.WriteBool(config.SignKeyExchange); writer.WriteBool(config.EnableSceneSwitching); writer.WriteInt32Packed(config.LoadSceneTimeOut); writer.WriteBool(config.EnableTimeResync); writer.WriteBits((byte)config.RpcHashSize, 3); stream.PadStream(); return(Convert.ToBase64String(stream.ToArray())); } } }
/// <summary> /// Returns a base64 encoded version of the config /// </summary> /// <returns></returns> public string ToBase64() { NetworkConfig config = this; using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteString(config.protocalVersion); writer.WriteInt32Packed(config.receiveTickrate); writer.WriteInt32Packed(config.maxReceiveEventsPerTickRate); writer.WriteInt32Packed(config.eventTickrate); writer.WriteInt32Packed(config.clientConnectionBufferTimeout); writer.WriteInt32Packed(config.secondsHistory); writer.WriteBool(config.enableTimeResync); writer.WriteBool(config.ensureNetworkedVarLengthSafety); writer.WriteBits((byte)config.rpcHashSize, 3); writer.WriteBool(recycleNetworkIDs); writer.WriteSinglePacked(networkIDRecycleDelay); writer.WriteBool(enableNetworkedVar); writer.WriteBool(clientSendSceneEvents); writer.WriteBool(serverSendSceneEvents); stream.PadStream(); return Convert.ToBase64String(stream.ToArray()); } } }
/// <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()); } } }
/// <summary> /// Send a message to the target client ID whether they should send logs to this client. If this build is a client (not server) and is not allowed to toggle on the server, it will fail silently. /// Cannot target other clients if this build is a client (not server). /// </summary> /// <param name="clientID"></param> /// <param name="sendLogs"></param> /// <param name="includeStacktraceInMessage"></param> public void ToggleRemoteTarget(ulong clientID, bool sendLogs, bool includeStacktraceInMessage) { if (networkManager.isServer) { if (clientID == networkManager.serverID) { sendLogEvents = sendLogs; includeStacktrace = includeStacktraceInMessage; return; } bool IsClient(ulong ID) { using (List <ulong> .Enumerator clients = networkManager.clients) { while (clients.MoveNext()) { if (clients.Current == clientID) { return(true); } } } return(false); } if (!IsClient(clientID)) { Debug.LogError("Tried to toggle remote target for sending logs but the client ID '" + clientID + "' is not in the connected clients list."); return; } } else { if (clientID != networkManager.serverID) { Debug.LogError("Clients can only toggle network logs for the server. Tried to toggle non-server client ID '" + clientID + "'."); return; } } using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(sendLogs); MessageSender.Send(clientID, networkToggleLogMessageType, networkManager.networkInternalChannel, stream); } } }
internal static void WriteNetworkedVarData(List <INetworkedVar> networkedVarList, PooledBitWriter writer, Stream stream, uint clientId) { if (networkedVarList.Count == 0) { return; } for (int j = 0; j < networkedVarList.Count; j++) { bool canClientRead = networkedVarList[j].CanClientRead(clientId); writer.WriteBool(canClientRead); if (canClientRead) { networkedVarList[j].WriteField(stream); } } }
private void WriteParameters(Stream stream, bool autoSend) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { if (animatorParameters == null) { animatorParameters = animator.parameters; } for (int i = 0; i < animatorParameters.Length; i++) { if (autoSend && !GetParameterAutoSend(i)) { continue; } AnimatorControllerParameter par = animatorParameters[i]; if (par.type == AnimatorControllerParameterType.Int) { writer.WriteUInt32Packed((uint)animator.GetInteger(par.nameHash)); SetSendTrackingParam(par.name + ":" + animator.GetInteger(par.nameHash), i); } if (par.type == AnimatorControllerParameterType.Float) { writer.WriteSinglePacked(animator.GetFloat(par.nameHash)); SetSendTrackingParam(par.name + ":" + animator.GetFloat(par.nameHash), i); } if (par.type == AnimatorControllerParameterType.Bool) { writer.WriteBool(animator.GetBool(par.nameHash)); SetSendTrackingParam(par.name + ":" + animator.GetBool(par.nameHash), i); } } } }
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."); } } } }
internal void WriteNetworkedVarData(Stream stream, uint clientId) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { for (int i = 0; i < childNetworkedBehaviours.Count; i++) { childNetworkedBehaviours[i].NetworkedVarInit(); if (childNetworkedBehaviours[i].networkedVarFields.Count == 0) { continue; } for (int j = 0; j < childNetworkedBehaviours[i].networkedVarFields.Count; j++) { bool canClientRead = childNetworkedBehaviours[i].networkedVarFields[j].CanClientRead(clientId); writer.WriteBool(canClientRead); if (canClientRead) { childNetworkedBehaviours[i].networkedVarFields[j].WriteField(stream); } } } } }
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() + "'."); } } }
internal static void SpawnObject(NetworkedObject netObject, uint?clientOwnerId = null, Stream payload = null, bool destroyWithScene = false) { if (netObject.isSpawned) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Object already spawned"); } return; } else if (!netManager.isServer) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Only server can spawn objects"); } return; } else if (SpawnManager.GetNetworkedPrefabIndexOfName(netObject.NetworkedPrefabName) == -1) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("The prefab name " + netObject.NetworkedPrefabName + " does not exist as a networkedPrefab"); } return; } else if (!netManager.NetworkConfig.HandleObjectSpawning) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("NetworkConfig is set to not handle object spawning"); } return; } uint netId = GetNetworkObjectId(); netObject.NetworkId = netId; SpawnedObjects.Add(netId, netObject); SpawnedObjectsList.Add(netObject); netObject.isSpawned = true; netObject.destroyWithScene = destroyWithScene; netObject.sceneSpawnedInIndex = NetworkSceneManager.CurrentActiveSceneIndex; if (clientOwnerId != null) { netObject.OwnerClientId = clientOwnerId.Value; NetworkingManager.singleton.ConnectedClients[clientOwnerId.Value].OwnedObjects.Add(netObject); } if (payload == null) { netObject.InvokeBehaviourNetworkSpawn(null); } else { netObject.InvokeBehaviourNetworkSpawn(payload); } foreach (var client in netManager.ConnectedClients) { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(false); writer.WriteUInt32Packed(netObject.NetworkId); writer.WriteUInt32Packed(netObject.OwnerClientId); writer.WriteUInt64Packed(netObject.NetworkedPrefabHash); writer.WriteBool(netObject.destroyWithScene == null ? true : netObject.destroyWithScene.Value); writer.WriteBool(netObject.SceneDelayedSpawn); writer.WriteUInt32Packed(netObject.sceneSpawnedInIndex); 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); } netObject.WriteNetworkedVarData(stream, client.Key); if (payload != null) { stream.CopyFrom(payload); } InternalMessageHandler.Send(client.Key, MLAPIConstants.MLAPI_ADD_OBJECT, "MLAPI_INTERNAL", stream, SecuritySendFlags.None); } } } }
//Server only internal static void SpawnPlayerObject(NetworkedObject netObject, uint clientId, Stream payload = null) { if (netObject.isSpawned) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Object already spawned"); } return; } else if (!netManager.isServer) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Only server can spawn objects"); } return; } else if (!netManager.NetworkConfig.NetworkPrefabIds.ContainsKey(netObject.NetworkedPrefabName)) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("The prefab name " + netObject.NetworkedPrefabName + " does not exist as a networkedPrefab"); } return; } else if (!netManager.NetworkConfig.HandleObjectSpawning) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("NetworkConfig is set to not handle object spawning"); } return; } else if (netManager.ConnectedClients[clientId].PlayerObject != null) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Client already have a player object"); } return; } uint netId = GetNetworkObjectId(); netObject.NetworkId = netId; SpawnedObjects.Add(netId, netObject); SpawnedObjectsList.Add(netObject); netObject.isSpawned = true; netObject.sceneObject = false; netObject.isPlayerObject = true; netManager.ConnectedClients[clientId].PlayerObject = netObject; if (payload == null) { netObject.InvokeBehaviourNetworkSpawn(null); } else { netObject.InvokeBehaviourNetworkSpawn(payload); } foreach (var client in netManager.ConnectedClients) { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteBool(true); writer.WriteUInt32Packed(netObject.NetworkId); writer.WriteUInt32Packed(netObject.OwnerClientId); writer.WriteInt32Packed(netManager.NetworkConfig.NetworkPrefabIds[netObject.NetworkedPrefabName]); writer.WriteBool(netObject.sceneObject == null ? true : netObject.sceneObject.Value); 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); netObject.WriteNetworkedVarData(stream, client.Key); if (payload != null) { stream.CopyFrom(payload); } InternalMessageHandler.Send(client.Key, MLAPIConstants.MLAPI_ADD_OBJECT, "MLAPI_INTERNAL", stream); } } } }
internal void NetworkedVarUpdate() { if (!networkedVarInit) { NetworkedVarInit(); } //TODO: Do this efficiently. if (!CouldHaveDirtyVars()) { return; } networkedVarIndexesToReset.Clear(); networkedVarIndexesToResetSet.Clear(); for (int i = 0; i < NetworkingManager.Singleton.ConnectedClientsList.Count; i++) { //This iterates over every "channel group". for (int j = 0; j < channelMappedVarIndexes.Count; j++) { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt32Packed(NetworkId); writer.WriteUInt16Packed(NetworkedObject.GetOrderIndex(this)); uint clientId = NetworkingManager.Singleton.ConnectedClientsList[i].ClientId; bool writtenAny = false; for (int k = 0; k < networkedVarFields.Count; k++) { if (!channelMappedVarIndexes[j].Contains(k)) { //This var does not belong to the currently iterating channel group. writer.WriteBool(false); continue; } bool isDirty = networkedVarFields[k].IsDirty(); //cache this here. You never know what operations users will do in the dirty methods writer.WriteBool(isDirty); if (isDirty && (!IsServer || networkedVarFields[k].CanClientRead(clientId))) { writtenAny = true; networkedVarFields[k].WriteDelta(stream); if (!networkedVarIndexesToResetSet.Contains(k)) { networkedVarIndexesToResetSet.Add(k); networkedVarIndexesToReset.Add(k); } } } if (writtenAny) { if (IsServer) { InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_NETWORKED_VAR_DELTA, channelsForVarGroups[j], stream, SecuritySendFlags.None); } else { InternalMessageHandler.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_NETWORKED_VAR_DELTA, channelsForVarGroups[j], stream, SecuritySendFlags.None); } } } } } } for (int i = 0; i < networkedVarIndexesToReset.Count; i++) { networkedVarFields[networkedVarIndexesToReset[i]].ResetDirty(); } }
private static void OnSceneUnloadServer(Guid switchSceneGuid) { // Justification: Rare alloc, could(should?) reuse List <NetworkedObject> newSceneObjects = new List <NetworkedObject>(); { NetworkedObject[] networkedObjects = MonoBehaviour.FindObjectsOfType <NetworkedObject>(); for (int i = 0; i < networkedObjects.Length; i++) { if (networkedObjects[i].IsSceneObject == null) { SpawnManager.SpawnNetworkedObjectLocally(networkedObjects[i], SpawnManager.GetNetworkObjectId(), true, false, null, null, false, 0, false, true); newSceneObjects.Add(networkedObjects[i]); } } } for (int j = 0; j < NetworkingManager.Singleton.ConnectedClientsList.Count; j++) { if (NetworkingManager.Singleton.ConnectedClientsList[j].ClientId != NetworkingManager.Singleton.ServerClientId) { using (PooledBitStream stream = PooledBitStream.Get()) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt32Packed(CurrentActiveSceneIndex); writer.WriteByteArray(switchSceneGuid.ToByteArray()); uint sceneObjectsToSpawn = 0; for (int i = 0; i < newSceneObjects.Count; i++) { if (newSceneObjects[i].observers.Contains(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId)) { sceneObjectsToSpawn++; } } writer.WriteUInt32Packed(sceneObjectsToSpawn); for (int i = 0; i < newSceneObjects.Count; i++) { if (newSceneObjects[i].observers.Contains(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId)) { if (NetworkingManager.Singleton.NetworkConfig.UsePrefabSync) { writer.WriteBool(newSceneObjects[i].IsPlayerObject); writer.WriteUInt64Packed(newSceneObjects[i].NetworkId); writer.WriteUInt64Packed(newSceneObjects[i].OwnerClientId); writer.WriteUInt64Packed(newSceneObjects[i].PrefabHash); writer.WriteBool(newSceneObjects[i].DestroyWithScene); writer.WriteSinglePacked(newSceneObjects[i].transform.position.x); writer.WriteSinglePacked(newSceneObjects[i].transform.position.y); writer.WriteSinglePacked(newSceneObjects[i].transform.position.z); writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.x); writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.y); writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.z); if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar) { newSceneObjects[i].WriteNetworkedVarData(stream, NetworkingManager.Singleton.ConnectedClientsList[j].ClientId); } } else { writer.WriteBool(newSceneObjects[i].IsPlayerObject); writer.WriteUInt64Packed(newSceneObjects[i].NetworkId); writer.WriteUInt64Packed(newSceneObjects[i].OwnerClientId); writer.WriteUInt64Packed(newSceneObjects[i].NetworkedInstanceId); writer.WriteBool(newSceneObjects[i].DestroyWithScene); if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar) { newSceneObjects[i].WriteNetworkedVarData(stream, NetworkingManager.Singleton.ConnectedClientsList[j].ClientId); } } } } } InternalMessageHandler.Send(NetworkingManager.Singleton.ConnectedClientsList[j].ClientId, MLAPIConstants.MLAPI_SWITCH_SCENE, "MLAPI_INTERNAL", stream, SecuritySendFlags.None, null); } } } //Tell server that scene load is completed if (NetworkingManager.Singleton.IsHost) { OnClientSwitchSceneCompleted(NetworkingManager.Singleton.LocalClientId, switchSceneGuid); } isSwitching = false; if (OnSceneSwitched != null) { OnSceneSwitched(); } }
public void Write(Stream stream) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteInt32Packed(TeamID); writer.WriteBool(isRightHanded); writer.WriteBool(isMoving); writer.WriteBool(isSprinting); writer.WriteBool(isDribbling); writer.WriteBool(isScreening); writer.WriteBool(isHardScreening); writer.WriteBool(isShooting); writer.WriteBool(isHelping); writer.WriteBool(isMovementFrozen); writer.WriteBool(isBallInLeftHand); writer.WriteBool(isCtrlDown); writer.WriteBool(isAltDown); writer.WriteBool(isDribUp); writer.WriteBool(isDribDown); writer.WriteBool(isDribLeft); writer.WriteBool(isDribRight); writer.WriteBool(isAI); writer.WriteVector3Packed(m_target); } }
internal static void WriteSpawnCallForObject(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); NetworkedObject parent = null; if (!netObject.AlwaysReplicateAsRoot && netObject.transform.parent != null) { parent = netObject.transform.parent.GetComponent <NetworkedObject>(); } if (parent == null) { writer.WriteBool(false); } else { writer.WriteBool(true); writer.WriteUInt64Packed(parent.NetworkId); } if (!NetworkingManager.Singleton.NetworkConfig.EnableSceneManagement || 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); } } if (netObject.IncludeTransformWhenSpawning == null || netObject.IncludeTransformWhenSpawning(clientId)) { writer.WriteBool(true); 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); } else { writer.WriteBool(false); } writer.WriteBool(payload != null); if (payload != null) { writer.WriteInt32Packed((int)payload.Length); } if (NetworkingManager.Singleton.NetworkConfig.EnableNetworkedVar) { netObject.WriteNetworkedVarData(stream, clientId); netObject.WriteSyncedVarData(stream, clientId); } if (payload != null) { stream.CopyFrom(payload); } } }
public void Write(PooledBitWriter writer) { writer.WriteBool(ground_state); writer.WriteBool(hang_state); }