diff --git a/nekoyume/Assets/Editor/UberLogger.meta b/nekoyume/Assets/Editor/UberLogger.meta new file mode 100644 index 00000000000..3d1578f128a --- /dev/null +++ b/nekoyume/Assets/Editor/UberLogger.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: 924e28e7ff79f47cfa66acf89387353d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: diff --git a/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs new file mode 100644 index 00000000000..bd67cb659a2 --- /dev/null +++ b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs @@ -0,0 +1,983 @@ +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.Linq; +using System; +using UberLogger; +using System.Text.RegularExpressions; + +/// +/// The console logging frontend. +/// Pulls data from the UberLoggerEditor backend +/// + +public class UberLoggerEditorWindow : EditorWindow, UberLoggerEditor.ILoggerWindow +{ + [MenuItem("Window/Show Uber Console")] + static public void ShowLogWindow() + { + Init(); + } + + static public void Init() + { + var window = ScriptableObject.CreateInstance(); + window.Show(); + window.position = new Rect(200,200,400,300); + window.CurrentTopPaneHeight = window.position.height/2; + } + + public void OnLogChange(LogInfo logInfo) + { + Dirty = true; + // Repaint(); + } + + + void OnInspectorUpdate() + { + // Debug.Log("Update"); + if(Dirty) + { + Repaint(); + } + } + + void OnEnable() + { + // Connect to or create the backend + if(!EditorLogger) + { + EditorLogger = UberLogger.Logger.GetLogger(); + if(!EditorLogger) + { + EditorLogger = UberLoggerEditor.Create(); + } + } + + // UberLogger doesn't allow for duplicate loggers, so this is safe + // And, due to Unity serialisation stuff, necessary to do to it here. + UberLogger.Logger.AddLogger(EditorLogger); + EditorLogger.AddWindow(this); + +// _OR_NEWER only became available from 5.3 +#if UNITY_5 || UNITY_5_3_OR_NEWER + titleContent.text = "Uber Console"; +#else + title = "Uber Console"; + +#endif + + ClearSelectedMessage(); + + SmallErrorIcon = EditorGUIUtility.FindTexture( "d_console.erroricon.sml" ) ; + SmallWarningIcon = EditorGUIUtility.FindTexture( "d_console.warnicon.sml" ) ; + SmallMessageIcon = EditorGUIUtility.FindTexture( "d_console.infoicon.sml" ) ; + ErrorIcon = SmallErrorIcon; + WarningIcon = SmallWarningIcon; + MessageIcon = SmallMessageIcon; + Dirty = true; + Repaint(); + + } + + /// + /// Converts the entire message log to a multiline string + /// + public string ExtractLogListToString() + { + string result = ""; + foreach (CountedLog log in RenderLogs) + { + UberLogger.LogInfo logInfo = log.Log; + result += logInfo.GetRelativeTimeStampAsString() + ": " + logInfo.Severity + ": " + logInfo.Message + "\n"; + } + return result; + } + + /// + /// Converts the currently-displayed stack to a multiline string + /// + public string ExtractLogDetailsToString() + { + string result = ""; + if (RenderLogs.Count > 0 && SelectedRenderLog >= 0) + { + var countedLog = RenderLogs[SelectedRenderLog]; + var log = countedLog.Log; + + for (int c1 = 0; c1 < log.Callstack.Count; c1++) + { + var frame = log.Callstack[c1]; + var methodName = frame.GetFormattedMethodName(); + result += methodName + "\n"; + } + } + return result; + } + + /// + /// Handle "Copy" command; copies log & stacktrace contents to clipboard + /// + public void HandleCopyToClipboard() + { + const string copyCommandName = "Copy"; + + Event e = Event.current; + if (e.type == EventType.ValidateCommand && e.commandName == copyCommandName) + { + // Respond to "Copy" command + + // Confirm that we will consume the command; this will result in the command being re-issued with type == EventType.ExecuteCommand + e.Use(); + } + else if (e.type == EventType.ExecuteCommand && e.commandName == copyCommandName) + { + // Copy current message log and current stack to the clipboard + + // Convert all messages to a single long string + // It would be preferable to only copy one of the two, but that requires UberLogger to have focus handling + // between the message log and stack views + string result = ExtractLogListToString(); + + result += "\n"; + + // Convert current callstack to a single long string + result += ExtractLogDetailsToString(); + + GUIUtility.systemCopyBuffer = result; + } + } + + Vector2 DrawPos; + public void OnGUI() + { + //Set up the basic style, based on the Unity defaults + //A bit hacky, but means we don't have to ship an editor guistyle and can fit in to pro and free skins + Color defaultLineColor = GUI.backgroundColor; + GUIStyle unityLogLineEven = null; + GUIStyle unityLogLineOdd = null; + GUIStyle unitySmallLogLine = null; + + foreach(var style in GUI.skin.customStyles) + { + if (style.name=="CN EntryBackEven") unityLogLineEven = style; + else if(style.name=="CN EntryBackOdd") unityLogLineOdd = style; + else if(style.name=="CN StatusInfo") unitySmallLogLine = style; + } + + EntryStyleBackEven = new GUIStyle(unitySmallLogLine); + + EntryStyleBackEven.normal = unityLogLineEven.normal; + EntryStyleBackEven.margin = new RectOffset(0,0,0,0); + EntryStyleBackEven.border = new RectOffset(0,0,0,0); + EntryStyleBackEven.fixedHeight = 0; + + EntryStyleBackOdd = new GUIStyle(EntryStyleBackEven); + EntryStyleBackOdd.normal = unityLogLineOdd.normal; + // EntryStyleBackOdd = new GUIStyle(unityLogLine); + + + SizerLineColour = new Color(defaultLineColor.r*0.5f, defaultLineColor.g*0.5f, defaultLineColor.b*0.5f); + + // GUILayout.BeginVertical(GUILayout.Height(topPanelHeaderHeight), GUILayout.MinHeight(topPanelHeaderHeight)); + ResizeTopPane(); + DrawPos = Vector2.zero; + DrawToolbar(); + DrawFilter(); + + DrawChannels(); + + float logPanelHeight = CurrentTopPaneHeight-DrawPos.y; + + if(Dirty) + { + CurrentLogList = EditorLogger.CopyLogInfo(); + } + DrawLogList(logPanelHeight); + + DrawPos.y += DividerHeight; + + DrawLogDetails(); + + HandleCopyToClipboard(); + + //If we're dirty, do a repaint + Dirty = false; + if(MakeDirty) + { + Dirty = true; + MakeDirty = false; + Repaint(); + } + } + + //Some helper functions to draw buttons that are only as big as their text + bool ButtonClamped(string text, GUIStyle style, out Vector2 size) + { + var content = new GUIContent(text); + size = style.CalcSize(content); + var rect = new Rect(DrawPos, size); + return GUI.Button(rect, text, style); + } + + bool ToggleClamped(bool state, string text, GUIStyle style, out Vector2 size) + { + var content = new GUIContent(text); + return ToggleClamped(state, content, style, out size); + } + + bool ToggleClamped(bool state, GUIContent content, GUIStyle style, out Vector2 size) + { + size = style.CalcSize(content); + Rect drawRect = new Rect(DrawPos, size); + return GUI.Toggle(drawRect, state, content, style); + } + + void LabelClamped(string text, GUIStyle style, out Vector2 size) + { + var content = new GUIContent(text); + size = style.CalcSize(content); + + Rect drawRect = new Rect(DrawPos, size); + GUI.Label(drawRect, text, style); + } + + /// + /// Draws the thin, Unity-style toolbar showing error counts and toggle buttons + /// + void DrawToolbar() + { + var toolbarStyle = EditorStyles.toolbarButton; + + Vector2 elementSize; + if(ButtonClamped("Clear", EditorStyles.toolbarButton, out elementSize)) + { + EditorLogger.Clear(); + } + DrawPos.x += elementSize.x; + EditorLogger.ClearOnPlay = ToggleClamped(EditorLogger.ClearOnPlay, "Clear On Play", EditorStyles.toolbarButton, out elementSize); + DrawPos.x += elementSize.x; + EditorLogger.PauseOnError = ToggleClamped(EditorLogger.PauseOnError, "Error Pause", EditorStyles.toolbarButton, out elementSize); + DrawPos.x += elementSize.x; + var showTimes = ToggleClamped(ShowTimes, "Times", EditorStyles.toolbarButton, out elementSize); + if(showTimes!=ShowTimes) + { + MakeDirty = true; + ShowTimes = showTimes; + } + DrawPos.x += elementSize.x; + var showChannels = ToggleClamped(ShowChannels, "Channels", EditorStyles.toolbarButton, out elementSize); + if (showChannels != ShowChannels) + { + MakeDirty = true; + ShowChannels = showChannels; + } + DrawPos.x += elementSize.x; + var collapse = ToggleClamped(Collapse, "Collapse", EditorStyles.toolbarButton, out elementSize); + if(collapse!=Collapse) + { + MakeDirty = true; + Collapse = collapse; + SelectedRenderLog = -1; + } + DrawPos.x += elementSize.x; + + ScrollFollowMessages = ToggleClamped(ScrollFollowMessages, "Follow", EditorStyles.toolbarButton, out elementSize); + DrawPos.x += elementSize.x; + + var errorToggleContent = new GUIContent(EditorLogger.NoErrors.ToString(), SmallErrorIcon); + var warningToggleContent = new GUIContent(EditorLogger.NoWarnings.ToString(), SmallWarningIcon); + var messageToggleContent = new GUIContent(EditorLogger.NoMessages.ToString(), SmallMessageIcon); + + float totalErrorButtonWidth = toolbarStyle.CalcSize(errorToggleContent).x + toolbarStyle.CalcSize(warningToggleContent).x + toolbarStyle.CalcSize(messageToggleContent).x; + + float errorIconX = position.width-totalErrorButtonWidth; + if(errorIconX > DrawPos.x) + { + DrawPos.x = errorIconX; + } + + var showErrors = ToggleClamped(ShowErrors, errorToggleContent, toolbarStyle, out elementSize); + DrawPos.x += elementSize.x; + var showWarnings = ToggleClamped(ShowWarnings, warningToggleContent, toolbarStyle, out elementSize); + DrawPos.x += elementSize.x; + var showMessages = ToggleClamped(ShowMessages, messageToggleContent, toolbarStyle, out elementSize); + DrawPos.x += elementSize.x; + + DrawPos.y += elementSize.y; + DrawPos.x = 0; + + //If the errors/warning to show has changed, clear the selected message + if(showErrors!=ShowErrors || showWarnings!=ShowWarnings || showMessages!=ShowMessages) + { + ClearSelectedMessage(); + MakeDirty = true; + } + ShowWarnings = showWarnings; + ShowMessages = showMessages; + ShowErrors = showErrors; + } + + /// + /// Draws the channel selector + /// + void DrawChannels() + { + var channels = GetChannels(); + int currentChannelIndex = 0; + for(int c1=0; c1 + /// Based on filter and channel selections, should this log be shown? + /// + bool ShouldShowLog(System.Text.RegularExpressions.Regex regex, LogInfo log) + { + if(log.Channel==CurrentChannel || CurrentChannel=="All" || (CurrentChannel=="No Channel" && String.IsNullOrEmpty(log.Channel))) + { + if((log.Severity==LogSeverity.Message && ShowMessages) + || (log.Severity==LogSeverity.Warning && ShowWarnings) + || (log.Severity==LogSeverity.Error && ShowErrors)) + { + if(regex==null || regex.IsMatch(log.Message)) + { + return true; + } + } + } + + return false; + } + + /// + /// Converts a given log element into a piece of gui content to be displayed + /// + GUIContent GetLogLineGUIContent(UberLogger.LogInfo log, bool showTimes, bool showChannels) + { + var showMessage = log.Message; + + //Make all messages single line + showMessage = showMessage.Replace(UberLogger.Logger.UnityInternalNewLine, " "); + + // Format the message as follows: + // [channel] 0.000 : message <-- Both channel and time shown + // 0.000 : message <-- Time shown, channel hidden + // [channel] : message <-- Channel shown, time hidden + // message <-- Both channel and time hidden + var showChannel = showChannels && !string.IsNullOrEmpty(log.Channel); + var channelMessage = showChannel ? string.Format("[{0}]", log.Channel) : ""; + var channelTimeSeparator = (showChannel && showTimes) ? " " : ""; + var timeMessage = showTimes ? string.Format("{0}", log.GetRelativeTimeStampAsString()) : ""; + var prefixMessageSeparator = (showChannel || showTimes) ? " : " : ""; + showMessage = string.Format("{0}{1}{2}{3}{4}", + channelMessage, + channelTimeSeparator, + timeMessage, + prefixMessageSeparator, + showMessage + ); + + var content = new GUIContent(showMessage, GetIconForLog(log)); + return content; + } + + /// + /// Draws the main log panel + /// + public void DrawLogList(float height) + { + var oldColor = GUI.backgroundColor; + + + float buttonY = 0; + + System.Text.RegularExpressions.Regex filterRegex = null; + + if(!String.IsNullOrEmpty(FilterRegex)) + { + filterRegex = new Regex(FilterRegex); + } + + var collapseBadgeStyle = EditorStyles.miniButton; + var logLineStyle = EntryStyleBackEven; + + // If we've been marked dirty, we need to recalculate the elements to be displayed + if(Dirty) + { + LogListMaxWidth = 0; + LogListLineHeight = 0; + CollapseBadgeMaxWidth = 0; + RenderLogs.Clear(); + + //When collapsed, count up the unique elements and use those to display + if(Collapse) + { + var collapsedLines = new Dictionary(); + var collapsedLinesList = new List(); + + foreach(var log in CurrentLogList) + { + if(ShouldShowLog(filterRegex, log)) + { + var matchString = log.Message + "!$" + log.Severity + "!$" + log.Channel; + + CountedLog countedLog; + if(collapsedLines.TryGetValue(matchString, out countedLog)) + { + countedLog.Count++; + } + else + { + countedLog = new CountedLog(log, 1); + collapsedLines.Add(matchString, countedLog); + collapsedLinesList.Add(countedLog); + } + } + } + + foreach(var countedLog in collapsedLinesList) + { + var content = GetLogLineGUIContent(countedLog.Log, ShowTimes, ShowChannels); + RenderLogs.Add(countedLog); + var logLineSize = logLineStyle.CalcSize(content); + LogListMaxWidth = Mathf.Max(LogListMaxWidth, logLineSize.x); + LogListLineHeight = Mathf.Max(LogListLineHeight, logLineSize.y); + + var collapseBadgeContent = new GUIContent(countedLog.Count.ToString()); + var collapseBadgeSize = collapseBadgeStyle.CalcSize(collapseBadgeContent); + CollapseBadgeMaxWidth = Mathf.Max(CollapseBadgeMaxWidth, collapseBadgeSize.x); + } + } + //If we're not collapsed, display everything in order + else + { + foreach(var log in CurrentLogList) + { + if(ShouldShowLog(filterRegex, log)) + { + var content = GetLogLineGUIContent(log, ShowTimes, ShowChannels); + RenderLogs.Add(new CountedLog(log, 1)); + var logLineSize = logLineStyle.CalcSize(content); + LogListMaxWidth = Mathf.Max(LogListMaxWidth, logLineSize.x); + LogListLineHeight = Mathf.Max(LogListLineHeight, logLineSize.y); + } + } + } + + LogListMaxWidth += CollapseBadgeMaxWidth; + } + + var scrollRect = new Rect(DrawPos, new Vector2(position.width, height)); + float lineWidth = Mathf.Max(LogListMaxWidth, scrollRect.width); + + var contentRect = new Rect(0, 0, lineWidth, RenderLogs.Count*LogListLineHeight); + Vector2 lastScrollPosition = LogListScrollPosition; + LogListScrollPosition = GUI.BeginScrollView(scrollRect, LogListScrollPosition, contentRect); + + //If we're following the messages but the user has moved, cancel following + if(ScrollFollowMessages) + { + if(lastScrollPosition.y - LogListScrollPosition.y > LogListLineHeight) + { + UberDebug.UnityLog(String.Format("{0} {1}", lastScrollPosition.y, LogListScrollPosition.y)); + ScrollFollowMessages = false; + } + } + + float logLineX = CollapseBadgeMaxWidth; + + //Render all the elements + int firstRenderLogIndex = (int) (LogListScrollPosition.y/LogListLineHeight); + int lastRenderLogIndex = firstRenderLogIndex + (int) (height/LogListLineHeight); + + firstRenderLogIndex = Mathf.Clamp(firstRenderLogIndex, 0, RenderLogs.Count); + lastRenderLogIndex = Mathf.Clamp(lastRenderLogIndex, 0, RenderLogs.Count); + buttonY = firstRenderLogIndex*LogListLineHeight; + + for(int renderLogIndex=firstRenderLogIndex; renderLogIndex0) + { + LogListScrollPosition.y = ((RenderLogs.Count+1)*LogListLineHeight)-scrollRect.height; + } + + GUI.EndScrollView(); + DrawPos.y += height; + DrawPos.x = 0; + GUI.backgroundColor = oldColor; + } + + + /// + /// The bottom of the panel - details of the selected log + /// + public void DrawLogDetails() + { + var oldColor = GUI.backgroundColor; + + SelectedRenderLog = Mathf.Clamp(SelectedRenderLog, 0, CurrentLogList.Count); + + if(RenderLogs.Count>0 && SelectedRenderLog>=0) + { + var countedLog = RenderLogs[SelectedRenderLog]; + var log = countedLog.Log; + var logLineStyle = EntryStyleBackEven; + + var sourceStyle = new GUIStyle(GUI.skin.textArea); + sourceStyle.richText = true; + + var drawRect = new Rect(DrawPos, new Vector2(position.width-DrawPos.x, position.height-DrawPos.y)); + + //Work out the content we need to show, and the sizes + var detailLines = new List(); + float contentHeight = 0; + float contentWidth = 0; + float lineHeight = 0; + + + for(int c1=0; c1 GetChannels() + { + if(Dirty) + { + CurrentChannels = EditorLogger.CopyChannels(); + } + + var categories = CurrentChannels; + + var channelList = new List(); + channelList.Add("All"); + channelList.Add("No Channel"); + channelList.AddRange(categories); + return channelList; + } + + /// + /// Handles the split window stuff, somewhat bodgily + /// + private void ResizeTopPane() + { + //Set up the resize collision rect + CursorChangeRect = new Rect(0, CurrentTopPaneHeight, position.width, DividerHeight); + + var oldColor = GUI.color; + GUI.color = SizerLineColour; + GUI.DrawTexture(CursorChangeRect, EditorGUIUtility.whiteTexture); + GUI.color = oldColor; + EditorGUIUtility.AddCursorRect(CursorChangeRect,MouseCursor.ResizeVertical); + + if( Event.current.type == EventType.MouseDown && CursorChangeRect.Contains(Event.current.mousePosition)) + { + Resize = true; + } + + //If we've resized, store the new size and force a repaint + if(Resize) + { + CurrentTopPaneHeight = Event.current.mousePosition.y; + CursorChangeRect.Set(CursorChangeRect.x,CurrentTopPaneHeight,CursorChangeRect.width,CursorChangeRect.height); + Repaint(); + } + + if(Event.current.type == EventType.MouseUp) + Resize = false; + + CurrentTopPaneHeight = Mathf.Clamp(CurrentTopPaneHeight, 100, position.height-100); + } + + //Cache for GetSourceForFrame + string SourceLines; + LogStackFrame SourceLinesFrame; + + /// + ///If the frame has a valid filename, get the source string for the code around the frame + ///This is cached, so we don't keep getting it. + /// + string GetSourceForFrame(LogStackFrame frame) + { + if(SourceLinesFrame==frame) + { + return SourceLines; + } + + + if(frame.FileName==null) + { + return ""; + } + + var osFileName = UberLogger.Logger.ConvertDirectorySeparatorsFromUnityToOS(frame.FileName); + var filename = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), osFileName); + if (!System.IO.File.Exists(filename)) + { + return ""; + } + + int lineNumber = frame.LineNumber-1; + int linesAround = 3; + var lines = System.IO.File.ReadAllLines(filename); + var firstLine = Mathf.Max(lineNumber-linesAround, 0); + var lastLine = Mathf.Min(lineNumber+linesAround+1, lines.Count()); + + SourceLines = ""; + if(firstLine!=0) + { + SourceLines += "...\n"; + } + for(int c1=firstLine; c1"; + } + SourceLines += str; + } + if(lastLine!=lines.Count()) + { + SourceLines += "...\n"; + } + + SourceLinesFrame = frame; + return SourceLines; + } + + void ClearSelectedMessage() + { + SelectedRenderLog = -1; + SelectedCallstackFrame = -1; + ShowFrameSource = false; + } + + Vector2 LogListScrollPosition; + Vector2 LogDetailsScrollPosition; + + Texture2D ErrorIcon; + Texture2D WarningIcon; + Texture2D MessageIcon; + Texture2D SmallErrorIcon; + Texture2D SmallWarningIcon; + Texture2D SmallMessageIcon; + + bool ShowChannels = true; + bool ShowTimes = true; + bool Collapse = false; + bool ScrollFollowMessages = false; + float CurrentTopPaneHeight = 200; + bool Resize = false; + Rect CursorChangeRect; + int SelectedRenderLog = -1; + bool Dirty=false; + bool MakeDirty=false; + float DividerHeight = 5; + + double LastMessageClickTime = 0; + double LastFrameClickTime = 0; + + const double DoubleClickInterval = 0.3f; + + //Serialise the logger field so that Unity doesn't forget about the logger when you hit Play + [UnityEngine.SerializeField] + UberLoggerEditor EditorLogger; + + List CurrentLogList = new List(); + HashSet CurrentChannels = new HashSet(); + + //Standard unity pro colours + Color SizerLineColour; + + GUIStyle EntryStyleBackEven; + GUIStyle EntryStyleBackOdd; + string CurrentChannel=null; + string FilterRegex = null; + bool ShowErrors = true; + bool ShowWarnings = true; + bool ShowMessages = true; + int SelectedCallstackFrame = 0; + bool ShowFrameSource = false; + + class CountedLog + { + public UberLogger.LogInfo Log = null; + public Int32 Count=1; + public CountedLog(UberLogger.LogInfo log, Int32 count) + { + Log = log; + Count = count; + } + } + + List RenderLogs = new List(); + float LogListMaxWidth = 0; + float LogListLineHeight = 0; + float CollapseBadgeMaxWidth = 0; + +} diff --git a/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs.meta b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs.meta new file mode 100644 index 00000000000..560c65f0dbb --- /dev/null +++ b/nekoyume/Assets/Editor/UberLogger/UberLoggerEditorWindow.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6ef03148bd3bd4ff99c7296168e907fb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs b/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs index 8d9f3525735..6d71d034545 100644 --- a/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs +++ b/nekoyume/Assets/_Scripts/Blockchain/RPCAgent.cs @@ -958,8 +958,7 @@ public void OnRenderBlock(byte[] oldTip, byte[] newTip) BlockTipHashSubject.OnNext(BlockTipHash); _lastTipChangedAt = DateTimeOffset.UtcNow; - NcDebug.Log( - $"[{nameof(RPCAgent)}] Render block: {BlockIndex}, {BlockTipHash.ToString()}"); + NcDebug.Log($"[{nameof(RPCAgent)}] Render block: {BlockIndex}, {BlockTipHash.ToString()}", channel: "RenderBlock"); BlockRenderer.RenderBlock(null, null); }); } diff --git a/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs b/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs index 788fc9503b2..b156e32014b 100644 --- a/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs +++ b/nekoyume/Assets/_Scripts/Debugger/NcDebug.cs @@ -1,26 +1,8 @@ using System; using JetBrains.Annotations; -using UnityEngine; namespace Nekoyume { - /// - /// It overrides UnityEngine.Debug to mute debug messages completely on a platform-specific basis. - /// - /// Putting this inside of 'Plugins' foloder is ok. - /// - /// Important: - /// Other preprocessor directives than 'UNITY_EDITOR' does not correctly work. - /// - /// Note: - /// [Conditional] attribute indicates to compilers that a method call or attribute should be - /// ignored unless a specified conditional compilation symbol is defined. - /// - /// See Also: - /// http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx - /// - /// 2012.11. @kimsama - /// public static class NcDebug { // used for build with 'DEBUG_USE' symbol. @@ -30,105 +12,108 @@ public static string InsertTimestamp(string message) return $"[{DateTime.UtcNow:yyyy-M-d HH:mm:ss}] {message}"; } - public static void Log(object message) + public static void Log(object message, string channel = "") { #if UNITY_EDITOR - Debug.Log(message); + UberDebug.LogChannel(channel, message.ToString()); #elif DEBUG_USE - Debug.Log(InsertTimestamp(message.ToString())); + UnityEngine.Debug.Log(InsertTimestamp(message.ToString())); #endif } - public static void Log(object message, UnityEngine.Object context) + public static void Log(object message, UnityEngine.Object context, string channel = "") { #if UNITY_EDITOR - Debug.Log(message, context); + UberDebug.LogChannel(channel, message.ToString(), context); #elif DEBUG_USE - Debug.Log(InsertTimestamp(message.ToString()), context); + UnityEngine.Debug.Log(InsertTimestamp(message.ToString()), context); #endif } public static void LogFormat(string format, params object[] args) { + var message = string.Format(format, args); #if UNITY_EDITOR - Debug.LogFormat(format, args); + UberDebug.Log(message); #elif DEBUG_USE // LogFormat() in itself expands an array when it takes only one array. - Debug.Log(InsertTimestamp(string.Format(format, args))); + UnityEngine.Debug.Log(InsertTimestamp(message)); #endif } - public static void LogWarning(object message) + public static void LogWarning(object message, string channel = "") { #if UNITY_EDITOR - Debug.LogWarning(message); + UberDebug.LogWarningChannel(channel, message.ToString()); #elif DEBUG_USE - Debug.LogWarning(InsertTimestamp(message.ToString())); + UnityEngine.Debug.LogWarning(InsertTimestamp(message.ToString())); #endif } - public static void LogWarning(object message, UnityEngine.Object context) + public static void LogWarning(object message, UnityEngine.Object context, string channel = "") { #if UNITY_EDITOR - Debug.LogWarning(message, context); + UberDebug.LogWarningChannel(channel, message.ToString(), context); #elif DEBUG_USE - Debug.LogWarning(InsertTimestamp(message.ToString()), context); + UnityEngine.Debug.LogWarning(InsertTimestamp(message.ToString()), context); #endif } public static void LogWarningFormat(string format, params object[] args) { + var message = string.Format(format, args); #if UNITY_EDITOR - Debug.LogWarningFormat(format, args); + UberDebug.LogWarning(message); #elif DEBUG_USE // LogWarningFormat() in itself expands an array when it takes only one array. - Debug.LogWarningFormat(InsertTimestamp(string.Format(format, args))); + UnityEngine.Debug.LogWarningFormat(InsertTimestamp(message)); #endif } - public static void LogError(object message) + public static void LogError(object message, string channel = "") { #if UNITY_EDITOR - Debug.LogError(message); + UberDebug.LogErrorChannel(channel, message.ToString()); #elif DEBUG_USE - Debug.LogError(InsertTimestamp(message.ToString())); + UnityEngine.Debug.LogError(InsertTimestamp(message.ToString())); #endif } - public static void LogError(object message, UnityEngine.Object context) + public static void LogError(object message, UnityEngine.Object context, string channel = "") { #if UNITY_EDITOR - Debug.LogError(message, context); + UberDebug.LogErrorChannel(channel, message.ToString(), context); #elif DEBUG_USE - Debug.LogError(InsertTimestamp(message.ToString()), context); + UnityEngine.Debug.LogError(InsertTimestamp(message.ToString()), context); #endif } public static void LogErrorFormat(string format, params object[] args) { + var message = string.Format(format, args); #if UNITY_EDITOR - Debug.LogErrorFormat(format, args); + UberDebug.LogError(message); #elif DEBUG_USE // LogErrorFormat() in itself expands an array when it takes only one array. - Debug.LogErrorFormat(InsertTimestamp(string.Format(format, args))); + UnityEngine.Debug.LogErrorFormat(InsertTimestamp(message)); #endif } - public static void LogException(Exception exception) + public static void LogException(Exception exception, string channel = "") { #if UNITY_EDITOR - Debug.LogError(exception.Message); + UberDebug.LogErrorChannel(channel, exception.Message); #elif DEBUG_USE - Debug.LogError(InsertTimestamp(exception.Message)); + UnityEngine.Debug.LogError(InsertTimestamp(exception.Message)); #endif } - public static void LogException(Exception exception, UnityEngine.Object context) + public static void LogException(Exception exception, UnityEngine.Object context, string channel = "") { #if UNITY_EDITOR - Debug.LogError(exception.Message, context); + UberDebug.LogErrorChannel(channel, exception.Message, context); #elif DEBUG_USE - Debug.LogError(InsertTimestamp(exception.Message), context); + UnityEngine.Debug.LogError(InsertTimestamp(exception.Message), context); #endif } } diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger.meta new file mode 100644 index 00000000000..13554d22a72 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5d104a850059c7646bca9fc3f9c2381d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art.meta new file mode 100644 index 00000000000..9b8123b763c --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 08b646709d2a14c419ef4e641ce44797 +folderAsset: yes +timeCreated: 1437657322 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png new file mode 100644 index 00000000000..138bac3a33b Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png.meta new file mode 100644 index 00000000000..dc863ca54a9 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/Button.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 2ae9477f7f0774b808aef406d3bf2d3c +timeCreated: 1437687420 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png new file mode 100644 index 00000000000..9fcc2146aba Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png.meta new file mode 100644 index 00000000000..c6b9cf6eb04 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ButtonError.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: f752d027f2368431c924c0306e747c4b +timeCreated: 1437728159 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png new file mode 100644 index 00000000000..1af20cc9145 Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png.meta new file mode 100644 index 00000000000..b4b604c41b9 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ErrorIcon.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: f5e296e323cd64d619488c517c4692af +timeCreated: 1437663587 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png new file mode 100644 index 00000000000..d456d99c804 Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png.meta new file mode 100644 index 00000000000..46c2a163eab --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine1.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 58be81cf6eccb4cabbae417792fd2765 +timeCreated: 1437660139 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png new file mode 100644 index 00000000000..3dd4b752b05 Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png.meta new file mode 100644 index 00000000000..ca8f95d5a2e --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLine2.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 33bd69e44bf8341e5a10577910796fb6 +timeCreated: 1437660139 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png new file mode 100644 index 00000000000..1cf4942402b Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png.meta new file mode 100644 index 00000000000..5fbdcb2b673 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/LogLineSelected.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: c60b5ba991951418b86ce94a4b97321c +timeCreated: 1437660139 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png new file mode 100644 index 00000000000..46d19f8ac4b Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png.meta new file mode 100644 index 00000000000..4069e255dd8 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/MessageIcon.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: fa976bac27b1e440eb0d8bd71c1caac3 +timeCreated: 1437663836 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png new file mode 100644 index 00000000000..b368a5d652f Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png.meta new file mode 100644 index 00000000000..f91b871c3f5 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButton.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 1e3d00b6e3a884febbfd0da496905572 +timeCreated: 1437660139 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png new file mode 100644 index 00000000000..b9fc1fa8f54 Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png.meta new file mode 100644 index 00000000000..e802694ec67 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonClicked.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: c445efe53c41a452897859c5e65dde5c +timeCreated: 1437662129 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png new file mode 100644 index 00000000000..0c463ab22bb Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png.meta new file mode 100644 index 00000000000..da5095721de --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/ToolbarButtonDown.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: bd719bdc497244113bf9f08779f78082 +timeCreated: 1437664533 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin new file mode 100644 index 00000000000..9d6958b9714 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin @@ -0,0 +1,1433 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12001, guid: 0000000000000000e000000000000000, type: 0} + m_Name: UberConsoleSkin + m_EditorClassIdentifier: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_box: + m_Name: box + m_Normal: + m_Background: {fileID: 0} + m_TextColor: {r: .799999952, g: .799999952, b: .799999952, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 6 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 1 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_button: + m_Name: button + m_Normal: + m_Background: {fileID: 11006, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1} + m_Hover: + m_Background: {fileID: 11003, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 11005, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .90196079, g: .90196079, b: .90196079, a: 1} + m_OnHover: + m_Background: {fileID: 11004, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 11002, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_toggle: + m_Name: toggle + m_Normal: + m_Background: {fileID: 11018, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .891128957, g: .891128957, b: .891128957, a: 1} + m_Hover: + m_Background: {fileID: 11014, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 11013, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11016, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .890196085, g: .890196085, b: .890196085, a: 1} + m_OnHover: + m_Background: {fileID: 11015, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 11017, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 14 + m_Right: 0 + m_Top: 14 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 15 + m_Right: 0 + m_Top: 3 + m_Bottom: 0 + m_Overflow: + m_Left: -1 + m_Right: 0 + m_Top: -4 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_label: + m_Name: label + m_Normal: + m_Background: {fileID: 0} + m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 1 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_textField: + m_Name: textfield + m_Normal: + m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .799999952, g: .799999952, b: .799999952, a: 1} + m_Hover: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .899999976, g: .899999976, b: .899999976, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 3 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_textArea: + m_Name: textarea + m_Normal: + m_Background: {fileID: 11024, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .90196079, g: .90196079, b: .90196079, a: 1} + m_Hover: + m_Background: {fileID: 11026, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: .799999952, g: .799999952, b: .799999952, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 11025, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 1 + m_RichText: 0 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_window: + m_Name: window + m_Normal: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Hover: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 2800000, guid: e4083732964464539b3e141a263f50b6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Border: + m_Left: 10 + m_Right: 9 + m_Top: 19 + m_Bottom: 9 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 10 + m_Right: 10 + m_Top: 20 + m_Bottom: 10 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 1 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: -18} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalSlider: + m_Name: horizontalslider + m_Normal: + m_Background: {fileID: 11009, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 3 + m_Right: 3 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -2 + m_Bottom: -3 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 12 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalSliderThumb: + m_Name: horizontalsliderthumb + m_Normal: + m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 4 + m_Right: 4 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 7 + m_Right: 7 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 12 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalSlider: + m_Name: verticalslider + m_Normal: + m_Background: {fileID: 11021, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 3 + m_Bottom: 3 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: -1 + m_Overflow: + m_Left: -2 + m_Right: -3 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 0 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 12 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_verticalSliderThumb: + m_Name: verticalsliderthumb + m_Normal: + m_Background: {fileID: 11011, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 11012, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 11010, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 7 + m_Bottom: 7 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: -1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 12 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_horizontalScrollbar: + m_Name: horizontalscrollbar + m_Normal: + m_Background: {fileID: 11008, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 9 + m_Right: 9 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 4 + m_Right: 4 + m_Top: 1 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 15 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarThumb: + m_Name: horizontalscrollbarthumb + m_Normal: + m_Background: {fileID: 11007, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 6 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 6 + m_Right: 6 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: -1 + m_Bottom: 1 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 13 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarLeftButton: + m_Name: horizontalscrollbarleftbutton + m_Normal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_horizontalScrollbarRightButton: + m_Name: horizontalscrollbarrightbutton + m_Normal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbar: + m_Name: verticalscrollbar + m_Normal: + m_Background: {fileID: 11020, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 9 + m_Bottom: 9 + m_Margin: + m_Left: 1 + m_Right: 4 + m_Top: 4 + m_Bottom: 4 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 1 + m_Bottom: 1 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 15 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbarThumb: + m_Name: verticalscrollbarthumb + m_Normal: + m_Background: {fileID: 11019, guid: 0000000000000000e000000000000000, type: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 6 + m_Right: 6 + m_Top: 6 + m_Bottom: 6 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 6 + m_Bottom: 6 + m_Overflow: + m_Left: -1 + m_Right: -1 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 2 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 15 + m_FixedHeight: 0 + m_StretchWidth: 0 + m_StretchHeight: 1 + m_verticalScrollbarUpButton: + m_Name: verticalscrollbarupbutton + m_Normal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_verticalScrollbarDownButton: + m_Name: verticalscrollbardownbutton + m_Normal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_ScrollView: + m_Name: scrollview + m_Normal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Hover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Active: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Focused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 1 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_CustomStyles: + - m_Name: LogLine1 + m_Normal: + m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Hover: + m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 2800000, guid: 58be81cf6eccb4cabbae417792fd2765, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 0 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + - m_Name: LogLine2 + m_Normal: + m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Hover: + m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 2800000, guid: 33bd69e44bf8341e5a10577910796fb6, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 0 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + - m_Name: SelectedLogLine + m_Normal: + m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Hover: + m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnActive: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_OnFocused: + m_Background: {fileID: 0} + m_TextColor: {r: 0, g: 0, b: 0, a: 1} + m_Border: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 0 + m_FontStyle: 0 + m_Alignment: 0 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 0 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + - m_Name: ToolbarButton + m_Normal: + m_Background: {fileID: 2800000, guid: 1e3d00b6e3a884febbfd0da496905572, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Hover: + m_Background: {fileID: 2800000, guid: 1e3d00b6e3a884febbfd0da496905572, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Active: + m_Background: {fileID: 2800000, guid: c445efe53c41a452897859c5e65dde5c, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Focused: + m_Background: {fileID: 2800000, guid: 1e3d00b6e3a884febbfd0da496905572, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnNormal: + m_Background: {fileID: 2800000, guid: bd719bdc497244113bf9f08779f78082, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnHover: + m_Background: {fileID: 0} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnActive: + m_Background: {fileID: 2800000, guid: c445efe53c41a452897859c5e65dde5c, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_OnFocused: + m_Background: {fileID: 2800000, guid: c60b5ba991951418b86ce94a4b97321c, type: 3} + m_TextColor: {r: 1, g: 1, b: 1, a: 1} + m_Border: + m_Left: 1 + m_Right: 1 + m_Top: 0 + m_Bottom: 0 + m_Margin: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Padding: + m_Left: 3 + m_Right: 3 + m_Top: 3 + m_Bottom: 3 + m_Overflow: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_Font: {fileID: 0} + m_FontSize: 10 + m_FontStyle: 0 + m_Alignment: 4 + m_WordWrap: 0 + m_RichText: 1 + m_TextClipping: 0 + m_ImagePosition: 0 + m_ContentOffset: {x: 0, y: 0} + m_FixedWidth: 0 + m_FixedHeight: 0 + m_StretchWidth: 1 + m_StretchHeight: 0 + m_Settings: + m_DoubleClickSelectsWord: 1 + m_TripleClickSelectsLine: 1 + m_CursorColor: {r: 1, g: 1, b: 1, a: 1} + m_CursorFlashSpeed: -1 + m_SelectionColor: {r: 1, g: .384039074, b: 0, a: .699999988} diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin.meta new file mode 100644 index 00000000000..40240aec804 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/UberConsoleSkin.guiskin.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7018997e7c4ba41d8aa5a2338b82d57f +timeCreated: 1437656589 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png new file mode 100644 index 00000000000..0ad9537f379 Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png.meta new file mode 100644 index 00000000000..9762f65f5ac --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WarningIcon.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: ecc8f3c040a254019afd50c8bc285b48 +timeCreated: 1437663836 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png new file mode 100644 index 00000000000..84f7a959fae Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png.meta new file mode 100644 index 00000000000..7553eee175e --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WhiteTexture.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 1133c84ccb4d141f1b48c8c137f4b4ea +timeCreated: 1437657427 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png new file mode 100644 index 00000000000..cd1240457c5 Binary files /dev/null and b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png differ diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png.meta new file mode 100644 index 00000000000..a6788dd73dd --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/Art/WindowTexture.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: e4083732964464539b3e141a263f50b6 +timeCreated: 1437658895 +licenseType: Free +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE new file mode 100644 index 00000000000..c2ebf8e7932 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 bbbscarter + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE.meta new file mode 100644 index 00000000000..30d3a9b34f2 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/LICENSE.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f8478442035604d6c9af1c71c9733e99 +timeCreated: 1440268457 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md new file mode 100644 index 00000000000..408464ab45d --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md @@ -0,0 +1,61 @@ +# UberLogger +UberLogger is a free, modular, opensource replacement for Unity's +Debug.Log system. It also includes UberConsole, a replacement for +Unity's editor console, an in game console version of UberConsole, and +a file logger. + +## Core Features +* Drop in replacement for Unity's Debug.Log() methods. No code changes + needed. +* A threadsafe, modular backend that supports any number of loggers, + so Debug.Log can be routed to multiple locations. The supplied file + logger should work on mobile devices. +* Included are a replacement editor console, an in-game console and a + file logger. +* Support for named debug channels - UberDebug.LogChannel("Boot", "Some + message") can be filtered based on the channel name. +* Methods may be marked as excluded from callstacks by tagging them + with '[StackTraceIgnore]', to keep your logs tidy. + +## UberConsole Features +* More compact view shows more errors in the same space. +* Supports debug log channels. +* Messages can be filtered by regular expressions. +* Timestamps. +* Source code can be shown inline with the callstack. +* An in-game version of UberConsole is also provided. + +## Installation +* Stick the UberLogger folder somewhere under your Unity project + Assets folder. +* To use additional features like channels, use UberDebug instead of + Debug - it contains methods like Log, LogChannel, etc. +* To view the editor UberConsole, go to Window->Show Uber Console. +* To use UberConsole in your game, drag the UberAppConsole prefab into + your scene. +* Usage examples can be seen in the Examples folder. + +## Notes +* Tested in Unity 5.x, 2017.x, free and Pro. +* Logging disabled in non-debug builds. To force it on, define + ENABLE_UBERLOGGING. +* Due to file incompatibilities, the in-game console skin doesn't work + in Unity 4 and would need to be set up again. Same with the + prefab. That said, the code works, and so does the editor + UberConsole. +* Pull requests welcome! + +## Extensions +* [UberLogger-StructuredFile](https://github.com/falldamagestudio/UberLogger-StructuredFile) + adds a structured log file format with timestamps, channel names, and control over which + log messages are printed with callstacks and which are printed without. +* [UberLogger-Stackdriver](https://github.com/falldamagestudio/UberLogger-Stackdriver) + adds centralized logging. Log messages will be sent from game clients to Google's + Stackdriver service. The collected logs can be browsed and searched in the Stackdriver web UI. +* [UberLogger-LogChannels](https://github.com/falldamagestudio/UberLogger-LogChannels) + adds compile-time resolution and muting of log channels. This is useful for very large + projects where logging to muted channels causes performance problems. + + * * * * + +UberLogger: https://github.com/bbbscarter/UberLogger diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md.meta new file mode 100644 index 00000000000..43488ee47fc --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/README.md.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 951b1a41f8f1d4c57b6fbcc74ca23057 +timeCreated: 1438190280 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab new file mode 100644 index 00000000000..944412df980 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab @@ -0,0 +1,64 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &108080 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 4 + m_Component: + - 4: {fileID: 464206} + - 114: {fileID: 11463974} + m_Layer: 0 + m_Name: UberAppConsole + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &464206 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 108080} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 22.7158318, y: -1.60936856, z: 6.47446775} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 +--- !u!114 &11463974 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 108080} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a0e07a4dd7148412e9649a25c8abcb11, type: 3} + m_Name: + m_EditorClassIdentifier: + Skin: {fileID: 11400000, guid: 7018997e7c4ba41d8aa5a2338b82d57f, type: 2} + SmallErrorIcon: {fileID: 2800000, guid: f5e296e323cd64d619488c517c4692af, type: 3} + SmallWarningIcon: {fileID: 2800000, guid: ecc8f3c040a254019afd50c8bc285b48, type: 3} + SmallMessageIcon: {fileID: 2800000, guid: fa976bac27b1e440eb0d8bd71c1caac3, type: 3} + GUIColour: {r: 1, g: 1, b: 1, a: .781000018} + FontSize: 0 + SizerLineColour: {r: .164705887, g: .164705887, b: .164705887, a: 1} + SizerStartHeightRatio: .75 + ButtonTexture: {fileID: 2800000, guid: 2ae9477f7f0774b808aef406d3bf2d3c, type: 3} + ErrorButtonTexture: {fileID: 2800000, guid: f752d027f2368431c924c0306e747c4b, type: 3} + ButtonPosition: {x: 0, y: 0} + ButtonSize: {x: 32, y: 32} +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 108080} + m_IsPrefabParent: 1 diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab.meta new file mode 100644 index 00000000000..fff0c85c62a --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberAppConsole.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 82c521de7b47a4ce89bb1da3aa96e96f +timeCreated: 1438191581 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs new file mode 100644 index 00000000000..a464bf98291 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs @@ -0,0 +1,133 @@ +#if !ENABLE_UBERLOGGING && (DEVELOPMENT_BUILD || DEBUG || UNITY_EDITOR) +#define ENABLE_UBERLOGGING +#endif + +using UberLogger; + +//Helper functions to make logging easier +public static class UberDebug +{ + [StackTraceIgnore] + static public void Log(UnityEngine.Object context, string message, params object[] par) + { + #if ENABLE_UBERLOGGING + UberLogger.Logger.Log("", context, LogSeverity.Message, message, par); + #endif + } + + [StackTraceIgnore] + static public void Log(string message, params object[] par) + { + #if ENABLE_UBERLOGGING + UberLogger.Logger.Log("", null, LogSeverity.Message, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogChannel(UnityEngine.Object context, string channel, string message, params object[] par) + { + #if ENABLE_UBERLOGGING + UberLogger.Logger.Log(channel, context, LogSeverity.Message, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogChannel(string channel, string message, params object[] par) + { + #if ENABLE_UBERLOGGING + UberLogger.Logger.Log(channel, null, LogSeverity.Message, message, par); + #endif + } + + + [StackTraceIgnore] + static public void LogWarning(UnityEngine.Object context, object message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS) + UberLogger.Logger.Log("", context, LogSeverity.Warning, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogWarning(object message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS) + UberLogger.Logger.Log("", null, LogSeverity.Warning, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogWarningChannel(UnityEngine.Object context, string channel, string message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS) + UberLogger.Logger.Log(channel, context, LogSeverity.Warning, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogWarningChannel(string channel, string message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS) + UberLogger.Logger.Log(channel, null, LogSeverity.Warning, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogError(UnityEngine.Object context, object message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS) + UberLogger.Logger.Log("", context, LogSeverity.Error, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogError(object message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS) + UberLogger.Logger.Log("", null, LogSeverity.Error, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogErrorChannel(UnityEngine.Object context, string channel, string message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS) + UberLogger.Logger.Log(channel, context, LogSeverity.Error, message, par); + #endif + } + + [StackTraceIgnore] + static public void LogErrorChannel(string channel, string message, params object[] par) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS) + UberLogger.Logger.Log(channel, null, LogSeverity.Error, message, par); + #endif + } + + + //Logs that will not be caught by UberLogger + //Useful for debugging UberLogger + [LogUnityOnly] + static public void UnityLog(object message) + { + #if ENABLE_UBERLOGGING + UnityEngine.Debug.Log(message); + #endif + } + + [LogUnityOnly] + static public void UnityLogWarning(object message) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_WARNINGS) + UnityEngine.Debug.LogWarning(message); + #endif + } + + [LogUnityOnly] + static public void UnityLogError(object message) + { + #if (ENABLE_UBERLOGGING || ENABLE_UBERLOGGING_ERRORS) + UnityEngine.Debug.LogError(message); + #endif + } +} diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs.meta new file mode 100644 index 00000000000..57b13df8d65 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberDebug.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 78e53ab1366804822b3fa81f9ea350f7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs new file mode 100644 index 00000000000..0e0012b9b96 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs @@ -0,0 +1,705 @@ +using UnityEngine; +using System.Collections.Generic; +using System.Diagnostics; +using System; +using System.Reflection; +using System.Text.RegularExpressions; + +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace UberLogger +{ + //Use this to exclude methods from the stack trace + [AttributeUsage(AttributeTargets.Method)] + public class StackTraceIgnore : Attribute {} + + //Use this to stop UberLogger handling logs with this in the callstack. + [AttributeUsage(AttributeTargets.Method)] + public class LogUnityOnly : Attribute {} + + public enum LogSeverity + { + Message, + Warning, + Error, + } + + /// + /// Interface for deriving new logger backends. + /// Add a new logger via Logger.AddLogger() + /// + public interface ILogger + { + /// + /// Logging backend entry point. logInfo contains all the information about the logging request. + /// + void Log(LogInfo logInfo); + } + + /// + /// Interface for implementing new log message filter methods. + /// Filters will be applied to log messages before they are forwarded to any loggers or Unity itself. + /// + public interface IFilter + { + /// + /// Apply filter to log message. + /// Should return true if the message is to be kept, and false if the message is to be silenced. + /// + bool ApplyFilter(string channel, UnityEngine.Object source, LogSeverity severity, object message, params object[] par); + } + + //Information about a particular frame of a callstack + [System.Serializable] + public class LogStackFrame + { + public string MethodName; + public string DeclaringType; + public string ParameterSig; + + public int LineNumber; + public string FileName; + + string FormattedMethodNameWithFileName; + string FormattedMethodName; + string FormattedFileName; + + /// + /// Convert from a .Net stack frame + /// + public LogStackFrame(StackFrame frame) + { + var method = frame.GetMethod(); + MethodName = method.Name; + DeclaringType = method.DeclaringType.FullName; + + var pars = method.GetParameters(); + for (int c1=0; c1 + /// Convert from a Unity stack frame (for internal Unity errors rather than excpetions) + /// + public LogStackFrame(string unityStackFrame) + { + if(Logger.ExtractInfoFromUnityStackInfo(unityStackFrame, ref DeclaringType, ref MethodName, ref FileName, ref LineNumber)) + { + MakeFormattedNames(); + } + else + { + FormattedMethodNameWithFileName = unityStackFrame; + FormattedMethodName = unityStackFrame; + FormattedFileName = unityStackFrame; + } + } + + + /// + /// Basic stack frame info when we have nothing else + /// + public LogStackFrame(string message, string filename, int lineNumber) + { + FileName = filename; + LineNumber = lineNumber; + FormattedMethodNameWithFileName = message; + FormattedMethodName = message; + FormattedFileName = message; + } + + + + public string GetFormattedMethodNameWithFileName() + { + return FormattedMethodNameWithFileName; + } + + public string GetFormattedMethodName() + { + return FormattedMethodName; + } + + public string GetFormattedFileName() + { + return FormattedFileName; + } + + /// + /// Make a nice string showing the stack information - used by the loggers + /// + void MakeFormattedNames() + { + FormattedMethodName = String.Format("{0}.{1}({2})", DeclaringType, MethodName, ParameterSig); + + string filename = FileName; + if(!String.IsNullOrEmpty(FileName)) + { + var startSubName = FileName.IndexOf("Assets", StringComparison.OrdinalIgnoreCase); + + if(startSubName>0) + { + filename = FileName.Substring(startSubName); + } + } + FormattedFileName = String.Format("{0}:{1}", filename, LineNumber); + + FormattedMethodNameWithFileName = String.Format("{0} (at {1})", FormattedMethodName, FormattedFileName); + } + } + + /// + /// A single item of logging information + /// + [System.Serializable] + public class LogInfo + { + public UnityEngine.Object Source; + public string Channel; + public LogSeverity Severity; + public string Message; + public List Callstack; + public LogStackFrame OriginatingSourceLocation; + public double RelativeTimeStamp; + string RelativeTimeStampAsString; + public DateTime AbsoluteTimeStamp; + string AbsoluteTimeStampAsString; + + public string GetRelativeTimeStampAsString() + { + return RelativeTimeStampAsString; + } + + public string GetAbsoluteTimeStampAsString() + { + return AbsoluteTimeStampAsString; + } + + public LogInfo(UnityEngine.Object source, string channel, LogSeverity severity, List callstack, LogStackFrame originatingSourceLocation, object message, params object[] par) + { + Source = source; + Channel = channel; + Severity = severity; + Message = ""; + OriginatingSourceLocation = originatingSourceLocation; + + var messageString = message as String; + if(messageString!=null) + { + if(par.Length>0) + { + Message = System.String.Format(messageString, par); + } + else + { + Message = messageString; + } + } + else + { + if(message!=null) + { + Message = message.ToString(); + } + } + + Callstack = callstack; + RelativeTimeStamp = Logger.GetRelativeTime(); + AbsoluteTimeStamp = DateTime.UtcNow; + RelativeTimeStampAsString = String.Format("{0:0.0000}", RelativeTimeStamp); + AbsoluteTimeStampAsString = AbsoluteTimeStamp.ToString("yyyy-MM-dd HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture); + } + } + + /// + /// The core of UberLogger - the entry point for logging information + /// + public static class Logger + { + // Controls how many historical messages to keep to pass into newly registered loggers + public static int MaxMessagesToKeep = 1000; + + // If true, any logs sent to UberLogger will be forwarded on to the Unity logger. + // Useful if you want to use both systems + public static bool ForwardMessages = true; + + // Unity uses \n for line termination in internal multi-line strings. Use this instead of + // System.Environment.NewLine when you want to split multi-line strings which are emitted + // by Unity's internal APIs. + public static string UnityInternalNewLine = "\n"; + + // Unity uses forward-slashes as directory separators, regardless of OS. + // Convert from this separator to System.IO.Path.DirectorySeparatorChar before passing any Unity-originated + // paths to APIs which expect OS-native paths. + public static char UnityInternalDirectorySeparator = '/'; + + static List Loggers = new List(); + static LinkedList RecentMessages = new LinkedList(); + static long StartTick; + static bool AlreadyLogging = false; + static Regex UnityMessageRegex; + static List Filters = new List(); + + static Logger() + { + // Register with Unity's logging system +// _OR_NEWER only available from 5.3+ +#if UNITY_5 || UNITY_5_3_OR_NEWER + Application.logMessageReceivedThreaded += UnityLogHandler; +#else + Application.RegisterLogCallback(UnityLogHandler); +#endif + StartTick = DateTime.Now.Ticks; + UnityMessageRegex = new Regex(@"^([^\(]*)\((\d+)[^\)]*\)"); + } + + /// + /// Registered Unity error handler + /// + [StackTraceIgnore] + static void UnityLogHandler(string logString, string stackTrace, UnityEngine.LogType logType) + { + UnityLogInternal(logString, stackTrace, logType); + } + + static public double GetRelativeTime() + { + long ticks = DateTime.Now.Ticks; + return TimeSpan.FromTicks(ticks - StartTick).TotalSeconds; + } + + /// + /// Registers a new logger backend, which we be told every time there's a new log. + /// if populateWithExistingMessages is true, UberLogger will immediately pump the new logger with past messages + /// + static public void AddLogger(ILogger logger, bool populateWithExistingMessages=true) + { + lock(Loggers) + { + if(populateWithExistingMessages) + { + foreach(var oldLog in RecentMessages) + { + logger.Log(oldLog); + } + } + + if(!Loggers.Contains(logger)) + { + Loggers.Add(logger); + } + } + } + + /// + /// Registers a new filter mechanism, which will be able to silence any future log messages + /// + static public void AddFilter(IFilter filter) + { + lock (Loggers) + { + Filters.Add(filter); + } + } + + /// + /// Paths provided by Unity will contain forward slashes as directory separators on all OSes. + /// This method changes all forward slashes to OS-specific directory separators. + /// + static public string ConvertDirectorySeparatorsFromUnityToOS(string unityFileName) + { + return unityFileName.Replace(UnityInternalDirectorySeparator, System.IO.Path.DirectorySeparatorChar); + } + + /// + /// Tries to extract useful information about the log from a Unity error message. + /// Only used when handling a Unity error message and we can't get a useful callstack + /// + static public bool ExtractInfoFromUnityMessage(string log, ref string filename, ref int lineNumber) + { + // log = "Assets/Code/Debug.cs(140,21): warning CS0618: 'some error' + var firstMatch = UnityMessageRegex.Match(log); + + if (firstMatch.Success) + { + filename = firstMatch.Groups[1].Value; + lineNumber = Convert.ToInt32(firstMatch.Groups[2].Value); + return true; + } + return false; + } + + + /// + /// Tries to extract useful information about the log from a Unity stack trace + /// + static public bool ExtractInfoFromUnityStackInfo(string log, ref string declaringType, ref string methodName, ref string filename, ref int lineNumber) + { + // log = "DebugLoggerEditorWindow.DrawLogDetails () (at Assets/Code/Editor.cs:298)"; + var match = System.Text.RegularExpressions.Regex.Matches(log, @"(.*)\.(.*)\s*\(.*\(at (.*):(\d+)"); + + if(match.Count>0) + { + declaringType = match[0].Groups[1].Value; + methodName = match[0].Groups[2].Value; + filename = match[0].Groups[3].Value; + lineNumber = Convert.ToInt32(match[0].Groups[4].Value); + return true; + } + return false; + } + + + + struct IgnoredUnityMethod + { + public enum Mode { Show, ShowIfFirstIgnoredMethod, Hide }; + public string DeclaringTypeName; + public string MethodName; + public Mode ShowHideMode; + } + + // Example callstack when invoking Debug.LogWarning under Unity 5.5: + // Application.CallLogCallback + // DebugLogHandler.Internal_Log + // DebugLogHandler.LogFormat + // Logger.Log + // Debug.LogWarning + // + + + static IgnoredUnityMethod[] IgnoredUnityMethods = new IgnoredUnityMethod[] + { + // Internal trampoline, which invokes UberLogger's log callback + new IgnoredUnityMethod { DeclaringTypeName = "Application", MethodName = "CallLogCallback", ShowHideMode = IgnoredUnityMethod.Mode.Hide }, + + // Internal log-handling methods in Unity + new IgnoredUnityMethod { DeclaringTypeName = "DebugLogHandler", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.Hide }, + + // There are several entry points to Logger. These are primarily called by Unity's own code, but could also be called directly by 3rd party code. + // These are helpful to have on the callstack in case source code is not available (they help pinpoint the exact source code location that printed the message), + // but remaining ignored methods can safely be hidden + new IgnoredUnityMethod { DeclaringTypeName = "Logger", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod }, + + // Many of the Debug.* entry points result in log messages being printed + // These are helpful to have on the callstack in case source code is not available (they help pinpoint the exact source code location that printed the message), + // but remaining ignored methods can safely be hidden + new IgnoredUnityMethod { DeclaringTypeName = "Debug", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod }, + + // Many of the Assert.* entry points result in log messages being printed + // These are not helpful having on the callstack + // These are helpful to have on the callstack in case source code is not available (they help pinpoint the exact source code location that printed the message), + // but remaining ignored methods can safely be hidden + new IgnoredUnityMethod { DeclaringTypeName = "Assert", MethodName = null, ShowHideMode = IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod }, + }; + + /// + /// Identify a number of Unity methods which we would like to scrub from a stacktrace + /// Returns true if the method is part of scrubbing + /// + static IgnoredUnityMethod.Mode ShowOrHideMethod(MethodBase method) + { + foreach (IgnoredUnityMethod ignoredUnityMethod in IgnoredUnityMethods) + { + if ((method.DeclaringType.Name == ignoredUnityMethod.DeclaringTypeName) && ((ignoredUnityMethod.MethodName == null) || (method.Name == ignoredUnityMethod.MethodName))) + { + return ignoredUnityMethod.ShowHideMode; + } + } + + return IgnoredUnityMethod.Mode.Show; + } + + /// + /// Converts the curent stack trace into a list of UberLogger's LogStackFrame. + /// Excludes any methods with the StackTraceIgnore attribute + /// Excludes all methods (bar the first, sometimes) from a pre-defined list of ignored Unity methods/classes + /// Returns false if the stack frame contains any methods flagged as LogUnityOnly + /// + [StackTraceIgnore] + static bool GetCallstack(ref List callstack, out LogStackFrame originatingSourceLocation) + { + callstack.Clear(); + StackTrace stackTrace = new StackTrace(true); // get call stack + StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) + + bool encounteredIgnoredMethodPreviously = false; + + originatingSourceLocation = null; + + // Iterate backwards over stackframes; this enables us to show the "first" ignored Unity method if need be, but hide subsequent ones + for (int i = stackFrames.Length - 1; i >= 0; i--) + { + StackFrame stackFrame = stackFrames[i]; + + var method = stackFrame.GetMethod(); + if(method.IsDefined(typeof(LogUnityOnly), true)) + { + return true; + } + if(!method.IsDefined(typeof(StackTraceIgnore), true)) + { + IgnoredUnityMethod.Mode showHideMode = ShowOrHideMethod(method); + + bool setOriginatingSourceLocation = (showHideMode == IgnoredUnityMethod.Mode.Show); + + if (showHideMode == IgnoredUnityMethod.Mode.ShowIfFirstIgnoredMethod) + { + // "show if first ignored" methods are part of the stack trace only if no other ignored methods have been encountered already + if (!encounteredIgnoredMethodPreviously) + { + encounteredIgnoredMethodPreviously = true; + showHideMode = IgnoredUnityMethod.Mode.Show; + } + else + showHideMode = IgnoredUnityMethod.Mode.Hide; + } + + if (showHideMode == IgnoredUnityMethod.Mode.Show) + { + var logStackFrame = new LogStackFrame(stackFrame); + + callstack.Add(logStackFrame); + + if (setOriginatingSourceLocation) + originatingSourceLocation = logStackFrame; + } + } + } + + // Callstack has been processed backwards -- correct order for presentation + callstack.Reverse(); + + return false; + } + + /// + /// Converts a Unity callstack string into a list of UberLogger's LogStackFrame + /// Doesn't do any filtering, since this should only be dealing with internal Unity errors rather than client code + /// + static List GetCallstackFromUnityLog(string unityCallstack, out LogStackFrame originatingSourceLocation) + { + var lines = System.Text.RegularExpressions.Regex.Split(unityCallstack, UberLogger.Logger.UnityInternalNewLine); + + var stack = new List(); + foreach(var line in lines) + { + var frame = new LogStackFrame(line); + if(!string.IsNullOrEmpty(frame.GetFormattedMethodNameWithFileName())) + { + stack.Add(new LogStackFrame(line)); + } + } + + if (stack.Count > 0) + originatingSourceLocation = stack[0]; + else + originatingSourceLocation = null; + + return stack; + } + + /// + /// The core entry point of all logging coming from Unity. Takes a log request, creates the call stack and pumps it to all the backends + /// + [StackTraceIgnore()] + static void UnityLogInternal(string unityMessage, string unityCallStack, UnityEngine.LogType logType) + { + //Make sure only one thread can do this at a time. + //This should mean that most backends don't have to worry about thread safety (unless they do complicated stuff) + lock(Loggers) + { + //Prevent nasty recursion problems + if(!AlreadyLogging) + { + try + { + AlreadyLogging = true; + + var callstack = new List(); + LogStackFrame originatingSourceLocation; + var unityOnly = GetCallstack(ref callstack, out originatingSourceLocation); + if(unityOnly) + { + return; + } + + //If we have no useful callstack, fall back to parsing Unity's callstack + if(callstack.Count==0) + { + callstack = GetCallstackFromUnityLog(unityCallStack, out originatingSourceLocation); + } + + LogSeverity severity; + switch(logType) + { + case UnityEngine.LogType.Error: severity = LogSeverity.Error; break; + case UnityEngine.LogType.Assert: severity = LogSeverity.Error; break; + case UnityEngine.LogType.Exception: severity = LogSeverity.Error; break; + case UnityEngine.LogType.Warning: severity = LogSeverity.Warning; break; + default: severity = LogSeverity.Message; break; + } + + string filename = ""; + int lineNumber = 0; + + //Finally, parse the error message so we can get basic file and line information + if(ExtractInfoFromUnityMessage(unityMessage, ref filename, ref lineNumber)) + { + callstack.Insert(0, new LogStackFrame(unityMessage, filename, lineNumber)); + } + + var logInfo = new LogInfo(null, "", severity, callstack, originatingSourceLocation, unityMessage); + + //Add this message to our history + RecentMessages.AddLast(logInfo); + + //Make sure our history doesn't get too big + TrimOldMessages(); + + //Delete any dead loggers and pump them with the new log + Loggers.RemoveAll(l=>l==null); + Loggers.ForEach(l=>l.Log(logInfo)); + } + finally + { + AlreadyLogging = false; + } + } + } + } + + + /// + /// The core entry point of all logging coming from client code. + /// Takes a log request, creates the call stack and pumps it to all the backends + /// + [StackTraceIgnore()] + static public void Log(string channel, UnityEngine.Object source, LogSeverity severity, object message, params object[] par) + { + lock(Loggers) + { + if(!AlreadyLogging) + { + try + { + AlreadyLogging = true; + + foreach (IFilter filter in Filters) + { + if (!filter.ApplyFilter(channel, source, severity, message, par)) + return; + } + + var callstack = new List(); + LogStackFrame originatingSourceLocation; + var unityOnly = GetCallstack(ref callstack, out originatingSourceLocation); + if(unityOnly) + { + return; + } + + var logInfo = new LogInfo(source, channel, severity, callstack, originatingSourceLocation, message, par); + + //Add this message to our history + RecentMessages.AddLast(logInfo); + + //Make sure our history doesn't get too big + TrimOldMessages(); + + //Delete any dead loggers and pump them with the new log + Loggers.RemoveAll(l=>l==null); + Loggers.ForEach(l=>l.Log(logInfo)); + + //If required, pump this message back into Unity + if(ForwardMessages) + { + ForwardToUnity(source, severity, message, par); + } + } + finally + { + AlreadyLogging = false; + } + } + } + } + + /// + /// Forwards an UberLogger log to Unity so it's visible in the built-in console + /// + [LogUnityOnly()] + static void ForwardToUnity(UnityEngine.Object source, LogSeverity severity, object message, params object[] par) + { + object showObject = null; + if(message!=null) + { + var messageAsString = message as string; + if(messageAsString!=null) + { + if(par.Length>0) + { + showObject = String.Format(messageAsString, par); + } + else + { + showObject = message; + } + } + else + { + showObject = message; + } + } + + if(source==null) + { + if(severity==LogSeverity.Message) UnityEngine.Debug.Log(showObject); + else if(severity==LogSeverity.Warning) UnityEngine.Debug.LogWarning(showObject); + else if(severity==LogSeverity.Error) UnityEngine.Debug.LogError(showObject); + } + else + { + if(severity==LogSeverity.Message) UnityEngine.Debug.Log(showObject, source); + else if(severity==LogSeverity.Warning) UnityEngine.Debug.LogWarning(showObject, source); + else if(severity==LogSeverity.Error) UnityEngine.Debug.LogError(showObject, source); + } + } + + /// + /// Finds a registered logger, if it exists + /// + static public T GetLogger() where T:class + { + foreach(var logger in Loggers) + { + if(logger is T) + { + return logger as T; + } + } + return null; + } + + static void TrimOldMessages() + { + while(RecentMessages.Count > MaxMessagesToKeep) + { + RecentMessages.RemoveFirst(); + } + } + } + +} diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs.meta new file mode 100644 index 00000000000..b0adbfbc345 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLogger.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b82f8d256ff5d4555b51e2cf116640e1 +timeCreated: 1437572839 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs new file mode 100644 index 00000000000..1f487827f91 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs @@ -0,0 +1,493 @@ +using UnityEngine; +using System.Collections.Generic; +using System; +using UberLogger; + + +/// +/// The in-app console logging frontend and backend +/// +public class UberLoggerAppWindow : MonoBehaviour, UberLogger.ILogger +{ + public GUISkin Skin; + public Texture2D SmallErrorIcon; + public Texture2D SmallWarningIcon; + public Texture2D SmallMessageIcon; + public Color GUIColour = new Color(1, 1, 1, 0.5f); + + //If non-zero, scales the fonts + public int FontSize = 0; + public Color SizerLineColour = new Color(42.0f/255.0f, 42.0f/255.0f, 42.0f/255.0f); + public float SizerStartHeightRatio = 0.75f; + + public void Log(LogInfo logInfo) + { + LogInfo.Add(logInfo); + if(logInfo.Severity==LogSeverity.Error) + { + NoErrors++; + } + else if(logInfo.Severity==LogSeverity.Warning) + { + NoWarnings++; + } + else + { + NoMessages++; + } + if(logInfo.Severity==LogSeverity.Error && PauseOnError) + { + UnityEngine.Debug.Break(); + } + } + + void Clear() + { + LogInfo.Clear(); + NoWarnings = 0; + NoErrors = 0; + NoMessages = 0; + } + + void Start() + { + DontDestroyOnLoad(gameObject); + UberLogger.Logger.AddLogger(this); + ClearSelectedMessage(); + WindowRect = new Rect(0,0, Screen.width/2, Screen.height); + CurrentTopPaneHeight = Screen.height*SizerStartHeightRatio; + } + + public bool ShowWindow { get; set; } + public Texture2D ButtonTexture; + public Texture2D ErrorButtonTexture; + public Vector2 ButtonPosition; + public Vector2 ButtonSize = new Vector2(32, 32); + + /// + /// Shows either the activation button or the full UI + /// + public void OnGUI() + { + GUI.skin = Skin; + if(ShowWindow) + { + var oldGUIColor = GUI.color; + GUI.color = GUIColour; + WindowRect = new Rect(0,0, Screen.width/2, Screen.height); + //Set up the basic style, based on the Unity defaults + LogLineStyle1 = Skin.customStyles[0]; + LogLineStyle2 = Skin.customStyles[1]; + SelectedLogLineStyle = Skin.customStyles[2]; + + + + LogLineStyle1.fontSize = FontSize; + LogLineStyle2.fontSize = FontSize; + SelectedLogLineStyle.fontSize = FontSize; + + WindowRect = GUILayout.Window(1, WindowRect, DrawWindow, "Uber Console", GUI.skin.window); + GUI.color = oldGUIColor; + } + else + { + DrawActivationButton(); + } + } + + public void DrawActivationButton() + { + Texture2D buttonTex = ButtonTexture; + if(NoErrors>0) + { + buttonTex = ErrorButtonTexture; + } + var buttonPos = ButtonPosition; + buttonPos.x*=Screen.width; + buttonPos.y*=Screen.height; + if(buttonPos.x+ButtonSize.x> Screen.width) + { + buttonPos.x = Screen.width-ButtonSize.x; + } + if(buttonPos.y+ButtonSize.y > Screen.height) + { + buttonPos.y = Screen.height-ButtonSize.y; + } + var buttonRect = new Rect(buttonPos.x, buttonPos.y, ButtonSize.x, ButtonSize.y); + var style = new GUIStyle(); + + if(GUI.Button(buttonRect, buttonTex, style)) + { + ShowWindow = !ShowWindow; + } + } + + /// + /// Draws the main window + /// + void DrawWindow(int windowID) + { + // GUI.DragWindow(new Rect(0, 0, 10000, 20)); + var oldGUIColour = GUI.color; + GUI.color = GUIColour; + GUILayout.BeginVertical(GUILayout.Height(CurrentTopPaneHeight-GUI.skin.window.padding.top), GUILayout.MinHeight(100)); + DrawToolbar(); + DrawFilter(); + DrawChannels(); + DrawLogList(); + GUILayout.EndVertical(); + ResizeTopPane(); + + //Create a small gap so the resize handle isn't overwritten + GUILayout.Space(10); + GUILayout.BeginVertical(); + DrawLogDetails(); + GUILayout.EndVertical(); + GUI.color = oldGUIColour; + + DrawActivationButton(); + } + + //Some helper functions to draw buttons that are only as big as their text + bool ButtonClamped(string text, GUIStyle style) + { + return GUILayout.Button(text, style, GUILayout.MaxWidth(style.CalcSize(new GUIContent(text)).x)); + } + + bool ToggleClamped(bool state, string text, GUIStyle style) + { + return GUILayout.Toggle(state, text, style, GUILayout.MaxWidth(style.CalcSize(new GUIContent(text)).x)); + } + + bool ToggleClamped(bool state, GUIContent content, GUIStyle style, params GUILayoutOption[] par) + { + return GUILayout.Toggle(state, content, style, GUILayout.MaxWidth(style.CalcSize(content).x)); + } + + void LabelClamped(string text, GUIStyle style) + { + GUILayout.Label(text, style, GUILayout.MaxWidth(style.CalcSize(new GUIContent(text)).x)); + } + + /// + /// Draws the thin, Unity-style toolbar showing error counts and toggle buttons + /// + void DrawToolbar() + { + var toolbarStyle = GUI.skin.customStyles[3]; + GUILayout.BeginHorizontal(); + if(ButtonClamped("Clear", toolbarStyle)) + { + Clear(); + } + // PauseOnError = ToggleClamped(PauseOnError, "Pause On Error", toolbarStyle); + ShowTimes = ToggleClamped(ShowTimes, "Show Times", toolbarStyle); + + var buttonSize = toolbarStyle.CalcSize(new GUIContent("T")).y; + GUILayout.FlexibleSpace(); + + var showErrors = ToggleClamped(ShowErrors, new GUIContent(NoErrors.ToString(), SmallErrorIcon), toolbarStyle, GUILayout.Height(buttonSize)); + var showWarnings = ToggleClamped(ShowWarnings, new GUIContent(NoWarnings.ToString(), SmallWarningIcon), toolbarStyle, GUILayout.Height(buttonSize)); + var showMessages = ToggleClamped(ShowMessages, new GUIContent(NoMessages.ToString(), SmallMessageIcon), toolbarStyle, GUILayout.Height(buttonSize)); + //If the errors/warning to show has changed, clear the selected message + if(showErrors!=ShowErrors || showWarnings!=ShowWarnings || showMessages!=ShowMessages) + { + ClearSelectedMessage(); + } + ShowWarnings = showWarnings; + ShowMessages = showMessages; + ShowErrors = showErrors; + GUILayout.EndHorizontal(); + } + + /// + /// Draws the channel selector + /// + void DrawChannels() + { + var channels = GetChannels(); + int currentChannelIndex = 0; + for(int c1=0; c1 + /// Based on filter and channel selections, should this log be shown? + /// + bool ShouldShowLog(System.Text.RegularExpressions.Regex regex, LogInfo log) + { + if(log.Channel==CurrentChannel || CurrentChannel=="All" || (CurrentChannel=="No Channel" && String.IsNullOrEmpty(log.Channel))) + { + if((log.Severity==LogSeverity.Message && ShowMessages) + || (log.Severity==LogSeverity.Warning && ShowWarnings) + || (log.Severity==LogSeverity.Error && ShowErrors)) + { + if(regex==null || regex.IsMatch(log.Message)) + { + return true; + } + } + } + + return false; + } + + /// + /// Draws the main log panel + /// + public void DrawLogList() + { + var oldColor = GUI.backgroundColor; + + LogListScrollPosition = GUILayout.BeginScrollView(LogListScrollPosition); + var maxLogPanelHeight = WindowRect.height; + + float buttonY = 0; + float buttonHeight = LogLineStyle1.CalcSize(new GUIContent("Test")).y; + + System.Text.RegularExpressions.Regex filterRegex = null; + + if(!String.IsNullOrEmpty(FilterRegex)) + { + filterRegex = new System.Text.RegularExpressions.Regex(FilterRegex); + } + + int drawnButtons = 0; + var logLineStyle = LogLineStyle1; + for(int c1=0; c1LogListScrollPosition.y && buttonY + /// The bottom of the panel - details of the selected log + /// + public void DrawLogDetails() + { + var oldColor = GUI.backgroundColor; + SelectedMessage = Mathf.Clamp(SelectedMessage, 0, LogInfo.Count); + if(LogInfo.Count>0 && SelectedMessage>=0) + { + LogDetailsScrollPosition = GUILayout.BeginScrollView(LogDetailsScrollPosition); + var log = LogInfo[SelectedMessage]; + var logLineStyle = LogLineStyle1; + for(int c1=0; c1 GetChannels() + { + var categories = new HashSet(); + foreach(var logInfo in LogInfo) + { + if(!String.IsNullOrEmpty(logInfo.Channel) && !categories.Contains(logInfo.Channel)) + { + categories.Add(logInfo.Channel); + } + } + + var channelList = new List(); + channelList.Add("All"); + channelList.Add("No Channel"); + channelList.AddRange(categories); + return channelList; + } + + bool Resizing = false; + private void ResizeTopPane() + { + //Set up the resize collision rect + // float offset = GUI.skin.window.border.bottom; + float offset = 0; + var resizerRect = new Rect(0, CurrentTopPaneHeight+offset, WindowRect.width, 5f); + + var oldColor = GUI.color; + GUI.color = SizerLineColour; + GUI.DrawTexture(resizerRect, Texture2D.whiteTexture); + GUI.color = oldColor; + + if( Event.current.type == EventType.MouseDown && resizerRect.Contains(Event.current.mousePosition)) + { + Resizing = true; + } + + if(Resizing) + { + CurrentTopPaneHeight = Event.current.mousePosition.y; + } + + if(Event.current.type == EventType.MouseUp) + { + Resizing = false; + } + + + CurrentTopPaneHeight = Mathf.Clamp(CurrentTopPaneHeight, 100, WindowRect.height-100); + } + + void ClearSelectedMessage() + { + SelectedMessage = -1; + SelectedCallstackFrame = -1; + } + + Vector2 LogListScrollPosition; + Vector2 LogDetailsScrollPosition; + + + bool ShowTimes = true; + float CurrentTopPaneHeight; + int SelectedMessage = -1; + + double LastMessageClickTime = 0; + + List LogInfo = new List(); + bool PauseOnError = false; + int NoErrors; + int NoWarnings; + int NoMessages; + Rect WindowRect = new Rect(0,0, 100, 100); + + + GUIStyle LogLineStyle1; + GUIStyle LogLineStyle2; + GUIStyle SelectedLogLineStyle; + string CurrentChannel=null; + string FilterRegex = ""; + + bool ShowErrors = true; + bool ShowWarnings = true; + bool ShowMessages = true; + int SelectedCallstackFrame = 0; +} diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs.meta new file mode 100644 index 00000000000..c2d05c855e2 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerAppWindow.cs.meta @@ -0,0 +1,19 @@ +fileFormatVersion: 2 +guid: a0e07a4dd7148412e9649a25c8abcb11 +timeCreated: 1437728182 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: + - Skin: {fileID: 11400000, guid: 7018997e7c4ba41d8aa5a2338b82d57f, type: 2} + - ButtonTexture: {fileID: 2800000, guid: 2ae9477f7f0774b808aef406d3bf2d3c, type: 3} + - ErrorButtonTexture: {fileID: 2800000, guid: f752d027f2368431c924c0306e747c4b, + type: 3} + - SmallErrorIcon: {fileID: 2800000, guid: f5e296e323cd64d619488c517c4692af, type: 3} + - SmallWarningIcon: {fileID: 2800000, guid: ecc8f3c040a254019afd50c8bc285b48, type: 3} + - SmallMessageIcon: {fileID: 2800000, guid: fa976bac27b1e440eb0d8bd71c1caac3, type: 3} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs new file mode 100644 index 00000000000..b357a80a00f --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs @@ -0,0 +1,165 @@ +#if UNITY_EDITOR +using UnityEngine; +using System.Collections.Generic; +using System; +using UnityEditor; +using UberLogger; + + +/// +/// The basic editor logger backend +/// This is seperate from the editor frontend, so we can have multiple frontends active if we wish, +/// and so that we catch errors even without the frontend active. +/// Derived from ScriptableObject so it persists across play sessions. +/// +[System.Serializable] +public class UberLoggerEditor : ScriptableObject, UberLogger.ILogger +{ + List LogInfo = new List(); + HashSet Channels = new HashSet(); + + public bool PauseOnError = false; + public bool ClearOnPlay = true; + public bool WasPlaying = false; + public int NoErrors; + public int NoWarnings; + public int NoMessages; + + static public UberLoggerEditor Create() + { + var editorDebug = ScriptableObject.FindObjectOfType(); + + if(editorDebug==null) + { + editorDebug = ScriptableObject.CreateInstance(); + } + + editorDebug.NoErrors = 0; + editorDebug.NoWarnings = 0; + editorDebug.NoMessages = 0; + + return editorDebug; + } + + public void OnEnable() + { + EditorApplication.playModeStateChanged += OnPlaymodeStateChanged; + + //Make this scriptable object persist between Play sessions + hideFlags = HideFlags.HideAndDontSave; + } + + /// + /// If we're about to start playing and 'ClearOnPlay' is set, clear the current logs + /// + public void ProcessOnStartClear() + { + if(!WasPlaying && EditorApplication.isPlayingOrWillChangePlaymode) + { + if(ClearOnPlay) + { + Clear(); + } + } + WasPlaying = EditorApplication.isPlayingOrWillChangePlaymode; + } + + void OnPlaymodeStateChanged(PlayModeStateChange obj) + { + ProcessOnStartClear(); + } + + + /// + /// Interface for deriving new logger backends. + /// Add a new logger via Logger.AddLogger() + /// + public interface ILoggerWindow + { + /// + /// Logging backend entry point. logInfo contains all the information about the logging request. + /// + void OnLogChange(LogInfo logInfo); + } + List Windows = new List(); + + public void AddWindow(ILoggerWindow window) + { + if(!Windows.Contains(window)) + { + Windows.Add(window); + } + } + + public void Log(LogInfo logInfo) + { + lock(this) + { + if(!String.IsNullOrEmpty(logInfo.Channel) && !Channels.Contains(logInfo.Channel)) + { + Channels.Add(logInfo.Channel); + } + + LogInfo.Add(logInfo); + } + + if(logInfo.Severity==LogSeverity.Error) + { + NoErrors++; + } + else if(logInfo.Severity==LogSeverity.Warning) + { + NoWarnings++; + } + else + { + NoMessages++; + } + + foreach(var window in Windows) + { + window.OnLogChange(logInfo); + } + + if(logInfo.Severity==LogSeverity.Error && PauseOnError) + { + UnityEngine.Debug.Break(); + } + } + + public void Clear() + { + lock(this) + { + LogInfo.Clear(); + Channels.Clear(); + NoWarnings = 0; + NoErrors = 0; + NoMessages = 0; + + foreach(var window in Windows) + { + window.OnLogChange(null); + } + } + } + + public List CopyLogInfo() + { + lock(this) + { + return new List(LogInfo); + } + } + + public HashSet CopyChannels() + { + lock(this) + { + return new HashSet(Channels); + } + } + +} + +#endif diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs.meta new file mode 100644 index 00000000000..2eecee36315 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerEditor.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 171c7ffd53d8144faa6b0cd0cb750235 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs new file mode 100644 index 00000000000..85ec10e72e2 --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs @@ -0,0 +1,42 @@ +using UberLogger; +using System.IO; +using UnityEngine; + +/// +/// A basic file logger backend +/// +public class UberLoggerFile : UberLogger.ILogger +{ + private StreamWriter LogFileWriter; + private bool IncludeCallStacks; + + /// + /// Constructor. Make sure to add it to UberLogger via Logger.AddLogger(); + /// filename is relative to Application.persistentDataPath + /// if includeCallStacks is true it will dump out the full callstack for all logs, at the expense of big log files. + /// + public UberLoggerFile(string filename, bool includeCallStacks = true) + { + IncludeCallStacks = includeCallStacks; + var fileLogPath = System.IO.Path.Combine(Application.persistentDataPath, filename); + Debug.Log("Initialising file logging to " + fileLogPath); + LogFileWriter = new StreamWriter(fileLogPath, false); + LogFileWriter.AutoFlush = true; + } + + public void Log(LogInfo logInfo) + { + lock(this) + { + LogFileWriter.WriteLine(logInfo.Message); + if(IncludeCallStacks && logInfo.Callstack.Count>0) + { + foreach(var frame in logInfo.Callstack) + { + LogFileWriter.WriteLine(frame.GetFormattedMethodNameWithFileName()); + } + LogFileWriter.WriteLine(); + } + } + } +} diff --git a/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs.meta b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs.meta new file mode 100644 index 00000000000..f4b406b3ddd --- /dev/null +++ b/nekoyume/Assets/_Scripts/Debugger/UberLogger/UberLoggerFile.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b5a6acaaa5d694ea0a4f19ef3235bbeb +timeCreated: 1437774614 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs b/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs index 03750002f99..d2890239f37 100644 --- a/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs +++ b/nekoyume/Assets/_Scripts/UI/Widget/Base/Widget.cs @@ -269,7 +269,7 @@ public void Show(System.Action onClose, bool ignoreShowAnimation = false) public virtual void Show(bool ignoreShowAnimation = false) { - NcDebug.Log($"[Widget][{GetType().Name}] Show({ignoreShowAnimation}) invoked."); + NcDebug.Log($"[Widget][{GetType().Name}] Show({ignoreShowAnimation}) invoked.", channel: "Widget"); if (_coClose is not null) { StopCoroutine(_coClose); @@ -308,7 +308,7 @@ public void ForceClose(bool ignoreCloseAnimation = false) public virtual void Close(bool ignoreCloseAnimation = false) { - NcDebug.Log($"[Widget][{GetType().Name}] Close({ignoreCloseAnimation}) invoked."); + NcDebug.Log($"[Widget][{GetType().Name}] Close({ignoreCloseAnimation}) invoked.", channel: "Widget"); if (WidgetStack.Count > 0 && WidgetStack.Peek() == gameObject) {