예제 #1
0
        private void AcceptCallback(IAsyncResult ar)
        {
            LoginSocketState state = (LoginSocketState)ar.AsyncState;

            try
            {
                Socket client = state.Socket.EndAccept(ar);

                Thread.Sleep(1);

                if (state.Type == LoginSocketState.SocketType.Client)
                {
                    _clientManagerReset.Set();
                }
                else if (state.Type == LoginSocketState.SocketType.Search)
                {
                    _searchManagerReset.Set();
                }

                state.Socket = client;

                Logger.Info($"[{state.Type}] New Client: { ((IPEndPoint)state.Socket.RemoteEndPoint).Address}:{((IPEndPoint)state.Socket.RemoteEndPoint).Port}");

                if (state.Type == LoginSocketState.SocketType.Client)
                {
                    // ClientManager server sends data first
                    byte[] buffer = LoginServerMessages.GenerateServerChallenge(ref state);
                    SendToClient(ref state, buffer);

                    if (state != null)
                    {
                        state.State++;
                    }
                }
                else if (state.Type == LoginSocketState.SocketType.Search)
                {
                    // SearchManager server waits for data first
                }
            }
            catch (NullReferenceException)
            {
                if (state != null)
                {
                    state.Dispose();
                }
                state = null;
            }
            catch (SocketException e)
            {
                Logger.Error(e, $"Error accepting client. SocketErrorCode: {e.SocketErrorCode}");
                if (state != null)
                {
                    state.Dispose();
                }
                state = null;
                return;
            }

            WaitForData(ref state);
        }
예제 #2
0
        private void KeepAliveCallback(object s)
        {
            LoginServer server = (LoginServer)s;

            try
            {
                if (_keepAliveTimer == null)
                {
                    Dispose();
                    return;
                }

                LoginSocketState state = this;
                HeartbeatState++;

                Console.WriteLine("sending keep alive");
                if (!server.SendToClient(ref state, LoginServerMessages.SendKeepAlive()))
                {
                    Dispose();
                    return;
                }

                // every 2nd keep alive request, we send an additional heartbeat
                if (HeartbeatState % 2 == 0)
                {
                    Console.WriteLine("sending heartbeat");
                    if (!server.SendToClient(ref state, LoginServerMessages.SendHeartbeat()))
                    {
                        Dispose();
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                logger.Error(e, "Error running keep alive");
                Dispose();
            }
        }
예제 #3
0
 private void HandleSearchManager(ref LoginSocketState state, string query, Dictionary <string, string> keyValues)
 {
     if (state.State == 0)
     {
         if (query.Equals("nicks", StringComparison.InvariantCultureIgnoreCase))
         {
             SendToClient(ref state, LoginServerMessages.SendNicks(ref state, keyValues));
         }
         else if (query.Equals("check", StringComparison.InvariantCultureIgnoreCase))
         {
             SendToClient(ref state, LoginServerMessages.SendCheck(ref state, keyValues));
         }
     }
     else if (state.State == 1)
     {
         state.State++;
     }
     else if (state.State >= 2)
     {
         state.Dispose();
     }
 }
예제 #4
0
        private void HandleClientManager(ref LoginSocketState state, string query, Dictionary <string, string> keyValues)
        {
            if (state == null || String.IsNullOrWhiteSpace(query) || keyValues == null)
            {
                return;
            }

            if (state.State >= 4)
            {
                state.Dispose();
            }
            else
            {
                switch (query)
                {
                case "login":
                    SendToClient(ref state, LoginServerMessages.SendProof(ref state, keyValues));
                    Users[state.ProfileId] = state;
                    state.StartKeepAlive(this);

                    break;

                case "newuser":
                    SendToClient(ref state, LoginServerMessages.NewUser(ref state, keyValues));
                    break;

                case "addbuddy":
                    // \\addbuddy\\\\sesskey\\51437\\newprofileid\\1\\reason\\just be my friend

                    var newFriendId = long.Parse(keyValues["newprofileid"]);

                    if (Database.MainDBInstance.AddFriend(state.ProfileId, newFriendId))
                    {
                        //var signature = (state.ProfileId.ToString() + newFriendId.ToString()).ToMD5();
                        // "\\bm\\%d\\f\\%d\\msg\\%s|signed|%s",GPI_BM_REQUEST,profileid,reason,signature);
                        //SendToClient(ref state, $@"\bm\2\f\{newFriendId}\msg\{keyValues["reason"]}|signed|{signature}".ToAssciiBytes());

                        if (Users.TryGetValue(newFriendId, out LoginSocketState friendState))
                        {
                            SendToClient(ref friendState, $@"\bm\100\f\{state.ProfileId}\msg\|s|{state.Status}{state.GetLSParameter()}|ss|{state.StatusString}\final\".ToAssciiBytes());
                            SendToClient(ref state, $@"\bm\100\f\{newFriendId}\msg\|s|{friendState.Status}{friendState.GetLSParameter()}|ss|{friendState.StatusString}\final\".ToAssciiBytes());
                        }
                        else
                        {
                            SendToClient(ref state, $@"\bm\100\f\{newFriendId}\msg\|s|0|ss|Offline\final\".ToAssciiBytes());
                        }
                    }
                    break;

                case "delbuddy":
                    // \delbuddy\\sesskey\51437\delprofileid\1
                    Database.MainDBInstance.RemoveFriend(state.ProfileId, long.Parse(keyValues["delprofileid"]));
                    break;

                case "getprofile":
                    SendToClient(ref state, LoginServerMessages.SendProfile(ref state, keyValues));
                    break;

                case "updatepro":
                    //LoginServerMessages.UpdateProfile(ref state, keyValues);
                    break;

                case "status":

                    var remoteEndPoint = ((IPEndPoint)state.Socket.RemoteEndPoint);

                    var profile = Database.MainDBInstance.GetProfileById(state.ProfileId);

                    if (profile == null)
                    {
                        return;
                    }

                    var friends = profile.Friends ?? new List <long>();

                    SendToClient(ref state, $@"\bdy\{friends.Count + 1}\list\{string.Join(",",friends.Concat(new long[] { profile.Id }))}\final\".ToAssciiBytes());

                    // var loopbackIp = (uint)IPAddress.NetworkToHostOrder((int)IPAddress.Loopback.Address);
                    // var loopbackIp = ReverseEndian32((uint)IPAddress.NetworkToHostOrder((int)IPAddress.Parse("192.168.159.128").Address));
                    // var port = ReverseEndian16(27900);

                    state.Status       = keyValues.GetOrDefault("status") ?? state.Status ?? "0";
                    state.StatusString = keyValues.GetOrDefault("statstring") ?? state.StatusString ?? "Offline";
                    state.LocString    = keyValues.GetOrDefault("locstring") ?? state.LocString ?? "-1";

                    //SendToClient(ref state, $@"\bm\100\f\{profile.Id}\msg\|s|{1}|ss|DXP{"|ls|"}{-1}|ip|{loopbackIp}|p|{port}|qm|{0}\final\".ToAssciiBytes());

                    var statusResult = $@"\bm\100\f\{profile.Id}\msg\|s|{state.Status}{state.GetLSParameter()}|ss|{state.StatusString}\final\".ToAssciiBytes();
                    SendToClient(ref state, statusResult);

                    for (int i = 0; i < friends.Count; i++)
                    {
                        var friendId = friends[i];

                        if (Users.TryGetValue(friendId, out LoginSocketState friendState))
                        {
                            SendToClient(ref friendState, statusResult);
                            //SendToClient(ref state, $@"\bm\100\f\{friendId}\msg\|s|{1}|ss|DXP|ls|-1\final\".ToAssciiBytes());
                            SendToClient(ref state, $@"\bm\100\f\{friendId}\msg\|s|{friendState.Status}{friendState.GetLSParameter()}|ss|{friendState.StatusString}\final\".ToAssciiBytes());
                        }
                        else
                        {
                            SendToClient(ref state, $@"\bm\100\f\{friendId}\msg\|s|0|ss|Offline\final\".ToAssciiBytes());
                        }
                    }

                    // \status\1\sesskey\17562\statstring\DXP\locstring\-1

                    // userid\200000003\profileid\100000003\uniquenick\Bambochuk

                    //sendBuddies()
                    // SendToClient(ref state, $@"\bdy\1\list\100000003\final\".ToAssciiBytes());
                    //SendToClient(ref state, $@"\bdy\0\list\\final\".ToAssciiBytes());

                    // TODO: sendAddRequests();

                    //sendStatusUpdateToBuddies(this);

                    // send self status
                    // |s|%d|ss|%s%s%s|ip|%d|p|%d|qm|%d

                    /*
                     * c->status,
                     *      c->statusstr,
                     *      c->locstr[0] != 0 ? "|ls|" : "",
                     *      c->locstr,
                     *      reverse_endian32(c->ip),
                     *      reverse_endian16(c->port),
                     *      c->quietflags
                     */

                    // SendToClient(ref state, $@"\bm\100\f\100000003\msg\|s|{2}|ss|DXP{"|ls|"}{-1}|ip|{(uint)IPAddress.NetworkToHostOrder((int)IPAddress.Loopback.Address)}|p|{ReverseEndian16(6500)}|qm|{0}\final\".ToAssciiBytes());
                    //SendToClient(ref state, $@"\bm\100\f\100000002\msg\|s|0|ss|Offline\final\".ToAssciiBytes());
                    //SendToClient(ref state, $@"\bm\100\f\100000001\msg\|s|{1}|ss|DXP{"|ls|"}{-1}|ip|{(uint)IPAddress.NetworkToHostOrder((int)remoteEndPoint.Address.Address)}|p|{ReverseEndian16(6500)}|qm|{0}\final\".ToAssciiBytes());



                    // send friend status



                    break;

                case "logout":
                    Users.TryRemove(state.ProfileId, out LoginSocketState removingState);
                    LoginServerMessages.Logout(ref state, keyValues);
                    break;

                case "registernick":
                    SendToClient(ref state, DataFunctions.StringToBytes(string.Format(@"\rn\{0}\id\{1}\final\", keyValues["uniquenick"], keyValues["id"])));
                    break;

                case "ka":
                    SendToClient(ref state, $@"\ka\\final\".ToAssciiBytes());
                    break;

                default:
                    break;
                }
            }
        }