using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using SUISS.Cloud.Extensions; using UnityEngine; namespace SUISS.Cloud { public class FriendsController : IFriendsController { public FriendsController(IPlayernameController playernameController, Dictionary storage) { this._playernameController = playernameController; this._storage = storage; } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event Action> NewFriendEvent; private void FireNewFriendEvent(IList newFriends) { if (this.NewFriendEvent != null) { this.NewFriendEvent(newFriends); } } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event Action> NewInviteEvent; private void FireNewInviteEvent(IList newInvites) { if (this.NewInviteEvent != null) { this.NewInviteEvent(newInvites); } } public void StartUpdateLoop(Func> getInfo) { } public CloudRequest UpdateInfo(IDictionary info) { if (Json.Encode(info) == null) { throw new Exception("UpdateInfo(IDictionary info): info is not valid json."); } if (!string.IsNullOrEmpty(this._playernameController.PlayerName) && !string.IsNullOrEmpty(this._playernameController.PlayerName)) { return new CloudRequest(this.CoUpdateInfo(info)); } UnityEngine.Debug.LogWarning("Unable to update friend data! PlayernameController is not loged in yet."); return null; } public CloudRequest Invite(string friendName) { return new CloudRequest(this.CoInvite(friendName)); } public CloudRequest Unblock(string friendName) { return new CloudRequest(this.CoUnblock(friendName)); } public CloudRequest RefreshLists() { return new CloudRequest(this.CoRefreshLists()); } public CloudRequest Accept(IFriend friend) { return new CloudRequest(this.CoAccept(friend)); } public CloudRequest Block(IFriend friend) { return new CloudRequest(this.CoBlock(friend)); } public CloudRequest RemoveInvite(IFriend friend) { return new CloudRequest(this.CoRemoveInvite(friend)); } public CloudRequest RemoveAllInvites() { return new CloudRequest(this.CoRemoveAllInvites()); } public IEnumerable BlockedPlayernames { get { foreach (object obj in this.blocked) { yield return (string)obj; } yield break; } } public IEnumerable Invites { get { foreach (object obj in this.invites) { yield return (IFriend)obj; } yield break; } } public IEnumerable KnownFriends { get { foreach (object obj in this.readInvites) { yield return (string)obj; } yield break; } } public void MarkFriendKnown(string friendName) { this.readInvites.Add(friendName); } public void UnmarkFriendKnown(string friendName) { this.readInvites.Remove(friendName); } public IEnumerable Friends { get { foreach (object obj in this.friends) { yield return (IFriend)obj; } yield break; } } public IEnumerable Invited { get { foreach (object obj in this.invited) { yield return (string)obj; } yield break; } } private Dictionary PlayerStorage { get { if (!this._storage.ContainsKey(this._playernameController.PlayerUuid) || !(this._storage[this._playernameController.PlayerUuid] is Dictionary)) { this._storage.Add(this._playernameController.PlayerUuid, new Dictionary()); } return (Dictionary)this._storage[this._playernameController.PlayerUuid]; } } private List invites { get { if (!this.PlayerStorage.ContainsKey("invites") || !(this.PlayerStorage["invites"] is List)) { this.PlayerStorage["invites"] = new List(); } return (List)this.PlayerStorage["invites"]; } set { this.PlayerStorage["invites"] = value; } } private List readInvites { get { if (!this.PlayerStorage.ContainsKey("readInvites") || !(this.PlayerStorage["readInvites"] is List)) { this.PlayerStorage["readInvites"] = new List(); } return (List)this.PlayerStorage["readInvites"]; } set { this.PlayerStorage["readInvites"] = value; } } private DateTime LastUpdated { get { if (!this.PlayerStorage.ContainsKey("lastUpdated") || !(this.PlayerStorage["lastUpdated"] is long)) { this.PlayerStorage["lastUpdated"] = 0; } return new DateTime((long)this.PlayerStorage["lastUpdated"]); } } private List friends { get { if (!this.PlayerStorage.ContainsKey("friends") || !(this.PlayerStorage["friends"] is List)) { this.PlayerStorage["friends"] = new List(); } return (List)this.PlayerStorage["friends"]; } set { this.PlayerStorage["friends"] = value; } } private List blocked { get { if (!this.PlayerStorage.ContainsKey("blocked") || !(this.PlayerStorage["blocked"] is List)) { this.PlayerStorage.Add("blocked", new List()); } return (List)this.PlayerStorage["blocked"]; } set { this.PlayerStorage["blocked"] = value; } } private List invited { get { if (!this.PlayerStorage.ContainsKey("invited") || !(this.PlayerStorage["invited"] is List)) { this.PlayerStorage.Add("invited", new List()); } return (List)this.PlayerStorage["invited"]; } set { this.PlayerStorage["invited"] = value; } } private CloudRequest GetAccessToken() { return new CloudRequest(this.CoGetAccessToken()); } private IEnumerator CoGetAccessToken() { if (this._accessToken.HasExpired) { CloudRequest login = this._playernameController.RequestPlayerAccessToken("friends"); yield return login; if (login.Result != null && !login.Result.HasExpired) { this._accessToken = login.Result; } else { PlayernameErrors value = login.Error.Value; if (value != PlayernameErrors.NoInternet) { if (value != PlayernameErrors.LostValidRefreshToken) { yield return new YieldError(new FriendErrors?(FriendErrors.GeneralError)); } else { yield return new YieldError(new FriendErrors?(FriendErrors.LostRefreshToken)); } } else { yield return new YieldError(new FriendErrors?(FriendErrors.NoInternet)); } } } yield break; } private IEnumerator CoRemoveInvite(IFriend friend) { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } string url = string.Format("{0}/friends/{1}/clear?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token); Dictionary json = new Dictionary { { "friendName", friend.FriendName } }; ApiRequest request = ApiRequest.Post(url, json); yield return request; if (request.Error != null) { yield return this.FriendError(request.Error); } this.invited.Remove(friend.FriendName); yield break; } private IEnumerator CoRemoveAllInvites() { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } string url = string.Format("{0}/friends/{1}/requests/delete?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token); ApiRequest request = ApiRequest.Get(url); yield return request; if (request.Error != null) { yield return this.FriendError(request.Error); } this.invited.Clear(); yield break; } private IEnumerator CoUpdateInfo(IDictionary json) { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } Dictionary data = new Dictionary { { "data", json }, { "playername", this._playernameController.PlayerName } }; string url = string.Format("{0}/friends/{1}?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token); ApiRequest request = ApiRequest.Post(url, data); yield return request; if (request.Error != null) { yield return this.FriendError(request.Error); } yield break; } private IEnumerator CoInvite(string friendName) { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } string url = string.Format("{0}/friends/{1}/invite?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token); Dictionary json = new Dictionary { { "friendName", friendName } }; ApiRequest request = ApiRequest.Post(url, json); yield return request; if (request.Error != null) { yield return this.FriendError(request.Error); } this.invited.Add(friendName); yield break; } private IEnumerator CoUnblock(string friendName) { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } string url = string.Format("{0}/friends/{1}/unblock?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token); Dictionary json = new Dictionary { { "friendName", friendName } }; ApiRequest request = ApiRequest.Post(url, json); yield return request; if (request.Error != null) { yield return this.FriendError(request.Error); } this.blocked.Remove(friendName); yield break; } private IEnumerator CoAccept(IFriend friend) { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } string url = string.Format("{0}/friends/{1}/accept?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token); Dictionary json = new Dictionary { { "friendName", friend.FriendName } }; ApiRequest request = ApiRequest.Post(url, json); yield return request; if (request.Error != null) { yield return this.FriendError(request.Error); } this.friends.Add(friend); this.invites.Remove(this.invites.Find((object f) => ((IFriend)f).AccountUuid == friend.AccountUuid)); yield break; } private IEnumerator CoBlock(IFriend friend) { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } string url = string.Format("{0}/friends/{1}/block?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token); Dictionary json = new Dictionary { { "friendName", friend.FriendName } }; ApiRequest request = ApiRequest.Post(url, json); yield return request; if (request.Error != null) { yield return this.FriendError(request.Error); } this.blocked.Add(friend.FriendName); yield break; } private IEnumerator CoRefreshLists() { if (this._accessToken.HasExpired) { CloudRequest login = this.GetAccessToken(); yield return login; if (login.Error != null) { yield return new YieldError(login.Error); } } ApiRequest friendsRequest = ApiRequest.Get(string.Format("{0}/friends/{1}?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token)); yield return friendsRequest; if (friendsRequest.Result != null) { bool validJson = false; object json = Json.Decode(friendsRequest.Result.Data.ToString(), ref validJson); if (validJson) { List list = this.FriendsFromJson(json, "friends"); if (list != null) { List list2 = this.FindNew(this.TypedList(this.friends), list); this.friends = this.ObjectList(list); if (list2.Count > 0) { this.FireNewFriendEvent(list2); } } } else { UnityEngine.Debug.LogError(string.Format("Api call {0} return unexpected json!", "{0}/friends/{1}?access_token={2}")); yield return new YieldError(new FriendErrors?(FriendErrors.GeneralError)); } } else { yield return this.FriendError(friendsRequest.Error); } ApiRequest invitesRequest = ApiRequest.Get(string.Format("{0}/friends/{1}/requests?access_token={2}", "https://friends.sparklingsociety.net", this._playernameController.PlayerUuid, this._accessToken.Token)); yield return invitesRequest; if (invitesRequest.Result != null) { bool validJson2 = false; object json2 = Json.Decode(invitesRequest.Result.Data.ToString(), ref validJson2); if (validJson2) { List list3 = this.FriendsFromJson(json2, "requests"); if (list3 != null) { List list4 = this.FindNew(this.TypedList(this.invites), list3); this.invites = this.ObjectList(list3); if (list4.Count > 0) { this.FireNewInviteEvent(list4); } } } else { UnityEngine.Debug.LogError(string.Format("Api call {0} return unexpected json!", "{0}/friends/{1}/requests?access_token={2}")); yield return new YieldError(new FriendErrors?(FriendErrors.GeneralError)); } } else { yield return this.FriendError(invitesRequest.Error); } yield break; } private YieldError FriendError(ApiError error) { if (error.NoInternet) { return new YieldError(new FriendErrors?(FriendErrors.NoInternet)); } if (error.ServerError) { UnityEngine.Debug.LogError("Server error in FriendsController: " + error.Error); } UnityEngine.Debug.LogWarning("Api call failed in FriendsController: " + error.Error); return new YieldError(new FriendErrors?(FriendErrors.GeneralError)); } private List FindNew(List oldFriends, List friends) { List list = new List(); if (friends.Count > oldFriends.Count) { List list2 = new List(); foreach (Friend friend in oldFriends) { list2.Add(friend.AccountUuid); } foreach (Friend friend2 in friends) { if (!list2.Contains(friend2.AccountUuid)) { list.Add(friend2); } } } return list; } private List ObjectList(List tl) { List list = new List(); foreach (T t in tl) { list.Add(t); } return list; } private List TypedList(List ol) { List list = new List(); foreach (object obj in ol) { list.Add((T)((object)obj)); } return list; } private Friend FriendFromJson(object jsonValue) { if (jsonValue is Dictionary) { Dictionary dictionary = (Dictionary)jsonValue; string @string = dictionary.GetString("accountUuid", string.Empty); string string2 = dictionary.GetString("playerName", string.Empty); IDictionary games = this.GameInfoListFromJson(dictionary.Get("data", new Dictionary())); if (!string.IsNullOrEmpty(@string)) { return new Friend(@string, string2, games); } } return null; } private IDictionary GameInfoListFromJson(object jsonValue) { Dictionary dictionary = new Dictionary(); if (jsonValue is Dictionary) { Dictionary dictionary2 = (Dictionary)jsonValue; foreach (KeyValuePair keyValuePair in dictionary2) { GameInfo gameInfo = this.GameInfoFromJson(keyValuePair.Value); if (gameInfo != null) { dictionary.Add(keyValuePair.Key, gameInfo); } } } return dictionary; } private GameInfo GameInfoFromJson(object jsonValue) { if (jsonValue is Dictionary) { Dictionary dictionary = (Dictionary)jsonValue; string @string = dictionary.GetString("gameName", string.Empty); IDictionary data = (IDictionary)dictionary.Get("gameData", new Dictionary()); return new GameInfo(@string, data); } return null; } private List FriendsFromJson(object json, string listName) { if (json is Dictionary) { Dictionary dictionary = (Dictionary)json; if (dictionary.ContainsKey(listName) && dictionary[listName] is List) { List list = new List(); foreach (object jsonValue in ((List)dictionary[listName])) { Friend friend = this.FriendFromJson(jsonValue); if (friend != null) { list.Add(friend); } } return list; } } return null; } private List FriendNameFromJson(object json, string listName) { if (json is Dictionary) { Dictionary dictionary = (Dictionary)json; if (dictionary.ContainsKey(listName) && dictionary[listName] is List) { List list = new List(); foreach (object obj in ((List)dictionary[listName])) { if (obj is string) { list.Add((string)obj); } } return list; } } return null; } private const string FriendResourceName = "friends"; private const string UpdateInfoCall = "{0}/friends/{1}?access_token={2}"; private const string InviteCall = "{0}/friends/{1}/invite?access_token={2}"; private const string AcceptCall = "{0}/friends/{1}/accept?access_token={2}"; private const string BlockCall = "{0}/friends/{1}/block?access_token={2}"; private const string UnblockCall = "{0}/friends/{1}/unblock?access_token={2}"; private const string FriendsCall = "{0}/friends/{1}?access_token={2}"; private const string InvitesCall = "{0}/friends/{1}/requests?access_token={2}"; private const string BlockedCall = "{0}/friends/{1}/blocked?access_token={2}"; private const string InvitedCall = "{0}/friends/{1}/invited?access_token={2}"; private const string RemoveInviteCall = "{0}/friends/{1}/clear?access_token={2}"; private const string RemoveAllInvitesCall = "{0}/friends/{1}/requests/delete?access_token={2}"; private const string ServerUrl = "https://friends.sparklingsociety.net"; private const string FriendsKey = "friends"; private const string InvitesKey = "invites"; private const string ReadInvitesKey = "readInvites"; private const string BlockedKey = "blocked"; private const string LastUpdatedKey = "lastUpdated"; private const string InvitedKey = "invited"; private IAccessToken _accessToken = new AccessToken(); private IPlayernameController _playernameController; private Dictionary _storage; } }