Files
ft/Client/Assets/Scripts/Services/SettingService.cs

280 lines
9.1 KiB
C#

using Core.KV;
using game.KV;
using System.Globalization;
using System.Threading.Tasks;
using asap.core;
using Game;
using UnityEngine;
using System;
namespace game
{
public interface ISettingService
{
bool Music { get; set; }
bool Sound { get; set; }
bool Vibration { get; set; }
bool Notice { get; }
string Lang { get; set; }
int UnitOfWeight { get; set; }
bool ShowNotice { get; set; }
bool CheckRequestPermission();
}
public class DefaultSettingService : ISettingService
{
bool _music;
bool _sound;
bool _vibration;
string _lang;
int _unitOfWeight = 1;
bool? _showNotice;
private readonly bool requiresFormalKV;
private KvSessionOwner promptOwner;
internal bool HasKVPromptOwner => promptOwner != null;
// Preserve only our key/owner/error metadata across void UI boundaries, never platform payloads.
internal static InvalidOperationException PromptFailure(string message)
{
var error = new InvalidOperationException(message);
error.Data["B01PromptDiagnostic"] = message;
return error;
}
internal static void LogPromptFailure(Exception error) => Debug.LogError(
error.Data["B01PromptDiagnostic"] as string ?? "Notification prompt stopped: " + error.GetType().Name);
public DefaultSettingService() : this(false) { }
internal DefaultSettingService(bool formalKV) { requiresFormalKV = formalKV; }
// The frozen startup selection is supplied before login; this instance can never change owners.
internal void PreflightFormalPromptOwner(KvSessionOwner owner)
{
if (!requiresFormalKV || owner == null || (promptOwner != null && !ReferenceEquals(promptOwner, owner)))
{
throw PromptFailure("ShowNotice: formal owner mismatch.");
}
var read = KvSaveStore.ReadKV(owner, "ShowNotice");
if (!read.Success)
{
throw PromptFailure($"ShowNotice owner={owner.OwnerInstanceId}: {read.Error}");
}
}
internal void BindFormalPromptOwner(KvSessionOwner owner)
{
PreflightFormalPromptOwner(owner);
if (promptOwner == null)
{
promptOwner = owner;
}
RequirePromptOwner();
}
internal void ReleaseFailedPromptOwner(KvSessionOwner owner)
{
if (promptOwner == null)
{
return;
}
if (!ReferenceEquals(promptOwner, owner) || owner.Status != KVSyncStatus.Closed)
{
throw PromptFailure("ShowNotice: failed owner has not closed.");
}
promptOwner = null;
_showNotice = null;
}
internal void RequirePromptOwner()
{
if (promptOwner != null) ReadPrompt();
else if (requiresFormalKV) throw PromptFailure("ShowNotice: formal owner not handed off.");
}
private PlayerSaveReadResult ReadPrompt()
{
var read = KvSaveStore.ReadKV(promptOwner, "ShowNotice");
if (!read.Success)
{
throw PromptFailure($"ShowNotice owner={promptOwner.OwnerInstanceId}: {read.Error}");
}
return read;
}
public bool Music
{
set
{
if (value != _music)
{
PlayerPrefs.SetInt("Music", value ? 1 : 0);
_music = value;
GContext.Publish(new SoundMuteEvent(0));
}
}
get { return _music; }
}
public bool Sound
{
set
{
if (value != _sound)
{
PlayerPrefs.SetInt("Sound", value ? 1 : 0);
_sound = value;
GContext.Publish(new SoundMuteEvent(1));
}
}
get { return _sound; }
}
public bool Vibration
{
set
{
if (value != _vibration)
{
PlayerPrefs.SetInt("Vibration", value ? 1 : 0);
_vibration = value;
}
}
get { return _vibration; }
}
public bool Notice
{
get
{
return GContext.container.Resolve<ILocalNotificationService>().IsNoticeOpen;
}
}
public string Lang
{
set
{
if (value != _lang)
{
PlayerPrefs.SetString("Lang", value);
_lang = value;
}
}
get { return _lang; }
}
public int UnitOfWeight
{
set
{
if (value != _unitOfWeight)
{
PlayerPrefs.SetInt("UnitOfWeight", value);
_unitOfWeight = value;
}
}
get { return _unitOfWeight; }
}
public bool ShowNotice
{
get
{
if (requiresFormalKV && promptOwner == null)
{
RequirePromptOwner();
}
if (promptOwner != null)
{
var read = ReadPrompt();
_showNotice ??= read.Found == true && read.Value == "1";
return _showNotice.Value;
}
_showNotice ??= PlayFabMgr.Instance.GetLocalData("ShowNotice") == "1";
return _showNotice.Value;
}
set
{
if (requiresFormalKV && promptOwner == null)
{
RequirePromptOwner();
}
if (promptOwner != null)
{
ReadPrompt();
if (value != _showNotice)
{
_showNotice = value;
var promptEdit = KvSaveStore.WriteKV(promptOwner, "ShowNotice", value ? "1" : "0");
if (!promptEdit.Success)
{
throw PromptFailure($"ShowNotice owner={promptOwner.OwnerInstanceId}: {promptEdit.Error}; uncertain={promptEdit.LocalCommitMayHaveSucceeded}");
}
}
RequirePromptOwner();
return;
}
if (value != _showNotice)
{
_showNotice = value;
PlayFabMgr.Instance.UpdateUserDataValue("ShowNotice", value ? "1" : "0");
}
}
}
public void Init(cfg.Tables tables)
{
if (!PlayerPrefs.HasKey("Music"))
{
var globalConfig = tables.TbGlobalConfig;
Music = globalConfig.MusicSetting;
Sound = globalConfig.SoundSetting;
Vibration = true;
CultureInfo info = System.Globalization.CultureInfo.CurrentUICulture;
string Language = info.TwoLetterISOLanguageName;
if (Language == "zh")
{
if (info.DisplayName.Contains("Simplified"))
{
Language = "zh_Hans";
}
else
{
Language = "zh_Hant";
}
}
Lang = Language;
}
else
{
_music = PlayerPrefs.GetInt("Music") == 1;
_sound = PlayerPrefs.GetInt("Sound") == 1;
_vibration = PlayerPrefs.GetInt("Vibration") == 1;
_lang = PlayerPrefs.GetString("Lang");
_unitOfWeight = PlayerPrefs.GetInt("UnitOfWeight");
}
}
public bool CheckRequestPermission()
{
if (ShowNotice)
{
return false;
}
var notification = GContext.container.Resolve<ILocalNotificationService>();
if (notification is LocalNotificationService local) local.RequirePromptOwner(this);
if (notification.IsNoticeOpen)
{
ShowNotice = true;
return false;
}
return true;
}
private async Task<bool> AskPermission()
{
var result = new TaskCompletionSource<bool>();
var callbacks = new UnityEngine.Android.PermissionCallbacks();
callbacks.PermissionGranted += (x) => result.SetResult(true);
callbacks.PermissionDeniedAndDontAskAgain += (x) => result.SetResult(false);
callbacks.PermissionDenied += (x) => result.SetResult(false);
UnityEngine.Android.Permission.RequestUserPermission("android.permission.POST_NOTIFICATIONS", callbacks);
return await result.Task;
}
}
}