diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..914f5b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +.vs/CommunityServerAPI/v17/.suo diff --git a/.vs/CommunityServerAPI/DesignTimeBuild/.dtbcache.v2 b/.vs/CommunityServerAPI/DesignTimeBuild/.dtbcache.v2 index 440ed14..17ffe3a 100644 Binary files a/.vs/CommunityServerAPI/DesignTimeBuild/.dtbcache.v2 and b/.vs/CommunityServerAPI/DesignTimeBuild/.dtbcache.v2 differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/48ba5e31-9a7c-4cdb-ab00-e17e1a0be5b7.vsidx b/.vs/CommunityServerAPI/FileContentIndex/48ba5e31-9a7c-4cdb-ab00-e17e1a0be5b7.vsidx new file mode 100644 index 0000000..7e34476 Binary files /dev/null and b/.vs/CommunityServerAPI/FileContentIndex/48ba5e31-9a7c-4cdb-ab00-e17e1a0be5b7.vsidx differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/ce6afcfa-7a11-41d9-9da2-f9ba0cb881a8.vsidx b/.vs/CommunityServerAPI/FileContentIndex/ce6afcfa-7a11-41d9-9da2-f9ba0cb881a8.vsidx new file mode 100644 index 0000000..0ec4902 Binary files /dev/null and b/.vs/CommunityServerAPI/FileContentIndex/ce6afcfa-7a11-41d9-9da2-f9ba0cb881a8.vsidx differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/da7330ac-00fe-4d8d-afba-4cee117e0926.vsidx b/.vs/CommunityServerAPI/FileContentIndex/da7330ac-00fe-4d8d-afba-4cee117e0926.vsidx deleted file mode 100644 index bf4e1dc..0000000 Binary files a/.vs/CommunityServerAPI/FileContentIndex/da7330ac-00fe-4d8d-afba-4cee117e0926.vsidx and /dev/null differ diff --git a/.vs/CommunityServerAPI/FileContentIndex/f95db37b-3de8-4b85-9e62-c24fa01b25b6.vsidx b/.vs/CommunityServerAPI/FileContentIndex/f95db37b-3de8-4b85-9e62-c24fa01b25b6.vsidx deleted file mode 100644 index 0ebc807..0000000 Binary files a/.vs/CommunityServerAPI/FileContentIndex/f95db37b-3de8-4b85-9e62-c24fa01b25b6.vsidx and /dev/null differ diff --git a/.vs/CommunityServerAPI/v17/.suo b/.vs/CommunityServerAPI/v17/.suo index 562cfc0..37b490d 100644 Binary files a/.vs/CommunityServerAPI/v17/.suo and b/.vs/CommunityServerAPI/v17/.suo differ diff --git a/BattleBitAPI/Client/Client.cs b/BattleBitAPI/Client/Client.cs index 18192ca..0be34e4 100644 --- a/BattleBitAPI/Client/Client.cs +++ b/BattleBitAPI/Client/Client.cs @@ -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); + } + } } } diff --git a/BattleBitAPI/Common/Conts.cs b/BattleBitAPI/Common/Conts.cs index c7e398f..c1532e4 100644 --- a/BattleBitAPI/Common/Conts.cs +++ b/BattleBitAPI/Common/Conts.cs @@ -16,7 +16,7 @@ /// public const int NetworkKeepAlive = 15 * 1000;//15 seconds /// - /// 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. /// public const int HailConnectTimeout = 2 * 1000; diff --git a/BattleBitAPI/Networking/NetworkCommuncation.cs b/BattleBitAPI/Networking/NetworkCommuncation.cs index d401591..98db420 100644 --- a/BattleBitAPI/Networking/NetworkCommuncation.cs +++ b/BattleBitAPI/Networking/NetworkCommuncation.cs @@ -2,8 +2,12 @@ { public enum NetworkCommuncation : byte { - Hail = 0, + //Do not use + None = 0, + Hail = 1, + Accepted = 2, + Denied = 3, } } diff --git a/BattleBitAPI/Server/GameServer.cs b/BattleBitAPI/Server/GameServer.cs index 4c4f428..68aff28 100644 --- a/BattleBitAPI/Server/GameServer.cs +++ b/BattleBitAPI/Server/GameServer.cs @@ -16,8 +16,8 @@ namespace BattleBitAPI.Server /// Is game server connected to our server? /// public bool IsConnected { get; private set; } - public IPAddress IP { get; private set; } - public int Port { get; private set; } + public 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; diff --git a/BattleBitAPI/Server/ServerListener.cs b/BattleBitAPI/Server/ServerListener.cs index 967e1cb..362cd1b 100644 --- a/BattleBitAPI/Server/ServerListener.cs +++ b/BattleBitAPI/Server/ServerListener.cs @@ -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; } diff --git a/bin/Debug/net6.0/CommunityServerAPI.dll b/bin/Debug/net6.0/CommunityServerAPI.dll index d945abc..fc5e0cd 100644 Binary files a/bin/Debug/net6.0/CommunityServerAPI.dll and b/bin/Debug/net6.0/CommunityServerAPI.dll differ diff --git a/bin/Debug/net6.0/CommunityServerAPI.pdb b/bin/Debug/net6.0/CommunityServerAPI.pdb index c7a402d..e51269f 100644 Binary files a/bin/Debug/net6.0/CommunityServerAPI.pdb and b/bin/Debug/net6.0/CommunityServerAPI.pdb differ diff --git a/obj/Debug/net6.0/CommunityServerAPI.dll b/obj/Debug/net6.0/CommunityServerAPI.dll index d945abc..fc5e0cd 100644 Binary files a/obj/Debug/net6.0/CommunityServerAPI.dll and b/obj/Debug/net6.0/CommunityServerAPI.dll differ diff --git a/obj/Debug/net6.0/CommunityServerAPI.pdb b/obj/Debug/net6.0/CommunityServerAPI.pdb index c7a402d..e51269f 100644 Binary files a/obj/Debug/net6.0/CommunityServerAPI.pdb and b/obj/Debug/net6.0/CommunityServerAPI.pdb differ diff --git a/obj/Debug/net6.0/ref/CommunityServerAPI.dll b/obj/Debug/net6.0/ref/CommunityServerAPI.dll index 655a9b6..58ddf54 100644 Binary files a/obj/Debug/net6.0/ref/CommunityServerAPI.dll and b/obj/Debug/net6.0/ref/CommunityServerAPI.dll differ diff --git a/obj/Debug/net6.0/refint/CommunityServerAPI.dll b/obj/Debug/net6.0/refint/CommunityServerAPI.dll index 655a9b6..58ddf54 100644 Binary files a/obj/Debug/net6.0/refint/CommunityServerAPI.dll and b/obj/Debug/net6.0/refint/CommunityServerAPI.dll differ