diff --git a/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java b/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java index f23e7fc..78a6be9 100644 --- a/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java +++ b/SpigotCore_14/src/de/steamwar/core/WorldEditWrapper14.java @@ -115,6 +115,11 @@ public class WorldEditWrapper14 implements WorldEditWrapper.IWorldEditWrapper { } } + @Override + public File getWorldEditSchematicFolder() { + return WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getWorkingDirectoryFile(WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getConfiguration().saveDir); + } + private static class MCEditSchematicReader extends NBTSchematicReader { private final NBTInputStream inputStream; diff --git a/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java b/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java index 2b1cb0e..d08383f 100644 --- a/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java +++ b/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java @@ -88,6 +88,11 @@ public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper { return new SchematicReader(new NBTInputStream(is)).read(WorldEdit.getInstance().getServer().getWorlds().get(0).getWorldData()); } + @Override + public File getWorldEditSchematicFolder() { + return WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getWorkingDirectoryFile(WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getConfiguration().saveDir); + } + private static class SpongeSchematicReader implements ClipboardReader { private final NBTInputStream inputStream; diff --git a/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java b/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java index 0b860ee..8cb80e4 100644 --- a/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java +++ b/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java @@ -5,6 +5,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard; import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -17,7 +18,7 @@ public class WorldEditWrapper { InputStream getPlayerClipboard(Player player, boolean schemFormat); void setPlayerClipboard(Player player, InputStream is, boolean schemFormat); Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException; - + File getWorldEditSchematicFolder(); } static WorldEditPlugin getWorldEditPlugin() { diff --git a/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java b/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java index 8e334ae..4b6cde9 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java +++ b/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java @@ -19,17 +19,25 @@ package de.steamwar.sql; +import com.google.common.collect.Maps; +import de.steamwar.core.WorldEditWrapper; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.sql.Timestamp; import java.time.Instant; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; +import java.util.stream.Stream; public class StandaloneProvider implements Provider { @Override @@ -192,90 +200,166 @@ public class StandaloneProvider implements Provider { configs.computeIfAbsent(id, player -> new HashMap<>()).remove(config); } + private int nodeId = 1; + private final File schematicDir = WorldEditWrapper.impl.getWorldEditSchematicFolder(); + private final Map nodeById = new HashMap<>(); + private final Map> nodesByParent = new HashMap<>(); + private final Map nodesToPath = new HashMap<>(); + + { + nodesToPath.put(-1, schematicDir.toPath()); + } + + private List mapDir(Integer id) { + try (Stream stream = Files.list(id==null?schematicDir.toPath():nodesToPath.get(id))) { + List list = stream.map(path -> { + File file = path.toFile(); + SchematicNode node = new SchematicNode( + nodeId++, + 0, + file.getName().substring(file.getName().lastIndexOf(".")), + null, + "", + "normal", + file.isDirectory(), + 0, + Timestamp.from(Instant.now()), + file.getName().endsWith(".schem") + ); + nodesToPath.put(node.getId(), path); + nodeById.put(node.getId(), node); + return node; + }).collect(Collectors.toList()); + nodesByParent.putIfAbsent(id == null?-1:id, list); + return list; + } catch (IOException e) { + throw new SecurityException(e); + } + } + @Override - public void createSchematicNode(int owner, String name, Integer parent, String type, String item) {} + public void createSchematicNode(int owner, String name, Integer parent, String type, String item) { + + } @Override public SchematicNode getSchematicNode(int owner, String name, Integer parent) { - return null; + return nodesByParent.get(parent).stream().filter(node -> node.getName().equals(name)).findAny().orElse(null); } @Override public List getSchematicNodeInNode(Integer parent) { - return Collections.emptyList(); + return nodesByParent.computeIfAbsent(parent==null?-1:parent, integer -> mapDir(parent)); } @Override public List getSchematicDirectoryInNode(Integer parent) { - return Collections.emptyList(); + return getSchematicNodeInNode(parent).stream().filter(SchematicNode::isDir).collect(Collectors.toList()); } @Override public SchematicNode getSchematicDirectory(String name, Integer parent) { - return null; + return getSchematicDirectoryInNode(parent).stream().filter(node -> node.getName().equals(name)).findFirst().orElse(null); } @Override public SchematicNode getSchematicNode(String name, Integer parent) { - return null; + return getSchematicNodeInNode(parent).stream().filter(node -> name.equals(node.getName())).findFirst().orElse(null); } @Override public SchematicNode getSchematicNode(int id) { - return null; + return nodeById.getOrDefault(id, null); } @Override - public List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) { - return Collections.emptyList(); + public List getAccessibleSchematicsOfTypeInParent(int ignored, String schemType, Integer parent) { + return getSchematicDirectoryInNode(parent).stream().filter(node -> node.getType().equals(schemType)).collect(Collectors.toList()); } @Override - public List getAllAccessibleSchematicsOfType(int user, String schemType) { - return Collections.emptyList(); + public List getAllAccessibleSchematicsOfType(int ignored, String schemType) { + return getAllSchematicsAccessibleByUser(ignored).stream().filter(node -> schemType.equals(node.getType())).collect(Collectors.toList()); } @Override - public List getAllSchematicsOfType(int owner, String schemType) { - return Collections.emptyList(); + public List getAllSchematicsOfType(int ignored, String schemType) { + return getAllAccessibleSchematicsOfType(ignored, schemType); } @Override public List getAllSchematicsOfType(String schemType) { - return Collections.emptyList(); + return getAllAccessibleSchematicsOfType(-1, schemType); } @Override - public List getSchematicsAccessibleByUser(int user, Integer parent) { - return Collections.emptyList(); + public List getSchematicsAccessibleByUser(int ignored, Integer parent) { + return getSchematicNodeInNode(parent); } @Override public List getAllSchematicsAccessibleByUser(int user) { - return Collections.emptyList(); + return nodesByParent.values().stream().reduce((schematicNodes, schematicNodes2) -> { + schematicNodes.addAll(schematicNodes2); + return schematicNodes; + }).orElse(new ArrayList<>()); } @Override public List getAllParentsOfNode(int node) { - return Collections.emptyList(); + List allSchematicsAccessibleByUser = getAllSchematicsAccessibleByUser(node); + allSchematicsAccessibleByUser.remove(getSchematicNode(node)); + return allSchematicsAccessibleByUser; } @Override public Integer countNodes() { - return 0; + return nodesByParent.values().stream().map(List::size).reduce((Integer::sum)).orElse(0); } @Override - public void updateSchematicNode(SchematicNode node) {} + public void updateSchematicNode(SchematicNode node) { + try { + Path newPath = new File(nodesToPath.get(node.getParent() == null?-1:node.getParent()).toFile(), node.getName() + (node.getSchemFormat()?".schem":".schematic")).toPath(); + Files.move(nodesToPath.get(node.getId()), newPath); + nodesToPath.put(node.getId(), newPath); + } catch (IOException e) { + throw new SecurityException(e); + } + } @Override - public void deleteSchematicNode(SchematicNode node) {} + public void deleteSchematicNode(SchematicNode node) { + try { + Files.deleteIfExists(nodesToPath.get(node.getId())); + nodeById.remove(node.getId()); + nodesByParent.get(node.getParent() == null?-1:node.getId()).remove(node); + nodesToPath.remove(node.getId()); + } catch (IOException e) { + throw new SecurityException(e); + } + } @Override public InputStream getSchematicData(SchematicNode node) throws IOException { - return null; + return Files.newInputStream(nodesToPath.get(node.getId())); } @Override - public void saveSchematicNode(SchematicNode node, InputStream blob, boolean newFormat) {} + public void saveSchematicNode(SchematicNode node, InputStream blob, boolean newFormat) { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] bucket = new byte[1024]; + int nReadBytes; + + while((nReadBytes = blob.read(bucket, 0, bucket.length)) !=-1){ + byteArrayOutputStream.write(bucket, 0, nReadBytes); + } + + byte[] bytes = byteArrayOutputStream.toByteArray(); + Files.write(nodesToPath.get(node.getId()), bytes, StandardOpenOption.TRUNCATE_EXISTING); + } catch (IOException e) { + throw new SecurityException(e); + } + } }