/// <summary> /// Starts up the server /// </summary> public static void Main() { // Create a new server that listens on port 3000; //Database database = new Database("Server=localhost;Port=3306;Database=songdatabase;Uid=root;password=joeswanson;"); //Database database = new Database("Server=68.234.183.70;Port=3001;Database=songdatabase;Uid=BlottoServer;password=JJLrDtcrfvjym8gh1zUVklF19KDf1CTM;"); //Database database = new Database("Server=BlottoBeats.db.11772669.hostedresource.com;Port=3306;Database=BlottoBeats;Uid=BlottoBeats;password=JoeSwanson307!;"); //Server server = new Server(3000, database, "server.log", 3); Database database = null; Server server = null; // Server startup screen CommandLine.WriteLine("---------------------------------------------"); CommandLine.WriteLine(" BlottoBeats Server v1.0 (Stopped)"); CommandLine.WriteLine("---------------------------------------------"); CommandLine.WriteLine("Host ID: " + Properties.Settings.Default.hostID); CommandLine.WriteLine("Port: " + Properties.Settings.Default.port); CommandLine.WriteLine(); CommandLine.WriteLine("Database Name: " + Properties.Settings.Default.databaseName); CommandLine.WriteLine(); CommandLine.WriteLine("Username: "******"---------------------------------------------"); CommandLine.WriteLine("Type upstart <password> to log into the database and start the server."); CommandLine.WriteLine("Type help or ? for more commands."); while (true) { CommandLine line = CommandLine.Prompt(); switch (line.command.ToLower()) { // SERVER COMMANDS case "start": if (server != null && server.IsAlive()) CommandLine.WriteLine("ERROR: Can't start the server, the server is already started"); else if (database == null || server == null) CommandLine.WriteLine("ERROR: The update command needs to be run first"); else server.Start(); break; case "stop": if (server == null || !server.IsAlive()) CommandLine.WriteLine("ERROR: Can't stop the server, the server is already stopped"); else server.Stop(); break; case "restart": if (server == null || !server.IsAlive()) CommandLine.WriteLine("ERROR: Can't restart the server, the server is stopped"); else server.Restart(); break; case "update": case "updatedb": case "updatedatabase": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (server != null && server.IsAlive()) { CommandLine.WriteLine("ERROR: Can't update the database if the server is running. Stop the server first."); } else { database = new Database(Properties.Settings.Default.hostID, Properties.Settings.Default.port, Properties.Settings.Default.databaseName, Properties.Settings.Default.userID, line.args[0]); server = new Server(3000, database, "server.log", 3); CommandLine.WriteLine("Database updated successfully."); } break; case "upstart": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (server != null && server.IsAlive()) { CommandLine.WriteLine("ERROR: Can't update the database if the server is running. Stop the server first."); } else { database = new Database(Properties.Settings.Default.hostID, Properties.Settings.Default.port, Properties.Settings.Default.databaseName, Properties.Settings.Default.userID, line.args[0]); server = new Server(3000, database, "server.log", 3); CommandLine.WriteLine("Database updated successfully."); server.Start(); } break; // DATABASE COMMANDS case "dbhost": case "dbhostid": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else { Properties.Settings.Default.hostID = line.args[0]; Properties.Settings.Default.Save(); CommandLine.WriteLine("Setting is updated. You need to run the update command in order for the changes to be applied to the server."); } break; case "dbport": int port; if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (int.TryParse(line.args[0], out port) && port > 1024 && port <= 65535) { Properties.Settings.Default.port = port; Properties.Settings.Default.Save(); CommandLine.WriteLine("Setting is updated. You need to run the update command in order for the changes to be applied to the server."); } else { CommandLine.WriteLine("ERROR: The argument must be an integer between 1024 and 65535"); } break; case "database": case "databasename": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else { Properties.Settings.Default.databaseName = line.args[0]; Properties.Settings.Default.Save(); CommandLine.WriteLine("Setting is updated. You need to run the update command in order for the changes to be applied to the server."); } break; case "dbuser": case "dbuserid": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else { Properties.Settings.Default.userID = line.args[0]; Properties.Settings.Default.Save(); CommandLine.WriteLine("Setting is updated. You need to run the update command in order for the changes to be applied to the server."); } break; case "info": case "dbinfo": string health = "Stopped"; if (server != null && server.IsAlive()) health = "Running"; CommandLine.WriteLine("---------------------------------------------"); CommandLine.WriteLine(" BlottoBeats Server v1.0 (" + health + ")"); CommandLine.WriteLine("---------------------------------------------"); CommandLine.WriteLine("Host ID: " + Properties.Settings.Default.hostID); CommandLine.WriteLine("Port: " + Properties.Settings.Default.port); CommandLine.WriteLine(); CommandLine.WriteLine("Database Name: " + Properties.Settings.Default.databaseName); CommandLine.WriteLine(); CommandLine.WriteLine("Username: "******"---------------------------------------------"); break; // USER ACCOUNT COMMANDS case "newaccount": if (line.numArgs < 2) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires two arguments"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { UserToken token = database.Authenticate(new Credentials(line.args[0], line.args[1]), true); if (token != null) CommandLine.WriteLine("Registration Successful"); else CommandLine.WriteLine("Registration Failed"); } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: Registration could not proceed"); CommandLine.WriteLine(ex.Message); } } break; case "deleteaccount": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { int id = database.GetID(line.args[0]); if (id != 0) { database.deleteUser(id); CommandLine.WriteLine("User '" + line.args[0] + "' deleted."); } else { CommandLine.WriteLine("ERROR:User '" + line.args[0] + "' does not exist"); } } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: User could not be deleted"); CommandLine.WriteLine(ex.Message); } } break; case "resetpassword": if (line.numArgs < 2) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires two arguments"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { Credentials credentials = new Credentials(line.args[0], line.args[1]); int id = database.GetID(credentials.username); if (id != 0) { database.changePassword(id, credentials.GenerateHash()); CommandLine.WriteLine("Password Change Successful"); } else { CommandLine.WriteLine("ERROR:User '" + credentials.username + "' does not exist"); } } catch (DatabaseException ex){ CommandLine.WriteLine("DATABASE ERROR: Password could not be changed"); CommandLine.WriteLine(ex.Message); } } break; case "refreshtoken": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { if (database.RefreshToken(line.args[0])) CommandLine.WriteLine("Refreshed token"); else CommandLine.WriteLine("User '" + line.args[0] + "' does not exist"); } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: Refresh could not proceed"); CommandLine.WriteLine(ex.Message); } } break; case "whois": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { int id; if (int.TryParse(line.args[0], out id)) { string name = database.GetUsername(id); if (name != null) CommandLine.WriteLine("Username of user " + id + " is '" + name + "'"); else CommandLine.WriteLine("User " + id + " does not exist"); } else { CommandLine.WriteLine("ERROR: Argument 1 must be an integer"); } } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: Refresh could not proceed"); CommandLine.WriteLine(ex.Message); } } break; // SONG COMMANDS case "newsong": if (line.numArgs < 3) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires three arguments"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { int seed, tempo; if (line.numArgs < 4) { if (int.TryParse(line.args[0], out seed) && int.TryParse(line.args[1], out tempo)) { SongParameters song = new SongParameters(seed, tempo, line.args[2]); song = database.VoteOnSong(song, true, -1); CommandLine.WriteLine("Created new song with ID '" + song.ID + "' as anonymous"); } else { CommandLine.WriteLine("Arguments 1 and 2 must be integers"); } } else { int userID; if (int.TryParse(line.args[0], out seed) && int.TryParse(line.args[1], out tempo) && int.TryParse(line.args[3], out userID)) { SongParameters song = new SongParameters(seed, tempo, line.args[2], userID); song = database.VoteOnSong(song, true, -1); CommandLine.WriteLine("Created new song with ID '" + song.ID + "' belonging to user " + userID); } else { CommandLine.WriteLine("Arguments 1, 2, and 4 must be integers"); } } } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: Could not create song"); CommandLine.WriteLine(ex.Message); } } break; case "deletesong": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { int id; if (int.TryParse(line.args[0], out id) && database.SongExists(id)) { database.deleteSong(id); CommandLine.WriteLine("Song '" + id + "' deleted."); } else { CommandLine.WriteLine("ERROR:Song '" + id + "' does not exist"); } } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: Song could not be deleted"); CommandLine.WriteLine(ex.Message); } } break; case "setscore": if (line.numArgs < 2) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires two arguments"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { int id, score; if (int.TryParse(line.args[0], out id) && int.TryParse(line.args[1], out score) && database.SongExists(id)) { database.changeVoteScore(id, score); CommandLine.WriteLine("Song " + id + " score set to " + score); } else { CommandLine.WriteLine("ERROR:Song " + id + " does not exist"); } } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: Score could not be changed"); CommandLine.WriteLine(ex.Message); } } break; case "songinfo": if (line.numArgs < 1) { CommandLine.WriteLine("ERROR: The command '" + line.command + "' requires an argument"); } else if (server == null || !server.IsAlive()) { CommandLine.WriteLine("ERROR: The server is offline"); } else { try { int id; if (int.TryParse(line.args[0], out id)) { if (database.SongExists(id)) { SongParameters song = database.GetSong(id); CommandLine.WriteLine("Song " + song.ID); CommandLine.WriteLine(); CommandLine.WriteLine("Seed: " + song.seed); CommandLine.WriteLine("Tempo: " + song.tempo); CommandLine.WriteLine("Genre: " + song.genre); CommandLine.WriteLine(); CommandLine.WriteLine("Score: " + song.score); CommandLine.WriteLine("User: "******"Song " + id + " does not exist"); } } else { CommandLine.WriteLine("ERROR: Argument 1 must be an integer"); } } catch (DatabaseException ex) { CommandLine.WriteLine("DATABASE ERROR: Could not get song info"); CommandLine.WriteLine(ex.Message); } } break; // Shell commands case "quit": case "exit": if (server != null && server.IsAlive()) server.Stop(); return; case "help": case "?": CommandLine.WriteLine("-------------------------"); CommandLine.WriteLine(" COMMAND LIST"); CommandLine.WriteLine("-------------------------"); CommandLine.WriteLine("SERVER COMMANDS"); CommandLine.WriteLine("Start"); CommandLine.WriteLine(" Starts the server"); CommandLine.WriteLine("Stop"); CommandLine.WriteLine(" Stops the server"); CommandLine.WriteLine("Restart"); CommandLine.WriteLine(" Restarts the server"); CommandLine.WriteLine("Update <password>"); CommandLine.WriteLine(" Modifies the database according to the changes. The server must be stopped."); CommandLine.WriteLine("Upstart <password>"); CommandLine.WriteLine(" Modifies the database according to the changes and starts the server. The server must be stopped."); CommandLine.WriteLine(); CommandLine.WriteLine("DATABASE COMMANDS"); CommandLine.WriteLine("DBHost/DBHostID <new ID>"); CommandLine.WriteLine(" Changes the hostID of the database. Requires an update to take effect."); CommandLine.WriteLine("DBPort <new Port>"); CommandLine.WriteLine(" Changes the port of the database. Requires an update to take effect."); CommandLine.WriteLine("Database/DatabaseName <new name>"); CommandLine.WriteLine(" Changes the name of the database. Requires an update to take effect."); CommandLine.WriteLine("DBUser/DBUserID <new id>"); CommandLine.WriteLine(" Changes the userID to use with the database. Requires an update to take effect."); CommandLine.WriteLine("DBInfo"); CommandLine.WriteLine(" Displays information about the server."); CommandLine.WriteLine(); CommandLine.WriteLine("USER ACCOUNT COMMANDS"); CommandLine.WriteLine("Newaccount <username> <password>"); CommandLine.WriteLine(" Creates a new user account with the given username and password."); CommandLine.WriteLine("Deleteaccount <username>"); CommandLine.WriteLine(" Deletes a user account with the given username."); CommandLine.WriteLine("Resetpassword <username> <password>"); CommandLine.WriteLine(" Resets the password of the given username to the given password."); CommandLine.WriteLine("Refreshtoken <username>"); CommandLine.WriteLine(" Refreshes the token associated with the given user account."); CommandLine.WriteLine("Whois <id>"); CommandLine.WriteLine(" Returns the username of the user with the given ID."); CommandLine.WriteLine(); CommandLine.WriteLine("SONG COMMANDS"); CommandLine.WriteLine("Newsong <seed> <tempo> <genre> [<userID>]"); CommandLine.WriteLine(" Adds a new song to the database with the given seed, tempo, and genre, and optionally, userID. Displays the ID of the newly-added song."); CommandLine.WriteLine("Deletesong <id>"); CommandLine.WriteLine(" Removes the given song from the database."); CommandLine.WriteLine("Setscore <id> <score>"); CommandLine.WriteLine(" Sets the score of a given song to the given score."); CommandLine.WriteLine("Songinfo <id>"); CommandLine.WriteLine(" Gets all the info about the given song."); break; default: CommandLine.WriteLine("'" + line.command + "' is not a valid command. Type help or ? for a list of commands."); break; } } }
/// <summary> /// Creates a new server object that listens on the specified port /// </summary> /// <param name="port">The port to listen on</param> /// <param name="database">SQL Database string</param> /// <param name="logFileLocation">Location to save the log</param> /// <param name="logLevel">What level of logs to use</param> internal Server(int port, Database database, string logFileLocation, int logLevel) { this.database = database; this.logFileLocation = logFileLocation; this.logLevel = logLevel; this.tcpListener = new TcpListener(IPAddress.Any, port); this.listenAbort = true; }