From 866d57f8dc5558145595c19b7988a3a8730dce53 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Tue, 23 Nov 2021 19:27:03 +0100 Subject: [PATCH 1/3] WIP GDPR query processor Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/BungeeCore.java | 1 + .../bungeecore/commands/GDPRQuery.java | 239 ++++++++++++++++++ src/de/steamwar/bungeecore/sql/Statement.java | 8 +- 3 files changed, 244 insertions(+), 4 deletions(-) create mode 100644 src/de/steamwar/bungeecore/commands/GDPRQuery.java diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index 65fd3ce2..3ed7e127 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -128,6 +128,7 @@ public class BungeeCore extends Plugin { new ListCommand(); new StatCommand(); new VerifyCommand(); + new GDPRQuery(); // Punishment Commands: new PunishmentCommand("ban", Punishment.PunishmentType.Ban); diff --git a/src/de/steamwar/bungeecore/commands/GDPRQuery.java b/src/de/steamwar/bungeecore/commands/GDPRQuery.java new file mode 100644 index 00000000..ec693e5e --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/GDPRQuery.java @@ -0,0 +1,239 @@ +package de.steamwar.bungeecore.commands; + +import de.steamwar.bungeecore.sql.Statement; +import de.steamwar.bungeecore.sql.SteamwarUser; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.io.*; +import java.sql.SQLException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class GDPRQuery extends BasicCommand { + + public GDPRQuery() { + super("gdprquery", null); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(!(sender instanceof ProxiedPlayer)) + return; + ProxiedPlayer player = (ProxiedPlayer) sender; + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + + try { + createZip(user); + } catch (IOException e) { + throw new SecurityException("Could not create zip", e); + } + } + + private void createZip(SteamwarUser user) throws IOException { + ZipOutputStream out = new ZipOutputStream(new FileOutputStream("test.zip")); //TODO + + //TODO: Bauweltenurheberrecht + //TODO: Erklärung Art, Umfang (& Dauer?) + + copyBauwelt(user, out, "/home/minecraft/userworlds/" + user.getUuid().toString(), "BuildWorld12"); + copyBauwelt(user, out, "/home/minecraft/userworlds15/" + user.getId(), "BuildWorld15"); + copyPlayerdata(user, out, "/home/minecraft/userworlds", "BuildInventories12"); + copyPlayerdata(user, out, "/home/minecraft/userworlds15", "BuildInventories15"); + //TODO: Simulatoren von allen Bauwelten + + sqlCSV(user, out, bannedIPs, "BannedIPs.csv"); + sqlCSV(user, out, bauweltMember, "BuildMember.csv"); + sqlCSV(user, out, bauweltMembers, "BuildMembers.csv"); + sqlCSV(user, out, checkedSchems, "SchematicChecksessions.csv"); + sqlCSV(user, out, elo, "Elo.csv"); + sqlCSV(user, out, fights, "Fights.csv"); + sqlCSV(user, out, ignoredPlayers, "IgnoredPlayers.csv"); + sqlCSV(user, out, ignoringPlayers, "IgnoringPlayers.csv"); + sqlCSV(user, out, schematicMember, "SchematicMember.csv"); + sqlCSV(user, out, schematicMembers, "SchematicMembers.csv"); + sqlCSV(user, out, pollAnswers, "PollAnswers.csv"); + sqlCSV(user, out, punishments, "Punishments.csv"); + sqlCSV(user, out, sessions, "Sessions.csv"); + sqlCSV(user, out, userData, "UserData.csv"); + sqlCSV(user, out, personalKits, "PersonalKits.csv"); + sqlCSV(user, out, schematics, "Schematics.csv"); + + personalKits(user, out); + schematics(user, out); + userConfig(user, out); + + //TODO: Logs: Lobby & Bungeelogpos! + //TODO: Website + + out.close(); + } + + private static final Statement bannedIPs = new Statement("SELECT Timestamp, IP FROM BannedUserIPs WHERE UserID = ?"); + private static final Statement bauweltMember = new Statement("SELECT BauweltID AS Bauwelt, WorldEdit, World FROM BauweltMember WHERE MemberID = ?"); + private static final Statement bauweltMembers = new Statement("SELECT u.UserName AS 'User', m.WorldEdit AS WorldEdit, m.World AS World FROM BauweltMember m INNER JOIN UserData u ON m.MemberID = u.id WHERE m.BauweltID = ?"); + private static final Statement checkedSchems = new Statement("SELECT NodeName AS Schematic, StartTime, EndTime, DeclineReason AS Result FROM CheckedSchematic WHERE NodeOwner = ? ORDER BY StartTime ASC"); + private static final Statement elo = new Statement("SELECT GameMode, Elo FROM Elo WHERE UserID = ?"); + private static final Statement fights = new Statement("SELECT p.Team AS Team, p.Kit AS Kit, p.Kills AS Kills, p.IsOut AS Died, f.GameMode AS GameMode, f.Server AS Server, f.Arena AS Arena, f.StartTime AS StartTime, f.Duration AS Duration, (f.BlueLeader = p.UserID) AS IsBlueLeader, (f.RedLeader = p.UserID) AS IsRedLeader, f.Win AS Winner, f.WinCondition AS WinCondition FROM Fight f INNER JOIN FightPlayer p ON f.FightID = p.FightID WHERE p.UserID = ? ORDER BY StartTime ASC"); + private static final Statement ignoredPlayers = new Statement("SELECT u.UserName AS IgnoredPlayer FROM IgnoredPlayers i INNER JOIN UserData u ON i.Ignored = u.id WHERE Ignorer = ?"); + private static final Statement ignoringPlayers = new Statement("SELECT Ignorer AS IgnoringPlayers FROM IgnoredPlayers WHERE Ignored = ?"); + private static final Statement schematicMember = new Statement("SELECT s.NodeName AS SchematicName, u.UserName AS SchematicOwner FROM NodeMember m INNER JOIN SchematicNode s ON m.NodeId = s.NodeId INNER JOIN UserData u ON s.NodeOwner = u.id WHERE m.UserId = ?"); + private static final Statement schematicMembers = new Statement("SELECT s.NodeName AS SchematicName, u.UserName AS Member FROM NodeMember m INNER JOIN SchematicNode s ON m.NodeId = s.NodeId INNER JOIN UserData u ON m.UserId = u.id WHERE s.NodeOwner = ?"); + private static final Statement pollAnswers = new Statement("SELECT Question, Answer FROM PollAnswer WHERE UserID = ?"); + private static final Statement punishments = new Statement("SELECT Type, StartTime, EndTime, Perma, Reason FROM Punishments WHERE UserId = ?"); + private static final Statement sessions = new Statement("SELECT StartTime, EndTime FROM Session WHERE UserID = ?"); + private static final Statement userData = new Statement("SELECT * FROM UserData WHERE id = ?"); + private static final Statement personalKits = new Statement("SELECT GameMode, Name, InUse FROM PersonalKit WHERE UserID = ?"); + private static final Statement personalKitData = new Statement("SELECT GameMode, Name, Inventory, Armor FROM PersonalKit WHERE UserID = ?"); + private static final Statement schematics = new Statement("SELECT NodeName AS SchematicName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank FROM SchematicNode WHERE NodeOwner = ?"); + private static final Statement schematicData = new Statement("SELECT NodeName, ParentNode, NodeFormat, NodeData FROM SchematicNode WHERE NodeOwner = ?"); + private static final Statement userConfig = new Statement("SELECT * FROM UserConfig WHERE User = ?"); + + private void sqlCSV(SteamwarUser user, ZipOutputStream out, Statement statement, String path) throws IOException { + write(stream -> { + PrintWriter writer = new PrintWriter(stream); + statement.select(rs -> { + int columns = rs.getMetaData().getColumnCount(); + + for(int i = 1; i <= columns; i++) { + writer.write(rs.getMetaData().getColumnName(1)); + writer.write(";"); + } + writer.println(); + + while(rs.next()) { + for(int i = 1; i <= columns; i++) { + try { + writer.write(rs.getString(i)); + } catch (NullPointerException e) { + // ignored + } + writer.write(";"); + } + writer.println(); + } + return null; + }, user.getId()); + }, out, path); + } + + private void personalKits(SteamwarUser user, ZipOutputStream out) { + personalKitData.select(rs -> { + while(rs.next()) { + try { + write(stream -> { + try { + new PrintWriter(stream).print(rs.getString("Inventory")); + } catch (SQLException e) { + throw new SecurityException("Could not export PersonalKits", e); + } + }, out, "PersonalKit/" + rs.getString("GameMode") + "/" + rs.getString("Name") + ".Inventory.yml"); + write(stream -> { + try { + new PrintWriter(stream).print(rs.getString("Armor")); + } catch (SQLException e) { + throw new SecurityException("Could not export PersonalKits", e); + } + }, out, "PersonalKit/" + rs.getString("GameMode") + "/" + rs.getString("Name") + ".Armor.yml"); + } catch (IOException e) { + throw new SecurityException("Could not export PersonalKits", e); + } + } + return null; + }, user.getId()); + } + + private void schematics(SteamwarUser user, ZipOutputStream out) { + schematicData.select(rs -> { + while(rs.next()) { + String name = (rs.getString("ParentNode") != null ? rs.getString("ParentNode") : "") + ":" + rs.getString("NodeName"); + boolean format = rs.getBoolean("NodeFormat"); + try(InputStream data = rs.getBinaryStream("NodeData")) { + copy(data, out, "Schematics/" + name + (format ? ".schem" : ".schematic")); + } catch (IOException e) { + throw new SecurityException("Could not export Schematic", e); + } + } + return null; + }, user.getId()); + } + + private void userConfig(SteamwarUser user, ZipOutputStream out) { + userConfig.select(rs -> { + while(rs.next()) { + String name = rs.getString("Config"); + try(InputStream data = rs.getBinaryStream("Value")) { + copy(data, out, name + ".yapion"); + } catch (IOException e) { + throw new SecurityException("Could not export UserConfig", e); + } + } + return null; + }, user.getId()); + } + + private void copyBauwelt(SteamwarUser user, ZipOutputStream out, String inDir, String outDir) throws IOException { + //TODO: Überhaupt nötig wegen Urheberrecht? + File world = new File(inDir); + if(!world.exists()) + return; + + copy(new File(world, "level.dat"), out, outDir + "/level.dat"); + + File region = new File(world, "region"); + for(File regionfile : region.listFiles()) { + copy(regionfile, out, outDir + "/region/" + regionfile.getName()); + } + + File poi = new File(world, "poi"); + if(poi.exists()) { + for(File regionfile : poi.listFiles()) { + copy(regionfile, out, outDir + "/poi/" + regionfile.getName()); + } + } + + File playerdata = new File(world, "playerdata/" + user.getUuid().toString() + ".dat"); + if(playerdata.exists()) + copy(playerdata, out, outDir + "/playerdata/" + user.getUuid().toString() + ".dat"); + } + + private void copyPlayerdata(SteamwarUser user, ZipOutputStream out, String inDir, String outDir) throws IOException { + File worlds = new File(inDir); + String path = "playerdata/" + user.getUuid().toString() + ".dat"; + + int i = 0; + for(File world : worlds.listFiles()) { + File playerdata = new File(world, path); + if(!playerdata.exists()) + continue; + + copy(playerdata, out, outDir + "/" + (i++) + "/" + user.getUuid().toString() + ".dat"); + } + } + + private static void copy(File file, ZipOutputStream out, String path) throws IOException { + try(FileInputStream in = new FileInputStream(file)) { + copy(in, out, path); + } + } + + private static void copy(InputStream in, ZipOutputStream out, String path) throws IOException { + write(stream -> { + int bytes; + for(byte[] buf = new byte[8192]; (bytes = in.read(buf)) > 0; ) { + out.write(buf, 0, bytes); + } + }, out, path); + } + + private static void write(Writer writer, ZipOutputStream out, String path) throws IOException { + ZipEntry entry = new ZipEntry(path); + out.putNextEntry(entry); + writer.accept(out); + out.closeEntry(); + } + + private interface Writer { + void accept(OutputStream stream) throws IOException; + } +} diff --git a/src/de/steamwar/bungeecore/sql/Statement.java b/src/de/steamwar/bungeecore/sql/Statement.java index 9b1628c0..9889a7a4 100644 --- a/src/de/steamwar/bungeecore/sql/Statement.java +++ b/src/de/steamwar/bungeecore/sql/Statement.java @@ -88,7 +88,7 @@ public class Statement { private final String sql; private PreparedStatement st; - Statement(String sql) { + public Statement(String sql) { this.sql = sql; statements.add(this); try { @@ -102,7 +102,7 @@ public class Statement { st = con.prepareStatement(sql); } - T select(ResultSetUser user, Object... objects) { + public T select(ResultSetUser user, Object... objects) { synchronized (statements) { return prepare(() -> { ResultSet rs = st.executeQuery(); @@ -113,7 +113,7 @@ public class Statement { } } - void update(Object... objects) { + public void update(Object... objects) { synchronized (statements) { prepare(st::executeUpdate, objects); } @@ -135,7 +135,7 @@ public class Statement { } } - interface ResultSetUser { + public interface ResultSetUser { T use(ResultSet rs) throws SQLException; } From a6ea418047711d241de7b5c3f6c70f5196922721 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Tue, 23 Nov 2021 19:59:50 +0100 Subject: [PATCH 2/3] WIP GDPR query processor Signed-off-by: Lixfel --- .../bungeecore/commands/GDPRQuery.java | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/de/steamwar/bungeecore/commands/GDPRQuery.java b/src/de/steamwar/bungeecore/commands/GDPRQuery.java index ec693e5e..c7161cab 100644 --- a/src/de/steamwar/bungeecore/commands/GDPRQuery.java +++ b/src/de/steamwar/bungeecore/commands/GDPRQuery.java @@ -6,7 +6,6 @@ import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.io.*; -import java.sql.SQLException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -91,26 +90,31 @@ public class GDPRQuery extends BasicCommand { private void sqlCSV(SteamwarUser user, ZipOutputStream out, Statement statement, String path) throws IOException { write(stream -> { - PrintWriter writer = new PrintWriter(stream); + OutputStreamWriter writer = new OutputStreamWriter(stream); statement.select(rs -> { - int columns = rs.getMetaData().getColumnCount(); + try { + int columns = rs.getMetaData().getColumnCount(); - for(int i = 1; i <= columns; i++) { - writer.write(rs.getMetaData().getColumnName(1)); - writer.write(";"); - } - writer.println(); - - while(rs.next()) { for(int i = 1; i <= columns; i++) { - try { - writer.write(rs.getString(i)); - } catch (NullPointerException e) { - // ignored - } + writer.write(rs.getMetaData().getColumnLabel(i)); writer.write(";"); } - writer.println(); + writer.write("\n"); + + while(rs.next()) { + for(int i = 1; i <= columns; i++) { + try { + writer.write(rs.getString(i)); + } catch (NullPointerException e) { + // ignored + } + writer.write(";"); + } + writer.write("\n"); + } + writer.flush(); + } catch (IOException e) { + throw new SecurityException("Could not write file", e); } return null; }, user.getId()); @@ -121,20 +125,13 @@ public class GDPRQuery extends BasicCommand { personalKitData.select(rs -> { while(rs.next()) { try { - write(stream -> { - try { - new PrintWriter(stream).print(rs.getString("Inventory")); - } catch (SQLException e) { - throw new SecurityException("Could not export PersonalKits", e); - } - }, out, "PersonalKit/" + rs.getString("GameMode") + "/" + rs.getString("Name") + ".Inventory.yml"); - write(stream -> { - try { - new PrintWriter(stream).print(rs.getString("Armor")); - } catch (SQLException e) { - throw new SecurityException("Could not export PersonalKits", e); - } - }, out, "PersonalKit/" + rs.getString("GameMode") + "/" + rs.getString("Name") + ".Armor.yml"); + String path = "PersonalKit/" + rs.getString("GameMode") + "/" + rs.getString("Name"); + try(InputStream data = rs.getBinaryStream("Inventory")) { + copy(data, out, path + ".Inventory.yml"); + } + try(InputStream data = rs.getBinaryStream("Armor")) { + copy(data, out, path + ".Armor.yml"); + } } catch (IOException e) { throw new SecurityException("Could not export PersonalKits", e); } From 582924fb7dc3db1190ef0a756092f5c47f22aa04 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 25 Nov 2021 14:47:37 +0100 Subject: [PATCH 3/3] GDPR query processor Signed-off-by: Lixfel --- src/GDPRQueryREADME.md | 29 ++++ .../bungeecore/commands/GDPRQuery.java | 133 +++++++++++------- .../steamwar/messages/BungeeCore.properties | 10 +- 3 files changed, 124 insertions(+), 48 deletions(-) create mode 100644 src/GDPRQueryREADME.md diff --git a/src/GDPRQueryREADME.md b/src/GDPRQueryREADME.md new file mode 100644 index 00000000..bbe4fcbd --- /dev/null +++ b/src/GDPRQueryREADME.md @@ -0,0 +1,29 @@ +# SteamWar GDPR report + +## Copyright notice +The provided build worlds contain the world design of SteamWar contributors and is subject to their copyright. +The build worlds are therefore provided for personal use only. + +## Categories of personal data processed +- IP address +- Minecraft account +- E-Mail address (if using a website account) + +## Processing purposes of personal data and person-related data +- Provision of SteamWar user functionality (Minecraft account, IP address, BuildWorlds, BuildInventories, BuildMembers, Elo, IgnoredPlayers, SchematicMembers, SchematicChecksessions, Schematics, PersonalKits, UserData, UserConfigs) +- Manual analysis and punishment of player misbehaviour (BannedIPs, log files, Punishments) +- Statistical analysis (Sessions, Fights, SchematicChecksessions) +- Historical data storage (Fights) +- Technical error analysis (log files) +- Provision of the SteamWar website functionality (IP address, E-Mail address) + +## Data Accessors +- SteamWar software +- SteamWar Administration +- SteamWar Development +- SteamWar Moderation (limited to Punishments and SchematicChecksessions) + +## Storage duration +- Data for provision of functionality is stored until user triggered deletion +- Log file storage duration is targeted at one month, but might differ due to technical reasons +- Historical and statistical data deletion is not intended diff --git a/src/de/steamwar/bungeecore/commands/GDPRQuery.java b/src/de/steamwar/bungeecore/commands/GDPRQuery.java index c7161cab..bb98fca1 100644 --- a/src/de/steamwar/bungeecore/commands/GDPRQuery.java +++ b/src/de/steamwar/bungeecore/commands/GDPRQuery.java @@ -1,7 +1,10 @@ package de.steamwar.bungeecore.commands; +import de.steamwar.bungeecore.BungeeCore; +import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.Statement; import de.steamwar.bungeecore.sql.SteamwarUser; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -12,35 +15,47 @@ import java.util.zip.ZipOutputStream; public class GDPRQuery extends BasicCommand { public GDPRQuery() { - super("gdprquery", null); + super("gdprquery", "bungeecore.softreload"); } @Override public void execute(CommandSender sender, String[] args) { if(!(sender instanceof ProxiedPlayer)) return; - ProxiedPlayer player = (ProxiedPlayer) sender; - SteamwarUser user = SteamwarUser.get(player.getUniqueId()); - try { - createZip(user); - } catch (IOException e) { - throw new SecurityException("Could not create zip", e); + ProxiedPlayer player = (ProxiedPlayer) sender; + SteamwarUser user = args.length == 0 ? SteamwarUser.get(player.getUniqueId()) : SteamwarUser.get(args[0]); + if(user == null) { + Message.send("UNKNOWN_PLAYER", player); + return; } + + BungeeCord.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> { + try { + createZip(player, user); + } catch (IOException e) { + throw new SecurityException("Could not create zip", e); + } + }); } - private void createZip(SteamwarUser user) throws IOException { - ZipOutputStream out = new ZipOutputStream(new FileOutputStream("test.zip")); //TODO + private void createZip(ProxiedPlayer player, SteamwarUser user) throws IOException { + printUpdate(player, "GDPR_STATUS_WEBSITE"); - //TODO: Bauweltenurheberrecht - //TODO: Erklärung Art, Umfang (& Dauer?) + ZipOutputStream out = new ZipOutputStream(new FileOutputStream(user.getUserName() + ".zip")); + copy(getClass().getClassLoader().getResourceAsStream("GDPRQueryREADME.md"), out, "README.md"); + copy(getClass().getClassLoader().getResourceAsStream("GDPRQueryREADME.md"), out, "README.txt"); + + printUpdate(player, "GDPR_STATUS_WORLD"); copyBauwelt(user, out, "/home/minecraft/userworlds/" + user.getUuid().toString(), "BuildWorld12"); copyBauwelt(user, out, "/home/minecraft/userworlds15/" + user.getId(), "BuildWorld15"); + + printUpdate(player, "GDPR_STATUS_INVENTORIES"); copyPlayerdata(user, out, "/home/minecraft/userworlds", "BuildInventories12"); copyPlayerdata(user, out, "/home/minecraft/userworlds15", "BuildInventories15"); - //TODO: Simulatoren von allen Bauwelten + printUpdate(player, "GDPR_STATUS_DATABASE"); sqlCSV(user, out, bannedIPs, "BannedIPs.csv"); sqlCSV(user, out, bauweltMember, "BuildMember.csv"); sqlCSV(user, out, bauweltMembers, "BuildMembers.csv"); @@ -62,10 +77,11 @@ public class GDPRQuery extends BasicCommand { schematics(user, out); userConfig(user, out); - //TODO: Logs: Lobby & Bungeelogpos! - //TODO: Website + printUpdate(player, "GDPR_STATUS_LOGS"); + copyLogs(user, out, new File("/logs"), "logs"); out.close(); + printUpdate(player, "GDPR_STATUS_FINISHED"); } private static final Statement bannedIPs = new Statement("SELECT Timestamp, IP FROM BannedUserIPs WHERE UserID = ?"); @@ -89,36 +105,34 @@ public class GDPRQuery extends BasicCommand { private static final Statement userConfig = new Statement("SELECT * FROM UserConfig WHERE User = ?"); private void sqlCSV(SteamwarUser user, ZipOutputStream out, Statement statement, String path) throws IOException { - write(stream -> { - OutputStreamWriter writer = new OutputStreamWriter(stream); - statement.select(rs -> { - try { - int columns = rs.getMetaData().getColumnCount(); + write(stream -> statement.select(rs -> { + try { + OutputStreamWriter writer = new OutputStreamWriter(stream); + int columns = rs.getMetaData().getColumnCount(); + for(int i = 1; i <= columns; i++) { + writer.write(rs.getMetaData().getColumnLabel(i)); + writer.write(";"); + } + writer.write("\n"); + + while(rs.next()) { for(int i = 1; i <= columns; i++) { - writer.write(rs.getMetaData().getColumnLabel(i)); + try { + writer.write(rs.getString(i)); + } catch (NullPointerException e) { + // ignored + } writer.write(";"); } writer.write("\n"); - - while(rs.next()) { - for(int i = 1; i <= columns; i++) { - try { - writer.write(rs.getString(i)); - } catch (NullPointerException e) { - // ignored - } - writer.write(";"); - } - writer.write("\n"); - } - writer.flush(); - } catch (IOException e) { - throw new SecurityException("Could not write file", e); } - return null; - }, user.getId()); - }, out, path); + writer.flush(); + } catch (IOException e) { + throw new SecurityException("Could not write file", e); + } + return null; + }, user.getId()), out, path); } private void personalKits(SteamwarUser user, ZipOutputStream out) { @@ -169,8 +183,18 @@ public class GDPRQuery extends BasicCommand { }, user.getId()); } + private void copyLogs(SteamwarUser user, ZipOutputStream out, File log, String outFile) throws IOException { + if (log.isDirectory()) { + for(File logfile : log.listFiles()) { + copyLogs(user, out, logfile, outFile + "/" + logfile.getName().replace(".gz", "")); + } + } else { + Process reader = new ProcessBuilder("zgrep", "^.*" + user.getUserName() + "\\( issued server command:\\| moved too quickly!\\| executed command:\\| lost connection:\\||\\|»\\|\\[\\|\\]\\).*$", log.getPath()).start(); + copy(reader.getInputStream(), out, outFile); + } + } + private void copyBauwelt(SteamwarUser user, ZipOutputStream out, String inDir, String outDir) throws IOException { - //TODO: Überhaupt nötig wegen Urheberrecht? File world = new File(inDir); if(!world.exists()) return; @@ -208,22 +232,37 @@ public class GDPRQuery extends BasicCommand { } } - private static void copy(File file, ZipOutputStream out, String path) throws IOException { + private void printUpdate(ProxiedPlayer player, String message) { + if (player.isConnected()) + Message.send(message, player); + } + + private void copy(File file, ZipOutputStream out, String path) throws IOException { try(FileInputStream in = new FileInputStream(file)) { copy(in, out, path); } } - private static void copy(InputStream in, ZipOutputStream out, String path) throws IOException { - write(stream -> { - int bytes; - for(byte[] buf = new byte[8192]; (bytes = in.read(buf)) > 0; ) { - out.write(buf, 0, bytes); + private void copy(InputStream in, ZipOutputStream out, String path) throws IOException { + boolean initialized = false; + + int bytes; + for(byte[] buf = new byte[8192]; (bytes = in.read(buf)) > 0; ) { + if(!initialized) { + ZipEntry entry = new ZipEntry(path); + out.putNextEntry(entry); + initialized = true; } - }, out, path); + + out.write(buf, 0, bytes); + } + + if(initialized) { + out.closeEntry(); + } } - private static void write(Writer writer, ZipOutputStream out, String path) throws IOException { + private void write(Writer writer, ZipOutputStream out, String path) throws IOException { ZipEntry entry = new ZipEntry(path); out.putNextEntry(entry); writer.accept(out); diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index cc7d8af1..9e232f9d 100644 --- a/src/de/steamwar/messages/BungeeCore.properties +++ b/src/de/steamwar/messages/BungeeCore.properties @@ -549,4 +549,12 @@ VERIFY_SUCCESS=§7Erfolgreich mit dem Discord Account §e{0} §7verknüpft #Discord DISCORD_TICKET_MESSAGE=§7Ticket §e{0}§7» §f§l{1}: §7{2} DISCORD_TICKET_NEW=§7Ticket §e{0}§7» §aTicket wurde geöffnet! -DISCORD_TICKET_CLOSED=§7Ticket §e{0}§7» §cTicket wurde geschlossen! \ No newline at end of file +DISCORD_TICKET_CLOSED=§7Ticket §e{0}§7» §cTicket wurde geschlossen! + +#GDPR Query +GDPR_STATUS_WEBSITE=§7Website kann nicht automatisiert gepackt werden und muss daher manuell hinzugefügt werden. +GDPR_STATUS_WORLD=§7Packe Bauwelten... +GDPR_STATUS_INVENTORIES=§7Suche und packe Inventare... +GDPR_STATUS_DATABASE=§7Packe Datenbankinhalte... +GDPR_STATUS_LOGS=§7Suche und packe logs... +GDPR_STATUS_FINISHED=§7Packen abgeschlossen \ No newline at end of file