Author | Message | Time |
---|---|---|
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 |