Java 求生之路2随机喷漆脚本vtf文件统一重命名以及生成配置文件
一、一些简单讲述
为啥有这文章,当然是吃饱了撑的呗。
懒人包:
【百度云】C#版本免安装直接运行
一下是说明随机喷漆说明以及java版本代码(自娱自乐)。
(1)、必要基础(含模板配置下载)
你需要知道的一些小知识:
- 相关游戏:求生之路2(Left 4 Dead 2);
- vtf 喷漆在线制作: VTF Spray Converter;
- 娱乐性:纯属学习娱乐
- 专用性:这是为求生之路2游戏配置文件制作的工具,你可以当他是一个脚本 【百度云】模板资源;
注意:模板资源中仅配置了一张喷漆,喷漆脚本不会和喷漆模组冲突,但游戏内自行选择的喷漆将会无效。
在了解以上知识后,那么你可以正式开始了解文章内容了
(2)、脚本讲解
声明:脚本源自steam创意工坊随机喷漆模组简介的相关下载链接(可能由于个别原因已经下架,侵删)。
文件内容:
- 【文件】autoexec.cfg:游戏配置文件,新增部分内容。
- 【文件】start_spray.cfg:用户新增配置文件,用以配置喷漆。
- 【文件夹】random_spray:存放喷漆文件。
脚本安装说明:(资源包中文件夹已进行划分,只需要注意以下几点即可)
- left4dead2\cfg\autoexec.cfg:如果已经存在该文件,只需将其中的内容复制到已存在的同名文件中即可。
文件作用:通过 添加 exec start_spray.cfg 读取喷漆配置信息。 - left4dead2\cfg\start_spray.cfg:该文件用于配置自定义喷漆的一些参数,添加文件时也是修改该文件。
以下为 start_spray.cfg 文件的修改规则。
上图为一个喷漆时的配置,下图为两个喷漆的配置。
300 表示该编号喷漆的延时时间。
喷漆的名字可以任意,图中 #1.vtf 即为喷漆全名(包含扩展名)。
每个喷漆都有编号(图中的 spray01 即为第一张喷漆编号)。
配置喷漆分组,最好不超过20个为一组,太长会导致读取失败。
单个分组和两个分组对比,以此类推
多个分组增加规则: alias allspraycmd “分组1;wait 延时总和+一单位延时;分组2;wait 延时总和+一单位延时;exec start_spray.cfg”
注:对比图片就知道怎么改了,这里就不过多介绍了,本文后面的内容主要目的就是通过程序代码生成这个配置文件来代替手动修改。 - left4dead2\random_spray:制作好的喷漆文件存放的位置,细心的你应该发现了配置文件配置的路径文件夹就是它。
(3)、本文章主要目的以及处理方法
背景:因为vtf文件无法预览,所有我针对于所有的喷漆文件,对他们进行了内容的分类,见下图。所有文件夹下的vtf文件名称没有任何规则且随机(主要是制作的时候随便取的命名,为了快基本都是用编号命名)。
奇怪的命名:
FineA = Fine Animation = 精美的动画图片 喷漆
JKA = Jyoshi Koukousei Animation = 女高生漫画 喷漆
KHA = Kazutake Hazano Animation = 武叶佐乃漫画 喷漆
Other = … = 其他分类
RHA = Rabbit House Animation = 点兔动画 喷漆
目的:
- 将所有文件按照 # + 所属文件夹名称 + 数字编号 的格式进行重命名,同时可选择覆盖源文件或者不修改源文件,存放到指定文件夹。
- 生成start_spray.cfg配置文件,代替手动编辑配置进行新增或修改游戏用喷漆。
二、动手操作
实现
支持后期喷漆增量重新生成配置文件。
import java.io.*;
import java.nio.file.Files;
import java.util.HashMap;
/**
* 求生之路随机喷漆自动生成脚本
* */
public class RandomSAutoCreate {
public static String fileDir = "F:\\GameWorking\\求生之路\\MOD\\随机喷漆#55\\自制\\InUse";
public static String cfgFileName = "start_spray.cfg";//生成的配置文件名称
/**配置文件基本配置*/
public static String cmdCode = "alias";
public static String cmdCode2 = "allspraycmd";
public static String title = "//fix infinite load bug:\n" + cmdCode + " loadscript wait;\n";//cfg文件开始行
/**每张vtf对应基础配置*/
public static String mainContextHead = cmdCode + " spray";
public static String mainContextCentre = " \"cl_logofile random_spray/";
public static String mainContextTail = "\"\n";//自定义
/**vtf文件延时配置*/
public static String groupTitle = "cmd_spray";
public static String endResult = " exec start_spray.cfg\"\n";
/**其他*/
public static int index = -1;//记录(vtf)文件数量
public static String outPathSet = "random_spray";//文件输出位置设置,默认路径为fileDir文件夹中新建该文件夹
public static String outPath = "";//文件输出具体位置,由程序控制
public static int space = 1;//喷漆随机延时
public static int groupMaxNum = 32;//每组喷漆数量
/**
* 执行
* */
public static void main(String[] args) throws IOException {
File rootFile = new File(fileDir);
if(null != outPathSet && !"".equals(outPathSet)){
outPath = rootFile.getPath() + "\\" + outPathSet;
new File(outPath).mkdirs();
}
if(!rootFile.exists())
System.out.println("文件路径无效!");
else{
String rootName = rootFile.getName();
File[] files = rootFile.listFiles();
if(files.length != 0){
StringBuilder stringBuilder = changeFileName(rootName, files);//复制文件并进行重命名,同时统计生成配置文件数据
stringBuilder = generateCfgLastTimeSet(stringBuilder);//对配置文件进行补充
if(index >= 1)
createStartSprayCfgFile(rootFile.getPath(), stringBuilder);//生成配置文件
}
}
}
/**
* 处理文件夹中的文件
* */
public static StringBuilder changeFileName(String rootName, File[] files) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
if(index == -1){//根目录文件,处理配置头
stringBuilder.append(title);
index++;
}
HashMap<String, String> fileIndex = new HashMap();//存储文件名与新文件名的关系
int i = 1;
for(File file : files){
if(file.isFile() && !file.getName().equals(cfgFileName)){//处理文件时排除配置文件
String fileName = file.getName();
String fileNewName = "#" + rootName + i;//新文件名称,不包含扩展名
String fileKey = rootName + fileName.substring(0, fileName.lastIndexOf("."));//以 根目录名+无扩展名文件名 为key进行储存
if(fileIndex.containsKey(fileKey)){
fileNewName = fileIndex.get(fileKey);//查询并获取key对应的文件名
}
else{
fileIndex.put(fileKey, fileNewName);//存储进hashmap缓存
i++;
}
String fileNewFullName = fileNewName + fileName.substring(fileName.lastIndexOf("."));//新文件名,包括扩展名
//处理字符串生成,仅vtf文件
if(fileName.substring(fileName.lastIndexOf(".") + 1).equals("vtf"))
stringBuilder.append(mainContextHead + ++index + mainContextCentre + fileNewFullName + mainContextTail);
/**renameTo会删除源文件*/
if(null != outPath && !"".equals(outPath))
Files.copy(file.toPath(),new FileOutputStream(new File(outPath, fileNewFullName)));
else
file.renameTo(new File(file.getParent(), fileNewFullName));
//重命名或者移动重命名
//file.renameTo(new File(null != outPath && !"".equals(outPath) ? outPath : file.getParent(), fileNewFullName));
}
else if(file.isDirectory() && !file.getName().equals(outPathSet))//文件夹遍历处理
stringBuilder.append(changeFileName(file.getName(), file.listFiles()));
}
return stringBuilder;
}
/**
* 生成配置文件
* */
public static StringBuilder generateCfgLastTimeSet(StringBuilder stringBuilder){
stringBuilder.append("\n");
StringBuilder newStringBuilder = new StringBuilder();
StringBuilder endString = new StringBuilder();
for(int i = 1; i <= index; i++){
//处理每组开头
if(i % groupMaxNum == 1){
int groupId = i / groupMaxNum + 1;
newStringBuilder.append(cmdCode + " " + groupTitle + groupId + " \"");// ==> alias cmd_spray? "
}
//处理当前项
// if(i % groupMaxNum != 1)
// newStringBuilder.append(" ");
newStringBuilder.append("spray" + i + ";wait " + space + ";");// ==> spray?; wait 300;
//处理结尾开头
if(i == 1)
endString.append(cmdCode + " " + cmdCode2 + " \"");// ==> alias allspraycmd "
//处理每组结尾
if(i % groupMaxNum == 0 || i == index){
stringBuilder.append(newStringBuilder + "\"\n");//将每组配置添加进去
newStringBuilder = new StringBuilder();
if(i % groupMaxNum == 0){// ==> cmd_spray?;wait ????;
if(i != index)
endString.append(groupTitle + i / groupMaxNum + ";wait " + groupMaxNum * space + ";");
else{
endString.append(groupTitle + i / groupMaxNum + ";wait " + (groupMaxNum + 1) * space + ";");
endString.append(endResult + cmdCode2 + "\n");
}
}
else if(i == index){
endString.append(groupTitle + (i / groupMaxNum + 1) + ";wait "+ (i % groupMaxNum + 1) * space +";" + endResult + cmdCode2 + "\n");// ==> exec start_spray.cfg" \n allspraycmd \n
}
}
}
stringBuilder.append(endString);
return stringBuilder;
}
/**
* 尝试写入内容到指定文件
* */
public static void createStartSprayCfgFile(String path, StringBuilder context) throws IOException {
File file = new File(path);
if(!file.exists()) {
file.createNewFile();
}
file = new File(path, cfgFileName);
try(FileWriter fileWriter = new FileWriter(file)){
fileWriter.append(context);
}
}
}
可修改部分
fileDir:喷漆文件完整文件夹路径
outPathSet:空则直接重命名源文件,不移动位置。非空则创建一个该值的文件夹用以存放所有重命名后的文件。
space:喷漆随机延时参数(毫秒,越小能随机性越高,但消耗性能也越高,不过一般影响不大)
groupMaxNum:每组喷漆数量,太多可能会导致指令太长而无法被系统识别,建议小于25。
结果预览
以下为outPathSet = Out时的运行结果;生成了Out文件夹以及start_spray.cfg文件。
配置文件结果预览(例):