From ec6c3f514ccb757438a9f2fa7d3994b28f8432f5 Mon Sep 17 00:00:00 2001 From: Rex Chan Date: Fri, 6 Apr 2018 19:07:08 -0700 Subject: [PATCH] Added Steam Workshop Support Minor Bugfixes --- src/StellarisDK/FileClasses/DataParser.java | 231 +++++++++--------- src/StellarisDK/FileClasses/DataPattern.java | 2 +- .../FileClasses/Helper/DataCell.java | 10 +- src/StellarisDK/GUI/AbstractUI.java | 12 +- src/StellarisDK/GUI/AgendaUI.java | 3 +- src/StellarisDK/GUI/ModLoader.java | 41 ++-- src/StellarisDK/GUI/guiController.java | 88 ++++--- 7 files changed, 219 insertions(+), 168 deletions(-) diff --git a/src/StellarisDK/FileClasses/DataParser.java b/src/StellarisDK/FileClasses/DataParser.java index 95bc0e1..6f9b0c1 100644 --- a/src/StellarisDK/FileClasses/DataParser.java +++ b/src/StellarisDK/FileClasses/DataParser.java @@ -19,7 +19,7 @@ public class DataParser { private final static Pattern pattern = Pattern.compile("(?s)(?m)(^\\w+)\\s=\\s\\{(.+?)[\\r\\n]\\}[\\r\\n]?"); private final static Pattern constants = Pattern.compile("(\\@\\w+) = (.+)"); - public static void parseToConsole(File file) throws IOException{ + public static void parseToConsole(File file) throws IOException { Scanner scan = new Scanner(file); Component data; String temp; @@ -34,7 +34,7 @@ public static void parseToConsole(File file) throws IOException{ Matcher obj = pattern.matcher(objectDat); obj.find(); data = new Component(); - data.setData((DataMap)data.load(obj.group(2))); + data.setData((DataMap) data.load(obj.group(2))); System.out.println(data.export()); } else { break; @@ -75,8 +75,8 @@ public static ArrayList parseAll(File file) throws IOException { temp = scan.findWithinHorizon(name, 0); if (temp != null) namespace.getChildren().add(new TreeItem<>(temp)); - }while (temp != null); - if(!namespace.getChildren().isEmpty()) + } while (temp != null); + if (!namespace.getChildren().isEmpty()) out.add(namespace); do { temp = scan.findWithinHorizon(constants, 0); @@ -92,118 +92,119 @@ public static ArrayList parseAll(File file) throws IOException { obj.find(); String tabby = obj.group(2).replaceAll(" {4}", "\t"); GenericData gData; - String search = file.getParent().split("\\\\")[file.getParent().split("\\\\").length-1]; - System.out.println(bracketCheck(tabby)); - switch (search) { - case "agendas": - gData = new Agenda(tabby, obj.group(1)); - break; - case "ambient_objects": - gData = new AmbientObject(tabby); - break; - case "anomalies": - if(obj.group(1).equals("anomaly")){ - gData = new Anomaly(tabby); - }else{ - gData = new AnomalyCategory(tabby); - } - break; - case "armies": - gData = new Army(tabby, obj.group(1)); - break; - case "ascension_perks": - gData = new Tradition(tabby, obj.group(1), false); - break; - case "attitudes": - gData = new Attitude(tabby, obj.group(1)); - break; - case "bombardment_stances": - case "buildable_pops": - case "building tags": - case "buildings": - case "colors": - gData = new Component(tabby, obj.group(1)); - break; - case "component_sets": - gData = new CompSet(tabby); - break; - case "component_templates": - gData = new Component(tabby, obj.group(1)); - break; - case "country_types": - case "defines": - case "deposits": - case "diplo_phrases": - case "edicts": - case "event_chains": - case "fallen_empires": - case "game_rules": - case "global_ship_designs": - case "governments": - case "authorities": - case "civics": - case "graphical_culture": - case "mandates": - case "map_modes": - case "megastructures": - case "name_lists": - case "notification_modifiers": - case "observation_station_missions": - case "on_actions": - case "opinion_modifiers": - case "personalities": - case "planet_classes": - case "planet_modifiers": - case "policies": - case "pop_faction_types": - case "precursor_civilizations": - case "random_names": - case "base": - case "scripted_effects": - case "scripted_loc": - case "scripted_triggers": - case "scripted_variables": - case "section_templates": - case "sector_settings": - case "sector_types": - case "ship_behaviors": - case "ship_sizes": - case "solar_system_initializers": - case "special_projects": - case "species_archetypes": - case "species_classes": - case "species_names": - case "species_rights": - case "star_classes": - case "starbase_buildings": - case "starbase_levels": - case "starbase_modules": - case "starbase_types": - case "start_screen_messages": - case "static_modifiers": - case "strategic_resources": - case "subjects": - case "system_types": - case "technology": - case "category": - case "tier": - case "terraform": - case "tile_blockers": - case "tradition_categories": - gData = new Component(tabby, obj.group(1)); - break; - case "traditions": - gData = new Tradition(tabby, obj.group(1), true); - break; - case "traits": - case "events": - gData = new Event(tabby, obj.group(1)); - break; - case "localisation": - default: - gData = new Component(tabby, obj.group(1)); + String search = file.getParent().split("\\\\")[file.getParent().split("\\\\").length - 1]; + if (bracketCheck(tabby)) { + switch (search) { + case "agendas": + gData = new Agenda(tabby, obj.group(1)); + break; + case "ambient_objects": + gData = new AmbientObject(tabby); + break; + case "anomalies": + if (obj.group(1).equals("anomaly")) { + gData = new Anomaly(tabby); + } else { + gData = new AnomalyCategory(tabby); + } + break; + case "armies": + gData = new Army(tabby, obj.group(1)); + break; + case "ascension_perks": + gData = new Tradition(tabby, obj.group(1), false); + break; + case "attitudes": + gData = new Attitude(tabby, obj.group(1)); + break; + case "bombardment_stances": + case "buildable_pops": + case "building tags": + case "buildings": + case "colors": + gData = new Component(tabby, obj.group(1)); + break; + case "component_sets": + gData = new CompSet(tabby); + break; + case "component_templates": + gData = new Component(tabby, obj.group(1)); + break; + case "country_types": + case "defines": + case "deposits": + case "diplo_phrases": + case "edicts": + case "event_chains": + case "fallen_empires": + case "game_rules": + case "global_ship_designs": + case "governments": + case "authorities": + case "civics": + case "graphical_culture": + case "mandates": + case "map_modes": + case "megastructures": + case "name_lists": + case "notification_modifiers": + case "observation_station_missions": + case "on_actions": + case "opinion_modifiers": + case "personalities": + case "planet_classes": + case "planet_modifiers": + case "policies": + case "pop_faction_types": + case "precursor_civilizations": + case "random_names": + case "base": + case "scripted_effects": + case "scripted_loc": + case "scripted_triggers": + case "scripted_variables": + case "section_templates": + case "sector_settings": + case "sector_types": + case "ship_behaviors": + case "ship_sizes": + case "solar_system_initializers": + case "special_projects": + case "species_archetypes": + case "species_classes": + case "species_names": + case "species_rights": + case "star_classes": + case "starbase_buildings": + case "starbase_levels": + case "starbase_modules": + case "starbase_types": + case "start_screen_messages": + case "static_modifiers": + case "strategic_resources": + case "subjects": + case "system_types": + case "technology": + case "category": + case "tier": + case "terraform": + case "tile_blockers": + case "tradition_categories": + gData = new Component(tabby, obj.group(1)); + break; + case "traditions": + gData = new Tradition(tabby, obj.group(1), true); + break; + case "traits": + case "events": + gData = new Event(tabby, obj.group(1)); + break; + case "localisation": + default: + gData = new Component(tabby, obj.group(1)); + } + out.add(new TreeItem<>(gData)); } - out.add(new TreeItem<>(gData)); } else { break; } diff --git a/src/StellarisDK/FileClasses/DataPattern.java b/src/StellarisDK/FileClasses/DataPattern.java index 406f2db..74d05e4 100644 --- a/src/StellarisDK/FileClasses/DataPattern.java +++ b/src/StellarisDK/FileClasses/DataPattern.java @@ -13,7 +13,7 @@ public class DataPattern { // Pattern matches for single value variable // i.e. key, size, power - public static final Pattern kv = Pattern.compile("(?m)^\\t?(\\w+)(\\s?[=<>]+\\s?)([^\\s\\{#\\n]+)(#.+)*"); + public static final Pattern kv = Pattern.compile("(?m)^\\t?(\\w+)(\\s?[=<>]+\\s?)([^\\{#\\n]+)(#.+)*$"); // Pattern matches for single lines objects // Group 1-3: Special match for color diff --git a/src/StellarisDK/FileClasses/Helper/DataCell.java b/src/StellarisDK/FileClasses/Helper/DataCell.java index ec6642c..f1b3ca5 100644 --- a/src/StellarisDK/FileClasses/Helper/DataCell.java +++ b/src/StellarisDK/FileClasses/Helper/DataCell.java @@ -212,10 +212,14 @@ private void setCM() { ContextMenu contextMenu = new ContextMenu(); MenuItem createNew = new MenuItem("New.."); createNew.setOnAction(event -> { - if (!((DataEntry) getItem()).isSingleEntry()) { + if (getItem() instanceof DataEntry) { + if (!((DataEntry) getItem()).isSingleEntry()) { + getTreeItem().getChildren().add(new TreeItem("Click_to_Edit")); + } else { + getTreeItem().getParent().getChildren().add(new TreeItem("Click_to_Edit")); + } + } else { getTreeItem().getChildren().add(new TreeItem("Click_to_Edit")); - }else{ - getTreeItem().getParent().getChildren().add(new TreeItem("Click_to_Edit")); } }); MenuItem edit = new MenuItem("Rename"); diff --git a/src/StellarisDK/GUI/AbstractUI.java b/src/StellarisDK/GUI/AbstractUI.java index 72e5ef5..629b01f 100644 --- a/src/StellarisDK/GUI/AbstractUI.java +++ b/src/StellarisDK/GUI/AbstractUI.java @@ -133,10 +133,14 @@ public void load() { } } else if (new KeyCodeCombination(KeyCode.N, KeyCombination.CONTROL_DOWN).match(event)) { System.out.println("CTRL+N"); - if (!((DataEntry) selected.getValue()).isSingleEntry()) { - selected.getChildren().add(new TreeItem<>("Click_to_Edit")); - }else { - selected.getParent().getChildren().add(new TreeItem<>("Click_to_Edit")); + if (selected.getValue() instanceof DataEntry) { + if (!((DataEntry) selected.getValue()).isSingleEntry()) { + selected.getChildren().add(new TreeItem<>("Click_to_Edit")); + } else { + selected.getParent().getChildren().add(new TreeItem<>("Click_to_Edit")); + } + } else { + selected.getChildren().add(new TreeItem("Click_to_Edit")); } } else if (event.getCode() == KeyCode.DELETE) { if (selected.getParent() != null || !((DataEntry) selected.getValue()).isRequired()) diff --git a/src/StellarisDK/GUI/AgendaUI.java b/src/StellarisDK/GUI/AgendaUI.java index 29318f4..4ccd328 100644 --- a/src/StellarisDK/GUI/AgendaUI.java +++ b/src/StellarisDK/GUI/AgendaUI.java @@ -9,4 +9,5 @@ public AgendaUI(Agenda obj) { window.setText("Agenda Editor"); this.obj = obj; } -} + +} \ No newline at end of file diff --git a/src/StellarisDK/GUI/ModLoader.java b/src/StellarisDK/GUI/ModLoader.java index 011c980..b3b552d 100644 --- a/src/StellarisDK/GUI/ModLoader.java +++ b/src/StellarisDK/GUI/ModLoader.java @@ -25,28 +25,41 @@ public ModLoader(ArrayList modList) { @Override public void load() { - for (TreeItem modList : modList) { - CheckBox temp = new CheckBox(modList.getValue().toString()); - temp.setId(temp.getText()); - list.getChildren().add(temp); + if (list.getChildren().size() == 0) { + for (TreeItem modList : modList) { + CheckBox temp = new CheckBox(modList.getValue().toString()); + temp.setId(temp.getText()); + list.getChildren().add(temp); + } + Button load = new Button("Load Selected"); + load.setOnAction(event -> removeUnchecked()); + list.getChildren().add(load); + } + } + + public void load(ArrayList modList) { + this.modList = modList; + if (list.getChildren().size() > 0) { + list.getChildren().remove(0, list.getChildren().size()); } - Button load = new Button("Load Selected"); - load.setOnAction(event -> removeUnchecked()); - list.getChildren().add(load); + load(); } private void removeUnchecked() { for (TreeItem item : modList) { + item.getChildren().clear(); itemView.getRoot().getChildren().remove(item); if (((CheckBox) list.getChildren().get(modList.indexOf(item))).isSelected()) { itemView.getRoot().getChildren().add(item); - String mainLoadPath = FileSystemView.getFileSystemView().getDefaultDirectory().getPath() + - "\\Paradox Interactive\\Stellaris\\" + - (((ModDescriptor) item.getValue()).getValue("path").toString().replaceAll("/", "\\\\")); - guiController.loadMod(mainLoadPath, item, true); - item.getChildren().add(new TreeItem<>(item.getValue())); - }else{ - modList.set(modList.indexOf(item), null); + if ((((ModDescriptor) item.getValue()).getValue("path") != null)) { + String mainLoadPath = FileSystemView.getFileSystemView().getDefaultDirectory().getPath() + + "\\Paradox Interactive\\Stellaris\\" + + (((ModDescriptor) item.getValue()).getValue("path").toString().replaceAll("/", "\\\\")); + guiController.loadMod(mainLoadPath, item, true); + item.getChildren().add(new TreeItem<>(item.getValue())); + } else { + guiController.extractZip(item); + } } } root.getChildren().remove(this); diff --git a/src/StellarisDK/GUI/guiController.java b/src/StellarisDK/GUI/guiController.java index b0b9a16..3216228 100644 --- a/src/StellarisDK/GUI/guiController.java +++ b/src/StellarisDK/GUI/guiController.java @@ -25,13 +25,13 @@ import javafx.util.Callback; import javax.swing.filechooser.FileSystemView; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.TreeSet; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import static StellarisDK.FileClasses.DataParser.parseToConsole; @@ -42,8 +42,8 @@ public class guiController extends AnchorPane { public static TreeItem compSet; - private ArrayList modList; - private ModLoader loader; + private ArrayList modList = new ArrayList<>(); + private ModLoader modLoader = new ModLoader(modList); private ModDescriptor mainMd; @@ -70,6 +70,13 @@ public guiController() { throw new RuntimeException(e); } + File modFolder = new File(FileSystemView.getFileSystemView().getDefaultDirectory().getPath() + "\\Paradox Interactive\\Stellaris\\mod"); + for (File mod : modFolder.listFiles()) { + if (mod.isFile() && mod.getName().endsWith(".mod")) { + modList.add(new TreeItem<>(new ModDescriptor(mod.getPath()))); + } + } + itemView.setRoot(new TreeItem<>("root")); itemView.setShowRoot(false); itemView.setEditable(true); @@ -297,7 +304,7 @@ private void setCM(TreeCell cell) { fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("Text File (*.txt)", "*.txt")); File temp = fc.showSaveDialog(stage); if (temp != null) { - saveFiles(temp, cell.getTreeItem()); + saveFiles(temp, cell.getTreeItem(), cell.getTreeItem()); } }); @@ -377,6 +384,9 @@ private void setCM(TreeCell cell) { } event.consume(); }); + + modLoader.setRoot(mainWindow); + modLoader.setTree(itemView); } private TreeItem createNew(String type) { @@ -527,21 +537,9 @@ protected void createNewMD() { @FXML protected void openMod() { - if (modList == null) { - modList = new ArrayList<>(); - File modFolder = new File(FileSystemView.getFileSystemView().getDefaultDirectory().getPath() + "\\Paradox Interactive\\Stellaris\\mod"); - for (File mod : modFolder.listFiles()) { - if (mod.isFile() && mod.getName().endsWith(".mod")) { - modList.add(new TreeItem<>(new ModDescriptor(mod.getPath()))); - } - } - loader = new ModLoader(modList); - loader.load(); - loader.setRoot(mainWindow); - loader.setTree(itemView); - } - if (!mainWindow.getChildren().contains(loader)) - mainWindow.getChildren().add(loader); + modLoader.load(); + if (!mainWindow.getChildren().contains(modLoader)) + mainWindow.getChildren().add(modLoader); } @FXML @@ -678,7 +676,7 @@ private void open(GenericData obj) { mainWindow.getChildren().add(obj.ui); } - private void saveFiles(File saveLoc, TreeItem current) { + private void saveFiles(File saveLoc, TreeItem current, TreeItem root) { boolean output = false; String temp = ""; for (Object item : current.getChildren()) { @@ -698,11 +696,11 @@ private void saveFiles(File saveLoc, TreeItem current) { temp = ((Locale) ((TreeItem) item).getValue()).export(); } else if (((TreeItem) item).getChildren().size() != 0) { if (((TreeItem) item).getValue().equals("Constants") || ((TreeItem) item).getValue().equals("Namespace")) { - saveFiles(saveLoc, (TreeItem) item); + saveFiles(saveLoc, (TreeItem) item, root); } else { saveLoc.mkdir(); File test = new File(saveLoc.getPath() + "\\" + ((TreeItem) item).getValue()); - saveFiles(test, (TreeItem) item); + saveFiles(test, (TreeItem) item, root); } } } @@ -711,8 +709,8 @@ private void saveFiles(File saveLoc, TreeItem current) { File out = new File(saveLoc.getPath()); try { if (out.isDirectory()) { - FileWriter fw = new FileWriter(new File(out.getParent() + "\\" + modRoot.getValue() + ".mod")); - fw.write(mainMd.export()); + FileWriter fw = new FileWriter(new File(out.getParent() + "\\" + root.getValue().toString().replaceAll("[\\\\/:*?\"<>|]", "") + ".mod")); + fw.write(((ModDescriptor) root.getValue()).export()); fw.close(); } else { if (!out.exists()) { @@ -742,8 +740,38 @@ private void saveMod(TreeItem root) { main = new File(main.getParent(), folder); } main.mkdir(); - saveFiles(main, root); + saveFiles(main, root, root); + } + } + } + + protected static void extractZip(TreeItem root) { + if (((ModDescriptor) root.getValue()).getValue("archive") != null) { + byte[] buffer = new byte[2048]; + try (FileInputStream archive = new FileInputStream(((ModDescriptor) root.getValue()).getValue("archive").toString().replaceAll("/", "\\\\"))) { + ZipInputStream zis = new ZipInputStream(archive); + ZipEntry entry = zis.getNextEntry(); + while (entry != null) { + if (!entry.getName().equals("descriptor.mod")) { + File file = new File("mods/" + root.getValue().toString() + "/" + entry.getName()); + file.getParentFile().mkdirs(); + System.out.println(file.getAbsolutePath()); + FileOutputStream fos = new FileOutputStream(file); + int size; + while ((size = zis.read(buffer)) > 0) { + fos.write(buffer, 0, size); + } + fos.close(); + } + entry = zis.getNextEntry(); + } + zis.closeEntry(); + zis.close(); + } catch (IOException e) { + e.printStackTrace(); } + loadMod("mods/" + root.getValue().toString() + "/", root, true); + root.getChildren().add(new TreeItem<>(root.getValue())); } } @@ -753,9 +781,9 @@ protected void saveSelect() { dialog.initModality(Modality.APPLICATION_MODAL); dialog.initOwner(this.stage); VBox box = new VBox(); - for (TreeItem modList : modList) { - if (modList != null) { - CheckBox temp = new CheckBox(modList.getValue().toString()); + for (Object mod : itemView.getRoot().getChildren()) { + if (mod != null && !((TreeItem) mod).getValue().equals("Stellaris")) { + CheckBox temp = new CheckBox(((TreeItem) mod).getValue().toString()); temp.setId(temp.getText()); box.getChildren().add(temp); }