Finished first draft of File syncing
This commit is contained in:
parent
c28a566c78
commit
6883287c72
10 changed files with 209 additions and 18 deletions
|
@ -7,8 +7,11 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import ru.bclib.api.TagAPI;
|
||||
import ru.bclib.api.WorldDataAPI;
|
||||
import ru.bclib.api.dataexchange.DataExchangeAPI;
|
||||
import ru.bclib.api.dataexchange.DataHandler;
|
||||
import ru.bclib.api.dataexchange.handler.HelloClient;
|
||||
import ru.bclib.api.dataexchange.handler.HelloServer;
|
||||
import ru.bclib.api.dataexchange.handler.RequestFiles;
|
||||
import ru.bclib.api.dataexchange.handler.SendFiles;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.recipes.CraftingRecipes;
|
||||
import ru.bclib.registry.BaseBlockEntities;
|
||||
|
@ -16,6 +19,9 @@ import ru.bclib.registry.BaseRegistry;
|
|||
import ru.bclib.util.Logger;
|
||||
import ru.bclib.world.surface.BCLSurfaceBuilders;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BCLib implements ModInitializer {
|
||||
public static final String MOD_ID = "bclib";
|
||||
public static final Logger LOGGER = new Logger(MOD_ID);
|
||||
|
@ -30,8 +36,12 @@ public class BCLib implements ModInitializer {
|
|||
WorldDataAPI.registerModCache(MOD_ID);
|
||||
Configs.save();
|
||||
|
||||
DataExchangeAPI.registerDescriptor(HelloClient.DESCRIPTOR);
|
||||
DataExchangeAPI.registerDescriptor(HelloServer.DESCRIPTOR);
|
||||
DataExchangeAPI.registerDescriptors(List.of(
|
||||
HelloClient.DESCRIPTOR,
|
||||
HelloServer.DESCRIPTOR,
|
||||
RequestFiles.DESCRIPTOR,
|
||||
SendFiles.DESCRIPTOR
|
||||
));
|
||||
}
|
||||
|
||||
public static boolean isDevEnvironment() {
|
||||
|
|
|
@ -59,7 +59,7 @@ public class DataExchangeAPI extends DataExchange {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a new Descriptor for a DataHandler.
|
||||
* Add a new Descriptor for a {@link DataHandler}.
|
||||
* @param desc The Descriptor you want to add.
|
||||
*/
|
||||
public static void registerDescriptor(DataHandlerDescriptor desc){
|
||||
|
@ -67,6 +67,15 @@ public class DataExchangeAPI extends DataExchange {
|
|||
api.getDescriptors().add(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk-Add a Descriptors for your {@link DataHandler}-Objects.
|
||||
* @param desc The Descriptors you want to add.
|
||||
*/
|
||||
public static void registerDescriptors(List<DataHandlerDescriptor> desc){
|
||||
DataExchange api = DataExchange.getInstance();
|
||||
api.getDescriptors().addAll(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the Handler.
|
||||
* <p>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package ru.bclib.api.dataexchange;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import ru.bclib.api.dataexchange.handler.HelloClient;
|
||||
import ru.bclib.api.dataexchange.handler.HelloServer;
|
||||
import ru.bclib.api.dataexchange.handler.RequestFiles;
|
||||
import ru.bclib.api.dataexchange.handler.SendFiles;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
|
|
@ -97,10 +97,10 @@ abstract public class DataExchange {
|
|||
return new byte[0];
|
||||
}
|
||||
|
||||
public void serializeContent(FriendlyByteBuf buf){
|
||||
public int serializeContent(FriendlyByteBuf buf){
|
||||
DataHandler.writeString(buf, modID);
|
||||
DataHandler.writeString(buf, uniqueID);
|
||||
serializeFileContent(buf);
|
||||
return serializeFileContent(buf);
|
||||
}
|
||||
public static Pair<AutoFileSyncEntry, byte[]> deserializeContent(FriendlyByteBuf buf){
|
||||
final String modID = DataHandler.readString(buf);
|
||||
|
@ -138,10 +138,11 @@ abstract public class DataExchange {
|
|||
return new Pair(hash, data);
|
||||
}
|
||||
|
||||
private void serializeFileContent(FriendlyByteBuf buf) {
|
||||
private int serializeFileContent(FriendlyByteBuf buf) {
|
||||
byte[] content = getContent();
|
||||
buf.writeInt(content.length);
|
||||
buf.writeByteArray(content);
|
||||
return content.length;
|
||||
}
|
||||
|
||||
private static byte[] deserializeFileContent(FriendlyByteBuf buf) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import ru.bclib.api.dataexchange.DataHandler;
|
|||
import ru.bclib.api.dataexchange.DataHandlerDescriptor;
|
||||
import ru.bclib.api.dataexchange.handler.DataExchange.AutoSyncID;
|
||||
import ru.bclib.api.datafixer.DataFixerAPI;
|
||||
import ru.bclib.gui.screens.SyncFilesScreen;
|
||||
import ru.bclib.gui.screens.WarnBCLibVersionMismatch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -134,8 +135,10 @@ public class HelloClient extends DataHandler {
|
|||
|
||||
BCLib.LOGGER.info(" - " + e + ": " + (willRequest ? " (requesting)":""));
|
||||
}
|
||||
|
||||
if (filesToRequest.size()>0) {
|
||||
showDonwloadConfigs(client, filesToRequest);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,9 +157,13 @@ public class HelloClient extends DataHandler {
|
|||
|
||||
@Environment(EnvType.CLIENT)
|
||||
protected void showDonwloadConfigs(Minecraft client, List<AutoSyncID> files){
|
||||
requestFileDownloads((hadErrors)->{
|
||||
client.stop();
|
||||
}, files);
|
||||
client.setScreen(new SyncFilesScreen((download) -> {
|
||||
Minecraft.getInstance().setScreen((Screen)null);
|
||||
if (download){
|
||||
requestFileDownloads(files);
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
private void requestBCLibDownload(Consumer<Boolean> whenFinished){
|
||||
|
@ -164,9 +171,8 @@ public class HelloClient extends DataHandler {
|
|||
whenFinished.accept(true);
|
||||
}
|
||||
|
||||
private void requestFileDownloads(Consumer<Boolean> whenFinished, List<AutoSyncID> files){
|
||||
private void requestFileDownloads(List<AutoSyncID> files){
|
||||
BCLib.LOGGER.info("Starting download of Files:" + files.size());
|
||||
DataExchangeAPI.send(new RequestFiles(files));
|
||||
whenFinished.accept(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,12 @@ import ru.bclib.api.dataexchange.handler.DataExchange.AutoSyncID;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RequestFiles extends DataHandler {
|
||||
public static DataHandlerDescriptor DESCRIPTOR = new DataHandlerDescriptor(new ResourceLocation(BCLib.MOD_ID, "request_files"), RequestFiles::new, false, false);
|
||||
static String currentToken = "";
|
||||
|
||||
protected List<AutoSyncID> files;
|
||||
private RequestFiles(){
|
||||
|
@ -29,6 +31,9 @@ public class RequestFiles extends DataHandler {
|
|||
|
||||
@Override
|
||||
protected void serializeData(FriendlyByteBuf buf) {
|
||||
newToken();
|
||||
writeString(buf, currentToken);
|
||||
|
||||
buf.writeInt(files.size());
|
||||
|
||||
for (AutoSyncID a : files){
|
||||
|
@ -37,8 +42,10 @@ public class RequestFiles extends DataHandler {
|
|||
}
|
||||
}
|
||||
|
||||
String receivedToken = "";
|
||||
@Override
|
||||
protected void deserializeFromIncomingData(FriendlyByteBuf buf, PacketSender responseSender, boolean fromClient) {
|
||||
receivedToken = readString(buf);
|
||||
int size = buf.readInt();
|
||||
files = new ArrayList<>(size);
|
||||
|
||||
|
@ -61,6 +68,16 @@ public class RequestFiles extends DataHandler {
|
|||
.filter(e -> e!=null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
reply(new SendFiles(syncEntries), server);
|
||||
reply(new SendFiles(syncEntries, receivedToken), server);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void newToken(){
|
||||
currentToken = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
static {
|
||||
newToken();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,67 @@
|
|||
package ru.bclib.api.dataexchange.handler;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.dataexchange.DataHandler;
|
||||
import ru.bclib.api.dataexchange.DataHandlerDescriptor;
|
||||
import ru.bclib.gui.screens.ConfirmRestartScreen;
|
||||
import ru.bclib.gui.screens.SyncFilesScreen;
|
||||
import ru.bclib.util.Pair;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.OpenOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SendFiles extends DataHandler {
|
||||
public static DataHandlerDescriptor DESCRIPTOR = new DataHandlerDescriptor(new ResourceLocation(BCLib.MOD_ID, "send_files"), SendFiles::new, false, false);
|
||||
|
||||
protected List<DataExchange.AutoFileSyncEntry> files;
|
||||
private String token = "";
|
||||
public SendFiles(){
|
||||
this(null);
|
||||
this(null, "");
|
||||
}
|
||||
public SendFiles(List<DataExchange.AutoFileSyncEntry> files) {
|
||||
public SendFiles(List<DataExchange.AutoFileSyncEntry> files, String token) {
|
||||
super(DESCRIPTOR.IDENTIFIER, true);
|
||||
this.files = files;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void serializeData(FriendlyByteBuf buf) {
|
||||
List<DataExchange.AutoFileSyncEntry> existingFiles = files.stream().filter(e -> e.fileName.exists()).collect(Collectors.toList());
|
||||
writeString(buf, token);
|
||||
buf.writeInt(existingFiles.size());
|
||||
|
||||
BCLib.LOGGER.info("Sending " + existingFiles.size() + " Files to Client:");
|
||||
for (DataExchange.AutoFileSyncEntry entry : existingFiles) {
|
||||
entry.serializeContent(buf);
|
||||
int length = entry.serializeContent(buf);
|
||||
BCLib.LOGGER.info(" - " + entry + " (" + length + " Bytes)");
|
||||
}
|
||||
}
|
||||
|
||||
private List<Pair<DataExchange.AutoFileSyncEntry, byte[]>> receivedFiles;
|
||||
@Override
|
||||
protected void deserializeFromIncomingData(FriendlyByteBuf buf, PacketSender responseSender, boolean fromClient) {
|
||||
token = readString(buf);
|
||||
if (!token.equals(RequestFiles.currentToken)) {
|
||||
BCLib.LOGGER.error("Unrequested File Transfer!");
|
||||
receivedFiles = new ArrayList<>(0);
|
||||
return;
|
||||
}
|
||||
|
||||
int size = buf.readInt();
|
||||
receivedFiles = new ArrayList<>(size);
|
||||
BCLib.LOGGER.info("Server sent " + size + " Files:");
|
||||
|
@ -55,6 +78,28 @@ public class SendFiles extends DataHandler {
|
|||
|
||||
@Override
|
||||
protected void runOnGameThread(Minecraft client, MinecraftServer server, boolean isClient) {
|
||||
BCLib.LOGGER.info("Writing Files:");
|
||||
for (Pair<DataExchange.AutoFileSyncEntry, byte[]> entry : receivedFiles) {
|
||||
final DataExchange.AutoFileSyncEntry e = entry.first;
|
||||
final byte[] data = entry.second;
|
||||
Path path = e.fileName.toPath();
|
||||
BCLib.LOGGER.info(" - Writing " + path + " (" + data.length + " Bytes)");
|
||||
try {
|
||||
Files.write(path, data);
|
||||
} catch (IOException ioException) {
|
||||
BCLib.LOGGER.error(" --> Writing "+e.fileName+" failed: " + ioException);
|
||||
}
|
||||
}
|
||||
|
||||
showConfirmRestart(client);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
protected void showConfirmRestart(Minecraft client){
|
||||
client.setScreen(new ConfirmRestartScreen(() -> {
|
||||
Minecraft.getInstance().setScreen((Screen)null);
|
||||
client.stop();
|
||||
}));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
49
src/main/java/ru/bclib/gui/screens/ConfirmRestartScreen.java
Normal file
49
src/main/java/ru/bclib/gui/screens/ConfirmRestartScreen.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package ru.bclib.gui.screens;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import ru.bclib.gui.GridScreen;
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ConfirmRestartScreen extends GridScreen {
|
||||
private final Component description;
|
||||
private final ConfirmRestartScreen.Listener listener;
|
||||
|
||||
public ConfirmRestartScreen(ConfirmRestartScreen.Listener listener) {
|
||||
this(listener, null);
|
||||
}
|
||||
|
||||
public ConfirmRestartScreen(ConfirmRestartScreen.Listener listener, Component message) {
|
||||
super(30, new TranslatableComponent("bclib.datafixer.confirmrestart.title"));
|
||||
|
||||
this.description = message==null?new TranslatableComponent("bclib.datafixer.confirmrestart.message"):message;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
protected void initLayout() {
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
|
||||
grid.addMessageRow(this.description, 25);
|
||||
|
||||
grid.startRow();
|
||||
grid.addButton( BUTTON_HEIGHT, CommonComponents.GUI_PROCEED, (button) -> {
|
||||
listener.proceed();
|
||||
});
|
||||
|
||||
grid.endRow();
|
||||
grid.recenterVertically();
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Listener {
|
||||
void proceed();
|
||||
}
|
||||
}
|
46
src/main/java/ru/bclib/gui/screens/SyncFilesScreen.java
Normal file
46
src/main/java/ru/bclib/gui/screens/SyncFilesScreen.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package ru.bclib.gui.screens;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import ru.bclib.gui.GridScreen;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class SyncFilesScreen extends GridScreen {
|
||||
private final Component description;
|
||||
private final SyncFilesScreen.Listener listener;
|
||||
public SyncFilesScreen(SyncFilesScreen.Listener listener) {
|
||||
super(30, new TranslatableComponent("bclib.datafixer.syncfiles.title"));
|
||||
|
||||
this.description = new TranslatableComponent("bclib.datafixer.syncfiles.message");
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
protected void initLayout() {
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
|
||||
grid.addMessageRow(this.description, 25);
|
||||
|
||||
grid.startRow();
|
||||
grid.addButton( BUTTON_HEIGHT, CommonComponents.GUI_NO, (button) -> {
|
||||
listener.proceed(false);
|
||||
});
|
||||
grid.addButton( BUTTON_HEIGHT, CommonComponents.GUI_YES, (button) -> {
|
||||
listener.proceed(true);
|
||||
});
|
||||
|
||||
grid.endRow();
|
||||
grid.recenterVertically();
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Listener {
|
||||
void proceed(boolean download);
|
||||
}
|
||||
}
|
|
@ -6,5 +6,9 @@
|
|||
"bclib.datafixer.backupWarning.nofixes": "Continue Without Fixes",
|
||||
"bclib.datafixer.backupWarning.continue": "Continue Without Backup",
|
||||
"bclib.datafixer.bclibmissmatch.title": "Version Mismatch",
|
||||
"bclib.datafixer.bclibmissmatch.message": "The Version of BCLib on the server and this client do not match. This will cause problems when playing.\n\nDo you want to automatically download the BCLib-Version from the server. You will need to delete the old version from your Mods Directory and restart the game."
|
||||
"bclib.datafixer.bclibmissmatch.message": "The Version of BCLib on the server and this client do not match. This will cause problems when playing.\n\nDo you want to automatically download the BCLib-Version from the server. You will need to delete the old version from your Mods Directory and restart the game.",
|
||||
"bclib.datafixer.syncfiles.title": "Mismatching (Config-)Files",
|
||||
"bclib.datafixer.syncfiles.message": "Some Files on the Server doe not match the versions on the client.\n\nDo you want to replace the local versions with the ones from the server?",
|
||||
"bclib.datafixer.confirmrestart.title": "Restart Required",
|
||||
"bclib.datafixer.confirmrestart.message": "The requested files were processed. You need o restart Minecraft now."
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue