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