Пример #1
0
        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();
            }
        }
Пример #2
0
 private void OnClient_Read(Client c, byte[] e)
 {
     if (Client_Read != null)
     {
         Client_Read(this, c, e);
     }
 }
Пример #3
0
 private void OnClient_Write(Client c)
 {
     if (Client_Write != null)
     {
         Client_Write(this, c);
     }
 }
Пример #4
0
        static void SendLoginBarrage(Client c)
        {
            SendChannelList(c);
            SendUserListUpdates(c, c.Value.Channel);

            string MOTD = GetMOTD();

            if (!string.IsNullOrEmpty(MOTD))
            {
                byte[] data = Packer.Serialize((byte)ServerPacket.MOTD, MOTD);
                c.Send(data);
            }
        }
Пример #5
0
        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();
            }
        }
Пример #6
0
 static void HandleChatPacket(Client c, string message)
 {
     if (GetUserLevel(c.Value.Username) & message.Contains("~"))
     {
         Console.WriteLine(c.Value.Username + " executed admin command. Command: " + message);
         ProcessCommand(message);
     }
     else
     {
         byte[] data = Packer.Serialize((byte)ServerPacket.Chatter, c.Value.UserID, message);
         BroadcastExclusive(c.Value.UserID, c.Value.Channel, data);
     }
 }
Пример #7
0
        //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);
            }
        }
Пример #8
0
 static void HandleKeepAlivePacket(Client c)
 {
     byte[] data = Packer.Serialize((byte)ServerPacket.KeepAlive);
     c.Send(data);
 }
Пример #9
0
 static void HandleNewsPacket(Client c)
 {
     byte[] data = Packer.Serialize((byte)ServerPacket.News, GetNews());
     c.Send(data);
 }
Пример #10
0
        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);
        }
Пример #11
0
        static void HandleEditProfilePacket(Client c, string avatar, string bio, string profile)
        {
            if (!(avatar.Contains("http://") || avatar.Contains("https://")))
                avatar = avatar.Insert(0, "http://");
            if (!(profile.Contains("http://") || profile.Contains("https://")))
                profile = profile.Insert(0, "http://");

            bool validProfile = Regex.IsMatch(profile, @"^(http:\/\/|https:\/\/)*(www\.)*hackforums\.net\/member\.php\?action=profile&uid=\d{1,7}$");

            MySqlCommand q = new MySqlCommand("UPDATE users SET Avatar=@Avatar, Bio=@Bio, ProfileLink=@ProfileLink WHERE Username=@Username;", SQL);
            q.Parameters.AddWithValue("@Username", c.Value.Username);
            q.Parameters.AddWithValue("@Bio", bio);
            q.Parameters.AddWithValue("@Avatar", avatar);
            q.Parameters.AddWithValue("@ProfileLink", validProfile ? profile : "");

            bool success = q.ExecuteNonQuery() == 0;

            byte[] data = Packer.Serialize((byte)ServerPacket.EditProfile, success);
            c.Send(data);
        }
Пример #12
0
        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;
            }
        }
Пример #13
0
        static void HandleAuthCodePacket(Client c, string authCode)
        {
            MySqlCommand q = new MySqlCommand("SELECT AuthType, Value FROM authcodes WHERE (User=@Username) AND Value=@Value;", SQL);
            q.Parameters.AddWithValue("@Username", c.Value.Username);
            q.Parameters.AddWithValue("@Value", authCode);

            MySqlDataReader r = q.ExecuteReader();
            bool read = r.Read() && r.HasRows;

            if (read)
            {
                AuthType authType = (AuthType) r.GetByte("AuthType");

                r.Close();

                q.CommandText = "DELETE FROM `authcodes` WHERE `Value`=@Value AND `User`=@Username LIMIT 1;";

                bool success = q.ExecuteNonQuery() != 0;

                byte[] data = Packer.Serialize((byte) ServerPacket.AuthResponse,(byte)authType, success);
                c.Send(data);
            }
            else
            {
                byte[] data = Packer.Serialize((byte) ServerPacket.AuthResponse, (byte)AuthType.Unknown, false);
                c.Send(data);
            }
        }
Пример #14
0
        static void ClientState(Server s, Client c, bool open)
        {
            if (open)
            {
                c.Value = new UserState();
                if (!string.IsNullOrEmpty(MOTD))
                {
                    byte[] data = Packer.Serialize((byte)ServerPacket.MOTD, MOTD);
                    c.Send(data);
                }
            }
            else
            {
                if (c.Value.Authenticated)
                {
                    byte[] data = Packer.Serialize((byte)ServerPacket.UserLeave, c.Value.UserId);
                    Broadcast(c.Value.Channel, data);

                    AwardPoints(c);

                    //Let's save the users data.
                    MySqlCommand q = new MySqlCommand(string.Empty, SQL);
                    q.CommandText = "UPDATE users SET Points=@Points,Rank=@Rank,Mute=@Mute WHERE Username=@Username;";
                    q.Parameters.AddWithValue("@Points", c.Value.Points);
                    q.Parameters.AddWithValue("@Rank", c.Value.Rank);
                    q.Parameters.AddWithValue("@Mute", c.Value.Mute);
                    q.Parameters.AddWithValue("@Username", c.Value.Username);

                    //If it fails there isn't much we can do about it.
                    q.ExecuteNonQuery();
                }
            }
        }
Пример #15
0
 static void Client_State(Server s, Client c, bool open)
 {
     if (open)
     {
         c.Value = new UserState();
     }
     else
     {
         if (c.Value.Authenticated)
         {
             byte[] data = Packer.Serialize((byte)ServerPacket.UserLeave, c.Value.UserID, c.Value.Username);
             Broadcast(c.Value.Channel, data);
         }
     }
 }
Пример #16
0
        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);
        }
Пример #17
0
 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;
     }
 }
Пример #18
0
        static void HandleRegisterPacket(Client c, string name, string pass, string email)
        {
            string n = name.Trim();

            if (n.Length == 0 || n.Length > 16 || pass.Length != 40 || !IsValidName(n) || email.Length == 0 || email.Length > 256)
            {
                byte[] fail = Packer.Serialize((byte)ServerPacket.Register, false);
                c.Send(fail);
                return;
            }

            MySqlCommand q = new MySqlCommand("SELECT Count(*) FROM users WHERE Username=@Username", SQL);
            q.Parameters.AddWithValue("@Username", n);

            MySqlDataReader r = q.ExecuteReader();
            bool available = r.Read() && (r.GetInt16(0) == 0);
            r.Close();

            if (available)
            {
                MySqlCommand q2 = new MySqlCommand(string.Empty, SQL);
                q2.CommandText = "INSERT INTO users VALUES (@Username,@Password,@Email,0,0,0,0,\"\",\"\",\"\");";
                q2.Parameters.AddWithValue("@Username", n);
                q2.Parameters.AddWithValue("@Password", pass);
                q2.Parameters.AddWithValue("@Email", email);

                //If registration fails, this will return false.
                bool success = (q2.ExecuteNonQuery() != 0);

                if (success)
                {
                    c.Value.Username = name;
                    c.Value.Email = email;
                    SendEmail(email, n);
                }

                byte[] data = Packer.Serialize((byte)ServerPacket.Register, success);
                c.Send(data);
            }
            else
            {
                byte[] data = Packer.Serialize((byte)ServerPacket.Register, false);
                c.Send(data);
            }
        }
Пример #19
0
        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);
        }
Пример #20
0
        static void HandleResendVerificationPacket(Client c)
        {
            MySqlCommand q = new MySqlCommand("SELECT * FROM authcodes WHERE User=@User AND AuthType=1", SQL);
            q.Parameters.AddWithValue("@User", c.Value.Username);

            MySqlDataReader r = q.ExecuteReader();
            bool available = r.Read();

            if (!available) return;

            string authCode = r.GetString("Value");

            SendEmail(c.Value.Email, c.Value.Username, authCode);
        }
Пример #21
0
        static void SendChannelList(Client c)
        {
            List<object> values = new List<object>();
            values.Add((byte)ServerPacket.ChannelList);
            values.AddRange(Channels);

            byte[] data = Packer.Serialize(values.ToArray());
            c.Send(data);
        }
Пример #22
0
        //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);
            }
        }
Пример #23
0
        static void SendUserListUpdates(Client c, byte oldChannel)
        {
            try
            {
                byte[] data1 = Packer.Serialize((byte)ServerPacket.UserJoin, c.Value.UserID, c.Value.Username);
                BroadcastExclusive(c.Value.UserID, c.Value.Channel, data1);

                List<object> cValues = new List<object>();
                cValues.Add((byte)ServerPacket.UserList);

                //Send updates to old channel.
                List<object> oldValues = new List<object>();
                oldValues.Add((byte)ServerPacket.UserList);

                foreach (Client u in Listener.Clients)
                {
                    if (u.Value.Authenticated && u.Value.Channel == c.Value.Channel)
                    {
                        cValues.Add(u.Value.UserID);
                        cValues.Add(u.Value.Username);
                    } else {
                        oldValues.Add(u.Value.UserID);
                        oldValues.Add(u.Value.Username);
                    }
                }

                byte[] data2 = Packer.Serialize(cValues.ToArray());
                c.Send(data2);
                if (oldValues.Count > 1)
                {
                    byte[] data3 = Packer.Serialize(oldValues.ToArray());
                    Broadcast(oldChannel, data3);
                }
            }
            catch { }
        }
Пример #24
0
 static void HandleViewProfilePacket(Client c, string username)
 {
     Client to = ClientFromUsername(username);
     if (to != null)
         SendProfileTo(c, to);
 }
Пример #25
0
 private void HandleState(Client s, bool open)
 {
     lock (_Clients)
     {
         _Clients.Remove(s);
         if (Client_State != null)
         {
             Client_State(this, s, false);
         }
     }
 }
Пример #26
0
        static void HandleWakeup(Client c, bool suppress = false)
        {
            c.Value.LastAction = DateTime.Now;

            if (!c.Value.Idle) return;

            c.Value.Idle = false;

            if (suppress) return;

            byte[] data = Packer.Serialize((byte)ServerPacket.WakeUp, c.Value.UserId);
            Broadcast(c.Value.Channel, data);
        }
Пример #27
0
 private void OnClient_State(Client c, bool open)
 {
     if (Client_State != null)
     {
         Client_State(this, c, open);
     }
 }
Пример #28
0
        static void MuteUser(Client c, string name, bool global)
        {
            Client muted = ClientFromUsername(name);

            if (muted != null)
            {
                if (global)
                {
                    foreach (Client x in Listener.Clients)
                    {
                        if (x != muted)
                            x.Value.Mute.Add(muted);
                        return;
                    }
                }

                c.Value.Mute.Add(muted);
                Console.WriteLine(name + " has been muted by " + c.Value.Username);
            }
        }
Пример #29
0
        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();
            }
        }
Пример #30
0
        static bool CheckCommand(Client c, string query)
        {
            string[] args = ParseArguments(query);
            string command = args[0].ToLower();
            if (command[0] == '/')
            {
                command = command.Substring(1, command.Length - 1);
                if (AdminCommands.Contains(command) && (c == null /*This is only null if typed directly into the console.*/ || c.Value.Rank == (byte)SpecialRank.Admin))
                {
                    //TODO: Find a better way to do this.
                    switch (command)
                    {
                        case "kick":
                            if (args.Length == 2)
                            {
                                if (KickUser(args[1]))
                                    return true;
                            }
                            break;
                        case "ban":
                            if (BanUser(args[1], args.Length == 3 && args[2] == 1.ToString() ? 1 : 0))
                                return true;
                            break;
                        case "unban":
                            if (args.Length == 2)
                            {
                                if (UnbanUser(args[1]))
                                    return true;
                            }
                            break;
                        case "globalmsg":
                            if (args.Length == 2)
                            {
                                byte[] data = Packer.Serialize((byte)ServerPacket.GlobalMsg, args[1]);
                                GlobalBroadcast(data);
                                return true;
                            }
                            break;
                        case "setlevel":
                            if (args.Length == 3)
                            {
                                if (SetUserRank(args[1], args[2]))
                                    return true;
                            }
                            break;
                        case "globalmute":
                            if (args.Length == 2 && args[1] != c.Value.Username)
                            {
                                MuteUser(c, args[1], true);
                                return true;
                            }
                            break;
                        case "globalunmute":
                            if (args.Length == 2 && args[1] != c.Value.Username)
                            {
                                UnmuteUser(c, args[1], true);
                                return true;
                            }
                            break;
                        case "updatemotd":
                            MOTD = GetMOTD();
                            return true;
                        case "shutdown":
                            UpdateAndSaveUsers(true);
                            Environment.Exit(0);
                            break;
                        case "cls":
                            ClearChat();
                            break;
                    }
                }

                if (UserCommands.Contains(command))
                {
                    switch (command)
                    {
                        case "mute":
                            if (args.Length == 2 && args[1] != c.Value.Username)
                            {
                                MuteUser(c, args[1], false);
                                return true;
                            }
                            break;
                        case "unmute":
                            if (args.Length == 2 && args[1] != c.Value.Username)
                            {
                                UnmuteUser(c, args[1], false);
                                return true;
                            }
                            break;
                    }
                }
            }
            return false;
        }