Ejemplo n.º 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);
            }
        }
Ejemplo n.º 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();
        }
Ejemplo n.º 3
0
 /// <summary>
 /// STATUS packet. The purpose of STATUS records is unknown. It is hypothesized that status values are:
 /// 1 = transient state, such as "logging in" or "ending trade";
 /// 2 = game has joined another game;
 /// 5 = game is attempting to join another game;
 /// 6 = standby announcement state;
 /// </summary>
 private void OnReceive_Status(NetState ns, GsTcpReader reader)
 {
     ns.GsStatus = int.Parse(reader.RecordValue);
     Kernel.WriteLine(TypeName, $"{ns} GsStatus=='{ns.GsStatus}'.");
     if (reader.HasParameter("statstring", out string statusString))
     {
         ns.GsStatusString = statusString;
     }
     if (reader.HasParameter("locstring", out string locationString))
     {
         ns.GsStatusLocation = locationString;
     }
 }
Ejemplo n.º 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.");
        }
Ejemplo n.º 5
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);
            }
        }
Ejemplo n.º 6
0
        private void ReceiveWfc29900(NetState ns, byte[] buffer, int length)
        {
            try {
                int offset = 0;
                while (offset < length && !ns.IsDisposing)
                {
                    GsTcpReader reader = new GsTcpReader(buffer, offset, length);
                    switch (reader.RecordType)
                    {
                    case "login":
                        OnReceive_Login(ns, reader);
                        break;

                    case "logout":
                        OnReceive_Logout(ns, reader);
                        break;

                    case "getprofile":
                        OnReceive_GetProfile(ns, reader);
                        break;

                    case "updatepro":
                        OnReceive_UpdateProfile(ns, reader);
                        break;

                    case "status":
                        OnReceive_Status(ns, reader);
                        break;

                    default:
                        Kernel.WriteLine(TypeName, $"{ns} sent unhandled Wfc29900 message.");
                        Console.WriteLine(BufferFormat.AsString(buffer, length));
                        break;
                    }
                    offset = reader.Position;
                }
            }
            catch (Exception e) {
                Console.Write($"{TypeName}: {e.Message}");
                ns.DisposeAfterNextFlush();
            }
        }