152 lines
5.4 KiB
Java
152 lines
5.4 KiB
Java
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.config.Configs;
|
|
import ru.bclib.gui.screens.ConfirmRestartScreen;
|
|
import ru.bclib.util.Pair;
|
|
import ru.bclib.util.Triple;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
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<AutoFileSyncEntry> files;
|
|
private String token = "";
|
|
public SendFiles(){
|
|
this(null, "");
|
|
}
|
|
public SendFiles(List<AutoFileSyncEntry> files, String token) {
|
|
super(DESCRIPTOR.IDENTIFIER, true);
|
|
this.files = files;
|
|
this.token = token;
|
|
}
|
|
|
|
public static boolean acceptFiles() {
|
|
return Configs.CLIENT_CONFIG.getBoolean(Configs.MAIN_SYNC_CATEGORY, "acceptFiles", true)
|
|
&& Configs.CLIENT_CONFIG.getBoolean(Configs.MAIN_SYNC_CATEGORY, "enabled", true);
|
|
}
|
|
|
|
@Override
|
|
protected boolean prepareData(boolean isClient) {
|
|
if (!Configs.MAIN_CONFIG.getBoolean(Configs.MAIN_SYNC_CATEGORY, "enabled", true)) {
|
|
BCLib.LOGGER.info("Auto-Sync was disabled on the server.");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected void serializeData(FriendlyByteBuf buf, boolean isClient) {
|
|
List<AutoFileSyncEntry> existingFiles = files.stream().filter(e -> e.fileName.exists()).collect(Collectors.toList());
|
|
/*
|
|
//this will try to send a file that was not registered or requested by the client
|
|
existingFiles.add(new AutoFileSyncEntry("none", new File("D:\\MinecraftPlugins\\BetterNether\\run\\server.properties"),true,(a, b, content) -> {
|
|
System.out.println("Got Content:" + content.length);
|
|
return true;
|
|
}));*/
|
|
|
|
/*//this will try to send a folder-file that was not registered or requested by the client
|
|
existingFiles.add(new AutoFileSyncEntry.ForDirectFileRequest(DataExchange.SYNC_FOLDER.folderID, new File("test.json"), DataExchange.SYNC_FOLDER.mapAbsolute("test.json").toFile()));*/
|
|
|
|
/*//this will try to send a folder-file that was not registered or requested by the client and is outside the base-folder
|
|
existingFiles.add(new AutoFileSyncEntry.ForDirectFileRequest(DataExchange.SYNC_FOLDER.folderID, new File("../breakout.json"), DataExchange.SYNC_FOLDER.mapAbsolute("../breakout.json").toFile()));*/
|
|
|
|
|
|
writeString(buf, token);
|
|
buf.writeInt(existingFiles.size());
|
|
|
|
BCLib.LOGGER.info("Sending " + existingFiles.size() + " Files to Client:");
|
|
for (AutoFileSyncEntry entry : existingFiles) {
|
|
int length = entry.serializeContent(buf);
|
|
BCLib.LOGGER.info(" - " + entry + " (" + length + " Bytes)");
|
|
}
|
|
}
|
|
|
|
private List<Pair<AutoFileSyncEntry, byte[]>> receivedFiles;
|
|
@Override
|
|
protected void deserializeFromIncomingData(FriendlyByteBuf buf, PacketSender responseSender, boolean fromClient) {
|
|
if (acceptFiles()) {
|
|
token = readString(buf);
|
|
if (!token.equals(RequestFiles.currentToken)) {
|
|
RequestFiles.newToken();
|
|
BCLib.LOGGER.error("Unrequested File Transfer!");
|
|
receivedFiles = new ArrayList<>(0);
|
|
return;
|
|
}
|
|
RequestFiles.newToken();
|
|
|
|
int size = buf.readInt();
|
|
receivedFiles = new ArrayList<>(size);
|
|
BCLib.LOGGER.info("Server sent " + size + " Files:");
|
|
for (int i = 0; i < size; i++) {
|
|
Triple<AutoFileSyncEntry, byte[], AutoSyncID> p = AutoFileSyncEntry.deserializeContent(buf);
|
|
if (p.first != null) {
|
|
receivedFiles.add(p);
|
|
BCLib.LOGGER.info(" - " + p.first + " (" + p.second.length + " Bytes)");
|
|
} else {
|
|
BCLib.LOGGER.error(" - Failed to receive File " + p.third + ", possibly sent from a Mod that is not installed on the client.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void runOnGameThread(Minecraft client, MinecraftServer server, boolean isClient) {
|
|
if (acceptFiles()) {
|
|
BCLib.LOGGER.info("Writing Files:");
|
|
|
|
//TODO: Reject files that were not in the last RequestFiles.
|
|
for (Pair<AutoFileSyncEntry, byte[]> entry : receivedFiles) {
|
|
final AutoFileSyncEntry e = entry.first;
|
|
final byte[] data = entry.second;
|
|
|
|
writeSyncedFile(e, data, e.fileName);
|
|
}
|
|
|
|
showConfirmRestart(client);
|
|
}
|
|
}
|
|
|
|
public static void writeSyncedFile(AutoSyncID e, byte[] data, File fileName) {
|
|
Path path = fileName.toPath();
|
|
BCLib.LOGGER.info(" - Writing " + path + " (" + data.length + " Bytes)");
|
|
try {
|
|
final File parentFile = path.getParent()
|
|
.toFile();
|
|
if (!parentFile.exists()){
|
|
parentFile.mkdirs();
|
|
}
|
|
Files.write(path, data);
|
|
DataExchange.didReceiveFile(e, fileName);
|
|
} catch (IOException ioException) {
|
|
BCLib.LOGGER.error(" --> Writing " + fileName + " failed: " + ioException);
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
protected void showConfirmRestart(Minecraft client){
|
|
client.setScreen(new ConfirmRestartScreen(() -> {
|
|
Minecraft.getInstance().setScreen((Screen)null);
|
|
client.stop();
|
|
}));
|
|
|
|
}
|
|
}
|