edman747 Posted January 22, 2007 Posted January 22, 2007 hello all,recent steam updates have uncovered a changelevel bug in svencoop3.0this bug prevents the server from automatically changing to the next map.it affects maps in a series like toonrun1.bsp toonrun2.bsp toonrun3.bspa workaround is to put a nextmap statement in the map config file.ie. toonrun1.cfg would have this added: nextmap toonrun2I imagine this is fixed in svencoop3.5while waiting for the upcoming release of version 3.5 originally planned dec 04question for the community: is it possible to write a script that will edit the cfg files?dir *.bspafrikakorps1.bspafrikakorps2.bspafrikakorps3.bspauspices.bsptoonrun1.bsptoonrun2.bsptoonrun3.bspappend a line to afrikakorps1.cfg like: nextmap afrikakorps2append a line to afrikakorps2.cfg like: nextmap afrikakorps3no change to afrikakorps3.cfgno change to auspices.cfgthis 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 extensionit 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 computerssomeone said it would be easy to do in perl or python but that would requireanyone 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.
edman747 Posted January 22, 2007 Author Posted January 22, 2007 here is what I've got.@echo offsetlocal enabledelayedexpansionif exist filenames.txt del filenames.txtfor %%x in (*.bsp) do echo %%x >>filenames.txtfor /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.txtendlocalreads 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.
Yzöwl Posted January 23, 2007 Posted January 23, 2007 Okay, well done for putting forward what you've done so far!The problem is I don't know exactly what you are trying to achieve, and therefore cannot help you without further information.Until then, however, the following snippet should do exactlythesame as your attempted code, but a little quicker, and using less space.@FOR /f "delims=" %%? IN ('DIR/b *.bsp') DO @ECHO/%%~n? >filenames.txt
edman747 Posted January 24, 2007 Author Posted January 24, 2007 Hello Yzowl, thanks for your reply.it is faster. here's what I have now@echo offif exist filenames.txt del filenames.txt@FOR /f "delims=" %%? IN ('DIR /b *.bsp') DO @ECHO/%%~n? >>filenames.txtwhat I want to do is read filenames.txtdetermine 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 map2ignore 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 isan identifiable pattern in the file names.afrikakorps1 afrikakorps2 afrikakorps3 auspices c1a0c4a3crisis2 extended extension gargfoot grunts2 hl_sp_portal hostage hostage2a hostage2b hplanet incoming osprey rampage sandstone sc_another sc_greysnake1 shattered stadium3 svencoop1 svencoop2 SweetHomeCity toonrun1 toonrun2 toonrun3 vger wired zerothanks again
edman747 Posted January 25, 2007 Author Posted January 25, 2007 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 ExplicitDim objFSODim ofolderDim objStreamDim intCounterDim arrTestNames ()Dim dicBaseNamesDim strBaseDim strNameDim strNumberDim nUBoundDim arrTempDim strOutputSet objFSO = CreateObject("Scripting.FileSystemObject")'create the output fileSet objStream = objFSO.createtextfile("search.log", True)CheckFolder (objFSO.getfolder(".")), objStreamReDim 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 numeralsSet 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 IfNext'now step through the dictionary using basenames.StepThruDic(objFSO.getfolder(".")), objStreamMsgBox "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 FunctionFunction 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 FunctionSub 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 NextEnd 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 NextEnd 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 NextEnd Sub thanks,
edman747 Posted January 27, 2007 Author Posted January 27, 2007 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 CompletedPlease check updated map.cfg'sSee 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 afrikakorps2afrikakorps2.cfg nextmap afrikakorps3hostage.cfg nextmap hostage2ahostage2a.cfg nextmap hostage2bsvencoop1.cfg nextmap svencoop2toonrun1.cfg nextmap toonrun2toonrun2.cfg nextmap toonrun3the 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 ExplicitDim objFSODim ofolderDim objStreamDim intCounterDim arrTestNames ()Dim dicBaseNamesDim strBaseDim strNameDim strNumberDim nUBoundDim arrTempDim strOutputSet objFSO = CreateObject("Scripting.FileSystemObject")'create the output fileSet objStream = objFSO.createtextfile("search.log", True)CheckFolder (objFSO.getfolder(".")), objStreamReDim Preserve arrTestNames (intCounter)FillArray(objFSO.getfolder(".")), objStream, arrTestNamesConst TextCompare = 1'Start by making a dictionary of all the base names. The value will be an array of the numeralsSet dicBaseNames = CreateObject("Scripting.Dictionary")dicBaseNames.CompareMode = TextCompareFor 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 IfNext'now step through the dictionary using basenames and numbers to update config files.StepThruDic(objFSO.getfolder(".")), objStreamMsgBox "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 FunctionFunction 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 FunctionSub 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 NextEnd 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 NextEnd 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 strOutputFor 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 NextNextEnd SubThank You,
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now