diff --git a/gradle.properties b/gradle.properties index 2b7f0d49..b717718e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version= 0.11.6 fabric_version = 0.36.1+1.17 # Mod Properties -mod_version = 0.4.0 +mod_version = 0.4.1 maven_group = ru.bclib archives_base_name = bclib diff --git a/src/main/java/ru/bclib/BCLib.java b/src/main/java/ru/bclib/BCLib.java index 681147fd..6ddbe5c7 100644 --- a/src/main/java/ru/bclib/BCLib.java +++ b/src/main/java/ru/bclib/BCLib.java @@ -39,6 +39,7 @@ public class BCLib implements ModInitializer { TagAPI.init(); CraftingRecipes.init(); WorldDataAPI.registerModCache(MOD_ID); + DataExchangeAPI.registerMod(MOD_ID); DataFixerAPI.registerPatch(() -> new BCLibPatch()); DataExchangeAPI.registerDescriptors(List.of( HelloClient.DESCRIPTOR, diff --git a/src/main/java/ru/bclib/api/WorldDataAPI.java b/src/main/java/ru/bclib/api/WorldDataAPI.java index 477807b7..5218f4f2 100644 --- a/src/main/java/ru/bclib/api/WorldDataAPI.java +++ b/src/main/java/ru/bclib/api/WorldDataAPI.java @@ -8,7 +8,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtIo; import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess; import ru.bclib.BCLib; -import ru.bclib.api.dataexchange.DataExchangeAPI; import ru.bclib.api.datafixer.DataFixerAPI; import java.io.File; @@ -20,8 +19,8 @@ import java.util.function.Consumer; /** * Mod-specifix data-storage for a world. - * - * This class provides the ability for mod to store persistent data inside a world. The Storage for the world is + *
+ * This class provides the ability for mod to store persistent data inside a world. The Storage for the world is
* currently initialized as part of the {@link DataFixerAPI} in {@link DataFixerAPI#fixData(LevelStorageAccess, boolean, Consumer)}
* or {@link DataFixerAPI#initializeWorldData(File, boolean)}
*/
@@ -32,45 +31,47 @@ public class WorldDataAPI {
public static void load(File dataDir) {
WorldDataAPI.dataDir = dataDir;
- MODS.stream().parallel().forEach(modID -> {
- File file = new File(dataDir, modID + ".nbt");
- CompoundTag root = new CompoundTag();
- if (file.exists()) {
- try {
- root = NbtIo.readCompressed(file);
- }
- catch (IOException e) {
- BCLib.LOGGER.error("World data loading failed", e);
- }
- }
- else {
- Optional
- * Will also register the Mod for the {@link DataExchangeAPI} using {@link DataExchangeAPI#registerMod(String)}
*
* @param modID - {@link String} modID.
*/
public static void registerModCache(String modID) {
MODS.add(modID);
- DataExchangeAPI.registerMod(modID);
}
/**
@@ -117,7 +118,7 @@ public class WorldDataAPI {
*/
public static void saveFile(String modID) {
try {
- if (!dataDir.exists()){
+ if (!dataDir.exists()) {
dataDir.mkdirs();
}
NbtIo.writeCompressed(getRootTag(modID), new File(dataDir, modID + ".nbt"));
diff --git a/src/main/java/ru/bclib/api/dataexchange/DataExchangeAPI.java b/src/main/java/ru/bclib/api/dataexchange/DataExchangeAPI.java
index fb179444..654136f6 100644
--- a/src/main/java/ru/bclib/api/dataexchange/DataExchangeAPI.java
+++ b/src/main/java/ru/bclib/api/dataexchange/DataExchangeAPI.java
@@ -13,157 +13,181 @@ import java.util.List;
import java.util.function.BiConsumer;
public class DataExchangeAPI extends DataExchange {
- private final static List
- * Depending on what the result of {@link DataHandler#getOriginatesOnServer()}, the Data is sent from the server
- * to the client (if {@code true}) or the other way around.
- *
- * The method {@link DataHandler#serializeData(FriendlyByteBuf)} is called just before the data is sent. You should
- * use this method to add the Data you need to the communication.
- *
- * @param h The Data that you want to send
- */
- public static void send(DataHandler h) {
- if (h.getOriginatesOnServer()) {
- DataExchangeAPI.getInstance().server.sendToClient(h);
- } else {
- DataExchangeAPI.getInstance().client.sendToServer(h);
- }
- }
-
- /**
- * Registers a File for automatic client syncing.
- *
- * @param modID The ID of the calling Mod
- * @param fileName The name of the File
- */
- public static void addAutoSyncFile(String modID, File fileName) {
- getInstance().addAutoSyncFileData(modID, fileName, false, FileHash.NEED_TRANSFER);
- }
-
- /**
- * Registers a File for automatic client syncing.
- *
- * The file is synced of the {@link FileHash} on client and server are not equal. This method will not copy the
- * configs content from the client to the server.
- *
- * @param modID The ID of the calling Mod
- * @param uniqueID A unique Identifier for the File. (see {@link ru.bclib.api.dataexchange.FileHash#uniqueID} for
- * Details
- * @param fileName The name of the File
- */
- public static void addAutoSyncFile(String modID, String uniqueID, File fileName) {
- getInstance().addAutoSyncFileData(modID, uniqueID, fileName, false, FileHash.NEED_TRANSFER);
- }
-
- /**
- * Registers a File for automatic client syncing.
- *
- * The content of the file is requested for comparison. This will copy the
- * entire file from the client to the server.
- *
- * You should only use this option, if you need to compare parts of the file in order to decide
- * if the File needs to be copied. Normally using the {@link ru.bclib.api.dataexchange.FileHash}
- * for comparison is sufficient.
- *
- * @param modID The ID of the calling Mod
- * @param fileName The name of the File
- * @param needTransfer If the predicate returns true, the file needs to get copied to the server.
- */
- public static void addAutoSyncFile(String modID, File fileName, NeedTransferPredicate needTransfer) {
- getInstance().addAutoSyncFileData(modID, fileName, true, needTransfer);
- }
-
- /**
- * Registers a File for automatic client syncing.
- *
- * The content of the file is requested for comparison. This will copy the
- * entire file from the client to the server.
- *
- * You should only use this option, if you need to compare parts of the file in order to decide
- * if the File needs to be copied. Normally using the {@link ru.bclib.api.dataexchange.FileHash}
- * for comparison is sufficient.
- *
- * @param modID The ID of the calling Mod
- * @param uniqueID A unique Identifier for the File. (see {@link ru.bclib.api.dataexchange.FileHash#uniqueID} for
- * Details
- * @param fileName The name of the File
- * @param needTransfer If the predicate returns true, the file needs to get copied to the server.
- */
- public static void addAutoSyncFile(String modID, String uniqueID, File fileName, NeedTransferPredicate needTransfer) {
- getInstance().addAutoSyncFileData(modID, uniqueID, fileName, true, needTransfer);
- }
-
- /**
- * Register a function that is called whenever the client receives a file from the server and replaced toe local
- * file with the new content.
- *
- * This callback is usefull if you need to reload the new content before the game is quit.
- * @param callback A Function that receives the AutoSyncID as well as the Filename.
- */
- public static void addOnWriteCallback(BiConsumer
+ * Depending on what the result of {@link DataHandler#getOriginatesOnServer()}, the Data is sent from the server
+ * to the client (if {@code true}) or the other way around.
+ *
+ * The method {@link DataHandler#serializeData(FriendlyByteBuf)} is called just before the data is sent. You should
+ * use this method to add the Data you need to the communication.
+ *
+ * @param h The Data that you want to send
+ */
+ public static void send(DataHandler h) {
+ if (h.getOriginatesOnServer()) {
+ DataExchangeAPI.getInstance().server.sendToClient(h);
+ }
+ else {
+ DataExchangeAPI.getInstance().client.sendToServer(h);
+ }
+ }
+
+ /**
+ * Registers a File for automatic client syncing.
+ *
+ * @param modID The ID of the calling Mod
+ * @param fileName The name of the File
+ */
+ public static void addAutoSyncFile(String modID, File fileName) {
+ getInstance().addAutoSyncFileData(modID, fileName, false, FileHash.NEED_TRANSFER);
+ }
+
+ /**
+ * Registers a File for automatic client syncing.
+ *
+ * The file is synced of the {@link FileHash} on client and server are not equal. This method will not copy the
+ * configs content from the client to the server.
+ *
+ * @param modID The ID of the calling Mod
+ * @param uniqueID A unique Identifier for the File. (see {@link ru.bclib.api.dataexchange.FileHash#uniqueID} for
+ * Details
+ * @param fileName The name of the File
+ */
+ public static void addAutoSyncFile(String modID, String uniqueID, File fileName) {
+ getInstance().addAutoSyncFileData(modID, uniqueID, fileName, false, FileHash.NEED_TRANSFER);
+ }
+
+ /**
+ * Registers a File for automatic client syncing.
+ *
+ * The content of the file is requested for comparison. This will copy the
+ * entire file from the client to the server.
+ *
+ * You should only use this option, if you need to compare parts of the file in order to decide
+ * if the File needs to be copied. Normally using the {@link ru.bclib.api.dataexchange.FileHash}
+ * for comparison is sufficient.
+ *
+ * @param modID The ID of the calling Mod
+ * @param fileName The name of the File
+ * @param needTransfer If the predicate returns true, the file needs to get copied to the server.
+ */
+ public static void addAutoSyncFile(String modID, File fileName, NeedTransferPredicate needTransfer) {
+ getInstance().addAutoSyncFileData(modID, fileName, true, needTransfer);
+ }
+
+ /**
+ * Registers a File for automatic client syncing.
+ *
+ * The content of the file is requested for comparison. This will copy the
+ * entire file from the client to the server.
+ *
+ * You should only use this option, if you need to compare parts of the file in order to decide
+ * if the File needs to be copied. Normally using the {@link ru.bclib.api.dataexchange.FileHash}
+ * for comparison is sufficient.
+ *
+ * @param modID The ID of the calling Mod
+ * @param uniqueID A unique Identifier for the File. (see {@link ru.bclib.api.dataexchange.FileHash#uniqueID} for
+ * Details
+ * @param fileName The name of the File
+ * @param needTransfer If the predicate returns true, the file needs to get copied to the server.
+ */
+ public static void addAutoSyncFile(String modID, String uniqueID, File fileName, NeedTransferPredicate needTransfer) {
+ getInstance().addAutoSyncFileData(modID, uniqueID, fileName, true, needTransfer);
+ }
+
+ /**
+ * Register a function that is called whenever the client receives a file from the server and replaced toe local
+ * file with the new content.
+ *
+ * This callback is usefull if you need to reload the new content before the game is quit.
+ *
+ * @param callback A Function that receives the AutoSyncID as well as the Filename.
+ */
+ public static void addOnWriteCallback(BiConsumer
+ * BCLib will ensure that the contents of sync-folder on the client is the same as the one on the server.
+ *
+ * @param modID ID of the Mod
+ * @return The path to the sync-folder
+ */
+ public static File getSyncFolder(String modID) {
+ File fl = SYNC_FOLDER.resolve(modID.replace(".", "-")
+ .replace(":", "-")
+ .replace("\\", "-")
+ .replace("/", "-"))
+ .toFile();
+
+ if (!fl.exists()){
+ fl.mkdirs();
+ }
+ return fl;
+ }
+
+ static {
+ addOnWriteCallback(Config::reloadSyncedConfig);
+ }
}
diff --git a/src/main/java/ru/bclib/api/dataexchange/handler/AutoFileSyncEntry.java b/src/main/java/ru/bclib/api/dataexchange/handler/AutoFileSyncEntry.java
index 2e6236bb..8b07255c 100644
--- a/src/main/java/ru/bclib/api/dataexchange/handler/AutoFileSyncEntry.java
+++ b/src/main/java/ru/bclib/api/dataexchange/handler/AutoFileSyncEntry.java
@@ -103,6 +103,7 @@ class AutoFileSyncEntry extends AutoSyncID {
data = buf.readByteArray(size);
return data;
}
+
public static AutoFileSyncEntry findMatching(FileHash hash) {
return findMatching(hash.modID, hash.uniqueID);
@@ -115,7 +116,7 @@ class AutoFileSyncEntry extends AutoSyncID {
public static AutoFileSyncEntry findMatching(String modID, String uniqueID) {
return DataExchange
.getInstance()
- .autoSyncFiles
+ .getAutoSyncFiles()
.stream()
.filter(asf -> asf.modID.equals(modID) && asf.uniqueID.equals(uniqueID))
.findFirst()
diff --git a/src/main/java/ru/bclib/api/dataexchange/handler/DataExchange.java b/src/main/java/ru/bclib/api/dataexchange/handler/DataExchange.java
index 9b15a7c9..7664076c 100644
--- a/src/main/java/ru/bclib/api/dataexchange/handler/DataExchange.java
+++ b/src/main/java/ru/bclib/api/dataexchange/handler/DataExchange.java
@@ -4,14 +4,17 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
+import net.fabricmc.loader.api.FabricLoader;
import ru.bclib.api.dataexchange.ConnectorClientside;
import ru.bclib.api.dataexchange.ConnectorServerside;
import ru.bclib.api.dataexchange.DataExchangeAPI;
import ru.bclib.api.dataexchange.DataHandler;
import ru.bclib.api.dataexchange.DataHandlerDescriptor;
import ru.bclib.api.dataexchange.FileHash;
+import ru.bclib.config.Configs;
import java.io.File;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -19,6 +22,12 @@ import java.util.Set;
import java.util.function.BiConsumer;
abstract public class DataExchange {
+ public final static Path SYNC_FOLDER = FabricLoader.getInstance()
+ .getGameDir()
+ .resolve("bclib-sync")
+ .toAbsolutePath();
+ public final static String SYNC_FOLDER_ID = "BCLIB-SYNC";
+
@FunctionalInterface
public interface NeedTransferPredicate {
public boolean test(FileHash clientHash, FileHash serverHash, FileContentWrapper content);
@@ -54,7 +63,9 @@ abstract public class DataExchange {
protected ConnectorServerside server;
protected ConnectorClientside client;
protected final Set