/// <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> /// 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; 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(); } } }
/// <inheritdoc /> public void WriteDelta(Stream stream) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed((ushort)dirtyEvents.Count); for (int i = 0; i < dirtyEvents.Count; i++) { writer.WriteBits((byte)dirtyEvents[i].eventType, 2); switch (dirtyEvents[i].eventType) { case NetworkedSetEvent <T> .EventType.Add: { writer.WriteObjectPacked(dirtyEvents[i].value); //BOX } break; case NetworkedSetEvent <T> .EventType.Remove: { writer.WriteObjectPacked(dirtyEvents[i].value); //BOX } break; case NetworkedSetEvent <T> .EventType.Clear: { //Nothing has to be written } break; } } } }
internal static BitStream WrapMessage(byte messageType, ulong clientID, BitStream messageBody, SecuritySendFlags flags) { try { bool encrypted = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && false; //NetworkManager.Get().NetworkConfig.EnableEncryption; bool authenticated = (flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated && false; //NetworkManager.Get().NetworkConfig.EnableEncryption; PooledBitStream outStream = PooledBitStream.Get(); using (PooledBitWriter outWriter = PooledBitWriter.Get(outStream)) { outWriter.WriteBit(encrypted); outWriter.WriteBit(authenticated); outWriter.WriteBits(messageType, 6); outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); } return(outStream); } catch (Exception e) { Debug.LogError("Error while wrapping headers"); Debug.LogError(e.ToString()); return(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 && 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()); } } }
/// <inheritdoc /> public void WriteDelta(Stream stream) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed((ushort)dirtyEvents.Count); for (int i = 0; i < dirtyEvents.Count; i++) { writer.WriteBits((byte)dirtyEvents[i].eventType, 3); switch (dirtyEvents[i].eventType) { //F**k me these signatures are proper aids case NetworkedListEvent <T> .EventType.Add: { writer.WriteObjectPacked(dirtyEvents[i].value); //BOX } break; case NetworkedListEvent <T> .EventType.Insert: { writer.WriteInt32Packed(dirtyEvents[i].index); writer.WriteObjectPacked(dirtyEvents[i].value); //BOX } break; case NetworkedListEvent <T> .EventType.Remove: { writer.WriteObjectPacked(dirtyEvents[i].value); //BOX } break; case NetworkedListEvent <T> .EventType.RemoveAt: { writer.WriteInt32Packed(dirtyEvents[i].index); } break; case NetworkedListEvent <T> .EventType.Value: { writer.WriteInt32Packed(dirtyEvents[i].index); writer.WriteObjectPacked(dirtyEvents[i].value); //BOX } break; case NetworkedListEvent <T> .EventType.Clear: { //Nothing has to be written } break; } } } }
/// <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()); } } }
/// <inheritdoc /> public void WriteDelta(Stream stream) { using (PooledBitWriter writer = PooledBitWriter.Get(stream)) { writer.WriteUInt16Packed((ushort)dirtyEvents.Count); for (int i = 0; i < dirtyEvents.Count; i++) { writer.WriteBits((byte)dirtyEvents[i].eventType, 3); switch (dirtyEvents[i].eventType) { case NetworkedDictionaryEvent <TKey, TValue> .NetworkedListEventType.Add: { writer.WriteObjectPacked(dirtyEvents[i].key); writer.WriteObjectPacked(dirtyEvents[i].value); } break; case NetworkedDictionaryEvent <TKey, TValue> .NetworkedListEventType.Remove: { writer.WriteObjectPacked(dirtyEvents[i].key); } break; case NetworkedDictionaryEvent <TKey, TValue> .NetworkedListEventType.RemovePair: { writer.WriteObjectPacked(dirtyEvents[i].key); writer.WriteObjectPacked(dirtyEvents[i].value); } break; case NetworkedDictionaryEvent <TKey, TValue> .NetworkedListEventType.Clear: { //write nothing } break; case NetworkedDictionaryEvent <TKey, TValue> .NetworkedListEventType.Value: { writer.WriteObjectPacked(dirtyEvents[i].key); writer.WriteObjectPacked(dirtyEvents[i].value); } break; default: break; } } } }
/// <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.ServerTargetFramerate); writer.WriteInt32Packed(config.NetworkedTransformTickrate); writer.WriteInt32Packed(config.ClientCommandTickrate); writer.WriteInt32Packed(config.MaxReceiveEventsPerTickRate); writer.WriteInt32Packed(config.LagCompensationTickRate); 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, 2); writer.WriteBool(ForceSamePrefabs); writer.WriteBool(UsePrefabSync); writer.WriteBool(EnableSceneManagement); writer.WriteBool(RecycleNetworkIds); writer.WriteSinglePacked(NetworkIdRecycleDelay); writer.WriteBool(EnableNetworkedVar); writer.WriteBool(AllowRuntimeSceneChanges); writer.WriteBool(EnableNetworkLogs); 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.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.WriteBits((byte)config.RpcHashSize, 3); writer.WriteBool(ForceSamePrefabs); writer.WriteBool(UsePrefabSync); writer.WriteBool(EnableNetworkedVar); stream.PadStream(); return(Convert.ToBase64String(stream.ToArray())); } } }
internal static BitStream WrapMessage(byte messageType, uint clientId, BitStream messageBody, SecuritySendFlags flags) { try { bool encrypted = ((flags & SecuritySendFlags.Encrypted) == SecuritySendFlags.Encrypted) && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; bool authenticated = (flags & SecuritySendFlags.Authenticated) == SecuritySendFlags.Authenticated && NetworkingManager.Singleton.NetworkConfig.EnableEncryption; PooledBitStream outStream = PooledBitStream.Get(); using (PooledBitWriter outWriter = PooledBitWriter.Get(outStream)) { outWriter.WriteBit(encrypted); outWriter.WriteBit(authenticated); #if !DISABLE_CRYPTOGRAPHY if (authenticated || encrypted) { outWriter.WritePadBits(); long hmacWritePos = outStream.Position; if (authenticated) { outStream.Write(HMAC_PLACEHOLDER, 0, HMAC_PLACEHOLDER.Length); } if (encrypted) { using (RijndaelManaged rijndael = new RijndaelManaged()) { rijndael.GenerateIV(); rijndael.Padding = PaddingMode.PKCS7; byte[] key = NetworkingManager.Singleton.IsServer ? CryptographyHelper.GetClientKey(clientId) : CryptographyHelper.GetServerKey(); if (key == null) { if (LogHelper.CurrentLogLevel <= LogLevel.Error) { LogHelper.LogError("Failed to grab key"); } return(null); } rijndael.Key = key; outStream.Write(rijndael.IV); using (CryptoStream encryptionStream = new CryptoStream(outStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write)) { encryptionStream.WriteByte(messageType); encryptionStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); } } } else { outStream.WriteByte(messageType); outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); } if (authenticated) { byte[] key = NetworkingManager.Singleton.IsServer ? CryptographyHelper.GetClientKey(clientId) : CryptographyHelper.GetServerKey(); if (key == null) { if (LogHelper.CurrentLogLevel <= LogLevel.Error) { LogHelper.LogError("Failed to grab key"); } return(null); } using (HMACSHA256 hmac = new HMACSHA256(key)) { byte[] computedHmac = hmac.ComputeHash(outStream.GetBuffer(), 0, (int)outStream.Length); outStream.Position = hmacWritePos; outStream.Write(computedHmac, 0, computedHmac.Length); } } } else { #endif outWriter.WriteBits(messageType, 6); outStream.Write(messageBody.GetBuffer(), 0, (int)messageBody.Length); #if !DISABLE_CRYPTOGRAPHY } #endif } return(outStream); } catch (Exception e) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogError("Error while wrapping headers"); } if (LogHelper.CurrentLogLevel <= LogLevel.Error) { LogHelper.LogError(e.ToString()); } return(null); } }