/// <summary> /// Sets the score for level. /// </summary> /// <param name='user'> /// User to set the new information. /// </param> /// <param name='level'> /// Level. /// </param> /// <param name='scoreToSubmit'> /// Score to submit. -1 if you dont save/overwrite the current score /// </param> /// <param name='starsToSubmit'> /// Stars to submit. -1 if you dont save/overwrite the current stars /// </param> /// <param name='onResultNewRecord'> /// On result new record. /// </param> public void SetScoreForLevel(UserCloud user, int level, int scoreToSubmit, int starsToSubmit, System.Action <UserHasReachedNewRecordDelegateEventArgs> onResultNewRecord = null, bool forceSaveInCloud = true) { if (DisableICloud) { ContinueWithSetScoreForLevel(user, level, scoreToSubmit, starsToSubmit, onResultNewRecord, forceSaveInCloud); return; } ContinueWithSetScoreForLevel(user, level, scoreToSubmit, starsToSubmit, null, false); // First at all, merge user info or download from Cloud if (CurrentCloudUser != null) { this.MergeUsers(result => { ContinueWithSetScoreForLevel(user, level, scoreToSubmit, starsToSubmit, onResultNewRecord, forceSaveInCloud); }); } else { // Download User from cloud and Merge data with local user this.LoadUserFromCloud(result => { ContinueWithSetScoreForLevel(user, level, scoreToSubmit, starsToSubmit, onResultNewRecord, forceSaveInCloud); }); } }
void onAskGiftSuccess(string jsonData) { enabled = true; Debug.Log("Send High Score Cache Service Success"); Dictionary <string, object> data = jsonData.dictionaryFromJson(); if (data.ContainsKey("reward")) { int rewardValue = Convert.ToInt32(data["reward"]); UserManagerCloud.Instance.CurrentUser.UserGoldCoins += rewardValue; UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); GameObject TipObj = GameObject.Find("MFP Gift Panel Portrait/Tip1"); UILabel tipLabel = TipObj.GetComponent <UILabel>(); tipLabel.text = Language.Get("GIFT_SUCCESS_TIP") + "+" + rewardValue.ToString() + Language.Get("MFP_MALL_TAB_DIAMOND"); PopupMessage.Show(Language.Get("GIFT_SUCCESS_TIP") + "+" + rewardValue.ToString() + Language.Get("MFP_MALL_TAB_DIAMOND")); //fsm.SendEvent(NGuiPlayMakerProxy.GetFsmEventEnumValue(NGuiPlayMakerDelegates.OnClickEvent)); } else { GameObject TipObj = GameObject.Find("MFP Gift Panel Portrait/Tip1"); UILabel tipLabel = TipObj.GetComponent <UILabel>(); tipLabel.text = Language.Get("TIP_INVALID_GIFT_CODE"); } }
public void onLoginFinished(string jsonData) { Dictionary <string, object> rootDict = jsonData.dictionaryFromJson(); if (rootDict != null && Convert.ToInt32(rootDict["errno"]) == 0) // success. no error { Debug.Log("360 Login Success"); bool isOk = parseLoginResult(jsonData); Debug.Log("Parse 360 information. Status = " + isOk.ToString()); if (isOk) { PlayerPrefs.SetInt(KEY_360, 1); // set a flag that user already use 360 login string userCacheFile = UserCloud.GetPath(FILE_LOGIN_CACHE); saveTextToFile(userCacheFile, jsonData); } } else { Debug.Log("360 Login Fail"); string userCacheFile = UserCloud.GetPath(FILE_LOGIN_CACHE); string cachedJsonData = loadTextFromFile(userCacheFile); bool isOK = parseLoginResult(cachedJsonData); Debug.Log("Try load 360 information from cache. Status = " + isOK.ToString()); } }
void OnPurchaseSuccess(string id) { purchasing = false; InAppPurchasesSystem.OnPurchaseSuccess -= OnPurchaseSuccess; InAppPurchasesSystem.OnPurchaseFail -= OnPurchaseFail; InAppPurchasesSystem.OnPurchaseCancel -= OnPurchaseFail; InAppProduct product = InAppPurchasesSystem.Instance.GetProduct(id); if (product != null) { #if UNITY_ANDROID AnalyticsBinding.LogEventPaymentAction(product.currencyCode, InAppPurchasesSystem.locale, "-" + product.price, id, 1, "lives_refill", "consumable", "", LoadLevelButton.lastUnlockedLevel); #else float price; if (!float.TryParse(product.price, out price)) { price = 0.99f; } AnalyticsBinding.LogEventPaymentAction(product.currencyCode, InAppPurchasesSystem.locale, -price, id, 1, "lives_refill", "consumable", "", LoadLevelButton.lastUnlockedLevel); #endif } // PlayerPrefs.SetInt(LivesSystem.livesKey, LivesSystem.maxLives); // PlayerPrefs.Save(); UserManagerCloud.Instance.CurrentUser.NumsLiveLeft = LivesSystem.maxLives; UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); LivesSystem.instance.Lives = LivesSystem.maxLives; fsm.SendEvent(sendEvent); }
public void onGetFriendFinished(string jsonData) { Debug.Log("360 SDK Friends: \n" + jsonData); Dictionary <string, object> rootDict = jsonData.dictionaryFromJson(); if (rootDict != null && Convert.ToInt32(rootDict["errno"]) == 0) // success. no error { Debug.Log("360 Get Friend Success"); bool isOk = parseUserFriendResult(jsonData); Debug.Log("Parse 360 Friend. Status = " + isOk.ToString()); if (isOk) { string cacheFile = UserCloud.GetPath(FILE_FRIEND_CACHE); saveTextToFile(cacheFile, jsonData); } } else { Debug.Log("360 Get Friend Fail"); string cacheFile = UserCloud.GetPath(FILE_FRIEND_CACHE); string cachedJsonData = loadTextFromFile(cacheFile); bool isOK = parseUserFriendResult(cachedJsonData); Debug.Log("Try load 360 Friend from cache. Status = " + isOK.ToString()); } }
public object Delete(CloudCombinationResultDTO cloudCombination) { UserCloud cloud = _uow.UserCloud.Find(x => x.Id == cloudCombination.Id).FirstOrDefault(); cloud.IsActive = false; _uow.Complete(); return(new { message = "Konfiguracija uspjesno obrisana" }); }
/// <summary> /// Gets the stars for level. /// </summary> /// <returns> /// The stars for level. -1 if Player doesn't that level /// </returns> /// <param name='user'> /// User to set the stars. /// </param> /// <param name='level'> /// Level. /// </param> public int GetStarsForLevel(UserCloud user, int level) { //Debug.Log("Geting stars" + user.FinishedLevels); if (!user.FinishedLevels.ContainsKey(level.ToString())) { return(-1); } Dictionary <string, object> infoLevel = (Dictionary <string, object>)user.FinishedLevels[level.ToString()]; return(Convert.ToInt32(infoLevel["stars"])); }
public void UpdateButtonStatus() { if (UserManagerCloud.Instance == null) { return; } //lastUnlockedLevel = User.CurrentUser.LastFinishedLvl == maxLevels ? User.CurrentUser.LastFinishedLvl : User.CurrentUser.LastFinishedLvl + 1; UserCloud currentUser = UserManagerCloud.Instance.CurrentUser; lastUnlockedLevel = currentUser.LastFinishedLvl == maxLevels ? currentUser.LastFinishedLvl : currentUser.LastFinishedLvl + 1; if (stars != null) { stars.UpdateStars(this); } if (levelIdx == maxLevels + 1 && maxLevels == lastUnlockedLevel && UserManagerCloud.Instance.GetScoreForLevel(lastUnlockedLevel) > 0) { SetButtonActive(true); //gameObject.SetActive(true); return; } else if (levelIdx > lastUnlockedLevel) { //wenming modify 如果级别关卡大于上次解锁的关卡,则不显示 SetButtonActive(false); // gameObject.SetActive(false); //TODO TALIN: DECOMMENT THIS return; } SetButtonActive(true); // gameObject.SetActive(true); //TODO TALIN: AND THIS! if (Match3BoardRenderer.levelIdx == levelIdx) { CompanionsManager.Instance.UpdateCenterButtonPosition(transform.localPosition); } if (levelIdx == lastUnlockedLevel) { lastButton = this; // Debug.Log("LAST UNLOCKED BUTTON: " + name + " " + transform.parent.name); CompanionsManager.Instance.UpdateAvatarPosition(transform.localPosition, userAvatarPos); if (newUnlockedLevel || Match3BoardRenderer.levelIdx == 0) { CompanionsManager.Instance.UpdateCenterButtonPosition(transform.localPosition); } } else if (newUnlockedLevel && levelIdx == lastUnlockedLevel - 1) { CompanionsManager.Instance.UpdateOldAvatarPosition(transform.localPosition, userAvatarPos); } }
public List <UserCloud> SelectUserClouds(int userId) { string query = "SELECT * FROM user_clouds WHERE user_id = " + userId + ";"; //Console.WriteLine(query); List <UserCloud> cloudList = new List <UserCloud>(); //Create Command if (this.OpenConnection() == true) { MySqlCommand cmd = new MySqlCommand(query, connection); //Create a data reader and Execute the command MySqlDataReader dataReader = cmd.ExecuteReader(); //Read the data and store them in the list while (dataReader.Read()) //TODO: gives only one row? or entire list? { UserCloud userCloud = new UserCloud(); //TODO: Add token expiration to this userCloud.User_id = Int32.Parse(dataReader["user_id"] + ""); userCloud.Cloud_id = Int32.Parse(dataReader["cloud_id"] + ""); userCloud.Cloud_token = dataReader["cloud_token"].ToString(); userCloud.Refresh_token = dataReader["refresh_token"].ToString(); userCloud.Custom_cloud_name = dataReader["custom_cloud_name"].ToString(); cloudList.Add(userCloud); } //close Data Reader dataReader.Close(); //close Connection this.CloseConnection(); //return list to be displayed if (cloudList.Count != 0) { //Console.WriteLine(""); return(cloudList); } else { Console.WriteLine("No userCloud found"); return(cloudList); } } else { Console.WriteLine("Server connection not open"); return(null); } }
public void AddItems(int count) { Debug.Log("Add items: " + count); itemCount += count; twinItem.itemCount += count; UpdateCountLabels(); twinItem.UpdateCountLabels(); if (!temporaryItem) { if (itemPrefab.GetComponent <Snowball>() != null) { UserManagerCloud.Instance.CurrentUser.SnowBall = itemCount; // TokensSystem.Instance.snowballs = itemCount; if (count < 0) { BIModel.Instance.addConsumeData(ItemModel.SNOW_BALL, Match3BoardRenderer.levelIdx); } } else if (itemPrefab.GetComponent <Hourglass>() != null) { UserManagerCloud.Instance.CurrentUser.Hourglass = itemCount; // TokensSystem.Instance.hourglasses = itemCount; if (count < 0) { BIModel.Instance.addConsumeData(ItemModel.HOUR_GLASS, Match3BoardRenderer.levelIdx); } } else if (itemPrefab.GetComponent <IcePick>() != null) { UserManagerCloud.Instance.CurrentUser.IcePick = itemCount; // TokensSystem.Instance.icePicks = itemCount; if (count < 0) { BIModel.Instance.addConsumeData(ItemModel.ICE_PICK, Match3BoardRenderer.levelIdx); } } else { UserManagerCloud.Instance.CurrentUser.MagicPower = itemCount; // TokensSystem.Instance.itemTokens = itemCount; if (count < 0) { BIModel.Instance.addConsumeData(ItemModel.MAGIC_POWER, Match3BoardRenderer.levelIdx); } } UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); //TokensSystem.Instance.SaveItems(); Debug.Log("Saved items"); } }
public void addDiamond(string productId) { foreach (DiamondProductData diamondProduct in ItemModel.Instance.diamondProducts) { if (diamondProduct.productID == productId) { UserManagerCloud.Instance.CurrentUser.UserGoldCoins += diamondProduct.diamondNum; // Update user.data UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); Debug.Log("Purchase has success," + diamondProduct.diamondNum + " diamonds added!"); BIModel.Instance.addOrderData(diamondProduct.price, diamondProduct.diamondNum); } } }
/// <summary> /// Saves the data to disk. /// </summary> /// <param name='onResultSave'> /// Info with result of Save. /// </param> public bool SaveDataToDisk(System.Action <ResultSave> onResultSave = null) { bool result = UserCloud.Serialize(FILE_NAME_LOCAL); if (result && onResultSave != null) { onResultSave(ResultSave.Disk); } else if (!result && onResultSave != null) { onResultSave(ResultSave.NotSaved); } return(result); }
/// <summary> /// Gets the score and stars for level. /// </summary> /// <param name='user'> /// User. /// </param> /// <param name='level'> /// Level. /// </param> /// <param name='score'> /// Score. /// </param> /// <param name='stars'> /// Stars. /// </param> public void GetScoreAndStarsForLevel(UserCloud user, int level, out int score, out int stars) { score = -1; stars = -1; if (!user.FinishedLevels.ContainsKey(level.ToString())) { return; } Dictionary <string, object> infoLevel = (Dictionary <string, object>)user.FinishedLevels[level.ToString()]; //Debug.Log("GetScore And Stars: " + Convert.ToInt32(infoLevel["score"])); score = Convert.ToInt32(infoLevel["score"]); stars = Convert.ToInt32(infoLevel["stars"]); }
/** * 支付完成后 回调的 * 根据返回的码来确定支付是否成功: * 返回值格式为支付状态|额度|其他信息, 比如1|1| 表示购买2元支付成功 * * 支付状态定义如下: * 0:none * 1:success; * 2:failed * 3:cancelled * * 支付额度定义如下: * 1 2元 20钻 * 2 6元 65钻 * 3 10元 110钻 * 4 15元 170钻 */ public void onBillingResult(string result) { Debug.Log("################# BillingResult=" + result); Debug.Log("onBillingResult=" + result); string[] results = result.Split('|'); string paynum = results [1].ToString(); int coin = getGoldCoinByNum(paynum); if (BillingResult.CANCELLED.Equals(results [0])) { // ExitWithUI (); // todo 给予玩家反馈 PopupMessage.Show(Language.Get("IAP_CANCEL")); //MFPBillingAndroid.Instance.ExitWithUI(); Debug.Log(" wenming MFPBillingAndroid onBillingResult CANCEL:" + paynum.ToString()); BiService.log("MFPBillingAndroid onBillingResult CANCEL:" + paynum.ToString()); } else if (BillingResult.SUCCESS.Equals(results [0])) { // todo 给予玩家反馈 UserManagerCloud.Instance.CurrentUser.UserGoldCoins += coin; UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); PopupMessage.Show(Language.Get("IAP_SUCCESS")); Debug.Log(" wenming MFPBillingAndroid onBillingResult SUCCESS:" + paynum.ToString()); BIModel.Instance.addOrderData(getPriceByNum(paynum), coin); } else if (BillingResult.FAILED.Equals(results [0])) { // todo 给予玩家反馈 PopupMessage.Show(Language.Get("IAP_FAILURE")); Debug.Log(" wenming MFPBillingAndroid onBillingResult FAILED:" + paynum.ToString()); BiService.log("MFPBillingAndroid onBillingResult FAILED:" + paynum.ToString()); } else { // todo 给予玩家反馈 PopupMessage.Show(Language.Get("IAP_FAILURE")); Debug.Log(" wenming MFPBillingAndroid onBillingResult EXCEPTION:" + paynum.ToString()); BiService.log("MFPBillingAndroid onBillingResult EXCEPTION:" + paynum.ToString()); } }
void OnClick() { if (LivesSystem.instance.Lives < LivesSystem.maxLives) { if (UserManagerCloud.Instance.CurrentUser.UserGoldCoins >= 20) { // refill energy UserManagerCloud.Instance.CurrentUser.UserGoldCoins -= 20; UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); // PlayerPrefs.SetInt(LivesSystem.livesKey, LivesSystem.maxLives); // PlayerPrefs.Save(); UserManagerCloud.Instance.CurrentUser.NumsLiveLeft = LivesSystem.maxLives; UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); LivesSystem.instance.Lives = LivesSystem.maxLives; BIModel.Instance.addPurchaseData("Lives", LivesSystem.maxLives, 20); fsm.SendEvent(sendEvent); buyLivePanelFsm.SendEvent("NGUI / ON CLICK"); } else { // go to mall MallTab mallTab = GameObject.Find("MallTabButton2").gameObject.GetComponent <MallTab>(); mallTab.OnClick(); buyLivePanelFsm.SendEvent("Other Panel"); mallFsm.SendEvent("Lives"); } } /* * if (purchasing) { * return; * } * * purchasing = true; * * InAppPurchasesSystem.OnPurchaseSuccess += OnPurchaseSuccess; * InAppPurchasesSystem.OnPurchaseFail += OnPurchaseFail; * InAppPurchasesSystem.OnPurchaseCancel += OnPurchaseFail; * InAppPurchasesSystem.Instance.PurchaseProduct(InAppPurchasesSystem.InAppPurchase.Lives); */ }
public object Save(CloudCombinationResultDTO cloudCombination) { UserCloud userCloud = new UserCloud(); userCloud.UserInput = JsonSerializer.Serialize(cloudCombination.CloudCombinationInput); userCloud.User = _uow.Users.Get(cloudCombination.UserId); userCloud.CloudDbSQL = cloudCombination.CloudCombinationResult.CloudDbSQL != null?_uow.CloudDbSQL.Get(cloudCombination.CloudCombinationResult.CloudDbSQL.Id) : null; userCloud.CloudFunction = cloudCombination.CloudCombinationResult.CloudFunction != null?_uow.CloudFunction.Get(cloudCombination.CloudCombinationResult.CloudFunction.Id) : null; userCloud.CloudStorage = cloudCombination.CloudCombinationResult.CloudStorage != null?_uow.CloudStorage.Get(cloudCombination.CloudCombinationResult.CloudStorage.Id) : null; userCloud.CloudVM = cloudCombination.CloudCombinationResult.CloudVM != null?_uow.CloudVM.Get(cloudCombination.CloudCombinationResult.CloudVM.Id) : null; userCloud.IsActive = true; userCloud.Name = cloudCombination.Name; _uow.UserCloud.Add(userCloud); _uow.Complete(); return(new { message = "Combination succesfully saved" }); }
void Update() { if (lives >= maxLives) { return; } long time = TimeSeconds(); /*if (lastUpdateTime != 0 && (time - lastUpdateTime) > 60) * { * waitTime = time; * return; * } */ if (PlayerPrefs.GetInt(timeModifyKey, 0) != 0 && PlayerPrefs.GetInt("cheat", 0) == 0) { Debug.Log("[LivesSystem] time changed. Reset waitTime!"); waitTime = time; UserManagerCloud.Instance.CurrentUser.LivesTime = waitTime; UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); PlayerPrefs.SetInt(timeModifyKey, 0); return; } // Debug.Log("[LivesSystem] time: " + time+", lastUpdateTime: " + lastUpdateTime); lastUpdateTime = time; if (time - waitTime >= lifeRefillTime) { while (lives < maxLives && time - waitTime >= lifeRefillTime) { waitTime += lifeRefillTime; Lives++; Debug.Log("[LivesSystem] Lives added!"); } } else if (time - waitTime < 0) { waitTime = time; } }
public static void SaveLivesAndNotify(int _lives, long _waitTime, bool notifications = true) { Exception e = new Exception(); Debug.Log("[LivesSystem] " + e.ToString()); Debug.Log("[LivesSystem] set UserCloud numsLiveLeft: " + _lives); UserManagerCloud.Instance.CurrentUser.NumsLiveLeft = _lives; UserManagerCloud.Instance.CurrentUser.LivesTime = _waitTime; // PlayerPrefs.SetInt(livesKey, _lives); // PlayerPrefs.SetString(livesTimeKey, _waitTime.ToString()); UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); if (notifications) { NativeMessagesSystem.CancelNotifications(Language.Get("LIVES_NOTIFICATION_MESSAGE")); if (_lives < maxLives) { long showTime = lifeRefillTime * (maxLives - _lives) - (TimeSeconds() - _waitTime); NativeMessagesSystem.ScheduleNotification(Language.Get("LIVES_NOTIFICATION_TITLE"), Language.Get("LIVES_NOTIFICATION_MESSAGE"), showTime); } } }
public bool buyItem(ItemProductData productData) { bool isOK = true; int userDiamondNum = UserManagerCloud.Instance.CurrentUser.UserGoldCoins; if (userDiamondNum >= productData.diamondNum) { UserManagerCloud.Instance.CurrentUser.UserGoldCoins -= productData.diamondNum; if (productData.itemName == ICE_PICK) { UserManagerCloud.Instance.CurrentUser.IcePick += productData.itemNum; } else if (productData.itemName == MAGIC_POWER) { UserManagerCloud.Instance.CurrentUser.MagicPower += productData.itemNum; } else if (productData.itemName == SNOW_BALL) { UserManagerCloud.Instance.CurrentUser.SnowBall += productData.itemNum; } else if (productData.itemName == HOUR_GLASS) { UserManagerCloud.Instance.CurrentUser.Hourglass += productData.itemNum; } // Update user.data UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); BIModel.Instance.addPurchaseData(productData.itemName, productData.itemNum, productData.diamondNum); } else { return(false); } return(true); }
public CloudCombinationResultDTO ChangeName(CloudCombinationResultDTO cloudComb) { UserCloud item = _uow.UserCloud.Find(x => x.Id == cloudComb.Id).FirstOrDefault(); item.Name = cloudComb.Name; _uow.Complete(); CloudCombinationResultDTO temp = new CloudCombinationResultDTO(); CloudCombinationDTO cloudCombinationInput = new CloudCombinationDTO(); CloudCombinationDTO cloudCombinationResult = new CloudCombinationDTO(); cloudCombinationInput = JsonSerializer.Deserialize <CloudCombinationDTO>(item.UserInput); if (item.CloudDbSQL != null) { cloudCombinationResult.CloudDbSQL = item.CloudDbSQL; } if (item.CloudFunction != null) { cloudCombinationResult.CloudFunction = item.CloudFunction; } if (item.CloudStorage != null) { cloudCombinationResult.CloudStorage = item.CloudStorage; } if (item.CloudVM != null) { cloudCombinationResult.CloudVM = item.CloudVM; } temp.CloudCombinationInput = cloudCombinationInput; temp.CloudCombinationResult = cloudCombinationResult; temp.UserId = cloudComb.UserId; temp.Name = item.Name; temp.Id = item.Id; return(temp); }
// Use this for initialization void Awake() { instance = this; lifeRefillTime = TweaksSystem.Instance.intValues["LifeRefillTime"]; //TODO TALIN: very easy to modify this property by the user if it's stored in playerprefs (save to binary file?) // Lives = PlayerPrefs.GetInt(livesKey, maxLives); Lives = UserManagerCloud.Instance.CurrentUser.NumsLiveLeft; Debug.LogWarning("[LivesSystem]Loaded lives: " + lives); long time = TimeSeconds(); // waitTime = System.Math.Min(long.Parse(PlayerPrefs.GetString(livesTimeKey, time.ToString())), time); waitTime = UserManagerCloud.Instance.CurrentUser.LivesTime == 0 ? time : UserManagerCloud.Instance.CurrentUser.LivesTime; //TODO: user modify time to get live. will not charge live. if (PlayerPrefs.HasKey(timeModifyKey)) { Debug.Log("[LivesSystem]The time of system has been modified!!" + PlayerPrefs.GetInt(timeModifyKey)); } else { Debug.Log("[LivesSystem]Cannot get the timeModify flag!"); } if (PlayerPrefs.GetInt(timeModifyKey, 0) != 0 && PlayerPrefs.GetInt("cheat", 0) == 0) { waitTime = TimeSeconds(); UserManagerCloud.Instance.CurrentUser.LivesTime = waitTime; // Update user.data UserCloud.Serialize(UserManagerCloud.FILE_NAME_LOCAL); PlayerPrefs.SetInt(timeModifyKey, 0); } }
/// <summary> /// Merges the users and save the info in Local File and Cloud File. Previously, User from Cloud must be initialized /// </summary> /// <param name='onResult'> /// On result. /// </param> /// <param name='args'> /// Arguments. /// </param> private void MergeUsers(System.Action <UserCloudDownloadDelegateEventArgs> onResult = null) { bool isDirty = false; Debug.Log("- MergeUser 1"); UserCloudDownloadDelegateEventArgs args = new UserCloudDownloadDelegateEventArgs(); if (CurrentCloudUser == null) { Debug.Log("- MergeUser 2"); args.Result = false; args.Message = "MergeUser: User from cloud must be initialized before the Merge"; args.Error = "User from Cloud was not initialized"; this.SaveUserInCloud(); RaiseUserHasBeenDownloaded(args, onResult); return; } //Updating Levels int levelsInCloudUser = CurrentCloudUser.LastFinishedLvl; int levelsInLocalUser = CurrentUser.LastFinishedLvl; Debug.Log("- MergeUser - UserLocal had Level: " + levelsInLocalUser); Debug.Log("- MergeUser - UserCloud had Level: " + levelsInCloudUser); if (levelsInCloudUser > levelsInLocalUser) { CurrentUser.LastFinishedLvl = levelsInCloudUser; isDirty = true; } for (int i = 1; i <= CurrentUser.LastFinishedLvl; i++) { int scoreForLocalUser; int scoreForCloudUser; int starsForLocalUser; int starsForCloudUser; this.GetScoreAndStarsForLevel(CurrentCloudUser, i, out scoreForCloudUser, out starsForCloudUser); this.GetScoreAndStarsForLevel(CurrentUser, i, out scoreForLocalUser, out starsForLocalUser); int winnerScore = scoreForCloudUser > scoreForLocalUser ? scoreForCloudUser : scoreForLocalUser; int winnerStars = starsForCloudUser > starsForLocalUser ? starsForCloudUser : starsForLocalUser; if (winnerScore != scoreForLocalUser || winnerStars != starsForLocalUser) { this.ContinueWithSetScoreForLevel(CurrentUser, i, winnerScore, winnerStars, null, false, i == CurrentUser.LastFinishedLvl); } if (scoreForCloudUser < scoreForLocalUser || starsForCloudUser < starsForLocalUser) { isDirty = true; } } Debug.Log("- MergeUser 4"); //Updating Coins if (CurrentCloudUser.UserGoldCoins > CurrentUser.UserGoldCoins) { CurrentUser.UserGoldCoins = CurrentCloudUser.UserGoldCoins; } else if (CurrentCloudUser.UserGoldCoins < CurrentUser.UserGoldCoins) { isDirty = true; } if (CurrentCloudUser.UserSilverCoins > CurrentUser.UserSilverCoins) { CurrentUser.UserSilverCoins = CurrentCloudUser.UserSilverCoins; } else if (CurrentCloudUser.UserSilverCoins < CurrentUser.UserSilverCoins) { isDirty = true; } //Updating Lives // if (CurrentCloudUser.NumsLiveLeft > CurrentUser.NumsLiveLeft) // { // isDirty = true; // CurrentUser.NumsLiveLeft = CurrentCloudUser.NumsLiveLeft; // } //Once finished Merging, both instance must be the same CurrentCloudUser = CurrentUser; //Raise the event args.Error = string.Empty; args.Message = "MergeUser: User has been downloaded"; args.Result = true; RaiseUserHasBeenDownloaded(args, onResult); if (onResult != null) { onResult(args); } // IsUserInit = true; Debug.Log(" - MergeUser. Level: " + CurrentUser.LastFinishedLvl); bool isPossibleToSaveInCloud = this.SaveDataToDisk(); if (isDirty && isPossibleToSaveInCloud) { this.SaveUserInCloud(); } }
private IEnumerator DownloadFromCloudByCheckingConflicts(System.Action <UserCloudDownloadDelegateEventArgs> onResul = null) { #if UNITY_IPHONE || UNITY_EDITOR JCloudDocumentOperation operation; // Let's check file for conflict first operation = JCloudDocument.FileHasConflictVersions(FILE_NAME_CLOUD); while (operation.finished == false) { yield return(null); // Wait for 1 frame } // Look for error -- if any, handle & stop coroutine here -- ignore cloud unvailable as it simply means conflicts are not handled if (operation.error.HasValue && operation.error.Value != JCloudDocumentError.CloudUnavailable) { HandleDocumentError(operation.error.Value, onResul); yield break; } // Did looking for conflict trigger a result? if (((bool?)operation.result).HasValue && (bool)operation.result == true) { // We have conflicts -- sort them out operation = JCloudDocument.FileFetchAllVersions(FILE_NAME_CLOUD); while (operation.finished == false) { yield return(null); } // Look for error -- if any, handle & stop coroutine here if (operation.error.HasValue) { HandleDocumentError(operation.error.Value, onResul); yield break; } // Get conflict versions JCloudDocumentVersions versions = (JCloudDocumentVersions)operation.result; // We will now attempt to pick the "best" version (e.g. most progress) -- you could offer UI UserCloud temporalUser; int lastLevelTemporalUser = -1; byte[] bestVersionIdentifier = null; foreach (JCloudDocumentVersionMetadata metadata in versions.versionsMetadata) { // Read version bytes operation = JCloudDocument.FileReadVersionBytes(FILE_NAME_CLOUD, metadata.uniqueIdentifier); while (operation.finished == false) { yield return(null); } // Look for error -- if any, handle & stop coroutine here if (operation.error.HasValue) { HandleDocumentError(operation.error.Value, onResul); yield break; } // Pick best version temporalUser = UserCloud.Deserialize((byte[])operation.result); if (temporalUser == null) { continue; } if (temporalUser.LastFinishedLvl > lastLevelTemporalUser) { lastLevelTemporalUser = temporalUser.LastFinishedLvl; bestVersionIdentifier = metadata.uniqueIdentifier; } } // At that point we should have the best version if (bestVersionIdentifier != null) { // Pick it as current version operation = JCloudDocument.FilePickVersion(FILE_NAME_CLOUD, bestVersionIdentifier, versions.versionsHash); while (operation.finished == false) { yield return(null); } // Look for error -- if any, handle & stop coroutine here if (operation.error.HasValue) { HandleDocumentError(operation.error.Value, onResul); yield break; } } } // At that point conflicts have been cleared -- wait for file reading operation = JCloudDocument.FileReadAllBytes(FILE_NAME_CLOUD); while (operation.finished == false) { yield return(null); // Wait for 1 frame } // Look for error -- if any, handle & stop coroutine here if (operation.error.HasValue) { HandleDocumentError(operation.error.Value, onResul); yield break; } byte[] bytes = operation.result as byte[]; if (bytes != null) { //Save iCloud info in Memory. Then, merge information with local user data Debug.Log("- LoadUserFromCloud OK"); CurrentCloudUser = UserCloud.Deserialize(bytes); this.MergeUsers(onResul); } #endif #if UNITY_ANDROID && !disableGoogleCloud byte[] googleCloudDataBytes = null; if (CanUseGoogleCloud()) { while (!PlayGameServices.isSignedIn() && googleCloudTryingToLogin) { yield return(null); // Wait for n frames until googleCloudTryingToLogin was setted to FALSE } if (!PlayGameServices.isSignedIn() && !googleCloudTryingToLogin) { HandleDocumentError(JCloudDocumentError.CloudUnavailable, onResul); yield break; } Debug.Log("[UserManagerCloud] DownloadFromCloudByCheckingConflicts(): Downloading user data from cloud..."); PlayGameServices.loadCloudDataForKey(0, false); // Wait a maximum of 6 seconds to retrieve google cloud data float timeLeftToWait = 6f; float lastTime = Time.realtimeSinceStartup; while (googleCloudData == null && timeLeftToWait > 0f) { timeLeftToWait -= Time.realtimeSinceStartup - lastTime; lastTime = Time.realtimeSinceStartup; yield return(null); // Wait for n frames until googleCloudData was setted in loadCloudDataForKeyFailedEvent or loadCloudDataForKeySucceededEvent } if (googleCloudData == "ERROR" || googleCloudData == null) { Debug.Log("ANDROID CLOUD SERVICES RETURNED ERROR DOWNLOADING"); HandleDocumentError(JCloudDocumentError.DocumentNotFound, onResul); yield break; } Debug.Log("[UserManagerCloud] There is google cloud data : " + googleCloudData.Length); try { googleCloudDataBytes = System.Convert.FromBase64String(googleCloudData); Debug.Log("[UserManagerCloud] Cloud data size: " + googleCloudDataBytes.Length); } catch (Exception) { Debug.LogWarning("[UserManagerCloud] Failed to decode android cloud data: " + googleCloudData); } } CurrentCloudUser = UserCloud.Deserialize(googleCloudDataBytes); MergeUsers(onResul); //Free memory googleCloudData = null; #endif yield break; }
private IEnumerator SaveInCloud(System.Action <UserCloudUploadedDelegateEventArgs> onResultSave = null) { Debug.Log("Saving in the Cloud"); UserCloudUploadedDelegateEventArgs args = new UserCloudUploadedDelegateEventArgs(); bool isPossibleSaveInCloud = true; byte[] bytes = null; string errorReadingLocalData = string.Empty; try { bytes = System.IO.File.ReadAllBytes(UserCloud.GetPath(FILE_NAME_LOCAL)); Debug.Log("[UserManagerCloud] Loaded local file user data: " + UserCloud.GetPath(FILE_NAME_LOCAL)); } catch (Exception ex) { Debug.LogWarning("[SaveInCloud] Error reading local user data file..."); isPossibleSaveInCloud = false; errorReadingLocalData = ex.Message; } if (isPossibleSaveInCloud == false) { Debug.LogWarning("Exception reading local user before save it: " + errorReadingLocalData); args.Error = errorReadingLocalData; args.Message = "There was an error saving to iCloud"; args.Result = false; args.SaveIn = ResultSave.NotSaved; RaiseUserHasBeenUploaded(args, onResultSave); yield break; } #if UNITY_IPHONE || UNITY_EDITOR JCloudDocumentOperation op = JCloudDocument.FileWriteAllBytes(FILE_NAME_CLOUD, bytes); while (op.finished == false) { Debug.Log("[SaveInCloud] Writting user data to cloud: " + op.progress); yield return(null); } if (op.error.HasValue) { string res = ""; switch (op.error.Value) { case JCloudDocumentError.PluginError: case JCloudDocumentError.NativeError: case JCloudDocumentError.InvalidArguments: // Look out for this one as it means you passed invalid path // Offer the user to retry res = "An error ocurred while saving text file. please retry."; Debug.LogWarning("[SaveInCloud] " + res); break; case JCloudDocumentError.DocumentNotFound: res = "There is no file present on this device. Create a new text file."; Debug.LogWarning("[SaveInCloud] " + res); break; case JCloudDocumentError.DownloadTimeout: // Offer the user to retry res = "Could not download user cloud file. Please retry."; Debug.LogWarning("[SaveInCloud] " + res); break; default: // We should never get there break; } Debug.LogWarning("[SaveInCloud] " + op.error.Value); args.Error = res; args.Message = "There was an error saving to iCloud"; args.Result = false; args.ErrorType = op.error.Value; args.SaveIn = ResultSave.NotSaved; RaiseUserHasBeenUploaded(args, onResultSave); } else { // OK Debug.Log("[SaveInCloud] Saved user file in cloud " + bytes.Length + " bytes"); args.Error = string.Empty; args.Message = "Saved in iCloud"; args.Result = true; args.SaveIn = ResultSave.Cloud; Debug.Log("[SaveInCloud] - SaveUser. Level: " + CurrentUser.LastFinishedLvl); RaiseUserHasBeenUploaded(args, onResultSave); } yield break; // byte[] bytes = System.IO.File.ReadAllBytes(UserCloud.GetPath(FILE_NAME_LOCAL)); // JCloudDocument.FileWriteAllBytes(FILE_NAME_CLOUD, bytes); // //// UserCloudUploadedDelegateEventArgs args = new UserCloudUploadedDelegateEventArgs(); //// //// if (onResultSave != null) //// onResultSave(ResultSave.Cloud); // // Debug.Log("Save File in Cloud " + bytes.Length); // yield break; #elif UNITY_ANDROID && !disableGoogleCloud if (CanUseGoogleCloud()) { while (!PlayGameServices.isSignedIn() && googleCloudTryingToLogin) { yield return(null); } if (PlayGameServices.isSignedIn() && !googleCloudTryingToLogin) { string strUserData = null; try { strUserData = System.Convert.ToBase64String(bytes); Debug.Log("[UserManagerCloud] Saving to Google Cloud services: " + bytes.Length + " bytes"); } catch (Exception) { Debug.LogWarning("[UserManagerCloud] Failed to encode user raw bytes to string. Size: " + bytes.Length + " bytes"); } if (strUserData != null) { PlayGameServices.setStateData(strUserData, 0); } } } yield break; #endif }
private void ContinueWithSetScoreForLevel(UserCloud user, int level, int scoreToSubmit, int starsToSubmit, System.Action <UserHasReachedNewRecordDelegateEventArgs> onResultNewRecord = null, bool forceSaveInCloud = true, bool saveToDisk = true) { Dictionary <string, object> infoLevel; int currentScore = this.GetScoreForLevel(user, level); int currentStars = this.GetStarsForLevel(user, level); bool isNeededUpdateScore = false; bool isNeededUpdateStars = false; if (currentScore < scoreToSubmit) { isNeededUpdateScore = true; } if (currentStars < starsToSubmit) { isNeededUpdateStars = true; } //Save the score if (scoreToSubmit > -1 && isNeededUpdateScore) { if (user.FinishedLevels.ContainsKey(level.ToString())) { infoLevel = (Dictionary <string, object>)user.FinishedLevels[level.ToString()]; infoLevel["score"] = scoreToSubmit; } else { infoLevel = new Dictionary <string, object>(); infoLevel["score"] = scoreToSubmit; infoLevel["stars"] = 0; user.FinishedLevels.Add(level.ToString(), infoLevel); } // [JianYu]: cache high score data, send them to server some time HighScoreModel.Instance.updateHighScoreCache(level, scoreToSubmit); } //Save the stars if (starsToSubmit > -1 && isNeededUpdateStars) { if (user.FinishedLevels.ContainsKey(level.ToString())) { infoLevel = (Dictionary <string, object>)user.FinishedLevels[level.ToString()]; infoLevel["stars"] = starsToSubmit; } else { infoLevel = new Dictionary <string, object>(); infoLevel["score"] = 0; infoLevel["stars"] = starsToSubmit; user.FinishedLevels.Add(level.ToString(), infoLevel); } } if (level > CurrentUser.LastFinishedLvl) { // wenming update data to 360 UserSNSManager.Instance.UploadData("360", level.ToString()); CurrentUser.LastFinishedLvl = level; } if (saveToDisk) { //user.SaveInDisk(); Debug.Log("Saving scores to disk"); bool isPossibleToSaveInCloud = true; isPossibleToSaveInCloud = this.SaveDataToDisk(); if (forceSaveInCloud && !DisableICloud && isPossibleToSaveInCloud) { this.SaveUserInCloud(); } } UserHasReachedNewRecordDelegateEventArgs e = new UserHasReachedNewRecordDelegateEventArgs(); if (isNeededUpdateScore || isNeededUpdateStars) { e.Level = level; e.Score = scoreToSubmit; e.Result = RecordType.Stars; if (isNeededUpdateScore && isNeededUpdateStars) { e.Result = RecordType.ScoreAndStars; } else if (isNeededUpdateScore) { e.Result = RecordType.Score; } e.Message = "User has reached a new record"; } else { e.Level = level; e.Score = scoreToSubmit; e.Result = RecordType.None; e.Message = "User has not reached a new record"; } RaiseUserHasReachedNewRecord(e, onResultNewRecord); //Debug.Log("SetScoreForLevel -> Score: " + scoreToSubmit + " for level: " + level); }
public static UserCloud Deserialize(byte[] data = null) { bool detailedLog = true; Stream str = null; // CryptoStream crStream = null; BinaryReader readStream = null; try { UserCloud nUser = new UserCloud(); // float timeStart = Time.realtimeSinceStartup; if (data == null) { string path = GetPath(UserManagerCloud.FILE_NAME_LOCAL); Debug.Log("Load user data from local file: " + path); if (!File.Exists(path)) { return(null); } str = File.OpenRead(path); } else { str = new MemoryStream(data); Debug.Log("Load user data from data! "); } // DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider(); // cryptic.Mode = CipherMode.ECB; // cryptic.Key = System.Text.Encoding.UTF8.GetBytes(TweaksSystem.CRYPTO_KEY); // // crStream = new CryptoStream(str, cryptic.CreateDecryptor(), CryptoStreamMode.Read); // // using (readStream = new BinaryReader(crStream)) using (readStream = new BinaryReader(str)) { float versionFile = readStream.ReadSingle(); if (detailedLog) { Debug.Log("File version " + versionFile); } /*if (versionFile < USER_DATA_VERSION) * { * Debug.LogWarning("[Deserialize] Trying to load older user data file!"); * * if (data != null) * { * return nUser; * } * return null; * }*/ nUser.UserGoldCoins = readStream.ReadInt32(); // nUser.UserGoldCoins = 1000; if (detailedLog) { Debug.Log("Gold coins " + nUser.UserGoldCoins); } nUser.UserSilverCoins = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Silver coins " + nUser.UserSilverCoins); } nUser.NumsLiveLeft = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Lives left " + nUser.NumsLiveLeft); } nUser.LastFinishedLvl = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Last finished level " + nUser.LastFinishedLvl); } Dictionary <string, object> levels = new Dictionary <string, object>(); int countLevels = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Finished levels count " + countLevels); } for (int i = 0; i < countLevels; i++) { string keyLevel = readStream.ReadString(); if (detailedLog) { Debug.Log("Level key: " + keyLevel); } Dictionary <string, object> levelInfo = new Dictionary <string, object>(); int countLevelInfo = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Level dict count: " + countLevelInfo); } for (int j = 0; j < countLevelInfo; j++) { string keyLevelInfo = readStream.ReadString(); if (detailedLog) { Debug.Log("Level info key: " + keyLevelInfo); } int valueLevelInfo = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Level info value: " + valueLevelInfo); } levelInfo.Add(keyLevelInfo, valueLevelInfo); } levels.Add(keyLevel, levelInfo); } nUser.FinishedLevels = levels; // [JianYu]: add codes for loading items nUser.SnowBall = readStream.ReadInt32(); nUser.Hourglass = readStream.ReadInt32(); nUser.IcePick = readStream.ReadInt32(); nUser.MagicPower = readStream.ReadInt32(); nUser.UpdateAt = new DateTime(readStream.ReadInt64()); if (detailedLog) { Debug.Log("Ticks: " + nUser.UpdateAt.Ticks); } if (versionFile > 3.0f) { string md5Data = readStream.ReadString(); // Create a StringComparer an compare the hashes. StringComparer comparer = StringComparer.OrdinalIgnoreCase; nUser.MaxLives = readStream.ReadInt32(); nUser.LivesTime = long.Parse(readStream.ReadString()); if (0 != comparer.Compare(md5Data, nUser.md5Data)) { nUser = null; } else { LivesSystem.maxLives = nUser.MaxLives; } } else { nUser.NumsLiveLeft = 5; //PlayerPrefs.GetInt("Lives", 5); } readStream.Close(); } str.Close(); // float durationTime = Time.realtimeSinceStartup - timeStart; // Debug.Log(" =>Ecrypt Deserialization Time: " + durationTime * 1000); return(nUser); } catch (Exception e) { Debug.LogWarning(e.Message + "\nUser Data saved in disk was corrupted. One or more fields were added."); Debug.LogWarning(e.StackTrace); return(null); } finally { if (detailedLog) { Debug.Log("[Deserialize] Closing possible open streams..."); } if (readStream != null) { if (detailedLog) { Debug.Log("Closing readStream stream..."); } readStream.Close(); } // if (crStream != null) // { // Debug.Log("Closing crStream stream..."); // crStream.Close(); // } if (str != null) { if (detailedLog) { Debug.Log("Closing str stream..."); } str.Close(); } } }
public static UserCloud Deserialize(byte[] data = null) { bool detailedLog = true; Stream str = null; // CryptoStream crStream = null; BinaryReader readStream = null; try { UserCloud nUser = new UserCloud(); // float timeStart = Time.realtimeSinceStartup; if (data == null) { string path = GetPath(UserManagerCloud.FILE_NAME_LOCAL); Debug.Log("Load user data from local file: " + path); if (!File.Exists(path)) return null; str = File.OpenRead(path); } else { str = new MemoryStream(data); Debug.Log("Load user data from data! "); } // DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider(); // cryptic.Mode = CipherMode.ECB; // cryptic.Key = System.Text.Encoding.UTF8.GetBytes(TweaksSystem.CRYPTO_KEY); // // crStream = new CryptoStream(str, cryptic.CreateDecryptor(), CryptoStreamMode.Read); // // using (readStream = new BinaryReader(crStream)) using (readStream = new BinaryReader(str)) { float versionFile = readStream.ReadSingle(); if (detailedLog) { Debug.Log("File version " + versionFile); } /*if (versionFile < USER_DATA_VERSION) { Debug.LogWarning("[Deserialize] Trying to load older user data file!"); if (data != null) { return nUser; } return null; }*/ nUser.UserGoldCoins = readStream.ReadInt32(); // nUser.UserGoldCoins = 1000; if (detailedLog) { Debug.Log("Gold coins " + nUser.UserGoldCoins); } nUser.UserSilverCoins = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Silver coins " + nUser.UserSilverCoins); } nUser.NumsLiveLeft = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Lives left " + nUser.NumsLiveLeft); } nUser.LastFinishedLvl = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Last finished level " + nUser.LastFinishedLvl); } Dictionary<string, object> levels = new Dictionary<string, object>(); int countLevels = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Finished levels count " + countLevels); } for (int i = 0; i < countLevels; i++) { string keyLevel = readStream.ReadString(); if (detailedLog) { Debug.Log("Level key: " + keyLevel); } Dictionary<string, object> levelInfo = new Dictionary<string, object>(); int countLevelInfo = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Level dict count: " + countLevelInfo); } for (int j = 0; j < countLevelInfo; j++) { string keyLevelInfo = readStream.ReadString(); if (detailedLog) { Debug.Log("Level info key: " + keyLevelInfo); } int valueLevelInfo = readStream.ReadInt32(); if (detailedLog) { Debug.Log("Level info value: " + valueLevelInfo); } levelInfo.Add(keyLevelInfo, valueLevelInfo); } levels.Add(keyLevel, levelInfo); } nUser.FinishedLevels = levels; // [JianYu]: add codes for loading items nUser.SnowBall = readStream.ReadInt32(); nUser.Hourglass = readStream.ReadInt32(); nUser.IcePick = readStream.ReadInt32(); nUser.MagicPower = readStream.ReadInt32(); nUser.UpdateAt = new DateTime(readStream.ReadInt64()); if (detailedLog) { Debug.Log("Ticks: " + nUser.UpdateAt.Ticks); } if (versionFile > 3.0f) { string md5Data = readStream.ReadString(); // Create a StringComparer an compare the hashes. StringComparer comparer = StringComparer.OrdinalIgnoreCase; nUser.MaxLives = readStream.ReadInt32(); nUser.LivesTime = long.Parse(readStream.ReadString()); if (0 != comparer.Compare(md5Data, nUser.md5Data) ) { nUser = null; } else { LivesSystem.maxLives = nUser.MaxLives; } } else { nUser.NumsLiveLeft = 5; //PlayerPrefs.GetInt("Lives", 5); } readStream.Close(); } str.Close(); // float durationTime = Time.realtimeSinceStartup - timeStart; // Debug.Log(" =>Ecrypt Deserialization Time: " + durationTime * 1000); return nUser; } catch (Exception e) { Debug.LogWarning(e.Message + "\nUser Data saved in disk was corrupted. One or more fields were added."); Debug.LogWarning(e.StackTrace); return null; } finally { if (detailedLog) { Debug.Log("[Deserialize] Closing possible open streams..."); } if (readStream != null) { if (detailedLog) { Debug.Log("Closing readStream stream..."); } readStream.Close(); } // if (crStream != null) // { // Debug.Log("Closing crStream stream..."); // crStream.Close(); // } if (str != null) { if (detailedLog) { Debug.Log("Closing str stream..."); } str.Close(); } } }