' general declarations:' define global arraysDim iplistarraya() As StringDim iplistarrayi() As StringDim logfilearraya() As StringDim logfilearrayi() As String' define global countersDim logfilelength As LongDim iplistlength As Long' define global flagsDim resetclicked As IntegerDim ipfileopen As IntegerDim logfileopen As Integer' define global path variablesDim logfilepath As StringDim iplistpath As String' ------------------------------------Private Sub form_load()' set initial values for flags, path vars, and counters upon startuplogfilepath = "c:\logs\"iplistpath = "c:\logs\iplist.txt"iplistlength = 0logfilelength = 0resetclicked = 0End SubPrivate Sub logopenbutton_Click()' using the path from the server log path global variable, open the ip list' verify that server log file has contents (quickly error check path and file content)' add contents of log file to log file array' cull useless values from log file array and sort it' make the log file buttons accessable (not greyed out)Dim templogfilearray() As StringDim temparraya() As StringDim temparrayi() As StringDim checkchar As StringDim index As LongDim index2 As LongDim index3 As Longindex = 0index2 = 0index3 = 0Dim aliasendpos As LongDim aliaslength As LongDim iplength As LongDim ipendpos As LongDim tempstring As Stringaliasendpos = 0aliaslength = 0iplength = 0ipendpos = 0logfileopen = 0If logfilepath = "c:\" Or logfilepath = "" Then MsgBox "The Path you have entered for the Log File is incomplete, Please Re-Enter."Else ' open logfile for reading and if file is empty close it and ask for another path ' if it has contents, read contents into temp arrays and count # of lines indicator.Caption = "Opening File Please Wait.." Open logfilepath For Input As #1 If LOF(1) > 0 Then While Not EOF(1) ReDim Preserve templogfilearray(0 To index) As String Line Input #1, templogfilearray(index) checkchar = Mid$(templogfilearray(index), 20, 1) If checkchar = "(" And InStr(templogfilearray(index), " connected from") <> 0 Then ReDim Preserve logfilearraya(0 To index) As String ReDim Preserve logfilearrayi(0 To index) As String ' calculate alias length and the start position aliasendpos = InStr(templogfilearray(index), " connected from") - 1 aliaslength = aliasendpos - 20 logfilearraya(index) = Mid$(templogfilearray(index), 21, aliaslength) ' calculate the ip length and start position ipendpos = Len(templogfilearray(index)) iplength = ipendpos - aliaslength - 37 logfilearrayi(index) = Mid$(templogfilearray(index), aliasendpos + 17, iplength) ' increment the value that will be the global logfilelength counter index = index + 1 End If Wend logfilelength = index index = index - 1 logfileopen = 1 If ipfileopen = logfileopen And ipfileopen = 1 Then writebutton.Enabled = True Combinebutton.Enabled = True End If displaylogval.Enabled = True indicator.Caption = "Log File Loaded" ' call the sort function to arrange elements in arrays by case sensitive player alias QuickSort logfilearraya, 0, logfilelength - 1, logfilearrayi indicator.Caption = "Log File Sorted" ' call the appropriate cull function to cut out any duplicates from the arrays logcullfunc logfilearraya, logfilearrayi, logfilelength indicator.Caption = "Duplicate Log Values Removed" Close #1 Else MsgBox "The Log File you have specified is empty, Please enter a different path, and retry." Close #1 End IfEnd IfEnd SubPrivate Sub logcullfunc(aliasarray() As String, iparray() As String, arraylength As Long)Dim temparraya() As StringDim temparrayi() As StringDim duplicates() As LongDim firstpos As LongDim index As LongDim index2 As LongDim tempcounter As Longfirstpos = 0index = 0index2 = 0tempcounter = 0ReDim duplicates(0 To arraylength) As LongReDim temparraya(0 To arraylength) As StringReDim temparrayi(0 To arraylength) As StringReDim Preserve aliasarray(0 To arraylength + 1) As StringReDim Preserve iparray(0 To arraylength + 1) As StringWhile index < arraylength duplicates(index) = 0 index = index + 1Wend' values in the arrays are pre-sorted by alias, but need to be also sorted by IP' first scan through the alias array for how many duplicate instances there are for each alias' store this duplicates value in a temparray using the same index position as the first alias' in the array that is duplicated, so you have a start position to send the sort' function for each different aliasindex = 0While index < arraylength ' if one alias matches the next alias count how many more there are and change the index ' position to skip them being counted on the next pass of the while loop If aliasarray(index) = aliasarray(index + 1) Then firstpos = index index2 = index + 1 While aliasarray(firstpos) = aliasarray(index2) duplicates(firstpos) = duplicates(firstpos) + 1 index2 = index2 + 1 Wend index = index + duplicates(firstpos) + 1 ' if they dont match, leave the value of the index in the duplicates array as a 0 ' then increment the index so the loop proceeds to check the next entry as normal Else index = index + 1 End IfWend' if the number of duplicates for an alias is not 0, send the sort function the arrays' and the bounds to sort only that section which contains duplicates of the alias:' the upper bound sent to the sort function will be the index position of the first entry' added to the number of duplicates that follow it. the lower bound will be the index position.' This will force the sort function to retain the sorting of the aliases from earlier' and only work on sorting those entries by IP and grouping the duplicate values in' consecutive blocks that the cull loop below will handle.index = 0While index < arraylength If duplicates(index) > 0 Then QuickSort iparray, index, duplicates(index) + index, aliasarray End If index = index + 1Wend' go through the array name by name, removing the consecutive duplicate IP entriesindex = 0While index < arraylength If aliasarray(index) = aliasarray(index + 1) Then If iparray(index) = iparray(index + 1) Then temparraya(tempcounter) = aliasarray(index) temparrayi(tempcounter) = iparray(index) Else temparraya(tempcounter) = aliasarray(index) temparrayi(tempcounter) = iparray(index) tempcounter = tempcounter + 1 End If Else temparraya(tempcounter) = aliasarray(index) temparrayi(tempcounter) = iparray(index) tempcounter = tempcounter + 1 End If index = index + 1Wend' refill the real arrays with the newly sorted temp arrays' reset the global logfilelength variable to the new length valueindex = 0logfilelength = tempcounterReDim logfilearraya(0 To logfilelength) As StringReDim logfilearrayi(0 To logfilelength) As StringWhile index < tempcounter logfilearraya(index) = temparraya(index) logfilearrayi(index) = temparrayi(index) index = index + 1WendEnd SubPrivate Sub QuickSort(searcharray() As String, intBottom As Long, intTop As Long, slavearray() As String)Dim strPivot As StringDim searcharraytemp As StringDim slavearraytemp As StringDim intBottomTemp As LongDim intTopTemp As LongintBottomTemp = intBottomintTopTemp = intTopstrPivot = searcharray((intBottom + intTop) \ 2)While (intBottomTemp <= intTopTemp)'comparison of the values is a descending sort using the bounds that were passed to the function'and cutting the list in half based on them While (searcharray(intBottomTemp) < strPivot And intBottomTemp < intTop) intBottomTemp = intBottomTemp + 1 Wend While (strPivot < searcharray(intTopTemp) And intTopTemp > intBottom) intTopTemp = intTopTemp - 1 Wend If intBottomTemp < intTopTemp Then ' the slave array element is sorted based only on the values from the ' searcharray comparison, in order to keep the value in the same index ' position as that of the corresponding value in the other array slavearraytemp = slavearray(intBottomTemp) slavearray(intBottomTemp) = slavearray(intTopTemp) slavearray(intTopTemp) = slavearraytemp searcharraytemp = searcharray(intBottomTemp) searcharray(intBottomTemp) = searcharray(intTopTemp) searcharray(intTopTemp) = searcharraytemp End If If intBottomTemp <= intTopTemp Then intBottomTemp = intBottomTemp + 1 intTopTemp = intTopTemp - 1 End IfWend'the function calls itself recursively until everything is correctly sortedIf (intBottom < intTopTemp) Then QuickSort searcharray, intBottom, intTopTemp, slavearrayIf (intBottomTemp < intTop) Then QuickSort searcharray, intBottomTemp, intTop, slavearrayEnd Sub
def parse_name_and_ip(line) # OSP logfile connects look like: # [2009-03-02 15:42] (asdf connected from 123.45.67.89) if line =~ /\((.+) connected from ([\d.]+)\)/ [$1, $2] else nil endenddef parse_connects(file) connects = [] file.each_line do |line| name, ip = parse_name_and_ip(line) if name connects << [ip, name] end end connects end# print tab-separated unique connects sorted by IPconnects = parse_connects(ARGF)uniq_connects = connects.uniq # :Dsorted_connects = uniq_connects.sort # :Dsorted_connects.each {|ip,name| puts "#{ip}\t#{name}"}
ARGF.read.scan(/\((.+) connected from ([\d.]+)\)/).uniq.sort_by{|name,ip| ip}.each{|name,ip| puts "#{ip}\t#{name}"}
gave that sql library a little look over..pretty slick stuff. looks very nicely maintained and super efficient.
I didn't think you could get another players IP?It'd be cool to put in a player name and get references to the chat with them in the log, not sure if it does that, or it's something you wanna do.
The only hiccup I've noticed is that linux servers use an endline character that vb6 is unable to handle correctly, so I have to open the logs in wordpad and save them prior to scanning. Hopefully I'll figure out a way to fix that for future builds.