static void Client_Read(Server s, Client c, byte[] e) { try { object[] values = Packer.Deserialize(e); ClientPacket packet = (ClientPacket)values[0]; if (c.Value.Authenticated) { switch (packet) { case ClientPacket.Channel: HandleChannelPacket(c, (byte)values[1]); break; case ClientPacket.ChatMessage: HandleChatPacket(c, (string)values[1]); break; } } else { switch (packet) { case ClientPacket.SignIn: HandleSignInPacket(c, (string)values[1], (string)values[2]); break; case ClientPacket.Register: HandleRegisterPacket(c, (string)values[1], (string)values[2]); break; } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); c.Disconnect(); } }
private void Process(object s, SocketAsyncEventArgs e) { try { if (e.SocketError == SocketError.Success) { Client T = new Client(e.AcceptSocket, Size); lock (_Clients ){ if (_Clients.Count < MaxConnections) { _Clients.Add(T); T.Client_State += (Client x, bool y) => HandleState(x, y); T.Client_Read += (Client x, byte[] y) => OnClient_Read(x, y); T.Client_Write += (Client x) => OnClient_Write(x); if (Client_State != null) { Client_State(this, T, true); } } else { T.Disconnect(); } } e.AcceptSocket = null; if (!Handle.AcceptAsync(e)) Process(null, e); } else { Disconnect(); } } catch { Disconnect(); } }
static void HandleRegisterPacket(Client c, string name, string pass) { if (name.Length == 0 || name.Length > 16 || pass.Length != 40) { c.Disconnect(); return; } MySqlCommand q = new MySqlCommand(string.Empty, SQL); q.CommandText = "INSERT INTO users VALUES (@Username,@Password);"; q.Parameters.AddWithValue("@Username", name); q.Parameters.AddWithValue("@Password", pass); bool success = (q.ExecuteNonQuery() != 0); byte[] data = Packer.Serialize((byte)ServerPacket.Register, success); c.Send(data); }
//TODO: Don't disconnect people, instead return an error code. static void HandleSignInPacket(Client c, string name, string pass) { if (name.Length == 0 || name.Length > 16 || pass.Length != 40) { c.Disconnect(); return; } //Don't let them join if they were banned. GetBanList(); if (BanList.Contains(name.ToLower(), StringComparer.OrdinalIgnoreCase)) { c.Disconnect(); return; } MySqlCommand q = new MySqlCommand(string.Empty, SQL); q.CommandText = "SELECT Count(*) FROM users WHERE Username=@Username AND Password=@Password;"; q.Parameters.AddWithValue("@Username", name); q.Parameters.AddWithValue("@Password", pass); MySqlDataReader r = q.ExecuteReader(); bool success = r.Read() && (r.GetInt16("Count(*)") != 0); r.Close(); byte[] data = Packer.Serialize((byte)ServerPacket.SignIn, success); c.Send(data); if (success) { //If this user is already logged in from somewhere else then disconnect them. Client existing = ClientFromUsername(name); if (existing != null) { existing.Disconnect(); } c.Value.UserID = RunningID++; c.Value.Username = name; c.Value.Authenticated = true; SendLoginBarrage(c); } }
//TODO: Don't disconnect people, instead return an error code. static void HandleSignInPacket(Client c, string name, string pass) { string n = name.Trim(); if (n.Length == 0 || n.Length > 16 || pass.Length != 40 || !IsValidName(n)) { byte[] fail = Packer.Serialize((byte)ServerPacket.SignIn, false, false); c.Send(fail); return; } MySqlCommand q = new MySqlCommand("SELECT Points, Username, Rank, Ban, Mute, Email FROM users WHERE (Username=@Username OR Email=@Username) AND Password=@Password;", SQL); q.Parameters.AddWithValue("@Username", n); q.Parameters.AddWithValue("@Password", pass); MySqlDataReader r = q.ExecuteReader(); bool success = r.Read(); if (success) { int points = r.GetInt32("Points"); byte rank = r.GetByte("Rank"); bool ban = r.GetBoolean("Ban"); string email = r.GetString("Email"); string username = r.GetString("Username"); r.Close(); //TODO: Restructure this. r.Dispose(); if (ban) { c.Disconnect(); return; } //Second ban check, checks ip table. q = new MySqlCommand(string.Empty, SQL) {CommandText = "SELECT * FROM ipbans WHERE ip=@ip;"}; q.Parameters.AddWithValue("@ip", c.EndPoint.Address.ToString()); r = q.ExecuteReader(); bool sCheck = r.Read(); r.Close(); if (sCheck) { c.Disconnect(); return; } q = new MySqlCommand("SELECT * FROM authcodes WHERE User=@User;", SQL); q.Parameters.AddWithValue("@User", username); r = q.ExecuteReader(); //Pending email verification bool unverified = r.Read() && r.GetByte("AuthType") == (byte)AuthType.AccountVerification; r.Close(); if (unverified) { byte[] notVerified = Packer.Serialize((byte)ServerPacket.NotVerified); c.Send(notVerified); } byte[] data = Packer.Serialize((byte)ServerPacket.SignIn, true, !unverified); c.Send(data); //If this user is already logged in from somewhere else then disconnect them. Client existing = ClientFromUsername(n); if (existing != null && existing != c) { existing.Disconnect(); } c.Value.UserId = RunningID++; c.Value.Username = username; c.Value.Points = points; c.Value.Rank = rank; c.Value.Mute = new List<Client>(); c.Value.LastPayout = DateTime.Now; c.Value.LastAction = DateTime.Now; c.Value.Email = email; c.Value.Authenticated = true; c.Value.Verified = !unverified; if (!unverified) { SendProfile(c); SendLoginBarrage(c); } } else { r.Close();//TODO: Restructure this. byte[] data1 = Packer.Serialize((byte)ServerPacket.SignIn, false, false); c.Send(data1); } }
static void HandleChannelPacket(Client c, byte channel) { if (channel < Channels.Length) { byte oldChannel = c.Value.Channel; c.Value.Channel = channel; SendUserListUpdates(c, oldChannel); } else { c.Disconnect(); return; } }
static void HandlePMPacket(Client c, string recipient, string message, string subject, ushort id = default(ushort)) { if (!(IsValidName(recipient) && IsValidData(message) && IsValidData(subject))) { c.Disconnect(); return; } Client u = ClientFromUsername(recipient); if (u == null) return; PrivateMessage pm = null; if (id == default(ushort) && !privateMessages.Exists(x => x.Id == id)) { pm = new PrivateMessage(id = (ushort)_random.Next(ushort.MinValue, ushort.MaxValue), subject, c.Value.Username, DateTime.Now, message); privateMessages.Add(pm); byte[] confirm = Packer.Serialize((byte)ServerPacket.PMConfirm, id, u.Value.Username, message, subject, DateTime.Now); c.Send(confirm); } else { pm = privateMessages.Find(x => x.Id == id); pm.Message.Add(message); } byte[] data = Packer.Serialize((byte)ServerPacket.PM, id, c.Value.Username, u.Value.Username, message, subject, DateTime.Now); u.Send(data); }
static void HandleChatPacket(Client c, string message) { if (!IsValidData(message)) { c.Disconnect(); return; } if (CheckCommand(c, message)) { //byte[] confirmCommand = Packer.Serialize((byte)ServerPacket.) return; } c.Value.AddPoints(5); //AWARD 5 POINTS FOR ACTIVITY*** if (RecentMessages.Count == 10) RecentMessages.RemoveAt(0); ChatMessage msg = new ChatMessage(DateTime.Now.ToLocalTime().ToString(), message, c.Value.Username, c.Value.Rank); RecentMessages.Add(msg); byte[] data = Packer.Serialize((byte)ServerPacket.Chatter, c.Value.UserId, message); BroadcastExclusive(c.Value.UserId, c.Value.Channel, data, c); }
static void HandleChannelPacket(Client c, byte channel) { if (channel < Channels.Length) { //Let everyone in the old channel know this guy left. byte[] data = Packer.Serialize((byte)ServerPacket.UserLeave, c.Value.UserId); Broadcast(c.Value.Channel, data); c.Value.Channel = channel; SendUserListUpdates(c); } else { c.Disconnect(); return; } }
static void ClientRead(Server s, Client c, byte[] e) { try { //Anti-flood measures. if (c.Value.IsFlooding()) { c.Disconnect(); return; } object[] values = Packer.Deserialize(e); if (values == null) return; ClientPacket packet = (ClientPacket)values[0]; if (c.Value.Authenticated && c.Value.Verified) { switch (packet) { case ClientPacket.Channel: HandleWakeup(c, true); //Supress the packet send here since we are changing rooms anyways. HandleChannelPacket(c, (byte)values[1]); break; case ClientPacket.ChatMessage: HandleWakeup(c); HandleChatPacket(c, (string)values[1]); break; case ClientPacket.PM: HandleWakeup(c); HandlePMPacket(c, (string)values[1], (string)values[2], (string)values[3], values.Length == 5 ? (ushort)values[4] : default(ushort)); break; case ClientPacket.KeepAlive: HandleKeepAlivePacket(c); break; case ClientPacket.News: HandleNewsPacket(c); break; case ClientPacket.ViewProfile: HandleViewProfilePacket(c, (string)values[1]); break; case ClientPacket.EditProfile: HandleEditProfilePacket(c, (string)values[1], (string)values[2], (string)values[3]); break; case ClientPacket.AuthCode: HandleAuthCodePacket(c, (string) values[1]); break; } } else { switch (packet) { case ClientPacket.SignIn: HandleSignInPacket(c, (string)values[1], (string)values[2]); break; case ClientPacket.Register: HandleRegisterPacket(c, (string)values[1], (string)values[2], (string)values[3]); break; case ClientPacket.ResendVerification: HandleResendVerificationPacket(c); break; case ClientPacket.AuthCode: HandleAuthCodePacket(c, (string) values[1]); break; } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); c.Disconnect(); } }
private void Process(object s, SocketAsyncEventArgs e) { try { if (e.SocketError == SocketError.Success) { Client T = new Client(e.AcceptSocket, Size); lock (_Clients) { if (_Clients.Count <= MaxConnections) { _Clients.Add(T); T.Client_State += HandleState; T.Client_Read += OnClient_Read; T.Client_Write += OnClient_Write; OnClient_State(T, true); } else { T.Disconnect(); } } e.AcceptSocket = null; if (!Handle.AcceptAsync(e)) Process(null, e); } else { Disconnect(); } } catch { Disconnect(); } }