|
- using CIG3.ExtensionMethods;
- using SUISS.Cloud;
- using SUISS.Cloud.Boomlagoon.JSON;
- using SUISS.Core;
- using SUISS.Storage;
- using SUISSEngine;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Threading;
- using UnityEngine;
-
- public sealed class CIGVisitingIslandsManager : SingletonMonobehaviour<CIGVisitingIslandsManager>
- {
- private class IslandData : StorableDictionary<VisitingIsland>
- {
- }
-
- private class StorableStringDict : StorableDictionary<string>
- {
- }
-
- public static readonly TimeSpan CacheRetention = TimeSpan.FromDays(1.0);
-
- private const string IslandsEndPoint = "https://sparkling-society-islands.herokuapp.com";
-
- private const string LoginUrl = "https://sparkling-society-usernames.herokuapp.com/login/gamestates";
-
- public const string StorageKey = "OtherIslandsData";
-
- public const string IslandCacheKey = "IslandCache";
-
- public const string LastSentIslandDataKey = "LastSentIslandData";
-
- public GameObject[] islands;
-
- public GameObject[] otherIslands;
-
- private CIGSparkSocServices _services;
-
- private IAccessToken _accessToken;
-
- private Island _currentIsland;
-
- private string _currentIslandUuid;
-
- private string _islandsUrl = "{0}/islands/{1}/{2}?access_token={3}";
-
- private Dictionary<string, object> storage => Storage.Get(StorageLifecycle.Game).GetDictionary("OtherIslandsData");
-
- private IslandData IslandCache
- {
- get
- {
- if (!storage.ContainsKey("IslandCache"))
- {
- storage["IslandCache"] = new IslandData();
- }
- return (IslandData)storage["IslandCache"];
- }
- set
- {
- storage["IslandCache"] = value;
- }
- }
-
- private StorableStringDict LastSentIslandData
- {
- get
- {
- if (!storage.ContainsKey("LastSentIslandData"))
- {
- storage["LastSentIslandData"] = new StorableStringDict();
- }
- return (StorableStringDict)storage["LastSentIslandData"];
- }
- set
- {
- storage["LastSentIslandData"] = value;
- }
- }
-
- public bool IsLoggedIn => _accessToken != null && !_accessToken.HasExpired;
-
- public int SentIslandCount => LastSentIslandData.Count;
-
- public event Action<Island, string> DataDownloadedEvent;
-
- private void FireDataDownloadedEventEvent(Island island, string uuid)
- {
- if (this.DataDownloadedEvent != null)
- {
- this.DataDownloadedEvent(island, uuid);
- }
- }
-
- private void Start()
- {
- _services = SingletonMonobehaviour<CIGSparkSocServices>.Instance;
- if (_services == null)
- {
- UnityEngine.Debug.LogError("CIGVisitingIslandsManager requires CIGSparkSocServices, but was unable to find it!");
- }
- StartCoroutine(SyncMyIslands());
- }
-
- protected override void Awake()
- {
- base.Awake();
- }
-
- protected override void OnDestroy()
- {
- base.OnDestroy();
- }
-
- public bool IslandIsSent()
- {
- return LastSentIslandData.Count > 0;
- }
-
- public bool LoadVisitingIslandData(Island island, string uuid)
- {
- if (IslandCache.ContainsKey(uuid + island.GetSceneName()))
- {
- VisitingIsland visitingIsland = IslandCache[uuid + island.GetSceneName()];
- ImportIsland(island, JsonToGrid(visitingIsland.Data));
- return true;
- }
- return false;
- }
-
- public bool VisitingIslandDataAvaible(Island island, string uuid)
- {
- return IslandCache.ContainsKey(uuid + island.GetSceneName());
- }
-
- public bool IsUnlocked(Island island, string uuid)
- {
- if (IslandCache.ContainsKey(uuid + island.GetSceneName()))
- {
- return IslandCache[uuid + island.GetSceneName()].UnLocked;
- }
- return false;
- }
-
- public void DownLoadIslandData(Island island, string uuid)
- {
- if (!VisitingIslandDataAvaible(island, uuid) || !(IslandCache[uuid + island.GetSceneName()].Time + CacheRetention > DateTime.UtcNow))
- {
- LoadIslandData(island, uuid);
- }
- }
-
- public void DownloadAllIslandsData(string uuid)
- {
- foreach (Island island in IslandExtensions.GetIslands())
- {
- DownLoadIslandData(island, uuid);
- }
- }
-
- public GameObject GetReadOnlyIslandPrefabByName(Island island)
- {
- GameObject[] array = otherIslands;
- foreach (GameObject gameObject in array)
- {
- if (gameObject.name == island.GetSceneName() + "ReadOnly")
- {
- return gameObject;
- }
- }
- return null;
- }
-
- private bool ShouldSync()
- {
- if (!SingletonMonobehaviour<CIGSparkSocServices>.IsAvailable || !SingletonMonobehaviour<CIGGameStats>.IsAvailable || !SingletonMonobehaviour<CIGWebService>.IsAvailable)
- {
- return false;
- }
- CIGSparkSocServices instance = SingletonMonobehaviour<CIGSparkSocServices>.Instance;
- CIGGameStats instance2 = SingletonMonobehaviour<CIGGameStats>.Instance;
- CIGWebService instance3 = SingletonMonobehaviour<CIGWebService>.Instance;
- if (!instance.IsLinkedToPlayername())
- {
- return false;
- }
- if (instance.IsTopPlayer())
- {
- return true;
- }
- if (instance2.GetTotalBuildingCount() < 20)
- {
- return false;
- }
- if (!ShouldSyncUuid(instance.GetInstallUuid(), instance3.IslandSyncChangePercent))
- {
- return false;
- }
- return true;
- }
-
- private bool ShouldSyncUuid(string uuid, int syncPercent)
- {
- float num = Mathf.Clamp01((float)syncPercent / 100f);
- uint num2 = (uint)(4.2949673E+09f * num);
- uint hashCode = (uint)uuid.GetHashCode();
- return hashCode <= num2;
- }
-
- private IEnumerator SyncMyIslands()
- {
- yield return null;
- while (true)
- {
- if (ShouldSync())
- {
- foreach (Island island in IslandExtensions.GetIslands())
- {
- JSONValue data = StorableToJson(ExportIsland(island));
- CloudRequest<ApiError> sendData = SendIslandData(island, data);
- yield return sendData;
- if (sendData.Error != null)
- {
- UnityEngine.Debug.LogWarning($"Failed to update {island.GetSceneName()} island. Message {sendData.Error.Error}");
- }
- }
- yield return new WaitForSeconds(300f);
- }
- else
- {
- yield return new WaitForSeconds(10f);
- }
- }
- }
-
- private GameObject FindIslandPrefabByName(Island island)
- {
- GameObject[] array = islands;
- foreach (GameObject gameObject in array)
- {
- if (gameObject.name == island.GetSceneName())
- {
- return gameObject;
- }
- }
- return null;
- }
-
- private bool HasIslandChanged(Island island, JSONValue data)
- {
- if (!LastSentIslandData.ContainsKey(island.GetSceneName()))
- {
- return true;
- }
- return LastSentIslandData[island.GetSceneName()] != data.ToString();
- }
-
- private string GetGridStorageKey(GameObject islandPrefab)
- {
- if (islandPrefab != null)
- {
- IsometricIsland component = islandPrefab.GetComponent<IsometricIsland>();
- if (component != null)
- {
- IsometricGrid grid = component.grid;
- if (grid != null)
- {
- Serializing serializing = grid.serializing;
- if (serializing != null)
- {
- return (serializing.StorageKey == null) ? string.Empty : serializing.StorageKey;
- }
- }
- }
- }
- return string.Empty;
- }
-
- private Dictionary<string, object> ExportIsland(Island island)
- {
- string gridStorageKey = GetGridStorageKey(FindIslandPrefabByName(island));
- if (gridStorageKey != null && gridStorageKey.Length > 0)
- {
- return Storage.Get(StorageLifecycle.Game).GetDictionary(gridStorageKey);
- }
- return new Dictionary<string, object>();
- }
-
- private void ImportIsland(Island island, Dictionary<string, object> grid)
- {
- string gridStorageKey = GetGridStorageKey(GetReadOnlyIslandPrefabByName(island));
- if (gridStorageKey != null && gridStorageKey.Length > 0)
- {
- Storage storage = Storage.Get(StorageLifecycle.Game);
- storage.Root[gridStorageKey] = grid;
- }
- }
-
- private Dictionary<string, object> JsonToGrid(JSONObject dataObj)
- {
- Dictionary<string, object> dictionary = new Dictionary<string, object>();
- foreach (KeyValuePair<string, JSONValue> item in dataObj)
- {
- if (item.Value.Type != 0)
- {
- UnityEngine.Debug.LogError("Grid data should only have string values! But found:" + item.Value.Type.ToString());
- }
- else
- {
- dictionary.Add(item.Key, item.Value.Str);
- }
- }
- return dictionary;
- }
-
- private JSONValue StorableToJson(object data)
- {
- if (object.ReferenceEquals(data, null))
- {
- return new JSONValue((JSONObject)null);
- }
- if (data is Dictionary<string, object>)
- {
- Dictionary<string, object> dictionary = (Dictionary<string, object>)data;
- JSONObject jSONObject = new JSONObject();
- foreach (KeyValuePair<string, object> item in dictionary)
- {
- jSONObject.Add(item.Key, StorableToJson(item.Value));
- }
- return new JSONValue(jSONObject);
- }
- if (data is List<object>)
- {
- List<object> list = (List<object>)data;
- JSONArray jSONArray = new JSONArray();
- foreach (object item2 in list)
- {
- jSONArray.Add(StorableToJson(item2));
- }
- return new JSONValue(jSONArray);
- }
- if (data is object[])
- {
- object[] array = (object[])data;
- JSONArray jSONArray2 = new JSONArray();
- object[] array2 = array;
- foreach (object data2 in array2)
- {
- jSONArray2.Add(StorableToJson(data2));
- }
- return new JSONValue(jSONArray2);
- }
- if (data is string)
- {
- return new JSONValue((string)data);
- }
- if (data is bool)
- {
- return new JSONValue((bool)data);
- }
- if (data is char)
- {
- return new JSONValue(((char)data).ToString());
- }
- if (data is float)
- {
- return new JSONValue(Convert.ToDouble((float)data));
- }
- if (data is double)
- {
- return new JSONValue((double)data);
- }
- if (data is sbyte)
- {
- return new JSONValue(((sbyte)data).ToString());
- }
- if (data is byte)
- {
- return new JSONValue(((byte)data).ToString());
- }
- if (data is short)
- {
- return new JSONValue(Convert.ToDouble((short)data));
- }
- if (data is ushort)
- {
- return new JSONValue(Convert.ToDouble((ushort)data));
- }
- if (data is int)
- {
- return new JSONValue(Convert.ToDouble((int)data));
- }
- if (data is uint)
- {
- return new JSONValue(Convert.ToDouble((uint)data));
- }
- if (data is long)
- {
- return new JSONValue(Convert.ToDouble((long)data));
- }
- if (data is ulong)
- {
- return new JSONValue(Convert.ToDouble((ulong)data));
- }
- if (data is decimal)
- {
- return new JSONValue(Convert.ToDouble((decimal)data));
- }
- if (data is IStorable)
- {
- return StorableToJson(((IStorable)data).ToStorage());
- }
- return new JSONValue((JSONObject)null);
- }
-
- private CloudRequest<ApiError> LoginIslandServer()
- {
- return new CloudRequest<ApiError>(CoLoginIslandServer());
- }
-
- private IEnumerator CoLoginIslandServer()
- {
- if (_services.IsRegisteredInstall())
- {
- CloudRequest<IAccessToken, PlayernameErrors?> request = _services.GetVisitingIslandsAccessToken();
- yield return request;
- if (request.Error.HasValue)
- {
- yield return new YieldError<ApiError>(new ApiError
- {
- Error = request.Error.ToString(),
- ErrorCode = (int)request.Error.Value,
- Status = 0,
- ServerError = false,
- NoInternet = false
- });
- }
- else
- {
- _accessToken = request.Result;
- }
- }
- }
-
- private CloudRequest<ApiError> SendIslandData(Island island, JSONValue data)
- {
- return new CloudRequest<ApiError>(CoSendIslandData(island, data));
- }
-
- private IEnumerator CoSendIslandData(Island island, JSONValue data)
- {
- if (!HasIslandChanged(island, data))
- {
- yield break;
- }
- if (!IsLoggedIn)
- {
- CloudRequest<ApiError> login = LoginIslandServer();
- yield return login;
- if (login.Error != null)
- {
- UnityEngine.Debug.LogWarning("[Login] Could not send island data. " + login.Error.Error);
- yield return new YieldError<ApiError>(login.Error);
- yield break;
- }
- }
- string url = string.Format(_islandsUrl, "https://sparkling-society-islands.herokuapp.com", _services.GetInstallUuid(), island.GetSceneName(), _accessToken.Token);
- ApiRequest request = ApiRequest.Post(url, data);
- yield return request;
- if (request.Error != null)
- {
- UnityEngine.Debug.LogError("Unable to send island data. Server message:" + request.Error.Error);
- yield return new YieldError<ApiError>(request.Error);
- }
- else
- {
- UnityEngine.Debug.Log("Island: " + island.GetSceneName() + " data send to server!");
- LastSentIslandData[island.GetSceneName()] = data.ToString();
- }
- }
-
- private CloudRequest<ApiError> LoadIslandData(Island island, string installUuid)
- {
- return new CloudRequest<ApiError>(CoLoadIslandData(island, installUuid));
- }
-
- private IEnumerator CoLoadIslandData(Island island, string installUuid)
- {
- if (!IsLoggedIn)
- {
- CloudRequest<ApiError> login = LoginIslandServer();
- yield return login;
- if (login.Error != null)
- {
- UnityEngine.Debug.LogError("[Login] Could not load island data. " + login.Error.Error);
- yield return new YieldError<ApiError>(login.Error);
- yield break;
- }
- }
- string url = string.Format(_islandsUrl, "https://sparkling-society-islands.herokuapp.com", installUuid, island.GetSceneName(), _accessToken.Token);
- ApiRequest request = ApiRequest.Get(url);
- yield return request;
- if (request.Error != null)
- {
- if (request.Error.Status == 404)
- {
- UnityEngine.Debug.LogWarning("Trying to get data from a player who has never sent us gamestate! (http 404)");
- IslandCache[installUuid + island.GetSceneName()] = new VisitingIsland(island, installUuid, new JSONObject());
- FireDataDownloadedEventEvent(island, installUuid);
- }
- UnityEngine.Debug.LogError("[Island Data] Could not load island data. " + request.Error.Error);
- yield return new YieldError<ApiError>(request.Error);
- yield break;
- }
- JSONObject data = new JSONObject();
- if (request.Result.Data.Type != JSONValueType.Object || !request.Result.Data.Obj.ContainsKey("data"))
- {
- UnityEngine.Debug.LogWarning("Get Island data expected 'data' field. But the server didn't provide it.");
- }
- else
- {
- JSONValue jSONValue = request.Result.Data.Obj["data"];
- if (jSONValue.Type != JSONValueType.Object)
- {
- UnityEngine.Debug.LogError("Island data expected to be json Object found: " + jSONValue.Type.ToString());
- }
- else
- {
- data = jSONValue.Obj;
- }
- }
- IslandCache[installUuid + island.GetSceneName()] = new VisitingIsland(island, installUuid, data);
- FireDataDownloadedEventEvent(island, installUuid);
- }
- }
|