Valhalla Legends Forums Archive | Battle.net Bot Development | [VB6] Problem With Ban Command

AuthorMessageTime
Dyndrilliac
Lately to kill time I've been rewriting parts of my bot's code. I got to the commands today and decide to finally implement wildcard support.

Here's what I have:[code]Case "ban"
If HaveOps = False Then
AddQ "/w " & UserName & " Error: I am not currently an operator."
GoTo Ending
End If
Dim Name As String
Name = Split(Text(1), " ")(0)
Do Until Left$(Name, 1) <> " "
Name = Mid$(Name, 2)
Loop
If Name = vbNullString Then
AddQ "/w " & UserName & " Error: Invalid Username!"
GoTo Ending
End If
Splt() = Split(Text(1), " ", 2)
Dim sBanMessage As String
sBanMessage = Splt(1)
If InStr(Name, "*") <> 0 Then
Dim x As Integer
x = 1
For x
If Match(frmMain.ChannelList.ListItems.Item(x), Name) = True Then
If GetList(Access(), frmMain.ChannelList.ListItems.Item(x)) = True Then
AddQ "/w " & UserName & "Error: That user is in the database."
Else
AddQ "/ban " & frmMain.ChannelList.ListItems.Item(x) & " " & sBanMessage
If bIPBan = True Then
AddQ "/ignore " & frmMain.ChannelList.ListItems.Item(x)
End If
End If
End If
Next x[/code]

It errors when it gets to the beginning of the For ... Loop I'm pretty sure most of it is correct, I'm also pretty sure I'm checking in the wrong place for the full username to compare the wildcard to.

Any help would be appreciated.
May 31, 2004, 5:55 AM
warz
Might want to go ahead and insert a "exit function" at the end of that first if statement so it doesnt do all that work for no reason. you might also want to look into the like operator.

[code]
wildcard = (name Like searchstring)
[/code]

returns a bool value
May 31, 2004, 6:00 AM
tA-Kane
I have decided to write a document (in my spare time) on how to write a custom wildcard matching function, similar to my parsing a BNI file document.

Hopefully I'll have it done in a week or two. If this thread isn't still on the first page of these forums when the document is finished, I'll create a new thread.
May 31, 2004, 6:57 AM
Dyndrilliac
The matching function to compare the 2 strings works, and everything there works except the place where im looking for the string to compare the wildcard to and the for loop... However, I look forward to reading it nonetheless.

[code]Public Function Match(ByVal uName As String, ByVal Check As String) As Boolean
Call PrepareCheck(Check)
If uName = Empty Then
Match = False
Exit Function
End If
If LCase$(uName) Like LCase$(Check) Then Match = True
End Function

Public Sub PrepareCheck(ByRef Check As String)
Check = Replace(Check, "[", "§")
Check = Replace(Check, "]", "¨")
Check = Replace(Check, "§", "[[]")
Check = Replace(Check, "¨", "[]]")
Check = Replace(Check, "#", "[#]")
Check = Replace(Check, "-", "[-]")
End Sub[/code]

Warz, that doesn't help me at all. I already have the actual checking mechanism. See above.
May 31, 2004, 7:09 AM
Fire
Rather then doing For x, I would do something like For x = 0 to ChannelList.ListCount - 1. When you find the name, add a statement such as Exit Function or goto ending in your case.
Hope that helps
May 31, 2004, 9:38 AM
Gangz
Here is an example of how the like operator could work for you.


[code]
argSplit = Split(message)
If UCase(argSplit(0)) = Form1.varTrigger & "BAN" Then
templen = Len(argSplit(0) & argSplit(1)) + 1: If templen <> Len(message) Then temp = Mid(message, templen + 1)
If InStr(argSplit(1), "*") Then
For X = 0 To Form1.ul.ListCount - 1
If UCase(Form1.ul.List(X)) Like UCase(argSplit(1)) Then Form1.cboQueue.AddItem "/ban " & Form1.ul.List(X) & temp
Next X
Else: Form1.cboQueue.AddItem "/ban " & argSplit(1) & temp
End If
End If
[/code]

its a little messy but you should be able to understand it.

Edit: After more throughly reading the above posts. Having the match function is just adding more trouble for yourself. Doing it by the method above, is less coding then what you have just on the ban command, not including the function too. Its easier to find problems if you dont relay it to so many different parts.
May 31, 2004, 4:55 PM
Fire
Most likely he uses this method and style of coding throughout his program. It is in his best interest to simply add a For x = 0 to ChannelList.ListCount -1 check, and Exiting/Goto the end of a function.

Such as:

[code]
Dim x As Integer
For x = 0 to frmMain.ChannelList.ListCount - 1
If Match(frmMain.ChannelList.ListItems.Item(x), Name) = True Then
If GetList(Access(), frmMain.ChannelList.ListItems.Item(x)) = True Then
AddQ "/w " & UserName & "Error: That user is in the database."
Else
AddQ "/ban " & frmMain.ChannelList.ListItems.Item(x) & " " & sBanMessage
If bIPBan = True Then
AddQ "/ignore " & frmMain.ChannelList.ListItems.Item(x)
End If
End If
End If
Next x

[/code]

[code] If InStr(argSplit(1), "*") Then [/code]

I would recommend against this type of check, there is no contraint on the position of the wildcard operator/amount of * there are.
Example: $ban **abc*

I would simply do a compare using the Mid(argSplit(1), 6,1), assuming your command
is as follows:
Example: $ban *abc
May 31, 2004, 8:45 PM
tA-Kane
[quote author=tA-Kane link=board=17;threadid=7047;start=0#msg62914 date=1085986622]
I have decided to write a document (in my spare time) on how to write a custom wildcard matching function, similar to my parsing a BNI file document.

Hopefully I'll have it done in a week or two. If this thread isn't still on the first page of these forums when the document is finished, I'll create a new thread.
[/quote]


I suddenly got extremely lazy and unmotivated when I found some bugs in the code that I was going to base my document off off (code of mine that's just under a year old).

So, against my better judgement, I'm just going to paste my wildcardcompare() function instead. It's not like it's hard work, anyways...

[code]Function WildcardCompare(WildcardStr As String, CompareStr As String) As Function
Dim WildLoc, CompareLoc, NextCompare As Integer
Dim CurrentWild, NextWild, CurrentCompare As String
Dim WasMassWild As Boolean
Dim Count As Integer

'Please, if you MODIFY this code, do send me the changes you make (even to an
'email at kane@clan-mac.com), and the reason. Feel free to USE the code as
'you wish.

WildLoc = 1
CompareLoc = 1
Do
Again:
CurrentWild = Mid(WildcardStr,WildLoc,1)
CurrentCompare = Mid(CompareStr,CompareLoc,1)
Select Case CurrentWild
Case "*"
FoundWild:
NextWild = Mid(WildcardStr,WildLoc+1,1)
If NextWild = "" Then
'last char is a masswild, all chars before match; so must match.
Return True
ElseIf NextWild = "*" Then
WildLoc = WildLoc+1
GoTo Again
ElseIf NextWild = "?" Then
WasMassWild = True 'For the case of recovering from "*?"
WildLoc = WildLoc+1
'CompareLoc = CompareLoc+1
GoTo Again
End If
NextCompare = InStr(CompareLoc,CompareStr,NextWild)
CurrentCompare = Mid(CompareStr,NextCompare,1)
If NextWild <> CurrentCompare Then
Return False
Else
WildLoc = WildLoc+2
CompareLoc = NextCompare+1
End If
Case "?"
If CurrentCompare = "" And WasMassWild = False Then
Return False
ElseIf CurrentCompare = "" And WasMassWild = True And Mid(WildcardStr,WildLoc+1,1) = "" Then
Return True
Else
WildLoc = WildLoc+1
CompareLoc = CompareLoc+1
NextWild = Mid(WildcardStr,WildLoc,1)
If WasMassWild = True And NextWild <> "*" And NextWild <> "?" Then
WasMassWild = False
End If
End If
Case ""
If CurrentCompare = "" Or WasMassWild = True Then
Return True
Else
'end of wild string, compare string has more; DOESNT MATCH
Return False
End If
Else
If WasMassWild = True Then
GoTo FoundWild
End If
If CurrentWild <> CurrentCompare Then
Return False
Else
WildLoc = WildLoc+1
CompareLoc = CompareLoc+1
End If
End Select
Count = Count + 1
If Count > 255 Then
Beep
MsgBox "Infinite loop"
Return False
End If
Loop
End Function[/code]

WildcardStr is the string with the wildcard, and CompareStr is the string to compare it against.

If it returns false, then CompareStr doesn't match WildcardStr, and the contrary for true.

A neat thing with this is that you can have a wildcard with a minimum number of characters by using "(? times minimum characters)+*" ... so for "????*", you would have a wildcard with a minimum number of 4 characters... anything less than that won't match.

Additionally, you can have a maximum number of characters, as well. Simply move the asterisk to the front of the question marks, instead of having it after them.

Even more, you could specify both a minimum and a maximum by using "????*????" (whereas the minimum would be the number of quetsion marks in the left set of question marks, and the maximum would be the minimum + the number of question marks in the right set of question marks).

One of the bigger bugs is in specifying both a min and a max... if you have a string both before and after (so, for example, "asdf????*????adsf"), it always uses the maximum instead of having a minimum as well.

I'm sure it'd be an easy fix (hey, the code's very simple), but I'm just too lazy. Maybe if I had a reason to update this?

FYI, this function specifies a maximum length of 255 characters. You can easily remove that by removing the Count variable, and then removing the bottom-most 6 lines of code within the loop (so, everything between End Select and Loop).

Have fun.

Please, if you MODIFY this code, do send me the changes you make (even to an email at kane@clan-mac.com), and the reason. Feel free to USE the code as you wish.
June 1, 2004, 7:49 AM
Grok
Dyndrilliac, if your bot is not an operator, and someone tells it to ban, it looks like it immediately does an AddQ "/w " & UserName & " I am not currently an operator." Bad idea. Check security before deciding to respond. Don't let unauthorized people make your bot do much of anything.
June 2, 2004, 4:05 AM
Dyndrilliac
[quote author=Grok link=board=17;threadid=7047;start=0#msg63214 date=1086149138]
Dyndrilliac, if your bot is not an operator, and someone tells it to ban, it looks like it immediately does an AddQ "/w " & UserName & " I am not currently an operator." Bad idea. Check security before deciding to respond. Don't let unauthorized people make your bot do much of anything.
[/quote]

I just posted the section of code that has to do with the code for the ban command, it doesnt do any thing anyone tells it to unless they are on the user list - then it chacks for trigger, number of commands being issued, the names of commands, and then splits everything after that into an array.

I just need to get this command to work...

Which it still doesn't.

This is what I have:

[code]Case "ban"
If HaveOps = False Then
AddQ "/w " & UserName & " Error: I am not currently an operator."
GoTo ErrCommand
Else
Dim sName As String
sName = Split(Text(1), " ")(0)
Do Until Left$(sName, 1) <> " "
sName = Mid$(sName, 2)
Loop
If sName = vbNullString Then
AddQ "/w " & UserName & " Error: Invalid Username!"
GoTo ErrCommand
End If
Splt() = Split(Text(1), " ", 2)
Dim sBanMessage As String
sBanMessage = Splt(1)
'// * Wildcard support = not finished.
If InStr(sName, "*") <> 0 Then
Dim g As Integer
'// Error on For...Loop
For g = 0 To frmMain.ChannelList.ListItems.Count - 1
If Match(frmMain.ChannelList.ListItems.Item(g), sName) = True Then
If GetList(Access(), frmMain.ChannelList.ListItems.Item(g)) = True Then
Else
AddQ "/ban " & frmMain.ChannelList.ListItems.Item(g) & " " & sBanMessage
If bIPBan = True Then
AddQ "/ignore " & frmMain.ChannelList.ListItems.Item(g)
End If
End If
End If
Next g[/code]
June 2, 2004, 5:02 AM
tA-Kane
[quote author=Dyndrilliac link=board=17;threadid=7047;start=0#msg63220 date=1086152557]I just need to get this command to work...

Which it still doesn't.[/quote]Debugging! Examples of problematic usage!

[quote author=Dyndrilliac link=board=17;threadid=7047;start=0#msg63220 date=1086152557][code]Case "ban"
If HaveOps = False Then
AddQ "/w " & UserName & " Error: I am not currently an operator."
GoTo ErrCommand
Else
Dim sName As String
sName = Split(Text(1), " ")(0)
Do Until Left$(sName, 1) <> " "
sName = Mid$(sName, 2)
Loop
If sName = vbNullString Then
AddQ "/w " & UserName & " Error: Invalid Username!"
GoTo ErrCommand
End If
Splt() = Split(Text(1), " ", 2)
Dim sBanMessage As String
sBanMessage = Splt(1)
'// * Wildcard support = not finished.
If InStr(sName, "*") <> 0 Then
Dim g As Integer
'// Error on For...Loop
For g = 0 To frmMain.ChannelList.ListItems.Count - 1
If Match(frmMain.ChannelList.ListItems.Item(g), sName) = True Then
If GetList(Access(), frmMain.ChannelList.ListItems.Item(g)) = True Then
Else
AddQ "/ban " & frmMain.ChannelList.ListItems.Item(g) & " " & sBanMessage
If bIPBan = True Then
AddQ "/ignore " & frmMain.ChannelList.ListItems.Item(g)
End If
End If
End If
Next g[/code][/quote]

The first thing that comes to my mind is
[code]If Match(frmMain.ChannelList.ListItems.Item(g), sName) = True Then[/code]Check to make sure you're passing the correct paramters to Match(). I'm not familiar with with Match(), but I wrote *my* WildcardCompare() to have the wildcard string (in this case, sName) passed first.

Next up, I saw[code]If GetList(Access(), frmMain.ChannelList.ListItems.Item(g)) = True Then
Else[/code]Does GetList() return true if the user is allowed to use !ban, or return true if the user is not allowed? If it returns true if the user IS allowed, then there's your problem.

Also, you should check if the user is allowed long before you do any major processing... like, I would check if the user is allowed before I even check to see if you have ops, that way it doesn't even send the "I don't have ops" reply to the user if they're not allowed to use !ban.

Lastly, I saw this comment:[code]'// * Wildcard support = not finished.[/code]

You should try to finish your supporting functions before you write the functions that use the supporting functions. In this case, Match() (I assume) would be your supporting function that would need to be finished.

If your support functions are incomplete, it could return unexpected results.
June 5, 2004, 8:19 PM
Dyndrilliac
All the actual functions are complete, I just added that in there to remind myself I haven't fixed the ban/kick commands.

Here's GetList():[code]Function GetList(List() As String, Compare As String) As Boolean
On Error GoTo ExitHandle

Dim i As Integer
i = 0

Do Until List(i) = vbNullString
If LCase(Compare) = LCase(List(i)) Then
GetList = True
Exit Function
Else
i = i + 1
End If
Loop

GetList = False
Exit Function
ExitHandle:
GetList = False
End Function[/code]

[quote]Also, you should check if the user is allowed long before you do any major processing... like, I would check if the user is allowed before I even check to see if you have ops, that way it doesn't even send the "I don't have ops" reply to the user if they're not allowed to use !ban.[/quote]

Did you even read my post?

[quote]I just posted the section of code that has to do with the code for the ban command, it doesnt do any thing anyone tells it to unless they are on the user list - then it chacks for trigger, number of commands being issued, the names of commands, and then splits everything after that into an array.[/quote]

I check for that already -.-....
[code]If GetList(Access(), LCase(UserName)) = True Then
If Message = "?trigger" Then
AddQ "/w " & UserName & " Trigger is: " & varTrigger & " (ALT + 00" & Asc(varTrigger) & ")"
Else
CommandRecognition tmp, Message
End If
End If[/code]

The ban command, as with all my other commands, are in the CommandRecognition Sub. I just chose to post only the RELEVANT pieces of code...

And I already posted my Match function.
June 5, 2004, 11:42 PM
tA-Kane
I blame the Like operator.
June 6, 2004, 11:25 PM

Search