Refactor
This commit is contained in:
parent
6883287c72
commit
3438c86de2
6 changed files with 182 additions and 169 deletions
|
@ -23,7 +23,7 @@ import java.util.function.Predicate;
|
|||
* You can compare instances using {@link #equals(Object)} to determine if two files are
|
||||
* identical.
|
||||
*/
|
||||
public class FileHash {
|
||||
public class FileHash extends DataExchange.AutoSyncID {
|
||||
/**
|
||||
* The md5-hash of the file
|
||||
*/
|
||||
|
@ -40,35 +40,19 @@ public class FileHash {
|
|||
*/
|
||||
public final int value;
|
||||
|
||||
/**
|
||||
* A Unique ID for the referenced File.
|
||||
* <p>
|
||||
* Files with the same {@link #modID} need to have a unique IDs. Normally the filename from {@link #FileHash(String, File, byte[], int, int)}
|
||||
* is used to generated that ID, but you can directly specify one using {@link #FileHash(String, String, byte[], int, int)}.
|
||||
*/
|
||||
@NotNull
|
||||
public final String uniqueID;
|
||||
|
||||
/**
|
||||
* The ID of the Mod that is registering the File
|
||||
*/
|
||||
@NotNull
|
||||
public final String modID;
|
||||
|
||||
FileHash(String modID, File file, byte[] md5, int size, int value) {
|
||||
this(modID, file.getName(), md5, size, value);
|
||||
}
|
||||
|
||||
FileHash(String modID, String uniqueID, byte[] md5, int size, int value) {
|
||||
Objects.nonNull(modID);
|
||||
Objects.nonNull(uniqueID);
|
||||
super(modID, uniqueID);
|
||||
Objects.nonNull(md5);
|
||||
|
||||
this.md5 = md5;
|
||||
this.size = size;
|
||||
this.value = value;
|
||||
this.modID = modID;
|
||||
this.uniqueID = uniqueID;
|
||||
}
|
||||
|
||||
private static int ERR_DOES_NOT_EXIST = -10;
|
||||
|
@ -85,7 +69,7 @@ public class FileHash {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%08x", size)
|
||||
return super.toString()+": "+String.format("%08x", size)
|
||||
+ "-"
|
||||
+ String.format("%08x", value)
|
||||
+ "-"
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
package ru.bclib.api.dataexchange.handler;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import ru.bclib.api.dataexchange.DataHandler;
|
||||
import ru.bclib.api.dataexchange.FileHash;
|
||||
import ru.bclib.util.Pair;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
class AutoFileSyncEntry extends DataExchange.AutoSyncID {
|
||||
public final DataExchange.NeedTransferPredicate needTransfer;
|
||||
public final File fileName;
|
||||
public final boolean requestContent;
|
||||
private FileHash hash;
|
||||
|
||||
AutoFileSyncEntry(String modID, File fileName, boolean requestContent, DataExchange.NeedTransferPredicate needTransfer) {
|
||||
this(modID, fileName.getName(), fileName, requestContent, needTransfer);
|
||||
}
|
||||
|
||||
AutoFileSyncEntry(String modID, String uniqueID, File fileName, boolean requestContent, DataExchange.NeedTransferPredicate needTransfer) {
|
||||
super(modID, uniqueID);
|
||||
this.needTransfer = needTransfer;
|
||||
this.fileName = fileName;
|
||||
this.requestContent = requestContent;
|
||||
}
|
||||
|
||||
public FileHash getFileHash() {
|
||||
if (hash == null)
|
||||
{
|
||||
hash = FileHash.create(modID, fileName, uniqueID);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
if (!fileName.exists()) return new byte[0];
|
||||
final Path path = fileName.toPath();
|
||||
|
||||
try {
|
||||
return Files.readAllBytes(path);
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public int serializeContent(FriendlyByteBuf buf) {
|
||||
DataHandler.writeString(buf, modID);
|
||||
DataHandler.writeString(buf, uniqueID);
|
||||
return serializeFileContent(buf);
|
||||
}
|
||||
|
||||
public static Pair<AutoFileSyncEntry, byte[]> deserializeContent(FriendlyByteBuf buf) {
|
||||
final String modID = DataHandler.readString(buf);
|
||||
final String uniqueID = DataHandler.readString(buf);
|
||||
byte[] data = deserializeFileContent(buf);
|
||||
|
||||
AutoFileSyncEntry entry = AutoFileSyncEntry.findMatching(modID, uniqueID);
|
||||
return new Pair<>(entry, data);
|
||||
}
|
||||
|
||||
|
||||
public void serialize(FriendlyByteBuf buf) {
|
||||
getFileHash().serialize(buf);
|
||||
buf.writeBoolean(requestContent);
|
||||
|
||||
if (requestContent) {
|
||||
serializeFileContent(buf);
|
||||
}
|
||||
}
|
||||
|
||||
public static DataExchange.AutoSyncTriple deserializeAndMatch(FriendlyByteBuf buf) {
|
||||
Pair<FileHash, byte[]> e = deserialize(buf);
|
||||
AutoFileSyncEntry match = findMatching(e.first);
|
||||
return new DataExchange.AutoSyncTriple(e.first, e.second, match);
|
||||
}
|
||||
|
||||
public static Pair<FileHash, byte[]> deserialize(FriendlyByteBuf buf) {
|
||||
FileHash hash = FileHash.deserialize(buf);
|
||||
boolean withContent = buf.readBoolean();
|
||||
byte[] data = null;
|
||||
if (withContent) {
|
||||
data = deserializeFileContent(buf);
|
||||
}
|
||||
|
||||
return new Pair(hash, data);
|
||||
}
|
||||
|
||||
private int serializeFileContent(FriendlyByteBuf buf) {
|
||||
byte[] content = getContent();
|
||||
buf.writeInt(content.length);
|
||||
buf.writeByteArray(content);
|
||||
return content.length;
|
||||
}
|
||||
|
||||
private static byte[] deserializeFileContent(FriendlyByteBuf buf) {
|
||||
byte[] data;
|
||||
int size = buf.readInt();
|
||||
data = buf.readByteArray(size);
|
||||
return data;
|
||||
}
|
||||
|
||||
public static AutoFileSyncEntry findMatching(FileHash hash) {
|
||||
return findMatching(hash.modID, hash.uniqueID);
|
||||
}
|
||||
|
||||
public static AutoFileSyncEntry findMatching(DataExchange.AutoSyncID aid) {
|
||||
return findMatching(aid.modID, aid.uniqueID);
|
||||
}
|
||||
|
||||
public static AutoFileSyncEntry findMatching(String modID, String uniqueID) {
|
||||
return DataExchange
|
||||
.getInstance()
|
||||
.autoSyncFiles
|
||||
.stream()
|
||||
.filter(asf -> asf.modID.equals(modID) && asf.uniqueID.equals(uniqueID))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import net.fabricmc.api.Environment;
|
|||
import net.fabricmc.fabric.api.client.networking.v1.ClientLoginConnectionEvents;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.bclib.api.dataexchange.ConnectorClientside;
|
||||
import ru.bclib.api.dataexchange.ConnectorServerside;
|
||||
import ru.bclib.api.dataexchange.DataExchangeAPI;
|
||||
|
@ -16,17 +16,11 @@ 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.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
abstract public class DataExchange {
|
||||
@FunctionalInterface
|
||||
|
@ -34,21 +28,50 @@ abstract public class DataExchange {
|
|||
public boolean test(FileHash clientHash, FileHash serverHash, byte[] content);
|
||||
}
|
||||
|
||||
final static class AutoSyncID extends Pair<String, String>{
|
||||
public static class AutoSyncID {
|
||||
/**
|
||||
* A Unique ID for the referenced File.
|
||||
* <p>
|
||||
* Files with the same {@link #modID} need to have a unique IDs. Normally the filename from {@link #FileHash(String, File, byte[], int, int)}
|
||||
* is used to generated that ID, but you can directly specify one using {@link #FileHash(String, String, byte[], int, int)}.
|
||||
*/
|
||||
@NotNull
|
||||
public final String uniqueID;
|
||||
|
||||
/**
|
||||
* The ID of the Mod that is registering the File
|
||||
*/
|
||||
@NotNull
|
||||
public final String modID;
|
||||
|
||||
public AutoSyncID(String modID, String uniqueID) {
|
||||
super(modID, uniqueID);
|
||||
Objects.nonNull(modID);
|
||||
Objects.nonNull(uniqueID);
|
||||
|
||||
this.modID = modID;
|
||||
this.uniqueID = uniqueID;
|
||||
}
|
||||
|
||||
public String getModID() { return this.first; }
|
||||
public String getUniqueID() { return this.second; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return first+"."+second;
|
||||
return modID+"."+uniqueID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AutoSyncID that = (AutoSyncID) o;
|
||||
return uniqueID.equals(that.uniqueID) && modID.equals(that.modID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(uniqueID, modID);
|
||||
}
|
||||
}
|
||||
|
||||
final static class AutoSyncTriple extends Triple<FileHash, byte[], DataExchange.AutoFileSyncEntry>{
|
||||
final static class AutoSyncTriple extends Triple<FileHash, byte[], AutoFileSyncEntry>{
|
||||
public AutoSyncTriple(FileHash first, byte[] second, AutoFileSyncEntry third) {
|
||||
super(first, second, third);
|
||||
}
|
||||
|
@ -58,117 +81,6 @@ abstract public class DataExchange {
|
|||
return first.modID+"."+first.uniqueID;
|
||||
}
|
||||
}
|
||||
static class AutoFileSyncEntry {
|
||||
public final NeedTransferPredicate needTransfer;
|
||||
public final File fileName;
|
||||
public final String modID;
|
||||
public final String uniqueID;
|
||||
public final boolean requestContent;
|
||||
private FileHash hash;
|
||||
|
||||
AutoFileSyncEntry(String modID, File fileName, boolean requestContent, NeedTransferPredicate needTransfer) {
|
||||
this(modID, fileName.getName(), fileName, requestContent, needTransfer);
|
||||
}
|
||||
|
||||
AutoFileSyncEntry(String modID, String uniqueID, File fileName, boolean requestContent, NeedTransferPredicate needTransfer) {
|
||||
this.needTransfer = needTransfer;
|
||||
this.fileName = fileName;
|
||||
this.modID = modID;
|
||||
this.uniqueID = uniqueID;
|
||||
this.requestContent = requestContent;
|
||||
}
|
||||
|
||||
public FileHash getFileHash(){
|
||||
if (hash == null) {
|
||||
hash = FileHash.create(modID, fileName, uniqueID);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
public byte[] getContent(){
|
||||
if (!fileName.exists()) return new byte[0];
|
||||
final Path path = fileName.toPath();
|
||||
|
||||
try {
|
||||
return Files.readAllBytes(path);
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public int serializeContent(FriendlyByteBuf buf){
|
||||
DataHandler.writeString(buf, modID);
|
||||
DataHandler.writeString(buf, uniqueID);
|
||||
return serializeFileContent(buf);
|
||||
}
|
||||
public static Pair<AutoFileSyncEntry, byte[]> deserializeContent(FriendlyByteBuf buf){
|
||||
final String modID = DataHandler.readString(buf);
|
||||
final String uniqueID = DataHandler.readString(buf);
|
||||
byte[] data = deserializeFileContent(buf);
|
||||
|
||||
AutoFileSyncEntry entry = AutoFileSyncEntry.findMatching(modID, uniqueID);
|
||||
return new Pair<>(entry, data);
|
||||
}
|
||||
|
||||
|
||||
public void serialize(FriendlyByteBuf buf){
|
||||
getFileHash().serialize(buf);
|
||||
buf.writeBoolean(requestContent);
|
||||
|
||||
if (requestContent) {
|
||||
serializeFileContent(buf);
|
||||
}
|
||||
}
|
||||
|
||||
public static AutoSyncTriple deserializeAndMatch(FriendlyByteBuf buf){
|
||||
Pair<FileHash, byte[]> e = deserialize(buf);
|
||||
AutoFileSyncEntry match = findMatching(e.first);
|
||||
return new AutoSyncTriple(e.first, e.second, match);
|
||||
}
|
||||
|
||||
public static Pair<FileHash, byte[]> deserialize(FriendlyByteBuf buf){
|
||||
FileHash hash = FileHash.deserialize(buf);
|
||||
boolean withContent = buf.readBoolean();
|
||||
byte[] data = null;
|
||||
if (withContent) {
|
||||
data = deserializeFileContent(buf);
|
||||
}
|
||||
|
||||
return new Pair(hash, data);
|
||||
}
|
||||
|
||||
private int serializeFileContent(FriendlyByteBuf buf) {
|
||||
byte[] content = getContent();
|
||||
buf.writeInt(content.length);
|
||||
buf.writeByteArray(content);
|
||||
return content.length;
|
||||
}
|
||||
|
||||
private static byte[] deserializeFileContent(FriendlyByteBuf buf) {
|
||||
byte[] data;
|
||||
int size = buf.readInt();
|
||||
data = buf.readByteArray(size);
|
||||
return data;
|
||||
}
|
||||
|
||||
public static AutoFileSyncEntry findMatching(FileHash hash){
|
||||
return findMatching(hash.modID, hash.uniqueID);
|
||||
}
|
||||
public static AutoFileSyncEntry findMatching(AutoSyncID aid){
|
||||
return findMatching(aid.getModID(), aid.getUniqueID());
|
||||
}
|
||||
|
||||
public static AutoFileSyncEntry findMatching(String modID, String uniqueID){
|
||||
return DataExchange
|
||||
.getInstance()
|
||||
.autoSyncFiles
|
||||
.stream()
|
||||
.filter(asf -> asf.modID.equals(modID) && asf.uniqueID.equals(uniqueID))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static DataExchangeAPI instance;
|
||||
protected static DataExchangeAPI getInstance(){
|
||||
|
|
|
@ -67,10 +67,10 @@ public class HelloClient extends DataHandler {
|
|||
}
|
||||
|
||||
//send config Data
|
||||
final List<DataExchange.AutoFileSyncEntry> autoSyncFiles = DataExchange.getInstance().autoSyncFiles;
|
||||
final List<AutoFileSyncEntry> autoSyncFiles = DataExchange.getInstance().autoSyncFiles;
|
||||
buf.writeInt(autoSyncFiles.size());
|
||||
for (DataExchange.AutoFileSyncEntry entry : autoSyncFiles) {
|
||||
System.out.println("Serializing " + entry.getFileHash());
|
||||
for (AutoFileSyncEntry entry : autoSyncFiles) {
|
||||
//System.out.println("Serializing " + entry.getFileHash());
|
||||
entry.serialize(buf);
|
||||
}
|
||||
}
|
||||
|
@ -96,10 +96,10 @@ public class HelloClient extends DataHandler {
|
|||
count = buf.readInt();
|
||||
autoSyncedFiles = new ArrayList<>(count);
|
||||
for (int i=0; i< count; i++) {
|
||||
System.out.println("Deserializing ");
|
||||
DataExchange.AutoSyncTriple t = DataExchange.AutoFileSyncEntry.deserializeAndMatch(buf);
|
||||
//System.out.println("Deserializing ");
|
||||
DataExchange.AutoSyncTriple t = AutoFileSyncEntry.deserializeAndMatch(buf);
|
||||
autoSyncedFiles.add(t);
|
||||
System.out.println(t.first);
|
||||
//System.out.println(t.first);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ public class RequestFiles extends DataHandler {
|
|||
buf.writeInt(files.size());
|
||||
|
||||
for (AutoSyncID a : files){
|
||||
writeString(buf, a.getModID());
|
||||
writeString(buf, a.getUniqueID());
|
||||
writeString(buf, a.modID);
|
||||
writeString(buf, a.uniqueID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,16 +63,14 @@ public class RequestFiles extends DataHandler {
|
|||
|
||||
@Override
|
||||
protected void runOnGameThread(Minecraft client, MinecraftServer server, boolean isClient) {
|
||||
List<DataExchange.AutoFileSyncEntry> syncEntries = files
|
||||
.stream().map(asid -> DataExchange.AutoFileSyncEntry.findMatching(asid))
|
||||
List<AutoFileSyncEntry> syncEntries = files
|
||||
.stream().map(asid -> AutoFileSyncEntry.findMatching(asid))
|
||||
.filter(e -> e!=null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
reply(new SendFiles(syncEntries, receivedToken), server);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void newToken(){
|
||||
currentToken = UUID.randomUUID().toString();
|
||||
}
|
||||
|
|
|
@ -12,28 +12,24 @@ 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;
|
||||
protected List<AutoFileSyncEntry> files;
|
||||
private String token = "";
|
||||
public SendFiles(){
|
||||
this(null, "");
|
||||
}
|
||||
public SendFiles(List<DataExchange.AutoFileSyncEntry> files, String token) {
|
||||
public SendFiles(List<AutoFileSyncEntry> files, String token) {
|
||||
super(DESCRIPTOR.IDENTIFIER, true);
|
||||
this.files = files;
|
||||
this.token = token;
|
||||
|
@ -41,18 +37,18 @@ public class SendFiles extends DataHandler {
|
|||
|
||||
@Override
|
||||
protected void serializeData(FriendlyByteBuf buf) {
|
||||
List<DataExchange.AutoFileSyncEntry> existingFiles = files.stream().filter(e -> e.fileName.exists()).collect(Collectors.toList());
|
||||
List<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) {
|
||||
for (AutoFileSyncEntry entry : existingFiles) {
|
||||
int length = entry.serializeContent(buf);
|
||||
BCLib.LOGGER.info(" - " + entry + " (" + length + " Bytes)");
|
||||
}
|
||||
}
|
||||
|
||||
private List<Pair<DataExchange.AutoFileSyncEntry, byte[]>> receivedFiles;
|
||||
private List<Pair<AutoFileSyncEntry, byte[]>> receivedFiles;
|
||||
@Override
|
||||
protected void deserializeFromIncomingData(FriendlyByteBuf buf, PacketSender responseSender, boolean fromClient) {
|
||||
token = readString(buf);
|
||||
|
@ -66,7 +62,7 @@ public class SendFiles extends DataHandler {
|
|||
receivedFiles = new ArrayList<>(size);
|
||||
BCLib.LOGGER.info("Server sent " + size + " Files:");
|
||||
for (int i=0; i<size; i++){
|
||||
Pair<DataExchange.AutoFileSyncEntry, byte[]> p = DataExchange.AutoFileSyncEntry.deserializeContent(buf);
|
||||
Pair<AutoFileSyncEntry, byte[]> p = AutoFileSyncEntry.deserializeContent(buf);
|
||||
if (p.first != null) {
|
||||
receivedFiles.add(p);
|
||||
BCLib.LOGGER.info(" - " + p.first + " (" + p.second.length + " Bytes)");
|
||||
|
@ -79,8 +75,8 @@ 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;
|
||||
for (Pair<AutoFileSyncEntry, byte[]> entry : receivedFiles) {
|
||||
final AutoFileSyncEntry e = entry.first;
|
||||
final byte[] data = entry.second;
|
||||
Path path = e.fileName.toPath();
|
||||
BCLib.LOGGER.info(" - Writing " + path + " (" + data.length + " Bytes)");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue