コード例 #1
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        public async Task CreateUser(PlayerProfile profile)
        {
            try
            {
                var pw = bridge.DoSHA256(Guid.NewGuid().ToString("N"));

                var ps = new RestParameterSet();
                ps.AddParameterHash("password", pw);
                ps.AddParameterString("app_version", GDConstants.Version.ToString());
                ps.AddParameterString("device_name", bridge.DeviceName);
                ps.AddParameterString("device_version", bridge.DeviceVersion);
                ps.AddParameterString("unlocked_worlds", profile.StrPurchasedWorlds);
                ps.AddParameterString("device_resolution", bridge.DeviceResolution.FormatAsResolution());

                var response = await QueryAsync <QueryResultCreateUser>("create-user", ps, RETRY_CREATEUSER);

                if (response == null)
                {
                    SAMLog.Error("Backend::CU_Null", "CreateUser returned NULL");
                    ShowErrorCommunication();
                }
                else if (response.result == "success")
                {
                    MonoSAMGame.CurrentInst.DispatchBeginInvoke(() =>
                    {
                        profile.AccountType        = AccountType.Anonymous;
                        profile.OnlineUserID       = response.user.ID;
                        profile.OnlineRevisionID   = response.user.RevID;
                        profile.OnlinePasswordHash = pw;

                        MainGame.Inst.SaveProfile();

                        Reupload(profile).EnsureNoError();
                    });
                }
                else if (response.result == "error")
                {
                    SAMLog.Error("Backend::CU_Err", $"CreateUser: Error {response.errorid}: {response.errormessage}");
                    ShowErrorCommunication();
                }
            }
            catch (RestConnectionException e)
            {
                SAMLog.Warning("Backend::CU_RCE", e);                 // probably no internet
                ShowErrorConnection();
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::CU_E", e);
                ShowErrorCommunication();
            }
        }
コード例 #2
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        public async Task <QueryResultRanking> GetRanking(PlayerProfile profile, GraphBlueprint limit, bool multiplayer)
        {
            try
            {
                var ps = new RestParameterSet();
                ps.AddParameterInt("userid", profile.OnlineUserID);

                if (multiplayer)
                {
                    ps.AddParameterString("world_id", "@");
                }
                else if (limit == null)
                {
                    ps.AddParameterString("world_id", "*");
                }
                else
                {
                    ps.AddParameterString("world_id", limit.ID.ToString("B"));
                }

                var response = await QueryAsync <QueryResultRanking>("get-ranking", ps, RETRY_GETRANKING);

                if (response == null)
                {
                    ShowErrorCommunication();
                    return(null);
                }
                else if (response.result == "success")
                {
                    return(response);
                }
                else
                {
                    ShowErrorCommunication();
                    return(null);
                }
            }
            catch (RestConnectionException e)
            {
                SAMLog.Warning("Backend::GR_RCE", e);                 // probably no internet
                ShowErrorConnection();
                return(null);
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::GR_E", e);
                ShowErrorCommunication();
                return(null);
            }
        }
コード例 #3
0
ファイル: SGServerAPI.cs プロジェクト: Mikescher/SwitchGame
        public async Task LogClient(UserSettings profile, SAMLogEntry entry)
        {
            try
            {
                var ps = new RestParameterSet();
                //ps.AddParameterInt("userid", profile.OnlineUserID, false);
                //ps.AddParameterHash("password", profile.OnlinePasswordHash, false);
                ps.AddParameterString("app_version", SGConstants.Version.ToString(), false);
                ps.AddParameterString("screen_resolution", bridge.DeviceResolution.FormatAsResolution(), false);
                ps.AddParameterString("exception_id", entry.Type, false);
                ps.AddParameterCompressed("exception_message", entry.MessageShort, false);
                ps.AddParameterCompressed("exception_stacktrace", entry.MessageLong, false);
                ps.AddParameterCompressed("additional_info", bridge.FullDeviceInfoString, false);

                var response = await QueryAsync <QueryResultLogClient>("log-client", ps, RETRY_LOGERROR);

                if (response == null)
                {
                    SAMLog.Warning("Log_Upload_LC_NULL", "response == null");
                }
                else if (response.result == "error")
                {
                    SAMLog.Warning("Log_Upload_LC_ERR", response.errormessage);
                }
            }
            catch (RestConnectionException e)
            {
                // well, that sucks
                // probably no internet
                SAMLog.Warning("Backend::LC_RCE", e);                 // probably no internet
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::LC_E", e);
            }
        }
コード例 #4
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        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"));
            }
        }
コード例 #5
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        public async Task <Tuple <ChangePasswordResult, string> > ChangePassword(PlayerProfile profile, string newPassword)
        {
            try
            {
                var pwHashOld = profile.OnlinePasswordHash;
                var pwHashNew = bridge.DoSHA256(newPassword);

                var ps = new RestParameterSet();
                ps.AddParameterInt("userid", profile.OnlineUserID);
                ps.AddParameterHash("password_old", pwHashOld);
                ps.AddParameterString("app_version", GDConstants.Version.ToString());
                ps.AddParameterHash("password_new", pwHashNew);

                var response = await QueryAsync <QueryResultChangePassword>("change-password", ps, RETRY_CHANGE_PW);

                if (response == null)
                {
                    ShowErrorCommunication();
                    return(Tuple.Create(ChangePasswordResult.InternalError, "Internal server error"));
                }
                else if (response.result == "success")
                {
                    MonoSAMGame.CurrentInst.DispatchBeginInvoke(() =>
                    {
                        profile.AccountType        = AccountType.Full;
                        profile.OnlinePasswordHash = pwHashNew;
                        profile.OnlineRevisionID   = response.user.RevID;

                        MainGame.Inst.SaveProfile();
                    });

                    return(Tuple.Create(ChangePasswordResult.Success, string.Empty));
                }
                else if (response.result == "error")
                {
                    if (response.errorid == BackendCodes.INTERNAL_EXCEPTION)
                    {
                        ShowErrorCommunication();
                        return(Tuple.Create(ChangePasswordResult.InternalError, response.errormessage));
                    }

                    if (response.errorid == BackendCodes.WRONG_PASSWORD)
                    {
                        return(Tuple.Create(ChangePasswordResult.AuthError, string.Empty));
                    }

                    SAMLog.Error("Backend::CP_ERR", $"ChangePassword: Error {response.errorid}: {response.errormessage}");
                    ShowErrorCommunication();
                    return(Tuple.Create(ChangePasswordResult.InternalError, response.errormessage));
                }
                else
                {
                    return(Tuple.Create(ChangePasswordResult.InternalError, "Inetrnal server error"));
                }
            }
            catch (RestConnectionException e)
            {
                SAMLog.Warning("Backend::CP_RCE", e);                 // probably no internet
                ShowErrorConnection();
                return(Tuple.Create(ChangePasswordResult.NoConnection, string.Empty));
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::CP_E", e);
                ShowErrorCommunication();
                return(Tuple.Create(ChangePasswordResult.InternalError, "Internal server error"));
            }
        }
コード例 #6
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        public async Task <Tuple <UpgradeResult, string> > UpgradeUser(PlayerProfile profile, string username, string password)
        {
            try
            {
                var pwHashOld = profile.OnlinePasswordHash;
                var pwHashNew = bridge.DoSHA256(password);

                var ps = new RestParameterSet();
                ps.AddParameterInt("userid", profile.OnlineUserID);
                ps.AddParameterHash("password_old", pwHashOld);
                ps.AddParameterString("app_version", GDConstants.Version.ToString());
                ps.AddParameterHash("password_new", pwHashNew);
                ps.AddParameterString("username_new", username);

                var response = await QueryAsync <QueryResultUpgradeUser>("upgrade-user", ps, RETRY_VERIFY);

                if (response == null)
                {
                    ShowErrorCommunication();
                    return(Tuple.Create(UpgradeResult.InternalError, "Internal server error"));
                }
                else if (response.result == "success")
                {
                    MonoSAMGame.CurrentInst.DispatchBeginInvoke(() =>
                    {
                        profile.AccountType          = AccountType.Full;
                        profile.OnlineUsername       = response.user.Username;
                        profile.OnlinePasswordHash   = pwHashNew;
                        profile.OnlineRevisionID     = response.user.RevID;
                        profile.AccountReminderShown = true;

                        MainGame.Inst.SaveProfile();
                    });


                    return(Tuple.Create(UpgradeResult.Success, string.Empty));
                }
                else if (response.result == "error")
                {
                    if (response.errorid == BackendCodes.INTERNAL_EXCEPTION)
                    {
                        ShowErrorCommunication();
                        return(Tuple.Create(UpgradeResult.InternalError, response.errormessage));
                    }

                    if (response.errorid == BackendCodes.WRONG_PASSWORD)
                    {
                        return(Tuple.Create(UpgradeResult.AuthError, string.Empty));
                    }

                    if (response.errorid == BackendCodes.UPGRADE_USER_ACCOUNT_ALREADY_SET)
                    {
                        return(Tuple.Create(UpgradeResult.AlreadyFullAcc, string.Empty));
                    }

                    if (response.errorid == BackendCodes.UPGRADE_USER_DUPLICATE_USERNAME)
                    {
                        return(Tuple.Create(UpgradeResult.UsernameTaken, string.Empty));
                    }

                    SAMLog.Error("Backend::UU_ERR", $"UpgradeUser: Error {response.errorid}: {response.errormessage}");
                    ShowErrorCommunication();
                    return(Tuple.Create(UpgradeResult.InternalError, response.errormessage));
                }
                else
                {
                    ShowErrorCommunication();
                    return(Tuple.Create(UpgradeResult.InternalError, "Internal server error"));
                }
            }
            catch (RestConnectionException e)
            {
                SAMLog.Warning("Backend::UU_RCE", e);                 // probably no internet
                ShowErrorConnection();
                return(Tuple.Create(UpgradeResult.NoConnection, string.Empty));
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::UU_E", e);
                ShowErrorCommunication();
                return(Tuple.Create(UpgradeResult.InternalError, "Internal server error"));
            }
        }
コード例 #7
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        public async Task <Tuple <VerifyResult, int, string> > Verify(string username, string password)
        {
            try
            {
                var pwHash = bridge.DoSHA256(password);

                var ps = new RestParameterSet();
                ps.AddParameterString("username", username);
                ps.AddParameterHash("password", pwHash);
                ps.AddParameterString("app_version", GDConstants.Version.ToString());

                var response = await QueryAsync <QueryResultVerify>("verify", ps, RETRY_VERIFY);

                if (response == null)
                {
                    return(Tuple.Create(VerifyResult.InternalError, -1, "Internal server error"));
                }
                else if (response.result == "success")
                {
                    if (response.user.AutoUser)
                    {
                        return(Tuple.Create(VerifyResult.WrongUsername, -1, string.Empty));
                    }

                    return(Tuple.Create(VerifyResult.Success, response.user.ID, string.Empty));
                }
                else if (response.result == "error")
                {
                    if (response.errorid == BackendCodes.INTERNAL_EXCEPTION)
                    {
                        return(Tuple.Create(VerifyResult.InternalError, -1, response.errormessage));
                    }
                    else if (response.errorid == BackendCodes.WRONG_PASSWORD)
                    {
                        return(Tuple.Create(VerifyResult.WrongPassword, -1, string.Empty));
                    }
                    else if (response.errorid == BackendCodes.USER_BY_NAME_NOT_FOUND)
                    {
                        return(Tuple.Create(VerifyResult.WrongUsername, -1, string.Empty));
                    }
                    else
                    {
                        ShowErrorCommunication();
                        SAMLog.Error("Backend::V_ERR", $"Verify: Error {response.errorid}: {response.errormessage}");
                        return(Tuple.Create(VerifyResult.InternalError, -1, response.errormessage));
                    }
                }
                else
                {
                    return(Tuple.Create(VerifyResult.InternalError, -1, "Internal server exception"));
                }
            }
            catch (RestConnectionException e)
            {
                SAMLog.Warning("Backend::V_RCE", e);                 // probably no internet
                ShowErrorConnection();
                return(Tuple.Create(VerifyResult.NoConnection, -1, string.Empty));
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::V_E", e);
                ShowErrorCommunication();
                return(Tuple.Create(VerifyResult.InternalError, -1, "Internal server exception"));
            }
        }
コード例 #8
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        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();
                });
            }
        }
コード例 #9
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        public async Task Ping(PlayerProfile profile)
        {
            try
            {
                var ps = new RestParameterSet();
                ps.AddParameterInt("userid", profile.OnlineUserID);
                ps.AddParameterHash("password", profile.OnlinePasswordHash);
                ps.AddParameterString("app_version", GDConstants.Version.ToString());
                ps.AddParameterString("device_name", bridge.DeviceName);
                ps.AddParameterString("device_version", bridge.DeviceVersion);
                ps.AddParameterString("unlocked_worlds", profile.StrPurchasedWorlds);
                ps.AddParameterString("device_resolution", bridge.DeviceResolution.FormatAsResolution());

                var response = await QueryAsync <QueryResultPing>("ping", ps, RETRY_PING);

                if (response == null)
                {
                    return;                     // meh - internal server error
                }
                else if (response.result == "success")
                {
                    if (response.user.RevID > profile.OnlineRevisionID)
                    {
                        await DownloadData(profile);
                    }

                    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::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;
                            profile.OnlineUsername     = "******";
                            profile.AccountType        = AccountType.Local;
                            profile.OnlinePasswordHash = "";

                            MainGame.Inst.SaveProfile();

                            MainGame.Inst.Backend.CreateUser(MainGame.Inst.Profile).EnsureNoError();
                        });
                    }
                    else
                    {
                        SAMLog.Error("Backend::PingError", $"Ping: Error {response.errorid}: {response.errormessage}");
                    }
                }
            }
            catch (RestConnectionException e)
            {
                SAMLog.Warning("Backend::PingRCE", e);                 // probably no internet
                ShowErrorConnection();
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::PingE", e);
                ShowErrorCommunication();
            }
        }
コード例 #10
0
ファイル: GDServerAPI.cs プロジェクト: ssttv/GridDominance
        public async Task DownloadData(PlayerProfile profile)
        {
            try
            {
                var ps = new RestParameterSet();
                ps.AddParameterInt("userid", profile.OnlineUserID);
                ps.AddParameterHash("password", profile.OnlinePasswordHash);
                ps.AddParameterString("app_version", GDConstants.Version.ToString());

                var response = await QueryAsync <QueryResultDownloadData>("download-data", ps, RETRY_DOWNLOADDATA);

                if (response == null)
                {
                    return;                     // meh - internal server error
                }
                else if (response.result == "success")
                {
                    MonoSAMGame.CurrentInst.DispatchBeginInvoke(() =>
                    {
                        profile.OnlineRevisionID = response.user.RevID;

                        foreach (var scdata in response.scores)
                        {
                            profile.SetCompleted(Guid.Parse(scdata.levelid), (FractionDifficulty)scdata.difficulty, scdata.best_time, false);
                        }

                        profile.MultiplayerPoints    = response.user.MultiplayerScore;
                        profile.HasMultiplayerGames |= response.user.MultiplayerScore > 0;

                        MainGame.Inst.SaveProfile();
                    });
                }
                else if (response.result == "error")
                {
                    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::DD_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::DD_ERR", $"SetScore: Error {response.errorid}: {response.errormessage}");
                        ShowErrorCommunication();
                    }
                }
            }
            catch (RestConnectionException e)
            {
                SAMLog.Warning("Backend::DD_RCE", e);                 // probably no internet
                ShowErrorConnection();
            }
            catch (Exception e)
            {
                SAMLog.Error("Backend::DD_E", e);
                ShowErrorCommunication();
            }
        }