| 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 |