using System; using System.Collections.Generic; using System.Collections; using System.Text; using System.IO; using System.Net; using System.Net.Sockets; namespace BeIT_APS_Socket_Server { /// /// The standard Module that handles any standard commands between the server and client. /// class StandardModule : Zone { private Int64 _baseLatency; /// /// The latency in 100 nanosecond intervals (supposedly) thus a readable latency /// would be: latency*100 / 1,000,000 = milliseconds public Int64 latency { get { return _baseLatency; } set { _baseLatency = value; } } private Boolean _isAdmin; /// /// Is the user an authenticated admin? /// public Boolean isAdmin { get { return _isAdmin; } set { _isAdmin = value; } } private Boolean _isLoggedIn; /// /// Is the user Logged In ? /// public Boolean isLoggedIn { get { return _isLoggedIn; } set { _isLoggedIn = value; } } private List _zones; /// /// The accessor for all of the zones. /// public List registeredZones { get { return _zones; } set { _zones = value; } } /// /// The Module Constructor. Assigns the netHandler /// Takes a TcpClient from the TcpListener Server in /// netHandler.cs public StandardModule(netHandlerClientIO clientIO) { setIOHandler(clientIO); isAdmin = false; isLoggedIn = false; } /// /// Analyses the client reply, then runs the appropriate command. Virtual to be overidden /// by custom Modules. /// Expects a String with the command name as the first word in caps /// then follows the commands params. "eg: LOGIN "Matthew Lloyd" "12345"" /// It requires an Object input since the ParameterizedThreadStart() needs a method /// that accepts only objects as its input. public override void runCommand(Object cmd) { String[] command = ((String) cmd).Trim().Split(new Char[] { ' ' }); switch (command[0]) { case "LOGIN": handleLogin(command); break; case "PING?": ReplypingPong((String) cmd); break; case "PONG!": ReplypingPong((String) cmd); break; } } /// /// Login to the socket server. /// /// The parsed command line with the Login parameters. public void handleLogin(String[] command) { ServerSettings svrSettings = new ServerSettings(); if (command[2] == svrSettings.LoginPassword) { isAdmin = true; socketInOut.sendData("LOGIN TRUE TRUE \"Welcome " + command[1] + " to the Admin System\""); } else { isAdmin = false; socketInOut.sendData("LOGIN TRUE FALSE \"Welcome " + command[1] + " to the User System\""); } isLoggedIn = true; } /// /// Replys to a PING? request. Updates Latency, and outputs to Standard Output /// Expects a string similar to "PING? 12345" where the first command /// param is the number of seconds since 1970. private void ReplypingPong(String input) { String[] PingSplit = input.Split(new char[] { ' ' }); updateLatency(Convert.ToInt64(PingSplit[1], 10)); Console.WriteLine("Client Latency: {0}", showLatency()); String output = pingPong(input); socketInOut.sendData(output); } /// /// Gives a Reply to a PING or PONG request /// Only expects either "PING? " or "PONG! " /// Either PING? 12345, PONG! 12345 or "*" depending on input private String pingPong(String input) { DateTime now = DateTime.Now; if (input == "") return "PING? " + now.Ticks.ToString(); else if (input.StartsWith("PING?")) return "PONG! " + now.Ticks.ToString(); return "*"; } /// /// Gives a Reply to a PING or PONG request /// Either PING? 12345, PONG! 12345 or "*" depending on input public String pingPong() { return pingPong(""); } /// /// Updates latency between the Server and the Client /// /// The number of milliseconds since midnight January 1, 1970 private void updateLatency(Int64 milliSec) { DateTime now = DateTime.UtcNow; DateTime then = new DateTime(milliSec * 10000); DateTime yearCutout = new DateTime(now.Year, 1, 1, 0, 0, 0, 0); DateTime secondYearCutout = new DateTime(then.Year, 1, 1, 0, 0, 0, 0); TimeSpan nowWithoutYear = now.Subtract(yearCutout); TimeSpan thenWithoutYear = then.Subtract(secondYearCutout); latency = nowWithoutYear.Ticks - thenWithoutYear.Ticks; } /// /// Returns the latency in milliseconds with the units added on. /// /// The converted Server-Client Latency from nanoseconds to Milliseconds with the units added on public String showLatency() { return (((Double)latency) * 0.00001).ToString() + " ms"; } } }