public void QueueScore(string key, long value, string desc) { if (Application.isEditor) { //ConDebug.Log($"Editor Mode: Try to queue score... {key}: {value} ({desc})"); } long oldValue = 0; if (successfullyReportedScoreDict.TryGetValue(key, out oldValue) && oldValue == value) { // 앱이 실행된 이후 성공적으로 등록했던 점수와 동일하다면 다시 할 필요는 없다. } else { if (BlackContext.instance.CheatMode) { if (notifyCheatModeOnlyOnce == false) { ConDebug.Log("### Cheat Mode was turned on (notified only at the first time)"); ConDebug.Log($"ReportScore: {key}: {value} ({desc})"); notifyCheatModeOnlyOnce = true; } return; } queuedScoreDict[key] = value; } }
internal static void DeleteSaveFileAndReloadScene() { // From MSDN: If the file to be deleted does not exist, no exception is thrown. ConDebug.Log("DeleteSaveFileAndReloadScene"); DeleteAllSaveFiles(); Splash.LoadSplashScene(); }
IEnumerator Start() { while (true) { yield return(new WaitForSeconds(3.0f)); // 1초 간격으로 리포트하니까 그 사이 queuedScoreDict가 바뀌어 있을 수도 있다. // 복사해서 써야한다. foreach (var kv in new Dictionary <string, long>(queuedScoreDict)) { ConDebug.Log($"Social.ReportScore {kv.Key}: {kv.Value}..."); if (!Application.isEditor) { Social.ReportScore(kv.Value, kv.Key, success => { ConDebug.Log($"Social.ReportScore {kv.Key}: {kv.Value} (Result:{success})"); if (success) { successfullyReportedScoreDict[kv.Key] = kv.Value; } }); } else { ConDebug.Log($"Social.ReportScore {kv.Key}: {kv.Value} (Result:EDITOR MODE)"); successfullyReportedScoreDict[kv.Key] = kv.Value; } yield return(new WaitForSeconds(1.0f)); } queuedScoreDict.Clear(); } }
void Update() { if (Keyboard.current[Key.F8].wasReleasedThisFrame) { if (scanOnce == false) { scanOnce = true; foreach (var rootGo in SceneManager.GetActiveScene().GetRootGameObjects()) { foreach (var comp in rootGo.GetComponentsInChildren <DeactivateOnLiveBuild>()) { comp.gameObject.SetActive(false); } foreach (var comp in rootGo.GetComponentsInChildren <HideOnLiveBuild>()) { comp.Hide(); } } } ScreenCapture.CaptureScreenshot(filename); ConDebug.Log($"Screenshot saved to {filename}"); } }
void ExecuteBackgroundTimeCompensationImmediatelyOrDelayed() { // 네트워크 시각이 이 시점(프로그램이 백그라운드에서 막 되살아난 시점)에서 networkTime.OnApplicationPause()의 호출이 완료되어 // 재조회가 완료되어 있으면 참 좋겠지만, 대부분 아닐 것이다. // 그렇다면 바로 백그라운드 시간 보상을 해 줄 수 있고, 아니라면 좀 나중에 해야 한다. if (focusLostNetworkTimeRequestSequence != networkTime.RequestSequence && networkTime.State == NetworkTime.QueryState.NoError) { // 백그라운드 모드를 잘 다녀왔고, 다녀오고 재조회까지 신속히 정상 완료 됐다면 이 경우다. ExecuteBackgroundTimeCompensation(GetBackgroundDurationUsec()); } else if (onApplicationPauseCalled == false && networkTime.State == NetworkTime.QueryState.NoError) { // <see cref="BackgroundTimeCompensator"/>가 인정할 때는 백그라운드 상태가 있었지만, // 실제로 네트워크 타임을 재조회할 필요가 없는 상태다. (왜냐면 <see cref="BackgroundTimeCompensator.OnApplicationPause(bool)"/>가 호출되지 않았기 때문에) // 이 경우도 실제로 흐른 시간 만큼 보상 해 주면 된다. ExecuteBackgroundTimeCompensation(GetBackgroundDurationUsec()); } else { // 네트워크 시간 재조회가 필요하지만 아직은 안됐다. // 기다렸다 네트워크 시간 재조회가 되면 하자. ConDebug.Log("Background time compensation delayed since renewed network time not received yet."); pendingBackgroundTimeCompensation = true; } }
static void WriteStringDataToTextFile(string path, Dictionary <ScString, StrBaseData> strData, bool appendAscii, float progress) { EditorUtility.DisplayProgressBar("Reload Data", path, progress); ConDebug.Log($"Writing {path}..."); StringBuilder sb = new StringBuilder(); var orderedKeys = strData.Keys.OrderBy(NormalizeLineEndings, System.StringComparer.Ordinal); foreach (var k in orderedKeys) { foreach (var s in strData[k].str) { if (s != null && s.ToString().Length > 0) { string normalized = NormalizeLineEndings(s.ToString()); sb.AppendLine(normalized.Replace("\r\n", @"\n")); } } } if (appendAscii) { // 0x20: Blank character // 0x7e: ~ // 0x7f: [Delete] character (special character) sb.AppendLine(string.Concat(Enumerable.Range('\x20', '\x7e' - '\x20' + 1).Select(e => (char)e))); } File.WriteAllText(path, sb.ToString()); }
static async Task PrebuildDependentDataSetAsync(DataSet newDataSet) { var stageAssetLocList = await Addressables.LoadResourceLocationsAsync("Stage", typeof(StageMetadata)).Task; newDataSet.StageMetadataLocDict = stageAssetLocList.ToDictionary(e => e.PrimaryKey, e => e); newDataSet.StageMetadataLocList = new List <IResourceLocation>(); foreach (var seq in newDataSet.StageSequenceData) { if (newDataSet.StageMetadataLocDict.TryGetValue(seq.stageName, out var stageMetadata)) { if (Verbose) { ConDebug.Log($"Stage: {seq.stageName} - {stageMetadata}"); } newDataSet.StageMetadataLocList.Add(stageMetadata); } else { Debug.LogError($"Stage metadata with name {seq.stageName} not found."); newDataSet.StageMetadataLocList.Add(null); } } }
static void PrintGoldRate(string goldRateBigIntStr) { if (BigInteger.TryParse(goldRateBigIntStr, out var n)) { //var n = BigInteger.Parse("256"); ConDebug.Log(n.ToString("n0")); var nb = n.ToByteArray(); var level = 0; foreach (var t in nb) { for (var j = 0; j < 8; j++) { level++; if (((t >> j) & 1) == 1) { ConDebug.Log($"Level {level} = {BigInteger.One << (level - 1):n0}/s"); } } } } else { Debug.LogError("Invalid number format"); } }
public static void WriteLine(string s) { #if UNITY_2020 ConDebug.Log(s); #else Logger.WriteLine(s); #endif }
public void PushAction(Action action) { stack.Push(action); if (Verbose) { ConDebug.Log($"BackButtonHandler pushed: {stack.Count} actions stacked."); } }
void ExecuteTopAction() { stack.Peek()(); if (Verbose) { ConDebug.Log("BackButtonHandler execute top action."); } }
public void PopAction() { stack.Pop(); if (Verbose) { ConDebug.Log($"BackButtonHandler popped: {stack.Count} actions stacked."); } }
public async Task LoadPlayLogAsync(string playLogCode) { var saveDbUrl = ConfigPopup.BaseUrl + "/playLog"; ProgressMessage.instance.Open("Loading play log"); playLogCode = playLogCode.Trim(); var url = string.Format("{0}/{1}", saveDbUrl, playLogCode); ConDebug.LogFormat("URL: {0}", url); try { using (var httpClient = new HttpClient()) { var getTask = await httpClient.GetAsync(url); if (getTask.IsSuccessStatusCode) { var text = await getTask.Content.ReadAsStringAsync(); var userPlayLogDataRoot = Json.Deserialize(text) as Dict; var userPlayLogDataFields = userPlayLogDataRoot["fields"] as Dict; var userPlayLogDataFieldsSaveData = userPlayLogDataFields["playLogData"] as Dict; var userPlayLogDataFieldsSaveDataStringValue = userPlayLogDataFieldsSaveData["bytesValue"] as string; var userPlayLogUncompressedSizeData = userPlayLogDataFields["playLogUncompressedSizeData"] as Dict; var userPlayLogUncompressedSizeDataIntegerValue = int.Parse(userPlayLogUncompressedSizeData["integerValue"] as string); var playLogDataBase64 = userPlayLogDataFieldsSaveDataStringValue; var playLogData = Convert.FromBase64String(playLogDataBase64); var playLogUncompressedData = new byte[userPlayLogUncompressedSizeDataIntegerValue]; LZ4Codec.Decode(playLogData, 0, playLogData.Length, playLogUncompressedData, 0, playLogUncompressedData.Length); readLogStream = new MemoryStream(playLogUncompressedData); ConDebug.LogFormat("Play Log Data Base64 ({0} bytes): {1}", playLogDataBase64 != null ? playLogDataBase64.Length : 0, playLogDataBase64); ConDebug.LogFormat("Play Log Data ({0} bytes - compresseed)", playLogData.Length); } else { Debug.LogError($"Loading play log failed - status code {getTask.StatusCode}"); } } } catch (Exception e) { Debug.LogError($"Play log upload exception: {e}"); } finally { // 어떤 경우가 됐든지 마지막으로는 진행 상황 창을 닫아야 한다. ProgressMessage.instance.Close(); } }
// 저장 슬롯 증가 (성공적인 저장 후 항상 1씩 증가되어야 함) public static void IncreaseSaveDataSlotAndWrite() { var oldSaveDataSlot = GetSaveSlot(); var newSaveDataSlot = PositiveMod(oldSaveDataSlot + 1, maxSaveDataSlot); ConDebug.Log($"Increase save data slot from {oldSaveDataSlot} to {newSaveDataSlot}..."); PlayerPrefs.SetInt(saveDataSlotKey, newSaveDataSlot); PlayerPrefs.Save(); ConDebug.Log($"Increase save data slot from {oldSaveDataSlot} to {newSaveDataSlot}... OKAY"); }
public async void OnClick() { Sound.instance.PlayButtonClick(); var lastClearedStageId = BlackContext.instance.LastClearedStageId; ConDebug.Log($"Last Cleared Stage ID: {lastClearedStageId}"); await stageDetailPopup.OpenPopupAfterLoadingAsync(lastClearedStageId); }
void SaveWipStageData(string stageName, HashSet <uint> coloredMinPoints, float remainTime) { ConDebug.Log($"Saving save data for '{stageName}'..."); InitializeMessagePackConditional(); var bytes = MessagePackSerializer.Serialize( CreateWipStageSaveData(stageName, coloredMinPoints, remainTime, null), Data.DefaultOptions); FileUtil.SaveAtomically(GetStageSaveFileName(stageName), bytes); }
public void OnPaletteChange(int paletteButtonIndex) { if (Verbose) { ConDebug.Log($"Palette Change Notification {paletteButtonIndex}"); } // 셰이더 상 팔레트 인덱스는 0번째가 외곽선 용이다. 하나 더해서 넘겨줘야한다. singlePaletteRenderer.SetPaletteIndex(paletteButtonIndex + 1); }
static void ReloadDataSafe(ICollection <string> xlsxList, bool force) { if (xlsxList.Count == 0) { Debug.Log("Already up-to-date."); return; } var dataSet = new DataSet(); if (force == false) { EditorUtility.DisplayProgressBar("Reload Data", "Loading the previous DataSet", 0); dataSet = Data.LoadSharedDataSet(); } var csvForDiffPath = Path.Combine("Data", "CsvForDiff"); Directory.CreateDirectory(csvForDiffPath); var xlsxIndex = 0; foreach (var xlsx in xlsxList) { ConDebug.Log($"Loading {xlsx}..."); EditorUtility.DisplayProgressBar("Reload Data", xlsx, (xlsxIndex + 1.0f) / xlsxList.Count); var tableList = new ExcelToObject.TableList(xlsx); tableList.MapInto(dataSet); xlsxIndex++; Xlsx2Csv20.Xlsx2Csv.Convert(xlsx, Path.Combine(csvForDiffPath, Path.GetFileNameWithoutExtension(xlsx) + ".csv")); } // 번역되는 텍스트는 diff를 쉽게 볼 수 있도록 텍스트파일로도 쓴다. WriteStringDataToTextFile(Path.Combine("Data", "StrKoData.txt"), dataSet.StrKoData, true, 0.2f); WriteStringDataToTextFile(Path.Combine("Data", "StrEnData.txt"), dataSet.StrEnData, true, 1.0f); ConDebug.Log($"{dataSet.StageSequenceData.Count} entries on StageSequenceData"); EditorUtility.DisplayProgressBar("Reload Data", "Serializing and writing...", 0.0f); SerializeAndWriteDataSet(dataSet); EditorUtility.ClearProgressBar(); if (force == false) { Debug.Log("Updated Xlsx List"); foreach (var xlsx in xlsxList) { Debug.Log($"- {xlsx}"); } } }
public static PlatformNotificationRequest GetPlatformNotificationRequest() { if (BlackContext.instance == null) { Debug.LogError( $"RegisterAllRepeatingNotifications(): {nameof(BlackContext)}.{nameof(BlackContext.instance)} is null. Abort."); return(null); } if (Data.dataSet == null) { Debug.LogError( $"RegisterAllRepeatingNotifications(): {nameof(Data)}.{nameof(Data.dataSet)} is null. Abort."); return(null); } if (BlackContext.instance.LastDailyRewardRedeemedIndex < Data.dataSet.DailyRewardData.Count) { var data = Data.dataSet.DailyRewardData[(int)BlackContext.instance.LastDailyRewardRedeemedIndex.ToLong()]; var title = "\\{0}일차 이벤트".Localized(BlackContext.instance.LastDailyRewardRedeemedIndex + 1); // iOS는 이모지 지원이 된다! if (Application.platform == RuntimePlatform.IPhonePlayer) { title = $"{title}"; } var desc = data.notificationDesc.Localized(data.amount.ToInt()); var largeIconIndex = Mathf.Max(0, BlackContext.instance.LastClearedStageId - 1); var currentDate = DateTime.Now; var localZone = TimeZoneInfo.Local; var currentOffset = localZone.GetUtcOffset(currentDate); var localHours = currentOffset.Hours; if (localHours < 0) { localHours += 24; } var request = new PlatformNotificationRequest { title = title, body = desc, largeIcon = string.Format("su_00_{0:D3}", largeIconIndex), localHours = localHours }; ConDebug.Log($"RegisterAllRepeatingNotifications UTC Offset Hour: {localHours}"); return(request); } return(null); }
public static void DeleteSaveFile(string stageName) { var saveDataPath = FileUtil.GetPath(GetStageSaveFileName(stageName)); ConDebug.Log($"Deleting save file '{saveDataPath}'..."); File.Delete(saveDataPath); var wipPngPath = FileUtil.GetPath(GetWipPngFileName(stageName)); ConDebug.Log($"Deleting save file '{wipPngPath}'..."); File.Delete(wipPngPath); }
void ExecuteBackgroundTimeCompensation() { ConDebug.Log("Background time compensation started."); if (networkTime.State != NetworkTime.QueryState.NoError) { Debug.LogError( "ExecuteBackgroundTimeCompensation() should be called after network time received successfully."); } else { ExecuteBackgroundTimeCompensation(GetBackgroundDurationUsec()); } }
void OnForegrounded(MonoBehaviour backgrounder) { ConDebug.Log($"Last backgrounder removed. Finishing background mode: {backgrounder.name}"); Sound.instance.ResumeToNormalTimeAndResumeAudioMixer(); // 잠깐 백그라운드에 갔다가 돌아오는 경우 지나간 시간만큼 보상을 해 준다. (게임을 켜 놓은 것 처럼) if (focusLost) { focusLost = false; ExecuteBackgroundTimeCompensationImmediatelyOrDelayed(); } }
public static byte[] SerializeDataSetWithComparison <T>(T value) { BlackStringTable.StringNumberDict.Clear(); var notCompressed = MessagePackSerializer.Serialize(value, DefaultNoCompOptions); BlackStringTable.StringNumberDict.Clear(); var compressed = MessagePackSerializer.Serialize(value, DefaultOptions); ConDebug.Log("=== Serialization Result ==="); ConDebug.Log($" Before compression: {notCompressed.Length:n0} bytes"); ConDebug.Log($" After compression: {compressed.Length:n0} bytes"); ConDebug.Log($" Compression ratio: {(float) compressed.Length / notCompressed.Length:f2}"); return(compressed); }
RectInt GetRectRange(ulong maxRectUlong) { var xMin = (int)(maxRectUlong & 0xffff); var yMax = gridWorld.TexSize - (int)((maxRectUlong >> 16) & 0xffff); var xMax = (int)((maxRectUlong >> 32) & 0xffff); var yMin = gridWorld.TexSize - (int)((maxRectUlong >> 48) & 0xffff); var r = new RectInt(xMin, yMin, xMax - xMin, yMax - yMin); if (Verbose) { ConDebug.Log($"{r.xMin},{r.yMin} -- {r.xMax},{r.yMax} (area={r.size.x * r.size.y})"); } return(r); }
static bool SaveBlackSaveData(BlackSaveData blackSaveData) { //ConDebug.LogFormat("Start Saving JSON Data: {0}", JsonUtility.ToJson(blackSaveData)); var saveDataArray = MessagePackSerializer.Serialize(blackSaveData, Data.DefaultOptions); ConDebug.LogFormat("Saving path: {0}", SaveFileName); if (lastSaveDataArray != null && lastSaveDataArray.SequenceEqual(saveDataArray)) { ConDebug.LogFormat("Saving skipped since there is no difference made compared to last time saved."); } else { try { // 진짜 쓰자!! WriteAllBytesAtomically(SaveFileName, saveDataArray); // 마지막 저장 데이터 갱신 lastSaveDataArray = saveDataArray; ConDebug.Log($"{SaveFileName} Saved. (written to disk)"); // 유저 서비스를 위해 필요할 수도 있으니까 개발 중일 때는 base64 인코딩 버전 세이브 파일도 저장한다. // 실서비스 버전에서는 불필요한 기능이다. if (Application.isEditor) { var base64Path = SaveFileName + ".base64.txt"; ConDebug.LogFormat("Saving path (base64): {0}", base64Path); File.WriteAllText(base64Path, Convert.ToBase64String(saveDataArray)); ConDebug.Log($"{base64Path} Saved. (written to disk)"); } IncreaseSaveDataSlotAndWrite(); var lastBlackLevel = blackSaveData.lastClearedStageId; var gem = (blackSaveData.freeGemScUInt128 + blackSaveData.paidGemScUInt128).ToUInt128() .ToClampedLong(); BlackLogManager.Add(BlackLogEntry.Type.GameSaved, lastBlackLevel, gem); } catch (Exception e) { Debug.LogException(e); Debug.LogError("Writing to disk failed!!!"); ConfirmPopup.instance.Open("Writing to disk failed!!!"); BlackLogManager.Add(BlackLogEntry.Type.GameSaveFailure, 0, 0); return(false); } } return(true); }
static void ExecuteBackgroundTimeCompensation(long usec) { ConDebug.Log($"ExecuteBackgroundTimeCompensation() {(float) usec / 1e6:f1} sec ({usec} usec) elapsed."); if (usec > 0) { if (BlackContext.instance != null) { // TODO Background Compensation } } else { Debug.LogError($"ExecuteBackgroundTimeCompensation() with negative usec? {usec}"); } }
public void CreateAllLabels(StageData stageData) { var maxRectDict = stageData.islandDataByMinPoint.ToDictionary(e => e.Key, e => GetRectRange(e.Value.maxRect)); var rectIndex = 0; var subgroupCapacity = 50; GameObject islandLabelNumberSubgroup = null; foreach (var kv in maxRectDict) { if (Verbose) { ConDebug.Log( $"Big sub rect island: ({kv.Value.xMin},{kv.Value.yMin})-({kv.Value.xMax},{kv.Value.yMax}) area={kv.Value.size.x * kv.Value.size.y}"); } if (rectIndex % subgroupCapacity == 0) { islandLabelNumberSubgroup = new GameObject($"Island Label Subgroup ({rectIndex:d4}-{rectIndex + subgroupCapacity - 1:d4})"); islandLabelNumberSubgroup.transform.parent = islandLabelNumberGroup; var subGroupRt = islandLabelNumberSubgroup.AddComponent <RectTransform>(); subGroupRt.anchoredPosition3D = Vector3.zero; subGroupRt.localScale = Vector3.one; } if (islandLabelNumberSubgroup == null) { Debug.LogError($"Logic error. {nameof(islandLabelNumberSubgroup)} should not be null at this point."); continue; } var label = Instantiate(islandLabelNumberPrefab, islandLabelNumberSubgroup.transform) .GetComponent <IslandLabel>(); var labelRt = label.Rt; var texSizeFloat = (float)gridWorld.TexSize; var delta = rt.sizeDelta; var anchoredPosition = kv.Value.center / texSizeFloat * delta - delta / 2; labelRt.anchoredPosition = anchoredPosition; var sizeDelta = (Vector2)kv.Value.size / texSizeFloat * delta; labelRt.sizeDelta = sizeDelta; var paletteIndex = paletteButtonGroup.GetPaletteIndexByColor(stageData.islandDataByMinPoint[kv.Key].rgba); label.Text = (paletteIndex + 1).ToString(); labelByMinPoint[kv.Key] = label; label.name = $"Island Label {rectIndex:d4} #{paletteIndex + 1:d2}"; rectIndex++; } }
public void OnNetworkTimeStateChange(NetworkTime.QueryState state) { if (pendingBackgroundTimeCompensation) { ConDebug.Log($"Pending background time compensation starting now: networkTime.QueryState={state}"); if (state == NetworkTime.QueryState.NoError) { pendingBackgroundTimeCompensation = false; ExecuteBackgroundTimeCompensation(); } else if (state == NetworkTime.QueryState.Error) { pendingBackgroundTimeCompensation = false; } } }
public void DebugPrintCloudMetadata(byte[] bytes) { var cloudMetadata = GetCloudMetadataFromBytes(bytes); if (cloudMetadata != null) { ConDebug.LogFormat("prevAccountLevel = {0}", cloudMetadata.level); ConDebug.LogFormat("prevAccountLevelExp = {0}", cloudMetadata.levelExp); ConDebug.LogFormat("prevAccountGem = {0}", cloudMetadata.gem); ConDebug.LogFormat("prevAccountGoldRate = {0}", cloudMetadata.goldRate); ConDebug.LogFormat("prevSaveDate = {0}", cloudMetadata.saveDate); } else { ConDebug.LogFormat("Cloud metadata is null."); } }
static void GatherAllStaticLocalizedTextRef() { List <string> textRefList = new List <string>(); foreach (var root in SceneManager.GetActiveScene().GetRootGameObjects()) { foreach (var staticLocalizedText in root.GetComponentsInChildren <StaticLocalizedText>(true)) { textRefList.Add(staticLocalizedText.StrRef); } } textRefList = textRefList.Distinct().ToList(); textRefList.Sort(); File.WriteAllLines("textref.txt", textRefList.ToArray()); ConDebug.LogFormat("textref.txt written: {0} items", textRefList.Count); }