First commit.

This commit is contained in:
MrOkiDoki 2023-03-03 15:15:17 +03:00
parent 7ccab30fa7
commit c7db144b83
49 changed files with 1880 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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 ----
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,8 @@
namespace BattleBitAPI.Common.Enums
{
public enum MapDayNight : byte
{
Day = 0,
Night = 1,
}
}

View File

@ -0,0 +1,10 @@
namespace BattleBitAPI.Common.Enums
{
public enum MapSize : byte
{
_16vs16 = 0,
_32vs32 = 1,
_64vs64 = 2,
_127vs127 = 3,
}
}

View File

@ -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;
}
}
}
}

View File

@ -0,0 +1,8 @@
namespace BattleBitAPI.Common.Serialization
{
public interface IStreamSerializable
{
void Read(Stream ser);
void Write(Stream ser);
}
}

View File

@ -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,
};
}
}
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1,9 @@
namespace BattleBitAPI.Networking
{
public enum NetworkCommuncation : byte
{
Hail = 0,
}
}

View File

@ -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;
}
}
}
}

View File

@ -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();
}
}
}

11
CommunityServerAPI.csproj Normal file
View File

@ -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>

25
CommunityServerAPI.sln Normal file
View File

@ -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

28
Program.cs Normal file
View File

@ -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.");
}
}

View File

@ -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.

View File

@ -0,0 +1,9 @@
{
"runtimeOptions": {
"tfm": "net6.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
}
}
}

View File

@ -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"
}
}
}
}
}

View File

@ -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>

View File

@ -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" />

View File

@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]

View File

@ -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.

View File

@ -0,0 +1 @@
21fb1a9498e672664d0dba2f17f71ec14a2f15d4

View File

@ -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\

View File

@ -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.

View File

@ -0,0 +1 @@
76e36c3de7385f6b24db215b47c9a35739cb1496

View File

@ -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.

View File

@ -0,0 +1 @@
7bb18fdad0a682ea33c476da54a2e3d1ac669888

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

68
obj/project.assets.json Normal file
View File

@ -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"
}
}
}
}

8
obj/project.nuget.cache Normal file
View File

@ -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": []
}