/**********************************************************
RunUO AoV C# script file
Official Age of Valor Script :: www.uovalor.com
Last modified by Red Squirrel on Feb-12-2011 07:52:20pm
Filepath: scripts\Misc\ServerList.cs
Lines of code: 153

Description: 

***********************************************************/


using System;
using System.Net;
using System.Net.Sockets;
using Server;
using System.IO;
using Server.Network;
using System.Collections;
using System.Collections.Generic;

namespace Server.Misc
{
	public class ServerList
	{

		public static readonly string Address = "login.uovalor.com";
		public const string ServerName = "Age of Valor";
		
		public class ServerEntry
		{
			private IPAddress ip;
			private int port;
			private string host;
			private string name;
			private bool resolved;
			
			public string GetName()
			{
				return name;
			}
			
			public IPEndPoint GetIPEndPoint()
			{
				return new IPEndPoint(ip,port);
			}
			
			public bool TryResolve()
			{
				if(resolved)return true;
				if(Resolve(host, out ip ))
				{	
					Console.WriteLine("Resolved server list entry: {0} to {1}",host,ip);
					resolved=true;
					return true;
				}
				Console.WriteLine("Failed to resolve server list entry: {0} will retry later",host);
				return false;				
			}
			
			
			public ServerEntry(string pname,string phost,int pport)
			{
				port=pport;
				host=phost;
				name=pname;
				resolved=false;
				new ResolveTimer(this).Start();
			}			
			
			public class ResolveTimer : Timer
			{
				ServerEntry owner;
				
				public ResolveTimer(ServerEntry entry) : base( TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(30) )
				{
					owner=entry;
					Priority = TimerPriority.FiveSeconds;
				}
				
				protected override void OnTick()
				{				
					if(owner.TryResolve())Stop();	
				}
			}
		}
		
		private static List<ServerEntry> ServerEntries = new List<ServerEntry>();
		
		
		public static void Initialize()
		{
			
			//Load server list info from file, if file does not exist, create it			
			
			bool first=true;
			
			if(File.Exists("localconfig\\serverlist.txt"))
			{
				using(StreamReader  sr = new StreamReader("localconfig\\serverlist.txt"))
				{
					
					try
					{
						while (sr.Peek() >= 0) 
						{
							string fullstr = sr.ReadLine();
							
							string[] components = fullstr.Split(':');
							
							string cserver=components[0];
							string cport=components[1];
							string cdesc=components[2];
							
							if(cserver=="" || cport=="" || cdesc=="")continue;	

							if(first)
							{
								first=false;
								Listener.Port = Convert.ToInt32(cport);
							}
							
							ServerEntries.Add(new ServerEntry(cdesc,cserver,Convert.ToInt32(cport)));
						}
					}
					catch (Exception e)
					{
						Console.WriteLine("Error loading server list... {0}",e.ToString());
						Console.ReadKey();
					}
					
				}
			}			
			else
			{
				StreamWriter SW= new StreamWriter("localconfig\\serverlist.txt");
				SW.Write("localhost:1337:localhost");
				SW.Close();
				
				Console.WriteLine("serverlist.txt not found, created default...");
				
				ServerEntries.Add(new ServerEntry("localhost","localhost",1337));
			}
			
			
			
			
			
			
			
			
			/*Listener.Port = 1337;
			
			ServerEntries.Add(new ServerEntry("Age of Valor","uosrv.uovalor.com",1337));
			ServerEntries.Add(new ServerEntry("TC1 Public","tc1.uovalor.com",1337));
			ServerEntries.Add(new ServerEntry("DEV1 Private","aovdev.loc",1337));			
			*/

			EventSink.ServerList += new ServerListEventHandler( EventSink_ServerList );
		}		

		public static void EventSink_ServerList( ServerListEventArgs e )
		{
			try
			{
				for(int i=0;i<ServerEntries.Count;i++)
				{
					if(ServerEntries[i].TryResolve()) e.AddServer(ServerEntries[i].GetName(),ServerEntries[i].GetIPEndPoint());
				}
			}
			catch
			{
				e.Rejected = true;
			}
		}

		public static bool Resolve( string addr, out IPAddress outValue )
		{

            if ( IPAddress.TryParse( addr, out outValue ) )
                return true;

			try
			{
				IPHostEntry iphe = Dns.GetHostEntry( addr );

				if ( iphe.AddressList.Length > 0 )
				{
					outValue = iphe.AddressList[iphe.AddressList.Length - 1];
					return true;
				}
			}
			catch
			{
			}

			outValue = IPAddress.None;
			return false;
		}

		private static bool IsLocalMachine( NetState state )
		{
			Socket sock = state.Socket;

			IPAddress theirAddress = ((IPEndPoint)sock.RemoteEndPoint).Address;

			if ( IPAddress.IsLoopback( theirAddress ) )
				return true;

			bool contains = false;

			IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() );

			for ( int i = 0; !contains && i < iphe.AddressList.Length; ++i )
				contains = theirAddress.Equals( iphe.AddressList[i] );

			return contains;
		}
	}
}