Client socket connecting to server part.

This commit is contained in:
MrOkiDoki 2023-03-03 17:42:13 +03:00
parent c7db144b83
commit c638227376
18 changed files with 176 additions and 46 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.vs/CommunityServerAPI/v17/.suo

Binary file not shown.

View File

@ -1,7 +1,9 @@
using BattleBitAPI.Common.Enums;
using BattleBitAPI.Common.Serialization;
using BattleBitAPI.Networking;
using CommunityServerAPI.BattleBitAPI;
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
@ -11,19 +13,19 @@ namespace BattleBitAPI.Client
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; }
public bool IsConnected { get; set; }
public int GamePort { get; set; }
public bool IsPasswordProtected { get; set; }
public string ServerName { get; set; }
public string Gamemode { get; set; }
public string Map { get; set; }
public MapSize MapSize { get; set; }
public MapDayNight DayNight { get; set; }
public int CurrentPlayers { get; set; }
public int InQueuePlayers { get; set; }
public int MaxPlayers { get; set; }
public string LoadingScreenText { get; set; }
public string ServerRulesText { get; set; }
// ---- Private Variables ----
private TcpClient mClient;
@ -51,43 +53,152 @@ namespace BattleBitAPI.Client
//Attempt to connect to server async.
this.mIsConnectingFlag = true;
//Dispose old client if exist.
if (this.mClient != null)
{
try { this.mClient.Close(); } catch { }
try { this.mClient.Dispose(); } catch { }
this.mClient = null;
}
//Create new client
this.mClient = new TcpClient();
this.mClient.SendBufferSize = Const.MaxNetworkPackageSize;
this.mClient.ReceiveBufferSize = Const.MaxNetworkPackageSize;
//Attempt to connect.
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())
try
{
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);
//Did we connect?
mClient.EndConnect(x);
//Send our hail package.
mClient.GetStream().Write(hail.Buffer, 0, hail.WritePosition);
var networkStream = mClient.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 (mClient.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.IsConnected = true;
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 && mClient.Available > 0)
{
string errorString = null;
using (var readStream = BattleBitAPI.Common.Serialization.Stream.Get())
{
readStream.WritePosition = networkStream.Read(readStream.Buffer, 0, mClient.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)
{
mLogError("Unable to connect to API server: " + e.Message);
return;
}
}, null);
//We haven't connected yet.
return;
}
//We are connected at this point.
}
// ---- Callbacks ----
private void mOnConnectedToServer()
{
}
private void mOnDisconnectedFromServer(string reason)
{
}
// ---- Private ----
private void mLogError(string str)
{
}
private void mCloseConnection(string reason)
{
if (this.IsConnected)
{
this.IsConnected = false;
//Dispose old client if exist.
if (this.mClient != null)
{
try { this.mClient.Close(); } catch { }
try { this.mClient.Dispose(); } catch { }
this.mClient = null;
}
mOnDisconnectedFromServer(reason);
}
}
}
}

View File

@ -16,7 +16,7 @@
/// </summary>
public const int NetworkKeepAlive = 15 * 1000;//15 seconds
/// <summary>
/// How long server will wait client to send their hail package. In miliseconds.
/// How long server/client will wait other side to send their hail/initial package. In miliseconds.
/// </summary>
public const int HailConnectTimeout = 2 * 1000;

View File

@ -2,8 +2,12 @@
{
public enum NetworkCommuncation : byte
{
Hail = 0,
//Do not use
None = 0,
Hail = 1,
Accepted = 2,
Denied = 3,
}
}

View File

@ -16,8 +16,8 @@ namespace BattleBitAPI.Server
/// 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 IPAddress GameIP { get; private set; }
public int GamePort { get; private set; }
public bool IsPasswordProtected { get; private set; }
public string ServerName { get; private set; }
public string Gamemode { get; private set; }
@ -49,8 +49,8 @@ namespace BattleBitAPI.Server
this.IsConnected = true;
this.Socket = socket;
this.IP = iP;
this.Port = port;
this.GameIP = iP;
this.GamePort = port;
this.IsPasswordProtected = isPasswordProtected;
this.ServerName = serverName;
this.Gamemode = gamemode;

View File

@ -2,6 +2,7 @@
using System.Net.Sockets;
using BattleBitAPI.Common.Enums;
using BattleBitAPI.Common.Extentions;
using BattleBitAPI.Common.Serialization;
using BattleBitAPI.Networking;
using CommunityServerAPI.BattleBitAPI;
@ -290,18 +291,30 @@ namespace BattleBitAPI.Server
}
server = new GameServer(client, ip, gamePort, isPasswordProtected, serverName, gameMode, gamemap, size, dayNight, currentPlayers, queuePlayers, maxPlayers, loadingScreenText, serverRulesText);
//Send accepted notification.
networkStream.WriteByte((byte)NetworkCommuncation.Accepted);
}
}
}
catch
catch (Exception e)
{
client.SafeClose();
return;
}
try
{
var networkStream = client.GetStream();
using (var pck = BattleBitAPI.Common.Serialization.Stream.Get())
{
pck.Write((byte)NetworkCommuncation.Denied);
pck.Write(e.Message);
//Send denied notification.
networkStream.Write(pck.Buffer, 0, pck.WritePosition);
}
await networkStream.FlushAsync();
}
catch { }
//Did server connected successfully?
if (server == null)
{
client.SafeClose();
return;
}