1
0
Fork 0

ClientCore Rework and Comment

This commit is contained in:
sheychen 2016-11-13 01:26:03 +01:00
parent 493e16b9c5
commit 4476963f4a
16 changed files with 307 additions and 214 deletions

View File

@ -4,6 +4,9 @@ using System.Text;
namespace Galactic_Colors_Control_Common namespace Galactic_Colors_Control_Common
{ {
/// <summary>
/// All used types - byte[] convertions
/// </summary>
public static class Binary public static class Binary
{ {
public static bool ToBool(ref byte[] bytes) public static bool ToBool(ref byte[] bytes)
@ -14,6 +17,7 @@ namespace Galactic_Colors_Control_Common
return data[1] == 1 ? true : false; return data[1] == 1 ? true : false;
} }
///<remarks>1 byte</remarks>
public static byte[] FromBool(bool x) public static byte[] FromBool(bool x)
{ {
return x ? new byte[1] { 1 } : new byte[1] { 0 }; return x ? new byte[1] { 1 } : new byte[1] { 0 };
@ -27,6 +31,7 @@ namespace Galactic_Colors_Control_Common
return text; return text;
} }
///<remarks>len(in bytes) + string</remarks>
public static byte[] FromString(string text) public static byte[] FromString(string text)
{ {
byte[] data = Encoding.ASCII.GetBytes(text); byte[] data = Encoding.ASCII.GetBytes(text);
@ -48,6 +53,7 @@ namespace Galactic_Colors_Control_Common
return BitConverter.ToInt32(data, 0); return BitConverter.ToInt32(data, 0);
} }
///<remarks>4 bytes</remarks>
public static byte[] FromInt(int x) public static byte[] FromInt(int x)
{ {
byte[] data = new byte[4]; byte[] data = new byte[4];

View File

@ -5,6 +5,35 @@ namespace Galactic_Colors_Control_Common
{ {
public static class Common public static class Common
{ {
/// <summary>
/// Write line in console with correct colors
/// </summary>
/// <param name="v">Text to write</param>
/// <param name="Fore">Foreground color</param>
/// <param name="Back">Background color</param>
public static void ConsoleWrite(string v, ConsoleColor Fore = ConsoleColor.White, ConsoleColor Back = ConsoleColor.Black)
{
Console.Write("\b");
Console.ForegroundColor = Fore;
Console.BackgroundColor = Back;
Console.WriteLine(v);
ConsoleResetColor();
Console.Write(">");
}
/// <summary>
/// Reset Console Colors
/// For non black background console as Ubuntu
/// </summary>
public static void ConsoleResetColor()
{
Console.ResetColor();
Console.BackgroundColor = ConsoleColor.Black;
}
/// <summary>
/// Simpler string array creation
/// </summary>
public static string[] Strings(params string[] args) public static string[] Strings(params string[] args)
{ {
return args; return args;
@ -17,7 +46,7 @@ namespace Galactic_Colors_Control_Common
{ {
foreach (string str in array) foreach (string str in array)
{ {
text += (str + Environment.NewLine); text += ((text == "" ? "" : Environment.NewLine) + str);
} }
} }
return text; return text;
@ -28,7 +57,7 @@ namespace Galactic_Colors_Control_Common
string text = ""; string text = "";
foreach (int i in array) foreach (int i in array)
{ {
text += (i.ToString() + Environment.NewLine); text += ((text == "" ? "" : Environment.NewLine) + i.ToString());
} }
return text; return text;
} }

View File

@ -52,6 +52,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Protocol\Data.cs" /> <Compile Include="Protocol\Data.cs" />
<Compile Include="Protocol\EventData.cs" /> <Compile Include="Protocol\EventData.cs" />
<Compile Include="Protocol\EventDataArgs.cs" />
<Compile Include="Protocol\RequestData.cs" /> <Compile Include="Protocol\RequestData.cs" />
<Compile Include="Protocol\RequestResult.cs" /> <Compile Include="Protocol\RequestResult.cs" />
<Compile Include="Protocol\ResultData.cs" /> <Compile Include="Protocol\ResultData.cs" />

View File

@ -1,9 +1,16 @@
namespace Galactic_Colors_Control_Common.Protocol namespace Galactic_Colors_Control_Common.Protocol
{ {
/// <summary>
/// Packet Master Class
/// </summary>
public class Data public class Data
{ {
public enum DataType { Request, Result, Event }; public enum DataType { Request, Result, Event };
/// <summary>
/// Create Packet from bytes
/// </summary>
/// <param name="bytes">row bytes (remove used bytes)</param>
public static Data FromBytes(ref byte[] bytes) public static Data FromBytes(ref byte[] bytes)
{ {
switch ((DataType)Binary.ToInt(ref bytes)) switch ((DataType)Binary.ToInt(ref bytes))
@ -22,16 +29,25 @@
} }
} }
/// <summary>
/// Small readable text
/// </summary>
public virtual string ToSmallString() public virtual string ToSmallString()
{ {
return null; return null;
} }
/// <summary>
/// Long readble text
/// </summary>
public virtual string ToLongString() public virtual string ToLongString()
{ {
return null; return null;
} }
/// <summary>
/// Generate bytes to send
/// </summary>
public virtual byte[] ToBytes() public virtual byte[] ToBytes()
{ {
return new byte[0]; return new byte[0];

View File

@ -1,16 +1,28 @@
namespace Galactic_Colors_Control_Common.Protocol namespace Galactic_Colors_Control_Common.Protocol
{ {
public enum EventTypes { ChatMessage, ServerJoin, ServerLeave, ServerKick, PartyJoin, PartyLeave, PartyKick } public enum EventTypes
{
ChatMessage, //To displat in chatbox
ServerJoin, //A player join server
ServerLeave, //A player leave server
ServerKick, //You are kick from server
PartyJoin, //A player join your party
PartyLeave, //A player leave your party
PartyKick //Tou are jick from your party
}
/// <summary>
/// Server to Client Packet
/// </summary>
public class EventData : Data public class EventData : Data
{ {
public EventTypes type; public EventTypes type;
public string[] data; public string[] data; //EventArgs like
public EventData(EventTypes p1, string[] p2 = null) public EventData(EventTypes Type, string[] Data = null)
{ {
type = p1; type = Type;
data = p2; data = Data;
} }
public EventData(ref byte[] bytes) public EventData(ref byte[] bytes)

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Galactic_Colors_Control_Common.Protocol
{
/// <summary>
/// Hide EventData in EventArgs
/// for OnEvent Handler
/// </summary>
public class EventDataArgs : EventArgs
{
private EventData m_Data;
public EventDataArgs(EventData _myData)
{
m_Data = _myData;
}
public EventData Data { get { return m_Data; } }
}
}

View File

@ -1,14 +1,17 @@
namespace Galactic_Colors_Control_Common.Protocol namespace Galactic_Colors_Control_Common.Protocol
{ {
/// <summary>
/// Client to Server Data request packet 'allways' return ResultData
/// </summary>
public class RequestData : Data public class RequestData : Data
{ {
public int id; public int id; //Client Size autoindent id
public string[] args; public string[] args;
public RequestData(int p1, string[] p2) public RequestData(int Id, string[] Args)
{ {
id = p1; id = Id;
args = p2; args = Args;
} }
public RequestData(ref byte[] bytes) public RequestData(ref byte[] bytes)

View File

@ -1,5 +1,9 @@
namespace Galactic_Colors_Control_Common.Protocol namespace Galactic_Colors_Control_Common.Protocol
{ {
/// <summary>
/// Part of RequestData
/// Commands return
/// </summary>
public class RequestResult public class RequestResult
{ {
public ResultTypes type; public ResultTypes type;

View File

@ -2,24 +2,27 @@
{ {
public enum ResultTypes { Error, OK } public enum ResultTypes { Error, OK }
/// <summary>
/// Server to Client Result from RequestData
/// </summary>
public class ResultData : Data public class ResultData : Data
{ {
public int id; public int id; //Client Side Autoindent
public ResultTypes type; public ResultTypes type;
public string[] result; public string[] result;
public ResultData(int p1, ResultTypes p2, string[] p3 = null) public ResultData(int Id, ResultTypes Type, string[] Result = null)
{ {
id = p1; id = Id;
type = p2; type = Type;
result = p3; result = Result;
} }
public ResultData(int p1, RequestResult p2) public ResultData(int Id, RequestResult Result)
{ {
id = p1; id = Id;
type = p2.type; type = Result.type;
result = p2.result; result = Result.result;
} }
public ResultData(ref byte[] bytes) public ResultData(ref byte[] bytes)

View File

@ -51,6 +51,10 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Galactic Colors Control Common\Galactic Colors Control Common.csproj">
<Project>{022A69CE-22B5-4934-BE9F-A9C6DF9557ED}</Project>
<Name>Galactic Colors Control Common</Name>
</ProjectReference>
<ProjectReference Include="..\Galactic Colors Control\Galactic Colors Control.csproj"> <ProjectReference Include="..\Galactic Colors Control\Galactic Colors Control.csproj">
<Project>{93582ce8-c8c8-4e19-908b-d671ecbade25}</Project> <Project>{93582ce8-c8c8-4e19-908b-d671ecbade25}</Project>
<Name>Galactic Colors Control</Name> <Name>Galactic Colors Control</Name>

View File

@ -1,40 +1,43 @@
using Galactic_Colors_Control; using Galactic_Colors_Control;
using Galactic_Colors_Control_Common;
using Galactic_Colors_Control_Common.Protocol;
using System; using System;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
namespace Galactic_Colors_Control_Console namespace Galactic_Colors_Control_Console
{ {
/// <summary>
/// Console Client
/// </summary>
internal class Program internal class Program
{ {
private static Client client; private static Client client;
private static bool run = true; private static bool run = true;
private static Thread Writer; private static char commandChar = '/';
private static void Main() private static void Main()
{ {
client = new Client(); client = new Client();
Console.Title = "Galactic Colors Control Client"; client.OnEvent += new EventHandler(OnEvent); //Set OnEvent function
Console.Title = "Galactic Colors Control Client"; //Start display
Console.Write(">"); Console.Write(">");
Write("Galactic Colors Control Client"); Common.ConsoleWrite("Galactic Colors Control Client", ConsoleColor.Red);
Write("Console " + Assembly.GetEntryAssembly().GetName().Version.ToString()); Common.ConsoleWrite("Console " + Assembly.GetEntryAssembly().GetName().Version.ToString(), ConsoleColor.DarkYellow);
bool hostSet = false; bool hostSet = false;
while (!hostSet) while (!hostSet) //Request hostname
{ {
Write("Enter server host:"); Common.ConsoleWrite("Enter server host:");
string host = client.ValidateHost(Console.ReadLine()); string host = client.ValidateHost(Console.ReadLine());
if (host == null) if (host[0] == '*')
{ {
foreach (string output in client.Output.ToArray()) host = host.Substring(1);
{ Common.ConsoleWrite(host, ConsoleColor.Red);
Write(output);
}
client.Output.Clear();
client.ResetHost(); client.ResetHost();
} }
else else
{ {
Write("Use " + host + "? y/n"); Common.ConsoleWrite("Use " + host + "? y/n");
ConsoleKeyInfo c = new ConsoleKeyInfo(); ConsoleKeyInfo c = new ConsoleKeyInfo();
while (c.Key != ConsoleKey.Y && c.Key != ConsoleKey.N) while (c.Key != ConsoleKey.Y && c.Key != ConsoleKey.N)
{ {
@ -50,58 +53,48 @@ namespace Galactic_Colors_Control_Console
} }
} }
} }
if (client.ConnectHost()) if (client.ConnectHost()) //Try connection
{ {
run = true; run = true;
Writer = new Thread(OutputWriter);
Writer.Start();
while (run) while (run)
{ {
client.SendRequest(Console.ReadLine()); Execute(Console.ReadLine()); //Process console input
if (!client.isRunning) { run = false; } if (!client.isRunning) { run = false; }
} }
Writer.Join();
Console.Read(); Console.Read();
} }
else else
{ {
foreach (string output in client.Output.ToArray()) Common.ConsoleWrite("Can't connect sorry. Bye", ConsoleColor.Red);
{
Write(output);
}
client.Output.Clear();
Console.Read(); Console.Read();
} }
} }
private static void OutputWriter() private static void Execute(string input)
{ {
while (run || client.Output.Count > 0) if (input == null)
{ return;
if (client.Output.Count > 0)
{
string text = client.Output[0];
switch (text)
{
case "/clear":
Console.Clear();
break;
default: if (input.Length == 0)
Write(text); return;
break;
} string[] req;
client.Output.Remove(text); if(input[0] == commandChar)
} {
Thread.Sleep(200); input = input.Substring(1);
req = Common.SplitArgs(input);
} }
else
{
req = Common.Strings("say", input);
}
Common.ConsoleWrite(client.Request(req).ToSmallString()); //Add processing (common)
} }
private static void Write(string text) private static void OnEvent(object sender, EventArgs e)
{ {
Console.Write("\b"); EventData eve = ((EventDataArgs)e).Data;
Console.WriteLine(text); Common.ConsoleWrite(eve.ToSmallString()); //TODO add processing (common)
Console.Write(">");
} }
} }
} }

View File

@ -1,4 +1,5 @@
using Galactic_Colors_Control; //TODO comment and update for new clientcore
using Galactic_Colors_Control;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Content;
@ -211,7 +212,8 @@ namespace Galactic_Colors_Control_GUI
case GameStatus.Game: case GameStatus.Game:
if (showOutput) if (showOutput)
if (client.Output.Count > 0) //TODO
/*if (client.Output.Count > 0)
{ {
string text = client.Output[0]; string text = client.Output[0];
switch (text) switch (text)
@ -225,7 +227,7 @@ namespace Galactic_Colors_Control_GUI
break; break;
} }
client.Output.Remove(text); client.Output.Remove(text);
} }*/
if (!client.isRunning) { gameStatus = GameStatus.Kick; } if (!client.isRunning) { gameStatus = GameStatus.Kick; }
break; break;
} }
@ -327,7 +329,7 @@ namespace Galactic_Colors_Control_GUI
} }
if (GUI.Button(new Rectangle(ScreenWidth / 2 + 5, ScreenHeight / 4 + 100, 135, 40), buttonsSprites[0], "No", basicFont)) if (GUI.Button(new Rectangle(ScreenWidth / 2 + 5, ScreenHeight / 4 + 100, 135, 40), buttonsSprites[0], "No", basicFont))
{ {
client.Output.Clear(); //TODO client.Output.Clear();
client.ResetHost(); client.ResetHost();
GUI.ResetFocus(); GUI.ResetFocus();
showYNMessage = false; showYNMessage = false;
@ -406,7 +408,7 @@ namespace Galactic_Colors_Control_GUI
if (showChat) if (showChat)
{ {
GUI.Box(new Rectangle(0, 30, 310, 310), buttonsSprites[0]); GUI.Box(new Rectangle(0, 30, 310, 310), buttonsSprites[0]);
if (GUI.TextField(new Rectangle(5, 35, 305, 20), ref chatInput, basicFont, null, Manager.textAlign.centerLeft, "Enter message")) { if (chatInput != null) { ChatAdd(chatInput); client.SendRequest(chatInput); chatInput = null; } } //TODO if (GUI.TextField(new Rectangle(5, 35, 305, 20), ref chatInput, basicFont, null, Manager.textAlign.centerLeft, "Enter message")) { if (chatInput != null) { ChatAdd(chatInput); client.SendRequest(chatInput); chatInput = null; } }
GUI.Label(new Rectangle(5, 60, 305, 245), chatText, smallFont, null, Manager.textAlign.topLeft, true); GUI.Label(new Rectangle(5, 60, 305, 245), chatText, smallFont, null, Manager.textAlign.topLeft, true);
} }
@ -446,9 +448,9 @@ namespace Galactic_Colors_Control_GUI
{ {
messageTitle = "Error"; messageTitle = "Error";
messageText = string.Empty; messageText = string.Empty;
foreach (string line in client.Output.ToArray()) { messageText += (line + Environment.NewLine); } //TODO foreach (string line in client.Output.ToArray()) { messageText += (line + Environment.NewLine); }
showOKMessage = true; showOKMessage = true;
client.Output.Clear(); //TODO client.Output.Clear();
client.ResetHost(); ; client.ResetHost(); ;
} }
else else
@ -470,9 +472,9 @@ namespace Galactic_Colors_Control_GUI
{ {
messageTitle = "Error"; messageTitle = "Error";
messageText = string.Empty; messageText = string.Empty;
foreach (string line in client.Output.ToArray()) { messageText += (line + Environment.NewLine); } //TODO foreach (string line in client.Output.ToArray()) { messageText += (line + Environment.NewLine); }
showOKMessage = true; showOKMessage = true;
client.Output.Clear(); //TODO client.Output.Clear();
client.ResetHost(); client.ResetHost();
} }
showLoading = false; showLoading = false;
@ -485,9 +487,9 @@ namespace Galactic_Colors_Control_GUI
{ {
if (username.Length > 3) if (username.Length > 3)
{ {
client.Output.Clear(); //TODO client.Output.Clear();
client.SendRequest("/connect " + username); //TODO client.SendRequest("/connect " + username);
int wait = 0; /*int wait = 0;
while (wait < 20) while (wait < 20)
{ {
if (client.Output.Count > 0) if (client.Output.Count > 0)
@ -523,7 +525,7 @@ namespace Galactic_Colors_Control_GUI
showOKMessage = true; showOKMessage = true;
showLoading = false; showLoading = false;
client.Output.Clear(); client.Output.Clear();
} }*/
} }
} }
showLoading = false; showLoading = false;
@ -533,6 +535,8 @@ namespace Galactic_Colors_Control_GUI
{ {
showLoading = true; showLoading = true;
GUI.ResetFocus(); GUI.ResetFocus();
//TODO
/*
if (showParty) if (showParty)
{ {
client.SendRequest("/party leave"); client.SendRequest("/party leave");
@ -584,7 +588,7 @@ namespace Galactic_Colors_Control_GUI
showLoading = false; showLoading = false;
client.Output.Clear(); client.Output.Clear();
} }
} }*/
} }
private void ChatAdd(string text) private void ChatAdd(string text)

View File

@ -1,4 +1,5 @@
using System; using Galactic_Colors_Control_Common;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
@ -125,7 +126,7 @@ namespace Galactic_Colors_Control_Server
Console.ForegroundColor = Program.config.logForeColor[(int)log.type]; Console.ForegroundColor = Program.config.logForeColor[(int)log.type];
Console.Write("\b"); Console.Write("\b");
Console.WriteLine(DateTime.UtcNow.ToString("[yyyy-MM-dd]", CultureInfo.InvariantCulture) + ": " + log.text); Console.WriteLine(DateTime.UtcNow.ToString("[yyyy-MM-dd]", CultureInfo.InvariantCulture) + ": " + log.text);
Utilities.ConsoleResetColor(); Common.ConsoleResetColor();
Console.Write(">"); Console.Write(">");
} }
} }

View File

@ -54,7 +54,7 @@ namespace Galactic_Colors_Control_Server
break; break;
default: default:
Utilities.ConsoleWrite("Use --debug or --dev"); Common.ConsoleWrite("Use --debug or --dev");
break; break;
} }
} }
@ -92,7 +92,7 @@ namespace Galactic_Colors_Control_Server
string ConsoleInput = Console.ReadLine(); string ConsoleInput = Console.ReadLine();
Console.Write(">"); Console.Write(">");
string[] args = Common.SplitArgs(ConsoleInput); string[] args = Common.SplitArgs(ConsoleInput);
Utilities.ConsoleWrite(new ResultData(-1, Commands.Manager.Execute(args, null, true)).ToSmallString()); Common.ConsoleWrite(new ResultData(-1, Commands.Manager.Execute(args, null, true)).ToSmallString());
ConsoleInput = null; ConsoleInput = null;
} }
} }

View File

@ -1,4 +1,5 @@
using Galactic_Colors_Control_Common.Protocol; using Galactic_Colors_Control_Common;
using Galactic_Colors_Control_Common.Protocol;
using System; using System;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -49,32 +50,6 @@ namespace Galactic_Colors_Control_Server
return Program.clients[soc].partyID; return Program.clients[soc].partyID;
} }
/// <summary>
/// Write line in console with correct colors
/// </summary>
/// <param name="v">Text to write</param>
/// <param name="Fore">Foreground color</param>
/// <param name="Back">Background color</param>
public static void ConsoleWrite(string v, ConsoleColor Fore = ConsoleColor.White, ConsoleColor Back = ConsoleColor.Black)
{
Console.Write("\b");
Console.ForegroundColor = Fore;
Console.BackgroundColor = Back;
Console.WriteLine(v);
ConsoleResetColor();
Console.Write(">");
}
/// <summary>
/// Reset Console Colors
/// For non black background console as Ubuntu
/// </summary>
public static void ConsoleResetColor()
{
Console.ResetColor();
Console.BackgroundColor = ConsoleColor.Black;
}
/// <summary> /// <summary>
/// Send data to specified socket /// Send data to specified socket
/// </summary> /// </summary>
@ -111,7 +86,7 @@ namespace Galactic_Colors_Control_Server
{ {
Send(soc, packet); Send(soc, packet);
} }
ConsoleWrite(packet.ToSmallString()); Common.ConsoleWrite(packet.ToSmallString());
} }
/// <summary> /// <summary>
@ -132,7 +107,7 @@ namespace Galactic_Colors_Control_Server
} }
if (Program.selectedParty == party) if (Program.selectedParty == party)
{ {
ConsoleWrite(data.ToSmallString()); Common.ConsoleWrite(data.ToSmallString());
} }
} }
@ -147,7 +122,7 @@ namespace Galactic_Colors_Control_Server
{ {
if (server) if (server)
{ {
ConsoleWrite(data.ToSmallString()); Common.ConsoleWrite(data.ToSmallString());
} }
else else
{ {

View File

@ -1,4 +1,5 @@
using Galactic_Colors_Control_Common.Protocol; using Galactic_Colors_Control_Common;
using Galactic_Colors_Control_Common.Protocol;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -9,34 +10,62 @@ using System.Threading;
namespace Galactic_Colors_Control namespace Galactic_Colors_Control
{ {
/// <summary>
/// Client CrossPlatform Core
/// </summary>
public class Client public class Client
{ {
private Socket ClientSocket = new Socket private Socket ClientSocket = new Socket
(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public int PORT = 0; public string IP = null; //Server IP
private int _errorCount = 0; public int PORT = 0; //Server Port
private bool _run = true;
public string IP = null;
public struct CoreConfig
{
public int resultsBuffer; //Max amount of waiting results
public int timeout; //Request timeout in ms
public int refresh; //Threads sleep in ms
public CoreConfig(int buffer, int time, int speed)
{
resultsBuffer = buffer;
timeout = time;
refresh = speed;
}
}
public CoreConfig config = new CoreConfig(20, 2000, 200); //Set default config
private int _errorCount = 0; //Leave if > 5
private bool _run = true; //Thread Stop
public bool isRunning { get { return _run; } } public bool isRunning { get { return _run; } }
public List<string> Output = new List<string>();
private int RequestId = 0; private int RequestId = 0;
private List<ResultData> Results = new List<ResultData>();
private Thread RecieveThread; //Main Thread
public EventHandler OnEvent; //Execute on EventData reception (must be short or async)
private Thread RecieveThread; /// <summary>
/// Soft Server Reset
/// </summary>
public void ResetHost() public void ResetHost()
{ {
IP = null; IP = null;
PORT = 0; PORT = 0;
} }
/// <summary>
/// Test and Convert Hostname to Address
/// </summary>
/// <param name="text">Hostname</param>
/// <returns>Address(IP:PORT) or Error(*'text')</returns>
public string ValidateHost(string text) public string ValidateHost(string text)
{ {
if (text == null) { text = ""; } if (text == null) { text = ""; } //Prevent NullException
string[] parts = text.Split(new char[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries); string[] parts = text.Split(new char[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries); //Split IP and Port
if (parts.Length == 0) if (parts.Length == 0) //Default config (localhost)
{ {
parts = new string[] { "" }; parts = new string[] { "" };
PORT = 25001; PORT = 25001;
@ -45,7 +74,7 @@ namespace Galactic_Colors_Control
{ {
if (parts.Length > 1) if (parts.Length > 1)
{ {
if (!int.TryParse(parts[1], out PORT)) { PORT = 0; } if (!int.TryParse(parts[1], out PORT)) { PORT = 0; } //Check Port
if (PORT < 0 || PORT > 65535) { PORT = 0; } if (PORT < 0 || PORT > 65535) { PORT = 0; }
} }
else else
@ -57,29 +86,28 @@ namespace Galactic_Colors_Control
{ {
try try
{ {
IPHostEntry ipHostEntry = Dns.GetHostEntry(parts[0]); IPHostEntry ipHostEntry = Dns.GetHostEntry(parts[0]);//Resolve Hostname
IPAddress host = ipHostEntry.AddressList.First(a => a.AddressFamily == AddressFamily.InterNetwork); IPAddress host = ipHostEntry.AddressList.First(a => a.AddressFamily == AddressFamily.InterNetwork);//Get IPv4
IP = host.ToString(); IP = host.ToString();
return IP + ":" + PORT; return IP + ":" + PORT;
} }
catch (Exception e) catch (Exception e)
{ {
PORT = 0; PORT = 0;
Output.Add(e.Message); return "*" + e.Message;
return null;
} }
} }
else else
{ {
Output.Add("Incorrect Port"); return "*Port Format";
return null;
} }
} }
/// <summary> /// <summary>
/// Set IP and PORT before /// Start Server connection
/// </summary> /// </summary>
/// <returns>Connection succes</returns> /// <remarks>Setup IP and Port before</remarks>
/// <returns>connection success</returns>
public bool ConnectHost() public bool ConnectHost()
{ {
int attempts = 0; int attempts = 0;
@ -89,32 +117,27 @@ namespace Galactic_Colors_Control
try try
{ {
attempts++; attempts++;
Output.Add("Connection attempt " + attempts);
ClientSocket.Connect(IP, PORT); ClientSocket.Connect(IP, PORT);
} }
catch (SocketException) catch (SocketException) { }
{
Output.Clear();
}
} }
if (attempts < 5) if (attempts < 5) //Connection success
{ {
Output.Clear();
Output.Add("Connected to " + IP.ToString());
_run = true; _run = true;
RecieveThread = new Thread(ReceiveLoop); RecieveThread = new Thread(ReceiveLoop); //Starting Main Thread
RecieveThread.Start(); RecieveThread.Start();
return true; return true;
} }
else else
{ {
Output.Clear();
Output.Add("Can't connected to " + IP.ToString());
ResetSocket(); ResetSocket();
return false; return false;
} }
} }
/// <summary>
/// Hard Reset (unsafe)
/// </summary>
private void ResetSocket() private void ResetSocket()
{ {
ClientSocket.Close(); ClientSocket.Close();
@ -128,91 +151,78 @@ namespace Galactic_Colors_Control
public void ExitHost() public void ExitHost()
{ {
Send(new RequestData(GetRequestId(), new string[1] { "exit" }));// Tell the server we are exiting Send(new RequestData(GetRequestId(), new string[1] { "exit" }));// Tell the server we are exiting
_run = false; _run = false; //Stopping Thread
RecieveThread.Join(2000); RecieveThread.Join(2000);
ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Shutdown(SocketShutdown.Both);
ClientSocket.Close(); ClientSocket.Close();
Output.Add("Bye");
ResetHost(); ResetHost();
} }
public void SendRequest(string request) /// <summary>
/// Send RequestData to server
/// </summary>
/// <param name="args">Request args</param>
/// <returns>ResultData or Timeout</returns>
public ResultData Request(string[] args)
{ {
switch (request.ToLower()) // TODO filter Client Side Requests
RequestData req = new RequestData(GetRequestId(), args);
if (!Send(req))
return new ResultData(req.id, ResultTypes.Error, Common.Strings("Send Exception"));
DateTime timeoutDate = DateTime.Now.AddMilliseconds(config.timeout); //Create timeout DataTime
while (timeoutDate > DateTime.Now)
{ {
case "/exit": foreach (ResultData res in Results.ToArray()) //Check all results
ExitHost(); {
break; if (res.id == req.id)
case "/ping":
PingHost();
break;
case "/clear":
Output.Add("/clear");
break;
default:
//TODO add key and send error here
if (request.Length > 0)
{ {
if (request[0] == '/') Results.Remove(res);
{ return res;
request = request.Substring(1);
string[] array = request.Split(new char[1] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries);
if (array.Length > 0)
{
Send(new RequestData(GetRequestId(), array));
}
else
{
Output.Add("Any Command");
}
}
else
{
Send(new RequestData(GetRequestId(), new string[2] { "say", request }));
}
} }
break; }
Thread.Sleep(config.refresh);
} }
return new ResultData(req.id, ResultTypes.Error, Common.Strings("Timeout"));
} }
private void PingHost() /// <summary>
/// Ping Current Server IP
/// </summary>
/// <returns>Time in ms or 'Timeout'</returns>
private string PingHost()
{ {
Ping p = new Ping(); Ping ping = new Ping();
PingReply r; PingReply reply;
r = p.Send(IP); reply = ping.Send(IP);
if (reply.Status == IPStatus.Success)
return reply.RoundtripTime.ToString();
if (r.Status == IPStatus.Success) return "Timeout";
{
Output.Add(r.RoundtripTime.ToString() + " ms.");
}
else
{
Output.Add("Time out");
}
} }
private void Send(Data packet) /// <summary>
/// Send Data object to server
/// </summary>
/// <returns>Send success</returns>
private bool Send(Data packet)
{ {
try try
{ {
ClientSocket.Send(packet.ToBytes()); ClientSocket.Send(packet.ToBytes());
return true;
} }
catch catch //Can't contact server
{ {
Output.Add("Can't contact server : " + _errorCount);
_errorCount++; _errorCount++;
} }
if (_errorCount >= 5) return false;
{
Output.Add("Kick : too_much_errors");
_run = false;
}
} }
/// <summary>
/// Main Thread
/// </summary>
private void ReceiveLoop() private void ReceiveLoop()
{ {
while (_run) while (_run)
@ -225,40 +235,40 @@ namespace Galactic_Colors_Control
} }
catch catch
{ {
Output.Add("Server timeout"); _errorCount++;
}
if (_errorCount >= 5)
{
_run = false;
} }
if (received == 0) return; if (received == 0) return;
_errorCount = 0; _errorCount = 0;
var data = new byte[received]; var data = new byte[received];
Array.Copy(buffer, data, received); Array.Copy(buffer, data, received);
Data packet = Data.FromBytes(ref data); Data packet = Data.FromBytes(ref data); //Create Data object from recieve bytes
if (packet != null) if (packet != null)
{ {
switch (packet.GetType().Name) switch (packet.GetType().Name)
{ {
case "EventData": case "EventData":
EventData eve = (EventData)packet; EventData eve = (EventData)packet;
Output.Add(eve.ToSmallString()); if (OnEvent != null)
OnEvent.Invoke(this, new EventDataArgs(eve));
break; break;
case "ResultData": case "ResultData":
ResultData res = (ResultData)packet; ResultData res = (ResultData)packet;
Output.Add(res.ToSmallString()); ResultAdd(res);
break; break;
default: default: //Ignore others Packets
Output.Add("Wrong packet");
break; break;
} }
} }
else Thread.Sleep(config.refresh);
{
Output.Add("Wrong packet");
}
Thread.Sleep(200);
} }
Output.Add("/*exit*/"); //TODOOutput.Add("/*exit*/");
} }
public int GetRequestId(bool indent = true) public int GetRequestId(bool indent = true)
@ -266,5 +276,14 @@ namespace Galactic_Colors_Control
if (indent) { RequestId++; } if (indent) { RequestId++; }
return RequestId; return RequestId;
} }
/// <summary>
/// Add to Results
/// </summary>
public void ResultAdd(ResultData res)
{
while (Results.Count + 1 > config.resultsBuffer) { Results.RemoveAt(0); } //Removes firsts
Results.Add(res);
}
} }
} }