Skip to content

Commit

Permalink
merge: v1.1.8 for mc1.20.1
Browse files Browse the repository at this point in the history
  • Loading branch information
sakurawald committed Dec 23, 2023
1 parent a0f8e50 commit 5ae016c
Show file tree
Hide file tree
Showing 184 changed files with 176,345 additions and 2 deletions.
Binary file added .github/images/motd.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/images/system_message.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import com.google.gson.JsonParser

plugins {
id 'fabric-loom' version '1.4-SNAPSHOT'
Expand Down Expand Up @@ -124,7 +123,7 @@ modrinth {
versionNumber = "$mod_version"
versionType = "release"
uploadFile = remapJar
gameVersions = ["1.20.2"]
gameVersions = ["1.20.1"]
loaders = ["fabric"]
dependencies {
required.project "fabric-api"
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/assets/fuji/Cat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package assets.fuji;


public class Cat {
// we place a cat here, and you can ask the cat to meow
}
43 changes: 43 additions & 0 deletions src/main/java/io/github/sakurawald/Fuji.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.github.sakurawald;

import io.github.sakurawald.config.handler.ConfigHandler;
import io.github.sakurawald.module.ModuleManager;
import io.github.sakurawald.util.LogUtil;
import io.github.sakurawald.util.ScheduleUtil;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.Logger;

import java.nio.file.Path;

// TODO: warmup module
// TODO: placeholder module
// TODO: /tppos module
// TODO: command alias module (test priority with ZeroPermissionModule)
// TODO: playtime(every/for) rewards and rank like module
// TODO: kit module
// TODO: luckperms context calculate module
// TODO: /invsee module

public class Fuji implements ModInitializer {
public static final String MOD_ID = "fuji";
public static final Logger LOGGER = LogUtil.createLogger("Fuji");
public static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve(MOD_ID).toAbsolutePath();
public static MinecraftServer SERVER;

@Override
public void onInitialize() {
/* modules */
ModuleManager.initializeModules();
ServerLifecycleEvents.SERVER_STARTED.register(server -> ModuleManager.reportModules());

/* scheduler */
ServerLifecycleEvents.SERVER_STARTED.register(server -> ScheduleUtil.startScheduler());
ServerLifecycleEvents.SERVER_STOPPING.register(server -> {
ScheduleUtil.triggerJobs(ConfigHandler.ConfigHandlerAutoSaveJob.class.getName());
ScheduleUtil.shutdownScheduler();
});
}
}
16 changes: 16 additions & 0 deletions src/main/java/io/github/sakurawald/config/Configs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.github.sakurawald.config;

import io.github.sakurawald.config.handler.ConfigHandler;
import io.github.sakurawald.config.handler.ObjectConfigHandler;
import io.github.sakurawald.config.model.*;


public class Configs {

public static final ConfigHandler<ConfigModel> configHandler = new ObjectConfigHandler<>("config.json", ConfigModel.class);
public static final ConfigHandler<ChatModel> chatHandler = new ObjectConfigHandler<>("chat.json", ChatModel.class);
public static final ConfigHandler<PvPModel> pvpHandler = new ObjectConfigHandler<>("pvp.json", PvPModel.class);
public static final ConfigHandler<WorksModel> worksHandler = new ObjectConfigHandler<>("works.json", WorksModel.class);
public static final ConfigHandler<HeadModel> headHandler = new ObjectConfigHandler<>("head.json", HeadModel.class);
public static final ConfigHandler<SchedulerModule> schedulerHandler = new ObjectConfigHandler<>("scheduler.json", SchedulerModule.class);
}
128 changes: 128 additions & 0 deletions src/main/java/io/github/sakurawald/config/handler/ConfigHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package io.github.sakurawald.config.handler;

import assets.fuji.Cat;
import com.google.gson.*;
import io.github.sakurawald.module.initializer.works.work_type.Work;
import io.github.sakurawald.util.ScheduleUtil;
import lombok.Cleanup;
import lombok.Getter;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Map;
import java.util.Set;

import static io.github.sakurawald.Fuji.LOGGER;


public abstract class ConfigHandler<T> {

@Getter
protected static final Gson gson = new GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.serializeNulls()
.registerTypeAdapter(Work.class, new Work.WorkTypeAdapter())
.create();

protected File file;
protected T model;

protected boolean merged = false;

public ConfigHandler(File file) {
this.file = file;
}

public static JsonElement getJsonElement(String resourcePath) {
try {
InputStream inputStream = Cat.class.getResourceAsStream(resourcePath);
assert inputStream != null;
@Cleanup Reader reader = new BufferedReader(new InputStreamReader(inputStream));
return JsonParser.parseReader(reader);
} catch (Exception e) {
LOGGER.error(e.getMessage());
}

return null;
}

public abstract void loadFromDisk();

public abstract void saveToDisk();


public T model() {
return this.model;
}

public JsonElement toJsonElement() {
return gson.toJsonTree(this.model);
}


@SuppressWarnings("unused")
public void backupFromDisk() {
if (!file.exists()) return;
String originalFileName = file.getName();
String backupFileName = originalFileName + ".bak";
String backupFilePath = file.getParent() + File.separator + backupFileName;
File backupFile = new File(backupFilePath);
try {
Files.copy(file.toPath(), backupFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
LOGGER.error("Backup file failed: " + e.getMessage());
}
}

public void autoSave(String cron) {
String jobName = this.file.getName();
String jobGroup = ConfigHandlerAutoSaveJob.class.getName();
ScheduleUtil.removeJobs(jobGroup, jobName);
ScheduleUtil.addJob(ConfigHandlerAutoSaveJob.class, jobName, jobGroup, cron, new JobDataMap() {
{
this.put(ConfigHandler.class.getName(), ConfigHandler.this);
}
});
}

public void mergeJson(JsonElement oldJson, JsonElement newJson) {
if (!oldJson.isJsonObject() || !newJson.isJsonObject()) {
throw new IllegalArgumentException("Both elements must be JSON objects.");
}
mergeFields(oldJson.getAsJsonObject(), newJson.getAsJsonObject());
}

private void mergeFields(JsonObject oldJson, JsonObject newJson) {
Set<Map.Entry<String, JsonElement>> entrySet = newJson.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
String key = entry.getKey();
JsonElement value = entry.getValue();

if (oldJson.has(key) && oldJson.get(key).isJsonObject() && value.isJsonObject()) {
mergeFields(oldJson.getAsJsonObject(key), value.getAsJsonObject());
} else {
// note: for JsonArray, we will not directly set array elements, but we will add new properties for every array element (language default empty-value). e.g. For List<ExamplePojo>, we will never change the size of this list, but we will add missing properties for every ExamplePojo with the language default empty-value.
if (!oldJson.has(key)) {
oldJson.add(key, value);
LOGGER.warn("Add missing json property: file = {}, key = {}, value = {}", this.file.getName(), key, value);
}
}
}
}

public static class ConfigHandlerAutoSaveJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LOGGER.debug("AutoSave ConfigWrapper {}", context.getJobDetail().getKey().getName());
ConfigHandler<?> configHandler = (ConfigHandler<?>) context.getJobDetail().getJobDataMap().get(ConfigHandler.class.getName());
configHandler.saveToDisk();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.github.sakurawald.config.handler;

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonWriter;
import io.github.sakurawald.Fuji;
import lombok.Cleanup;

import java.io.*;
import java.lang.reflect.InvocationTargetException;


public class ObjectConfigHandler<T> extends ConfigHandler<T> {

Class<T> configClass;

public ObjectConfigHandler(File file, Class<T> configClass) {
super(file);
this.file = file;
this.configClass = configClass;
}

public ObjectConfigHandler(String child, Class<T> configClass) {
this(new File(Fuji.CONFIG_PATH.toString(), child), configClass);
}

public void loadFromDisk() {
// Does the file exist?
try {
if (!file.exists()) {
saveToDisk();
} else {
// read older json from disk
@Cleanup Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(this.file)));
JsonElement olderJsonElement = JsonParser.parseReader(reader);

// merge older json with newer json
if (!this.merged) {
this.merged = true;
T newerJsonInstance = configClass.getDeclaredConstructor().newInstance();
JsonElement newerJsonElement = gson.toJsonTree(newerJsonInstance, configClass);
mergeJson(olderJsonElement, newerJsonElement);
}

// read merged json
model = gson.fromJson(olderJsonElement, configClass);

this.saveToDisk();
}

} catch (IOException | NoSuchMethodException | InstantiationException | IllegalAccessException |
InvocationTargetException e) {
Fuji.LOGGER.error("Load config failed: " + e.getMessage());
}
}


public void saveToDisk() {
try {
// Should we generate a default config instance ?
if (!file.exists()) {
//noinspection ResultOfMethodCallIgnored
this.file.getParentFile().mkdirs();
this.model = configClass.getDeclaredConstructor().newInstance();
}

// Save.
JsonWriter jsonWriter = gson.newJsonWriter(new BufferedWriter(new FileWriter(this.file)));
gson.toJson(this.model, configClass, jsonWriter);
jsonWriter.close();
} catch (IOException | InstantiationException | NoSuchMethodException | IllegalAccessException |
InvocationTargetException e) {
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package io.github.sakurawald.config.handler;

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonWriter;
import io.github.sakurawald.Fuji;
import lombok.Cleanup;

import java.io.*;


public class ResourceConfigHandler extends ConfigHandler<JsonElement> {

final String resourcePath;

public ResourceConfigHandler(File file, String resourcePath) {
super(file);
this.file = file;
this.resourcePath = resourcePath;
}

public ResourceConfigHandler(String resourcePath) {
this(Fuji.CONFIG_PATH.resolve(resourcePath).toFile(), resourcePath);
}

public void loadFromDisk() {
// Does the file exist?
try {
if (!file.exists()) {
saveToDisk();
} else {
// read older json from disk
@Cleanup Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(this.file)));
JsonElement olderJsonElement = JsonParser.parseReader(reader);

// merge older json with newer json
if (!this.merged) {
this.merged = true;
JsonElement newerJsonElement = ResourceConfigHandler.getJsonElement(this.resourcePath);
mergeJson(olderJsonElement, newerJsonElement);
}

// read merged json
model = olderJsonElement;
this.saveToDisk();
}

} catch (IOException e) {
Fuji.LOGGER.error("Load config failed: " + e.getMessage());
}
}


@SuppressWarnings("ResultOfMethodCallIgnored")
public void saveToDisk() {
try {
// Should we generate a default config instance ?
if (!file.exists()) {
this.file.getParentFile().mkdirs();
this.model = ResourceConfigHandler.getJsonElement(this.resourcePath);
}

// Save.
JsonWriter jsonWriter = gson.newJsonWriter(new BufferedWriter(new FileWriter(this.file)));
gson.toJson(this.model, jsonWriter);
jsonWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

}
17 changes: 17 additions & 0 deletions src/main/java/io/github/sakurawald/config/model/ChatModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.sakurawald.config.model;

import java.util.HashMap;

@SuppressWarnings("InnerClassMayBeStatic")
public class ChatModel {

public Format format = new Format();

public class Format {
public HashMap<String, String> player2format = new HashMap<>() {
{
this.put("SakuraWald", "<#FFC7EA>%message%");
}
};
}
}
Loading

0 comments on commit 5ae016c

Please sign in to comment.