public void ProcessLogin(Dictionary<string, string> Recv)
{
// Make sure we have all the required data to process this login
if (!Recv.ContainsKey("uniquenick") || !Recv.ContainsKey("challenge") || !Recv.ContainsKey("response"))
{
Stream.SendAsync(@"\error\\err\0\fatal\\errmsg\Invalid Query!\id\1\final\");
Disconnect(2);
return;
}
// Warp this in a try/catch, incase database is offline or something
try
{
using (GamespyDatabase Conn = new GamespyDatabase())
{
// Try and fetch the user from the database
Dictionary<string, object> User = Conn.GetUser(Recv["uniquenick"]);
if (User == null)
{
Stream.SendAsync(@"\error\\err\265\fatal\\errmsg\The uniquenick provided is incorrect!\id\1\final\");
Disconnect(2);
return;
}
// Set player variables
PlayerId = Int32.Parse(User["id"].ToString());
PlayerNick = Recv["uniquenick"];
PlayerEmail = User["email"].ToString();
PlayerCountryCode = User["country"].ToString();
PasswordHash = User["password"].ToString();
// Use the GenerateProof method to compare with the "response" value. This validates the given password
if (Recv["response"] == GenerateProof(Recv["challenge"], ServerChallengeKey))
{
// Password is correct, Create session key and respond
SessionKey = Crc.ComputeChecksum(PlayerNick);
Stream.SendAsync(
@"\lc\2\sesskey\{0}\proof\{1}\userid\{2}\profileid\{2}\uniquenick\{3}\lt\{4}__\id\1\final\",
SessionKey,
GenerateProof(ServerChallengeKey, Recv["challenge"]), // Do this again, Params are reversed!
PlayerId,
PlayerNick,
GenerateRandomString(22) // Generate LT whatever that is (some sort of random string, 22 chars long)
);
// Log, Update database, and call event
GpcmServer.Log("Client Login: {0} - {1} - {2}", PlayerNick, PlayerId, RemoteEndPoint);
Conn.Execute("UPDATE accounts SET lastip=@P0, session=@P1 WHERE id=@P2", RemoteEndPoint.Address, SessionKey, PlayerId);
// Update status last, and call success login
Status = LoginStatus.Completed;
if (OnSuccessfulLogin != null)
OnSuccessfulLogin(this);
}
else
{
// The proof string failed, so the password provided was incorrect
GpcmServer.Log("Failed Login Attempt: {0} - {1} - {2}", PlayerNick, PlayerId, RemoteEndPoint);
Stream.SendAsync(@"\error\\err\260\fatal\\errmsg\The password provided is incorrect.\id\1\final\");
Disconnect(3);
}
}
}
catch
{
Disconnect(4);
return;
}
}