/// <summary> /// Constructor /// </summary> /// <param name="ReadArgs">The Tcp Client connection</param> public GPCMClient(TCPStream stream, long connectionid) : base(stream, connectionid) { PlayerInfo = new GPCMPlayerInfo(); Stream.OnDataReceived += ProcessData; Stream.IsMessageFinished += IsMessageFinished; Stream.OnDisconnected += ClientDisconnected; Stream.BeginReceive(); }
/// <summary> /// update profile status /// </summary> /// <param name="profileid"></param> /// <param name="status"></param> /// <param name="statstring"></param> /// <param name="location"></param> /// <param name="lastIP"></param> public static void UpdateStatus(GPCMPlayerInfo playerInfo, uint status, string statstring, string location) { GPCMServer.DB.Execute("UPDATE profiles SET status = @P0, statstring=@P1, location=@P2 WHERE profileid=@P3", status, statstring, location, playerInfo.Profileid); }
/// <summary> /// update sessionkey in database, when we are going to get someone's profile /// we first find uniquenick by search profileid and namespaceid and productid and partnerid /// </summary> /// <param name="dict"></param> /// <param name="sesskey"></param> /// <param name="player"></param> public static void UpdateSessionKey(Dictionary <string, string> dict, ushort sesskey, GPCMPlayerInfo player) { Dictionary <string, object> temp = GPCMServer.DB.Query("SELECT id FROM namespace WHERE profileid = @P0 AND namespaceid = @P1 ", player.PlayerId, dict["namespaceid"])[0]; uint id = Convert.ToUInt32(temp["id"]); GPCMServer.DB.Execute("UPDATE namespace SET sesskey = @P0 WHERE id = @P1 ", sesskey, id); }
public GPCMSession(TemplateTcpServer server) : base(server) { DisconnectAfterSend = false; PlayerInfo = new GPCMPlayerInfo(); }
/// <summary> /// Generates an MD5 hash, which is used to verify the clients login information /// </summary> /// <param name="challenge1">First challenge key</param> /// <param name="challenge2">Second challenge key</param> /// <param name="userdata">The user data to append to the proof</param> /// <param name="partnerid">The partnerid to append</param> /// <returns> /// The proof verification MD5 hash string that can be compared to what the client sends, /// to verify that the users entered password matches the specific user data in the database. /// </returns> private static string GenerateProof(string challenge1, string challenge2, string userdata, uint partnerid, GPCMPlayerInfo playerinfo) { string realUserData = userdata; if (partnerid != (uint)PartnerID.Gamespy) { realUserData = string.Format("{0}@{1}", partnerid, userdata); } // Generate our string to be hashed StringBuilder HashString = new StringBuilder(playerinfo.PasswordHash); HashString.Append(' ', 48); // 48 spaces HashString.Append(realUserData); HashString.Append(challenge1); HashString.Append(challenge2); HashString.Append(playerinfo.PasswordHash); return(HashString.ToString().GetMD5Hash()); }
/// <summary> /// This method is called when the client requests for the Account profile /// </summary> public static void SendProfile(GPCMClient client, Dictionary <string, string> recv) { //TODO // \getprofile\\sesskey\19150\profileid\2\id\2\final\ //profileid is if (!recv.ContainsKey("profileid")) { GameSpyUtils.SendGPError(client, GPErrorCode.Parse, "There was an error parsing an incoming request."); return; } uint targetPID, messID, sesskey; if (!uint.TryParse(recv["profileid"], out targetPID)) { GameSpyUtils.SendGPError(client, GPErrorCode.Parse, "There was an error parsing an incoming request."); return; } if (!uint.TryParse(recv["id"], out messID)) { GameSpyUtils.SendGPError(client, GPErrorCode.Parse, "There was an error parsing an incoming request."); return; } if (!uint.TryParse(recv["sesskey"], out sesskey)) { GameSpyUtils.SendGPError(client, GPErrorCode.Parse, "There was an error parsing an incoming request."); return; } string datatoSend = @"\pi\profileid\" + targetPID + @"\mp\4"; // If the client want to access the public information // of another client if (targetPID != client.PlayerInfo.PlayerId) { GPCMPlayerInfo playerInfo = GetProfileQuery.GetProfileInfo(targetPID); if (playerInfo == null) { GameSpyUtils.SendGPError(client, 4, "Unable to get profile information."); return; } datatoSend = string.Format(datatoSend + @"\nick\{0}\uniquenick\{1}\id\{2}", playerInfo.PlayerNick, playerInfo.PlayerUniqueNick, messID); if (playerInfo.PlayerEmail.Length > 0) { datatoSend += @"\email\" + playerInfo.PlayerEmail; } if (playerInfo.PlayerLastName.Length > 0) { datatoSend += @"\lastname\" + playerInfo.PlayerLastName; } if (playerInfo.PlayerFirstName.Length > 0) { datatoSend += @"\firstname\" + playerInfo.PlayerFirstName; } if (playerInfo.PlayerICQ != 0) { datatoSend += @"\icquin\" + playerInfo.PlayerICQ; } if (playerInfo.PlayerHomepage.Length > 0) { datatoSend += @"\homepage\" + playerInfo.PlayerHomepage; } if (playerInfo.PlayerPicture != 0) { datatoSend += @"\pic\" + playerInfo.PlayerPicture; } if (playerInfo.PlayerAim.Length > 0) { datatoSend += @"\aim\" + playerInfo.PlayerAim; } if (playerInfo.PlayerOccupation != 0) { datatoSend += @"\occ\" + playerInfo.PlayerOccupation; } if (playerInfo.PlayerZIPCode.Length > 0) { datatoSend += @"\zipcode\" + playerInfo.PlayerZIPCode; } if (playerInfo.PlayerCountryCode.Length > 0) { datatoSend += @"\countrycode\" + playerInfo.PlayerCountryCode; } if (playerInfo.PlayerBirthday > 0 && playerInfo.PlayerBirthmonth > 0 && playerInfo.PlayerBirthyear > 0) { datatoSend += @"\birthday\" + (uint)((playerInfo.PlayerBirthday << 24) | (playerInfo.PlayerBirthmonth << 16) | playerInfo.PlayerBirthyear); } if (playerInfo.PlayerLocation.Length > 0) { datatoSend += @"\loc\" + playerInfo.PlayerLocation; } if (playerInfo.PlayerSex != PlayerSexType.PAT) { if (playerInfo.PlayerSex == PlayerSexType.FEMALE) { datatoSend += @"\sex\1"; } else if (playerInfo.PlayerSex == PlayerSexType.MALE) { datatoSend += @"\sex\0"; } } if (playerInfo.PlayerLatitude != 0.0f) { datatoSend += @"\lat\" + playerInfo.PlayerLatitude; } if (playerInfo.PlayerLongitude != 0.0f) { datatoSend += @"\lon\" + playerInfo.PlayerLongitude; } if (playerInfo.PlayerIncomeID != 0) { datatoSend += @"\inc\" + playerInfo.PlayerIncomeID; } if (playerInfo.PlayerIndustryID != 0) { datatoSend += @"\ind\" + playerInfo.PlayerIndustryID; } if (playerInfo.PlayerMarried != 0) { datatoSend += @"\mar\" + playerInfo.PlayerMarried; } if (playerInfo.PlayerChildCount != 0) { datatoSend += @"\chc\" + playerInfo.PlayerChildCount; } if (playerInfo.PlayerInterests != 0) { datatoSend += @"\i1\" + playerInfo.PlayerInterests; } if (playerInfo.PlayerOwnership != 0) { datatoSend += @"\o1\" + playerInfo.PlayerOwnership; } if (playerInfo.PlayerConnectionType != 0) { datatoSend += @"\conn\" + playerInfo.PlayerConnectionType; } // SUPER NOTE: Please check the Signature of the PID, otherwise when it will be compared with other peers, it will break everything (See gpiPeer.c @ peerSig) datatoSend += @"\sig\" + GameSpyLib.Common.Random.GenerateRandomString(33, GameSpyLib.Common.Random.StringType.Hex) + @"\final\"; } else { // Since this is our profile, we have to see ALL informations that we can edit. This means that we don't need to check the public masks for sending // the data datatoSend = string.Format(datatoSend + @"\nick\{0}\uniquenick\{1}\email\{2}\id\{3}\pmask\{4}", client.PlayerInfo.PlayerNick, client.PlayerInfo.PlayerUniqueNick, client.PlayerInfo.PlayerEmail, /*(ProfileSent ? "5" : "2")*/ messID, client.PlayerInfo.PlayerPublicMask ); if (client.PlayerInfo.PlayerLastName.Length > 0) { datatoSend += @"\lastname\" + client.PlayerInfo.PlayerLastName; } if (client.PlayerInfo.PlayerFirstName.Length > 0) { datatoSend += @"\firstname\" + client.PlayerInfo.PlayerFirstName; } if (client.PlayerInfo.PlayerICQ != 0) { datatoSend += @"\icquin\" + client.PlayerInfo.PlayerICQ; } if (client.PlayerInfo.PlayerHomepage.Length > 0) { datatoSend += @"\homepage\" + client.PlayerInfo.PlayerHomepage; } if (client.PlayerInfo.PlayerPicture != 0) { datatoSend += @"\pic\" + client.PlayerInfo.PlayerPicture; } if (client.PlayerInfo.PlayerAim.Length > 0) { datatoSend += @"\aim\" + client.PlayerInfo.PlayerAim; } if (client.PlayerInfo.PlayerOccupation != 0) { datatoSend += @"\occ\" + client.PlayerInfo.PlayerOccupation; } if (client.PlayerInfo.PlayerZIPCode.Length > 0) { datatoSend += @"\zipcode\" + client.PlayerInfo.PlayerZIPCode; } if (client.PlayerInfo.PlayerCountryCode.Length > 0) { datatoSend += @"\countrycode\" + client.PlayerInfo.PlayerCountryCode; } if (client.PlayerInfo.PlayerBirthday > 0 && client.PlayerInfo.PlayerBirthmonth > 0 && client.PlayerInfo.PlayerBirthyear > 0) { datatoSend += @"\birthday\" + (uint)((client.PlayerInfo.PlayerBirthday << 24) | (client.PlayerInfo.PlayerBirthmonth << 16) | client.PlayerInfo.PlayerBirthyear); } if (client.PlayerInfo.PlayerLocation.Length > 0) { datatoSend += @"\loc\" + client.PlayerInfo.PlayerLocation; } if (client.PlayerInfo.PlayerSex == PlayerSexType.FEMALE) { datatoSend += @"\sex\1"; } else if (client.PlayerInfo.PlayerSex == PlayerSexType.MALE) { datatoSend += @"\sex\0"; } if (client.PlayerInfo.PlayerLatitude != 0.0f) { datatoSend += @"\lat\" + client.PlayerInfo.PlayerLatitude; } if (client.PlayerInfo.PlayerLongitude != 0.0f) { datatoSend += @"\lon\" + client.PlayerInfo.PlayerLongitude; } if (client.PlayerInfo.PlayerIncomeID != 0) { datatoSend += @"\inc\" + client.PlayerInfo.PlayerIncomeID; } if (client.PlayerInfo.PlayerIndustryID != 0) { datatoSend += @"\ind\" + client.PlayerInfo.PlayerIndustryID; } if (client.PlayerInfo.PlayerMarried != 0) { datatoSend += @"\mar\" + client.PlayerInfo.PlayerMarried; } if (client.PlayerInfo.PlayerChildCount != 0) { datatoSend += @"\chc\" + client.PlayerInfo.PlayerChildCount; } if (client.PlayerInfo.PlayerInterests != 0) { datatoSend += @"\i1\" + client.PlayerInfo.PlayerInterests; } if (client.PlayerInfo.PlayerOwnership != 0) { datatoSend += @"\o1\" + client.PlayerInfo.PlayerOwnership; } if (client.PlayerInfo.PlayerConnectionType != 0) { datatoSend += @"\conn\" + client.PlayerInfo.PlayerConnectionType; } // SUPER NOTE: Please check the Signature of the PID, otherwise when it will be compared with other peers, it will break everything (See gpiPeer.c @ peerSig) datatoSend += @"\sig\" + GameSpyLib.Common.Random.GenerateRandomString(33, GameSpyLib.Common.Random.StringType.Hex) + @"\final\"; // Set that we send the profile initially if (!client.ProfileSent) { client.ProfileSent = true; } } client.Send(datatoSend); }
/// <summary> /// The user profile you searched must be accurate, /// because it contains uniquenick, /// we know that there may be multiple uniquenicks with different namespaceid productid partnerid under a nick, /// so we determine the unique namespaceid productid partnerid based on the incoming sesskey to determine uniquenick /// </summary> /// <param name="profileid"></param> /// <returns></returns> public static GPCMPlayerInfo GetProfileInfo(uint profileid) { //var Rows = Query("SELECT profiles.firstname, profiles.lastname, profiles.publicmask, profiles.latitude, profiles.longitude, " + // "profiles.aim, profiles.picture, profiles.occupationid, profiles.incomeid, profiles.industryid, profiles.marriedid, profiles.childcount, profiles.interests1, " + // @"profiles.ownership1, profiles.connectiontype, profiles.sex, profiles.zipcode, profiles.countrycode, profiles.homepage, profiles.birthday, profiles.birthmonth, " + // @"profiles.birthyear, profiles.location, profiles.icq, profiles.status, profiles.nick, namespace.uniquenick, users.email FROM profiles " + // @"INNER JOIN users ON users.userid = profiles.userid INNER JOIN namespace ON namespace.profileid = profiles.profileid WHERE profiles.profileid=@P0", profileid); var Rows = GPCMServer.DB.Query("SELECT * FROM profiles " + @"INNER JOIN users ON users.userid = profiles.userid " + @"INNER JOIN namespace ON namespace.profileid = profiles.profileid WHERE profiles.profileid=@P0", profileid); if (Rows.Count == 0) { return(null); } var data = Rows[0]; GPCMPlayerInfo playerInfo = new GPCMPlayerInfo(); uint uintTemp; int intTemp; float floatTemp; if (!uint.TryParse(data["publicmask"].ToString(), out uintTemp)) { playerInfo.PlayerPublicMask = PublicMasks.MASK_NONE; } else { playerInfo.PlayerPublicMask = (PublicMasks)uintTemp; } playerInfo.PlayerNick = data["nick"].ToString(); playerInfo.PlayerUniqueNick = data["uniquenick"].ToString(); if (playerInfo.PlayerPublicMask != PublicMasks.MASK_NONE) { if (data["email"].ToString().Length > 0) { if ((playerInfo.PlayerPublicMask & PublicMasks.MASK_EMAIL) > 0) { playerInfo.PlayerEmail = data["email"].ToString(); } } if (data["lastname"].ToString().Length > 0) { playerInfo.PlayerLastName = data["lastname"].ToString(); } if (data["firstname"].ToString().Length > 0) { playerInfo.PlayerFirstName = data["firstname"].ToString(); } if (int.TryParse(data["icq"].ToString(), out intTemp)) { playerInfo.PlayerICQ = intTemp; } if ((playerInfo.PlayerPublicMask & PublicMasks.MASK_HOMEPAGE) > 0) { playerInfo.PlayerEmail = data["email"].ToString(); } if (int.TryParse(data["picture"].ToString(), out intTemp)) { playerInfo.PlayerPicture = intTemp; } if (data["aim"].ToString().Length > 0) { playerInfo.PlayerAim = data["aim"].ToString(); } if (int.TryParse(data["occupationid"].ToString(), out intTemp)) { playerInfo.PlayerOccupation = intTemp; } if (data["zipcode"].ToString().Length > 0) { if ((playerInfo.PlayerPublicMask & PublicMasks.MASK_ZIPCODE) > 0) { playerInfo.PlayerZIPCode = data["zipcode"].ToString(); } } if (data["countrycode"].ToString().Length > 0) { if ((playerInfo.PlayerPublicMask & PublicMasks.MASK_COUNTRYCODE) > 0) { playerInfo.PlayerCountryCode = data["countrycode"].ToString(); } } ushort bday, byear, bmonth; if (ushort.TryParse(data["birthday"].ToString(), out bday) && ushort.TryParse(data["birthmonth"].ToString(), out bmonth) && ushort.TryParse(data["birthyear"].ToString(), out byear)) { if ((playerInfo.PlayerPublicMask & PublicMasks.MASK_BIRTHDAY) > 0) { playerInfo.PlayerBirthday = bday; playerInfo.PlayerBirthmonth = bmonth; playerInfo.PlayerBirthyear = byear; } } if (data["location"].ToString().Length > 0) { playerInfo.PlayerLocation = data["location"].ToString(); } if ((playerInfo.PlayerPublicMask & PublicMasks.MASK_SEX) > 0) { if (!Enum.TryParse(data["sex"].ToString(), out playerInfo.PlayerSex)) { playerInfo.PlayerSex = PlayerSexType.PAT; } } if (float.TryParse(data["latitude"].ToString(), out floatTemp)) { playerInfo.PlayerLatitude = floatTemp; } if (float.TryParse(data["longitude"].ToString(), out floatTemp)) { playerInfo.PlayerLongitude = floatTemp; } if (int.TryParse(data["incomeid"].ToString(), out intTemp)) { playerInfo.PlayerIncomeID = intTemp; } if (int.TryParse(data["industryid"].ToString(), out intTemp)) { playerInfo.PlayerIndustryID = intTemp; } if (int.TryParse(data["marriedid"].ToString(), out intTemp)) { playerInfo.PlayerMarried = intTemp; } if (int.TryParse(data["childcount"].ToString(), out intTemp)) { playerInfo.PlayerChildCount = intTemp; } if (int.TryParse(data["interests1"].ToString(), out intTemp)) { playerInfo.PlayerInterests = intTemp; } if (int.TryParse(data["ownership1"].ToString(), out intTemp)) { playerInfo.PlayerOwnership = intTemp; } if (int.TryParse(data["connectiontype"].ToString(), out intTemp)) { playerInfo.PlayerConnectionType = intTemp; } } return(playerInfo); }