From de6d8bbb1008ae9ba31b470e4ab02d30cc0bbfc0 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Wed, 3 Nov 2021 16:28:01 +0100 Subject: [PATCH] Implement Streaming Signed-off-by: Chaoscaot --- .../de/steamwar/core/WorldEditWrapper14.java | 44 ++++++++++++------- .../de/steamwar/core/WorldEditWrapper8.java | 30 +++++++++---- .../de/steamwar/core/WorldEditWrapper.java | 2 +- .../src/de/steamwar/sql/SchematicNode.java | 19 ++------ 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java b/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java index 96b135b..f23e7fc 100644 --- a/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java +++ b/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java @@ -29,10 +29,9 @@ import com.sk89q.worldedit.world.registry.LegacyMapper; import de.steamwar.sql.NoClipboardException; import org.bukkit.entity.Player; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.util.*; +import java.util.logging.Level; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; @@ -43,7 +42,7 @@ public class WorldEditWrapper14 implements WorldEditWrapper.IWorldEditWrapper { private static final ClipboardFormat SCHEM = BuiltInClipboardFormat.SPONGE_SCHEMATIC; @Override - public byte[] getPlayerClipboard(Player player, boolean schemFormat) { + public InputStream getPlayerClipboard(Player player, boolean schemFormat) { ClipboardHolder clipboardHolder; try { clipboardHolder = WorldEditWrapper.getWorldEditPlugin().getSession(player).getClipboard(); @@ -55,21 +54,36 @@ public class WorldEditWrapper14 implements WorldEditWrapper.IWorldEditWrapper { if(clipboard == null) throw new NoClipboardException(); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - try{ - if(schemFormat){ - ClipboardWriter writer = SCHEM.getWriter(outputStream); - writer.write(clipboard); - writer.close(); - }else{ - SCHEMATIC.getWriter(outputStream).write(clipboard); - } + PipedOutputStream outputStream = new PipedOutputStream(); + PipedInputStream inputStream; + try { + inputStream = new PipedInputStream(outputStream, 4096); }catch(NullPointerException e){ throw new RuntimeException(e.getMessage(), new IOException(e)); } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + throw new SecurityException("Could not init piped input stream", e); } - return outputStream.toByteArray(); + + new Thread(() -> { + try{ + if(schemFormat){ + ClipboardWriter writer = SCHEM.getWriter(outputStream); + writer.write(clipboard); + writer.close(); + }else{ + SCHEMATIC.getWriter(outputStream).write(clipboard); + } + }catch(NullPointerException | IOException e) { + Core.getInstance().getLogger().log(Level.SEVERE, "Could not write schematic", e); + } + try { + outputStream.close(); + } catch (IOException e) { + Core.getInstance().getLogger().log(Level.SEVERE, "Could not close schem writer", e); + } + }, "SchemWriter").start(); + + return inputStream; } @Override diff --git a/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java b/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java index 3e243bd..2b1cb0e 100644 --- a/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java +++ b/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java @@ -19,19 +19,18 @@ import com.sk89q.worldedit.world.registry.WorldData; import de.steamwar.sql.NoClipboardException; import org.bukkit.entity.Player; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.logging.Level; import java.util.stream.Collectors; public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper { @Override - public byte[] getPlayerClipboard(Player player, boolean schemFormat) { + public InputStream getPlayerClipboard(Player player, boolean schemFormat) { ClipboardHolder clipboardHolder; try { clipboardHolder = WorldEditWrapper.getWorldEditPlugin().getSession(player).getClipboard(); @@ -43,13 +42,28 @@ public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper { if(clipboard == null) throw new NoClipboardException(); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PipedOutputStream outputStream = new PipedOutputStream(); + PipedInputStream inputStream; try { - ClipboardFormat.SCHEMATIC.getWriter(outputStream).write(clipboard, clipboardHolder.getWorldData()); + inputStream = new PipedInputStream(outputStream, 4096); } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + throw new SecurityException("Could not init piped input stream", e); } - return outputStream.toByteArray(); + + new Thread(() -> { + try { + ClipboardFormat.SCHEMATIC.getWriter(outputStream).write(clipboard, clipboardHolder.getWorldData()); + } catch (IOException e) { + Core.getInstance().getLogger().log(Level.SEVERE, "Could not write schematic", e); + } + try { + outputStream.close(); + } catch (IOException e) { + Core.getInstance().getLogger().log(Level.SEVERE, "Could not close schem writer", e); + } + }, "SchemWriter").start(); + + return inputStream; } @Override diff --git a/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java b/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java index 920bc9f..0b860ee 100644 --- a/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java +++ b/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java @@ -14,7 +14,7 @@ public class WorldEditWrapper { public static final IWorldEditWrapper impl = VersionDependent.getVersionImpl(Core.getInstance()); public interface IWorldEditWrapper { - byte[] getPlayerClipboard(Player player, boolean schemFormat); + InputStream getPlayerClipboard(Player player, boolean schemFormat); void setPlayerClipboard(Player player, InputStream is, boolean schemFormat); Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException; diff --git a/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java b/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java index c32ae3e..f554f31 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java +++ b/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java @@ -25,6 +25,7 @@ import de.steamwar.core.VersionedRunnable; import de.steamwar.core.WorldEditWrapper; import org.bukkit.entity.Player; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Blob; @@ -476,28 +477,16 @@ public class SchematicNode { public void saveFromBytes(byte[] bytes, boolean newFormat) { if(isDir) throw new SecurityException("Node is Directory"); - Blob blob = SQL.blob(); - try { - blob.setBytes(1, bytes); - updateDatabase(blob, newFormat); - } catch (SQLException e) { - throw new SecurityException(e); - } + updateDatabase(new ByteArrayInputStream(bytes), newFormat); } private void saveFromPlayer(Player player, boolean newFormat) throws IOException, NoClipboardException { if(isDir) throw new SecurityException("Node is Directory"); - Blob blob = SQL.blob(); - try { - blob.setBytes(1, WorldEditWrapper.impl.getPlayerClipboard(player, newFormat)); - } catch (SQLException exception) { - throw new RuntimeException(exception.getMessage(), exception); - } - updateDatabase(blob, newFormat); + updateDatabase(WorldEditWrapper.impl.getPlayerClipboard(player, newFormat), newFormat); } - private void updateDatabase(Blob blob, boolean newFormat) { + private void updateDatabase(InputStream blob, boolean newFormat) { SQL.update("UPDATE SchematicNode SET NodeData = ?, NodeFormat = ? WHERE NodeId = ?", blob, newFormat, id); schemFormat = newFormat; }