Use ProgressScreen for larger Data-Transfers
This commit is contained in:
parent
469e97b790
commit
3321d1c90e
5 changed files with 86 additions and 11 deletions
|
@ -55,6 +55,7 @@ public abstract class BaseDataHandler {
|
|||
@Environment(EnvType.CLIENT)
|
||||
abstract void sendToServer(Minecraft client);
|
||||
|
||||
protected boolean isBlocking() { return false; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
|
|
@ -56,7 +56,10 @@ public abstract class DataHandler extends BaseDataHandler {
|
|||
@Override
|
||||
void receiveFromServer(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender) {
|
||||
deserializeIncomingData(buf, responseSender, true);
|
||||
client.execute(() -> runOnGameThread(client, null, true));
|
||||
final Runnable runner = () -> runOnGameThread(client, null, true);
|
||||
|
||||
if (isBlocking()) client.executeBlocking(runner);
|
||||
else client.execute(runner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,7 +67,10 @@ public abstract class DataHandler extends BaseDataHandler {
|
|||
super.receiveFromClient(server, player, handler, buf, responseSender);
|
||||
|
||||
deserializeIncomingData(buf, responseSender, false);
|
||||
server.execute(() -> runOnGameThread(null, server, false));
|
||||
final Runnable runner = () -> runOnGameThread(null, server, false);
|
||||
|
||||
if (isBlocking()) server.executeBlocking(runner);
|
||||
else server.execute(runner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,7 +162,10 @@ public abstract class DataHandler extends BaseDataHandler {
|
|||
super.receiveFromClient(server, player, handler, buf, responseSender);
|
||||
|
||||
deserializeIncomingDataOnServer(buf, responseSender);
|
||||
server.execute(() -> runOnServerGameThread(server));
|
||||
final Runnable runner = () -> runOnServerGameThread(server);
|
||||
|
||||
if (isBlocking()) server.executeBlocking(runner);
|
||||
else server.execute(runner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -220,7 +229,10 @@ public abstract class DataHandler extends BaseDataHandler {
|
|||
@Override
|
||||
final void receiveFromServer(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender) {
|
||||
deserializeIncomingDataOnClient(buf, responseSender);
|
||||
client.execute(() -> runOnClientGameThread(client));
|
||||
final Runnable runner = () -> runOnClientGameThread(client);
|
||||
|
||||
if (isBlocking()) client.executeBlocking(runner);
|
||||
else client.execute(runner);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package ru.bclib.api.dataexchange.handler.autosync;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.ProgressListener;
|
||||
import ru.bclib.gui.screens.ProgressScreen;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
@ -23,8 +27,35 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Used to seperate large data transfers into multiple smaller messages.
|
||||
* <p>
|
||||
* {@link DataHandler} will automatically convert larger messages into Chunks on the Server
|
||||
* and assemble the original message from those chunks on the client.
|
||||
*/
|
||||
public class Chunker extends DataHandler.FromServer {
|
||||
public static class PacketChunkReceiver {
|
||||
private static ProgressScreen progressScreen;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static void setProgressScreen(ProgressScreen scr){
|
||||
progressScreen = scr;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static ProgressScreen getProgressScreen(){
|
||||
return progressScreen;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static ProgressListener getProgressListener(){
|
||||
return progressScreen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for assembling the original ByteBuffer created by {@link PacketChunkSender} on the
|
||||
* receiving end. Automatically created from the header {@link Chunker}-Message (where the serialNo==-1)
|
||||
*/
|
||||
static class PacketChunkReceiver {
|
||||
@NotNull
|
||||
public final UUID uuid;
|
||||
public final int chunkCount;
|
||||
|
@ -70,6 +101,10 @@ public class Chunker extends DataHandler.FromServer {
|
|||
}
|
||||
|
||||
public boolean testFinished(){
|
||||
ProgressListener listener = getProgressListener();
|
||||
if (listener!=null){
|
||||
listener.progressStagePercentage((100*receivedCount)/chunkCount);
|
||||
}
|
||||
if (incomingBuffer == null){
|
||||
return true;
|
||||
} if (lastReadSerial>=chunkCount-1){
|
||||
|
@ -79,7 +114,7 @@ public class Chunker extends DataHandler.FromServer {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void addBuffer(FriendlyByteBuf input){
|
||||
private void addBuffer(FriendlyByteBuf input){
|
||||
final int size = input.readableBytes();
|
||||
final int cap = networkedBuf.capacity()-networkedBuf.writerIndex();
|
||||
|
||||
|
@ -102,7 +137,10 @@ public class Chunker extends DataHandler.FromServer {
|
|||
|
||||
Map<Integer, FriendlyByteBuf> incomingBuffer = new HashMap<>();
|
||||
int lastReadSerial = -1;
|
||||
int receivedCount = 0;
|
||||
public void processReceived(FriendlyByteBuf buf, int serialNo, int size){
|
||||
receivedCount++;
|
||||
|
||||
if (lastReadSerial == serialNo-1){
|
||||
addBuffer(buf);
|
||||
lastReadSerial = serialNo;
|
||||
|
@ -130,6 +168,10 @@ public class Chunker extends DataHandler.FromServer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for splitting an outgoing ByteBuffer into several smaller Chunks and
|
||||
* send them as seperate messages to the {@link Chunker}-Channel
|
||||
*/
|
||||
public static class PacketChunkSender {
|
||||
private final FriendlyByteBuf networkedBuf;
|
||||
public final UUID uuid;
|
||||
|
@ -160,7 +202,9 @@ public class Chunker extends DataHandler.FromServer {
|
|||
}
|
||||
}
|
||||
|
||||
private static final int HEADER_SIZE = 1 + 16 + 4 + 4; //header = version + UUID + serialNo + size
|
||||
//header = version + UUID + serialNo + size, see serializeDataOnServer
|
||||
private static final int HEADER_SIZE = 1 + 16 + 4 + 4;
|
||||
|
||||
public static final int MAX_PACKET_SIZE = 1024*1024;
|
||||
private static final int MAX_PAYLOAD_SIZE = MAX_PACKET_SIZE - HEADER_SIZE;
|
||||
|
||||
|
@ -188,17 +232,20 @@ public class Chunker extends DataHandler.FromServer {
|
|||
|
||||
@Override
|
||||
protected void serializeDataOnServer(FriendlyByteBuf buf) {
|
||||
//Sending Header. Make sure to change HEADER_SIZE if you change this!
|
||||
buf.writeByte(0);
|
||||
buf.writeLong(uuid.getMostSignificantBits());
|
||||
buf.writeLong(uuid.getLeastSignificantBits());
|
||||
buf.writeInt(serialNo);
|
||||
|
||||
//sending Payload
|
||||
if (serialNo == -1){
|
||||
//this is our header
|
||||
//this is our header-Chunk that transports status information
|
||||
buf.writeInt(chunkCount);
|
||||
writeString(buf, origin.getNamespace());
|
||||
writeString(buf, origin.getPath());
|
||||
} else {
|
||||
//this is an actual payload chunk
|
||||
buf.capacity(MAX_PACKET_SIZE);
|
||||
final int size = Math.min(MAX_PAYLOAD_SIZE, networkedBuf.readableBytes());
|
||||
buf.writeInt(size);
|
||||
|
|
|
@ -6,6 +6,7 @@ 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.network.chat.TranslatableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import ru.bclib.BCLib;
|
||||
import ru.bclib.api.dataexchange.DataExchangeAPI;
|
||||
|
@ -14,6 +15,7 @@ import ru.bclib.api.dataexchange.DataHandlerDescriptor;
|
|||
import ru.bclib.api.dataexchange.handler.autosync.AutoSyncID.WithContentOverride;
|
||||
import ru.bclib.api.dataexchange.handler.autosync.SyncFolderDescriptor.SubFile;
|
||||
import ru.bclib.config.Configs;
|
||||
import ru.bclib.gui.screens.ProgressScreen;
|
||||
import ru.bclib.gui.screens.SyncFilesScreen;
|
||||
import ru.bclib.gui.screens.WarnBCLibVersionMismatch;
|
||||
import ru.bclib.util.ModUtil;
|
||||
|
@ -300,6 +302,10 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isBlocking() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Override
|
||||
|
@ -371,8 +377,6 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
}
|
||||
|
||||
client.setScreen(new SyncFilesScreen(modFiles, configFiles, singleFiles, folderFiles, filesToRemove.size(), (downloadMods, downloadConfigs, downloadFiles, removeFiles) -> {
|
||||
Minecraft.getInstance()
|
||||
.setScreen((Screen) null);
|
||||
if (downloadMods || downloadConfigs || downloadFiles) {
|
||||
BCLib.LOGGER.info("Updating local Files:");
|
||||
List<AutoSyncID.WithContentOverride> localChanges = new ArrayList<>(files.toArray().length);
|
||||
|
@ -398,6 +402,9 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
aid.relFile.delete();
|
||||
});
|
||||
}
|
||||
|
||||
Minecraft.getInstance()
|
||||
.setScreen(Chunker.getProgressScreen());
|
||||
}));
|
||||
|
||||
}
|
||||
|
@ -422,6 +429,11 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
|
||||
private void requestFileDownloads(List<AutoSyncID> files) {
|
||||
BCLib.LOGGER.info("Starting download of Files:" + files.size());
|
||||
|
||||
final ProgressScreen progress = new ProgressScreen(null, new TranslatableComponent("title.bclib.filesync.progress"), new TranslatableComponent("message.bclib.filesync.progress"));
|
||||
progress.progressStart(new TranslatableComponent("message.bclib.filesync.progress.stage.empty"));
|
||||
Chunker.setProgressScreen(progress);
|
||||
|
||||
DataExchangeAPI.send(new RequestFiles(files));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,7 +179,10 @@ public class SendFiles extends DataHandler.FromServer {
|
|||
if (!parentFile.exists()) {
|
||||
parentFile.mkdirs();
|
||||
}
|
||||
Files.write(path, data);
|
||||
//TODO: Disabled for testing. MUST BE ENABLED IN PRODUCTION!!!
|
||||
if (!BCLib.isDevEnvironment()) {
|
||||
Files.write(path, data);
|
||||
}
|
||||
if (removeAfter != null){
|
||||
final String bakFileName = removeAfter.toFile().getName();
|
||||
String collisionFreeName = bakFileName;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue