First commit.
This commit is contained in:
parent
7ccab30fa7
commit
c7db144b83
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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 ----
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
namespace CommunityServerAPI.BattleBitAPI
|
||||
{
|
||||
public static class Const
|
||||
{
|
||||
// ---- Networking ----
|
||||
/// <summary>
|
||||
/// Maximum data size for a single package. 4MB is default.
|
||||
/// </summary>
|
||||
public const int MaxNetworkPackageSize = 1024 * 1024 * 4;//4mb
|
||||
/// <summary>
|
||||
/// How long should server/client wait until connection is determined as timed out when no packages is being sent for long time.
|
||||
/// </summary>
|
||||
public const int NetworkTimeout = 60 * 1000;//60 seconds
|
||||
/// <summary>
|
||||
/// How frequently client/server will send keep alive to each other when no message is being sent to each other for a while.
|
||||
/// </summary>
|
||||
public const int NetworkKeepAlive = 15 * 1000;//15 seconds
|
||||
/// <summary>
|
||||
/// How long server will wait client to send their hail package. In miliseconds.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace BattleBitAPI.Common.Enums
|
||||
{
|
||||
public enum MapDayNight : byte
|
||||
{
|
||||
Day = 0,
|
||||
Night = 1,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace BattleBitAPI.Common.Enums
|
||||
{
|
||||
public enum MapSize : byte
|
||||
{
|
||||
_16vs16 = 0,
|
||||
_32vs32 = 1,
|
||||
_64vs64 = 2,
|
||||
_127vs127 = 3,
|
||||
}
|
||||
}
|
|
@ -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<int> 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<bool> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace BattleBitAPI.Common.Serialization
|
||||
{
|
||||
public interface IStreamSerializable
|
||||
{
|
||||
void Read(Stream ser);
|
||||
void Write(Stream ser);
|
||||
}
|
||||
}
|
|
@ -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>(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<T>() 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<Stream> mPool = new Queue<Stream>(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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BattleBitAPI.Common.Threading
|
||||
{
|
||||
public class ThreadSafe<T>
|
||||
{
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Swaps current value with new value and returns old one.
|
||||
/// </summary>
|
||||
/// <param name="newValue"></param>
|
||||
/// <returns>Old value</returns>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace BattleBitAPI.Networking
|
||||
{
|
||||
public enum NetworkCommuncation : byte
|
||||
{
|
||||
Hail = 0,
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// Is game server connected to our server?
|
||||
/// </summary>
|
||||
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; }
|
||||
|
||||
/// <summary>
|
||||
/// Reason why connection was terminated.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 ---
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public Func<IPAddress, Task<bool>> OnGameServerConnecting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fired when a game server connects.
|
||||
/// </summary>
|
||||
public Func<GameServer, Task> OnGameServerConnected { get; set; }
|
||||
/// <summary>
|
||||
/// Fired when a game server disconnects. Check (server.TerminationReason) to see the reason.
|
||||
/// </summary>
|
||||
public Func<GameServer, Task> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -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
|
|
@ -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<bool> 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.");
|
||||
}
|
||||
}
|
|
@ -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": ""
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net6.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\okidoki\.nuget\packages\</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.4.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\okidoki\.nuget\packages\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
|
@ -0,0 +1,4 @@
|
|||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
|
|
@ -0,0 +1,23 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 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.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1 @@
|
|||
21fb1a9498e672664d0dba2f17f71ec14a2f15d4
|
|
@ -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\
|
|
@ -0,0 +1,8 @@
|
|||
// <auto-generated/>
|
||||
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;
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
76e36c3de7385f6b24db215b47c9a35739cb1496
|
|
@ -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
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
7bb18fdad0a682ea33c476da54a2e3d1ac669888
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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": []
|
||||
}
|
Loading…
Reference in New Issue