/// <summary> /// This is the primary method for fetching an accounts BF2 PID /// </summary> /// <param name="recvData"></param> private void SendCheck(Dictionary <string, string> recvData) { // Make sure we have the needed data if (!recvData.ContainsKey("nick")) { Stream.SendAsync(@"\error\\err\0\fatal\\errmsg\Invalid Query!\id\1\final\"); return; } // Try to get user data from database try { using (GamespyDatabase Db = new GamespyDatabase()) { int pid = Db.GetPlayerId(recvData["nick"]); if (pid == 0) { Stream.SendAsync(@"\error\\err\265\fatal\\errmsg\Username [{0}] doesn't exist!\id\1\final\", recvData["nick"]); } else { Stream.SendAsync(@"\cur\0\pid\{0}\final\", pid); } } } catch { Stream.SendAsync(@"\error\\err\265\fatal\\errmsg\Database service is Offline!\id\1\final\"); //Dispose(); } }
/// <summary> /// Constructor /// </summary> /// <param name="Pid">The player account ID</param> public AccountEditForm(int Pid) { InitializeComponent(); this.AccountId = Pid; // Register for Events GpcmClient.OnSuccessfulLogin += GpcmClient_OnSuccessfulLogin; GpcmClient.OnDisconnect += GpcmClient_OnDisconnect; // Fill the account information boxes using (GamespyDatabase Database = new GamespyDatabase()) { Dictionary <string, object> User = Database.GetUser(AccountId); PlayerID.Value = AccountId = Int32.Parse(User["id"].ToString()); AccountNick.Text = User["name"].ToString(); AccountEmail.Text = User["email"].ToString(); // Disable options if user is online if (GamespyEmulator.IsPlayerConnected(AccountId)) { SatusLabel.Text = "Online (IP: " + User["lastip"].ToString() + ")"; UpdateBtn.Enabled = false; DeleteBtn.Enabled = false; DisconnectBtn.Enabled = true; } else { SatusLabel.Text = "Offline"; } } }
/// <summary> /// Logs the client out of the game client, and closes the stream /// </summary> /// <param name="reason"> /// The disconnect reason code. /// </param> /// <remarks> /// If set the <paramref name="reason"/> is set to <see cref="DisconnectReason.ForcedServerShutdown"/>, /// the OnDisconect event will not be called, the database will not be updated to reset everyone's session code, /// and the EventArgs objects will NOT be returned to the IO pool. You should only set to /// <see cref="DisconnectReason.ForcedServerShutdown"/> for a planned server shutdown. /// </remarks> public void Disconnect(DisconnectReason reason) { // Update database session if (Status == LoginStatus.Completed && reason != DisconnectReason.ForcedServerShutdown) { try { using (GamespyDatabase Database = new GamespyDatabase()) Database.Execute("UPDATE player SET online=0 WHERE id=" + PlayerId); } catch { } } // If connection is still alive, disconnect user try { Stream.OnDisconnect -= Stream_OnDisconnect; Stream.DataReceived -= Stream_DataReceived; Stream.Close(reason == DisconnectReason.ForcedServerShutdown); } catch { } // Set status and log if (Status == LoginStatus.Completed) { if (reason == DisconnectReason.NormalLogout) { ServerManager.Log( "Client Logout: {0} - {1} - {2}", PlayerNick, PlayerId, RemoteEndPoint ); } else { ServerManager.Log( "Client Disconnected: {0} - {1} - {2}, Code={3}", PlayerNick, PlayerId, RemoteEndPoint, Enum.GetName(typeof(DisconnectReason), reason) ); } } // Preapare to be unloaded from memory Status = LoginStatus.Disconnected; Dispose(); // Call disconnect event OnDisconnect?.Invoke(this); }
/// <summary> /// Updates the Users Country code when sent by the client /// </summary> /// <param name="recv">Array of information sent by the server</param> private void UpdateUser(Dictionary <string, string> Recv) { // Set clients country code try { using (GamespyDatabase Conn = new GamespyDatabase()) Conn.UpdateUser(PlayerId, Recv["countrycode"]); } catch (Exception e) { Program.ErrorLog.Write("ERROR: [GpcmClient.UpdateUser] " + e.Message); } }
/// <summary> /// Whenever the "newuser" command is recieved, this method is called to /// add the new users information into the database /// </summary> /// <param name="Recv">Array of parms sent by the server</param> private void CreateNewUser(Dictionary <string, string> Recv) { // Make sure the user doesnt exist already try { using (GamespyDatabase Database = new GamespyDatabase()) { // Check to see if user exists if (Database.UserExists(Recv["nick"])) { Stream.SendAsync(@"\error\\err\516\fatal\\errmsg\This account name is already in use!\id\1\final\"); Disconnect(DisconnectReason.CreateFailedUsernameExists); return; } // We need to decode the Gamespy specific encoding for the password string Password = GamespyUtils.DecodePassword(Recv["passwordenc"]); string Cc = (RemoteEndPoint.AddressFamily == AddressFamily.InterNetwork) ? GeoIP.GetCountryCode(RemoteEndPoint.Address) : "US"; // Attempt to create account. If Pid is 0, then we couldnt create the account if ((PlayerId = Database.CreateUser(Recv["nick"], Password, Recv["email"], Cc)) == 0) { Stream.SendAsync(@"\error\\err\516\fatal\\errmsg\Error creating account!\id\1\final\"); Disconnect(DisconnectReason.CreateFailedDatabaseError); return; } Stream.SendAsync(@"\nur\\userid\{0}\profileid\{0}\id\1\final\", PlayerId); } } catch (Exception e) { // Check for invalid query params if (e is KeyNotFoundException) { Stream.SendAsync(@"\error\\err\0\fatal\\errmsg\Invalid Query!\id\1\final\"); } else { Stream.SendAsync(@"\error\\err\516\fatal\\errmsg\Error creating account!\id\1\final\"); Program.ErrorLog.Write("ERROR: [GpcmClient.CreateNewUser] An error occured while trying to create a new User account :: " + e.Message); } Disconnect(DisconnectReason.GeneralError); return; } }
/// <summary> /// Starts the Login Server listeners, and begins accepting new connections /// </summary> public static void StartServers() { // Make sure we arent already running! if (isRunning) { return; } try { // Start the DB Connection Console.Write("Connecting to Mysql... "); using (GamespyDatabase Database = new GamespyDatabase()) { Console.Write("Success!" + Environment.NewLine); // Reset game sessions if (Config.GetType <bool>("Settings", "ResetGameSessionsOnStartup")) { Console.Write("Resetting all game sessions... "); Database.Execute("UPDATE web_users SET game_session=0 WHERE id > 0"); Console.Write("Success!" + Environment.NewLine); } } // Create our end point to bind to int port = Config.GetType <int>("Settings", "LoginServerPort"); IPAddress address = IPAddress.Parse(Config.GetValue("Settings", "ServerBindIp")); // Start the Client Manager Server Console.Write("<GPCM> Binding to TCP port {0}... ", port); CmServer = new GpcmServer(new IPEndPoint(address, port)); Console.Write("Success!" + Environment.NewLine); // Start Search Provider Server Console.Write("<GPSP> Binding to TCP port {0}... ", ++port); SpServer = new GpspServer(new IPEndPoint(address, port)); Console.Write("Success!" + Environment.NewLine); } catch { Console.Write("Failed!" + Environment.NewLine); throw; } // Let the client know we are ready for connections isRunning = true; }
/// <summary> /// Event fired when the Delete button is pushed /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DeleteBtn_Click(object sender, EventArgs e) { if (MessageBox.Show("Are you sure you want to delete account?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { using (GamespyDatabase Database = new GamespyDatabase()) { if (Database.DeleteUser(AccountId) == 1) { Notify.Show("Account deleted successfully!", "Operation Successful", AlertType.Success); } else { Notify.Show("Failed to remove account from database!", "Operation failed", AlertType.Warning); } } this.Close(); } }
public AccountListForm() { InitializeComponent(); SortedCol = DataTable.Columns[0]; // Try to connect to the database try { using (GamespyDatabase Driver = new GamespyDatabase()) { } } catch (DbConnectException Ex) { ExceptionForm.ShowDbConnectError(Ex); Load += (s, e) => Close(); // Close form return; } // Setting the limit will build the inital list LimitSelect.SelectedIndex = 2; }
/// <summary> /// Logs the client out of the game client, and closes the stream /// </summary> /// <param name="where"> /// The disconnect code. If set to 9, the OnDisconect event will not be called, the database /// will not be updated to reset everyone's session code, and the EventArgs objects will NOT /// be returned to the IO pool. You should only set to 9 for a planned server shutdown. /// </param> /// <remarks> /// Codes: /// 0 => Client sends the "logout" command /// 1 => Keep Alive Packet failed to send (may not work with new async socket code) /// 2 => Invalid login query, or username was incorrect /// 3 => Incorrect Password /// 4 => An error occured while trying to login the client (could be database related) /// 5 => Cant create account, username exists already /// 6 => Error Creating new account in database /// 7 => Invalid query for account creation, or an exception was thrown while trying to create account /// 8 => Stream Disconnected /// 9 => Forced server shutdown [No events called, database sessions are not updated, and EventArgs are disposed] /// 10 => Client challenge already sent /// </remarks> public void Disconnect(int where) { // Update database session if (Status == LoginStatus.Completed && where < 9) { try { using (GamespyDatabase Database = new GamespyDatabase()) Database.Execute("UPDATE web_users SET game_session=0 WHERE pid=" + PlayerId); } catch { } } // If connection is still alive, disconnect user try { Stream.OnDisconnect -= Stream_OnDisconnect; Stream.DataReceived -= Stream_DataReceived; Stream.Close(where == 9); } catch { } // Set status and log if (Status == LoginStatus.Completed) { ServerManager.Log("Client Logout: {0} - {1} - {2}, Code={3}", PlayerNick, PlayerId, RemoteEndPoint, where); } // Preapare to be unloaded from memory Status = LoginStatus.Disconnected; Dispose(); // Call disconnect event if (OnDisconnect != null) { OnDisconnect(this); } }
/// <summary> /// Delete Account menu item click event /// </summary> private void menuItemDelete_Click(object sender, System.EventArgs e) { int Id = Int32.Parse(DataTable.SelectedRows[0].Cells[0].Value.ToString()); string Name = DataTable.SelectedRows[0].Cells[1].Value.ToString(); if (MessageBox.Show("Are you sure you want to delete account \"" + Name + "\"?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { using (GamespyDatabase Database = new GamespyDatabase()) { if (Database.DeleteUser(Id) == 1) { Notify.Show("Account deleted successfully!", "Operation Successful", AlertType.Success); } else { Notify.Show("Failed to remove account from database!", "Operation Failed", AlertType.Warning); } } BuildList(); } }
/// <summary> /// This method is requested by the client when logging in to fetch all the account /// names that have the specified email address and password combination /// </summary> /// <param name="recvData"></param> private void SendNicks(Dictionary <string, string> recvData) { // Make sure we have the needed data if (!recvData.ContainsKey("email") || (!recvData.ContainsKey("pass") && !recvData.ContainsKey("passenc"))) { Stream.SendAsync(@"\error\\err\0\fatal\\errmsg\Invalid Query!\id\1\final\"); return; } // Try to get user data from database try { // Get our password from the provided query string password = (recvData.ContainsKey("pass")) ? recvData["pass"] : GamespyUtils.DecodePassword(recvData["passenc"]); // Fetch soldiers that match this email and password using (GamespyDatabase Db = new GamespyDatabase()) { var Clients = Db.GetUsersByEmailPass(recvData["email"], password); StringBuilder Response = new StringBuilder(@"\nr\" + Clients.Count); for (int i = 0; i < Clients.Count; i++) { Response.AppendFormat(@"\nick\{0}\uniquenick\{0}", Clients[i]["name"]); } Response.Append(@"\ndone\\final\"); Stream.SendAsync(Response.ToString()); } } catch { Stream.SendAsync(@"\error\\err\551\fatal\\errmsg\Unable to get any associated profiles.\id\1\final\"); } }
/// <summary> /// Event fired when the Submit button is pushed /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UpdateBtn_Click(object sender, EventArgs e) { int Pid = (int)PlayerID.Value; using (GamespyDatabase Database = new GamespyDatabase()) { // Make sure there is no empty fields! if (AccountNick.Text.Trim().Length < 3) { MessageBox.Show("Please enter a valid account name", "Error"); return; } else if (!Validator.IsValidEmail(AccountEmail.Text)) { MessageBox.Show("Please enter a valid account email", "Error"); return; } else if (Pid != AccountId) { if (!Validator.IsValidPID(Pid.ToString())) { MessageBox.Show("Invalid PID Format. A PID must be 8 or 9 digits in length", "Error"); return; } // Make sure the PID doesnt exist! else if (Database.UserExists(Pid)) { MessageBox.Show("Battlefield 2 PID is already taken. Please try a different PID.", "Error"); return; } } Database.UpdateUser(AccountId, Pid, AccountNick.Text, AccountPass.Text, AccountEmail.Text); } this.Close(); }
/// <summary> /// Event fired when the next button is clicked /// </summary> private async void NextBtn_Click(object sender, EventArgs e) { // Disable this form this.Enabled = false; string Message1 = ""; // Initiate the Task Form if (TypeSelect.SelectedIndex == 1) { TaskForm.Show(this, "Create Database", "Connecting to MySQL Database...", false); Message1 = "Successfully Connected to MySQL Database! We will attempt to create the necessary tables into the specified database. Continue?"; } else { TaskForm.Show(this, "Create Database", "Creating SQLite Database...", false); Message1 = "Successfully Created the SQLite Database! We will attempt to create the necessary tables into the specified database. Continue?"; } // Temporarily set settings if (!SetConfigSettings()) { this.Enabled = true; TaskForm.CloseForm(); return; } // Try and install the SQL try { bool PreviousInstall = true; // Run in a seperate thread, dont wanna lock up the GUI thread await Task.Run(() => { // Switch mode if (DbMode == DatabaseMode.Stats) { // Open up the database connetion using (StatsDatabase Db = new StatsDatabase()) { // We only have work to do if the tables are not installed if (!Db.TablesExist) { PreviousInstall = false; // Verify that the user wants to install DB tables DialogResult Res = MessageBox.Show(Message1, "Verify Installation", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0x40000 // Force window on top ); // If we dont want to install tables, back out! if (Res == DialogResult.No) { return; } // Create our tables TaskForm.Progress.Report(new TaskProgressUpdate("Creating Stats Tables")); Db.CreateSqlTables(TaskForm.Progress); } } } else // Gamespy Mode { // Open up the database connetion using (GamespyDatabase Db = new GamespyDatabase()) { // We only have work to do if the tables are not installed if (!Db.TablesExist) { PreviousInstall = false; // Verify that the user wants to install DB tables DialogResult Res = MessageBox.Show(Message1, "Verify Installation", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0x40000 // Force window on top ); // If we dont want to install tables, back out! if (Res == DialogResult.No) { return; } // Create our tables TaskForm.Progress.Report(new TaskProgressUpdate("Creating Gamespy Tables")); Db.CreateSqlTables(); } } } }); // No errors, so save the config file Program.Config.Save(); // Close the task form TaskForm.CloseForm(); // Show Success Form if (!PreviousInstall) { MessageBox.Show("Successfully installed the database tables!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0x40000 // Force window on top ); } else { MessageBox.Show( "We've detected that the database was already installed here. Your database settings have been saved and no further setup is required.", "Existing Installation Found", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0x40000 // Force window on top ); } // Close this form, as we are done now this.Close(); } catch (Exception Ex) { // Close the task form and re-enable this form TaskForm.CloseForm(); this.Enabled = true; // Revert the temporary config settings and show the error to the user Program.Config.Reload(); MessageBox.Show(Ex.Message, "Database Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0x40000 // Force window on top ); return; } finally { if (TaskForm.IsOpen) { TaskForm.CloseForm(); } this.Enabled = true; } }
/// <summary> /// Reads the next input in the console (Blocking Method) /// </summary> private static void CheckInput() { // Get user input [Blocking] string Input = Console.ReadLine(); // Make sure input is not empty if (String.IsNullOrWhiteSpace(Input)) { Console.WriteLine("Please enter a command"); Console.WriteLine(); Console.Write("Cmd > "); return; } // Split input into an array by whitespace, empty entries are removed string[] InParts = Input.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); Dictionary <string, object> user = new Dictionary <string, object>(); // Process Task try { switch (InParts[0].ToLowerInvariant()) { case "stop": case "quit": case "exit": IsRunning = false; // Setting to false will stop program loop break; case "connections": Console.WriteLine("Total Connections: {0}", ServerManager.NumConnections()); break; case "accounts": using (GamespyDatabase Db = new GamespyDatabase()) Console.WriteLine("Total Accounts: {0}", Db.GetNumAccounts()); break; case "fetch": // Prevent an out of range exception if (InParts.Length < 2) { Console.WriteLine("Incorrect command format. Please type 'help' to see list of available commands."); break; } // Make sure we have a nick if (String.IsNullOrEmpty(InParts[1])) { Console.WriteLine("No account named provided. Please make sure you are providing an account name, and not a space"); break; } // Fetch user account info using (GamespyDatabase Db = new GamespyDatabase()) user = Db.GetUser(InParts[1]); if (user == null) { Console.WriteLine("Account '{0}' does not exist in the gamespy database.", InParts[1]); break; } // Get BF2 PID Console.WriteLine(" - PlayerID: " + user["id"].ToString()); Console.WriteLine(" - Email: " + user["email"].ToString()); Console.WriteLine(" - Country: " + user["country"].ToString()); break; case "create": // Prevent an out of range exception if (InParts.Length < 4) { Console.WriteLine("Incorrect command format. Please type 'help' to see list of available commands."); break; } // Make sure our strings are not empty! if (String.IsNullOrEmpty(InParts[1]) || String.IsNullOrEmpty(InParts[2]) || String.IsNullOrEmpty(InParts[3])) { Console.WriteLine("Account name, password, or email was not provided. Please try again with the correct format."); break; } // Disposible connection using (GamespyDatabase Db = new GamespyDatabase()) { // Make sure the account exists! if (Db.UserExists(InParts[1])) { Console.WriteLine("Account '{0}' already exists in the gamespy database.", InParts[1]); break; } bool r = Db.CreateUser(InParts[1], InParts[2], InParts[3], "00") > 0; Console.WriteLine((r == true) ? "Account created successfully" : "Error creating account!"); } break; case "delete": // Prevent an out of range exception if (InParts.Length < 2) { Console.WriteLine("Incorrect command format. Please type 'help' to see list of available commands."); break; } // Make sure our strings are not empty! if (String.IsNullOrEmpty(InParts[1])) { Console.WriteLine("Account name was not provided. Please try again with the correct format."); break; } // Disposible connection using (GamespyDatabase Db = new GamespyDatabase()) { // Make sure the account exists! if (!Db.UserExists(InParts[1])) { break; } // Do a confimration Console.Write("Are you sure you want to delete account '{0}'? <y/n>: ", InParts[1]); string v = Console.ReadLine().ToLower().Trim(); // If no, stop here if (v == "n" || v == "no" || v == "na" || v == "nope") { Console.WriteLine("Command cancelled."); break; } // Process any command other then no if (v == "y" || v == "yes" || v == "ya" || v == "yep") { if (Db.DeleteUser(InParts[1]) == 1) { Console.WriteLine("Account deleted successfully"); } else { Console.WriteLine("Failed to remove account from database."); } } else { Console.WriteLine("Incorrect repsonse. Aborting command"); } } break; case "setpid": // Prevent an out of range exception if (InParts.Length < 3) { Console.WriteLine("Incorrect command format. Please type 'help' to see list of available commands."); break; } // Make sure our strings are not empty! if (String.IsNullOrEmpty(InParts[1]) || String.IsNullOrEmpty(InParts[2])) { Console.WriteLine("Account name or PID not provided. Please try again with the correct format."); break; } // Disposible connection using (GamespyDatabase Db = new GamespyDatabase()) { // Make sure the account exists! user = Db.GetUser(InParts[1]); if (user == null) { Console.WriteLine("Account '{0}' does not exist in the gamespy database.", InParts[1]); break; } // Try to make a PID out of parts 2 int newpid; if (!Int32.TryParse(InParts[2], out newpid)) { Console.WriteLine("Player ID must be an numeric only!"); break; } // try and set the PID int result = Db.SetPID(InParts[1], newpid); string message = ""; switch (result) { case 1: message = "New PID is set!"; break; case 0: message = "Error setting PID"; break; case -1: message = String.Format("Account '{0}' does not exist in the gamespy database.", InParts[1]); break; case -2: message = String.Format("PID {0} is already in use.", newpid); break; } Console.WriteLine(" - " + message); } break; case "?": case "help": Console.Write(Environment.NewLine + "stop/quit/exit - Stops the server" + Environment.NewLine + "connections - Displays the current number of connected clients" + Environment.NewLine + "accounts - Displays the current number accounts in the DB." + Environment.NewLine + "create {nick} {password} {email} - Create a new Gamespy account." + Environment.NewLine + "delete {nick} - Deletes a user account." + Environment.NewLine + "fetch {nick} - Displays the account information" + Environment.NewLine + "setpid {nick} {newpid} - Sets the BF2 Player ID of the givin account name" + Environment.NewLine ); break; case "enter": // Insert a break point here in Visual Studio to and enter this command to "Enter" the program during debugging IsRunning = true; break; default: Console.WriteLine("Unrecognized input '{0}'", Input); break; } } catch (Exception e) { Console.Write(e.Message); } // Await a new command if (IsRunning) { Console.WriteLine(); Console.Write("Cmd > "); } }
public Server() { Console.WriteLine("Initializing..." + Environment.NewLine); // Start the DB Connection try { Database = new GamespyDatabase(); } catch { // The exception message will already be on the console return; } // Bind gpcm server on port 29900 try { Console.WriteLine("<GPCM> Binding to port 29900"); CmServer = new GpcmServer(); } catch (Exception ex) { Console.WriteLine("Error binding to port 29900! " + ex.Message); Console.WriteLine("Press any key to close"); Console.ReadKey(); return; } // Bind gpsp server on port 29901 try { Console.WriteLine("<GPSP> Binding to port 29901"); SpServer = new GpspServer(); } catch (Exception ex) { Console.WriteLine("Error binding to port 29901! " + ex.Message); Console.WriteLine("Press any key to close"); Console.ReadKey(); return; } // Let the client know we are ready for connections Console.Write( Environment.NewLine + "Ready for connections! Type 'help' for a list of commands" + Environment.NewLine + Environment.NewLine ); Console.Beep(); // Handle input while (isRunning) { CheckInput(); } CmServer.Shutdown(); SpServer.Shutdown(); Console.WriteLine("Server shutdown Successfully"); }
/// <summary> /// This method verifies the login information sent by /// the client, and returns encrypted data for the client /// to verify as well /// </summary> public void ProcessLogin(Dictionary <string, string> Recv) { // Make sure we have all the required data to process this login if (!Recv.ContainsKey("uniquenick") || !Recv.ContainsKey("challenge") || !Recv.ContainsKey("response")) { Stream.SendAsync(@"\error\\err\0\fatal\\errmsg\Invalid Query!\id\1\final\"); Disconnect(DisconnectReason.InvalidLoginQuery); return; } // Dispose connection after use try { using (GamespyDatabase Conn = new GamespyDatabase()) { // Try and fetch the user from the database Dictionary <string, object> User = Conn.GetUser(Recv["uniquenick"]); if (User == null) { Stream.SendAsync(@"\error\\err\265\fatal\\errmsg\The uniquenick provided is incorrect!\id\1\final\"); Disconnect(DisconnectReason.InvalidUsername); return; } // Check if user is banned bool banned = Int32.Parse(User["permban"].ToString()) > 0; if (banned) { Stream.SendAsync(@"\error\\err\265\fatal\\errmsg\You account has been permanently suspended.\id\1\final\"); Disconnect(DisconnectReason.PlayerIsBanned); return; } // Set player variables PlayerId = Int32.Parse(User["id"].ToString()); PlayerNick = Recv["uniquenick"]; PlayerEmail = User["email"].ToString(); PlayerCountryCode = User["country"].ToString(); PasswordHash = User["password"].ToString().ToLowerInvariant(); // Use the GenerateProof method to compare with the "response" value. This validates the given password if (Recv["response"] == GenerateProof(Recv["challenge"], ServerChallengeKey)) { // Create session key SessionKey = Crc.ComputeChecksum(PlayerNick); // Password is correct Stream.SendAsync( @"\lc\2\sesskey\{0}\proof\{1}\userid\{2}\profileid\{2}\uniquenick\{3}\lt\{4}__\id\1\final\", SessionKey, GenerateProof(ServerChallengeKey, Recv["challenge"]), // Do this again, Params are reversed! PlayerId, PlayerNick, GenerateRandomString(22) // Generate LT whatever that is (some sort of random string, 22 chars long) ); // Log Incoming Connections ServerManager.Log("Client Login: {0} - {1} - {2}", PlayerNick, PlayerId, RemoteEndPoint); // Update status last, and call success login Status = LoginStatus.Completed; CompletedLoginProcess = true; OnSuccessfulLogin?.Invoke(this); } else { // Log Incoming Connections ServerManager.Log("Failed Login Attempt: {0} - {1} - {2}", PlayerNick, PlayerId, RemoteEndPoint); // Password is incorrect with database value Stream.SendAsync(@"\error\\err\260\fatal\\errmsg\The password provided is incorrect.\id\1\final\"); Disconnect(DisconnectReason.InvalidPassword); } } } catch (Exception ex) { ExceptionHandler.GenerateExceptionLog(ex); Disconnect(DisconnectReason.GeneralError); return; } }
/// <summary> /// This method verifies the login information sent by /// the client, and returns encrypted data for the client /// to verify as well /// </summary> public void ProcessLogin(Dictionary <string, string> Recv) { // Make sure we have all the required data to process this login if (!Recv.ContainsKey("uniquenick") || !Recv.ContainsKey("challenge") || !Recv.ContainsKey("response")) { Stream.SendAsync(@"\error\\err\0\fatal\\errmsg\Invalid Query!\id\1\final\"); Disconnect(2); return; } // Dispose connection after use try { using (GamespyDatabase Conn = new GamespyDatabase()) { // Try and fetch the user from the database Dictionary <string, object> User = Conn.GetUser(Recv["uniquenick"]); if (User == null) { Stream.SendAsync(@"\error\\err\265\fatal\\errmsg\The uniquenick provided is incorrect!\id\1\final\"); Disconnect(2); return; } // Set player variables PlayerId = Int32.Parse(User["pid"].ToString()); PlayerNick = Recv["uniquenick"]; PlayerEmail = User["email"].ToString(); PlayerCountryCode = User["game_country"].ToString(); PasswordHash = User["password"].ToString().ToLowerInvariant(); // Use the GenerateProof method to compare with the "response" value. This validates the given password if (Recv["response"] == GenerateProof(Recv["challenge"], ServerChallengeKey)) { // Create session key SessionKey = Crc.ComputeChecksum(PlayerNick); // Password is correct Stream.SendAsync( @"\lc\2\sesskey\{0}\proof\{1}\userid\{2}\profileid\{2}\uniquenick\{3}\lt\{4}__\id\1\final\", SessionKey, GenerateProof(ServerChallengeKey, Recv["challenge"]), // Do this again, Params are reversed! PlayerId, PlayerNick, GenerateRandomString(22) // Generate LT whatever that is (some sort of random string, 22 chars long) ); // Log Incoming Connections ServerManager.Log("Client Login: {0} - {1} - {2}", PlayerNick, PlayerId, RemoteEndPoint); Conn.Execute( "UPDATE web_users SET last_game_ip=@P0, game_session=1, game_tstamp=@P1 WHERE pid=@P2", RemoteEndPoint.Address, DateTime.UtcNow.ToUnixTimestamp(), PlayerId ); // Update status last, and call success login Status = LoginStatus.Completed; if (OnSuccessfulLogin != null) { OnSuccessfulLogin(this); } } else { // Log Incoming Connections ServerManager.Log("Failed Login Attempt: {0} - {1} - {2}", PlayerNick, PlayerId, RemoteEndPoint); // Password is incorrect with database value Stream.SendAsync(@"\error\\err\260\fatal\\errmsg\The password provided is incorrect.\id\1\final\"); Disconnect(3); } } } catch (Exception ex) { ExceptionHandler.GenerateExceptionLog(ex); Disconnect(4); return; } }
private void CreateBtn_Click(object sender, EventArgs e) { int Pid = (int)PidBox.Value; using (GamespyDatabase Database = new GamespyDatabase()) { // Make sure there is no empty fields! if (AccountName.Text.Trim().Length < 3) { MessageBox.Show("Please enter a valid account name", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (AccountPass.Text.Trim().Length < 3) { MessageBox.Show("Please enter a valid account password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (!Validator.IsValidEmail(AccountEmail.Text)) { MessageBox.Show("Please enter a valid account email", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // Check if PID exists (for changing PID) if (PidSelect.SelectedIndex == 1) { if (!Validator.IsValidPID(Pid.ToString())) { MessageBox.Show("Invalid PID Format. A PID must be 8 or 9 digits in length", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (Database.UserExists(Pid)) { MessageBox.Show("PID is already in use. Please enter a different PID.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } // Check if the user exists if (Database.UserExists(AccountName.Text)) { MessageBox.Show("Account name is already in use. Please select a different Account Name.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } try { // Attempt to create the account if (PidSelect.SelectedIndex == 1) { Database.CreateUser(Pid, AccountName.Text, AccountPass.Text, AccountEmail.Text, "00"); } else { Database.CreateUser(AccountName.Text, AccountPass.Text, AccountEmail.Text, "00"); } Notify.Show("Account Created Successfully!", AccountName.Text, AlertType.Success); } catch (Exception E) { MessageBox.Show(E.Message, "Account Create Error"); } } this.DialogResult = DialogResult.OK; this.Close(); }
/// <summary> /// Fills the DataGridView with a list of accounts /// </summary> private void BuildList() { // Define initial variables int Limit = Int32.Parse(LimitSelect.SelectedItem.ToString()); int Start = (ListPage == 1) ? 0 : (ListPage - 1) * Limit; string Like = SearchBox.Text.Replace("'", "").Trim(); WhereClause Where = null; // Build Query using (GamespyDatabase Driver = new GamespyDatabase()) { SelectQueryBuilder Query = new SelectQueryBuilder(Driver); Query.SelectColumns("id", "name", "email", "country", "lastip", "session"); Query.SelectFromTable("accounts"); Query.AddOrderBy(SortedCol.Name, ((SortDir == ListSortDirection.Ascending) ? Sorting.Ascending : Sorting.Descending)); Query.Limit(Limit, Start); // User entered search if (!String.IsNullOrWhiteSpace(Like)) { Where = Query.AddWhere("name", Comparison.Like, "%" + Like + "%"); } // Online Accounts if (OnlineAccountsCheckBox.Checked) { if (Where == null) { Where = Query.AddWhere("session", Comparison.NotEqualTo, 0); } else { Where.AddClause(LogicOperator.And, "session", Comparison.NotEqualTo, 0); } } // Clear out old junk DataTable.Rows.Clear(); // Add players to data grid int RowCount = 0; foreach (Dictionary <string, object> Row in Driver.QueryReader(Query.BuildCommand())) { DataTable.Rows.Add(new string[] { Row["id"].ToString(), Row["name"].ToString(), Row["email"].ToString(), Row["country"].ToString(), (Row["session"].ToString() != "0") ? "Yes" : "No", //(Gamespy.GamespyServer.IsPlayerConnected(Int32.Parse(Row["id"].ToString())) ? "Yes" : "No"), Row["lastip"].ToString(), }); RowCount++; } // Get Filtered Rows Query = new SelectQueryBuilder(Driver); Query.SelectCount(); Query.SelectFromTable("accounts"); if (Where != null) { Query.AddWhere(Where); } int TotalFilteredRows = Query.ExecuteScalar <int>(); // Get Total Player Count, if the Where clause is null, this will be the same as the Filtered Row Count int TotalRows = TotalFilteredRows; if (Where != null) { Query = new SelectQueryBuilder(Driver); Query.SelectCount(); Query.SelectFromTable("accounts"); TotalRows = Query.ExecuteScalar <int>(); } // Stop Count int Stop = (ListPage == 1) ? RowCount : ((ListPage - 1) * Limit) + RowCount; // First / Previous button if (ListPage == 1) { FirstBtn.Enabled = false; PreviousBtn.Enabled = false; } else { FirstBtn.Enabled = true; PreviousBtn.Enabled = true; } // Next / Last Button LastBtn.Enabled = false; NextBtn.Enabled = false; // Get total number of pages if (TotalFilteredRows / (ListPage * Limit) > 0) { float total = float.Parse(TotalFilteredRows.ToString()) / float.Parse(Limit.ToString()); TotalPages = Int32.Parse(Math.Floor(total).ToString()); if (TotalFilteredRows % Limit != 0) { TotalPages++; } LastBtn.Enabled = true; NextBtn.Enabled = true; } // Set page number PageNumber.Maximum = TotalPages; PageNumber.Value = ListPage; // Update Row Count Information RowCountDesc.Text = String.Format( "Showing {0} to {1} of {2} account{3}", ++Start, Stop, TotalFilteredRows, ((TotalFilteredRows > 1) ? "s " : " ") ); // Add Total row count if (!String.IsNullOrWhiteSpace(Like)) { RowCountDesc.Text += String.Format("(filtered from " + TotalRows + " total account{0})", ((TotalRows > 1) ? "s" : "")); } // Update DataTable.Update(); } }