diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..f3c57ce --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,22 @@ +name: CI +on: + workflow_dispatch: + pull_request: + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: "Set up JDK 17" + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: "Build with Maven" + run: "mvn -B compile test --file api/pom.xml" \ No newline at end of file diff --git a/api/src/main/java/com/crowfunder/cogmaster/CogmasterConfig.java b/api/src/main/java/com/crowfunder/cogmaster/CogmasterConfig.java index b0a3b0d..37e1245 100644 --- a/api/src/main/java/com/crowfunder/cogmaster/CogmasterConfig.java +++ b/api/src/main/java/com/crowfunder/cogmaster/CogmasterConfig.java @@ -13,7 +13,7 @@ public record Translations(String path) { public record Routers(String path) { } - public record Parsers(String path, List list) { + public record Parsers(String path) { } public record Assets(String path) { diff --git a/api/src/main/java/com/crowfunder/cogmaster/Configs/ConfigEntry.java b/api/src/main/java/com/crowfunder/cogmaster/Configs/ConfigEntry.java index ca330eb..3cdf010 100644 --- a/api/src/main/java/com/crowfunder/cogmaster/Configs/ConfigEntry.java +++ b/api/src/main/java/com/crowfunder/cogmaster/Configs/ConfigEntry.java @@ -14,7 +14,7 @@ public class ConfigEntry { // Own identifier config path private final Path path; - // If the config is a derived config, this path points to derivative (parent) config + // If the config is a derived config, this path points to the derived from (parent) config private final Path derivedPath; // Source config name diff --git a/api/src/main/java/com/crowfunder/cogmaster/Index/IndexRepository.java b/api/src/main/java/com/crowfunder/cogmaster/Index/IndexRepository.java index 3adcb9f..507446a 100644 --- a/api/src/main/java/com/crowfunder/cogmaster/Index/IndexRepository.java +++ b/api/src/main/java/com/crowfunder/cogmaster/Index/IndexRepository.java @@ -22,7 +22,7 @@ class IndexRepository { private final RouterService routerService; private final TranslationsService translationsService; // The actual index - private final Index index = new Index(); + private Index index; public IndexRepository(ParserService parserService, RouterService routerService, TranslationsService translationsService) { @@ -34,7 +34,7 @@ public IndexRepository(ParserService parserService, RouterService routerService, @PostConstruct public void populateIndex() { logger.info("Parsing the configs, populating ConfigIndex..."); - index.update(parserService.populateConfigIndex()); + index = parserService.populateConfigIndex(); logger.info("Finished parsing"); logger.info("Resolving derivations..."); @@ -68,14 +68,13 @@ private void resolveDerivation(ConfigEntry configEntry) { ParameterArray derivedParameters = new ParameterArray(); ConfigEntry derivedConfig = readConfigIndex(configEntry.getSourceConfig(), configEntry.getDerivedPath()); while (derivedConfig != null) { - derivedParameters.update(derivedConfig.getParameters()); + derivedParameters.update(derivedConfig.getParameters()); // would this not mean the parent potentially overwriting the child parameters? if (!derivedConfig.isDerived()) { configEntry.setDerivedImplementationType(derivedConfig.getImplementationType()); } derivedConfig = readConfigIndex(configEntry.getSourceConfig(), derivedConfig.getDerivedPath()); } configEntry.updateDerivedParameters(derivedParameters); - index.addConfigIndexEntry(configEntry.getSourceConfig(), configEntry.getPath(), configEntry); } // Resolve and cache ALL derivations from ConfigIndex diff --git a/api/src/main/java/com/crowfunder/cogmaster/Parsers/Parser.java b/api/src/main/java/com/crowfunder/cogmaster/Parsers/Parser.java index 7a6d79b..717a0d7 100644 --- a/api/src/main/java/com/crowfunder/cogmaster/Parsers/Parser.java +++ b/api/src/main/java/com/crowfunder/cogmaster/Parsers/Parser.java @@ -4,6 +4,7 @@ import com.crowfunder.cogmaster.Index.Index; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.io.Resource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -22,12 +23,11 @@ public class Parser { - // Path to parsed xml config file - private final String xmlFilePath; - + Logger logger = LoggerFactory.getLogger(Parser.class); + // Parsed xml config file resource + private final Resource xmlFileResource; // Config name, should also correspond to root node of parameters in derived entries private final String configName; - // List of paths leading to parameters to index into ParameterIndex private final List indexableParameterPaths; @@ -37,17 +37,19 @@ public class Parser { // Do I care? No idea. Index index = new Index(); - Logger logger = LoggerFactory.getLogger(Parser.class); - - public String getXmlFilePath() { - return xmlFilePath; + public Parser(String configName, Resource xmlFileResource, List indexableParameterPaths) { + this.xmlFileResource = xmlFileResource; + this.indexableParameterPaths = indexableParameterPaths; + this.configName = configName; } - public List getIndexableParameterPaths() { - return indexableParameterPaths; + // Temporary constructor until reverse indexing works + public Parser(String configName, Resource xmlFileResource) { + this.xmlFileResource = xmlFileResource; + this.indexableParameterPaths = new ArrayList<>(); + this.configName = configName; } - public Index populateConfigIndex() { // Restart the index for parsing @@ -55,7 +57,7 @@ public Index populateConfigIndex() { try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document doc = builder.parse(Parser.class.getResourceAsStream(xmlFilePath)); + Document doc = builder.parse(xmlFileResource.getInputStream()); doc.getDocumentElement().normalize(); // Start reading @@ -85,7 +87,6 @@ public Index populateConfigIndex() { logger.error(e.toString()); throw new RuntimeException(e); } - return index; } @@ -251,19 +252,4 @@ private ParameterValue parseParameterValue(Node parameterNode) { } return parameterValue; } - - - public Parser(String configName, String xmlFilePath, List indexableParameterPaths) { - this.xmlFilePath = xmlFilePath; - this.indexableParameterPaths = indexableParameterPaths; - this.configName = configName; - } - - // Temporary constructor until reverse indexing works - public Parser(String configName, String xmlFilePath) { - this.xmlFilePath = xmlFilePath; - this.indexableParameterPaths = new ArrayList<>(); - this.configName = configName; - } - } diff --git a/api/src/main/java/com/crowfunder/cogmaster/Parsers/ParserService.java b/api/src/main/java/com/crowfunder/cogmaster/Parsers/ParserService.java index 5607806..9835598 100644 --- a/api/src/main/java/com/crowfunder/cogmaster/Parsers/ParserService.java +++ b/api/src/main/java/com/crowfunder/cogmaster/Parsers/ParserService.java @@ -2,29 +2,42 @@ import com.crowfunder.cogmaster.CogmasterConfig; import com.crowfunder.cogmaster.Index.Index; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.stereotype.Service; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @Service public class ParserService { + Logger logger = LoggerFactory.getLogger(ParserService.class); private final List parsers; - private final List parserNames; - private final String parseablePath; public ParserService(CogmasterConfig cogmasterConfig) { - - // Initialize existing parsers, probably not the best idea to do it like that but oh well + // Initialize existing parsers, probably not the best idea to do it like that + // but oh well this.parsers = new ArrayList<>(); - this.parserNames = cogmasterConfig.parsers().list(); - this.parseablePath = cogmasterConfig.parsers().path(); + var parseablePath = cogmasterConfig.parsers().path(); - for (String parserName : this.parserNames) { - this.parsers.add(new Parser(parserName, "/" + parseablePath + "/" + parserName + ".xml")); - } + try { + PathMatchingResourcePatternResolver r = new PathMatchingResourcePatternResolver(); + var parserResources = r.getResources("classpath*:/" + parseablePath + "/*.xml"); + for (Resource resource : parserResources) { + var parserName = resource.getFilename().split("\\.")[0]; + this.parsers.add(new Parser(parserName, resource)); + } + + } catch (IOException e) { + logger.error("Failed to load properties from specified path: /{}/*", parseablePath); + throw new RuntimeException("Failed to load properties", e); + } } public Index populateConfigIndex() { diff --git a/api/src/main/resources/application.yml b/api/src/main/resources/application.yml index bed5cf0..dce7a57 100644 --- a/api/src/main/resources/application.yml +++ b/api/src/main/resources/application.yml @@ -14,14 +14,6 @@ cogmaster: parsers: path: "parseable" - list: - - "item" - - "harness" - - "effect" - - "conversation" - - "attack" - - "actor" - - "accessory" assets: path: "assets" \ No newline at end of file diff --git a/api/src/test/resources/application.yml b/api/src/test/resources/application.yml new file mode 100644 index 0000000..dce7a57 --- /dev/null +++ b/api/src/test/resources/application.yml @@ -0,0 +1,19 @@ +spring: + application: + name: "Cogmaster" + +server: + port: 2137 + +cogmaster: + translations: + path: "properties" + + routers: + path: "routers" + + parsers: + path: "parseable" + + assets: + path: "assets" \ No newline at end of file diff --git a/api/src/test/resources/parseable/actor.xml b/api/src/test/resources/parseable/actor.xml new file mode 100644 index 0000000..066879f --- /dev/null +++ b/api/src/test/resources/parseable/actor.xml @@ -0,0 +1,16 @@ + + + + Block/Barbed Hedgehog + + + Block/Parts/Barbed Hedgehog Base + + Variant + Normal + + + + + + diff --git a/api/src/test/resources/parseable/effect.xml b/api/src/test/resources/parseable/effect.xml new file mode 100644 index 0000000..007bea4 --- /dev/null +++ b/api/src/test/resources/parseable/effect.xml @@ -0,0 +1,17 @@ + + + + Action + + + Action + implementation.action.fire_action + + + + + + + + + diff --git a/api/src/test/resources/parseable/item.xml b/api/src/test/resources/parseable/item.xml new file mode 100644 index 0000000..9888303 --- /dev/null +++ b/api/src/test/resources/parseable/item.xml @@ -0,0 +1,563 @@ + + + + Accessory/Armor/Aura/Snipe Aura, Cocoa + true + + + Accessory/Parts/Base, Custom Colors + + Accessory + + Armor/Aura/Snipe Aura, Cocoa + + Colorizations + + + 11 + + 1295 + + + + 3114 + + + 3370 + + + Icon + ui/icon/inventory/icon_accessory-aaura_cm.png + + + + + + Weapon/Sword/Brandish + true + + + Weapon/Sword/Parts/Base (3 Hit) + + 233+((667/Chain End Speed)*Fire Speed) + 677 + Attack Values + + + 80 + + PC/Damage/Sword/Sword Base + + + + AutoSpawnType + GEAR + Chain End Speed + 1.5 + Charge Time + 3000 + Charged Attack + + Weapon/Sword/Burst Brandish (Charge) + + Burst Color + 0.654902, 0.7490196, 0.7764706, 1.0 + Burst Damage + + + PC/Damage/Handgun/Handgun Base + + 2 + true + + Damage + + + PC/Damage/Sword/Sword Base (Charged) + + 2 + true + + Style + Cautery Sword + + + Damage + + + PC/Damage/Sword/Sword Base + + 2 + + Damage Sound + + Description + + Display Speed + 5 + End Combo Damage + + + PC/Damage/Sword/Sword Base (Last Chain) + + 2 + true + + End Speed + 2.0 + Extra Action 0 + + Extra Action 1 + + Extra Action 2 + + Fire Speed + 1.0 + Flavor + f.brandish + Global Modifier + + + Icon + ui/icon/inventory/weapon/sword/bandish.png + Icon Colorizations + + + Model + + item/weapon/sword/calibur/model_brandish-r1.dat + + Name + m.brandish + Rarity + 2 + Sound - Pitch + Default + Start Speed + 1.75 + Status Values + + + Swing FX + + particle/swing/pc_default_simple.dat + + Blend + ADDITIVE + Scale + 1.5 + Strider Color + 0.6862745, 0.80784315, 0.8117647, 1.0 + Strider Style + Default + Swing Color In/Out + 0.5254902, 0.42745098, 0.44705883, 0.0 + Swing Color Middle + 0.57254905, 0.7764706, 0.78039217, 1.0 + Texture + particle/texture/fx_pcswing.png + + + Swing Sound 1 + sound/effect/weapon/sword_01.ogg + Swing Sound 2 + sound/effect/weapon/sword_02.ogg + Swing Sound 3 + sound/effect/weapon/sword_03.ogg + Tags + + fam_beast, fam_slime, fam_undead, sc_freeze, vanilla + + + + + + + Weapon/Sword/Parts/Base (3 Hit) + + + Icon + implementation.icon.file + + + Icon Colorizations + implementation.icon.colorizations + + + Name + implementation.name + + + Description + implementation.description + + + Flavor + implementation.flavor + + + Rarity + implementation.rarity + + + Model + implementation.model + + + Attack Values + implementation.attack_values + + + Display Speed + implementation.display_speed + + + Status Values + implementation.status_values + + + Damage + implementation.attacks[0].ref["Damage"], implementation.attacks[1].ref["Damage"], implementation.incomplete_charged_attack["Damage"] + + + End Combo Damage + implementation.attacks[2].ref["Damage"] + + + Charge Time + implementation.charge_time + + + Start Speed + implementation.attacks[0].ref["Start Speed"], implementation.attacks[1].ref["Start Speed"], implementation.attacks[2].ref["Start Speed"] + + + Fire Speed + implementation.incomplete_charged_attack["Fire Speed"], implementation.attacks[0].ref["Fire Speed"], implementation.attacks[1].ref["Fire Speed"], implementation.attacks[2].ref["Fire Speed"] + + + End Speed + implementation.incomplete_charged_attack["End Speed"], implementation.attacks[0].ref["End Speed"], implementation.attacks[1].ref["End Speed"] + + + Chain End Speed + implementation.attacks[2].ref["End Speed"] + + + 233+((667/Chain End Speed)*Fire Speed) + implementation.attacks[2].ref["Rearm"] + + + Swing Sound 1 + implementation.attacks[0].ref["Sound"], implementation.incomplete_charged_attack["Sound"] + + + Swing Sound 2 + implementation.attacks[1].ref["Sound"] + + + Swing Sound 3 + implementation.attacks[2].ref["Sound"] + + + Sound - Pitch + implementation.attacks[0].ref["Sound - Pitch"], implementation.attacks[1].ref["Sound - Pitch"], implementation.attacks[2].ref["Sound - Pitch"], implementation.incomplete_charged_attack["Sound - Pitch"], implementation.charged_attack["Sound - Pitch"] + + + Damage Sound + implementation.damage_effect["Sound"] + + + Swing FX + implementation.attacks[0].ref["Swing"], implementation.attacks[1].ref["Swing"], implementation.attacks[2].ref["Swing"], implementation.incomplete_charged_attack["Swing"] + + + Extra Action 0 + implementation.attacks[0].ref["Extra Action"], implementation.incomplete_charged_attack["Extra Action"] + + + Extra Action 1 + implementation.attacks[1].ref["Extra Action"] + + + Extra Action 2 + implementation.attacks[2].ref["Extra Action"] + + + Charged Attack + implementation.charged_attack + + + Global Modifier + implementation.global_modifier + + + Tags + implementation.tags.derived + + + AutoSpawnType + implementation.auto_spawn_type + + + + + ui/icon/inventory/icon_sword.png + + + 516 + + + 770 + + + 1025 + + + + Base (3 Hit) + Template Sword + NOT FOR USE + + Sword + + + item/weapon/sword/banstick/model.dat + + + + + Weapon/Sword/Parts/Base (3 Hit)/Swing 0 (R-L) + + Damage + + 50.0 + 2 + + End Speed + 2.0 + Extra Action + + Fire Speed + 1.0 + Sound + sound/effect/weapon/sword_01.ogg + Sound - Pitch + Default + Start Speed + 1.75 + Swing + + particle/swing/pc_default_simple.dat + + Blend + ADDITIVE + Scale + 1.5 + Strider Color + 0.8, 0.8, 1.0, 1.0 + Strider Style + Default + Swing Color In/Out + 0.8, 0.8, 1.0, 0.0 + Swing Color Middle + 1.0, 1.0, 1.0, 1.0 + Texture + particle/texture/fx_pcswing.png + + + + + + + + Weapon/Sword/Parts/Base (3 Hit)/Swing 1 (L-R) + + Damage + + 50.0 + 2 + + End Speed + 2.0 + Extra Action + + Fire Speed + 1.0 + Sound + sound/effect/weapon/sword_02.ogg + Sound - Pitch + Default + Start Speed + 1.75 + Swing + + particle/swing/pc_default_simple.dat + + Blend + ADDITIVE + Scale + 1.5 + Strider Color + 0.8, 0.8, 1.0, 1.0 + Strider Style + Default + Swing Color In/Out + 0.8, 0.8, 1.0, 0.0 + Swing Color Middle + 1.0, 1.0, 1.0, 1.0 + Texture + particle/texture/fx_pcswing.png + + + + + + + + Weapon/Sword/Parts/Base (3 Hit)/Swing 2 (R-L) + + Damage + + 50.0 + 2 + + End Speed + 1.0 + Extra Action + + Fire Speed + 1.0 + Rearm + 900 + Sound + sound/effect/weapon/sword_03.ogg + Sound - Pitch + Default + Start Speed + 1.75 + Swing + + particle/swing/pc_default_simple.dat + + Blend + ADDITIVE + Scale + 1.5 + Strider Color + 0.8, 0.8, 1.0, 1.0 + Strider Style + Default + Swing Color In/Out + 0.8, 0.8, 1.0, 0.0 + Swing Color Middle + 1.0, 1.0, 1.0, 1.0 + Texture + particle/texture/fx_pcswing.png + + + + + + + + Weapon/Sword/Parts/Base (3 Hit)/Incomplete (R-L) + + Damage + + 50.0 + 2 + + End Speed + 1.0 + Extra Action + + Fire Speed + 1.0 + Sound + sound/effect/weapon/sword_01.ogg + Sound - Pitch + Default + Start Speed + 2.0 + Swing + + particle/swing/pc_default_simple.dat + + Blend + ADDITIVE + Scale + 1.5 + Strider Color + 0.8, 0.8, 1.0, 1.0 + Strider Style + Default + Swing Color In/Out + 0.8, 0.8, 1.0, 0.0 + Swing Color Middle + 1.0, 1.0, 1.0, 1.0 + Texture + particle/texture/fx_pcswing.png + + + + + + Weapon/Sword/Parts/Base (3 Hit)/Charge (Round House) + + Damage + + 50.0 + 2 + + End Speed + 0.75 + Extra Action + + Fire Speed + 1.0 + Impulse + + 1.0, 0.0 + 200 + 300 + + Knock-Back + + 3.5, 0.0 + 300 + 3 + + Radius + 2.0 + Sound + sound/effect/weapon/sword_c01.ogg + Sound - Pitch + Default + Start Speed + 2.2 + Swing + + particle/swing/calibur_charged.dat + + Variant + Calibur + + + + + + Sound Effect + + Shape + Point + Sound + + + + 3000 + 3 + + + + \ No newline at end of file diff --git a/api/src/test/resources/properties/design.properties b/api/src/test/resources/properties/design.properties new file mode 100644 index 0000000..6f3f06b --- /dev/null +++ b/api/src/test/resources/properties/design.properties @@ -0,0 +1 @@ +e.location_already_placed=A room has already been installed at this location. diff --git a/api/src/test/resources/properties/item-names.properties b/api/src/test/resources/properties/item-names.properties new file mode 100644 index 0000000..50d029a --- /dev/null +++ b/api/src/test/resources/properties/item-names.properties @@ -0,0 +1,2 @@ +a.shd=Shadow {0} +a.sniped=Sniped {0} diff --git a/api/src/test/resources/properties/item.properties b/api/src/test/resources/properties/item.properties new file mode 100644 index 0000000..0b5ba5f --- /dev/null +++ b/api/src/test/resources/properties/item.properties @@ -0,0 +1,5 @@ +m.buccaneer_bicorne=Buccaneer Bicorne +m.prize_box_seq={0} Prize Box {1} +m.brandish=Brandish +p.anniv=Anniversary +m.oni_helm=Oni Helm \ No newline at end of file diff --git a/api/src/test/resources/properties/mission.properties b/api/src/test/resources/properties/mission.properties new file mode 100644 index 0000000..a3a6ed7 --- /dev/null +++ b/api/src/test/resources/properties/mission.properties @@ -0,0 +1,2 @@ +n.great_escape=Sputterspark +n.shocking_sentient_sentries_1=Sputterspark \ No newline at end of file