public static byte[] CreateMutualContactStatusMessage(int userId) { UserObj user; if (_users.Any(x => x.ID == userId)) { user = _users.Find(x => x.ID == userId); } else { user = DatabaseCommunication.ReadUser(userId); } byte[] dataBytes; dataBytes = ByteHelper.ConcatinateArray(BitConverter.GetBytes(user.ID), new byte[] { (byte)((user.Online ? 128 : 0) + 64 + 32 + user.Name.Length) }, Encoding.Unicode.GetBytes(user.Name)); if (user.Online) { byte[] socketBytes = ByteHelper.ConcatinateArray(BitConverter.GetBytes(user.Socket.Port), user.Socket.Address.GetAddressBytes()); dataBytes = ByteHelper.ConcatinateArray(dataBytes, socketBytes); } return(dataBytes); }
public static void TellMutualContactsAboutUserStatusChange(int userId) { List <int> contacts = DatabaseCommunication.GetOnlineContacts(userId); if (contacts.Count != 0) // if the user has no online contacts, there is no need to do the rest. { byte[] contactStatusMessageBytes = CreateMutualContactStatusMessage(userId); foreach (int contactId in contacts) { MessageToUser(contactId, ChatTwo_Protocol.MessageType.ContactStatus, contactStatusMessageBytes); } } }
private void StatusUpdate_Click(object sender, EventArgs e) { bool worked = DatabaseCommunication.UpdateUser((int)numericUpDown1.Value, new System.Net.IPEndPoint(new System.Net.IPAddress(new byte[] { 10, 0, 0, 1 }), 9020)); if (worked) { WriteLog("user[" + (int)numericUpDown1.Value + "] Changed to online.", Color.Blue.ToArgb()); } else { WriteLog("user[" + (int)numericUpDown1.Value + "] Does not exist.", Color.Red.ToArgb()); } }
private void ReadUser_Click(object sender, EventArgs e) { UserObj user = DatabaseCommunication.ReadUser((int)numericUpDown1.Value); if (user != null) { WriteLog(user.ToString(), Color.Purple.ToArgb()); } else { WriteLog("user[" + (int)numericUpDown1.Value + "] Does not exist.", Color.Red.ToArgb()); } }
private void CreateUser_Click(object sender, EventArgs e) { string hashedPassword = ByteHelper.GetHashString(Encoding.Unicode.GetBytes(textBox2.Text)); bool worked = DatabaseCommunication.CreateUser(textBox1.Text, hashedPassword); if (worked) { WriteLog("user[\"" + textBox1.Text + "\"] Was created successfully.", Color.Blue.ToArgb()); } else { WriteLog("user[\"" + textBox1.Text + "\"] Was not created.", Color.Red.ToArgb()); } }
private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { DialogResult reply = MessageBox.Show(this, "Are you sure you want to close the server?", "Close?", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (reply == DialogResult.No) { e.Cancel = true; } else { // Add closing of sockets and stuff here! _server.Stop(); DatabaseCommunication.Disconnect(); } }
private void btnSqlUpdate_Click(object sender, EventArgs e) { bool worked = DatabaseCommunication.UpdateDatabase(tbxSqlUser.Text, tbxSqlPassword.Text, tbxSqlAddress.Text, (int)nudSqlPort.Value); if (worked) { tbxSql_ConnectionStringValuesChanged(null, null); toolStripStatusLabel1.Text = "SQL database Updated"; btnSqlTest_Click(null, null); } else { WriteLog("Could not update the database.", Color.Red.ToArgb()); } }
public static void SendAllContacts(int userId) { Dictionary <int, byte> contacts = DatabaseCommunication.GetAllContacts(userId); foreach (KeyValuePair <int, byte> contact in contacts) { byte[] contactStatusMessageBytes; if (contact.Value == 0x03) // 0b00000011 { contactStatusMessageBytes = CreateMutualContactStatusMessage(contact.Key); } else { contactStatusMessageBytes = CreateNonMutualContactStatusMessage(contact.Key, ByteHelper.CheckBitCodeIndex(contact.Value, 0), ByteHelper.CheckBitCodeIndex(contact.Value, 1)); } MessageToUser(userId, ChatTwo_Protocol.MessageType.ContactStatus, contactStatusMessageBytes); } }
public static byte[] CreateNonMutualContactStatusMessage(int userId, bool relationshipTo, bool relationshipFrom) { UserObj user; if (_users.Any(x => x.ID == userId)) { user = _users.Find(x => x.ID == userId); } else { user = DatabaseCommunication.ReadUser(userId); } byte[] dataBytes; dataBytes = ByteHelper.ConcatinateArray(BitConverter.GetBytes(user.ID), new byte[] { (byte)((relationshipTo ? 64 : 0) + (relationshipFrom ? 32 : 0) + user.Name.Length) }, Encoding.Unicode.GetBytes(user.Name)); return(dataBytes); }
private void btnSqlConnect_Click(object sender, EventArgs e) { tbxSqlUser.ReadOnly = !tbxSqlUser.ReadOnly; tbxSqlPassword.ReadOnly = !tbxSqlPassword.ReadOnly; tbxSqlAddress.ReadOnly = !tbxSqlAddress.ReadOnly; nudSqlPort.Enabled = !nudSqlPort.Enabled; btnSqlTest.Enabled = !btnSqlTest.Enabled; if (DatabaseCommunication.Active) { DatabaseCommunication.Disconnect(); btnSqlConnect.Text = "Start Database Connection"; tabSqlTest.Parent = null; } else { DatabaseCommunication.Connect(tbxSqlUser.Text, tbxSqlPassword.Text, tbxSqlAddress.Text, (int)nudSqlPort.Value); btnSqlConnect.Text = "Stop Database Connection"; tabSqlTest.Parent = tabControl1; } UpdateServerStatus(); }
public static void UserConnect(UserObj user) { DatabaseCommunication.UpdateUser(user.ID, user.Socket); TellMutualContactsAboutUserStatusChange(user.ID); SendAllContacts(user.ID); }
public static void MessageReceivedHandler(object sender, PacketReceivedEventArgs args) { if (!DatabaseCommunication.Active) #if DEBUG { throw new NotImplementedException("Database connection was not active and a reply for this have not been implemented yet."); } // Need to add a simple debug message here, but this works as a great breakpoint until then. // Also need to make some kind of error message I can send back to the client. #else { return; } #endif if (args.Data[0] == 0x92) { string sharedSecret; // Position of the Type byte is 30 (SignatureByteLength + MacByteLength + TimezByteLength + UserIdByteLength). ChatTwo_Protocol.MessageType type = (ChatTwo_Protocol.MessageType)args.Data[ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4 + 4]; // Position of the UserID bytes is 26 (SignatureByteLength + MacByteLength + TimezByteLength) with a length of 4. int userId = ByteHelper.ToInt32(args.Data, ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4); if (type == ChatTwo_Protocol.MessageType.CreateUser) { sharedSecret = ChatTwo_Protocol.DefaultSharedSecret; } else if (type == ChatTwo_Protocol.MessageType.Login) { #if DEBUG byte[] test = ByteHelper.SubArray(args.Data, ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4); #endif // Don't take the Timez as part of the sharedSecret. This is mostly because of a problem I have in the client where I make the sharedSecrt before I add the Timez. sharedSecret = ByteHelper.GetHashString(ByteHelper.SubArray(args.Data, ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4)); } else { if (!_users.Any(x => x.ID == userId)) { return; // This is mostly to prevent clients with a connection to a previces server instants from crashing the server. Need to fix this. } sharedSecret = _users.Find(x => x.ID == userId).Secret; } if (ChatTwo_Protocol.ValidateMac(args.Data, sharedSecret)) { Message message = ChatTwo_Protocol.MessageReceivedHandler(args); switch (message.Type) { case ChatTwo_Protocol.MessageType.CreateUser: { string passwordHash = Convert.ToBase64String(message.Data, 0, ByteHelper.HashByteLength); string username = Encoding.Unicode.GetString(ByteHelper.SubArray(message.Data, ByteHelper.HashByteLength)); if (username.Length < 1 || username.Length > 30) { // Username is too short or too long. MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.CreateUserReply, new byte[] { 0x02 }); return; } bool worked = DatabaseCommunication.CreateUser(username, passwordHash); if (!worked) { // Some error prevented the user from being created. Best guess is that a user with that name already exist. MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.CreateUserReply, new byte[] { 0x01 }); return; } // Uesr creation was successful! MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.CreateUserReply, new byte[] { 0x00 }); break; } case ChatTwo_Protocol.MessageType.Login: { string passwordHash = Convert.ToBase64String(message.Data, 0, ByteHelper.HashByteLength); string username = Encoding.Unicode.GetString(ByteHelper.SubArray(message.Data, ByteHelper.HashByteLength)); UserObj user = DatabaseCommunication.LoginUser(username, passwordHash); if (user == null) { // Have to send back a LoginReply message here with a "wrong username/password" error. _tempUsers.Add(message.Ip, sharedSecret); MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.LoginReply, new byte[] { 0x01 }); return; } if (_users.Any(x => x.ID == user.ID)) { // Have to send back a LoginReply message here with a "User is already online" error. _tempUsers.Add(message.Ip, sharedSecret); MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.LoginReply, new byte[] { 0x02 }); return; } user.Secret = sharedSecret; user.Socket = message.Ip; user.Online = true; _users.Add(user); MessageToUser(user.ID, ChatTwo_Protocol.MessageType.LoginReply, ByteHelper.ConcatinateArray(new byte[] { 0x00 }, BitConverter.GetBytes(user.ID)), user.Name); UserConnect(user); break; } case ChatTwo_Protocol.MessageType.Status: { UserObj user = _users.Find(x => x.ID == message.From); if (user != null) // If the user is not found, don't do anything. (Can this happen?) { if (!IPEndPoint.Equals(user.Socket, message.Ip)) { user.Socket = message.Ip; // Message all contacts of the user with the new IP change. TellMutualContactsAboutUserStatusChange(user.ID); } DatabaseCommunication.UpdateUser(user.ID, user.Socket); } break; } case ChatTwo_Protocol.MessageType.ContactRequest: { string username = Encoding.Unicode.GetString(message.Data); UserObj user = DatabaseCommunication.LookupUser(username); if (user == null) { // Have to send back a ContactRequestReply message here with a "No user with that name" error. MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x01 }); return; } if (user.ID == message.From) { // Have to send back a ContactRequestReply message here with a "You can't add your self" error. MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x02 }); return; } bool added = DatabaseCommunication.AddContact(message.From, user.ID); if (!added) { // Have to send back a ContactRequestReply message here with a "User is already a contact" error. MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x03 }); return; } MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x00 }); //if (_users.Any(x => x.ID == user.ID)) // TellContactsAboutUserStatusChange(message.From, true); // Need to figure this out. break; } } } #if DEBUG else { throw new NotImplementedException("Could not validate the MAC of the received message."); } // Need to add a simple debug message here, but this works as a great breakpoint until then. #endif } #if DEBUG else { throw new NotImplementedException("Could not validate the signature of the received message. The signature was \"0x" + args.Data[0] + "\" but only \"0x92\" is allowed."); } // Need to add a simple debug message here, but this works as a great breakpoint until then. #endif }
private void btnSqlTest_Click(object sender, EventArgs e) { tbxSql_ConnectionStringValuesChanged(null, null); btnSqlTest.Enabled = false; // Basic user feedback. toolStripStatusLabel1.Text = "Testing connection and access to the database..."; statusStrip1.Refresh(); // Has to be done or the statusStrip won't display the new toolStripStatusLabel text. // Test the connection and access, giving the user feedback if it fails. DatabaseCommunication.ConnectionTestResult dbTest = DatabaseCommunication.TestConnection(tbxSqlUser.Text, tbxSqlPassword.Text, tbxSqlAddress.Text, (int)nudSqlPort.Value); // Check the result of the connetion test. bool connectTestSuccessful = dbTest == DatabaseCommunication.ConnectionTestResult.Successful; if (connectTestSuccessful) { toolStripStatusLabel1.Text = "Database connection test: successful"; lblSqlConnection.Text = "Test: successful"; toolTip1.SetToolTip(lblSqlConnection, ""); btnSqlConnect.Enabled = true; } else { string errorMessage; string errorTip; switch (dbTest) { case DatabaseCommunication.ConnectionTestResult.NoConnection: errorMessage = "Could not connect to the server at \"" + tbxSqlAddress.Text + ":" + (int)nudSqlPort.Value + "\""; errorTip = "." + Environment.NewLine + Environment.NewLine + "Please make sure the MySQL server is running and the IP address and port is correct."; break; case DatabaseCommunication.ConnectionTestResult.FailLogin: errorMessage = "Login rejected by server"; errorTip = "." + Environment.NewLine + Environment.NewLine + "Please make sure the username and password is correct."; break; case DatabaseCommunication.ConnectionTestResult.NoPermission: errorMessage = "Permission failed for user"; errorTip = "." + Environment.NewLine + Environment.NewLine + "Talk to the system admin to gain access to the MySQL server."; break; case DatabaseCommunication.ConnectionTestResult.MissingDatabase: errorMessage = "Database does not exist"; errorTip = "." + Environment.NewLine + Environment.NewLine + "You can create/repair the database by clicking the button below."; btnSqlCreate.Enabled = true; break; case DatabaseCommunication.ConnectionTestResult.MissingTable: errorMessage = "One or more of the tables do not exist"; errorTip = "." + Environment.NewLine + Environment.NewLine + "You can create/repair the database by clicking the button below."; btnSqlCreate.Enabled = true; break; case DatabaseCommunication.ConnectionTestResult.OutDated: errorMessage = "SQL database need to be updated"; errorTip = "."; btnSqlUpdate.Enabled = true; break; default: errorMessage = "Unknown SQL error"; errorTip = "."; break; } if (sender != null) { MessageBox.Show(errorMessage + errorTip, "SQL Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } toolStripStatusLabel1.Text = "Database connection test: failed. " + errorMessage; lblSqlConnection.Text = "Test: failed"; lblSqlConnection.Image = _infoTip; toolTip1.SetToolTip(lblSqlConnection, errorMessage + errorTip); } btnSqlTest.Enabled = true; }