diff --git a/.vs/CommunityServerAPI/DesignTimeBuild/.dtbcache.v2 b/.vs/CommunityServerAPI/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000..440ed14 Binary files /dev/null and b/.vs/CommunityServerAPI/DesignTimeBuild/.dtbcache.v2 differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/026c4087-856f-4fee-9b51-b790775d2b15.vsidx b/.vs/CommunityServerAPI/FileContentIndex/026c4087-856f-4fee-9b51-b790775d2b15.vsidx new file mode 100644 index 0000000..ffe58a3 Binary files /dev/null and b/.vs/CommunityServerAPI/FileContentIndex/026c4087-856f-4fee-9b51-b790775d2b15.vsidx differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/3a66ce49-204d-44a0-9e33-15bee7f794b5.vsidx b/.vs/CommunityServerAPI/FileContentIndex/3a66ce49-204d-44a0-9e33-15bee7f794b5.vsidx new file mode 100644 index 0000000..e24349b Binary files /dev/null and b/.vs/CommunityServerAPI/FileContentIndex/3a66ce49-204d-44a0-9e33-15bee7f794b5.vsidx differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/da7330ac-00fe-4d8d-afba-4cee117e0926.vsidx b/.vs/CommunityServerAPI/FileContentIndex/da7330ac-00fe-4d8d-afba-4cee117e0926.vsidx new file mode 100644 index 0000000..bf4e1dc Binary files /dev/null and b/.vs/CommunityServerAPI/FileContentIndex/da7330ac-00fe-4d8d-afba-4cee117e0926.vsidx differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/f95db37b-3de8-4b85-9e62-c24fa01b25b6.vsidx b/.vs/CommunityServerAPI/FileContentIndex/f95db37b-3de8-4b85-9e62-c24fa01b25b6.vsidx new file mode 100644 index 0000000..0ebc807 Binary files /dev/null and b/.vs/CommunityServerAPI/FileContentIndex/f95db37b-3de8-4b85-9e62-c24fa01b25b6.vsidx differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/read.lock b/.vs/CommunityServerAPI/FileContentIndex/read.lock new file mode 100644 index 0000000..e69de29 diff --git a/.vs/CommunityServerAPI/v17/.futdcache.v2 b/.vs/CommunityServerAPI/v17/.futdcache.v2 new file mode 100644 index 0000000..4461d21 Binary files /dev/null and b/.vs/CommunityServerAPI/v17/.futdcache.v2 differ diff --git a/.vs/CommunityServerAPI/v17/.suo b/.vs/CommunityServerAPI/v17/.suo new file mode 100644 index 0000000..562cfc0 Binary files /dev/null and b/.vs/CommunityServerAPI/v17/.suo differ diff --git a/.vs/ProjectEvaluation/communityserverapi.metadata.v5.2 b/.vs/ProjectEvaluation/communityserverapi.metadata.v5.2 new file mode 100644 index 0000000..e897504 Binary files /dev/null and b/.vs/ProjectEvaluation/communityserverapi.metadata.v5.2 differ diff --git a/.vs/ProjectEvaluation/communityserverapi.projects.v5.2 b/.vs/ProjectEvaluation/communityserverapi.projects.v5.2 new file mode 100644 index 0000000..7069791 Binary files /dev/null and b/.vs/ProjectEvaluation/communityserverapi.projects.v5.2 differ diff --git a/BattleBitAPI/Client/Client.cs b/BattleBitAPI/Client/Client.cs new file mode 100644 index 0000000..18192ca --- /dev/null +++ b/BattleBitAPI/Client/Client.cs @@ -0,0 +1,93 @@ +using BattleBitAPI.Common.Enums; +using BattleBitAPI.Common.Serialization; +using BattleBitAPI.Networking; +using System; +using System.Net; +using System.Net.Sockets; + +namespace BattleBitAPI.Client +{ + // This class was created mainly for Unity Engine, for this reason, Task async was not implemented. + public class Client + { + // ---- Public Variables ---- + public bool IsConnected { get; private set; } + public int Port { get; private set; } + public bool IsPasswordProtected { get; private set; } + public string ServerName { get; private set; } + public string Gamemode { get; private set; } + public string Map { get; private set; } + public MapSize MapSize { get; private set; } + public MapDayNight DayNight { get; private set; } + public int CurrentPlayers { get; private set; } + public int InQueuePlayers { get; private set; } + public int MaxPlayers { get; private set; } + public string LoadingScreenText { get; private set; } + public string ServerRulesText { get; private set; } + + // ---- Private Variables ---- + private TcpClient mClient; + private string mDestination; + private int mPort; + private bool mIsConnectingFlag; + + // ---- Construction ---- + public Client(string destination, int port) + { + this.mDestination = destination; + this.mPort = port; + } + + // ---- Main Tick ---- + public void Tick() + { + //Are we connecting? + if (mIsConnectingFlag) + return; + + //Have we connected? + if (!this.IsConnected) + { + //Attempt to connect to server async. + this.mIsConnectingFlag = true; + + var state = mClient.BeginConnect(mDestination, mPort, (x) => + { + this.mIsConnectingFlag = false; + + //Did we connect? + try { mClient.EndConnect(x); } + catch { return; } + + using (var hail = BattleBitAPI.Common.Serialization.Stream.Get()) + { + hail.Write((byte)NetworkCommuncation.Hail); + hail.Write((ushort)this.Port); + hail.Write(this.IsPasswordProtected); + hail.Write(this.ServerName); + hail.Write(this.Gamemode); + hail.Write(this.Map); + hail.Write((byte)this.MapSize); + hail.Write((byte)this.DayNight); + hail.Write((byte)this.CurrentPlayers); + hail.Write((byte)this.InQueuePlayers); + hail.Write((byte)this.MaxPlayers); + hail.Write(this.LoadingScreenText); + hail.Write(this.ServerRulesText); + + //Send our hail package. + mClient.GetStream().Write(hail.Buffer, 0, hail.WritePosition); + } + + }, null); + + return; + } + } + + // ---- Private ---- + + + + } +} diff --git a/BattleBitAPI/Common/Conts.cs b/BattleBitAPI/Common/Conts.cs new file mode 100644 index 0000000..c7e398f --- /dev/null +++ b/BattleBitAPI/Common/Conts.cs @@ -0,0 +1,40 @@ +namespace CommunityServerAPI.BattleBitAPI +{ + public static class Const + { + // ---- Networking ---- + /// + /// Maximum data size for a single package. 4MB is default. + /// + public const int MaxNetworkPackageSize = 1024 * 1024 * 4;//4mb + /// + /// How long should server/client wait until connection is determined as timed out when no packages is being sent for long time. + /// + public const int NetworkTimeout = 60 * 1000;//60 seconds + /// + /// How frequently client/server will send keep alive to each other when no message is being sent to each other for a while. + /// + public const int NetworkKeepAlive = 15 * 1000;//15 seconds + /// + /// How long server will wait client to send their hail package. In miliseconds. + /// + public const int HailConnectTimeout = 2 * 1000; + + // ---- Server Fields ---- + public const int MinServerNameLength = 5; + public const int MaxServerNameLength = 400; + + public const int MinGamemodeNameLength = 2; + public const int MaxGamemodeNameLength = 12; + + public const int MinMapNameLength = 2; + public const int MaxMapNameLength = 36; + + public const int MinLoadingScreenTextLength = 0; + public const int MaxLoadingScreenTextLength = 1024 * 8; + + public const int MinServerRulesTextLength = 0; + public const int MaxServerRulesTextLength = 1024 * 8; + + } +} diff --git a/BattleBitAPI/Common/Enums/MapDayNight.cs b/BattleBitAPI/Common/Enums/MapDayNight.cs new file mode 100644 index 0000000..0a40c84 --- /dev/null +++ b/BattleBitAPI/Common/Enums/MapDayNight.cs @@ -0,0 +1,8 @@ +namespace BattleBitAPI.Common.Enums +{ + public enum MapDayNight : byte + { + Day = 0, + Night = 1, + } +} diff --git a/BattleBitAPI/Common/Enums/MapSize.cs b/BattleBitAPI/Common/Enums/MapSize.cs new file mode 100644 index 0000000..87d1613 --- /dev/null +++ b/BattleBitAPI/Common/Enums/MapSize.cs @@ -0,0 +1,10 @@ +namespace BattleBitAPI.Common.Enums +{ + public enum MapSize : byte + { + _16vs16 = 0, + _32vs32 = 1, + _64vs64 = 2, + _127vs127 = 3, + } +} diff --git a/BattleBitAPI/Common/Extentions/Extentions.cs b/BattleBitAPI/Common/Extentions/Extentions.cs new file mode 100644 index 0000000..3ef94dd --- /dev/null +++ b/BattleBitAPI/Common/Extentions/Extentions.cs @@ -0,0 +1,82 @@ +using System.Net; +using System.Net.Sockets; + +namespace BattleBitAPI.Common.Extentions +{ + public static class Extentions + { + public static long TickCount + { + get + { +#if NETCOREAPP + return System.Environment.TickCount64; +#else + return (long)Environment.TickCount; +#endif + } + } + public unsafe static uint ToUInt(this IPAddress address) + { +#if NETCOREAPP + return BitConverter.ToUInt32(address.GetAddressBytes()); +#else + return BitConverter.ToUInt32(address.GetAddressBytes(), 0); +#endif + } + + public static void SafeClose(this TcpClient client) + { + try { client.Close(); } catch { } + try { client.Dispose(); } catch { } + } + public static async Task Read(this NetworkStream networkStream, Serialization.Stream outputStream, int size, CancellationToken token = default) + { + int read = 0; + int readUntil = outputStream.WritePosition + size; + + //Ensure we have space. + outputStream.EnsureWriteBufferSize(size); + + //Continue reading until we have the package. + while (outputStream.WritePosition < readUntil) + { + int sizeToRead = readUntil - outputStream.WritePosition; + int received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); + if (received <= 0) + throw new Exception("NetworkStream was closed."); + + read += received; + outputStream.WritePosition += received; + } + + return read; + } + public static async Task TryRead(this NetworkStream networkStream, Serialization.Stream outputStream, int size, CancellationToken token = default) + { + try + { + int readUntil = outputStream.WritePosition + size; + + //Ensure we have space. + outputStream.EnsureWriteBufferSize(size); + + //Continue reading until we have the package. + while (outputStream.WritePosition < readUntil) + { + int sizeToRead = readUntil - outputStream.WritePosition; + int received = await networkStream.ReadAsync(outputStream.Buffer, outputStream.WritePosition, sizeToRead, token); + if (received <= 0) + throw new Exception("NetworkStream was closed."); + outputStream.WritePosition += received; + } + + return true; + } + catch + { + return false; + } + } + } +} diff --git a/BattleBitAPI/Common/Serialization/IStreamSerializble.cs b/BattleBitAPI/Common/Serialization/IStreamSerializble.cs new file mode 100644 index 0000000..61fcb6c --- /dev/null +++ b/BattleBitAPI/Common/Serialization/IStreamSerializble.cs @@ -0,0 +1,8 @@ +namespace BattleBitAPI.Common.Serialization +{ + public interface IStreamSerializable + { + void Read(Stream ser); + void Write(Stream ser); + } +} diff --git a/BattleBitAPI/Common/Serialization/Stream.cs b/BattleBitAPI/Common/Serialization/Stream.cs new file mode 100644 index 0000000..eddf56f --- /dev/null +++ b/BattleBitAPI/Common/Serialization/Stream.cs @@ -0,0 +1,670 @@ +using BattleBitAPI.Common.Extentions; +using System.Net; + +namespace BattleBitAPI.Common.Serialization +{ + public class Stream : IDisposable + { + public const int DefaultBufferSize = 1024 * 512; + +#if BIGENDIAN + public static readonly bool IsLittleEndian = false; +#else + public static readonly bool IsLittleEndian = true; +#endif + + public byte[] Buffer; + public int WritePosition; + public int ReadPosition; + public bool InPool; + + public bool CanRead(int size) + { + int readableLenght = WritePosition - ReadPosition; + return (readableLenght >= size); + } + public void EnsureWriteBufferSize(int requiredSize) + { + int bufferLenght = Buffer.Length; + + int leftSpace = bufferLenght - WritePosition; + if (leftSpace < requiredSize) + { + int newSize = bufferLenght + Math.Max(requiredSize, 1024); + System.Array.Resize(ref Buffer, newSize); + } + } + + // -------- Write ------ + public void Write(byte value) + { + EnsureWriteBufferSize(1); + Buffer[WritePosition] = value; + WritePosition += 1; + } + public void Write(bool value) + { + EnsureWriteBufferSize(1); + Buffer[WritePosition] = value ? (byte)1 : (byte)0; + WritePosition += 1; + } + public unsafe void Write(short value) + { + EnsureWriteBufferSize(2); + fixed (byte* ptr = &Buffer[WritePosition]) + *((short*)ptr) = value; + WritePosition += 2; + } + public unsafe void Write(ushort value) + { + EnsureWriteBufferSize(2); + fixed (byte* ptr = &Buffer[WritePosition]) + *((ushort*)ptr) = value; + WritePosition += 2; + } + public unsafe void Write(int value) + { + EnsureWriteBufferSize(4); + fixed (byte* ptr = &Buffer[WritePosition]) + *((int*)ptr) = value; + WritePosition += 4; + } + public unsafe void Write(uint value) + { + EnsureWriteBufferSize(4); + fixed (byte* ptr = &Buffer[WritePosition]) + *((uint*)ptr) = value; + WritePosition += 4; + } + public unsafe void Write(long value) + { + EnsureWriteBufferSize(8); + fixed (byte* ptr = &Buffer[WritePosition]) + *((long*)ptr) = value; + WritePosition += 8; + } + public unsafe void Write(ulong value) + { + EnsureWriteBufferSize(8); + fixed (byte* ptr = &Buffer[WritePosition]) + *((ulong*)ptr) = value; + WritePosition += 8; + } + public unsafe void Write(decimal value) + { + EnsureWriteBufferSize(16); + fixed (byte* ptr = &Buffer[WritePosition]) + *((decimal*)ptr) = value; + WritePosition += 16; + } + public unsafe void Write(double value) + { + EnsureWriteBufferSize(16); + fixed (byte* ptr = &Buffer[WritePosition]) + *((double*)ptr) = value; + WritePosition += 16; + } + public unsafe void Write(float value) + { + int intValue = *((int*)&value); + EnsureWriteBufferSize(4); + fixed (byte* ptr = &Buffer[WritePosition]) + *((int*)ptr) = intValue; + WritePosition += 4; + } + public unsafe void Write(string value) + { + int charCount = value.Length; + fixed (char* strPtr = value) + { + int size = System.Text.Encoding.UTF8.GetByteCount(strPtr, charCount); + EnsureWriteBufferSize(size + 2); + + + fixed (byte* buffPtr = &Buffer[WritePosition]) + { + *((ushort*)buffPtr) = (ushort)size; + System.Text.Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr + 2, size); + } + WritePosition += size + 2; + } + } + public unsafe void Write(DateTime value) + { + var utc = value.ToUniversalTime(); + + EnsureWriteBufferSize(8); + fixed (byte* ptr = &Buffer[WritePosition]) + *((long*)ptr) = utc.Ticks; + WritePosition += 8; + } + public unsafe void Write(IPAddress value) + { + uint ip = value.ToUInt(); + Write(ip); + } + public unsafe void Write(IPEndPoint value) + { + uint ip = value.Address.ToUInt(); + + Write(ip); + Write((ushort)value.Port); + } + public unsafe void WriteRaw(string value) + { + int charCount = value.Length; + fixed (char* strPtr = value) + { + int size = System.Text.Encoding.UTF8.GetByteCount(strPtr, charCount); + EnsureWriteBufferSize(size); + + fixed (byte* buffPtr = &Buffer[WritePosition]) + System.Text.Encoding.UTF8.GetBytes(strPtr, charCount, buffPtr, size); + WritePosition += size; + } + } + public unsafe void Write(T value) where T : IStreamSerializable + { + value.Write(this); + } + public void Write(byte[] source, int sourceIndex, int length) + { + if (length == 0) + return; + + EnsureWriteBufferSize(length); + System.Array.Copy(source, sourceIndex, this.Buffer, this.WritePosition, length); + this.WritePosition += length; + } + public void Write(Stream source) + { + EnsureWriteBufferSize(source.WritePosition); + System.Array.Copy(source.Buffer, 0, this.Buffer, this.WritePosition, source.WritePosition); + this.WritePosition += source.WritePosition; + } + + public unsafe void WriteAt(byte value, int position) + { + Buffer[position] = value; + } + public unsafe void WriteAt(short value, int position) + { + fixed (byte* ptr = &Buffer[position]) + *((short*)ptr) = value; + } + public unsafe void WriteAt(ushort value, int position) + { + fixed (byte* ptr = &Buffer[position]) + *((ushort*)ptr) = value; + } + public unsafe void WriteAt(int value, int position) + { + fixed (byte* ptr = &Buffer[position]) + *((int*)ptr) = value; + } + public unsafe void WriteAt(uint value, int position) + { + fixed (byte* ptr = &Buffer[position]) + *((uint*)ptr) = value; + } + public unsafe void WriteAt(long value, int position) + { + fixed (byte* ptr = &Buffer[position]) + *((long*)ptr) = value; + } + public unsafe void WriteAt(ulong value, int position) + { + fixed (byte* ptr = &Buffer[position]) + *((ulong*)ptr) = value; + } + + // -------- Read ------ + public byte ReadInt8() + { + + var value = Buffer[ReadPosition]; + ReadPosition++; + + return value; + } + public bool ReadBool() + { + + + var value = Buffer[ReadPosition]; + ReadPosition++; + + return value == 1; + } + public unsafe short ReadInt16() + { + short value = 0; + + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 2 == 0) + { + value = *((short*)pbyte); + } + else + { + if (IsLittleEndian) + { + value = (short)((*pbyte) | (*(pbyte + 1) << 8)); + } + else + { + value = (short)((*pbyte << 8) | (*(pbyte + 1))); + } + } + } + + ReadPosition += 2; + return value; + } + public unsafe ushort ReadUInt16() + { + ushort value = 0; + + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 2 == 0) + { + value = *((ushort*)pbyte); + } + else + { + if (IsLittleEndian) + { + value = (ushort)((*pbyte) | (*(pbyte + 1) << 8)); + } + else + { + value = (ushort)((*pbyte << 8) | (*(pbyte + 1))); + } + } + } + + ReadPosition += 2; + return value; + } + public unsafe int ReadInt32() + { + int value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 4 == 0) + { + value = *((int*)pbyte); + } + else + { + if (IsLittleEndian) + { + value = (int)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); + } + else + { + value = (int)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); + } + } + } + ReadPosition += 4; + + return value; + } + public unsafe uint ReadUInt32() + { + uint value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 4 == 0) + { + value = *((uint*)pbyte); + } + else + { + if (IsLittleEndian) + { + value = (uint)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); + } + else + { + value = (uint)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); + } + } + } + ReadPosition += 4; + + return value; + } + public unsafe long ReadInt64() + { + long value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 8 == 0) + { + value = *((long*)pbyte); + } + else + { + if (IsLittleEndian) + { + int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); + int i2 = (*(pbyte + 4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); + value = (uint)i1 | ((long)i2 << 32); + } + else + { + int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); + int i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7)); + value = (uint)i2 | ((long)i1 << 32); + } + } + } + ReadPosition += 8; + + return value; + } + public unsafe ulong ReadUInt64() + { + ulong value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 8 == 0) + { + value = *((ulong*)pbyte); + } + else + { + if (IsLittleEndian) + { + int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); + int i2 = (*(pbyte + 4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); + value = (uint)i1 | ((ulong)i2 << 32); + } + else + { + int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); + int i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7)); + value = (uint)i2 | ((ulong)i1 << 32); + } + } + } + ReadPosition += 8; + + return value; + } + public unsafe decimal ReadInt128() + { + + + decimal value = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + { + value = *((decimal*)ptr); + } + ReadPosition += 16; + + return value; + } + public unsafe double ReadDouble() + { + double value = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + { + value = *((double*)ptr); + } + ReadPosition += 16; + + return value; + } + public unsafe float ReadFloat() + { + int value = 0; + fixed (byte* pbyte = &Buffer[ReadPosition]) + { + if (ReadPosition % 4 == 0) + { + value = *((int*)pbyte); + } + else + { + if (IsLittleEndian) + { + value = (int)((*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24)); + } + else + { + value = (int)((*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3))); + } + } + } + ReadPosition += 4; + + return *(float*)&value; + } + public DateTime ReadDateTime() + { + long value = ReadInt64(); + try + { + return new DateTime(value, DateTimeKind.Utc); + } + catch + { + return DateTime.MinValue; + } + } + public bool TryReadDateTime(out DateTime time) + { + long value = ReadInt64(); + try + { + time = new DateTime(value, DateTimeKind.Utc); + return true; + } + catch { } + + time = default; + return false; + } + public unsafe IPAddress ReadIPAddress() + { + uint ip = ReadUInt32(); + return new IPAddress(ip); + } + public unsafe IPEndPoint ReadIPEndPoint() + { + uint ip = ReadUInt32(); + ushort port = ReadUInt16(); + + return new IPEndPoint(ip, port); + } + public T Read() where T : IStreamSerializable + { + T value = default; + value.Read(this); + return value; + } + + public byte[] ReadByteArray(int lenght) + { + if (lenght == 0) + return new byte[0]; + + byte[] newBuffer = new byte[lenght]; + System.Array.Copy(this.Buffer, this.ReadPosition, newBuffer, 0, lenght); + this.ReadPosition += lenght; + return newBuffer; + } + public void ReadTo(byte[] buffer, int offset, int size) + { + System.Array.Copy(this.Buffer, this.ReadPosition, buffer, offset, size); + this.ReadPosition += size; + } + public unsafe string ReadString(int size) + { + string str; + +#if NETCOREAPP + fixed (byte* ptr = &Buffer[ReadPosition]) + str = System.Text.Encoding.UTF8.GetString(ptr, size); +#else + str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); +#endif + ReadPosition += size; + + return str; + } + public unsafe bool TryReadString(out string str) + { + if (!CanRead(2)) + { + str = null; + return false; + } + + + int size = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + size = *((ushort*)ptr); + ReadPosition += 2; + + if (!CanRead(size)) + { + str = null; + return false; + } + +#if NETCOREAPP + fixed (byte* ptr = &Buffer[ReadPosition]) + str = System.Text.Encoding.UTF8.GetString(ptr, size); +#else + str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); +#endif + + ReadPosition += size; + + return true; + } + public unsafe bool TryReadString(out string str, int maximumSize = ushort.MaxValue) + { + if (!CanRead(2)) + { + str = null; + return false; + } + + + int size = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + size = *((ushort*)ptr); + ReadPosition += 2; + + if (size > maximumSize) + { + str = null; + return false; + } + + if (!CanRead(size)) + { + str = null; + return false; + } + +#if NETCOREAPP + fixed (byte* ptr = &Buffer[ReadPosition]) + str = System.Text.Encoding.UTF8.GetString(ptr, size); +#else + str = System.Text.Encoding.UTF8.GetString(Buffer, ReadPosition, size); +#endif + + ReadPosition += size; + + return true; + } + public unsafe bool TrySkipString() + { + if (!CanRead(2)) + return false; + + int size = 0; + fixed (byte* ptr = &Buffer[ReadPosition]) + size = *((ushort*)ptr); + ReadPosition += 2; + + if (!CanRead(size)) + return false; + + ReadPosition += size; + return true; + } + + public int NumberOfBytesReadable + { + get => WritePosition - ReadPosition; + } + public void SkipWriting(int size) + { + EnsureWriteBufferSize(size); + WritePosition += size; + } + public void SkipReading(int size) + { + ReadPosition += size; + } + + // -------- Finalizing ------ + public byte[] AsByteArrayData() + { + var data = new byte[this.WritePosition]; + System.Array.Copy(this.Buffer, 0, data, 0, this.WritePosition); + return data; + } + + public void Reset() + { + this.ReadPosition = 0; + this.WritePosition = 0; + } + + public void Dispose() + { + if (InPool) + return; + InPool = true; + + lock (mPool) + mPool.Enqueue(this); + } + + // ------- Pool ----- + private static Queue mPool = new Queue(1024 * 256); + public static Stream Get() + { + lock (mPool) + { + if (mPool.Count > 0) + { + var item = mPool.Dequeue(); + item.WritePosition = 0; + item.ReadPosition = 0; + item.InPool = false; + + return item; + } + } + + return new Stream() + { + Buffer = new byte[DefaultBufferSize], + InPool = false, + ReadPosition = 0, + WritePosition = 0, + }; + } + } +} \ No newline at end of file diff --git a/BattleBitAPI/Common/Threading/ThreadSafe.cs b/BattleBitAPI/Common/Threading/ThreadSafe.cs new file mode 100644 index 0000000..23f7431 --- /dev/null +++ b/BattleBitAPI/Common/Threading/ThreadSafe.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; + +namespace BattleBitAPI.Common.Threading +{ + public class ThreadSafe + { + private System.Threading.ReaderWriterLockSlim mLock; + public T Value; + + public ThreadSafe(T value) + { + this.Value = value; + this.mLock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.SupportsRecursion); + } + + public SafeWriteHandle GetWriteHandle() => new SafeWriteHandle(this.mLock); + public SafeReadHandle GetReadHandle() => new SafeReadHandle(this.mLock); + + /// + /// Swaps current value with new value and returns old one. + /// + /// + /// Old value + public T SwapValue(T newValue) + { + using (new SafeWriteHandle(this.mLock)) + { + var oldValue = this.Value; + this.Value = newValue; + return oldValue; + } + } + } + public class SafeWriteHandle : System.IDisposable + { + private System.Threading.ReaderWriterLockSlim mLock; + private bool mDisposed; + public SafeWriteHandle(System.Threading.ReaderWriterLockSlim mLock) + { + this.mLock = mLock; + mLock.EnterWriteLock(); + } + public void Dispose() + { + if (mDisposed) + return; + mDisposed = true; + mLock.ExitWriteLock(); + } + } + public class SafeReadHandle : System.IDisposable + { + private System.Threading.ReaderWriterLockSlim mLock; + private bool mDisposed; + public SafeReadHandle(System.Threading.ReaderWriterLockSlim mLock) + { + this.mLock = mLock; + mLock.EnterReadLock(); + } + public void Dispose() + { + if (mDisposed) + return; + mDisposed = true; + + mLock.ExitReadLock(); + } + } +} \ No newline at end of file diff --git a/BattleBitAPI/Networking/NetworkCommuncation.cs b/BattleBitAPI/Networking/NetworkCommuncation.cs new file mode 100644 index 0000000..d401591 --- /dev/null +++ b/BattleBitAPI/Networking/NetworkCommuncation.cs @@ -0,0 +1,9 @@ +namespace BattleBitAPI.Networking +{ + public enum NetworkCommuncation : byte + { + Hail = 0, + + + } +} diff --git a/BattleBitAPI/Server/GameServer.cs b/BattleBitAPI/Server/GameServer.cs new file mode 100644 index 0000000..4c4f428 --- /dev/null +++ b/BattleBitAPI/Server/GameServer.cs @@ -0,0 +1,215 @@ +using System.Net; +using System.Net.Sockets; +using BattleBitAPI.Common.Enums; +using BattleBitAPI.Common.Extentions; +using BattleBitAPI.Networking; +using CommunityServerAPI.BattleBitAPI; + +namespace BattleBitAPI.Server +{ + public class GameServer + { + // ---- Public Variables ---- + public TcpClient Socket { get; private set; } + + /// + /// Is game server connected to our server? + /// + public bool IsConnected { get; private set; } + public IPAddress IP { get; private set; } + public int Port { get; private set; } + public bool IsPasswordProtected { get; private set; } + public string ServerName { get; private set; } + public string Gamemode { get; private set; } + public string Map { get; private set; } + public MapSize MapSize { get; private set; } + public MapDayNight DayNight { get; private set; } + public int CurrentPlayers { get; private set; } + public int InQueuePlayers { get; private set; } + public int MaxPlayers { get; private set; } + public string LoadingScreenText { get; private set; } + public string ServerRulesText { get; private set; } + + /// + /// Reason why connection was terminated. + /// + public string TerminationReason { get; private set; } + + // ---- Private Variables ---- + private byte[] mKeepAliveBuffer; + private Common.Serialization.Stream mWriteStream; + private Common.Serialization.Stream mReadStream; + private uint mReadPackageSize; + private long mLastPackageReceived; + private long mLastPackageSent; + + // ---- Constrction ---- + public GameServer(TcpClient socket, IPAddress iP, int port, bool isPasswordProtected, string serverName, string gamemode, string map, MapSize mapSize, MapDayNight dayNight, int currentPlayers, int inQueuePlayers, int maxPlayers, string loadingScreenText, string serverRulesText) + { + this.IsConnected = true; + this.Socket = socket; + + this.IP = iP; + this.Port = port; + this.IsPasswordProtected = isPasswordProtected; + this.ServerName = serverName; + this.Gamemode = gamemode; + this.Map = map; + this.MapSize = mapSize; + this.DayNight = dayNight; + this.CurrentPlayers = currentPlayers; + this.InQueuePlayers = inQueuePlayers; + this.MaxPlayers = maxPlayers; + this.LoadingScreenText = loadingScreenText; + this.ServerRulesText = serverRulesText; + + this.TerminationReason = string.Empty; + + this.mWriteStream = new Common.Serialization.Stream() + { + Buffer = new byte[Const.MaxNetworkPackageSize], + InPool = false, + ReadPosition = 0, + WritePosition = 0, + }; + this.mReadStream = new Common.Serialization.Stream() + { + Buffer = new byte[Const.MaxNetworkPackageSize], + InPool = false, + ReadPosition = 0, + WritePosition = 0, + }; + this.mKeepAliveBuffer = new byte[4] + { + 0,0,0,0, + }; + } + + // ---- Tick ---- + public async Task Tick() + { + if (!this.IsConnected) + return; + + try + { + //Are we still connected on socket level? + if (!Socket.Connected) + { + mClose("Connection was terminated."); + return; + } + + var networkStream = Socket.GetStream(); + + //Read network packages. + while (Socket.Available > 0) + { + this.mLastPackageReceived = Extentions.TickCount; + + //Do we know the package size? + if (this.mReadPackageSize == 0) + { + const int sizeToRead = 4; + int leftSizeToRead = sizeToRead - this.mReadStream.WritePosition; + + int read = await networkStream.ReadAsync(this.mReadStream.Buffer, this.mReadStream.WritePosition, leftSizeToRead); + if (read <= 0) + throw new Exception("Connection was terminated."); + + this.mReadStream.WritePosition += read; + + //Did we receive the package? + if (this.mReadStream.WritePosition >= 4) + { + //Read the package size + this.mReadPackageSize = this.mReadStream.ReadUInt32(); + + if (this.mReadPackageSize > Const.MaxNetworkPackageSize) + throw new Exception("Incoming package was larger than 'Conts.MaxNetworkPackageSize'"); + + //Reset the stream. + this.mReadStream.Reset(); + } + } + else + { + int sizeToRead = (int)mReadPackageSize; + int leftSizeToRead = sizeToRead - this.mReadStream.WritePosition; + + int read = await networkStream.ReadAsync(this.mReadStream.Buffer, this.mReadStream.WritePosition, leftSizeToRead); + if (read <= 0) + throw new Exception("Connection was terminated."); + + this.mReadStream.WritePosition += read; + + //Do we have the package? + if (this.mReadStream.WritePosition >= mReadPackageSize) + { + this.mReadPackageSize = 0; + + await mExecutePackage(this.mReadStream); + + //Reset + this.mReadStream.Reset(); + } + } + } + + //Send the network packages. + if (this.mWriteStream.WritePosition > 0) + { + lock (this.mWriteStream) + { + if (this.mWriteStream.WritePosition > 0) + { + networkStream.Write(this.mWriteStream.Buffer, 0, this.mWriteStream.WritePosition); + this.mWriteStream.WritePosition = 0; + + this.mLastPackageSent = Extentions.TickCount; + } + } + } + + //Are we timed out? + if ((Extentions.TickCount - this.mLastPackageReceived) > Const.NetworkTimeout) + throw new Exception("Game server timedout."); + + //Send keep alive if needed + if ((Extentions.TickCount - this.mLastPackageSent) > Const.NetworkKeepAlive) + { + //Send keep alive. + networkStream.Write(this.mKeepAliveBuffer, 0, 4); + + this.mLastPackageSent = Extentions.TickCount; + } + } + catch (Exception e) + { + mClose(e.Message); + } + } + + // ---- Internal ---- + private async Task mExecutePackage(Common.Serialization.Stream stream) + { + var communcation = (NetworkCommuncation)stream.ReadInt8(); + switch (communcation) + { + + } + } + + private void mClose(string reason) + { + if (this.IsConnected) + { + this.TerminationReason = reason; + this.IsConnected = false; + + this.mWriteStream = null; + this.mReadStream = null; + } + } + } +} diff --git a/BattleBitAPI/Server/ServerListener.cs b/BattleBitAPI/Server/ServerListener.cs new file mode 100644 index 0000000..967e1cb --- /dev/null +++ b/BattleBitAPI/Server/ServerListener.cs @@ -0,0 +1,344 @@ +using System.Net; +using System.Net.Sockets; +using BattleBitAPI.Common.Enums; +using BattleBitAPI.Common.Extentions; +using BattleBitAPI.Networking; +using CommunityServerAPI.BattleBitAPI; + +namespace BattleBitAPI.Server +{ + public class ServerListener : IDisposable + { + // --- Public --- + public bool IsListening { get; private set; } + public bool IsDisposed { get; private set; } + public int ListeningPort { get; private set; } + + // --- Events --- + /// + /// Fired when an attempt made to connect to the server. + /// Connection will be allowed if function returns true, otherwise will be blocked. + /// Default, any connection attempt will be accepted. + /// + public Func> OnGameServerConnecting { get; set; } + + /// + /// Fired when a game server connects. + /// + public Func OnGameServerConnected { get; set; } + /// + /// Fired when a game server disconnects. Check (server.TerminationReason) to see the reason. + /// + public Func OnGameServerDisconnected { get; set; } + + // --- Private --- + private TcpListener mSocket; + + // --- Construction --- + public ServerListener() { } + + // --- Starting --- + public void Start(IPAddress bindIP, int port) + { + if (this.IsDisposed) + throw new ObjectDisposedException(this.GetType().FullName); + if (bindIP == null) + throw new ArgumentNullException(nameof(bindIP)); + if (IsListening) + throw new Exception("Server is already listening."); + + this.mSocket = new TcpListener(bindIP, port); + this.mSocket.Start(); + + this.ListeningPort = port; + this.IsListening = true; + + mMainLoop(); + } + public void Start(int port) + { + Start(IPAddress.Loopback, port); + } + + // --- Stopping --- + public void Stop() + { + if (this.IsDisposed) + throw new ObjectDisposedException(this.GetType().FullName); + if (!IsListening) + throw new Exception("Already not running."); + + try + { + mSocket.Stop(); + } + catch { } + + this.mSocket = null; + this.ListeningPort = 0; + this.IsListening = true; + } + + // --- Main Loop --- + private async Task mMainLoop() + { + while (IsListening) + { + var client = await mSocket.AcceptTcpClientAsync(); + mInternalOnClientConnecting(client); + } + } + private async Task mInternalOnClientConnecting(TcpClient client) + { + var ip = (client.Client.RemoteEndPoint as IPEndPoint).Address; + + bool allow = true; + if (OnGameServerConnecting != null) + allow = await OnGameServerConnecting(ip); + + if (!allow) + { + //Connection is not allowed from this IP. + client.SafeClose(); + return; + } + + GameServer server = null; + try + { + using (CancellationTokenSource source = new CancellationTokenSource(Const.HailConnectTimeout)) + { + using (var readStream = Common.Serialization.Stream.Get()) + { + var networkStream = client.GetStream(); + + //Read package type + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the package type"); + NetworkCommuncation type = (NetworkCommuncation)readStream.ReadInt8(); + if (type != NetworkCommuncation.Hail) + throw new Exception("Incoming package wasn't hail."); + } + + //Read port + int gamePort; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the Port"); + gamePort = readStream.ReadUInt16(); + } + + //Read is Port protected + bool isPasswordProtected; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the IsPasswordProtected"); + isPasswordProtected = readStream.ReadBool(); + } + + //Read the server name + string serverName; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the ServerName Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinServerNameLength || stringSize > Const.MaxServerNameLength) + throw new Exception("Invalid server name size"); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the ServerName"); + + serverName = readStream.ReadString(stringSize); + } + + //Read the gamemode + string gameMode; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the gamemode Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinGamemodeNameLength || stringSize > Const.MaxGamemodeNameLength) + throw new Exception("Invalid gamemode size"); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the gamemode"); + + gameMode = readStream.ReadString(stringSize); + } + + //Read the gamemap + string gamemap; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the map size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinMapNameLength || stringSize > Const.MaxMapNameLength) + throw new Exception("Invalid map size"); + + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the map"); + + gamemap = readStream.ReadString(stringSize); + } + + //Read the mapSize + MapSize size; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the MapSize"); + size = (MapSize)readStream.ReadInt8(); + } + + //Read the day night + MapDayNight dayNight; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the MapDayNight"); + dayNight = (MapDayNight)readStream.ReadInt8(); + } + + //Current Players + int currentPlayers; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Current Players"); + currentPlayers = readStream.ReadInt8(); + } + + //Queue Players + int queuePlayers; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Queue Players"); + queuePlayers = readStream.ReadInt8(); + } + + //Max Players + int maxPlayers; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 1, source.Token)) + throw new Exception("Unable to read the Max Players"); + maxPlayers = readStream.ReadInt8(); + } + + //Read Loading Screen Text + string loadingScreenText; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the Loading Screen Text Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinLoadingScreenTextLength || stringSize > Const.MaxLoadingScreenTextLength) + throw new Exception("Invalid server Loading Screen Text Size"); + + if (stringSize > 0) + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the Loading Screen Text"); + + loadingScreenText = readStream.ReadString(stringSize); + } + else + { + loadingScreenText = string.Empty; + } + } + + //Read Server Rules Text + string serverRulesText; + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, 2, source.Token)) + throw new Exception("Unable to read the Server Rules Text Size"); + + int stringSize = readStream.ReadUInt16(); + if (stringSize < Const.MinServerRulesTextLength || stringSize > Const.MaxServerRulesTextLength) + throw new Exception("Invalid server Server Rules Text Size"); + + if (stringSize > 0) + { + readStream.Reset(); + if (!await networkStream.TryRead(readStream, stringSize, source.Token)) + throw new Exception("Unable to read the Server Rules Text"); + + serverRulesText = readStream.ReadString(stringSize); + } + else + { + serverRulesText = string.Empty; + } + } + + server = new GameServer(client, ip, gamePort, isPasswordProtected, serverName, gameMode, gamemap, size, dayNight, currentPlayers, queuePlayers, maxPlayers, loadingScreenText, serverRulesText); + } + } + } + catch + { + client.SafeClose(); + return; + } + + //Did server connected successfully? + if (server == null) + { + client.SafeClose(); + return; + } + + //Call the callback. + if (OnGameServerConnected != null) + await OnGameServerConnected.Invoke(server); + + //Set the buffer sizes. + client.ReceiveBufferSize = Const.MaxNetworkPackageSize; + client.SendBufferSize = Const.MaxNetworkPackageSize; + + //Join to main server loop. + await mHandleGameServer(server); + } + private async Task mHandleGameServer(GameServer server) + { + while (server.IsConnected) + { + await server.Tick(); + await Task.Delay(1); + } + + if (OnGameServerDisconnected != null) + await OnGameServerDisconnected.Invoke(server); + } + + // --- Disposing --- + public void Dispose() + { + //Already disposed? + if (this.IsDisposed) + return; + this.IsDisposed = true; + + if (IsListening) + Stop(); + } + } +} diff --git a/CommunityServerAPI.csproj b/CommunityServerAPI.csproj new file mode 100644 index 0000000..2fb5483 --- /dev/null +++ b/CommunityServerAPI.csproj @@ -0,0 +1,11 @@ + + + + Exe + net6.0 + enable + disable + True + + + diff --git a/CommunityServerAPI.sln b/CommunityServerAPI.sln new file mode 100644 index 0000000..1a7e5a7 --- /dev/null +++ b/CommunityServerAPI.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33205.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityServerAPI", "CommunityServerAPI.csproj", "{787887A1-8AEE-43E4-AF9B-A3883DE04486}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Debug|Any CPU.Build.0 = Debug|Any CPU + {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Release|Any CPU.ActiveCfg = Release|Any CPU + {787887A1-8AEE-43E4-AF9B-A3883DE04486}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {107CE7B8-8DB9-4467-AF24-1F22E52469E5} + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..3f2aac5 --- /dev/null +++ b/Program.cs @@ -0,0 +1,28 @@ +using BattleBitAPI.Server; +using System.Net; + +class Program +{ + static void Main(string[] args) + { + ServerListener server = new ServerListener(); + server.OnGameServerConnecting += OnClientConnecting; + server.OnGameServerConnected += OnGameServerConnected; + server.OnGameServerDisconnected += OnGameServerDisconnected; + + server.Start(29294); + } + + private static async Task OnClientConnecting(IPAddress ip) + { + return true; + } + private static async Task OnGameServerConnected(GameServer server) + { + Console.WriteLine("Server "+server.ServerName+" was connected."); + } + private static async Task OnGameServerDisconnected(GameServer server) + { + Console.WriteLine("Server " + server.ServerName + " was disconnected."); + } +} \ No newline at end of file diff --git a/bin/Debug/net6.0/CommunityServerAPI.deps.json b/bin/Debug/net6.0/CommunityServerAPI.deps.json new file mode 100644 index 0000000..d656064 --- /dev/null +++ b/bin/Debug/net6.0/CommunityServerAPI.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v6.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v6.0": { + "CommunityServerAPI/1.0.0": { + "runtime": { + "CommunityServerAPI.dll": {} + } + } + } + }, + "libraries": { + "CommunityServerAPI/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/bin/Debug/net6.0/CommunityServerAPI.dll b/bin/Debug/net6.0/CommunityServerAPI.dll new file mode 100644 index 0000000..d945abc Binary files /dev/null and b/bin/Debug/net6.0/CommunityServerAPI.dll differ diff --git a/bin/Debug/net6.0/CommunityServerAPI.exe b/bin/Debug/net6.0/CommunityServerAPI.exe new file mode 100644 index 0000000..b200a82 Binary files /dev/null and b/bin/Debug/net6.0/CommunityServerAPI.exe differ diff --git a/bin/Debug/net6.0/CommunityServerAPI.pdb b/bin/Debug/net6.0/CommunityServerAPI.pdb new file mode 100644 index 0000000..c7a402d Binary files /dev/null and b/bin/Debug/net6.0/CommunityServerAPI.pdb differ diff --git a/bin/Debug/net6.0/CommunityServerAPI.runtimeconfig.json b/bin/Debug/net6.0/CommunityServerAPI.runtimeconfig.json new file mode 100644 index 0000000..4986d16 --- /dev/null +++ b/bin/Debug/net6.0/CommunityServerAPI.runtimeconfig.json @@ -0,0 +1,9 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + } + } +} \ No newline at end of file diff --git a/obj/CommunityServerAPI.csproj.nuget.dgspec.json b/obj/CommunityServerAPI.csproj.nuget.dgspec.json new file mode 100644 index 0000000..46f8c21 --- /dev/null +++ b/obj/CommunityServerAPI.csproj.nuget.dgspec.json @@ -0,0 +1,63 @@ +{ + "format": 1, + "restore": { + "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj": {} + }, + "projects": { + "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj", + "projectName": "CommunityServerAPI", + "projectPath": "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj", + "packagesPath": "C:\\Users\\okidoki\\.nuget\\packages\\", + "outputPath": "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\obj\\", + "projectStyle": "PackageReference", + "configFilePaths": [ + "C:\\Users\\okidoki\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.101\\RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/obj/CommunityServerAPI.csproj.nuget.g.props b/obj/CommunityServerAPI.csproj.nuget.g.props new file mode 100644 index 0000000..c0ffeaa --- /dev/null +++ b/obj/CommunityServerAPI.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + $(UserProfile)\.nuget\packages\ + C:\Users\okidoki\.nuget\packages\ + PackageReference + 6.4.0 + + + + + \ No newline at end of file diff --git a/obj/CommunityServerAPI.csproj.nuget.g.targets b/obj/CommunityServerAPI.csproj.nuget.g.targets new file mode 100644 index 0000000..3dc06ef --- /dev/null +++ b/obj/CommunityServerAPI.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs b/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs new file mode 100644 index 0000000..ed92695 --- /dev/null +++ b/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] diff --git a/obj/Debug/net6.0/CommunityServerAPI.AssemblyInfo.cs b/obj/Debug/net6.0/CommunityServerAPI.AssemblyInfo.cs new file mode 100644 index 0000000..25b5ac6 --- /dev/null +++ b/obj/Debug/net6.0/CommunityServerAPI.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("CommunityServerAPI")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("CommunityServerAPI")] +[assembly: System.Reflection.AssemblyTitleAttribute("CommunityServerAPI")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/obj/Debug/net6.0/CommunityServerAPI.AssemblyInfoInputs.cache b/obj/Debug/net6.0/CommunityServerAPI.AssemblyInfoInputs.cache new file mode 100644 index 0000000..86235ae --- /dev/null +++ b/obj/Debug/net6.0/CommunityServerAPI.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +21fb1a9498e672664d0dba2f17f71ec14a2f15d4 diff --git a/obj/Debug/net6.0/CommunityServerAPI.GeneratedMSBuildEditorConfig.editorconfig b/obj/Debug/net6.0/CommunityServerAPI.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..89f2395 --- /dev/null +++ b/obj/Debug/net6.0/CommunityServerAPI.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,11 @@ +is_global = true +build_property.TargetFramework = net6.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.InvariantGlobalization = +build_property.PlatformNeutralAssembly = +build_property.EnforceExtendedAnalyzerRules = +build_property._SupportedPlatformList = Linux,macOS,Windows +build_property.RootNamespace = CommunityServerAPI +build_property.ProjectDir = C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\ diff --git a/obj/Debug/net6.0/CommunityServerAPI.GlobalUsings.g.cs b/obj/Debug/net6.0/CommunityServerAPI.GlobalUsings.g.cs new file mode 100644 index 0000000..8578f3d --- /dev/null +++ b/obj/Debug/net6.0/CommunityServerAPI.GlobalUsings.g.cs @@ -0,0 +1,8 @@ +// +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; diff --git a/obj/Debug/net6.0/CommunityServerAPI.assets.cache b/obj/Debug/net6.0/CommunityServerAPI.assets.cache new file mode 100644 index 0000000..9f9f1cb Binary files /dev/null and b/obj/Debug/net6.0/CommunityServerAPI.assets.cache differ diff --git a/obj/Debug/net6.0/CommunityServerAPI.csproj.AssemblyReference.cache b/obj/Debug/net6.0/CommunityServerAPI.csproj.AssemblyReference.cache new file mode 100644 index 0000000..05f814f Binary files /dev/null and b/obj/Debug/net6.0/CommunityServerAPI.csproj.AssemblyReference.cache differ diff --git a/obj/Debug/net6.0/CommunityServerAPI.csproj.CoreCompileInputs.cache b/obj/Debug/net6.0/CommunityServerAPI.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..cbca712 --- /dev/null +++ b/obj/Debug/net6.0/CommunityServerAPI.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +76e36c3de7385f6b24db215b47c9a35739cb1496 diff --git a/obj/Debug/net6.0/CommunityServerAPI.csproj.FileListAbsolute.txt b/obj/Debug/net6.0/CommunityServerAPI.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..0d5776d --- /dev/null +++ b/obj/Debug/net6.0/CommunityServerAPI.csproj.FileListAbsolute.txt @@ -0,0 +1,30 @@ +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\bin\Debug\net6.0\CommunityServerAPI.exe +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\bin\Debug\net6.0\CommunityServerAPI.deps.json +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\bin\Debug\net6.0\CommunityServerAPI.runtimeconfig.json +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\bin\Debug\net6.0\CommunityServerAPI.dll +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\bin\Debug\net6.0\CommunityServerAPI.pdb +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.csproj.AssemblyReference.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.GeneratedMSBuildEditorConfig.editorconfig +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.AssemblyInfoInputs.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.AssemblyInfo.cs +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.csproj.CoreCompileInputs.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.dll +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\refint\CommunityServerAPI.dll +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.pdb +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\CommunityServerAPI.genruntimeconfig.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\CommunityServerAPI\obj\Debug\net6.0\ref\CommunityServerAPI.dll +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.exe +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.deps.json +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.runtimeconfig.json +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.dll +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.pdb +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.csproj.AssemblyReference.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.GeneratedMSBuildEditorConfig.editorconfig +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.AssemblyInfoInputs.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.AssemblyInfo.cs +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.csproj.CoreCompileInputs.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.dll +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\refint\CommunityServerAPI.dll +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.pdb +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.genruntimeconfig.cache +C:\Projects\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\ref\CommunityServerAPI.dll diff --git a/obj/Debug/net6.0/CommunityServerAPI.dll b/obj/Debug/net6.0/CommunityServerAPI.dll new file mode 100644 index 0000000..d945abc Binary files /dev/null and b/obj/Debug/net6.0/CommunityServerAPI.dll differ diff --git a/obj/Debug/net6.0/CommunityServerAPI.genruntimeconfig.cache b/obj/Debug/net6.0/CommunityServerAPI.genruntimeconfig.cache new file mode 100644 index 0000000..73b72f4 --- /dev/null +++ b/obj/Debug/net6.0/CommunityServerAPI.genruntimeconfig.cache @@ -0,0 +1 @@ +7bb18fdad0a682ea33c476da54a2e3d1ac669888 diff --git a/obj/Debug/net6.0/CommunityServerAPI.pdb b/obj/Debug/net6.0/CommunityServerAPI.pdb new file mode 100644 index 0000000..c7a402d Binary files /dev/null and b/obj/Debug/net6.0/CommunityServerAPI.pdb differ diff --git a/obj/Debug/net6.0/apphost.exe b/obj/Debug/net6.0/apphost.exe new file mode 100644 index 0000000..b200a82 Binary files /dev/null and b/obj/Debug/net6.0/apphost.exe differ diff --git a/obj/Debug/net6.0/ref/CommunityServerAPI.dll b/obj/Debug/net6.0/ref/CommunityServerAPI.dll new file mode 100644 index 0000000..655a9b6 Binary files /dev/null and b/obj/Debug/net6.0/ref/CommunityServerAPI.dll differ diff --git a/obj/Debug/net6.0/refint/CommunityServerAPI.dll b/obj/Debug/net6.0/refint/CommunityServerAPI.dll new file mode 100644 index 0000000..655a9b6 Binary files /dev/null and b/obj/Debug/net6.0/refint/CommunityServerAPI.dll differ diff --git a/obj/project.assets.json b/obj/project.assets.json new file mode 100644 index 0000000..5ac13e0 --- /dev/null +++ b/obj/project.assets.json @@ -0,0 +1,68 @@ +{ + "version": 3, + "targets": { + "net6.0": {} + }, + "libraries": {}, + "projectFileDependencyGroups": { + "net6.0": [] + }, + "packageFolders": { + "C:\\Users\\okidoki\\.nuget\\packages\\": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj", + "projectName": "CommunityServerAPI", + "projectPath": "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj", + "packagesPath": "C:\\Users\\okidoki\\.nuget\\packages\\", + "outputPath": "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\obj\\", + "projectStyle": "PackageReference", + "configFilePaths": [ + "C:\\Users\\okidoki\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\7.0.101\\RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/obj/project.nuget.cache b/obj/project.nuget.cache new file mode 100644 index 0000000..e3f7341 --- /dev/null +++ b/obj/project.nuget.cache @@ -0,0 +1,8 @@ +{ + "version": 2, + "dgSpecHash": "tHrDsfp7Nn2iQbhzfDTWk4twPq5Pi+pgCx3I0zLLSYzA9F0842gK5lxqUvfvU4ZOILIzNQ8CS3k53iBPaAm5CQ==", + "success": true, + "projectFilePath": "C:\\Projects\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj", + "expectedPackageFiles": [], + "logs": [] +} \ No newline at end of file