Core implementation continues.

This commit is contained in:
MrOkiDoki 2023-07-28 03:24:00 +03:00
parent 2aab2eaaf8
commit f2611313cf
44 changed files with 1204 additions and 439 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,361 +0,0 @@
using BattleBitAPI.Common.Enums;
using BattleBitAPI.Common.Extentions;
using BattleBitAPI.Common.Serialization;
using BattleBitAPI.Networking;
using CommunityServerAPI.BattleBitAPI;
using System;
using System.Diagnostics;
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 GamePort { get; set; } = 30000;
public bool IsPasswordProtected { get; set; } = false;
public string ServerName { get; set; } = "";
public string Gamemode { get; set; } = "";
public string Map { get; set; } = "";
public MapSize MapSize { get; set; } = MapSize._16vs16;
public MapDayNight DayNight { get; set; } = MapDayNight.Day;
public int CurrentPlayers { get; set; } = 0;
public int InQueuePlayers { get; set; } = 0;
public int MaxPlayers { get; set; } = 16;
public string LoadingScreenText { get; set; } = "";
public string ServerRulesText { get; set; } = "";
// ---- Private Variables ----
private TcpClient mSocket;
private string mDestination;
private int mPort;
private byte[] mKeepAliveBuffer;
private Common.Serialization.Stream mWriteStream;
private Common.Serialization.Stream mReadStream;
private uint mReadPackageSize;
private long mLastPackageReceived;
private long mLastPackageSent;
private bool mIsConnectingFlag;
// ---- Construction ----
public Client(string destination, int port)
{
this.mDestination = destination;
this.mPort = port;
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,
};
this.mLastPackageReceived = Extentions.TickCount;
this.mLastPackageSent = Extentions.TickCount;
}
// ---- 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;
//Dispose old client if exist.
if (this.mSocket != null)
{
try { this.mSocket.Close(); } catch { }
try { this.mSocket.Dispose(); } catch { }
this.mSocket = null;
}
//Create new client
this.mSocket = new TcpClient();
this.mSocket.SendBufferSize = Const.MaxNetworkPackageSize;
this.mSocket.ReceiveBufferSize = Const.MaxNetworkPackageSize;
//Attempt to connect.
try
{
var state = mSocket.BeginConnect(mDestination, mPort, (x) =>
{
try
{
//Did we connect?
mSocket.EndConnect(x);
var networkStream = mSocket.GetStream();
//Prepare our hail package and send it.
using (var hail = BattleBitAPI.Common.Serialization.Stream.Get())
{
hail.Write((byte)NetworkCommuncation.Hail);
hail.Write((ushort)this.GamePort);
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.
networkStream.Write(hail.Buffer, 0, hail.WritePosition);
networkStream.Flush();
}
//Sadly can not use Task Async here, Unity isn't great with tasks.
var watch = Stopwatch.StartNew();
//Read the first byte.
NetworkCommuncation response = NetworkCommuncation.None;
while (watch.ElapsedMilliseconds < Const.HailConnectTimeout)
{
if (mSocket.Available > 0)
{
var data = networkStream.ReadByte();
if (data >= 0)
{
response = (NetworkCommuncation)data;
break;
}
}
Thread.Sleep(1);
}
//Were we accepted.
if (response == NetworkCommuncation.Accepted)
{
//We are accepted.
this.mIsConnectingFlag = false;
this.IsConnected = true;
this.mLastPackageReceived = Extentions.TickCount;
this.mLastPackageSent = Extentions.TickCount;
mOnConnectedToServer();
}
else
{
//Did we at least got a response?
if (response == NetworkCommuncation.None)
throw new Exception("Server did not respond to your connect request.");
//Try to read our deny reason.
if (response == NetworkCommuncation.Denied && mSocket.Available > 0)
{
string errorString = null;
using (var readStream = BattleBitAPI.Common.Serialization.Stream.Get())
{
readStream.WritePosition = networkStream.Read(readStream.Buffer, 0, mSocket.Available);
if (!readStream.TryReadString(out errorString))
errorString = null;
}
if (errorString != null)
throw new Exception(errorString);
}
throw new Exception("Server denied our connect request with an unknown reason.");
}
}
catch (Exception e)
{
this.mIsConnectingFlag = false;
mLogError("Unable to connect to API server: " + e.Message);
return;
}
}, null);
}
catch
{
this.mIsConnectingFlag = false;
}
//We haven't connected yet.
return;
}
//We are connected at this point.
try
{
//Are we still connected on socket level?
if (!mSocket.Connected)
{
mClose("Connection was terminated.");
return;
}
var networkStream = mSocket.GetStream();
//Read network packages.
while (mSocket.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 = networkStream.Read(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'");
//Is this keep alive package?
if (this.mReadPackageSize == 0)
{
Console.WriteLine("Keep alive was received.");
}
//Reset the stream.
this.mReadStream.Reset();
}
}
else
{
int sizeToRead = (int)mReadPackageSize;
int leftSizeToRead = sizeToRead - this.mReadStream.WritePosition;
int read = networkStream.Read(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;
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("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;
Console.WriteLine("Keep alive was sent.");
}
}
catch (Exception e)
{
mClose(e.Message);
}
}
// ---- Internal ----
private void mExecutePackage(Common.Serialization.Stream stream)
{
var communcation = (NetworkCommuncation)stream.ReadInt8();
switch (communcation)
{
}
}
// ---- Callbacks ----
private void mOnConnectedToServer()
{
Console.WriteLine("Connected to server.");
}
private void mOnDisconnectedFromServer(string reason)
{
Console.WriteLine("Disconnected from server (" + reason + ").");
}
// ---- Private ----
private void mLogError(string str)
{
Console.WriteLine(str);
}
private void mClose(string reason)
{
if (this.IsConnected)
{
this.IsConnected = false;
//Dispose old client if exist.
if (this.mSocket != null)
{
try { this.mSocket.Close(); } catch { }
try { this.mSocket.Dispose(); } catch { }
this.mSocket = null;
}
mOnDisconnectedFromServer(reason);
}
}
}
}

View File

@ -14,11 +14,15 @@
/// <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
public const int NetworkKeepAlive = 5 * 1000;//15 seconds
/// <summary>
/// How long server/client will wait other side to send their hail/initial package. In miliseconds.
/// </summary>
#if DEBUG
public const int HailConnectTimeout = 20 * 1000;
#else
public const int HailConnectTimeout = 2 * 1000;
#endif
// ---- Server Fields ----
public const int MinServerNameLength = 5;

View File

@ -0,0 +1,303 @@
namespace BattleBitAPI.Common
{
public class PlayerStats
{
public bool IsBanned;
public Roles Roles;
public PlayerProgess Progress = new PlayerProgess();
public byte[] ToolProgress;
public byte[] Achievements;
public byte[] Selections;
public void Write(Common.Serialization.Stream ser)
{
ser.Write(this.IsBanned);
ser.Write((ulong)this.Roles);
Progress.Write(ser);
if (ToolProgress != null)
{
ser.Write((ushort)ToolProgress.Length);
ser.Write(ToolProgress, 0, ToolProgress.Length);
}
else
{
ser.Write((ushort)0);
}
if (Achievements != null)
{
ser.Write((ushort)Achievements.Length);
ser.Write(Achievements, 0, Achievements.Length);
}
else
{
ser.Write((ushort)0);
}
if (Selections != null)
{
ser.Write((ushort)Selections.Length);
ser.Write(Selections, 0, Selections.Length);
}
else
{
ser.Write((ushort)0);
}
}
public void Read(Common.Serialization.Stream ser)
{
this.IsBanned = ser.ReadBool();
this.Roles = (Roles)ser.ReadUInt64();
this.Progress.Read(ser);
int size = ser.ReadInt16();
this.ToolProgress = ser.ReadByteArray(size);
size = ser.ReadInt16();
this.Achievements = ser.ReadByteArray(size);
size = ser.ReadInt16();
this.Selections = ser.ReadByteArray(size);
}
public class PlayerProgess
{
private const uint ParamCount = 42;
public uint KillCount;
public uint LeaderKills;
public uint AssaultKills;
public uint MedicKills;
public uint EngineerKills;
public uint SupportKills;
public uint ReconKills;
public uint DeathCount;
public uint WinCount;
public uint LoseCount;
public uint FriendlyShots;
public uint FriendlyKills;
public uint Revived;
public uint RevivedTeamMates;
public uint Assists;
public uint Prestige;
public uint Rank;
public uint EXP;
public uint ShotsFired;
public uint ShotsHit;
public uint Headshots;
public uint ObjectivesComplated;
public uint HealedHPs;
public uint RoadKills;
public uint Suicides;
public uint VehiclesDestroyed;
public uint VehicleHPRepaired;
public uint LongestKill;
public uint PlayTimeSeconds;
public uint LeaderPlayTime;
public uint AssaultPlayTime;
public uint MedicPlayTime;
public uint EngineerPlayTime;
public uint SupportPlayTime;
public uint ReconPlayTime;
public uint LeaderScore;
public uint AssaultScore;
public uint MedicScore;
public uint EngineerScore;
public uint SupportScore;
public uint ReconScore;
public uint TotalScore;
public void Write(Common.Serialization.Stream ser)
{
ser.Write(ParamCount);
{
ser.Write(KillCount);
ser.Write(LeaderKills);
ser.Write(AssaultKills);
ser.Write(MedicKills);
ser.Write(EngineerKills);
ser.Write(SupportKills);
ser.Write(ReconKills);
ser.Write(DeathCount);
ser.Write(WinCount);
ser.Write(LoseCount);
ser.Write(FriendlyShots);
ser.Write(FriendlyKills);
ser.Write(Revived);
ser.Write(RevivedTeamMates);
ser.Write(Assists);
ser.Write(Prestige);
ser.Write(Rank);
ser.Write(EXP);
ser.Write(ShotsFired);
ser.Write(ShotsHit);
ser.Write(Headshots);
ser.Write(ObjectivesComplated);
ser.Write(HealedHPs);
ser.Write(RoadKills);
ser.Write(Suicides);
ser.Write(VehiclesDestroyed);
ser.Write(VehicleHPRepaired);
ser.Write(LongestKill);
ser.Write(PlayTimeSeconds);
ser.Write(LeaderPlayTime);
ser.Write(AssaultPlayTime);
ser.Write(MedicPlayTime);
ser.Write(EngineerPlayTime);
ser.Write(SupportPlayTime);
ser.Write(ReconPlayTime);
ser.Write(LeaderScore);
ser.Write(AssaultScore);
ser.Write(MedicScore);
ser.Write(EngineerScore);
ser.Write(SupportScore);
ser.Write(ReconScore);
ser.Write(TotalScore);
}
}
public void Read(Common.Serialization.Stream ser)
{
Reset();
uint mParamCount = ser.ReadUInt32();
int maxReadPosition = ser.ReadPosition + (int)(mParamCount * 4);
{
bool canRead() => ser.ReadPosition < maxReadPosition;
if (canRead())
this.KillCount = ser.ReadUInt32();
if (canRead())
this.LeaderKills = ser.ReadUInt32();
if (canRead())
this.AssaultKills = ser.ReadUInt32();
if (canRead())
this.MedicKills = ser.ReadUInt32();
if (canRead())
this.EngineerKills = ser.ReadUInt32();
if (canRead())
this.SupportKills = ser.ReadUInt32();
if (canRead())
this.ReconKills = ser.ReadUInt32();
if (canRead())
this.DeathCount = ser.ReadUInt32();
if (canRead())
this.WinCount = ser.ReadUInt32();
if (canRead())
this.LoseCount = ser.ReadUInt32();
if (canRead())
this.FriendlyShots = ser.ReadUInt32();
if (canRead())
this.FriendlyKills = ser.ReadUInt32();
if (canRead())
this.Revived = ser.ReadUInt32();
if (canRead())
this.RevivedTeamMates = ser.ReadUInt32();
if (canRead())
this.Assists = ser.ReadUInt32();
if (canRead())
this.Prestige = ser.ReadUInt32();
if (canRead())
this.Rank = ser.ReadUInt32();
if (canRead())
this.EXP = ser.ReadUInt32();
if (canRead())
this.ShotsFired = ser.ReadUInt32();
if (canRead())
this.ShotsHit = ser.ReadUInt32();
if (canRead())
this.Headshots = ser.ReadUInt32();
if (canRead())
this.ObjectivesComplated = ser.ReadUInt32();
if (canRead())
this.HealedHPs = ser.ReadUInt32();
if (canRead())
this.RoadKills = ser.ReadUInt32();
if (canRead())
this.Suicides = ser.ReadUInt32();
if (canRead())
this.VehiclesDestroyed = ser.ReadUInt32();
if (canRead())
this.VehicleHPRepaired = ser.ReadUInt32();
if (canRead())
this.LongestKill = ser.ReadUInt32();
if (canRead())
this.PlayTimeSeconds = ser.ReadUInt32();
if (canRead())
this.LeaderPlayTime = ser.ReadUInt32();
if (canRead())
this.AssaultPlayTime = ser.ReadUInt32();
if (canRead())
this.MedicPlayTime = ser.ReadUInt32();
if (canRead())
this.EngineerPlayTime = ser.ReadUInt32();
if (canRead())
this.SupportPlayTime = ser.ReadUInt32();
if (canRead())
this.ReconPlayTime = ser.ReadUInt32();
if (canRead())
this.LeaderScore = ser.ReadUInt32();
if (canRead())
this.AssaultScore = ser.ReadUInt32();
if (canRead())
this.MedicScore = ser.ReadUInt32();
if (canRead())
this.EngineerScore = ser.ReadUInt32();
if (canRead())
this.SupportScore = ser.ReadUInt32();
if (canRead())
this.ReconScore = ser.ReadUInt32();
if (canRead())
this.TotalScore = ser.ReadUInt32();
}
ser.ReadPosition = maxReadPosition;
}
public void Reset()
{
KillCount = 0;
LeaderKills = 0;
AssaultKills = 0;
MedicKills = 0;
EngineerKills = 0;
SupportKills = 0;
ReconKills = 0;
DeathCount = 0;
WinCount = 0;
LoseCount = 0;
FriendlyShots = 0;
FriendlyKills = 0;
Revived = 0;
RevivedTeamMates = 0;
Assists = 0;
Prestige = 0;
Rank = 0;
EXP = 0;
ShotsFired = 0;
ShotsHit = 0;
Headshots = 0;
ObjectivesComplated = 0;
HealedHPs = 0;
RoadKills = 0;
Suicides = 0;
VehiclesDestroyed = 0;
VehicleHPRepaired = 0;
LongestKill = 0;
PlayTimeSeconds = 0;
LeaderPlayTime = 0;
AssaultPlayTime = 0;
MedicPlayTime = 0;
EngineerPlayTime = 0;
SupportPlayTime = 0;
ReconPlayTime = 0;
LeaderScore = 0;
AssaultScore = 0;
MedicScore = 0;
EngineerScore = 0;
SupportScore = 0;
ReconScore = 0;
TotalScore = 0;
}
}
}
}

View File

@ -0,0 +1,9 @@
namespace BattleBitAPI.Common.Enums
{
public enum ChatChannel
{
AllChat,
TeamChat,
SquadChat
}
}

View File

@ -2,9 +2,11 @@
{
public enum MapSize : byte
{
_16vs16 = 0,
_32vs32 = 1,
_64vs64 = 2,
_127vs127 = 3,
None = 0,
_8v8=8,
_16vs16 = 16,
_32vs32 = 32,
_64vs64 = 64,
_127vs127 = 90,
}
}

View File

@ -0,0 +1,12 @@
namespace BattleBitAPI.Common
{
public enum Roles : ulong
{
None = 0,
Admin = 1 << 0,
Moderator = 1 << 1,
Special = 1 << 2,
Vip = 1 << 3,
}
}

View File

@ -2,12 +2,20 @@
{
public enum NetworkCommuncation : byte
{
//Do not use
None = 0,
Hail = 1,
Accepted = 2,
Denied = 3,
ExecuteCommand = 10,
SendPlayerStats = 11,
PlayerConnected = 50,
PlayerDisconnected = 51,
OnPlayerTypedMessage = 52,
OnPlayerKilledAnotherPlayer = 53,
GetPlayerStats = 54,
SavePlayerStats = 55,
}
}

54
BattleBitAPI/Player.cs Normal file
View File

@ -0,0 +1,54 @@
using BattleBitAPI.Server;
using System.Numerics;
namespace BattleBitAPI
{
public class Player
{
public ulong SteamID { get; set; }
public string Name { get; set; }
public GameServer GameServer { get; set; }
public void Kick(string reason = "")
{
this.GameServer.Kick(this, reason);
}
public void Kill()
{
this.GameServer.Kill(this);
}
public void ChangeTeam()
{
this.GameServer.ChangeTeam(this);
}
public void KickFromSquad()
{
this.GameServer.KickFromSquad(this);
}
public void DisbandTheSquad()
{
this.GameServer.DisbandPlayerCurrentSquad(this);
}
public void PromoteToSquadLeader()
{
this.GameServer.PromoteSquadLeader(this);
}
public void WarnPlayer(string msg)
{
this.GameServer.WarnPlayer(this, msg);
}
public void Message(string msg)
{
this.GameServer.MessageToPlayer(this, msg);
}
public void Teleport(Vector3 target)
{
}
public override string ToString()
{
return this.Name + " (" + this.SteamID + ")";
}
}
}

View File

@ -1,5 +1,6 @@
using System.Net;
using System.Net.Sockets;
using System.Numerics;
using BattleBitAPI.Common.Enums;
using BattleBitAPI.Common.Extentions;
using BattleBitAPI.Networking;
@ -7,7 +8,7 @@ using CommunityServerAPI.BattleBitAPI;
namespace BattleBitAPI.Server
{
public class GameServer
public class GameServer : IDisposable
{
// ---- Public Variables ----
public TcpClient Socket { get; private set; }
@ -15,6 +16,7 @@ namespace BattleBitAPI.Server
/// <summary>
/// Is game server connected to our server?
/// </summary>
public ulong ServerHash { get; private set; }
public bool IsConnected { get; private set; }
public IPAddress GameIP { get; private set; }
public int GamePort { get; private set; }
@ -34,20 +36,26 @@ namespace BattleBitAPI.Server
/// Reason why connection was terminated.
/// </summary>
public string TerminationReason { get; private set; }
internal bool ReconnectFlag { get; set; }
// ---- Private Variables ----
private byte[] mKeepAliveBuffer;
private Func<GameServer, mInternalResources, Common.Serialization.Stream, Task> mExecutionFunc;
private Common.Serialization.Stream mWriteStream;
private Common.Serialization.Stream mReadStream;
private uint mReadPackageSize;
private long mLastPackageReceived;
private long mLastPackageSent;
private bool mIsDisposed;
private mInternalResources mInternal;
// ---- 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)
public GameServer(TcpClient socket, mInternalResources resources, Func<GameServer, mInternalResources, Common.Serialization.Stream, Task> func, 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.mInternal = resources;
this.mExecutionFunc = func;
this.GameIP = iP;
this.GamePort = port;
@ -86,6 +94,8 @@ namespace BattleBitAPI.Server
this.mLastPackageReceived = Extentions.TickCount;
this.mLastPackageSent = Extentions.TickCount;
this.ServerHash = (ulong)(port << 32) | iP.ToUInt();
}
// ---- Tick ----
@ -93,6 +103,8 @@ namespace BattleBitAPI.Server
{
if (!this.IsConnected)
return;
if (this.mIsDisposed)
return;
try
{
@ -131,13 +143,6 @@ namespace BattleBitAPI.Server
if (this.mReadPackageSize > Const.MaxNetworkPackageSize)
throw new Exception("Incoming package was larger than 'Conts.MaxNetworkPackageSize'");
//Is this keep alive package?
if (this.mReadPackageSize == 0)
{
Console.WriteLine("Keep alive was received.");
}
//Reset the stream.
this.mReadStream.Reset();
}
}
@ -157,7 +162,7 @@ namespace BattleBitAPI.Server
{
this.mReadPackageSize = 0;
await mExecutePackage(this.mReadStream);
await this.mExecutionFunc(this, this.mInternal, this.mReadStream);
//Reset
this.mReadStream.Reset();
@ -172,7 +177,7 @@ namespace BattleBitAPI.Server
{
if (this.mWriteStream.WritePosition > 0)
{
networkStream.Write(this.mWriteStream.Buffer, 0, this.mWriteStream.WritePosition);
networkStream.WriteAsync(this.mWriteStream.Buffer, 0, this.mWriteStream.WritePosition);
this.mWriteStream.WritePosition = 0;
this.mLastPackageSent = Extentions.TickCount;
@ -182,17 +187,15 @@ namespace BattleBitAPI.Server
//Are we timed out?
if ((Extentions.TickCount - this.mLastPackageReceived) > Const.NetworkTimeout)
throw new Exception("Game server timedout.");
throw new Exception("Timedout.");
//Send keep alive if needed
if ((Extentions.TickCount - this.mLastPackageSent) > Const.NetworkKeepAlive)
{
//Send keep alive.
networkStream.Write(this.mKeepAliveBuffer, 0, 4);
await networkStream.WriteAsync(this.mKeepAliveBuffer, 0, 4);
await networkStream.FlushAsync();
this.mLastPackageSent = Extentions.TickCount;
Console.WriteLine("Keep alive was sent.");
}
}
catch (Exception e)
@ -201,26 +204,206 @@ namespace BattleBitAPI.Server
}
}
// ---- Internal ----
private async Task mExecutePackage(Common.Serialization.Stream stream)
// ---- Functions ----
public void WriteToSocket(Common.Serialization.Stream pck)
{
var communcation = (NetworkCommuncation)stream.ReadInt8();
switch (communcation)
lock (mWriteStream)
{
mWriteStream.Write((uint)pck.WritePosition);
mWriteStream.Write(pck.Buffer, 0, pck.WritePosition);
}
}
public void ExecuteCommand(string cmd)
{
if (string.IsNullOrWhiteSpace(cmd))
return;
int bytesLong = System.Text.Encoding.UTF8.GetByteCount(cmd);
lock (mWriteStream)
{
mWriteStream.Write((uint)(1 + 2 + bytesLong));
mWriteStream.Write((byte)NetworkCommuncation.ExecuteCommand);
mWriteStream.Write(cmd);
}
}
public void SetNewPassword(string newPassword)
{
ExecuteCommand("setpass " + newPassword);
}
public void SetPingLimit(int newPing)
{
ExecuteCommand("setmaxping " + newPing);
}
public void AnnounceShort(string msg)
{
ExecuteCommand("an " + msg);
}
public void AnnounceLong(string msg)
{
ExecuteCommand("ann " + msg);
}
public void UILogOnServer(string msg, float messageLifetime)
{
ExecuteCommand("serverlog " + msg + " " + messageLifetime);
}
public void ForceStartGame()
{
ExecuteCommand("forcestart");
}
public void ForceEndGame()
{
ExecuteCommand("endgame");
}
public void SayToChat(string msg)
{
ExecuteCommand("say " + msg);
}
public void StopServer()
{
ExecuteCommand("stop");
}
public void CloseServer()
{
ExecuteCommand("notifyend");
}
public void KickAllPlayers()
{
ExecuteCommand("kick all");
}
public void Kick(ulong steamID, string reason)
{
ExecuteCommand("kick " + steamID + " " + reason);
}
public void Kick(Player player, string reason)
{
Kick(player.SteamID, reason);
}
public void Kill(ulong steamID)
{
ExecuteCommand("kill " + steamID);
}
public void Kill(Player player)
{
Kill(player.SteamID);
}
public void ChangeTeam(ulong steamID)
{
ExecuteCommand("changeteam " + steamID);
}
public void ChangeTeam(Player player)
{
ChangeTeam(player.SteamID);
}
public void KickFromSquad(ulong steamID)
{
ExecuteCommand("squadkick " + steamID);
}
public void KickFromSquad(Player player)
{
KickFromSquad(player.SteamID);
}
public void DisbandPlayerSSquad(ulong steamID)
{
ExecuteCommand("squaddisband " + steamID);
}
public void DisbandPlayerCurrentSquad(Player player)
{
DisbandPlayerSSquad(player.SteamID);
}
public void PromoteSquadLeader(ulong steamID)
{
ExecuteCommand("squadpromote " + steamID);
}
public void PromoteSquadLeader(Player player)
{
PromoteSquadLeader(player.SteamID);
}
public void WarnPlayer(ulong steamID, string msg)
{
ExecuteCommand("warn " + steamID + " " + msg);
}
public void WarnPlayer(Player player, string msg)
{
WarnPlayer(player.SteamID, msg);
}
public void MessageToPlayer(ulong steamID, string msg)
{
ExecuteCommand("msg " + steamID + " " + msg);
}
public void MessageToPlayer(Player player, string msg)
{
MessageToPlayer(player.SteamID, msg);
}
// ---- Closing ----
private void mClose(string reason)
{
if (this.IsConnected)
{
this.TerminationReason = reason;
this.IsConnected = false;
}
}
// ---- Disposing ----
public void Dispose()
{
if (this.mIsDisposed)
return;
this.mIsDisposed = true;
if (this.mWriteStream != null)
{
this.mWriteStream.Dispose();
this.mWriteStream = null;
}
if (this.mReadStream != null)
{
this.mReadStream.Dispose();
this.mReadStream = null;
}
if (this.Socket != null)
{
this.Socket.SafeClose();
this.Socket = null;
}
}
// ---- Overrides ----
public override string ToString()
{
return
this.GameIP + ":" + this.GamePort + " - " +
this.ServerName;
}
// ---- Internal ----
public class mInternalResources
{
public Dictionary<ulong, Player> Players = new Dictionary<ulong, Player>(254);
public void AddPlayer<TPlayer>(TPlayer player) where TPlayer : Player
{
lock (Players)
{
Players.Remove(player.SteamID);
Players.Add(player.SteamID, player);
}
}
public void RemovePlayer<TPlayer>(TPlayer player) where TPlayer : Player
{
lock (Players)
Players.Remove(player.SteamID);
}
public bool TryGetPlayer(ulong steamID, out Player result)
{
lock (Players)
return Players.TryGetValue(steamID, out result);
}
}
}
}

View File

@ -1,5 +1,7 @@
using System.Net;
using System.Net.Sockets;
using System.Numerics;
using BattleBitAPI.Common;
using BattleBitAPI.Common.Enums;
using BattleBitAPI.Common.Extentions;
using BattleBitAPI.Common.Serialization;
@ -8,7 +10,7 @@ using CommunityServerAPI.BattleBitAPI;
namespace BattleBitAPI.Server
{
public class ServerListener : IDisposable
public class ServerListener<TPlayer> : IDisposable where TPlayer : Player
{
// --- Public ---
public bool IsListening { get; private set; }
@ -17,26 +19,138 @@ namespace BattleBitAPI.Server
// --- 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.
/// Fired when an attempt made to connect to the server.<br/>
/// Default, any connection attempt will be accepted
/// </summary>
///
/// <remarks>
/// IPAddress: IP of incoming connection <br/>
/// </remarks>
///
/// <value>
/// Returns: true if allow connection, false if deny the connection.
/// </value>
public Func<IPAddress, Task<bool>> OnGameServerConnecting { get; set; }
/// <summary>
/// Fired when a game server connects.
/// </summary>
///
/// <remarks>
/// GameServer: Game server that is connecting.<br/>
/// </remarks>
public Func<GameServer, Task> OnGameServerConnected { get; set; }
/// <summary>
/// Fired when a game server disconnects. Check (server.TerminationReason) to see the reason.
/// Fired when a game server reconnects. (When game server connects while a socket is already open)
/// </summary>
///
/// <remarks>
/// GameServer: Game server that is reconnecting.<br/>
/// </remarks>
public Func<GameServer, Task> OnGameServerReconnected { get; set; }
/// <summary>
/// Fired when a game server disconnects. Check (GameServer.TerminationReason) to see the reason.
/// </summary>
///
/// <remarks>
/// GameServer: Game server that disconnected.<br/>
/// </remarks>
public Func<GameServer, Task> OnGameServerDisconnected { get; set; }
/// <summary>
/// Fired when a new instance of PlayerClass is being created.
/// </summary>
///
/// <remarks>
/// ulong - SteamID of the player <br/>
/// string - Username of the player <br/>
/// Gameserver - The game server instance that player in <br/>
/// </remarks>
/// <value>
/// Returns: An instance of Player class where 'SteamID', 'Username', 'Gameserver' assiged.
/// </value>
public Func<ulong, string, GameServer, TPlayer> OnCreateClient { get; set; }
/// <summary>
/// Fired when a player connects to a server.<br/>
/// Check player.GameServer get the server that player joined.
/// </summary>
///
/// <remarks>
/// Player: The player that connected to the server<br/>
/// </remarks>
public Func<TPlayer, Task> OnPlayerConnected { get; set; }
/// <summary>
/// Fired when a player disconnects from a server.<br/>
/// Check player.GameServer get the server that player left.
/// </summary>
///
/// <remarks>
/// Player: The player that disconnected from the server<br/>
/// </remarks>
public Func<TPlayer, Task> OnPlayerDisconnected { get; set; }
/// <summary>
/// Fired when a player types a message to text chat.<br/>
/// </summary>
///
/// <remarks>
/// Player: The player that typed the message <br/>
/// ChatChannel: The channel the message was sent <br/>
/// string - Message: The message<br/>
/// </remarks>
public Func<TPlayer, ChatChannel, string, Task> OnPlayerTypedMessage { get; set; }
/// <summary>
/// Fired when a player kills another player.
/// </summary>
///
/// <remarks>
/// Player: The killer player<br/>
/// Vector3: The position of killer<br/>
/// Player: The target player that got killed<br/>
/// Vector3: The target player's position<br/>
/// string - Tool: The tool user to kill the player<br/>
/// </remarks>
public Func<TPlayer, Vector3, TPlayer, Vector3, string, Task> OnAPlayerKilledAnotherPlayer { get; set; }
/// <summary>
/// Fired when game server requests the stats of a player, this function should return in 3000ms or player will not able to join to server.
/// </summary>
///
/// <remarks>
/// ulong - SteamID of the player<br/>
/// </remarks>
/// <value>
/// Returns: The stats of the player.
/// </value>
public Func<ulong, Task<PlayerStats>> OnGetPlayerStats { get; set; }
/// <summary>
/// Fired when game server requests to save the stats of a player.
/// </summary>
///
/// <remarks>
/// ulong - SteamID of the player<br/>
/// PlayerStats - Stats of the player<br/>
/// </remarks>
/// <value>
/// Returns: The stats of the player.
/// </value>
public Func<ulong, PlayerStats, Task> OnSavePlayerStats { get; set; }
// --- Private ---
private TcpListener mSocket;
private Dictionary<ulong, GameServer> mActiveConnections;
// --- Construction ---
public ServerListener() { }
public ServerListener()
{
this.mActiveConnections = new Dictionary<ulong, GameServer>(16);
}
// --- Starting ---
public void Start(IPAddress bindIP, int port)
@ -105,6 +219,7 @@ namespace BattleBitAPI.Server
}
GameServer server = null;
GameServer.mInternalResources resources;
try
{
using (CancellationTokenSource source = new CancellationTokenSource(Const.HailConnectTimeout))
@ -290,7 +405,67 @@ namespace BattleBitAPI.Server
}
}
server = new GameServer(client, ip, gamePort, isPasswordProtected, serverName, gameMode, gamemap, size, dayNight, currentPlayers, queuePlayers, maxPlayers, loadingScreenText, serverRulesText);
resources = new GameServer.mInternalResources();
server = new GameServer(client, resources, mExecutePackage, ip, gamePort, isPasswordProtected, serverName, gameMode, gamemap, size, dayNight, currentPlayers, queuePlayers, maxPlayers, loadingScreenText, serverRulesText);
//Client Count
int clientCount = 0;
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, 1, source.Token))
throw new Exception("Unable to read the Client Count Players");
clientCount = readStream.ReadInt8();
}
//Get each client.
while (clientCount > 0)
{
clientCount--;
ulong steamid = 0;
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, 8, source.Token))
throw new Exception("Unable to read the SteamId");
steamid = readStream.ReadUInt64();
}
string username;
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, 2, source.Token))
throw new Exception("Unable to read the Username Size");
int stringSize = readStream.ReadUInt16();
if (stringSize > 0)
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, stringSize, source.Token))
throw new Exception("Unable to read the Username");
username = readStream.ReadString(stringSize);
}
else
{
username = string.Empty;
}
}
if (OnCreateClient != null)
{
var player = OnCreateClient(steamid, username, server);
resources.AddPlayer(player);
}
else
{
TPlayer player = Activator.CreateInstance<TPlayer>();
player.SteamID = steamid;
player.Name = username;
player.GameServer = server;
resources.AddPlayer(player);
}
}
//Send accepted notification.
networkStream.WriteByte((byte)NetworkCommuncation.Accepted);
@ -301,8 +476,6 @@ namespace BattleBitAPI.Server
{
try
{
Console.WriteLine(e.Message);
var networkStream = client.GetStream();
using (var pck = BattleBitAPI.Common.Serialization.Stream.Get())
{
@ -316,14 +489,44 @@ namespace BattleBitAPI.Server
}
catch { }
if (server != null)
{
server.Dispose();
server = null;
}
client.SafeClose();
return;
}
bool connectionExist = false;
//Track the connection
lock (this.mActiveConnections)
{
//An old connection exist with same IP + Port?
if (connectionExist = this.mActiveConnections.TryGetValue(server.ServerHash, out var oldServer))
{
oldServer.ReconnectFlag = true;
this.mActiveConnections.Remove(server.ServerHash);
}
this.mActiveConnections.Add(server.ServerHash, server);
}
//Call the callback.
if (OnGameServerConnected != null)
await OnGameServerConnected.Invoke(server);
if (!connectionExist)
{
//New connection!
if (OnGameServerConnected != null)
await OnGameServerConnected.Invoke(server);
}
else
{
//Reconnection
if (OnGameServerReconnected != null)
await OnGameServerReconnected.Invoke(server);
}
//Set the buffer sizes.
client.ReceiveBufferSize = Const.MaxNetworkPackageSize;
@ -334,14 +537,152 @@ namespace BattleBitAPI.Server
}
private async Task mHandleGameServer(GameServer server)
{
while (server.IsConnected)
using (server)
{
await server.Tick();
await Task.Delay(1);
while (server.IsConnected)
{
await server.Tick();
await Task.Delay(1);
}
if (OnGameServerDisconnected != null && !server.ReconnectFlag)
await OnGameServerDisconnected.Invoke(server);
}
if (OnGameServerDisconnected != null)
await OnGameServerDisconnected.Invoke(server);
//Remove from list.
if (!server.ReconnectFlag)
lock (this.mActiveConnections)
this.mActiveConnections.Remove(server.ServerHash);
}
// --- Logic Executing ---
private async Task mExecutePackage(GameServer server, GameServer.mInternalResources resources, Common.Serialization.Stream stream)
{
var communcation = (NetworkCommuncation)stream.ReadInt8();
switch (communcation)
{
case NetworkCommuncation.PlayerConnected:
{
if (stream.CanRead(8))
{
ulong steamID = stream.ReadUInt64();
if (stream.TryReadString(out var username))
{
if (OnCreateClient != null)
{
var player = OnCreateClient(steamID, username, server);
resources.AddPlayer(player);
if (OnPlayerConnected != null)
await OnPlayerConnected.Invoke(player);
}
else
{
TPlayer player = Activator.CreateInstance<TPlayer>();
player.SteamID = steamID;
player.Name = username;
player.GameServer = server;
resources.AddPlayer(player);
if (OnPlayerConnected != null)
await OnPlayerConnected.Invoke(player);
}
}
}
break;
}
case NetworkCommuncation.PlayerDisconnected:
{
if (stream.CanRead(8))
{
ulong steamID = stream.ReadUInt64();
bool exist;
Player player;
lock (resources.Players)
exist = resources.Players.Remove(steamID, out player);
if (exist)
{
if (OnPlayerDisconnected != null)
await OnPlayerDisconnected.Invoke((TPlayer)player);
}
}
break;
}
case NetworkCommuncation.OnPlayerTypedMessage:
{
if (stream.CanRead(8 + 1 + 2))
{
ulong steamID = stream.ReadUInt64();
if (resources.TryGetPlayer(steamID, out var player))
{
ChatChannel chat = (ChatChannel)stream.ReadInt8();
if (stream.TryReadString(out var msg))
{
if (OnPlayerTypedMessage != null)
await OnPlayerTypedMessage.Invoke((TPlayer)player, chat, msg);
}
}
}
break;
}
case NetworkCommuncation.OnPlayerKilledAnotherPlayer:
{
if (stream.CanRead(8 + 12 + 8 + 12 + 2))
{
ulong killer = stream.ReadUInt64();
Vector3 killerPos = new Vector3(stream.ReadFloat(), stream.ReadFloat(), stream.ReadFloat());
ulong victim = stream.ReadUInt64();
Vector3 victimPos = new Vector3(stream.ReadFloat(), stream.ReadFloat(), stream.ReadFloat());
if (stream.TryReadString(out var tool))
{
if (resources.TryGetPlayer(killer, out var killerClient))
if (resources.TryGetPlayer(victim, out var victimClient))
if (OnAPlayerKilledAnotherPlayer != null)
OnAPlayerKilledAnotherPlayer.Invoke((TPlayer)killerClient, killerPos, (TPlayer)victimClient, victimPos, tool);
}
}
break;
}
case NetworkCommuncation.GetPlayerStats:
{
if (stream.CanRead(8))
{
ulong steamID = stream.ReadUInt64();
if (OnGetPlayerStats != null)
{
var stats = await OnGetPlayerStats.Invoke(steamID);
using (var response = Common.Serialization.Stream.Get())
{
response.Write((byte)NetworkCommuncation.SendPlayerStats);
response.Write(steamID);
stats.Write(response);
server.WriteToSocket(response);
}
}
}
break;
}
case NetworkCommuncation.SavePlayerStats:
{
if (stream.CanRead(8 + 4))
{
ulong steamID = stream.ReadUInt64();
PlayerStats stats = new PlayerStats();
stats.Read(stream);
if (OnSavePlayerStats != null)
await OnSavePlayerStats.Invoke(steamID, stats);
}
break;
}
}
}
// --- Disposing ---

View File

@ -1,47 +1,37 @@
using BattleBitAPI.Client;
using BattleBitAPI;
using BattleBitAPI.Common;
using BattleBitAPI.Common.Enums;
using BattleBitAPI.Server;
using System.Net;
using System.Numerics;
class Program
{
static void Main(string[] args)
{
if (Console.ReadLine().Contains("h"))
{
ServerListener server = new ServerListener();
server.OnGameServerConnecting += OnClientConnecting;
server.OnGameServerConnected += OnGameServerConnected;
server.OnGameServerDisconnected += OnGameServerDisconnected;
server.Start(29294);
Thread.Sleep(-1);
}
else
{
Client c = new Client("127.0.0.1", 29294);
c.ServerName = "Test Server";
c.Gamemode = "TDP";
c.Map = "DustyDew";
while (true)
{
c.Tick();
Thread.Sleep(1);
}
}
var listener = new ServerListener<MyPlayer>();
listener.OnGetPlayerStats += OnGetPlayerStats;
listener.OnSavePlayerStats += OnSavePlayerStats;
listener.Start(29294);//Port
Thread.Sleep(-1);
}
private static async Task<bool> OnClientConnecting(IPAddress ip)
public static PlayerStats Stats;
private static async Task OnSavePlayerStats(ulong steamID, PlayerStats stats)
{
Console.WriteLine(ip + " is connecting.");
return true;
Stats = stats;
}
private static async Task OnGameServerConnected(GameServer server)
private static async Task<PlayerStats> OnGetPlayerStats(ulong steamID)
{
Console.WriteLine("Server " + server.ServerName + " was connected.");
if (Stats == null)
Stats = new PlayerStats();
Stats.Progress.Rank = 155;
Stats.Roles = Roles.Moderator;
Stats.IsBanned = true;
return Stats;
}
private static async Task OnGameServerDisconnected(GameServer server)
{
Console.WriteLine("Server " + server.ServerName + " was disconnected. (" + server.TerminationReason + ")");
}
}
}
class MyPlayer : Player
{
}

Binary file not shown.

View File

@ -0,0 +1,63 @@
{
"format": 1,
"restore": {
"C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj": {}
},
"projects": {
"C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj",
"projectName": "CommunityServerAPI",
"projectPath": "C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj",
"packagesPath": "C:\\Users\\Oki\\.nuget\\packages\\",
"outputPath": "C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\Oki\\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.201\\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\Oki\.nuget\packages\</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.5.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\Oki\.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:\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 @@
6499f830a3ef23dc09747dba385a33c80022cbb9

View File

@ -0,0 +1,15 @@
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.exe
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.deps.json
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.runtimeconfig.json
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.dll
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\bin\Debug\net6.0\CommunityServerAPI.pdb
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.csproj.AssemblyReference.cache
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.GeneratedMSBuildEditorConfig.editorconfig
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.AssemblyInfoInputs.cache
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.AssemblyInfo.cs
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.csproj.CoreCompileInputs.cache
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.dll
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\refint\CommunityServerAPI.dll
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.pdb
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\CommunityServerAPI.genruntimeconfig.cache
C:\BattleBit\BattleBitRemastered\Servers\CommunityServerAPI\BattleBit-Community-Server-API\obj\Debug\net6.0\ref\CommunityServerAPI.dll

Binary file not shown.

View File

@ -0,0 +1 @@
d9d42763bb2e966538725d2a9c9de71bcfc60aa9

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\\Oki\\.nuget\\packages\\": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj",
"projectName": "CommunityServerAPI",
"projectPath": "C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj",
"packagesPath": "C:\\Users\\Oki\\.nuget\\packages\\",
"outputPath": "C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\Oki\\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.201\\RuntimeIdentifierGraph.json"
}
}
}
}

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

@ -0,0 +1,8 @@
{
"version": 2,
"dgSpecHash": "pUUV0vYUBKisP9wHLyg+4LLgPpJ6nV59j98jNphsryg3WNDca7+wrgNUZlRnXogF4/FlbIby2tBboJ+SQRQCGA==",
"success": true,
"projectFilePath": "C:\\BattleBit\\BattleBitRemastered\\Servers\\CommunityServerAPI\\BattleBit-Community-Server-API\\CommunityServerAPI.csproj",
"expectedPackageFiles": [],
"logs": []
}