
edman747
MemberAbout edman747

edman747's Achievements
0
Reputation
-
I have a script that processes a list of file names. if there is a pattern in the file names that indicates a series of related names. the script updates the associated configuration file with the name of the next file in the series and writes an entry in a log. the file names are read from a directory and striped of the file extension then the names are stored a dictionary where the base file name characters are stored in strBase as a key and if there is a number, the number and the rest of the line are stored in strNumber as an array of string. simple file names like map1, map2, map3. strBase = map, strNumber(0) = 1, strNumber(1) = 2 ... and a series like: escape2_a, escape2_b, escape2_c. work just fine. problem: a series of names like 1, 2, 3 are interrupted by single (non-series) names like 2hotel and series names like assaultmesa2, assaultmesa2-2 get inverted? with no formal file naming convention or input into individual users choice of file names. I made the following assumption: a series of names can be one or more char optionally followed by one or more numbers. every time there is a special case that does not match. I have to keep changing the script to include some logic to handle special case names. would anyone be willing to suggest a better way of doing this? TIA here is the output subroutine. Sub StepThruDic(objCurrentFolder, objLogFile) Dim strTemp Dim strSearch Dim strOutput Dim objNewFolder Dim objFile Dim objStream Dim i Dim strNextmap strOutput = "changelevel bug squished. Summary of changes:" objLogFile.writeline strOutput For Each strBase in dicBaseNames.Keys For i = 1 To UBound(dicBaseNames(strBase)) 'skip c1,c2,c3 series, blank records, special case strbase is a number or starts with a number. If strBase <> "c" _ and "nextmap " & strbase & dicBaseNames(strBase)(i) <> "nextmap " _ and dicBaseNames(strBase)(i - 1) <> "2hotel" _ and dicBaseNames(strBase)(i - 1) <> "2battle" then strNextmap = strbase & dicBaseNames(strBase)(i) If Len(strBase) = 0 and dicBaseNames(strBase)(i - 1) = "2" then strNextmap = "3" End If ' write to the search log. strOutput = strBase & dicBaseNames(strBase)(i - 1) & ".cfg" objLogFile.writeline strOutput strOutput = " nextmap " & strNextmap objLogFile.writeline strOutput ' update the config file. If objFSO.FileExists(strBase & dicBaseNames(strBase)(i - 1) & ".cfg") Then objFSO.OpenTextFile(strBase & dicBaseNames(strBase)(i - 1) & ".cfg", 8).WriteLine _ vbCR & vbLF & "nextmap " & strbase & dicBaseNames(strBase)(i) Else 'create the config file. strTemp = strBase & dicBaseNames(strBase)(i - 1) & ".cfg" Set objStream = objFSO.createtextfile(strTemp, True) objStream.WriteLine _ "nextmap" & " " & strbase & dicBaseNames(strBase)(i) End If End If Next Next ' in the odd case when series sequence cannot be determined by mapname. ' begin to rip the ent data and search for trigger_changelevel or map string ' if strBase & dicBaseNames(strBase)(i) = "c1a0" or "c1a0d" then ' Dim Act : Set Act = CreateObject("Wscript.Shell") ' Act.Run("cmd.exe /c ripent.exe -export " & strBase & dicBaseNames(strBase)(i)),1,True ' search for unique string "map" get the name. ' test for more than one occurrence of "map" take the second one. ' end if End Sub
-
batch or vbs help
edman747 replied to edman747's topic in Programming (C++, Delphi, VB/VBS, CMD/batch, etc.)
here is a solution. users can put this script in their Half-Life\svencoop\maps directory. and double click to run it. a small dialog pops up, saying: Series Map Search Completed Please check updated map.cfg's See search.log for details. the user has to click ok to dismiss the dialog. when they open search.log in notepad, they will see something similar to this: changelevel bug squished. Summary of changes: afrikakorps1.cfg nextmap afrikakorps2 afrikakorps2.cfg nextmap afrikakorps3 hostage.cfg nextmap hostage2a hostage2a.cfg nextmap hostage2b svencoop1.cfg nextmap svencoop2 toonrun1.cfg nextmap toonrun2 toonrun2.cfg nextmap toonrun3 the script is a little sloppy. I don't check to see if a previous search.log exist. and where I read the directory once just to get a count of map names. then redim the array using the count and read the directory again to fill the array. also I don't check to see if the correct config file exist before writing to it. but it does create a log showing which config files were updated. a couple of days ago I had never written a vbscript before. check out the for each loop where I step through the dictionary using the basename and strNumber. that is part is cool and it eliminates a huge painful nested if. Option Explicit Dim objFSO Dim ofolder Dim objStream Dim intCounter Dim arrTestNames () Dim dicBaseNames Dim strBase Dim strName Dim strNumber Dim nUBound Dim arrTemp Dim strOutput Set objFSO = CreateObject("Scripting.FileSystemObject") 'create the output file Set objStream = objFSO.createtextfile("search.log", True) CheckFolder (objFSO.getfolder(".")), objStream ReDim Preserve arrTestNames (intCounter) FillArray(objFSO.getfolder(".")), objStream, arrTestNames Const TextCompare = 1 'Start by making a dictionary of all the base names. The value will be an array of the numerals Set dicBaseNames = CreateObject("Scripting.Dictionary") dicBaseNames.CompareMode = TextCompare For Each strName In arrTestNames strBase = GetBaseName(strName) strNumber = GetSequenceNumber(strName) If dicBaseNames.Exists(strBase) Then nUBound = UBound(dicBaseNames(strBase)) + 1 arrTemp = dicBaseNames(strBase) ReDim Preserve arrTemp(nUBound) arrTemp(nUBound) = strNumber dicBaseNames(strBase) = arrTemp Else dicBaseNames.Add strBase, Array(strNumber) End If Next 'now step through the dictionary using basenames and numbers to update config files. StepThruDic(objFSO.getfolder(".")), objStream MsgBox "Series Map Search Completed." + vbCr + "Please check updated map.cfg's." + vbCr + "See search.log for details" Function GetSequenceNumber(strName) Dim oRE Dim colMatches Dim oMatch Set oRE = New Regexp oRE.Pattern = "\D*(\d*)(\D*)" oRE.IgnoreCase = True Set colMatches = oRE.Execute(strName) For Each oMatch In colMatches GetSequenceNumber = oMatch.Submatches(0) & oMatch.Submatches(1) Exit Function Next GetSequenceNumber = "" End Function Function GetBaseName(strName) Dim oRE Dim colMatches Dim oMatch Set oRE = New Regexp oRE.Pattern = "(\D*)\d*(\D*)" oRE.IgnoreCase = True Set colMatches = oRE.Execute(strName) For Each oMatch In colMatches GetBaseName = oMatch.SubMatches(0) Exit Function Next GetBaseName = "ERROR" End Function Sub CheckFolder(objCurrentFolder, objLogFile) Dim strTemp Dim strSearch Dim strOutput Dim objNewFolder Dim objFile Dim objStream dim a strSearch = ".bsp" For Each objFile In objCurrentFolder.Files strTemp = Right(objFile.Name, 4) If UCase(strTemp) = UCase(strSearch) Then 'Got one 'a=Split(CStr(objFile.Name),".") intCounter = intCounter + 1 'strOutput = CStr(intCounter) & " " & a(0) 'objLogFile.writeline strOutput End If Next End Sub Sub FillArray(objCurrentFolder, objLogFile, arrTestNames) Dim strTemp Dim strSearch Dim strOutput Dim objNewFolder Dim objFile Dim objStream dim a dim intIndex strSearch = ".bsp" intIndex = 0 For Each objFile In objCurrentFolder.Files strTemp = Right(objFile.Name, 4) If UCase(strTemp) = UCase(strSearch) Then 'Got one a=Split(CStr(objFile.Name),".") 'populate database arrTestNames (intIndex) = a(0) 'strOutput = arrTestNames (intIndex) 'objLogFile.writeline strOutput intIndex = intIndex + 1 End If Next End Sub Sub StepThruDic(objCurrentFolder, objLogFile) Dim strTemp Dim strSearch Dim strOutput Dim objNewFolder Dim objFile Dim objStream Dim i strOutput = "changelevel bug squished. Summary of changes:" objLogFile.writeline strOutput For Each strBase in dicBaseNames.Keys For i = 1 To UBound(dicBaseNames(strBase)) If strBase <> "c" then strOutput = strBase & dicBaseNames(strBase)(i - 1) & ".cfg" objLogFile.writeline strOutput strOutput = " nextmap" & " " & strbase & dicBaseNames(strBase)(i) objLogFile.writeline strOutput objFSO.OpenTextFile(strBase & dicBaseNames(strBase)(i - 1) & ".cfg", 8).WriteLine _ "nextmap" & " " & strbase & dicBaseNames(strBase)(i) End If Next Next End Sub Thank You, -
batch or vbs help
edman747 replied to edman747's topic in Programming (C++, Delphi, VB/VBS, CMD/batch, etc.)
here is what I've got so far as a vbscript souliton. a little broken when it comes to the odd case hostage hostage2a hostage2b. and for opening the correct file to append a line. any help. Option Explicit Dim objFSO Dim ofolder Dim objStream Dim intCounter Dim arrTestNames () Dim dicBaseNames Dim strBase Dim strName Dim strNumber Dim nUBound Dim arrTemp Dim strOutput Set objFSO = CreateObject("Scripting.FileSystemObject") 'create the output file Set objStream = objFSO.createtextfile("search.log", True) CheckFolder (objFSO.getfolder(".")), objStream ReDim Preserve arrTestNames (intCounter) FillArray(objFSO.getfolder(".")), objStream, arrTestNames 'Start by making a dictionary of all the base names. The value will be an array of the numerals Set dicBaseNames = CreateObject("Scripting.Dictionary") For Each strName In arrTestNames strBase = GetBaseName(strName) strNumber = GetSequenceNumber(strName) If dicBaseNames.Exists(strBase) Then nUBound = UBound(dicBaseNames(strBase)) + 1 arrTemp = dicBaseNames(strBase) ReDim Preserve arrTemp(nUBound) arrTemp(nUBound) = strNumber dicBaseNames(strBase) = arrTemp Else dicBaseNames.Add strBase, Array(strNumber) End If Next 'now step through the dictionary using basenames. StepThruDic(objFSO.getfolder(".")), objStream MsgBox "File Search Completed." + vbCr + "Please check search.log for details." Function GetSequenceNumber(strName) Dim oRE Dim colMatches Dim oMatch Set oRE = New Regexp oRE.Pattern = "\D*(\d*)(\D*)" oRE.IgnoreCase = True Set colMatches = oRE.Execute(strName) For Each oMatch In colMatches GetSequenceNumber = oMatch.Submatches(0) Exit Function Next GetSequenceNumber = "" End Function Function GetBaseName(strName) Dim oRE Dim colMatches Dim oMatch Set oRE = New Regexp oRE.Pattern = "(\D*)\d*(\D*)" oRE.IgnoreCase = True Set colMatches = oRE.Execute(strName) For Each oMatch In colMatches GetBaseName = oMatch.SubMatches(0) Exit Function Next GetBaseName = "ERROR" End Function Sub CheckFolder(objCurrentFolder, objLogFile) Dim strTemp Dim strSearch Dim strOutput Dim objNewFolder Dim objFile Dim objStream dim a strSearch = ".bsp" For Each objFile In objCurrentFolder.Files strTemp = Right(objFile.Name, 4) If UCase(strTemp) = UCase(strSearch) Then 'Got one 'a=Split(CStr(objFile.Name),".") intCounter = intCounter + 1 'strOutput = CStr(intCounter) & " " & a(0) 'objLogFile.writeline strOutput End If Next End Sub Sub FillArray(objCurrentFolder, objLogFile, arrTestNames) Dim strTemp Dim strSearch Dim strOutput Dim objNewFolder Dim objFile Dim objStream dim a dim intIndex strSearch = ".bsp" intIndex = 0 For Each objFile In objCurrentFolder.Files strTemp = Right(objFile.Name, 4) If UCase(strTemp) = UCase(strSearch) Then 'Got one a=Split(CStr(objFile.Name),".") 'populate database arrTestNames (intIndex) = a(0) 'strOutput = arrTestNames (intIndex) 'objLogFile.writeline strOutput intIndex = intIndex + 1 End If Next End Sub Sub StepThruDic(objCurrentFolder, objLogFile) Dim strTemp Dim strSearch Dim strOutput Dim objNewFolder Dim objFile Dim objStream dim a dim intIndex dim strName2 dim strBase2 dim strNumber2 dim strName3 dim strBase3 dim strNumber3 dim i For i = 0 to intCounter - 1 strName = arrTestNames(i) strBase = GetBaseName(strName) strNumber = GetSequenceNumber(strName) If strNumber = "" Then strName2 = arrTestNames(i + 1) strBase2 = GetBaseName(strName2) If StrComp(strBase2, strBase) = 0 Then strNumber2 = GetSequenceNumber(strName2) strOutput = "nextmap" & " " & strbase2 & strnumber2 & " " & strname & ".cfg" objLogFile.writeline strOutput End If If strNumber2 = "1" Then strName3 = arrTestNames(i + 2) strBase3 = GetBaseName(strName3) If StrComp(strBase3, strBase) = 0 Then strNumber3 = GetSequenceNumber(strName3) strOutput = "nextmap" & " " & strbase3 & strnumber3 & " " & strname2 & ".cfg" objLogFile.writeline strOutput End If End If End If If strNumber = "1" Then strName2 = arrTestNames(i + 1) strBase2 = GetBaseName(strName2) If StrComp(strBase2, strBase) = 0 Then strNumber2 = GetSequenceNumber(strName2) strOutput = "nextmap" & " " & strbase2 & strnumber2 & " " & strname & ".cfg" objLogFile.writeline strOutput End If If strNumber2 = "2" Then strName3 = arrTestNames(i + 2) strBase3 = GetBaseName(strName3) If StrComp(strBase3, strBase) = 0 Then strNumber3 = GetSequenceNumber(strName3) strOutput = "nextmap" & " " & strbase3 & strnumber3 & " " & strname2 & ".cfg" objLogFile.writeline strOutput End If End If End If Next End Sub thanks, -
batch or vbs help
edman747 replied to edman747's topic in Programming (C++, Delphi, VB/VBS, CMD/batch, etc.)
Hello Yzowl, thanks for your reply. it is faster. here's what I have now @echo off if exist filenames.txt del filenames.txt @FOR /f "delims=" %%? IN ('DIR /b *.bsp') DO @ECHO/%%~n? >>filenames.txt what I want to do is read filenames.txt determine if there is a repeating pattern in the file names indicating they are part of a set. if map1 is part of a set. append a line to the map1.cfg file that points to the nextmap in the set. ie. nextmap map2 ignore the single maps. here is part of filenames.txt there are four map sets. basename (afrikakorps, hostage, svencoop, toonrun) these are created by individual users. file naming conventions are undefined, most of the time there is an identifiable pattern in the file names. thanks again -
batch or vbs help
edman747 replied to edman747's topic in Programming (C++, Delphi, VB/VBS, CMD/batch, etc.)
here is what I've got. @echo off setlocal enabledelayedexpansion if exist filenames.txt del filenames.txt for %%x in (*.bsp) do echo %%x >>filenames.txt for /f "tokens=* delims=" %%a in (filenames.txt) do ( set txtline=%%a set txtline=!txtline:.bsp=! echo !txtline!>>tmp.txt) del filenames.txt & ren tmp.txt filenames.txt endlocal reads file names from a directory into text file. strips off the file name extension. I don't know how to compare the file names or do sub string manipulation. -
hello all, recent steam updates have uncovered a changelevel bug in svencoop3.0 this bug prevents the server from automatically changing to the next map. it affects maps in a series like toonrun1.bsp toonrun2.bsp toonrun3.bsp a workaround is to put a nextmap statement in the map config file. ie. toonrun1.cfg would have this added: nextmap toonrun2 I imagine this is fixed in svencoop3.5 while waiting for the upcoming release of version 3.5 originally planned dec 04 question for the community: is it possible to write a script that will edit the cfg files? dir *.bsp afrikakorps1.bsp afrikakorps2.bsp afrikakorps3.bsp auspices.bsp toonrun1.bsp toonrun2.bsp toonrun3.bsp append a line to afrikakorps1.cfg like: nextmap afrikakorps2 append a line to afrikakorps2.cfg like: nextmap afrikakorps3 no change to afrikakorps3.cfg no change to auspices.cfg this will not fix the Half-Life single player maps as the correct sequence cannot be determined from the file names. it's OK I already fixed them. in a batch script I can read the map names and strip off the file extension it is easy to append a nextmap statement to a cfg file. but I don't know how to manipulate the strings. this may only affect a couple of hundred maps on a couple of hundred computers someone said it would be easy to do in perl or python but that would require anyone wanting to use the script to install support for perl or python. vbs is native to xp but I don't know anything about it. any help I would be eternally grateful.