diff --git a/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java b/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java index 0b860ee..7cfba3b 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,10 +18,9 @@ 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; - } - static WorldEditPlugin getWorldEditPlugin() { + public static WorldEditPlugin getWorldEditPlugin() { return (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"); } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java b/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java index f83bfdd..c9c6259 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java +++ b/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java @@ -19,23 +19,29 @@ 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.IOException; -import java.io.InputStream; import java.io.*; 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; +import java.util.zip.GZIPInputStream; public class StandaloneProvider implements Provider { + public StandaloneProvider() { + nodesToPath.put(-1, schematicDir.toPath()); + } + @Override public BauweltMember getBauMember(int ownerID, int memberID) { OfflinePlayer player = Bukkit.getOfflinePlayer(SteamwarUser.get(memberID).getUUID()); @@ -196,90 +202,190 @@ public class StandaloneProvider implements Provider { configs.computeIfAbsent(id, player -> new HashMap<>()).remove(config); } + private int nodeId = 1; + private final File schematicDir = WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getWorkingDirectoryFile(WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getConfiguration().saveDir); + private final Map nodeById = new HashMap<>(); + private final Map> nodesByParent = new HashMap<>(); + private final Map nodesToPath = new HashMap<>(); + + 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.isDirectory()?file.getName():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) { + boolean isDir = type == null; + Path p = null; + try { + if(isDir) { + p = Files.createDirectory(new File(nodesToPath.get(parent == null?-1:parent).toFile(), name).toPath()); + } else { + p = Files.createFile(new File(nodesToPath.get(parent == null?-1:parent).toFile(), name + ".schem").toPath()); + } + } catch (IOException e) { + throw new SecurityException(e); + } + + File file = p.toFile(); + int id = nodeId++; + nodesToPath.put(id, p); + SchematicNode node = new SchematicNode( + nodeId++, + 0, + file.isDirectory()?file.getName():file.getName().substring(file.getName().lastIndexOf(".")), + null, + "", + "normal", + file.isDirectory(), + 0, + Timestamp.from(Instant.now()), + file.getName().endsWith(".schem") + ); + nodeById.put(id, node); + nodesByParent.get(parent == null?-1:parent).add(node); + } @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 new GZIPInputStream(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 (FileOutputStream stream = new FileOutputStream(nodesToPath.get(node.getId()).toFile())) { + byte[] bucket = new byte[1024]; + int nReadBytes; + + while((nReadBytes = blob.read(bucket, 0, bucket.length)) !=-1){ + stream.write(bucket, 0, nReadBytes); + } + + if(newFormat != node.getSchemFormat()) { + nodesToPath.get(node.getId()).toFile().renameTo(new File(nodesToPath.get(node.getId()).toFile().getParentFile(), node.getName() + "." + (newFormat?".schem":"schematic"))); + } + } catch (IOException e) { + throw new SecurityException(e); + } + } }