예제 #1
0
        /// <summary>
        /// "GETPROFILE" packet. Submitted by the client to get the content of a profile (i.e. associated with a friend code) by profileid.
        /// </summary>
        private void OnReceive_GetProfile(NetState ns, GsTcpReader reader)
        {
            int sessionKey = int.Parse(reader.GetParameter("sesskey"));
            int seqNum     = int.Parse(reader.GetParameter("id")); // sequence ID of this record.

            if (ns.GsSessionID != sessionKey)
            {
                Send(ns, GsSmsgError.ErrFatalSessionKeyInvalid(seqNum));
                throw new NetStateMsgException(ns, "sent incorrect sesskey parameter.", reader);
            }
            int profileID = int.Parse(reader.GetParameter("profileid"));
            AccountRequestProfile info = new AccountRequestProfile(profileID);

            EventSink.InvokeAccountProfile(info);
            if (info.IsHandled && info.IsSuccess)
            {
                Kernel.WriteLine(TypeName, $"{ns} requested profile for '{info.Account}'.");
                Send(ns, new GsSmsgProfileInfo(info.Account, seqNum));
            }
            else if (info.IsHandled)
            {
                Send(ns, GsSmsgError.ErrProfileRequestInvalid(seqNum));
            }
            else
            {
                Send(ns, GsSmsgError.ErrFatalDatabaseError(seqNum));
                throw new NetStateMsgException(ns, "sent GetProfile; EventSink did not handle the message.", reader);
            }
        }
예제 #2
0
        private void OnReceive_Logout(NetState ns, GsTcpReader reader)
        {
            int sessionKey = int.Parse(reader.GetParameter("sesskey")); // no need to validate this, just log out.

            Kernel.WriteLine(TypeName, $"{ns} sent logout.");
            ns.Dispose();
        }
예제 #3
0
        /// <summary>
        /// "login" packet. This is the response to the server's login challenge.
        /// </summary>
        private void OnReceive_Login(NetState ns, GsTcpReader reader)
        {
            string clientChallenge = reader.GetParameter("challenge"); // 32 chars ASCII upper/lower. Verifies server.
            string sessionToken    = reader.GetParameter("authtoken"); // identifies account DS wishes to log in with.
            string response        = reader.GetParameter("response");  // 128bit (as 32char hex) response LOGIN_CHALLENGE.
            string firewall        = reader.GetParameter("firewall");  // whether the client is behind a firewall.
            string port            = reader.GetParameter("port");      // port open on the device for communications.
            string product         = reader.GetParameter("productid"); // GameSpy-specific ID indicating the product attempting to connect to GameSpy.
            string gamename        = reader.GetParameter("gamename");  // GameSpy-specific name of the game
            // string nmspace = reader.GetParameter("nmspace"); // indicates presence of additional login parameters in this packet
            int seqNum = int.Parse(reader.GetParameter("id"));         // sequence ID of the previous LOGIN_CHALLENGE.
            // get account
            AccountRequestLogin info = new AccountRequestLogin(sessionToken);

            EventSink.InvokeAccountLogin(info);
            if (info.IsHandled && info.IsSuccess)
            {
                // verify client authentication:
                string verify = GsMd5Sum.HashChallenge(info.Account.GsLoginPassword, info.Account.GsLoginToken, clientChallenge, ns.GsServerChallenge);
                if (verify != response)
                {
                    throw new NetStateMsgException(ns, "sent incorrect LOGIN verification.", reader);
                }
                // client authenticated! Create server authentication proof and then login client:
                string proof = GsMd5Sum.HashChallenge(info.Account.GsLoginPassword, info.Account.GsLoginToken, ns.GsServerChallenge, clientChallenge);
                ns.Account = info.Account;
                ns.GenerateGamespySessionData();
                ns.Account.GenerateGamespyLoginData(info);
                Kernel.WriteLine(TypeName, $"{ns} logged in as '{ns.Account}'.");
                Send(ns, new GsSmsgLoggedIn(proof, ns, seqNum));
            }
            else if (info.IsHandled)
            {
                Send(ns, GsSmsgError.ErrFatalLoginFailed(seqNum));
                throw new NetStateMsgException(ns, $"sent wrong credentials: {info.FailReason}", reader);
            }
            else
            {
                Send(ns, GsSmsgError.ErrFatalDatabaseError(seqNum));
                throw new NetStateMsgException(ns, "sent Login; EventSink did not handle the message.", reader);
            }
        }
예제 #4
0
        /// <summary>
        /// "updatepro" packet. Appended to a GETPROFILE record (after its \final\ record terminator) to modify a
        /// profile. Note that, as it is does not have a corresponding response record (or perhaps because it is
        /// appended to a GETPROFILE record), there is no id key in this record.
        /// </summary>
        private void OnReceive_UpdateProfile(NetState ns, GsTcpReader reader)
        {
            int sessionKey = int.Parse(reader.GetParameter("sesskey"));

            if (ns.GsSessionID != sessionKey)
            {
                Send(ns, GsSmsgError.ErrFatalSessionKeyInvalid(0));
                throw new NetStateMsgException(ns, "sent incorrect sesskey parameter.", reader);
            }
            if (reader.HasParameter("firstname", out string firstName))
            {
                ns.Account.FirstName = firstName;
            }
            if (reader.HasParameter("lastname", out string lastName))
            {
                ns.Account.LastName = lastName;
            }
            Kernel.WriteLine(TypeName, $"{ns} updated profile.");
        }