示例#1
0
        public static void Switch(GPCMClient client, Dictionary <string, string> recv, GPCMConnectionUpdate OnSuccessfulLogin, GPCMStatusChanged OnStatusChanged)
        {
            string command = recv.Keys.First();

            try
            {
                switch (command)
                {
                case "inviteto":
                    InviteToHandler.AddFriends(client, recv);
                    break;

                case "login":
                    LoginHandler.ProcessLogin(client, recv, OnSuccessfulLogin, OnStatusChanged);
                    break;

                case "getprofile":
                    GetProfileHandler.SendProfile(client, recv);
                    break;

                case "addbuddy":
                    AddBuddyHandler.Addfriends(client, recv);
                    break;

                case "delbuddy":
                    DelBuddyHandler.Handle(client, recv);
                    break;

                case "updateui":
                    UpdateUiHandler.UpdateUi(client, recv);
                    break;

                case "updatepro":
                    UpdateProHandler.UpdateUser(client, recv);
                    break;

                case "registernick":
                    RegisterNickHandler.RegisterNick(client, recv);
                    break;

                case "logout":
                    client.DisconnectByReason(DisconnectReason.NormalLogout);
                    break;

                case "status":
                    StatusHandler.UpdateStatus(client, recv, OnStatusChanged);
                    break;

                case "newuser":
                    NewUserHandler.NewUser(client, recv);
                    break;

                case "ka":
                    KAHandler.SendKeepAlive(client);
                    break;

                default:
                    LogWriter.Log.Write("[GPCM] received unknown data " + command, LogLevel.Debug);
                    GameSpyUtils.SendGPError(client, GPErrorCode.General, "An invalid request was sended.");
                    break;
                }
            }
            catch (Exception e)
            {
                LogWriter.Log.WriteException(e);
            }
        }
示例#2
0
        /// <summary>
        /// This method verifies the login information sent by
        /// the client, and returns encrypted data for the client
        /// to verify as well
        /// </summary>
        public static void ProcessLogin(GPCMClient client, Dictionary <string, string> recv, GPCMConnectionUpdate OnSuccessfulLogin, GPCMStatusChanged OnStatusChanged)
        {
            uint partnerID = 0;

            // Make sure we have all the required data to process this login
            //if (!recv.ContainsKey("challenge") || !recv.ContainsKey("response"))
            //{
            //    GameSpyUtils.SendGPError(client, GPErrorCode.General, "Invalid response received from the client!");
            //    client.DisconnectByReason(DisconnectReason.InvalidLoginQuery);
            //    return;
            //}
            if (IsContainAllKeys(recv) != GPErrorCode.NoError)
            {
                GameSpyUtils.SendGPError(client, GPErrorCode.General, "Invalid response received from the client!");
                client.DisconnectByReason(DisconnectReason.InvalidLoginQuery);
                return;
            }


            // Parse the partnerid, required since it changes the challenge for Unique nick and User login
            ParseRequestToPlayerInfo(client, recv, ref partnerID);


            // Dispose connection after use
            try
            {
                // Try and fetch the user from the database

                Dictionary <string, object> queryResult;

                try
                {
                    if (client.PlayerInfo.PlayerUniqueNick.Length > 0)
                    {
                        queryResult = LoginQuery.GetUserFromUniqueNick(recv);
                    }
                    else if (client.PlayerInfo.PlayerAuthToken.Length > 0)
                    {
                        //TODO! Add the database entry
                        GameSpyUtils.SendGPError(client, GPErrorCode.General, "AuthToken is not supported yet");
                        return;
                    }
                    else
                    {
                        queryResult = LoginQuery.GetUserFromNickAndEmail(recv);
                    }
                }
                catch (Exception ex)
                {
                    LogWriter.Log.WriteException(ex);
                    GameSpyUtils.SendGPError(client, GPErrorCode.DatabaseError, "This request cannot be processed because of a database error.");
                    return;
                }

                //if no match found we disconnect the game
                if (queryResult == null)
                {
                    if (client.PlayerInfo.PlayerUniqueNick.Length > 0)
                    {
                        GameSpyUtils.SendGPError(client, GPErrorCode.LoginBadUniquenick, "The uniquenick provided is incorrect!");
                    }
                    else
                    {
                        GameSpyUtils.SendGPError(client, GPErrorCode.LoginBadUniquenick, "The information provided is incorrect!");
                    }
                    client.DisconnectByReason(DisconnectReason.InvalidUsername);
                    return;
                }

                // Check if user is banned
                string           msg;
                DisconnectReason reason;
                GPErrorCode      error = CheckUsersAccountAvailability(queryResult, out msg, out reason);
                if (error != GPErrorCode.NoError)
                {
                    GameSpyUtils.SendGPError(client, error, msg);
                    client.DisconnectByReason(reason);
                    return;
                }

                // we finally set the player variables and return challengeData
                string challengeData = SetPlayerInfo(client, queryResult, recv);
                string sendingBuffer;
                // Use the GenerateProof method to compare with the "response" value. This validates the given password
                if (recv["response"] == GenerateProof(recv["challenge"], client.ServerChallengeKey, challengeData, client.PlayerInfo.PlayerAuthToken.Length > 0 ? 0 : partnerID, client.PlayerInfo))
                {
                    // Create session key
                    client.SessionKey = Crc.ComputeChecksum(client.PlayerInfo.PlayerUniqueNick);

                    //actually we should store sesskey in database at namespace table, when we want someone's profile we just
                    //access to the sesskey to find the uniquenick for particular game
                    LoginQuery.UpdateSessionKey(recv, client.SessionKey, client.PlayerInfo);

                    // Password is correct
                    sendingBuffer = string.Format(@"\lc\2\sesskey\{0}\proof\{1}\userid\{2}\profileid\{2}\uniquenick\{3}\lt\{4}__\id\1\final\",
                                                  client.SessionKey,
                                                  GenerateProof(client.ServerChallengeKey, recv["challenge"], challengeData, client.PlayerInfo.PlayerAuthToken.Length > 0 ? 0 : partnerID, client.PlayerInfo), // Do this again, Params are reversed!
                                                  client.PlayerInfo.PlayerId,
                                                  client.PlayerInfo.PlayerUniqueNick,
                                                  // Generate LT whatever that is (some sort of random string, 22 chars long)
                                                  GameSpyLib.Common.Random.GenerateRandomString(22, GameSpyLib.Common.Random.StringType.Hex)
                                                  );
                    //Send response to client
                    client.Send(sendingBuffer);
                    // Log Incoming Connections
                    //LogWriter.Log.Write(LogLevel.Info, "{0,-8} [Login] {1} - {2} - {3}", client.ServerName, client.PlayerInfo.PlayerNick, client.PlayerInfo.PlayerId, RemoteEndPoint);
                    //string statusString = string.Format(" [Login Success!] Nick:{0} - Profileid:{1} - IP:{2}", client.PlayerInfo.PlayerNick, client.PlayerInfo.PlayerId, client.RemoteEndPoint);
                    client.StatusToLog("Login Success", client.PlayerInfo.PlayerNick, client.PlayerInfo.PlayerId, client.RemoteEndPoint, null);
                    // Update status last, and call success login
                    client.PlayerInfo.LoginStatus          = LoginStatus.Completed;
                    client.PlayerInfo.PlayerStatus         = PlayerStatus.Online;
                    client.PlayerInfo.PlayerStatusString   = "Online";
                    client.PlayerInfo.PlayerStatusLocation = "";
                    client.CompletedLoginProcess           = true;

                    OnSuccessfulLogin?.Invoke(client);
                    OnStatusChanged?.Invoke(client);
                    SendBuddiesHandler.HandleSendBuddies(client, recv);
                }
                else
                {
                    // Log Incoming Connection
                    string statusString = string.Format(@"[Login Failed!] Nick:{0} - Profileid:{1} - IP:{2}", client.PlayerInfo.PlayerNick, client.PlayerInfo.PlayerId, client.RemoteEndPoint);
                    client.ToLog(LogLevel.Info, statusString);
                    // Password is incorrect with database value.
                    client.Send(@"\error\\err\260\fatal\\errmsg\The password provided is incorrect.\id\1\final\");
                    client.DisconnectByReason(DisconnectReason.InvalidPassword);
                }
            }
            catch (Exception ex)
            {
                LogWriter.Log.Write(ex.ToString(), LogLevel.Error);
                client.DisconnectByReason(DisconnectReason.GeneralError);
                return;
            }
        }