/// <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); } }
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(); }
/// <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); } }
/// <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."); }