225 lines
9.7 KiB
C#
225 lines
9.7 KiB
C#
using MLAPI.NetworkingManagerComponents.Binary;
|
|
using MLAPI.NetworkingManagerComponents.Cryptography;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Security.Cryptography;
|
|
using UnityEngine;
|
|
|
|
namespace MLAPI.Data
|
|
{
|
|
/// <summary>
|
|
/// The configuration object used to start server, client and hosts
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NetworkConfig
|
|
{
|
|
/// <summary>
|
|
/// The protocol version. Different versions doesn't talk to each other.
|
|
/// </summary>
|
|
public ushort ProtocolVersion = 0;
|
|
/// <summary>
|
|
/// The transport hosts the sever uses
|
|
/// </summary>
|
|
public List<TransportHost> ServerTransports = new List<TransportHost>()
|
|
{
|
|
new TransportHost()
|
|
{
|
|
Name = "UDP Socket",
|
|
Port = 7777,
|
|
Websockets = false
|
|
}
|
|
};
|
|
/// <summary>
|
|
/// Channels used by the NetworkedTransport
|
|
/// </summary>
|
|
public List<Channel> Channels = new List<Channel>();
|
|
/// <summary>
|
|
/// Registered MessageTypes
|
|
/// </summary>
|
|
public List<MessageType> MessageTypes = new List<MessageType>();
|
|
internal HashSet<ushort> PassthroughMessageHashSet = new HashSet<ushort>();
|
|
internal HashSet<string> EncryptedChannelsHashSet = new HashSet<string>();
|
|
internal List<string> EncryptedChannels = new List<string>();
|
|
/// <summary>
|
|
/// A list of SceneNames that can be used during networked games.
|
|
/// </summary>
|
|
public List<string> RegisteredScenes = new List<string>();
|
|
/// <summary>
|
|
/// A list of spawnable prefabs
|
|
/// </summary>
|
|
[HideInInspector]
|
|
public List<NetworkedPrefab> NetworkedPrefabs = new List<NetworkedPrefab>();
|
|
internal Dictionary<string, int> NetworkPrefabIds;
|
|
internal Dictionary<int, string> NetworkPrefabNames;
|
|
/// <summary>
|
|
/// The default player prefab
|
|
/// </summary>
|
|
[SerializeField]
|
|
[HideInInspector]
|
|
internal string PlayerPrefabName;
|
|
/// <summary>
|
|
/// The size of the receive message buffer. This is the max message size.
|
|
/// </summary>
|
|
public int MessageBufferSize = 65535;
|
|
/// <summary>
|
|
/// Amount of times per second the receive queue is emptied and all messages inside are processed.
|
|
/// </summary>
|
|
public int ReceiveTickrate = 64;
|
|
/// <summary>
|
|
/// The max amount of messages to process per ReceiveTickrate. This is to prevent flooding.
|
|
/// </summary>
|
|
public int MaxReceiveEventsPerTickRate = 500;
|
|
/// <summary>
|
|
/// The amount of times per second every pending message will be sent away.
|
|
/// </summary>
|
|
public int SendTickrate = 64;
|
|
/// <summary>
|
|
/// The amount of times per second internal frame events will occur, examples include SyncedVar send checking.
|
|
/// </summary>
|
|
public int EventTickrate = 64;
|
|
/// <summary>
|
|
/// The max amount of Clients that can connect.
|
|
/// </summary>
|
|
public int MaxConnections = 100;
|
|
/// <summary>
|
|
/// The port for the NetworkTransport to use when connecting
|
|
/// </summary>
|
|
public int ConnectPort = 7777;
|
|
/// <summary>
|
|
/// The address to connect to
|
|
/// </summary>
|
|
public string ConnectAddress = "127.0.0.1";
|
|
/// <summary>
|
|
/// The amount of seconds to wait for handshake to complete before timing out a client
|
|
/// </summary>
|
|
public int ClientConnectionBufferTimeout = 10;
|
|
/// <summary>
|
|
/// Wheter or not to use connection approval
|
|
/// </summary>
|
|
public bool ConnectionApproval = false;
|
|
/// <summary>
|
|
/// The data to send during connection which can be used to decide on if a client should get accepted
|
|
/// </summary>
|
|
[HideInInspector]
|
|
public byte[] ConnectionData = new byte[0];
|
|
/// <summary>
|
|
/// The amount of seconds to keep a lag compensation position history
|
|
/// </summary>
|
|
public int SecondsHistory = 5;
|
|
/// <summary>
|
|
/// Wheter or not to make the library handle object spawning
|
|
/// </summary>
|
|
public bool HandleObjectSpawning = true;
|
|
/// <summary>
|
|
/// Wheter or not to enable encryption
|
|
/// </summary>
|
|
public bool EnableEncryption = true;
|
|
/// <summary>
|
|
/// Wheter or not to enable signed diffie hellman key exchange.
|
|
/// </summary>
|
|
public bool SignKeyExchange = true;
|
|
/// <summary>
|
|
/// Private RSA XML key to use for signing key exchange
|
|
/// </summary>
|
|
[TextArea]
|
|
public string RSAPrivateKey = "<RSAKeyValue><Modulus>vBEvOQki/EftWOgwh4G8/nFRvcDJLylc8P7Dhz5m/hpkkNtAMzizNKYUrGbs7sYWlEuMYBOWrzkIDGOMoOsYc9uCi+8EcmNoHDlIhK5yNfZUexYBF551VbvZ625LSBR7kmBxkyo4IPuA09fYCHeUFm3prt4h6aTD0Hjc7ZsJHUU=</Modulus><Exponent>EQ==</Exponent><P>ydgcrq5qLJOdDQibD3m9+o3/dkKoFeCC110dnMgdpEteCruyBdL0zjGKKvjjgy3XTSSp43EN591NiXaBp0JtDw==</P><Q>7obHrUnUCsSHUsIJ7+JOrupcGrQ0XaYcQ+Uwb2v7d2YUzwZ46U4gI9snfD2J0tc3DGEh3v3G0Q8q7bxEe3H4aw==</Q><DP>L34k3c6vkgSdbHp+1nb/hj+HZx6+I0PijQbZyolwYuSOmR0a1DGjA1bzVWe9D86NAxevgM9OkOjG8yrxVIgZqQ==</DP><DQ>OB+2gyBuIKa2bdNNodrlVlVC2RtXnZB/HwjAGjeGdnJfP8VJoE6eJo3rLEq3BG7fxq1xYaUfuLhGVg4uOyngGQ==</DQ><InverseQ>o97PimYu58qH5eFmySRCIsyhBr/tK2GM17Zd9QQPJZRSorrhIJn1m6gwQ/G5aJLIM/3Yl04CoyqmQGsPXMzW2w==</InverseQ><D>CxAR1i22w4vCquB7U0Pd8Nl9R2Wxez6rHTwpnoszPB+rkAzlqKj7e5FMgpykhoQfciKPyWqQZKkAeTMIRbN56JinvpAt5POId/28HDd5xjGymHE81k3RzoHqzQXFIOF1TSYKUWzjPPF/TU4nn7auD4i6lOODATsMqtLr5DRBN/0=</D></RSAKeyValue>"; //CHANGE THESE FOR PRODUCTION!
|
|
/// <summary>
|
|
/// Public RSA XML key to use for signing key exchange
|
|
/// </summary>
|
|
[TextArea]
|
|
public string RSAPublicKey = "<RSAKeyValue><Modulus>vBEvOQki/EftWOgwh4G8/nFRvcDJLylc8P7Dhz5m/hpkkNtAMzizNKYUrGbs7sYWlEuMYBOWrzkIDGOMoOsYc9uCi+8EcmNoHDlIhK5yNfZUexYBF551VbvZ625LSBR7kmBxkyo4IPuA09fYCHeUFm3prt4h6aTD0Hjc7ZsJHUU=</Modulus><Exponent>EQ==</Exponent></RSAKeyValue>"; //CHANGE THESE FOR PRODUCTION!
|
|
/// <summary>
|
|
/// Wheter or not to allow any type of passthrough messages
|
|
/// </summary>
|
|
public bool AllowPassthroughMessages = true;
|
|
/// <summary>
|
|
/// Wheter or not to enable scene switching
|
|
/// </summary>
|
|
public bool EnableSceneSwitching = true;
|
|
/// <summary>
|
|
/// If your logic uses the NetwokrTime, this should probably be turned off. If however it's needed to maximize accuracy, this is recommended to be turned on
|
|
/// </summary>
|
|
public bool EnableTimeResync = false;
|
|
|
|
private byte[] ConfigHash = null;
|
|
/// <summary>
|
|
/// Gets a SHA256 hash of parts of the NetworkingConfiguration instance
|
|
/// </summary>
|
|
/// <param name="cache"></param>
|
|
/// <returns></returns>
|
|
public byte[] GetConfig(bool cache = true)
|
|
{
|
|
if (ConfigHash != null && cache)
|
|
return ConfigHash;
|
|
|
|
using (BitWriter writer = new BitWriter())
|
|
{
|
|
writer.WriteUShort(ProtocolVersion);
|
|
for (int i = 0; i < Channels.Count; i++)
|
|
{
|
|
writer.WriteString(Channels[i].Name);
|
|
writer.WriteByte((byte)Channels[i].Type);
|
|
if (EnableEncryption)
|
|
writer.WriteBool(Channels[i].Encrypted);
|
|
}
|
|
for (int i = 0; i < MessageTypes.Count; i++)
|
|
{
|
|
writer.WriteString(MessageTypes[i].Name);
|
|
if (AllowPassthroughMessages)
|
|
writer.WriteBool(MessageTypes[i].Passthrough);
|
|
}
|
|
if (EnableSceneSwitching)
|
|
{
|
|
for (int i = 0; i < RegisteredScenes.Count; i++)
|
|
{
|
|
writer.WriteString(RegisteredScenes[i]);
|
|
}
|
|
}
|
|
if (HandleObjectSpawning)
|
|
{
|
|
for (int i = 0; i < NetworkedPrefabs.Count; i++)
|
|
{
|
|
writer.WriteString(NetworkedPrefabs[i].name);
|
|
}
|
|
}
|
|
writer.WriteBool(HandleObjectSpawning);
|
|
writer.WriteBool(EnableEncryption);
|
|
writer.WriteBool(AllowPassthroughMessages);
|
|
writer.WriteBool(EnableSceneSwitching);
|
|
writer.WriteBool(SignKeyExchange);
|
|
|
|
//using (SHA256Managed sha256 = new SHA256Managed())
|
|
//{
|
|
// Returns a 160 bit / 20 byte / 5 int checksum of the config
|
|
if (cache)
|
|
{
|
|
ConfigHash = MessageDigest.SHA1_Opt(writer.Finalize()).ToArray(); //sha256.ComputeHash(writer.Finalize());
|
|
return ConfigHash;
|
|
}
|
|
return MessageDigest.SHA1_Opt(writer.Finalize()).ToArray(); //sha256.ComputeHash(writer.Finalize());
|
|
//}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Compares a SHA256 hash with the current NetworkingConfiguration instances hash
|
|
/// </summary>
|
|
/// <param name="hash"></param>
|
|
/// <returns></returns>
|
|
public bool CompareConfig(byte[] hash)
|
|
{
|
|
byte[] localConfigHash = GetConfig();
|
|
|
|
if (hash.Length != localConfigHash.Length)
|
|
return false;
|
|
|
|
for (int i = 0; i < hash.Length; i++)
|
|
{
|
|
if (hash[i] != localConfigHash[i])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|