public async Task <Tuple <VerifyResult, string> > MergeLogin(PlayerProfile profile, string username, string password) { try { var pwHash = bridge.DoSHA256(password); var ps = new RestParameterSet(); ps.AddParameterInt("old_userid", profile.OnlineUserID); ps.AddParameterHash("old_password", profile.OnlinePasswordHash); ps.AddParameterString("app_version", GDConstants.Version.ToString()); ps.AddParameterString("new_username", username); ps.AddParameterHash("new_password", pwHash); ps.AddParameterJson("merge_data", CreateScoreArray(profile)); ps.AddParameterInt("s0", profile.TotalPoints); ps.AddParameterInt("s1", profile.GetWorldPoints(Levels.WORLD_001)); ps.AddParameterInt("s2", profile.GetWorldPoints(Levels.WORLD_002)); ps.AddParameterInt("s3", profile.GetWorldPoints(Levels.WORLD_003)); ps.AddParameterInt("s4", profile.GetWorldPoints(Levels.WORLD_004)); ps.AddParameterInt("t0", profile.TotalTime); ps.AddParameterInt("t1", profile.GetWorldTime(Levels.WORLD_001)); ps.AddParameterInt("t2", profile.GetWorldTime(Levels.WORLD_002)); ps.AddParameterInt("t3", profile.GetWorldTime(Levels.WORLD_003)); ps.AddParameterInt("t4", profile.GetWorldTime(Levels.WORLD_004)); ps.AddParameterInt("sx", profile.MultiplayerPoints); var response = await QueryAsync <QueryResultMergeLogin>("merge-login", ps, RETRY_CREATEUSER); if (response == null) { return(Tuple.Create(VerifyResult.InternalError, "Internal server error")); } else if (response.result == "success") { MonoSAMGame.CurrentInst.DispatchBeginInvoke(() => { profile.AccountType = AccountType.Full; profile.OnlineUsername = response.user.Username; profile.OnlineUserID = response.user.ID; profile.OnlineRevisionID = response.user.RevID; profile.OnlinePasswordHash = pwHash; profile.AccountReminderShown = true; foreach (var scdata in response.scores) { profile.SetCompleted(Guid.Parse(scdata.levelid), (FractionDifficulty)scdata.difficulty, scdata.best_time, false); } MainGame.Inst.SaveProfile(); SetScoreAndTime(profile).EnsureNoError(); //score could have been changed - reupload }); return(Tuple.Create(VerifyResult.Success, string.Empty)); } else if (response.result == "error") { if (response.errorid == BackendCodes.INTERNAL_EXCEPTION) { return(Tuple.Create(VerifyResult.InternalError, response.errormessage)); } else if (response.errorid == BackendCodes.WRONG_PASSWORD) { return(Tuple.Create(VerifyResult.WrongPassword, string.Empty)); } else if (response.errorid == BackendCodes.USER_BY_NAME_NOT_FOUND) { return(Tuple.Create(VerifyResult.WrongUsername, string.Empty)); } else { ShowErrorCommunication(); SAMLog.Error("Backend::ML_ERR", $"Verify: Error {response.errorid}: {response.errormessage}"); return(Tuple.Create(VerifyResult.InternalError, response.errormessage)); } } else { return(Tuple.Create(VerifyResult.InternalError, "Internal server exception")); } } catch (RestConnectionException e) { SAMLog.Warning("Backend::ML_RCE", e); // probably no internet ShowErrorConnection(); return(Tuple.Create(VerifyResult.NoConnection, string.Empty)); } catch (Exception e) { SAMLog.Error("Backend::ML_E", e); ShowErrorCommunication(); return(Tuple.Create(VerifyResult.InternalError, "Internal server exception")); } }
public async Task Reupload(PlayerProfile profile) { profile.NeedsReupload = false; try { var ps = new RestParameterSet(); ps.AddParameterInt("userid", profile.OnlineUserID); ps.AddParameterHash("password", profile.OnlinePasswordHash); ps.AddParameterString("app_version", GDConstants.Version.ToString()); ps.AddParameterJson("data", CreateScoreArray(profile)); ps.AddParameterInt("s0", profile.TotalPoints); ps.AddParameterInt("s1", profile.GetWorldPoints(Levels.WORLD_001)); ps.AddParameterInt("s2", profile.GetWorldPoints(Levels.WORLD_002)); ps.AddParameterInt("s3", profile.GetWorldPoints(Levels.WORLD_003)); ps.AddParameterInt("s4", profile.GetWorldPoints(Levels.WORLD_004)); ps.AddParameterInt("t0", profile.TotalTime); ps.AddParameterInt("t1", profile.GetWorldTime(Levels.WORLD_001)); ps.AddParameterInt("t2", profile.GetWorldTime(Levels.WORLD_002)); ps.AddParameterInt("t3", profile.GetWorldTime(Levels.WORLD_003)); ps.AddParameterInt("t4", profile.GetWorldTime(Levels.WORLD_004)); ps.AddParameterInt("sx", profile.MultiplayerPoints); var response = await QueryAsync <QueryResultSetMultiscore>("set-multiscore", ps, RETRY_DOWNLOADDATA); if (response == null) { return; // meh - internal server error } else if (response.result == "success") { if (response.update) { MonoSAMGame.CurrentInst.DispatchBeginInvoke(() => { profile.OnlineRevisionID = response.user.RevID; MainGame.Inst.SaveProfile(); if (profile.NeedsReupload) { Reupload(profile).EnsureNoError(); } }); } } else if (response.result == "error") { ShowErrorCommunication(); if (response.errorid == BackendCodes.INTERNAL_EXCEPTION) { return; // meh } else if (response.errorid == BackendCodes.WRONG_PASSWORD || response.errorid == BackendCodes.USER_BY_ID_NOT_FOUND) { MonoSAMGame.CurrentInst.DispatchBeginInvoke(() => { SAMLog.Error("Backend::RU_INVLOGIN", $"Local user cannot login on server ({response.errorid}:{response.errormessage}). Reset local user"); // something went horribly wrong // create new user on next run profile.OnlineUserID = -1; MainGame.Inst.SaveProfile(); }); } else { SAMLog.Error("Backend::RU_ERR", $"SetScore: Error {response.errorid}: {response.errormessage}"); } } } catch (RestConnectionException e) { SAMLog.Warning("Backend::RU_RCE", e); // probably no internet ShowErrorConnection(); MonoSAMGame.CurrentInst.DispatchBeginInvoke(() => { profile.NeedsReupload = true; MainGame.Inst.SaveProfile(); }); } catch (Exception e) { SAMLog.Error("Backend::RU_E", e); ShowErrorCommunication(); MonoSAMGame.CurrentInst.DispatchBeginInvoke(() => { profile.NeedsReupload = true; MainGame.Inst.SaveProfile(); }); } }