// TODO: Execute main code in a async task. static void Main(string[] args) { bool acceptAny = false; bool allowRegistration = false; ushort port = 3221; #region Read command line params for (int i = 0; i < args.Length; ++i) { var arg = args[i]; if (!arg.StartsWith("-", StringComparison.Ordinal) && !arg.StartsWith("/", StringComparison.Ordinal)) { Console.WriteLine("Parameters must start with '-' or '/'. Use '-?' to show help."); return; } if (arg.Length == 1) { continue; } arg = arg.Substring(1, arg.Length - 1); if (arg == "acceptany") { acceptAny = true; continue; } else if (arg.StartsWith("port=")) { var spl = arg.Split('='); if (spl.Length != 2 || !ushort.TryParse(spl[1], out port)) { Console.WriteLine("Error in parameter 'port'"); return; } } else { Console.WriteLine( "Access Battle Server\r\n\r\n" + "Usage: AccessBattleServer [-acceptany] [-port=3221]\r\n" + "\r\nOptions:\r\n" + "\t-port=3221 Define the port to use. Default: 3221\r\n" + "\t-acceptany Accept any client. Disables user database.\r\n" + "\t Clients will not require a password." + "\r\nUsing '/' instead of '-' is allowed.\r\n" ); return; } } #endregion Log.SetMode(LogMode.Console); Log.Priority = LogPriority.Information; // Create userdb folder if not existing IUserDatabaseProvider db = null; if (!acceptAny) { Console.WriteLine("=============="); Console.WriteLine("Database Setup"); Console.WriteLine("=============="); var plugins = PluginHandler.Instance.GetPlugins <IUserDatabaseProviderFactory>(); if (plugins.Count == 0) { Console.WriteLine("No database plugin found."); } Console.WriteLine("Please select an option:\r\n"); Console.WriteLine("\t1: Accept any client (no database)"); Console.WriteLine("\t2: Text based database"); for (int i = 0; i < plugins.Count; ++i) { Console.WriteLine("\t" + (i + 3) + ": " + plugins[i].Metadata.Description); } Console.WriteLine("\r\nEnter the number of the option."); if (int.TryParse(Console.ReadLine(), out int ichoice) && ichoice > 0 && ichoice <= plugins.Count + 2) { if (ichoice == 1) { acceptAny = true; } else if (ichoice == 2) { db = new TextFileUserDatabaseProvider(); } else { db = plugins[ichoice - 3].CreateInstance(); } if (!acceptAny) { Console.WriteLine("\r\nAre users allowed to create accounts?"); Console.WriteLine("Please select an option:\r\n"); Console.WriteLine("\t1: No"); Console.WriteLine("\t2: Yes"); if (int.TryParse(Console.ReadLine(), out int jchoice) && jchoice > 0 && jchoice < 3) { if (jchoice == 2) { allowRegistration = true; } } else { Console.WriteLine("Invalid choice! Selecting option 'No'."); } } } else { Console.WriteLine("Invalid choice! Server will exit."); return; } } try { if (!acceptAny) // Have to check again { try { Console.WriteLine("\r\n" + db.ConnectStringHint); var connectString = Console.ReadLine(); if (!db.Connect(connectString).GetAwaiter().GetResult()) { Log.WriteLine(LogPriority.Error, "Connecting to database failed. Server will exit."); return; } Console.WriteLine(); } catch (Exception e) { Log.WriteLine(LogPriority.Error, "Error setting up database: " + e.Message); Console.WriteLine("Server will exit."); return; } } _server = new GameServer(port, db) { AcceptAnyClient = acceptAny, AllowRegistration = allowRegistration }; try { _server.Start(); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); Console.WriteLine("Server will exit."); return; } Console.WriteLine("Game Server started"); if (acceptAny) { Console.WriteLine("! Any client is accepted"); } if (allowRegistration) { Console.WriteLine("! Any client can create an account"); } Console.WriteLine("Type 'help' to show available commands"); string line; while ((line = Console.ReadLine()) != "exit") { bool ok = false; line = line.Trim(); if (line == ("help")) { Console.WriteLine( "\texit Close this program.\r\n" + "\tlist List all games\r\n" + "\tadd user n p elo Adds user 'u' with password 'p'. elo is optional ELO rating (default:1000) \r\n" + "\tmcpw user Check if user must change password\r\n" + "\tset elo user elo Set ELO rating for user\r\n" + "\tget elo user Get ELO rating for user\r\n" + "\tdebug Debug command. Requires additional parameters:\r\n" + "\t win key=1234 1 Let player 1 win. Uses game key.\r\n" + "\t win name=gameX 2 Let player 2 win. Uses game name."); ok = true; } else if (line == ("list")) { var games = _server.Games.ToList(); if (games.Count == 0) { Console.WriteLine("There are no games");; } else { foreach (var game in games) { Console.WriteLine(game.Key + " - " + game.Value.Name); } } ok = true; } else if (line.StartsWith("set")) { if (line.StartsWith("set elo")) { if (db == null) { continue; } var sp = line.Split(' '); if (sp.Length == 4) { int elo; if (int.TryParse(sp[3], out elo)) { if (db.SetELO(sp[2], elo).GetAwaiter().GetResult()) { ok = true; } } } } } else if (line.StartsWith("get")) { if (line.StartsWith("get elo")) { if (db == null) { continue; } var sp = line.Split(' '); if (sp.Length == 3) { var elo = db.GetELO(sp[2]).GetAwaiter().GetResult(); if (elo != null) { Console.WriteLine("ELO: " + elo); ok = true; } } } } else if (line.StartsWith("mcpw")) { if (db == null) { continue; } var sp = line.Split(' '); if (sp.Length == 2) { bool?res = db.MustChangePasswordAsync(sp[1]).GetAwaiter().GetResult(); if (res == true) { Console.WriteLine("User must change password"); ok = true; } else if (res == false) { Console.WriteLine("User must not change password"); ok = true; } } } else if (line.StartsWith("debug ", StringComparison.Ordinal)) { var sp = line.Split(' '); if (sp.Length == 4) { if (sp[1] == "win") { uint k = 0; var spx = sp[2].Split('='); if (spx.Length != 2) { continue; } if (spx[0] == "key") { if (!uint.TryParse(spx[1], out k)) { continue; } } else if (spx[0] == "name") { k = _server.Games.FirstOrDefault(o => o.Value.Name == spx[1]).Key; } if (k == 0) { continue; } int p; if (!int.TryParse(sp[3], out p)) { continue; } _server.Win(p, k); ok = true; } } } else if (line.StartsWith("add user ", StringComparison.Ordinal)) { if (db == null) { continue; } var spl = line.Split(' '); if (spl.Length == 4 || spl.Length == 5) { int elo = 1000; if (spl.Length == 5 && !int.TryParse(spl[4], out elo)) { elo = 1000; } if (elo < 0) { elo = 0; } if (elo > 10000) { elo = 10000; } var pw = new System.Security.SecureString(); foreach (var c in spl[3]) { pw.AppendChar(c); } if (db.AddUserAsync(spl[2], pw, elo, true).GetAwaiter().GetResult()) { Console.WriteLine("user added"); } else { Console.WriteLine("add failed"); } ok = true; } } if (!ok) { Console.WriteLine("error"); } } } finally { Log.WriteLine(LogPriority.Information, "Stopping Server..."); _server?.Stop(); db?.Disconnect(); #if DEBUG Console.WriteLine("Press any key to exit..."); Console.ReadKey(); #endif Log.WriteLine(LogPriority.Information, "Game Server stopped"); } }
static void Main(string[] args) { // Testcode //string hash, salt; //PasswordHasher.GetNewHash("passw0rd", out hash, out salt); //Console.WriteLine(hash); //Console.WriteLine(salt); //Console.WriteLine(PasswordHasher.VerifyHash("passw0rd", hash, salt)); // ---------------- bool acceptAny = false; ushort port = 3221; string dbPath = "userdb.txt"; // Read command line params for (int i = 0; i < args.Length; ++i) { var arg = args[i]; if (!arg.StartsWith("-", StringComparison.Ordinal) && !arg.StartsWith("/", StringComparison.Ordinal)) { Console.WriteLine("Parameters must start with '-' or '/'. Use '-?' to show help."); return; } if (arg.Length == 1) { continue; } arg = arg.Substring(1, arg.Length - 1); if (arg == "acceptany") { acceptAny = true; continue; } else if (arg.StartsWith("usrdb=", StringComparison.Ordinal)) { var spl = arg.Split('='); if (spl.Length == 2) { dbPath = spl[1].Trim(new[] { '\"' }); continue; } else { Console.WriteLine("Error in parameter 'usrdb'"); return; } } else if (arg.StartsWith("port=")) { var spl = arg.Split('='); if (spl.Length != 2 || !ushort.TryParse(spl[1], out port)) { Console.WriteLine("Error in parameter 'port'"); return; } } else { Console.WriteLine( "Access Battle Server\r\n\r\n" + "Usage: AccessBattleServer [-acceptany] [-usrdb=path]\r\n" + "\r\nOptions:\r\n" + "\t-port=3221 Define the port to use. Default: 3221\r\n" + "\t-acceptany Accepts any client. Disables user database.\r\n" + "\t Clients require no password.\r\n" + "\t-usrdb=path Path to text file for user database.\r\n" + "\t default path is '.\\userdb.txt'.\r\n" + "\r\nUsing '/' instead of '-' is allowed.\r\n" ); return; } } Log.SetMode(LogMode.Console); Log.Priority = LogPriority.Information; // Create userdb folder if not existing Console.WriteLine("Using user database file: " + dbPath); try { var dir = System.IO.Path.GetDirectoryName(dbPath); if (!string.IsNullOrEmpty(dir) && !System.IO.Directory.Exists(dir)) { System.IO.Directory.CreateDirectory(dir); } } catch (Exception) { Console.WriteLine("Could not create directory for user database!"); } try { var userDb = new TextFileUserDatabaseProvider(dbPath); _server = new GameServer(port, userDb) { AcceptAnyClient = acceptAny }; _server.Start(); Console.WriteLine("Game Server started"); if (acceptAny) { Console.WriteLine("! Any client is accepted"); } Console.WriteLine("Type 'help' to show available commands"); string line; while ((line = Console.ReadLine()) != "exit") { bool ok = false; line = line.Trim(); if (line == ("help")) { Console.WriteLine( "\texit Close this program.\r\n" + "\tlist List all games\r\n" + "\tadd user n p Adds user 'u' with password 'p'\r\n" + "\tdebug Debug command. Requires additional parameters:\r\n" + "\t win key=1234 1 Let player 1 win. Uses game key.\r\n" + "\t win name=gameX 2 Let player 2 win. Uses game name."); ok = true; } else if (line == ("list")) { var games = _server.Games.ToList(); if (games.Count == 0) { Console.WriteLine("There are no games");; } else { foreach (var game in games) { Console.WriteLine(game.Key + " - " + game.Value.Name); } } ok = true; } else if (line.StartsWith("debug ", StringComparison.Ordinal)) { var sp = line.Split(' '); if (sp.Length == 4) { if (sp[1] == "win") { uint k = 0; var spx = sp[2].Split('='); if (spx.Length != 2) { continue; } if (spx[0] == "key") { if (!uint.TryParse(spx[1], out k)) { continue; } } else if (spx[0] == "name") { k = _server.Games.FirstOrDefault(o => o.Value.Name == spx[1]).Key; } if (k == 0) { continue; } int p; if (!int.TryParse(sp[3], out p)) { continue; } _server.Win(p, k); ok = true; } } } else if (line.StartsWith("add user ", StringComparison.Ordinal)) { var spl = line.Split(' '); if (spl.Length == 4) { var pw = new System.Security.SecureString(); foreach (var c in spl[3]) { pw.AppendChar(c); } if (userDb.AddUserAsync(spl[2], pw).GetAwaiter().GetResult()) { Console.WriteLine("user added"); } else { Console.WriteLine("add failed"); } ok = true; } } if (!ok) { Console.WriteLine("error"); } } } finally { Log.WriteLine(LogPriority.Information, "Stopping Server..."); _server.Stop(); #if DEBUG Console.WriteLine("Press any key to exit..."); Console.ReadKey(); #endif Log.WriteLine(LogPriority.Information, "Game Server stopped"); } }