1 #Region "Microsoft.VisualBasic::aee7fbf63af4e3127e69b71438483b32, Microsoft.VisualBasic.Core\ApplicationServices\Terminal\xConsole\xConsole.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module xConsole
35     
36     '         Constructor: (+1 OverloadsSub New
37     
38     '         Function: CheckNewVersion, ClearInput, ClosestConsoleColor, ConvertHexStringToByteArray, getColor
39     '                   GetConsoleWindow, (+2 Overloads) Implode, ParseLine, Print, ReadKeys
40     '                   ReadLine, RetrieveLinkerTimestamp, SetWindowPos
41     
42     '         Sub: __checkUpdates, CheckforUpdates, ClearInput, (+2 Overloads) CoolWrite, CoolWriteLine
43     '              Credits, ListFonts, RestoreColors, SetFont, SetIcon
44     '              SetWindowPos, Wait, Write, (+3 Overloads) WriteLine
45     '         Class CoolWriteSettings
46     
47     '             Properties: CoolWriting, CoolWritingDelay, CWRDDelay
48     
49     '             Constructor: (+1 OverloadsSub New
50     
51     '         Class Comparer
52     
53     '             Constructor: (+3 OverloadsSub New
54     '             Function: Find
55     
56     '         Class Spinner
57     
58     '             Constructor: (+2 OverloadsSub New
59     
60     '             Function: Turn
61     
62     '             Sub: Break, Run, RunTask
63     
64     
65     
66     
67     ' /********************************************************************************/
68
69 #End Region
70
71 '
72 ' * xConsole Source Code v 0.3.1
73 ' * Created by TheTrigger { overpowered.it } { thetriggersoft[at]]gmail[dot]com }
74 ' * 23/05/2014
75 '
76
77 Imports System.Drawing
78 Imports System.Globalization
79 Imports System.Reflection
80 Imports System.Runtime.InteropServices
81 Imports System.Text.RegularExpressions
82 Imports System.Threading
83 Imports System.Xml
84 Imports Microsoft.VisualBasic.Language
85 Imports sys = System.Math
86
87 Namespace Terminal
88
89     ''' <summary>
90     ''' Allows you to color and animate the console. ~ overpowered.it ~ TheTrigger - 💸
91     ''' </summary>
92     ''' <remarks>http://www.codeproject.com/Tips/626856/xConsole-Project</remarks>
93     Public Module xConsole
94
95 #Region "STATIC COSTRUCTOR .."
96
97         Sub New()
98             If System.Diagnostics.Debugger.IsAttached Then
99                 Try
100                     If CheckForUpdatesEnabled = True Then
101                         Call __checkUpdates()
102                     End If
103                 Catch generatedExceptionName As Exception
104                     Call App.LogException(generatedExceptionName)
105                 End Try
106             End If
107         End Sub
108
109         Private Sub __checkUpdates()
110             Dim key As Microsoft.Win32.RegistryKey =
111             Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software"True).CreateSubKey("OverPowered")
112
113             If key.GetValue("UpdateLastCheck"Is Nothing Then
114                 key.SetValue("UpdateLastCheck", 0)
115             End If
116
117             If CInt(key.GetValue("UpdateLastCheck")) < DateTime.Now.DayOfYear - 30 Then
118                 key.SetValue("UpdateLastCheck"DateTime.Now.DayOfYear)
119                 xConsole.CheckforUpdates()
120             End If
121
122             Call key.Close()
123         End Sub
124
125 #End Region
126
127 #Region "COOL WRITING ✌"
128
129         Public NotInheritable Class CoolWriteSettings
130             Private Sub New()
131             End Sub
132             ''' <summary>
133             ''' Gradual typing the output into console
134             ''' </summary>
135             Public Shared Property CoolWriting As Boolean = False
136
137             ''' <summary>
138             ''' Write speed
139             ''' </summary>
140             Public Shared Property CoolWritingDelay As Integer = 8
141
142             ''' <summary>
143             ''' Set the delay when write a new line or dots. (Default = 200).
144             ''' </summary>
145             Public Shared Property CWRDDelay As Integer = 280
146         End Class
147
148         ''' <summary>
149         ''' Gradual output animation 👍👍
150         ''' </summary>
151         ''' <param name="obj">The object to convert</param>
152         Public Sub CoolWrite(obj As Object)
153             CoolWrite(String.Format("{0}", obj))
154         End Sub
155
156         ''' <summary>
157         ''' Gradual output animation 👍👍
158         ''' </summary>
159         ''' <param name="format">The input string</param>
160         ''' <param name="args"></param>
161         Public Sub CoolWrite(format As StringParamArray args As Object())
162             AddToQueue(Sub()
163                            Dim old As Boolean = CoolWriteSettings.CoolWriting
164                            CoolWriteSettings.CoolWriting = True
165                            Call Print(String.Format(format, args))
166                            CoolWriteSettings.CoolWriting = old
167                        End Sub)
168         End Sub
169
170         ''' <summary>
171         ''' Gradual output animation
172         ''' </summary>
173         ''' <param name="format">The input string</param>
174         ''' <param name="args">Arguments</param>
175         Public Sub CoolWriteLine(format As StringParamArray args As Object())
176             Call CoolWrite(format & NEW_LINE, args)
177         End Sub
178
179         '////////////////////////////////////////////////////////////////////////////////////////////////
180         '////////////////////////////////////////////////////////////////////////////////////////////////
181         '////////////////////////////////////////////////////////////////////////////////////////////////
182 #End Region
183
184 #Region "WRITE LINE ✏"
185
186         ''' <summary>
187         ''' Allows you to write in the console-output with custom colors, followed by the current line terminator
188         ''' </summary>
189         Public Sub WriteLine()
190             Write(NEW_LINE)
191         End Sub
192
193         ''' <summary>
194         ''' Allows you to write in the console-output with custom colors, followed by the current line terminator
195         ''' </summary>
196         ''' <param name="obj">The object to convert</param>
197         Public Sub WriteLine(obj As Object)
198             Write(String.Format("{0}", obj) & NEW_LINE)
199         End Sub
200
201         ''' <summary>
202         ''' Allows you to write in the console-output with custom colors, followed by the current line terminator
203         ''' </summary>
204         ''' <param name="format">The input string</param>
205         ''' <param name="args">Arguments</param>
206         Public Sub WriteLine(format As StringParamArray args As Object())
207             Write(format & NEW_LINE, args)
208         End Sub
209
210         ''' <summary>
211         ''' Allows you to write in the console-output with custom colors
212         ''' </summary>
213         ''' <param name="format">The input string</param>
214         ''' <param name="args">Arguments</param>
215         Public Sub Write(format As StringParamArray args As Object())
216             AddToQueue(Sub() Print(String.Format(format, args)))
217         End Sub
218
219         '////////////////////////////////////////////////////////////////////////////////////////////////
220         '////////////////////////////////////////////////////////////////////////////////////////////////
221         '////////////////////////////////////////////////////////////////////////////////////////////////
222 #End Region
223
224 #Region "OTHER 🔦"
225
226         ''' <summary>
227         ''' (php-like) Implode function
228         ''' </summary>
229         ''' <param name="args">The list input</param>
230         ''' <param name="delimiter">Delimiter</param>
231         ''' <param name="start">Index offset</param>
232         ''' <returns>Imploded string</returns>
233         Public Function Implode(args As List(Of String), Optional delimiter As String = " "Optional start As Integer = 0) As String
234             Dim text As String = String.Empty
235             For i As Integer = start To args.Count - 1
236                 text += args(i) & (If((i = args.Count - 1), String.Empty, delimiter))
237             Next
238             Return text
239         End Function
240
241         ''' <summary>
242         ''' (php-like) Implode a List of strings
243         ''' </summary>
244         ''' <param name="args">The list input</param>
245         ''' <param name="start">Index offset</param>
246         ''' <returns>Imploded string</returns>
247         Public Function Implode(args As List(Of String), Optional start As Integer = 0) As String
248             Return Implode(args, Nothing, start)
249         End Function
250
251         ''' <summary>
252         ''' Just wait. in milliseconds
253         ''' </summary>
254         ''' <param name="time"></param>
255         Public Sub Wait(time As Integer)
256             AddToQueue(Sub() Thread.Sleep(time))
257         End Sub
258
259         ''' <summary>
260         ''' Restore default colors
261         ''' </summary>
262         Public Sub RestoreColors()
263             Console.ResetColor()
264             FONT_COLOR = Console.ForegroundColor
265             BACKGROUND_COLOR = Console.BackgroundColor
266         End Sub
267
268         ''' <summary>
269         ''' Show credits
270         ''' </summary>
271         Public Sub Credits()
272             WriteLine(vbCr & vbLf)
273             WriteLine(vbCr & vbTab & vbTab & "^8╒^r≡^7=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=^r≡^8╕^!")
274             WriteLine(vbCr & vbTab & vbTab & "^y│" & vbTab & "^3Created by^!:" & vbTab & "^8TheTrigger^!" & vbTab & vbTab & "^y│")
275             WriteLine(vbCr & vbTab & vbTab & "^y│" & vbTab & "^3WebSite^!:" & vbTab & "^8overpowered.it^!" & vbTab & vbTab & "^y│")
276             WriteLine(vbCr & vbTab & vbTab & "^y│" & vbTab & "^3Version^!:" & vbTab & "^g{0} ^!" & vbTab & vbTab & "^y│", MyASM.Version)
277             WriteLine(vbCr & vbTab & vbTab & "^y│" & vbTab & "^3Build Date^!:" & vbTab & "^y{0}" & vbTab & vbTab & "^y│^!.", RetrieveLinkerTimestamp().ToShortDateString())
278             WriteLine(vbCr & vbTab & vbTab & "^8╘^r■^7=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=═=^r■^8╛^!``")
279             WriteLine(vbCr & vbLf)
280         End Sub
281
282 #End Region
283
284 #Region "USER INPUT 🔣"
285
286         ''' <summary>
287         ''' Read the line, then parse it.
288         ''' </summary>
289         ''' <param name="ClearInput">Clear the buffer input</param>
290         ''' <returns>Return a List of strings</returns>
291         Public Function ReadLine(Optional Clearinput As Boolean = TrueAs List(Of String)
292             InnerQueue.WaitQueue()
293
294             If Clearinput Then
295                 xConsole.ClearInput()
296             End If
297
298             Dim sReadLine As String = Console.ReadLine()
299
300             Return ParseLine(sReadLine)
301         End Function
302
303         ''' <summary>
304         ''' Give back a ConsoleKeyInfo list
305         ''' </summary>
306         ''' <param name="Return"></param>
307         ''' <returns></returns>
308         Public Function ClearInput([Return] As BooleanAs List(Of ConsoleKeyInfo)
309             Dim CKI As New List(Of ConsoleKeyInfo)()
310             While Console.KeyAvailable
311                 CKI.Add(Console.ReadKey(False))
312             End While
313             Return CKI
314         End Function
315
316         ''' <summary>
317         ''' Clear the user input in stack
318         ''' </summary>
319         Public Sub ClearInput()
320             While Console.KeyAvailable
321                 Console.ReadKey(True)
322             End While
323         End Sub
324
325         ''' <summary>
326         ''' Parse the input string
327         ''' </summary>
328         ''' <param name="s">Input string</param>
329         ''' <returns></returns>
330         Public Function ParseLine(s As StringAs List(Of String)
331             Dim args As List(Of String) = Nothing
332
333             If String.IsNullOrWhiteSpace(s) Then
334                 args = New List(Of String)() From {
335                     String.Empty
336                 }
337                 Return args
338             End If
339
340             If even index
341             ' Split the item
342             ' Keep the entire item
343             args = s.Split(""""c).Select(Function(element, index) If(index Mod 2 = 0, element.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries), New String() {element})).SelectMany(Function(element) element).AsList()
344
345             If args.Count = 0 Then
346                 args.Add(String.Empty)
347             End If
348             Return args
349         End Function
350
351         ''' <summary>
352         ''' Read EACH keys from the buffer input (visible and hidden chars)
353         ''' </summary>
354         ''' <param name="ClearInput">Clear the buffer input</param>
355         ''' <returns>string with all chars</returns>
356         Public Function ReadKeys(Optional Clearinput As Boolean = TrueAs String
357             InnerQueue.WaitQueue()
358
359             If Clearinput Then
360                 xConsole.ClearInput()
361             End If
362
363             Dim key As New Value(Of Char)
364             Dim result As New List(Of Char)()
365             While AscW(key = Console.ReadKey(True).KeyChar) >= 0 AndAlso
366                 AscW(+key) <> 13
367                 Call result.Add(key.value)
368             End While
369
370             Return String.Join("", result)
371         End Function
372
373         '////////////////////////////////////////////////////////////////////////////////////////////////
374         '////////////////////////////////////////////////////////////////////////////////////////////////
375         '////////////////////////////////////////////////////////////////////////////////////////////////
376 #End Region
377
378 #Region "THE MAGIC-WRITER 👻"
379
380         ''' <summary>
381         ''' Convert input to color
382         ''' </summary>
383         ''' <param name="s">Input string</param>
384         ''' <returns>👽👽👽👾</returns>
385         Private Function getColor(s As StringOptional ForeC As ConsoleColor? = NothingOptional BackC As ConsoleColor? = NothingAs ConsoleColor
386             Dim FC As ConsoleColor = If(ForeC, FONT_COLOR)
387             Dim BC As ConsoleColor = If(BackC, BACKGROUND_COLOR)
388
389             If String.IsNullOrWhiteSpace(s) Then
390                 Return FC
391             End If
392
393             Dim Type As Char = s(0)
394             s = s.TrimStart(New Char() {"^"c, "*"c})
395             Dim i As Integer = -1
396
397             ' RGB case
398             If s.Length = 3 Then
399                 s = String.Format("{0}{0}{1}{1}{2}{2}", s(0), s(1), s(2))
400                 Dim colors As Byte() = ConvertHexStringToByteArray(s)
401                 Dim cc = ClosestConsoleColor(colors(0), colors(1), colors(2))
402                 Return cc
403
404                 Single Char
405             ElseIf s.Length = 1 OrElse s.Length = 2 Then
406
407                 ' INT CASE
408                 If Integer.TryParse(s, i) Then
409                     Return CType(If((i < 0 OrElse i > 16), 1, i), ConsoleColor)
410                 Else
411                     Char case
412                     Select Case s.ToLower()
413                         Case "!""-"
414                             ' Restore color
415                             Return If((Type = "^"c), FC, BC)
416
417                         Case "."
418                             ' Random color
419                             Dim c As Integer = 0
420                             Dim cList = [Enum].GetNames(GetType(ConsoleColor))
421                             Do
422                                 c = (RDN.[Next](0, cList.Length - 1))
423                             Loop While c = CInt(If((Type = "*"c), Console.ForegroundColor, Console.BackgroundColor))
424
425                             Return CType(c, ConsoleColor)
426
427                         Case "w"
428                             Return ConsoleColor.White
429                         Case "z"
430                             Return ConsoleColor.Black
431                         Case "y"
432                             Return ConsoleColor.Yellow
433                         Case "g"
434                             Return ConsoleColor.Green
435                         Case "r"
436                             Return ConsoleColor.Red
437                         Case "b"
438                             Return ConsoleColor.Blue
439                         Case "c"
440                             Return ConsoleColor.Cyan
441                         Case "m"
442                             Return ConsoleColor.Magenta
443                         Case Else
444                     End Select
445                 End If
446             End If
447             Return Console.ForegroundColor
448         End Function
449
450         Const c As String = vbCr & vbLf & ".,:;!?"
451         'string pattern = @"[\\]{0,1}(?:[\^|\*|°]{1})(?:[0-9a-fA-F]{3}|[0-9]{1,2}|[a-zA-Z!\.]{1})";
452         Const pattern As String = "[\\]{0,1}(?:[\^|\*]{1})(?:[0-9A-F]{3}|[0-9]{1,2}|[a-zA-Z!\.]{1})"
453
454         ''' <summary>
455         ''' The Parser
456         ''' </summary>
457         ''' <param name="input">Input string</param>
458         Private Function Print(input As StringAs Integer
459             If String.IsNullOrWhiteSpace(input) Then
460                 Return 0
461             End If
462
463             ' temp var for restore previous color
464             Dim ForAs ConsoleColor = Console.ForegroundColor
465             Dim Back As ConsoleColor = Console.BackgroundColor
466             Dim matches As MatchCollection = Regex.Matches(input, pattern)
467             Dim substrings As String() = Regex.Split(input, pattern)
468
469             Dim i As Integer = 0, StringSize As Integer = 0
470
471             For Each [sub] As String In substrings
472                 StringSize += [sub].Count()
473                 If CoolWriteSettings.CoolWriting Then
474                     For j As Integer = 0 To [sub].Length - 1
475                         Console.Write([sub](j))
476
477                         If c.Contains([sub](j)) AndAlso (j < [sub].Length - 1 AndAlso [sub](j + 1) <> [sub](j)) Then
478                             Thread.Sleep(CoolWriteSettings.CWRDDelay)
479                         Else
480                             Thread.Sleep(CoolWriteSettings.CoolWritingDelay)
481                         End If
482                     Next
483                 Else
484                     Console.Write([sub])
485                 End If
486
487                 If i < matches.Count Then
488                     Dim Type As Char = matches(i).Groups(0).Value(0)
489                     Select Case Type
490                         Case "*"c
491                             Console.BackgroundColor = getColor(matches(i).Groups(0).Value)
492                         Case "^"c
493                             Console.ForegroundColor = getColor(matches(i).Groups(0).Value)
494                         Case Else
495                             Console.Write("{0}", matches(i).Groups(0).Value.TrimStart("\"c))
496                     End Select
497                 End If
498
499                 i += 1
500             Next
501
502             If ClearColorsAtEnd Then
503                 Console.BackgroundColor = Fore
504                 Console.ForegroundColor = Back
505             End If
506
507             Return StringSize
508         End Function
509
510
511         '////////////////////////////////////////////////////////////////////////////////////////////////
512         '////////////////////////////////////////////////////////////////////////////////////////////////
513         '////////////////////////////////////////////////////////////////////////////////////////////////
514 #End Region
515
516 #Region "COMPARER 💻"
517
518         ''' <summary>
519         ''' This can compute the input then return back the most appropriate word.
520         ''' </summary>
521         Public Class Comparer
522
523             ''' <summary>
524             ''' This is the word to find
525             ''' </summary>
526             Public Word As String = String.Empty
527
528             ''' <summary>
529             ''' Descrizione
530             ''' </summary>
531             Public Description As String = String.Empty
532
533             ''' <summary>
534             ''' Init to 0!
535             ''' </summary>
536             Private Points As Integer = 0
537
538             ''' <summary>
539             ''' Initliaze a new instance
540             ''' </summary>
541             ''' <param name="w">The word to find</param>
542             ''' <param name="p">It's should be 0</param>
543             Public Sub New(w As String, p As Integer)
544                 Word = w
545                 Points = p
546             End Sub
547
548             ''' <summary>
549             ''' Initliaze a new instance
550             ''' </summary>
551             ''' <param name="w">The word to find</param>
552             Public Sub New(w As String)
553                 Word = w
554                 Points = 0
555             End Sub
556
557             ''' <summary>
558             ''' Initliaze a new instance
559             ''' </summary>
560             ''' <param name="w">The word to find</param>
561             ''' <param name="desc">Description (do nothing)</param>
562             Public Sub New(w As String, desc As String)
563                 Word = w
564                 Description = desc
565             End Sub
566
567             ''' <summary>
568             ''' Find a word from an input abbreviation (es n > name)
569             ''' </summary>
570             ''' <returns></returns>
571             Public Overloads Shared Function Find(abbr As StringByRef Words As List(Of Comparer)) As String
572                 Dim Result As String = String.Empty
573                 Dim Best As Integer = 0
574                 Dim c As Integer = 0
575
576                 While Words.Count > c AndAlso Words(c) IsNot Nothing
577                     Dim word = Words(c)
578
579                     If abbr = word.Word Then
580                         Result = abbr
581                         Exit While
582                     End If
583
584                     For i As Integer = 0 To abbr.Length - 1
585                         If abbr.Length < word.Word.Length AndAlso abbr(i) = word.Word(i) Then
586                             word.Points += 1
587                         Else
588                             word.Points = 0
589                             Exit For
590                         End If
591                     Next
592
593                     If word.Points > Best Then
594                         Best = word.Points
595                     End If
596
597
598                     c += 1
599                 End While
600                 End while
601                 Dim n As Integer = 0
602                 For Each word As Comparer In Words
603                     If word.Points = Best AndAlso word.Points > 0 Then
604                         Result = word.Word
605                         If System.Threading.Interlocked.Increment(n) > 1 Then
606                             Result = String.Empty
607                         End If
608                     End If
609                 Next
610
611                 Return Result
612             End Function
613         End Class
614
615         '////////////////////////////////////////////////////////////////////////////////////////////////
616         '////////////////////////////////////////////////////////////////////////////////////////////////
617         '////////////////////////////////////////////////////////////////////////////////////////////////
618 #End Region
619
620 #Region "SPINNER ⌛"
621
622         ''' <summary>
623         ''' A list of spinners for your console ❤
624         ''' </summary>
625         Public Class Spinner
626             Private counter As Integer = 0
627             Private c As Char()
628
629             ''' <summary>
630             ''' List of available spinners (you can add new)
631             ''' </summary>
632             Public Spinners As New List(Of Char())() From {
633                 New Char() {"-"c, "\"c, "|"c, "/"c},
634                 New Char() {"▄"c, "■"c, "▀"c, "■"c},
635                 New Char() {"╔"c, "╗"c, "╝"c, "╚"c},
636                 New Char() {"."c, "·"c, "`"c, "·"c},
637                 New Char() {"1"c, "2"c, "3"c, "4"c, "5"c, "6"c, "7"c, "8"c, "9"c, "0"c}
638             }
639
640             ''' <summary>
641             ''' looplooplooplooplooplooplooplooplooploop[...]
642             ''' </summary>
643             Private inLoop As Boolean = True
644
645             ''' <summary>
646             ''' The base string for spinning. {0} will display the spinner. COLOR is SUPPORTED! 🆒
647             ''' </summary>
648             Public SpinText As String = "{0} ^gLoading^!..."
649
650             ''' <summary>
651             ''' Initialize the spinner
652             ''' </summary>
653             ''' <param name="i">Index of the spinner to use</param>
654             ''' <param name="txt">Base string. `{0} show the spinner`</param>
655             Public Sub New(Optional i As Integer = 0, Optional txt As String = Nothing)
656                 If Not String.IsNullOrWhiteSpace(txt) Then
657                     SpinText = txt
658                 End If
659                 c = If((Spinners.Count > i), Spinners(i), Spinners(0))
660             End Sub
661
662             ''' <summary>
663             ''' Initialize a custom spinner
664             ''' </summary>
665             ''' <param name="spinner">Set a custom spinner, no size limit.</param>
666             Public Sub New(spinner As Char())
667                 c = spinner
668             End Sub
669
670             ''' <summary>
671             ''' Breaks the spinner
672             ''' </summary>
673             Public Sub Break()
674                 inLoop = False
675             End Sub
676
677             Private StringSize As Integer = 0
678
679             ''' <summary>
680             ''' Turn the spin!
681             ''' </summary>
682             ''' <param name="time">Waiting time. Default 130 ms</param>
683             ''' <returns>False if it has been stopped</returns>
684             ''' <example>while(spinner.Turn());</example>
685             Public Function Turn(Optional time As Integer = 130) As Boolean
686                 Dim [loop] = inLoop
687
688                 If [loop] Then
689                     counter += 1
690                     Dim wr As String = String.Format(SpinText, c(counter Mod c.Length), "wtf?")
691                     AddToQueue(Sub()
692                                    StringSize = Print(wr)
693                                    Dim left As Integer = Console.CursorLeft - StringSize
694                                    If left < 0 Then
695                                        left = 0
696                                    End If
697                                    Console.SetCursorPosition(left, Console.CursorTop)
698                                End Sub)
699
700                     Thread.Sleep(time)
701                 Else
702                     AddToQueue(Sub()
703                                    Dim pos As New Point(Console.CursorLeft, Console.CursorTop)
704                                    Console.Write(New String(" "c, StringSize))
705                                    Console.SetCursorPosition(pos.X, pos.Y)
706                                End Sub)
707                 End If
708
709                 Console.CursorVisible = Not [loop]
710
711                 Return [loop]
712             End Function
713
714             Public Sub Run(Optional speed As Integer = 130)
715                 Do While inLoop
716                     Call Turn(speed)
717                     Call Thread.Sleep(10)
718                 Loop
719             End Sub
720
721             Public Sub RunTask(Optional speed As Integer = 130)
722                 Call Parallel.RunTask(Sub() Call Run(speed))
723             End Sub
724         End Class
725
726 #End Region
727
728 #Region "SET FONT / ICON ⚠"
729
730         ''' <summary>
731         ''' Show list of fonts
732         ''' </summary>
733         Public Sub ListFonts()
734             Dim fonts = Helpers.ConsoleFonts
735
736             For f As Integer = 0 To fonts.Length - 1
737                 Console.WriteLine("{0}: X={1}, Y={2}", fonts(f).Index, fonts(f).SizeX, fonts(f).SizeY)
738             Next
739
740         End Sub
741
742         ''' <summary>
743         ''' Change console font
744         ''' </summary>
745         ''' <param name="i"></param>
746         Public Sub SetFont(Optional i As UInteger = 6)
747             Helpers.SetConsoleFont(i)
748         End Sub
749
750         Public Sub SetIcon(icon As Icon)
751             Helpers.SetConsoleIcon(icon)
752         End Sub
753
754 #End Region
755
756 #Region "Windows Positions 📍"
757
758 #Region "DLL IMPORT"
759         <DllImport("user32.dll", EntryPoint:="SetWindowPos")>
760         Private Function SetWindowPos(hWnd As IntPtr, hWndInsertAfter As Integer, x As Integer, Y As Integer, cx As Integer, cy As Integer,
761             wFlags As IntegerAs IntPtr
762         End Function
763         <DllImport("kernel32.dll", ExactSpelling:=True)>
764         Private Function GetConsoleWindow() As IntPtr
765         End Function
766         Private MyConsole As IntPtr = GetConsoleWindow()
767 #End Region
768
769         ''' <summary>
770         ''' Set new window position
771         ''' </summary>
772         Public Sub SetWindowPos(x As Integer, y As Integer)
773             SetWindowPos(MyConsole, 0, x, y, 0, 0,
774                 1)
775         End Sub
776 #End Region
777
778 #Region "SOME VARS 🔧"
779
780         ''' <summary>
781         ''' My ASM FILE
782         ''' </summary>
783         Dim MyASM As AssemblyName = Assembly.GetAssembly(GetType(xConsole)).GetName()
784
785         ''' <summary>
786         ''' Random number Generator
787         ''' </summary>
788         Dim RDN As New Random()
789
790         ''' <summary>
791         ''' This value is used when restoring the colors of the console.
792         ''' </summary>
793         Dim FONT_COLOR As ConsoleColor = Console.ForegroundColor
794         ''' <summary>
795         ''' This value is used when restoring the colors of the console.
796         ''' </summary>
797         Dim BACKGROUND_COLOR As ConsoleColor = Console.BackgroundColor
798
799         ''' <summary>
800         ''' Default line terminator
801         ''' </summary>
802         ReadOnly NEW_LINE As String = Environment.NewLine
803
804         ''' <summary>
805         ''' Check for updates every 7days. False to disable. (Default = true);
806         ''' </summary>
807         Public CheckForUpdatesEnabled As Boolean = True
808
809         ''' <summary>
810         ''' Clear colors automatically at the end of each Writeline. (Default = false);
811         ''' </summary>
812         Public ClearColorsAtEnd As Boolean = False
813
814
815 #End Region
816
817 #Region "THIRD PART ✅"
818         ''' <summary>
819         ''' Convert rgb color to ConsoleColor. From stackoverflow
820         ''' </summary>
821         Private Function ClosestConsoleColor(r As Byte, g As Byte, b As ByteAs ConsoleColor
822             Dim ret As ConsoleColor = 0
823             Dim rr As Double = r, gg As Double = g, bb As Double = b, delta As Double = Double.MaxValue
824
825             For Each cc As ConsoleColor In [Enum].GetValues(GetType(ConsoleColor))
826                 Dim n = [Enum].GetName(GetType(ConsoleColor), cc)
827                 Dim c = Color.FromName(If(n = "DarkYellow""Orange", n))
828                 Dim t = sys.Pow(c.R - rr, 2.0) + sys.Pow(c.G - gg, 2.0) + sys.Pow(c.B - bb, 2.0)
829                 If t = 0.0 Then
830                     Return cc
831                 End If
832                 If t < delta Then
833                     delta = t
834                     ret = cc
835                 End If
836             Next
837             Return ret
838         End Function
839
840
841         ''' <summary>
842         ''' Linker Timestamp
843         ''' </summary>
844         Private Function RetrieveLinkerTimestamp() As DateTime
845             ' from stackoverflow
846             Dim filePath As String = System.Reflection.Assembly.GetCallingAssembly().Location
847             Const c_PeHeaderOffset As Integer = 60
848             Const c_LinkerTimestampOffset As Integer = 8
849             Dim b As Byte() = New Byte(2047) {}
850             Dim s As System.IO.Stream = Nothing
851
852             Try
853                 s = New System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
854                 s.Read(b, 0, 2048)
855             Finally
856                 If s IsNot Nothing Then
857                     s.Close()
858                 End If
859             End Try
860
861             Dim i As Integer = System.BitConverter.ToInt32(b, c_PeHeaderOffset)
862             Dim secondsSince1970 As Integer = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset)
863             Dim dt As New DateTime(1970, 1, 1, 0, 0, 0)
864             dt = dt.AddSeconds(secondsSince1970)
865             dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours)
866             Return dt
867         End Function
868
869
870         ''' <summary>
871         ''' Convert String to byte array
872         ''' </summary>
873         ''' <param name="hexString"></param>
874         ''' <returns></returns>
875         Private Function ConvertHexStringToByteArray(hexString As StringAs Byte()
876             ' from stackoverflow
877             If hexString.Length Mod 2 <> 0 Then
878                 Throw New ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString))
879             End If
880
881             Dim HexAsBytes As Byte() = New Byte(hexString.Length \ 2 - 1) {}
882             For index As Integer = 0 To HexAsBytes.Length - 1
883                 Dim byteValue As String = hexString.Substring(index * 2, 2)
884                 HexAsBytes(index) = Byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture)
885             Next
886
887             Return HexAsBytes
888         End Function
889
890 #End Region
891
892 #Region "CHECK FOR NEW VERSION ♻"
893
894         Public Sub CheckforUpdates()
895             CheckForUpdatesEnabled = False
896
897             New version
898             ' BACK TO THE FUTURE!? wooooooooo
899             ' up to date
900             Call New Thread(Sub()
901                                 Thread.Sleep(10)
902                                 Dim data = CheckNewVersion()
903                                 If Not String.IsNullOrWhiteSpace(data("url").ToString()) Then
904                                     xConsole.WriteLine("[^mxConsole^!] ^6Current Ver: ^y{0}^! / ^6Latest: ^y{1}^!", MyASM.Version, data("ver"))
905                                     Dim compared As Integer = MyASM.Version.CompareTo(data("ver"))
906                                     If compared = -1 Then
907                                         xConsole.WriteLine("[^mxConsole^!] ^gNew version available!^!")
908                                         xConsole.WriteLine("[^mxConsole^!]^11 Download/info page: ^w{0}^!", data("url"))
909                                     ElseIf compared = 1 Then
910                                         xConsole.WriteLine("[^mxConsole^!] *y^r>>>^6" & vbNullChar & "BACK TO THE ^rFUTURE!^!*!")
911                                     Else
912                                         xConsole.WriteLine("[^mxConsole^!] ^gUp to date! :)^!")
913                                     End If
914                                 Else
915                                     xConsole.WriteLine("[^mxConsole^!] ^rCan not check for updates :/^!")
916                                 End If
917
918                             End Sub).Start()
919         End Sub
920
921         Private Function CheckNewVersion() As Dictionary(Of StringObject)
922             Dim reader As XmlTextReader = Nothing
923             Dim data As New Dictionary(Of StringObject)()
924             data.Add("ver"New Version())
925             data.Add("url"String.Empty)
926
927             Try
928                 Dim xmlURL As String = "http://trigger.overpowered.it/xConsole/curr_version.xml"
929                 reader = New XmlTextReader(xmlURL)
930                 xConsole.WriteLine("[^mxConsole^!] ^6Checking for newer version...^!")
931
932                 reader.MoveToContent()
933
934                 Dim elementName As String = ""
935
936                 If (reader.NodeType = XmlNodeType.Element) AndAlso (reader.Name = "data"Then
937                     While reader.Read()
938                         If reader.NodeType = XmlNodeType.Element Then
939                             elementName = reader.Name
940                         Else
941                             If (reader.NodeType = XmlNodeType.Text) AndAlso (reader.HasValue) Then
942                                 Select Case elementName
943                                     Case "version"
944                                         data("ver") = New Version(reader.Value)
945
946
947                                     Case "url"
948                                         data("url") = reader.Value
949
950
951                                 End Select
952                             End If
953                         End If
954                     End While
955                 End If
956
957             Catch generatedExceptionName As Exception
958             Finally
959                 If reader IsNot Nothing Then
960                     reader.Close()
961                 End If
962             End Try
963
964             Return data
965         End Function
966 #End Region
967     End Module
968 End Namespace