ModernUO/Scripts/Misc/ServerList.cs

156 lines
No EOL
3.6 KiB
C#

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using Server;
using Server.Network;
namespace Server.Misc
{
public class ServerList
{
/* Address:
*
* The default setting, a value of 'null', will attempt to detect your IP address automatically:
* private const string Address = null;
*
* This detection, however, does not work for servers behind routers. If you're running behind a router, put in your IP:
* private const string Address = "12.34.56.78";
*
* If you need to resolve a DNS host name, you can do that too:
* private const string Address = "shard.host.com";
*/
public static readonly string Address = null;
public static readonly string ServerName = "RunUO TC";
public static readonly bool AutoDetect = true;
public static void Initialize()
{
Listener.Port = 2593;
if ( Address == null ) {
if ( AutoDetect )
AutoDetection();
}
else {
Resolve( Address, out m_PublicAddress );
}
EventSink.ServerList += new ServerListEventHandler( EventSink_ServerList );
}
private static IPAddress m_PublicAddress;
private static void EventSink_ServerList( ServerListEventArgs e )
{
try
{
NetState ns = e.State;
Socket s = ns.Socket;
IPEndPoint ipep = (IPEndPoint)s.LocalEndPoint;
IPAddress localAddress = ipep.Address;
int localPort = ipep.Port;
if ( IsPrivateNetwork( localAddress ) ) {
ipep = (IPEndPoint)s.RemoteEndPoint;
if ( !IsPrivateNetwork( ipep.Address ) && m_PublicAddress != null )
localAddress = m_PublicAddress;
}
e.AddServer( ServerName, new IPEndPoint( localAddress, localPort ) );
}
catch
{
e.Rejected = true;
}
}
private static void AutoDetection()
{
if ( !HasPublicIPAddress() ) {
Console.Write( "ServerList: Auto-detecting public IP address..." );
m_PublicAddress = FindPublicAddress();
if ( m_PublicAddress != null )
Console.WriteLine( "done ({0})", m_PublicAddress.ToString() );
else
Console.WriteLine( "failed" );
}
}
private 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 {}
return false;
}
private static bool HasPublicIPAddress()
{
IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() );
IPAddress[] ips = iphe.AddressList;
for ( int i = 0; i < ips.Length; ++i )
if ( !IsPrivateNetwork( ips[i] ) )
return true;
return false;
}
private static bool IsPrivateNetwork( IPAddress ip )
{
// 10.0.0.0/8
// 172.16.0.0/12
// 192.168.0.0/16
if ( Utility.IPMatch( "192.168.*", ip ) )
return true;
else if ( Utility.IPMatch( "10.*", ip ) )
return true;
else if ( Utility.IPMatch( "172.16-31.*", ip ) )
return true;
else
return false;
}
private static IPAddress FindPublicAddress()
{
try {
WebRequest req = HttpWebRequest.Create( "http://www.runuo.com/ip.php" );
req.Timeout = 15000;
WebResponse res = req.GetResponse();
Stream s = res.GetResponseStream();
StreamReader sr = new StreamReader( s );
IPAddress ip = IPAddress.Parse( sr.ReadLine() );
sr.Close();
s.Close();
res.Close();
return ip;
} catch {
return null;
}
}
}
}