public AjaxLife(string[] arg)
{
// Parse the command line arguments. See CommandLine.cs.
CommandLineArgs args = new CommandLineArgs(arg);
// Set various options if they're specified.
string gridfile = "Grids.txt";
if (args["gridfile"] != null)
{
gridfile = args["gridfile"];
}
// Read in the grids. Loop through the space-separated file, adding them to the dictionary.
// Since there's no way of maintaining order, we also store the default separately.
Console.WriteLine("Reading grids from " + gridfile);
string[] grids = File.ReadAllLines(gridfile);
LoginServers = new Dictionary<string, string>();
bool defaulted = false;
foreach (string grid in grids)
{
string[] split = new string[1];
split[0] = " ";
string[] griddata = grid.Trim().Split(split, 2, StringSplitOptions.RemoveEmptyEntries);
LoginServers.Add(griddata[1], griddata[0]);
if (!defaulted)
{
DefaultLoginServer = griddata[1];
defaulted = true;
}
Console.WriteLine("Loaded grid " + griddata[1] + " (" + griddata[0] + ")");
}
Console.WriteLine("Default grid: " + DEFAULT_LOGIN_SERVER);
// More fun option setting.
if (args["root"] != null)
{
StaticRoot = args["root"];
}
if(!StaticRoot.EndsWith("/"))
{
StaticRoot += "/";
}
Console.WriteLine("Static root: " + STATIC_ROOT);
if (args["texturecache"] != null)
{
TextureCache = args["texturecache"];
}
// TextureCache must end with a forward slash. Make sure it does.
if (!TextureCache.EndsWith("/"))
{
TextureCache += "/";
}
if(args["texturebucket"] != null)
{
TextureBucket = args["texturebucket"];
}
if(args["textureroot"] != null)
{
TextureRoot = args["textureroot"];
}
if (args["mac"] != null)
{
MacAddress = args["mac"];
}
Console.WriteLine("Using MAC address: " + MAC_ADDRESS);
if (args["id0"] != null)
{
Id0 = args["id0"];
}
Console.WriteLine("Using id0: " + (ID0 == "" ? "[blank]" : ID0));
if (args["banlist"] != null)
{
BanList = args["banlist"];
}
if(BanList != "")
{
Console.WriteLine("Using banlist at "+BanList);
if (args["banupdate"] != null)
{
BanUpdateTime = double.Parse(args["banupdate"]);
}
if(BanUpdateTime > 0.0)
{
Console.WriteLine("Updating the banlist every "+BanUpdateTime+" seconds.");
}
else
{
Console.WriteLine("Banlist updating disabled.");
}
}
else
{
Console.WriteLine("Not using ban list.");
}
HandleContentEncoding = (args["doencoding"] != null);
Console.WriteLine("Handling content encoding: " + (HANDLE_CONTENT_ENCODING ? "Yes" : "No"));
if(args["spamdebug"] != null)
{
DebugMode = true;
Settings.LOG_LEVEL = Helpers.LogLevel.Debug;
}
else if(args["debug"] != null)
{
DebugMode = true;
Settings.LOG_LEVEL = Helpers.LogLevel.Info;
}
else
{
Settings.LOG_LEVEL = Helpers.LogLevel.Error;
}
Console.WriteLine("Debug mode: " + (DEBUG_MODE ? "On" : "Off"));
// Create an empty dictionary for the users. This is defined as public further up.
Users = new Dictionary<Guid, User>();
// Make a web server!
HttpWebServer webserver = new HttpWebServer((args["port"]!=null)?int.Parse(args["port"]):8080);
try
{
// If the "private" CLI argument was specified, make it private by making us only
// listen to the loopback address (127.0.0.0)
if (args["private"] != null)
{
webserver.LocalAddress = System.Net.IPAddress.Loopback;
Console.WriteLine("Using private mode.");
}
}
catch
{
// If we can't make it private, oh well.
}
// Make sure we have a usable texture cache, create it if not.
// If we're using S3, this is just used for conversions. If we're using
// our own texture system, we store textures here for client use.
Console.WriteLine("Checking texture cache...");
if (!Directory.Exists(TEXTURE_CACHE))
{
Console.WriteLine("Not found; Attempting to create texture cache...");
try
{
Directory.CreateDirectory(TEXTURE_CACHE);
Console.WriteLine("Created texture cache.");
}
catch
{
Console.WriteLine("Failed to create texture cache at " + TEXTURE_CACHE + "; aborting.");
return;
}
}
Console.WriteLine("Initialising RSA service...");
RSA = new RSACrypto();
// Create a new RSA keypair with the specified length. 1024 if unspecified.
RSA.InitCrypto((args["keylength"]==null)?1024:int.Parse(args["keylength"]));
RSAp = RSA.ExportParameters(true);
Console.WriteLine("Generated " + ((args["keylength"] == null) ? 1024 : int.Parse(args["keylength"])) + "-bit key.");
Console.WriteLine("RSA ready.");
// Grab the S3 details off the command line if available.
S3Config = new Affirma.ThreeSharp.ThreeSharpConfig();
S3Config.AwsAccessKeyID = (args["s3key"] == null) ? AccessKey : args["s3key"];
S3Config.AwsSecretAccessKey = (args["s3secret"] == null) ? PrivateAccessKey : args["s3secret"];
// Check that, if we're using S3, we have enough information to do so.
if(TextureBucket != "" && (S3Config.AwsAccessKeyID == "" || S3Config.AwsSecretAccessKey == "" || TextureRoot == ""))
{
Console.WriteLine("Error: To use S3 you must set s3key, s3secret, texturebucket and textureroot");
return;
}
UseS3 = (TextureBucket != ""); // We're using S3 if TextureBucket is not blank.
if (UseS3)
{
Console.WriteLine("Texture root: " + TEXTURE_ROOT);
Console.WriteLine("Using Amazon S3 for textures:");
Console.WriteLine("\tBucket: " + TEXTURE_BUCKET);
Console.WriteLine("\tAccess key: " + S3Config.AwsAccessKeyID);
Console.WriteLine("\tSecret: ".PadRight(S3Config.AwsSecretAccessKey.Length + 10, '*'));
}
else
{
TextureRoot = "textures/"; // Set the texture root to ourselves if not using S3.
Console.WriteLine("Using internal server for textures:");
Console.WriteLine("\tTexture root: " + TEXTURE_ROOT);
}
Console.WriteLine("Setting up pages...");
// Set up the root.
VirtualDirectory root = new VirtualDirectory();
webserver.Root = root;
#region Dynamic file setup
// Create the virtual files, passing most of them (except index.html and differentorigin.kat,
// as they don't need to deal with SL) the Users dictionary. Users is a reference object,
// so changes are reflected in all the pages. The same goes for individual User objects.
root.AddFile(new Html.MainPage("index.html", root, Users));
root.AddFile(new Html.Proxy("differentorigin.kat", root));
root.AddFile(new Html.BasicStats("ping.kat", root, Users));
root.AddFile(new Html.MakeFile("makefile.kat", root));
root.AddFile(new Html.iPhone("iphone.kat", root));
root.AddFile("robots.txt");
// textures/ is only used if we aren't using S3 for textures.
if(!UseS3)
{
root.AddDirectory(new DriveDirectory("textures", AjaxLife.TEXTURE_CACHE, root));
}
root.AddDirectory(new DriveDirectory("client", "client", root));
// API stuff.
VirtualDirectory api = new VirtualDirectory("api", root);
root.AddDirectory(api);
api.AddFile(new Html.CreateSession("newsession", api, Users));
api.AddFile(new Html.SendMessage("send", api, Users));
api.AddFile(new Html.EventQueue("events", api, Users));
api.AddFile(new Html.Logout("logout", api, Users));
api.AddFile(new Html.Connect("login", api, Users));
api.AddFile(new Html.LoginDetails("sessiondetails", api, Users));
#endregion
Console.WriteLine("Loading banlist...");
BannedUsers = new BanList(); // Create BanList.
Console.WriteLine("Starting server...");
// Start the webserver.
webserver.Start();
// Set a timer to call timecheck() every five seconds to check for timed out sessions.
System.Timers.Timer timer = new System.Timers.Timer(5000);
timer.AutoReset = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timecheck);
timer.Start();
// Sleep forever. Note that this means nothing after this line ever gets executed.
// We do this because no more processing takes place in this thread.
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
// We never get past this point, so all code past here has been deleted for now.
}