All pastes #197857 Raw Edit

Anonymous

public text v1 · immutable
·published 2006-10-11 15:53 UTC
rendered paste body
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
{

	/// <summary>
	/// The standard Module that handles any standard commands between the server and client.
	/// </summary>
	class StandardModule : Zone
	{		
		private Int64 _baseLatency;

		/// <summary>
		/// The latency in 100 nanosecond intervals (supposedly) thus a readable latency
		/// would be: latency*100 / 1,000,000 = milliseconds </summary>
		public Int64 latency { get { return _baseLatency; } set { _baseLatency = value; } }


		private Boolean _isAdmin;

		/// <summary>
		/// Is the user an authenticated admin?
		/// </summary>
		public Boolean isAdmin { get { return _isAdmin; } set { _isAdmin = value; } }


		private Boolean _isLoggedIn;

		/// <summary>
		/// Is the user Logged In ?
		/// </summary>
		public Boolean isLoggedIn { get { return _isLoggedIn; } set { _isLoggedIn = value; } }


		private List<Zone> _zones;

		/// <summary>
		/// The accessor for all of the zones.
		/// </summary>
		public List<Zone> registeredZones { get { return _zones; } set { _zones = value; } }


		/// <summary>
		/// The Module Constructor. Assigns the netHandler </summary>
		/// <param name="client">Takes a TcpClient from the TcpListener Server in 
		/// netHandler.cs</param>
		public StandardModule(netHandlerClientIO clientIO)
		{
			setIOHandler(clientIO);
			isAdmin = false;
			isLoggedIn = false;
		}

		/// <summary>
		/// Analyses the client reply, then runs the appropriate command. Virtual to be overidden
		/// by custom Modules.</summary>
		/// <param name="cmd">Expects a String with the command name as the first word in caps
		/// then follows the commands params. "eg: LOGIN "Matthew Lloyd" "12345""</param>
		/// <remarks>It requires an Object input since the ParameterizedThreadStart() needs a method
		/// that accepts only objects as its input.</remarks>
		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;
			}
		}

		/// <summary>
		/// Login to the socket server.
		/// </summary>
		/// <param name="command">The parsed command line with the Login parameters.</param>
		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;
		}

		/// <summary>
		/// Replys to a PING? request. Updates Latency, and outputs to Standard Output</summary>
		/// <param name="input">Expects a string similar to "PING? 12345" where the first command
		/// param is the number of seconds since 1970.</param>
		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);
		}

		/// <summary>
		/// Gives a Reply to a PING or PONG request</summary>
		/// <param name="input">Only expects either "PING? " or "PONG! "</param>
		/// <returns>Either PING? 12345, PONG! 12345 or "*" depending on input</returns>
		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 "*";
		}

		/// <summary>
		/// Gives a Reply to a PING or PONG request</summary>
		/// <returns>Either PING? 12345, PONG! 12345 or "*" depending on input</returns>
		public String pingPong()
		{
			return pingPong("");
		}

		/// <summary>
		/// Updates latency between the Server and the Client
		/// </summary>
		/// <param name="milliSec">The number of milliseconds since midnight January 1, 1970</param>
		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;
		}

		/// <summary>
		/// Returns the latency in milliseconds with the units added on.
		/// </summary>
		/// <returns>The converted Server-Client Latency from nanoseconds to Milliseconds with the units added on</returns>
		public String showLatency()
		{
			return (((Double)latency) * 0.00001).ToString() + " ms";
		}
	}
}