Skip to content

Commit

Permalink
将实现从节日迁移至功能
Browse files Browse the repository at this point in the history
  • Loading branch information
Gu-ZT committed Feb 20, 2024
1 parent ebca916 commit 5a27633
Show file tree
Hide file tree
Showing 46 changed files with 682 additions and 729 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,74 @@
package dev.dubhe.chinesefestivals;

import com.mojang.logging.LogUtils;
import dev.dubhe.chinesefestivals.features.Features;
import dev.dubhe.chinesefestivals.features.IFeature;
import dev.dubhe.chinesefestivals.festivals.Festivals;
import dev.dubhe.chinesefestivals.festivals.IFestival;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.function.BiFunction;

public class ChineseFestivals {
public static final Logger LOGGER = LogUtils.getLogger();
public static final String MOD_ID = "chinesefestivals";
public static final String FEATURES_CONFIG = "features";
public static IFestival debugFestival = null;
public static ChineseFestivalsContext context = new ChineseFestivalsContext();

public static void init() {
Festivals.init();
public static void init(ChineseFestivalsContext context) {
ChineseFestivals.context = context;
Festivals.refresh();
LOGGER.info("ChineseFestivals initialized");
}

public static ResourceLocation of(String id) {
return new ResourceLocation(ChineseFestivals.MOD_ID, id);
}

public static IFeature getOrCreateFeature(String id, BiFunction<String, IFestival[], IFeature> featureGenerator) {
File featureFile = getFeatureFile(id);
if (!featureFile.isFile()) {
IFeature feature = featureGenerator.apply(id, new IFestival[]{});
try {
if (!featureFile.createNewFile()) {
throw new IOException();
}
try (FileWriter writer = new FileWriter(featureFile)) {
Features.GSON.toJson(feature, IFeature.class, writer);
}
} catch (IOException e) {
throw new RuntimeException("Failed to create feature file", e);
}
return feature;
}
try (FileReader reader = new FileReader(featureFile)) {
return Features.GSON.fromJson(reader, IFeature.class);
} catch (IOException e) {
throw new RuntimeException("Failed to read feature file", e);
}
}

@NotNull
private static File getFeatureFile(String id) {
if (ChineseFestivals.context.configPath == null)
throw new RuntimeException("ChineseFestivals context not initialized");
Path featurePath = ChineseFestivals.context.configPath.resolve(MOD_ID).resolve(ChineseFestivals.FEATURES_CONFIG);
File featurePathFile = featurePath.toFile();
if (!featurePathFile.isDirectory() && !featurePath.toFile().mkdirs()) {
throw new RuntimeException("Failed to create feature directory");
}
return featurePath.resolve("%s.json".formatted(id)).toFile();
}

public static class ChineseFestivalsContext {
public Path configPath = new File(".").toPath().resolve("config");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import dev.dubhe.chinesefestivals.ChineseFestivals;
import dev.dubhe.chinesefestivals.features.Features;
import dev.dubhe.chinesefestivals.festivals.Festivals;
import dev.dubhe.chinesefestivals.festivals.IFestival;
import net.minecraft.commands.CommandSourceStack;
Expand All @@ -31,7 +32,18 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
}
return 0;
})
.then(DebugCommands.genCommands()).then(Commands.literal("test").then(Commands.argument("val", FloatArgumentType.floatArg()).executes((context) -> {
.then(DebugCommands.genCommands())
.then(Commands.literal("reload").executes(context -> {
try {
Features.refresh();
context.getSource().sendSuccess(() -> Component.literal("Reloaded!"), false);
} catch (Exception e) {
e.printStackTrace();
}
return Command.SINGLE_SUCCESS;
})
)
.then(Commands.literal("test").then(Commands.argument("val", FloatArgumentType.floatArg()).executes((context) -> {
test = FloatArgumentType.getFloat(context, "val");
context.getSource().sendSuccess(() -> Component.literal("success"), false);
return Command.SINGLE_SUCCESS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ public String getId() {

@Override
public boolean isNow() {
return this.enableTimes.stream().anyMatch(IFestival::isNow);
for (IFestival enableTime : this.enableTimes) {
if (enableTime.isNow()) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class FeatureParser implements JsonSerializer<IFeature>, JsonDeserializer<IFeature> {
Expand All @@ -13,7 +14,7 @@ public IFeature deserialize(JsonElement jsonElement, Type type, JsonDeserializat
if (!jsonElement.isJsonObject()) throw new JsonParseException("JSON format does not meet the requirements.");
JsonObject featureJsonObject = jsonElement.getAsJsonObject();
JsonElement tempJsonElement = featureJsonObject.get("id");
if (!(tempJsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()))
if (!(tempJsonElement.isJsonPrimitive() && tempJsonElement.getAsJsonPrimitive().isString()))
throw new JsonParseException("JSON format does not meet the requirements.");
String id = tempJsonElement.getAsString();
tempJsonElement = featureJsonObject.get("enable_times");
Expand All @@ -37,7 +38,7 @@ public JsonElement serialize(IFeature feature, Type type, JsonSerializationConte
JsonArray enableTimes = new JsonArray();
if (feature instanceof Feature feature1) {
for (IFestival time : feature1.enableTimes) {
enableTimes.add(Features.GSON.toJsonTree(time, IFeature.class));
enableTimes.add(Features.GSON.toJsonTree(time, IFestival.class));
}
}
root.add("enable_times", enableTimes);
Expand All @@ -56,10 +57,12 @@ else if (jsonElement.isJsonObject())

public IFestival deserialize(String str) throws JsonParseException {
str = str.replaceAll(" ", "");
String saveStr = str;
// "spring"
for (IFestival festival : Festivals.FESTIVALS) {
if (festival.getId().equals(str)) return festival;
}
str = saveStr;
// "冬至"
for (SolarTermFestival.SolarTerm jieQi : SolarTermFestival.SolarTerm.values()) {
if (jieQi.name.equals(str)) {
Expand All @@ -68,6 +71,7 @@ public IFestival deserialize(String str) throws JsonParseException {
return festival;
}
}
str = saveStr;
// "12.23"
String regular = "^\\d+.\\d+$";
if (str.matches(regular)) {
Expand All @@ -78,18 +82,19 @@ public IFestival deserialize(String str) throws JsonParseException {
Festivals.FESTIVALS.add(festival);
return festival;
}
str = saveStr;
// "腊月廿三"
regular = "^\\D月[初二廿三]\\D$";
regular = "^\\D月[初十二廿三]\\D$";
if (str.matches(regular)) {
int month = 0, day = 0;
for (LunarMonth lunarMonth : LunarMonth.values()) {
if (lunarMonth.name.equals(str)) {
if (lunarMonth.name.equals(str.substring(0, 2))) {
month = lunarMonth.month;
break;
}
}
for (LunarDay lunarDay : LunarDay.values()) {
if (lunarDay.name.equals(str)) {
if (lunarDay.name.equals(str.substring(2, 4))) {
day = lunarDay.day;
break;
}
Expand All @@ -99,6 +104,7 @@ public IFestival deserialize(String str) throws JsonParseException {
Festivals.FESTIVALS.add(festival);
return festival;
}
str = saveStr;
// "[12.23, 1.8]"
regular = "^\\[\\d+.\\d+,\\d+.\\d+]$";
if (str.matches(regular)) {
Expand All @@ -111,24 +117,25 @@ public IFestival deserialize(String str) throws JsonParseException {
Festivals.FESTIVALS.add(festival);
return festival;
}
str = saveStr;
// "[腊月廿三, 正月初八]"
regular = "^\\[\\D月[初二廿三]\\D,\\D月[初二廿三]\\D]$";
regular = "^\\[\\D月[初十二廿三]\\D,\\D月[初十二廿三]\\D]$";
if (str.matches(regular)) {
String[] split = str.substring(1, str.length() - 1).split(",");
int fromMonth = 0, fromDay = 0, toMonth = 0, toDay = 0;
for (LunarMonth lunarMonth : LunarMonth.values()) {
if (lunarMonth.name.equals(split[0])) {
if (lunarMonth.name.equals(split[0].substring(0, 2))) {
fromMonth = lunarMonth.month;
}
if (lunarMonth.name.equals(split[1])) {
if (lunarMonth.name.equals(split[1].substring(0, 2))) {
toMonth = lunarMonth.month;
}
}
for (LunarDay lunarDay : LunarDay.values()) {
if (lunarDay.name.equals(split[0])) {
if (lunarDay.name.equals(split[0].substring(2, 4))) {
fromDay = lunarDay.day;
}
if (lunarDay.name.equals(split[1])) {
if (lunarDay.name.equals(split[1].substring(2, 4))) {
toDay = lunarDay.day;
}
}
Expand Down Expand Up @@ -222,6 +229,7 @@ public JsonElement serialize(IFestival iFestival, Type type, JsonSerializationCo
} else if (Festivals.FESTIVALS.contains(iFestival)) {
return new JsonPrimitive(iFestival.getId());
} else {
System.out.println(Festivals.FESTIVALS.contains(iFestival));
throw new JsonParseException("This festival does not exist.");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.dubhe.chinesefestivals.features.impl.Dumplings;
import dev.dubhe.chinesefestivals.features.impl.SweetDumplings;
import dev.dubhe.chinesefestivals.ChineseFestivals;
import dev.dubhe.chinesefestivals.features.impl.*;
import dev.dubhe.chinesefestivals.festivals.IFestival;

import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Supplier;
Expand All @@ -18,22 +20,56 @@ public class Features {
.registerTypeAdapter(IFestival.class, new FeatureParser.FestivalParser())
.create();
public static final Map<String, BiFunction<String, IFestival[], IFeature>> FEATURE_GENERATORS = new ConcurrentHashMap<>();
public static final Supplier<IFeature> COUPLETS = new FeatureGetter("couplets", Couplets::new);
public static final Supplier<IFeature> DUMPLINGS = new FeatureGetter("dumplings", Dumplings::new);
public static final Supplier<IFeature> FIREWORKS = new FeatureGetter("fireworks", Fireworks::new);
public static final Supplier<IFeature> FLOWER_CAKE = new FeatureGetter("flower_cake", FlowerCake::new);
public static final Supplier<IFeature> HOTPOTS = new FeatureGetter("hotpots", Hotpots::new);
public static final Supplier<IFeature> LABA_CONGEE = new FeatureGetter("laba_congee", LabaCongee::new);
public static final Supplier<IFeature> LANTERNS = new FeatureGetter("lanterns", Lanterns::new);
public static final Supplier<IFeature> MOONCAKES = new FeatureGetter("mooncakes", Mooncakes::new);
public static final Supplier<IFeature> PLATES = new FeatureGetter("plates", Plates::new);
public static final Supplier<IFeature> SWEET_DUMPLINGS = new FeatureGetter("sweet_dumplings", SweetDumplings::new);
public static final List<Supplier<IFeature>> FEATURES = new Vector<>() {{
add(COUPLETS);
add(DUMPLINGS);
add(FIREWORKS);
add(FLOWER_CAKE);
add(HOTPOTS);
add(LABA_CONGEE);
add(LANTERNS);
add(MOONCAKES);
add(PLATES);
add(SWEET_DUMPLINGS);
}};

public static void refresh() {
for (Supplier<IFeature> feature : FEATURES) {
if (feature instanceof FeatureGetter getter) {
getter.refresh();
}
}
}

public static class FeatureGetter implements Supplier<IFeature> {
String id;
BiFunction<String, IFestival[], IFeature> featureGenerator;
IFeature feature = null;

public FeatureGetter(String id, BiFunction<String, IFestival[], IFeature> feature) {
public FeatureGetter(String id, BiFunction<String, IFestival[], IFeature> featureGenerator) {
this.id = id;
this.featureGenerator = feature;
this.featureGenerator = featureGenerator;
Features.FEATURE_GENERATORS.put(id, featureGenerator);
}

@Override
public IFeature get() {
if (feature == null) this.feature = ChineseFestivals.getOrCreateFeature(this.id, this.featureGenerator);
return this.feature;
}

public void refresh() {
this.feature = ChineseFestivals.getOrCreateFeature(this.id, this.featureGenerator);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import dev.dubhe.chinesefestivals.ChineseFestivals;
import dev.dubhe.chinesefestivals.data.BlockModelData;
import dev.dubhe.chinesefestivals.festivals.BlockFactory;
import dev.dubhe.chinesefestivals.festivals.BlockItemFactory;
import dev.dubhe.chinesefestivals.festivals.ItemFactory;
import dev.dubhe.chinesefestivals.festivals.*;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
Expand All @@ -18,13 +16,15 @@
import net.minecraft.world.level.block.state.BlockState;

import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;

public interface IFeature {
Map<ResourceLocation, Supplier<Block>> BLOCK_REGISTER = new HashMap<>();
Map<ResourceLocation, Supplier<Item>> ITEM_REGISTER = new HashMap<>();
Map<ResourceLocation, Supplier<PaintingVariant>> PAINTING_REGISTER = new HashMap<>();
Collection<BlockModelData> BLOCK_MODELS = new HashSet<>();

String getId();

boolean isNow();
Expand Down Expand Up @@ -78,4 +78,28 @@ static Supplier<Item> createBlockItem(String id, Supplier<Block> block, Item.Pro
ITEM_REGISTER.put(ChineseFestivals.of(id), itemFactory);
return itemFactory;
}

static ModelResourceLocation registerBlockModel(BlockModelData model) {
if (IFeature.BLOCK_MODELS.stream().parallel().noneMatch(it -> it.resourceLocation.equals(model.resourceLocation))) {
IFeature.BLOCK_MODELS.add(model);
}
return model.model();
}

static PaintingVariant registerPainting(String id, int x, int y) {
PaintingVariant variant = new PaintingVariant(x, y);
IFeature.PAINTING_REGISTER.put(ChineseFestivals.of(id), () -> variant);
return variant;
}

static <T> T execute(Function<IFeature, T> supplier) {
for (Supplier<IFeature> feature : Features.FEATURES) {
if (feature.get().isNow()) {
T data = supplier.apply(feature.get());
if (data == null) continue;
return data;
}
}
return null;
}
}
Loading

0 comments on commit 5a27633

Please sign in to comment.