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";
}
}
}