Oct 092017
 
Visual Basic 6.0 logo

A long, long time ago, there was a pretty useful little IRC bot for Windows called the [AnGeL] bot. It seems like nobody remembers it anymore, but it was born from the Anime / Sailor Moon scene back in the late 90s to early 2000s and developed by a German software engineer going by the name of [Benedikt Hübschen]. The bot was pretty widespread for a while, at least in the German speaking parts of the Internet, and it was extensible by writing VBScript code using Microsofts’ Windows Script Host.

So, essentially, it was what you’d have used if you couldn’t run UNIX or Linux with an eggdrop bot. And I sure couldn’t, because back then I barely even knew about the existence of such systems.

Recently, I ran into a small little problem though; I wanted the bot to create and maintain an SSL/TLS-only channel. So, an IRC channel that would let users join and chat with each other only if they’re connecting to the IRC server via an encrypted connection. This is usually done by setting the +z flag on the channel, which might be followed by the IRC server itself also setting the encryption indicator mode +Z automatically.

However, I found that the bot wouldn’t enforce +z at all. It wouldn’t even set the mode when asked to do so explicitly. It was possible to add it to the list of enforced modes, but it just wouldn’t work, with the same being true for +P (protect channel modes even when nobody is in the channel).

Luckily, Mr. Hübschen made the source code available under the GPL license (that’s what he told me personally) [here]! And yes, that is VisualBasic 6 code. And yes, VB6 is a part of the infamous Visual Studio 6, you might know the abbreviation “VC6” from C/C++ programs compiled with it. So I though I’d inspect the source code and attempt to fix this issue.

I fired up my Windows 2000 Pro SP4 virtual machine for that, installed Visual Studio 6 (thank you, MSDNAA/Dreamspark/Imagine) and its service pack 6, and then loaded the project file:

The AnGeL IRC bot source code loaded in VB6

That development environment is ancient, and it sure looks the part… what a mess.

I identified the part of the code that would need changing, it’s in the public function ChangeMode() in SourceCode/Modules/Server/Server_Functions.bas. I simply copied some code and adapted it for my purpose, adding just +z and +P support for now:

Server_Functions.bas, expand/collapse source code
  1. Public Function ChangeMode(Should As String, Current As String) ' : AddStack "Routines_ChangeMode(" & Should & ", " & Current & ")"
  2. Dim u As Long, CurMode As Long, Changes As String, InsertWhat As String
  3. Dim CurPos As Long, LimitPos As Long, KeyPos As Long
  4.   ' Added by GrandAdmiralThrawn (http://wp.xin.at/archives/4343):
  5.   ' modes +z (SSL/TLS enforce) and +P (permanent channel with
  6.   ' modes preservation even when empty):
  7.   CurMode = GetModeChar(Current, "z")
  8.   Select Case GetModeChar(Should, "z")
  9.     Case -1: If CurMode = 1 Then Changes = Changes & "-z"
  10.     Case 1: If CurMode = 0 Then Changes = Changes & "+z"
  11.   End Select
  12.   CurMode = GetModeChar(Current, "P")
  13.   Select Case GetModeChar(Should, "P")
  14.     Case -1: If CurMode = 1 Then Changes = Changes & "-P"
  15.     Case 1: If CurMode = 0 Then Changes = Changes & "+P"
  16.   End Select
  17.   ' End of modification by GAT.
  18.   CurMode = GetModeChar(Current, "p")
  19.   Select Case GetModeChar(Should, "p")
  20.     Case -1: If CurMode = 1 Then Changes = Changes & "-p"
  21.     Case 1: If CurMode = 0 Then Changes = Changes & "+p"
  22.   End Select
  23.   CurMode = GetModeChar(Current, "s")
  24.   Select Case GetModeChar(Should, "s")
  25.     Case -1: If CurMode = 1 Then Changes = Changes & "-s"
  26.     Case 1: If CurMode = 0 Then Changes = Changes & "+s"
  27.   End Select
  28.   CurMode = GetModeChar(Current, "m")
  29.   Select Case GetModeChar(Should, "m")
  30.     Case -1: If CurMode = 1 Then Changes = Changes & "-m"
  31.     Case 1: If CurMode = 0 Then Changes = Changes & "+m"
  32.   End Select
  33.   CurMode = GetModeChar(Current, "t")
  34.   Select Case GetModeChar(Should, "t")
  35.     Case -1: If CurMode = 1 Then Changes = Changes & "-t"
  36.     Case 1: If CurMode = 0 Then Changes = Changes & "+t"
  37.   End Select
  38.   CurMode = GetModeChar(Current, "i")
  39.   Select Case GetModeChar(Should, "i")
  40.     Case -1: If CurMode = 1 Then Changes = Changes & "-i"
  41.     Case 1: If CurMode = 0 Then Changes = Changes & "+i"
  42.   End Select
  43.   CurMode = GetModeChar(Current, "n")
  44.   Select Case GetModeChar(Should, "n")
  45.     Case -1: If CurMode = 1 Then Changes = Changes & "-n"
  46.     Case 1: If CurMode = 0 Then Changes = Changes & "+n"
  47.   End Select
  48.   If InStr(ServerChannelModes, "c") Then
  49.     CurMode = GetModeChar(Current, "c")
  50.     Select Case GetModeChar(Should, "c")
  51.       Case -1: If CurMode = 1 Then Changes = Changes & "-c"
  52.       Case 1: If CurMode = 0 Then Changes = Changes & "+c"
  53.     End Select
  54.   End If
  55.   If InStr(ServerChannelModes, "C") Then
  56.     CurMode = GetModeChar(Current, "C")
  57.     Select Case GetModeChar(Should, "C")
  58.       Case -1: If CurMode = 1 Then Changes = Changes & "-C"
  59.       Case 1: If CurMode = 0 Then Changes = Changes & "+C"
  60.     End Select
  61.   End If
  62.  
  63.   For u = 1 To Len(Should)
  64.     Select Case Mid(Should, u, 1)
  65.       Case "l": If GetModeChar(Should, "l") = 1 Then CurPos = CurPos + 1: LimitPos = CurPos + 1
  66.       Case "k": CurPos = CurPos + 1: KeyPos = CurPos + 1
  67.       Case " ": Exit For
  68.     End Select
  69.   Next u
  70.  
  71.   CurMode = GetModeChar(Current, "l")
  72.   Select Case GetModeChar(Should, "l")
  73.     Case -1: If CurMode = 1 Then Changes = Changes & "-l"
  74.     Case 1
  75.       If CurMode = 0 Then Changes = Changes & "+l": InsertWhat = " " & Param(Should, LimitPos)
  76.       If CurMode = 1 Then If Param(Current, 2) <> Param(Should, LimitPos) Then Changes = Changes & "+l": InsertWhat = " " & Param(Should, LimitPos)
  77.   End Select
  78.   CurMode = GetModeChar(Current, "k")
  79.   Select Case GetModeChar(Should, "k")
  80.     Case -1: If CurMode = 1 Then Changes = Changes & "-k" & InsertWhat & " " & Param(Current, ParamCount(Current)): InsertWhat = ""
  81.     Case 1: If CurMode = 0 Then Changes = Changes & "+k" & InsertWhat & " " & Param(Should, KeyPos): InsertWhat = ""
  82.   End Select
  83.  
  84.   Changes = CleanModes(Changes)
  85.   ChangeMode = Changes & InsertWhat
  86. End Function

Honestly, I didn’t think it would actually compile at all. But just hit File \ Make AnGeL.exe, and it all builds just fine! And it’s fast as well. At least the building process is.

I chose to have VB6 “Optimize for fast code” and to have it “favor Pentium Pro(tm)”, whatever that means. But I assume it’s faster on P6 / i686 architectures now (Pentium Pro, Pentium II/III and other more modern chips). Probably also requires such a processor now, breaking compatibility with 586 and earlier chips, but I’m not sure whether that’s true.

I gave it the version number 1.6.3, with the latest I could ever find on the web before having been 1.6.2. You can download this version together with the source code here:

If you just want to run it instead of an existing one, all you need to do is to copy the AnGeL.exe over the one you have now, and that’s it. To edit the code, you need VisualBasic 6, just load the project file ANGEL.VBP and you can start to modify and recompile it.

Hah, changing the AnGeL bot and building its source code after so many years… felt a little bit like touching the holy grail or something. ;)

My thanks fly out for Benedikt Hübschen for developing the AnGeL bot, and for open-sourcing it! Also, I would like to thank all the contributors to the project as well! I’ll continue to use the bot, probably for a long time to come. :)

CC BY-NC-SA 4.0 Fixing and (re)compiling ancient software: The AnGeL IRC bot © 2017 by The GAT at XIN.at is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

 Leave a Reply

CC BY-NC-SA 4.0 logo GPLv3 logo All text and images/files you post here will be implicitly licensed under the free [CC BY-NC-SA 4.0] license, and all source code you post will be implicitly licensed under the free [GNU General Public License version 3.0] unless explicity stated otherwise by yourself in your comment!

Warning 1: This site runs very modern software on an [ancient server] with four Pentium II Overdrive 333MHz CPUs. It's really slow when handling comments! Please click on "Submit Comment" only once! Do not click repeatedly, or the spambot detection system may ban you! Even if you land on a "white page of death" or receive a timeout, do not re-send your comment, it'll likely still have gone through. Consider re-sending it only if I haven't approved it within a few days. Check the newest post on this weblog to make sure I'm not on vacation or something, increasing the time it'd take for me to approve comments.

Warning 2: This site uses [Akismet] to reduce spam. The following parts of your comment data need to be shared with its operator, [Automattic]: IP, nick name, eMail, user agent, referrer, URL and the comments' content. [Learn how your comment data is processed].

Note: Your eMail address will not be published!

You may use these HTML tags and attributes: <em>⋯</em> <i>⋯</i> <b>⋯</b> <s>⋯</s> <u>⋯</u> <sub>⋯</sub> <sup>⋯</sup> <strike>⋯</strike> <strong>⋯</strong> <p style="">⋯</p> <code>⋯</code> <pre lang="" line="" escaped="">⋯</pre> <a href="" title="">⋯</a> <abbr title="">⋯</abbr> <acronym title="">⋯</acronym> <blockquote cite="">⋯</blockquote> <cite>⋯</cite> <q cite="">⋯</q> <span style="">⋯</span>. You may also use the [spoiler][/spoiler] shortcode to insert spoilers.

(required)

(required)