Skip to content

Commit

Permalink
添加文档和注释
Browse files Browse the repository at this point in the history
  • Loading branch information
Gu-ZT committed Nov 8, 2024
1 parent f82c99c commit 64b2f75
Show file tree
Hide file tree
Showing 13 changed files with 567 additions and 9 deletions.
25 changes: 25 additions & 0 deletions src/main/java/dev/anvilcraft/rg/api/ConfigUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,51 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;

/**
* ConfigUtil类提供文件操作实用程序,包括读取和写入JSON配置文件
*/
public class ConfigUtil {

/**
* 从指定的文件路径检索JSON对象内容。如果文件不存在或是目录,
* 它创建一个包含空JSON对象内容的新文件,并返回一个空JsonObject
*
* @param path 文件路径,不得为空
* @return 返回从文件读取的JSON对象,如果文件不存在,则返回一个新的空JsonObject
* @throws RGRuleException 如果读取文件失败,则抛出异常并说明原因
*/
public static @NotNull JsonObject getOrCreateContent(@NotNull Path path) {
File file = path.toFile();
try {
if (!file.exists() || file.isDirectory()) {
// 将空JSON对象写入不存在的或目录文件
FileUtils.writeStringToFile(file, "{}", StandardCharsets.UTF_8);
return new JsonObject();
}
// 读取文件内容并将其解析为JsonObject
String value = FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8);
return GsonHelper.parse(value);
} catch (IOException e) {
// 如果读取文件失败,则抛出自定义异常
throw new RGRuleException("Failed to read rolling gate config file", e);
}
}

/**
* 将内容写入指定的文件路径
*
* @param path 文件路径,不得为空
* @param content 要写入的内容,不能为空
* @throws RGRuleException 如果写入文件失败,则抛出异常并说明原因
*/
public static void writeContent(@NotNull Path path, @NotNull String content) {
try {
// 将指定内容写入文件
FileUtils.writeStringToFile(path.toFile(), content, StandardCharsets.UTF_8);
} catch (IOException e) {
// 如果写入文件失败,则抛出自定义异常
throw new RGRuleException("Failed to write rolling gate config file", e);
}
}
}

19 changes: 19 additions & 0 deletions src/main/java/dev/anvilcraft/rg/api/RGAdditional.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,29 @@
import dev.anvilcraft.rg.api.server.ServerRGRuleManager;
import net.neoforged.fml.IExtensionPoint;

/**
* RGAdditional接口扩展了IExtensionPoint接口,旨在提供一个扩展点,
* 用于在服务器和客户端加载特定规则。这个接口允许实现类
* 在需要时自定义规则加载逻辑
*/
public interface RGAdditional extends IExtensionPoint {

/**
* 为服务器端加载规则提供了一个默认方法。这个方法在服务器规则管理器中
* 提供了一个接入点,实现类可以覆盖此方法以加载自定义的服务器规则
*
* @param manager 服务器规则管理器,用于操作和管理服务器规则
*/
default void loadServerRules(ServerRGRuleManager manager) {
}

/**
* 为客户端加载规则提供了一个默认方法。这个方法在客户端规则管理器中
* 提供了一个接入点,实现类可以覆盖此方法以加载自定义的客户端规则
*
* @param manager 客户端规则管理器,用于操作和管理客户端规则
*/
default void loadClientRules(ClientRGRuleManager manager) {
}
}

99 changes: 93 additions & 6 deletions src/main/java/dev/anvilcraft/rg/api/RGCodec.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* Realms of the Gods (RG) 编码解码器接口
* 提供自定义类型与JSON之间的序列化和反序列化功能
*
* @param <T> 要序列化和反序列化的类型
*/
package dev.anvilcraft.rg.api;

import com.google.gson.JsonDeserializationContext;
Expand All @@ -12,63 +18,144 @@
import java.lang.reflect.Type;
import java.util.function.Function;

/**
* RGCodec 类实现 JsonDeserializer 和 JsonSerializer 接口
* 提供自定义类型与JSON之间的序列化和反序列化功能
*
* @param <T> 要序列化和反序列化的类型
*/
public class RGCodec<T> implements JsonDeserializer<T>, JsonSerializer<T> {
// 类型类
private final Class<T> clazz;
// 解码函数,将字符串转换为指定类型
private final Function<String, T> decoder;
// 编码函数,将指定类型转换为字符串
private final Function<T, String> encoder;
private final boolean isLock;
// 是否锁定,表示该类型是否具有固定的编解码逻辑
private final boolean isBuiltIn;

// 预定义的字符串类型编解码器
public static final RGCodec<String> STRING = new RGCodec<>(String.class, String::toString, String::toString, true);
// 预定义的布尔类型编解码器
public static final RGCodec<Boolean> BOOLEAN = new RGCodec<>(Boolean.class, s -> s.equals("true"), Object::toString, true);
// 预定义的字节类型编解码器
public static final RGCodec<Byte> BYTE = new RGCodec<>(Byte.class, Byte::parseByte, Object::toString, true);
// 预定义的短整型编解码器
public static final RGCodec<Short> SHORT = new RGCodec<>(Short.class, Short::parseShort, Object::toString, true);
// 预定义的整型编解码器
public static final RGCodec<Integer> INTEGER = new RGCodec<>(Integer.class, Integer::parseInt, Object::toString, true);
// 预定义的长整型编解码器
public static final RGCodec<Long> LONG = new RGCodec<>(Long.class, Long::parseLong, Object::toString, true);
// 预定义的浮点型编解码器
public static final RGCodec<Float> FLOAT = new RGCodec<>(Float.class, Float::parseFloat, Object::toString, true);
// 预定义的双精度浮点型编解码器
public static final RGCodec<Double> DOUBLE = new RGCodec<>(Double.class, Double::parseDouble, Object::toString, true);

private RGCodec(Class<T> clazz, Function<String, T> decoder, Function<T, String> encoder, boolean isLock) {
/**
* 构造一个 RGCodec 实例
*
* @param clazz 类型类
* @param decoder 解码函数
* @param encoder 编码函数
* @param isBuiltIn 是否内置
*/
private RGCodec(Class<T> clazz, Function<String, T> decoder, Function<T, String> encoder, boolean isBuiltIn) {
this.clazz = clazz;
this.decoder = decoder;
this.encoder = encoder;
this.isLock = isLock;
this.isBuiltIn = isBuiltIn;
}

/**
* 创建一个 RGCodec 实例
*
* @param clazz 类型类
* @param decoder 解码函数
* @param encoder 编码函数
* @param <T> 类型
* @return RGCodec 实例
*/
@SuppressWarnings("unused")
public static <T> @NotNull RGCodec<T> of(Class<T> clazz, Function<String, T> decoder, Function<T, String> encoder) {
return new RGCodec<>(clazz, decoder, encoder, false);
}

/**
* 获取类型类
*
* @return 类型类
*/
public Class<T> clazz() {
return this.clazz;
}

public boolean isLock() {
return isLock;
/**
* 检查编解码器是否内置
*
* @return 是否内置
*/
public boolean isBuiltIn() {
return isBuiltIn;
}

/**
* 解码字符串为指定类型
*
* @param str 字符串
* @return 解码后的对象
*/
public T decode(String str) {
if (str == null) return null;
return this.decoder.apply(str);
}

/**
* 编码对象为字符串
*
* @param value 对象
* @return 编码后的字符串
*/
public String encode(T value) {
if (value == null) return null;
return this.encoder.apply(value);
}

/**
* 强制编码对象为字符串,不进行类型检查
*
* @param value 对象
* @return 编码后的字符串
*/
public String forceEncode(Object value) {
if (value == null) return null;
//noinspection unchecked
return this.encoder.apply((T) value);
}

/**
* 从 JsonElement 中反序列化为指定类型对象
*
* @param json JSON元素
* @param typeOfT 类型
* @param context 反序列化上下文
* @return 反序列化后的对象
* @throws JsonParseException JSON解析异常
*/
@Override
public T deserialize(@NotNull JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return this.decode(json.getAsString());
}

/**
* 序列化对象为 JsonElement
*
* @param src 对象
* @param typeOfSrc 类型
* @param context 序列化上下文
* @return 序列化后的 JSON元素
*/
@Override
public @NotNull JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(this.encode(src));
}
}
}
20 changes: 20 additions & 0 deletions src/main/java/dev/anvilcraft/rg/api/RGEnvironment.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
package dev.anvilcraft.rg.api;

/**
* 枚举 RGEnvironment 表示模块可以运行的不同环境
* 它包括两种类型:客户端和服务器。此枚举提供了确定当前环境的方法
*/
public enum RGEnvironment {
/**
* 表示客户端环境
*/
CLIENT,
/**
* 表示服务器端环境
*/
SERVER;

/**
* 检查当前环境是否为客户端.
*
* @return 如果当前环境是客户端,则为true,否则为false
*/
public boolean isClient() {
return this == CLIENT;
}

/**
* 检查当前环境是否为服务器端
*
* @return 如果当前环境是服务器端,则为true,否则为false
*/
public boolean isServer() {
return this == SERVER;
}
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/dev/anvilcraft/rg/api/RGRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,18 @@
import java.util.List;
import java.util.Map;

/**
* RGRule类用于定义和管理配置规则它是一个泛型记录类,用于存储配置项的相关信息和操作逻辑
*
* @param <T> 配置项的类型
*/
public record RGRule<T>(String namespace, Class<T> type, RGEnvironment environment, String[] categories,
String serialize, String[] allowed,
List<RGValidator<T>> validators, T defaultValue, Field field, RGCodec<T> codec) {

/**
* CODECS映射用于存储支持的类型及其对应的编解码器
*/
public static final Map<String, RGCodec<?>> CODECS = new HashMap<>() {{
put("java.lang.Boolean", RGCodec.BOOLEAN);
put("boolean", RGCodec.BOOLEAN);
Expand All @@ -35,18 +44,32 @@ public record RGRule<T>(String namespace, Class<T> type, RGEnvironment environme
put("java.lang.String", RGCodec.STRING);
}};

/**
* 创建一个新的RGRule实例
*
* @param namespace 命名空间,用于区分不同的配置范围
* @param field 配置项对应的Field对象
* @param <T> 配置项的类型
* @return 新创建的RGRule实例
* @throws RGRuleException 如果配置项不合法或不支持,则抛出此异常
*/
@SuppressWarnings("unchecked")
public static <T> @NotNull RGRule<T> of(String namespace, @NotNull Field field) {
String name = field.getName();
// 检查配置项是否是静态的
if (!Modifier.isStatic(field.getModifiers())) throw RGRuleException.notStatic(name);
// 检查配置项是否是公开的
if (!Modifier.isPublic(field.getModifiers())) throw RGRuleException.notPublic(name);
// 检查配置项是否不是final的
if (Modifier.isFinal(field.getModifiers())) throw RGRuleException.beFinal(name);
Class<?> type = RGRule.checkType(field);
Rule rule = field.getAnnotation(Rule.class);
// 确保配置项上有Rule注解
if (rule == null) throw RGRuleException.notAnnotated(name);
String serialize = rule.serialize().isEmpty() ? RGRule.caseToSnake(name) : rule.serialize();
RGRule.checkSerialize(serialize);
List<RGValidator<T>> validators = new ArrayList<>();
// 实例化所有验证器
for (Class<?> validator : rule.validator()) {
try {
validators.add((RGValidator<T>) validator.getDeclaredConstructor().newInstance());
Expand All @@ -55,11 +78,14 @@ public record RGRule<T>(String namespace, Class<T> type, RGEnvironment environme
}
}
RGCodec<?> rgCodec = RGRule.CODECS.getOrDefault(type.getTypeName(), null);
// 确保类型支持
if (rgCodec == null) {
throw RGRuleException.unsupportedType(name, type);
} else if (rgCodec.clazz() == Boolean.class) {
// 为Boolean类型添加默认验证器
validators.add((RGValidator<T>) new RGValidator.BooleanValidator());
} else if (rgCodec.clazz() == String.class && validators.isEmpty()) {
// 为String类型添加默认验证器
validators.add((RGValidator<T>) new RGValidator.StringValidator());
}
try {
Expand All @@ -80,10 +106,21 @@ public record RGRule<T>(String namespace, Class<T> type, RGEnvironment environme
}
}

/**
* 获取配置项的名称
*
* @return 配置项的名称
*/
public @NotNull String name() {
return this.field.getName();
}

/**
* 获取配置项的当前值
*
* @return 配置项的值
* @throws RGRuleException 如果无法访问配置项的值,则抛出此异常
*/
@SuppressWarnings("unchecked")
public T getValue() {
try {
Expand All @@ -93,6 +130,7 @@ public T getValue() {
}
}


/**
* 检查并转换字段的类型
* <p>
Expand Down
Loading

0 comments on commit 64b2f75

Please sign in to comment.