Skip to content

Commit

Permalink
[WzFiles.java] 增加统一处理 wz 文件的工具类
Browse files Browse the repository at this point in the history
  • Loading branch information
bryan.zhang committed Aug 18, 2021
1 parent ad18498 commit c5767d4
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 0 deletions.
30 changes: 30 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>com.github.mrzhqiang.helper</groupId>
<artifactId>helper</artifactId>
<version>2021.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
Expand All @@ -35,8 +47,26 @@
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.25</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>

<repositories>
<repository>
<id>aliyun-nexus</id>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<build>
<plugins>
<plugin>
Expand Down
102 changes: 102 additions & 0 deletions src/main/java/com/github/mrzhqiang/maplestory/wz/WzFiles.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.github.mrzhqiang.maplestory.wz;

import com.github.mrzhqiang.helper.Environments;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;

public enum WzFiles {
;
private static final Logger LOGGER = LoggerFactory.getLogger(WzFiles.class);

public static final String WZ_KEY = "wz.path";
public static final String DEFAULT_WZ_PATH = "/wz";
public static final File WZ_DIR = new File(System.getProperty(WZ_KEY, Environments.USER_DIR + DEFAULT_WZ_PATH));

public static final File BASE_DIR = new File(WZ_DIR, "Base.wz");
public static final File CHARACTER_DIR = new File(WZ_DIR, "Character.wz");
public static final File EFFECT_DIR = new File(WZ_DIR, "Effect.wz");
public static final File ETC_DIR = new File(WZ_DIR, "Etc.wz");
public static final File ITEM_DIR = new File(WZ_DIR, "Item.wz");
public static final File MAP_DIR = new File(WZ_DIR, "Map.wz");
public static final File MOB_DIR = new File(WZ_DIR, "Mob.wz");
public static final File MORPH_DIR = new File(WZ_DIR, "Morph.wz");
public static final File NPC_DIR = new File(WZ_DIR, "Npc.wz");
public static final File QUEST_DIR = new File(WZ_DIR, "Quest.wz");
public static final File REACTOR_DIR = new File(WZ_DIR, "Reactor.wz");
public static final File SKILL_DIR = new File(WZ_DIR, "Skill.wz");
public static final File SOUND_DIR = new File(WZ_DIR, "Sound.wz");
public static final File STRING_DIR = new File(WZ_DIR, "String.wz");
public static final File TAMING_MOB_DIR = new File(WZ_DIR, "TamingMob.wz");
public static final File UI_DIR = new File(WZ_DIR, "UI.wz");

public static void main(String[] args) {
// 必须是 debug 模式下才可以输出到 out 目录
if (!Environments.debug()) {
return;
}

File[] foundFiles = new File(WzFiles.WZ_DIR, "String.wz")
.listFiles((dir, name) -> name.endsWith(".xml"));
if (foundFiles == null) {
return;
}

Path out = Paths.get(Environments.USER_DIR, "out");
try {
Files.deleteIfExists(out);
Files.createDirectories(out);
} catch (IOException e) {
LOGGER.error("无法操作目录:" + out, e);
}

for (File foundFile : foundFiles) {
try {
// Jsoup 在解析时自动用 html + body 包装 xml 内容,所以这里要拿到 body 的子元素
Elements imgDir = Jsoup.parse(foundFile, "UTF-8").body().children();
// select 方法执行 css 选择器语法
// 比如 tag[key=value] 是匹配 <tag key="value"></tag> 元素
Elements strings = imgDir.select("string[name=name]");
String filename = foundFile.getName();
Path target = Optional.of(filename)
.map(it -> it.split("\\."))
.filter(it -> it.length > 0)
.map(it -> it[0])
// resolve 方法将指定参数拼接到路径之后,比如 /path/to + args =>>> /path/to/args
// 这里的作用是按照 String.wz 目录结构输出
.map(out::resolve)
.orElse(out.resolve(filename));
strings.forEach(element -> writeElement(target, element));
} catch (IOException e) {
LOGGER.error("解析 [" + foundFile + "] 文件出现错误!", e);
}
}
}

private static void writeElement(Path target, Element element) {
String parentName = element.parent().attr("name");
String name = element.val();
// String.wz 中的文件,一般是 name 为第一个元素,如果存在下一个元素,则必定是 desc 描述
String desc = Optional.ofNullable(element.nextElementSibling()).map(Element::val).orElse("(无描述)");
String format = String.format("%s - %s - %s%n", parentName, name, desc);
try {
// 以 UTF-8 字节流写入内容到指定路径,CREATE 参数是文件不存在自动创建,APPEND 参数是每次追加到末尾
Files.write(target, format.getBytes(UTF_8), CREATE, APPEND);
} catch (IOException e) {
LOGGER.error("写入到 [" + target + "] 文件出现错误!", e);
}
}
}
36 changes: 36 additions & 0 deletions src/test/java/com/github/mrzhqiang/maplestory/wz/WzFilesTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.github.mrzhqiang.maplestory.wz;

import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import static org.junit.Assert.*;

public class WzFilesTest {

private static final String BASE_WZ_EXPECTED =
"[smap.img.xml, StandardPDD.img.xml, zmap.img.xml, zmap_cn.img.xml]";

@Test
public void testWzPath() {
File root = new File(WzFiles.WZ_DIR, "/Base.wz");
assertEquals(BASE_WZ_EXPECTED, Arrays.toString(root.list()));
}

@Test
public void testJsoupXml() throws IOException {
File wz = new File(WzFiles.WZ_DIR, "/Mob.wz/0100100.img.xml");
Elements imgdirs = Jsoup.parse(wz, "UTF-8").body().children();
assertEquals("0100100.img", imgdirs.attr("name"));
Elements info = imgdirs.select("imgdir[name=info]");
assertEquals("info", info.attr("name"));
Elements maxHP = info.select("int[name=maxHP]");
assertEquals("maxHP", maxHP.attr("name"));
assertEquals("8", maxHP.attr("value"));
}

}

0 comments on commit c5767d4

Please sign in to comment.