VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsCommandMgmt"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
'// Should this be different for each bot?
'// Instantiated CommandManagement Class for each Bot Object

Private CommandPool() As objCmd
Public BotIndex As Integer

Public Sub ImportCustom()
On Error Resume Next
    Dim FL() As String, I As Integer, File As String
    FL = FileList(AppData & "Commands\Custom Commands\*.txt")
    For I = 0 To UBound(FL)
        File = Left$(FL(I), Len(FL(I)) - 4)
        Dim MC$, MA$, MR$, CT%, MH$, MP$
        ReadCommand File, MC, MA, MP, MH, CT, MR
        Dim O As New objCmd
        DeleteCommand MC
        Set O = CreateCommand(MC, 3)
        O.Alias = MA
        O.Help = MH
        O.Parameters = MP
        O.Response = MR
        O.Use = CT
        O.CallbackIndex = BotIndex
    Next I
    If BotIndex = SelBot Then RefreshProfileCommandList
End Sub

Public Function GetPool() As Object()
    Dim GP() As Object, I As Integer
    ReDim GP(UBound(CommandPool))
    For I = 0 To UBound(CommandPool)
        Set GP(I) = CommandPool(I)
    Next I
    GetPool = GP
End Function

Public Sub DeleteType(Optional Owner As String, Optional Script As Boolean)
    Dim I As Integer, X As Integer
    If Script Then X = 1 Else X = 2
    For I = UBound(CommandPool) To 0 Step -1
        If CommandPool(I).Exposure = X Then
            Dim Cmd As String
            If Len(Owner) > 0 Then
                If LCase$(CommandPool(I).Owner) = LCase$(Owner) Then
                    Cmd = CommandPool(I).Cmd
                    DeleteCommand Cmd
                End If
            Else
                Cmd = CommandPool(I).Cmd
                DeleteCommand Cmd
            End If
        End If
    Next I
    If SelBot = BotIndex Then RefreshProfileCommandList
End Sub

Public Sub ImportInternal(Optional DeleteFirst As Boolean)
On Error GoTo hErr:
1   Call Init
    Dim r() As String, I As Integer, Section As String
2   r = Split(ReadFile(AppData & "Commands\Import.dat"), vbNewLine)
3   For I = 0 To UBound(r)
4       If InStr(r(I), "|") Then
5           Dim S() As String
6           S = Split(r(I), "|")
            'Command|Alias|Parameters|Help|Use
7           If UBound(S) = 4 Then
8               Dim O As New objCmd
                If DeleteFirst Then DeleteCommand S(0)
9               Set O = CreateCommand(S(0), 0)
                If Not O Is Nothing Then
10                  With O
11                      .Alias = S(1)
12                      .Help = S(3)
13                      .Callback = "cmd" & S(0)
                        .CallbackIndex = BotIndex
14                      .Owner = Section
15                      .Use = Val(S(4))
16                      .Parameters = S(2)
                    End With
                End If
            End If
        Else
            If Len(r(I)) > 0 Then
                Section = r(I)
            End If
        End If
    Next
    If BotIndex = SelBot Then RefreshProfileCommandList
19  Erase r
    Exit Sub
hErr:
    ErrorHandler Err.Number, Err.Description, Erl, "CommandManagement", "ImportInternal"
End Sub

Public Function Init()
    ReDim CommandPool(0)
    Set CommandPool(0) = New objCmd
End Function

Public Function Commands(Owner As String) As String()
    Dim I As Integer, C() As String
    ReDim C(0)
    For I = 0 To UBound(CommandPool)
        If LCase$(CommandPool(I).Owner) = LCase$(Owner) Then
            If LenB(C(0)) > 0 Then ReDim Preserve C(UBound(C) + 1)
            C(UBound(C)) = CommandPool(I).Cmd
        End If
    Next I
    Commands = C
End Function

Public Function RunCommand(CS As Object)
On Error GoTo hErr:
    Dim I As Integer, RankName As String, r As RankingStruct
    CS.Username = Suffix(CS.Username)
    If LenB(CS.Username) = 0 Then
        CS.IsConsole = True
        CS.Display = 3
    Else
        r = GetAccess(CS)
        RankName = r.RankName
    End If
    
    Dim ExactMatch As Boolean
1   For I = 0 To UBound(CommandPool)
        ExactMatch = False
        If LCase$(CS.Command) = LCase$(CommandPool(I).Cmd) Then ExactMatch = True
        If LenB(CommandPool(I).Alias) Then
            If LCase$(CS.Command) = LCase$(CommandPool(I).Alias) Then ExactMatch = True
        End If
        Dim CanUse As Boolean
        Select Case CommandPool(I).Use
        Case 0
            CanUse = (CommandDefined(CS.Command, CS.Index) = False Or _
                        CS.Display = 3 Or _
                        CS.IsConsole Or _
                        CommandCapable(CommandPool(I).Cmd, RankName, CS.Index))
        Case 1
            CanUse = CS.IsConsole = True
        Case 2
            CanUse = (CommandDefined(CS.Command, CS.Index) = False Or _
                        CommandCapable(CommandPool(I).Cmd, RankName, CS.Index)) And _
                        CS.IsConsole = False
        End Select
2       If ExactMatch And CanUse Then
            Select Case CommandPool(I).Exposure
            Case 0  'Internal
                ' Find Person Issuing Command
                If LenB(CommandPool(I).Callback) = 0 Then Exit Function
                Dim cmdHdl As New clsCommandHandler
3               CallByName cmdHdl, CommandPool(I).Callback, VbMethod, CS
                Set cmdHdl = Nothing
            Case 1  'Script
                If LenB(CommandPool(I).Callback) = 0 Then Exit Function
4               If frmBot.Bot(CommandPool(I).CallbackIndex).ScriptEnabled(CommandPool(I).Owner) Then
5                   frmBot.Bot(CommandPool(I).CallbackIndex).scProcessObj CommandPool(I).Owner, CommandPool(I).Callback, CS
                End If
            Case 2  'Plugin
                'Check if plugin is enabled
                If LenB(CommandPool(I).Callback) = 0 Then Exit Function
6               If frmBot.Bot(CommandPool(I).CallbackIndex).PluginEnabled(CommandPool(I).Owner) Then
7                   frmBot.Bot(CommandPool(I).CallbackIndex).plProcessObj CommandPool(I).Owner, CommandPool(I).Callback, CS
                End If
            Case 3  'Custom Command
                'Run Response
                Dim Resp As String, U As objUser, D As objDbUser, C As objMember
8               Resp = CommandPool(I).Response
9               Set U = CS.Bot.Users.GetByName(CS.Username)
                Set C = CS.Bot.Clan.GetByName(CS.Username)
10              Set D = CS.Bot.Database.GetUser(CS.Bot.Database.Find(CS.Username))
11              If Not U Is Nothing Then
12                  Resp = Replace$(Resp, "%clan", ExtractClanName(U.Statstring))
                    Resp = Replace$(Resp, "%gameid", U.Client)
13                  Resp = Replace$(Resp, "%game", ProductToStr(U.Client))
14                  Resp = Replace$(Resp, "%flags", U.Flags)
15                  Resp = Replace$(Resp, "%ping", U.Ping)
16                  Resp = Replace$(Resp, "%speaker", U.Username)
17                  Resp = Replace$(Resp, "%stats", DisplayStatInfoByUser(U))
                Else
18                  Resp = Replace$(Resp, "%clan", "N/A")
                    Resp = Replace$(Resp, "%gameid", "N/A")
                    Resp = Replace$(Resp, "%game", "N/A")
19                  Resp = Replace$(Resp, "%flags", "N/A")
20                  Resp = Replace$(Resp, "%ping", "N/A")
21                  Resp = Replace$(Resp, "%speaker", CS.Username)
22                  Resp = Replace$(Resp, "%stats", "N/A")
                End If
                If Not C Is Nothing Then
                    Resp = Replace$(Resp, "%clanrank", ClanRankToString(C.Rank))
                Else
                    Resp = Replace$(Resp, "%clanrank", "N/A")
                End If
23              If Not D Is Nothing Then
24                  Resp = Replace$(Resp, "%dbrank", D.Rank)
                Else
25                  Resp = Replace$(Resp, "%dbrank", "N/A")
                End If
                Resp = Replace$(Resp, "%dbcount", CS.Bot.Database.Count)
26              If InStr(CS.Message, " ") > 0 Then
                    Dim nv As Integer, rest As String, V As Integer, parts() As String
27                  parts = Split(CS.Message, " ")
28                  For V = 0 To UBound(parts)
29                     If InStrB(Resp, "%" & V + 1) Then nv = V + 1: Resp = Replace$(Resp, "%" & V + 1, parts(V))
                    Next
30                  For V = nv To UBound(parts)
31                      rest = rest & parts(V) & " "
                    Next
32                  If LenB(rest) Then
33                      rest = Left$(rest, Len(rest) - 1)
34                      Resp = Replace$(Resp, "%rest", rest)
                    End If
35              ElseIf LenB(CS.Message) Then
36                  Resp = Replace$(Resp, "%1", CS.Message)
37                  Resp = Replace$(Resp, "%rest", CS.Message)
                End If
                
38              Resp = Replace$(Resp, "%self", CS.Bot.Self.Username)
39              Resp = Replace$(Resp, "%sysup", DateTimeToShortestString(ConvertTickCount(DblTickCount)))
40              Resp = Replace$(Resp, "%botup", DateTimeToShortestString(ConvertTickCount(DblTickCount - TickLaunch)))
41              Resp = Replace$(Resp, "%connup", DateTimeToShortestString(ConvertTickCount(DblTickCount - CS.Bot.Self.TickOnline)))
42              Resp = Replace$(Resp, "%chancount", CS.Bot.Users.Count)
43              Resp = Replace$(Resp, "%friendcount", CS.Bot.Friends.Count)
44              Resp = Replace$(Resp, "%clancount", CS.Bot.Clan.Count)
45              Resp = Replace$(Resp, "%channel", CS.Bot.Self.Channel)
46              Resp = Replace$(Resp, "%date", Date)
47              Resp = Replace$(Resp, "%server", CS.Bot.Config.ServerNameEx)
48              Resp = Replace$(Resp, "%time", Time)
49              Resp = Replace$(Resp, "%version", "MirageBot " & AppVersion)

                'Clan<User>
                'ClanRank<User>
                'DbRank<User>
                'Flags<User>
                'Game<User>
                'GameID<User>
                'If<Expression ? TrueValue : FalseValue?>
                'Ping<User>
                'Stats<User>

                If Not options.CommandGlobal Then
                    Dim grPos As Integer, Content As String
50                  grPos = InStr(Resp, "DbRank<")
51                  Do Until grPos = 0
52                      Content = Mid$(Resp, grPos + 7)
53                      Content = Split(Content, ">")(0)
54                      Set D = CS.Bot.Database.GetUser(CS.Bot.Database.Find(Content))
55                      If Not D Is Nothing Then
56                          Resp = Left$(Resp, grPos - 1) & D.Rank & Mid$(Resp, grPos + 7 + Len(Content) + 1)
                        Else
57                          Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 7 + Len(Content) + 1)
                        End If
58                      grPos = InStr(Resp, "DbRank<")
                    Loop
59                  grPos = InStr(Resp, "ClanRank<")
60                  Do Until grPos = 0
61                      Content = Mid$(Resp, grPos + 9)
62                      Content = Split(Content, ">")(0)
63                      Set C = CS.Bot.Clan.GetByName(Content)
64                      If Not C Is Nothing Then
65                          Resp = Left$(Resp, grPos - 1) & ClanRankToString(C.Rank) & Mid$(Resp, grPos + 9 + Len(Content) + 1)
                        Else
66                          Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 9 + Len(Content) + 1)
                        End If
67                      grPos = InStr(Resp, "ClanRank<")
                    Loop
68                  grPos = InStr(Resp, "Clan<")
69                  Do Until grPos = 0
70                      Content = Mid$(Resp, grPos + 5)
71                      Content = Split(Content, ">")(0)
72                      Set U = CS.Bot.Users.GetByName(Content)
73                      If Not U Is Nothing Then
74                          Dim GCN As String
75                          GCN = ExtractClanName(U.Statstring): If LenB(GCN) = 0 Then GCN = "N/A"
76                          Resp = Left$(Resp, grPos - 1) & GCN & Mid$(Resp, grPos + 5 + Len(Content) + 1)
                        Else
77                          Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 5 + Len(Content) + 1)
                        End If
78                      grPos = InStr(Resp, "Clan<")
                    Loop
79                  grPos = InStr(Resp, "Ping<")
80                  Do Until grPos = 0
81                      Content = Mid$(Resp, grPos + 5)
82                      Content = Split(Content, ">")(0)
83                      Set U = CS.Bot.Users.GetByName(Content)
84                      If Not U Is Nothing Then
85                          Resp = Left$(Resp, grPos - 1) & U.Ping & Mid$(Resp, grPos + 5 + Len(Content) + 1)
                        Else
86                          Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 5 + Len(Content) + 1)
                        End If
87                      grPos = InStr(Resp, "Ping<")
                    Loop
88                  grPos = InStr(Resp, "Flags<")
89                  Do Until grPos = 0
90                      Content = Mid$(Resp, grPos + 6)
91                      Content = Split(Content, ">")(0)
92                      Set U = CS.Bot.Users.GetByName(Content)
93                      If Not U Is Nothing Then
94                          Resp = Left$(Resp, grPos - 1) & U.Flags & Mid$(Resp, grPos + 6 + Len(Content) + 1)
                        Else
95                          Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 6 + Len(Content) + 1)
                        End If
96                      grPos = InStr(Resp, "Flags<")
                    Loop
97                  grPos = InStr(Resp, "Game<")
98                  Do Until grPos = 0
99                      Content = Mid$(Resp, grPos + 5)
100                     Content = Split(Content, ">")(0)
101                     Set U = CS.Bot.Users.GetByName(Content)
102                     If Not U Is Nothing Then
103                         Resp = Left$(Resp, grPos - 1) & ProductToStr(U.Client) & Mid$(Resp, grPos + 5 + Len(Content) + 1)
                        Else
104                         Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 5 + Len(Content) + 1)
                        End If
105                     grPos = InStr(Resp, "Game<")
                    Loop
106                 grPos = InStr(Resp, "GameID<")
107                 Do Until grPos = 0
108                     Content = Mid$(Resp, grPos + 7)
109                     Content = Split(Content, ">")(0)
110                     Set U = CS.Bot.Users.GetByName(Content)
111                     If Not U Is Nothing Then
112                         Resp = Left$(Resp, grPos - 1) & U.Client & Mid$(Resp, grPos + 7 + Len(Content) + 1)
                        Else
113                         Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 7 + Len(Content) + 1)
                        End If
114                     grPos = InStr(Resp, "GameID<")
                    Loop
115                 grPos = InStr(Resp, "Stats<")
116                 Do Until grPos = 0
117                     Content = Mid$(Resp, grPos + 6)
118                     Content = Split(Content, ">")(0)
119                     Set U = CS.Bot.Users.GetByName(Content)
120                     If Not U Is Nothing Then
121                         Resp = Left$(Resp, grPos - 1) & DisplayStatInfoByUser(U) & Mid$(Resp, grPos + 6 + Len(Content) + 1)
                        Else
122                         Resp = Left$(Resp, grPos - 1) & "N/A" & Mid$(Resp, grPos + 6 + Len(Content) + 1)
                        End If
123                     grPos = InStr(Resp, "Stats<")
                    Loop
124                 grPos = InStr(Resp, "If<")
125                 Do Until grPos = 0
126                     Content = Mid$(Resp, grPos + 3)
127                     Content = Split(Content, "?>")(0)
128                     If InStr(Content, " ? ") Then
129                         Dim Sep() As String, Comp() As String, RetVal As String, ret() As String
130                         RetVal = vbNS
131                         Sep = Split(Content, " ? ")
132                         If UBound(Sep) = 1 Then
133                             If InStr(Sep(0), "=") Then
134                                 Comp = Split(Sep(0), "=")
135                                 ret = Split(Sep(1), " : ")
136                                 If UBound(ret) = 1 Then
137                                     If LCase$(Comp(0)) = LCase$(Comp(1)) Then
138                                         RetVal = ret(0)
                                        Else
139                                         RetVal = ret(1)
                                        End If
                                    End If
140                             ElseIf InStr(Sep(0), "<") Then
141                                 Comp = Split(Sep(0), "<")
142                                 ret = Split(Sep(1), " : ")
143                                 If UBound(ret) = 1 Then
144                                     If Val(Comp(0)) < Val(Comp(1)) Then
145                                         RetVal = ret(0)
                                        Else
146                                         RetVal = ret(1)
                                        End If
                                    End If
147                             ElseIf InStr(Sep(0), ">") Then
148                                 Comp = Split(Sep(0), ">")
149                                 ret = Split(Sep(1), " : ")
150                                 If UBound(ret) = 1 Then
151                                     If Val(Comp(0)) > Val(Comp(1)) Then
152                                         RetVal = ret(0)
                                        Else
153                                         RetVal = ret(1)
                                        End If
                                    End If
154                             ElseIf InStr(Sep(0), "~") Then
155                                 Comp = Split(Sep(0), "~")
156                                 ret = Split(Sep(1), " : ")
157                                 If UBound(ret) = 1 Then
158                                     If LCase$(Comp(0)) Like LCase$(Comp(1)) Then
159                                         RetVal = ret(0)
                                        Else
160                                         RetVal = ret(1)
                                        End If
                                    End If
161                             ElseIf InStr(Sep(0), "^") Then
162                                 Comp = Split(Sep(0), "^")
163                                 ret = Split(Sep(1), " : ")
164                                 If UBound(ret) = 1 Then
165                                     If InStr(LCase$(Comp(0)), LCase$(Comp(1))) Then
166                                         RetVal = ret(0)
167                                     Else
168                                         RetVal = ret(1)
                                        End If
                                    End If
                                End If
                            End If
                        End If
169                     Resp = Left$(Resp, grPos - 1) & RetVal & Mid$(Resp, grPos + 3 + Len(Content) + 2)
170                     grPos = InStr(Resp, "If<")
                    Loop
                End If
171             CS.Bot.SendLines Resp
            End Select
            RunCommand = True
            Exit Function
        End If
    Next I
    Exit Function
hErr:
    ErrorHandler Err.Number, Err.Description, Erl, "CommandManagement", "RunCommand '" & CS.Command & "'"
End Function

Public Function CreateCommand(Name As String, Optional Exposure As Integer) As Object
On Error GoTo hErr:
    If LenB(Name) = 0 Then Exit Function
1   Dim I As Integer
2   For I = 0 To UBound(CommandPool)
3       If CommandPool(I).Cmd = LCase$(Name) Then
4           Set CreateCommand = Nothing: Exit Function
        End If
    Next
5   If LenB(CommandPool(0).Cmd) <> 0 Then
        ReDim Preserve CommandPool(UBound(CommandPool) + 1)
        Set CommandPool(UBound(CommandPool)) = New objCmd
    End If
6   CommandPool(UBound(CommandPool)).Cmd = LCase$(Name)
7   CommandPool(UBound(CommandPool)).Exposure = Exposure
8   Set CreateCommand = CommandPool(UBound(CommandPool))
    Exit Function
hErr:
    ErrorHandler Err.Number, Err.Description, Erl, "CommandManagement", "CreateCommand"
End Function

Public Function DeleteCommand(Name As String) As Boolean
On Error GoTo hErr:
    If LenB(Name) = 0 Then Exit Function
    DeleteCommand = False
1   Dim I As Integer
2   For I = 0 To UBound(CommandPool)
3       If CommandPool(I).Cmd = LCase$(Name) Then
4           DeleteCommand = True
5           CommandPool(I).Cmd = vbNS
        End If
    Next
6   For I = UBound(CommandPool) To 0 Step -1
7       If Len(CommandPool(I).Cmd) = 0 Then
            Dim r As Integer
8           For r = I To UBound(CommandPool) - 1
9               Set CommandPool(r) = CommandPool(r + 1)
10          Next
            If UBound(CommandPool) = 0 Then
                ReDim CommandPool(0)
                Set CommandPool(0) = New objCmd
            Else
11              ReDim Preserve CommandPool(UBound(CommandPool) - 1)
            End If
        End If
    Next
    Exit Function
hErr:
    ErrorHandler Err.Number, Err.Description, Erl, "CommandManagement", "DeleteCommand"
End Function

Public Function OpenCommand(Name As String) As Object
On Error GoTo hErr:
1   Dim I As Integer
2   For I = 0 To UBound(CommandPool)
3       If CommandPool(I).Cmd = LCase$(Name) Or CommandPool(I).Alias = LCase$(Name) Then
4           Set OpenCommand = CommandPool(I): Exit Function
        End If
    Next
hErr:
5   Set OpenCommand = Nothing
End Function

Public Sub List()
    Dim C As ComboBox, r As RichTextBox
    Set C = frmCommandList.cbo
    C.Clear
    Dim I As Integer, H As Integer
    For H = 0 To UBound(Ranking)
        If CommandCount(Ranking(H).RankName) > 0 Then
            C.AddItem Ranking(H).RankName
            If LenB(frmCommandList.r(0).Tag) Then Load frmCommandList.r(frmCommandList.r.Count)
            Set r = frmCommandList.r(frmCommandList.r.UBound)
            r.Tag = Ranking(H).RankName
            r.Text = vbNS
            ReDim StrOut(0)
            For I = 0 To UBound(CommandPool)
                With CommandPool(I)
                    If CommandCapable(.Cmd, Ranking(H).RankName, SelBot) Then
                        If LenB(StrOut(0)) > 0 Then ReDim Preserve StrOut(UBound(StrOut) + 1)
                        StrOut(UBound(StrOut)) = .Owner & "¦<b>" & .Cmd & IIf(Len(.Alias), "/" & .Alias, vbNS) & "</b>" & _
                                IIf(Len(.Parameters), " <i>(" & .Parameters & ")</i>", vbNS) & _
                                " - " & .Help
                    End If
                End With
            Next I
            MedianThreeQuickSort1 StrOut
            For I = 0 To UBound(StrOut)
                If InStrB(StrOut(I), "¦") Then
                    If strTitle <> Split(StrOut(I), "¦")(0) Then
                        strTitle = Split(StrOut(I), "¦")(0)
                        frmCommandList.Output1 r, "<b>" & strTitle & "</b>"
                    End If
                    frmCommandList.Output2 r, CStr(Split(StrOut(I), "¦", 2)(1))
                End If
            Next
            r.SelStart = 0
            r.SelLength = Len(r.Text)
            r.SelFontSize = 10
            r.SelFontName = "Tahoma"
            r.SelHangingIndent = 200
            r.SelStart = 0
            r.SelLength = 0
        End If
    Next
    
    
    C.AddItem "<Console>"
    If LenB(frmCommandList.r(0).Tag) Then Load frmCommandList.r(frmCommandList.r.Count)
    Set r = frmCommandList.r(frmCommandList.r.UBound)
    r.Tag = "Console"
    r.Text = vbNS
    ReDim StrOut(0)
    For I = 0 To UBound(CommandPool)
        With CommandPool(I)
            If .Use = 1 Then
                If LenB(StrOut(0)) > 0 Then ReDim Preserve StrOut(UBound(StrOut) + 1)
                StrOut(UBound(StrOut)) = .Owner & "¦<b>" & .Cmd & IIf(Len(.Alias), "/" & .Alias, "</b>") & vbNS & _
                        IIf(Len(.Parameters), " <i>(" & .Parameters & ")</i>", vbNS) & _
                        " - " & .Help
            End If
        End With
    Next I
    MedianThreeQuickSort1 StrOut
    For I = 0 To UBound(StrOut)
        If InStrB(StrOut(I), "¦") Then
            If strTitle <> Split(StrOut(I), "¦")(0) Then
                strTitle = Split(StrOut(I), "¦")(0)
                frmCommandList.Output1 r, "<b>" & strTitle & "</b>"
            End If
            frmCommandList.Output2 r, CStr(Split(StrOut(I), "¦", 2)(1))
        End If
    Next
    r.SelStart = 0
    r.SelLength = Len(r.Text)
    r.SelFontSize = 10
    r.SelFontName = "Tahoma"
    r.SelHangingIndent = 200
    r.SelStart = 0
    r.SelLength = 0
    
    
    
    C.AddItem "<Unranked>"
    If LenB(frmCommandList.r(0).Tag) Then Load frmCommandList.r(frmCommandList.r.Count)
    Set r = frmCommandList.r(frmCommandList.r.UBound)
    r.Tag = "Unranked"
    r.Text = vbNS
    ReDim StrOut(0)
    For I = 0 To UBound(CommandPool)
        With CommandPool(I)
            If CommandDefined(.Cmd, SelBot) = False And .Use <> 1 Then
                If LenB(StrOut(0)) > 0 Then ReDim Preserve StrOut(UBound(StrOut) + 1)
                StrOut(UBound(StrOut)) = .Owner & "¦<b>" & .Cmd & IIf(Len(.Alias), "/" & .Alias, "</b>") & vbNS & _
                        IIf(Len(.Parameters), " <i>(" & .Parameters & ")</i>", vbNS) & _
                        " - " & .Help
            End If
        End With
    Next I
    MedianThreeQuickSort1 StrOut
    For I = 0 To UBound(StrOut)
        If InStrB(StrOut(I), "¦") Then
            If strTitle <> Split(StrOut(I), "¦")(0) Then
                strTitle = Split(StrOut(I), "¦")(0)
                frmCommandList.Output1 r, "<b>" & strTitle & "</b>"
            End If
            frmCommandList.Output2 r, CStr(Split(StrOut(I), "¦", 2)(1))
        End If
    Next
    r.SelStart = 0
    r.SelLength = Len(r.Text)
    r.SelFontSize = 10
    r.SelFontName = "Tahoma"
    r.SelHangingIndent = 200
    r.SelStart = 0
    r.SelLength = 0
    
    Erase StrOut

    frmCommandList.Show
    C.ListIndex = 0
End Sub


