diff --git a/.gitattributes b/.gitattributes index 032c1bd1..e25113da 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,58 @@ -* text=auto + # .gitattributes snippet to force users to use same line endings for project. + # + # Handle line endings automatically for files detected as text + # and leave all files detected as binary untouched. + * text=auto + # + # The above will handle all files NOT found below + # https://help.github.com/articles/dealing-with-line-endings/ + # https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes + + + + # These files are text and should be normalized (Convert crlf => lf) + *.php text + *.css text + *.js text + *.scala text + *.java text + *.kt text + *.kts text + *.gradle text + *.sh text + *.xml text + *.md text + *.json text + *.htm text + *.html text + *.xml text + *.txt text + *.ini text + *.inc text + *.pl text + *.rb text + *.py text + *.scm text + *.sql text + .htaccess text + *.sh text + + # These files are binary and should be left untouched + # (binary is a macro for -text -diff) + *.png binary + *.jpg binary + *.jpeg binary + *.gif binary + *.ico binary + *.mov binary + *.mp4 binary + *.mp3 binary + *.flv binary + *.fla binary + *.swf binary + *.gz binary + *.zip binary + *.7z binary + *.ttf binary + *.pyc binary diff --git a/.gitignore b/.gitignore index 44fd0498..5b578653 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ *.hprof hs*.log +archived/ + docsold/ #Maven exclusions @@ -210,4 +212,5 @@ local.properties .quarkus/ /subprojects/common/ddo-modeling/src/main/avro/ -/subprojects/common/ddo-core/src/generated/java/io/truthencode/ddo/core/GeneratedVersion.java \ No newline at end of file +/subprojects/common/ddo-core/src/generated/java/io/truthencode/ddo/core/GeneratedVersion.java +fixle.sh diff --git a/.trunk/configs/.hadolint.yaml b/.trunk/configs/.hadolint.yaml new file mode 100644 index 00000000..ea894f49 --- /dev/null +++ b/.trunk/configs/.hadolint.yaml @@ -0,0 +1,4 @@ +# Following source doesn't work in most setups +ignored: + - SC1090 + - SC1091 diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 102a641b..1be6c29b 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -9,10 +9,12 @@ plugins: uri: https://github.com/trunk-io/plugins lint: enabled: + - hadolint@2.12.0 + - terrascan@1.18.3 - checkov@2.4.9 - - osv-scanner@1.3.6 + - osv-scanner@1.4.0 - trivy@0.45.0 - - trufflehog@3.54.4 + - trufflehog@3.56.0 - taplo@0.8.1 - actionlint@1.6.25 - dotenv-linter@3.3.0 @@ -22,7 +24,7 @@ lint: - markdownlint@0.36.0 - oxipng@8.0.0 - prettier@3.0.3 - - renovate@36.91.0 + - renovate@36.93.7 - scalafmt@3.7.14 - shellcheck@0.9.0 - shfmt@3.6.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index d70ef907..c8e02eb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [0.1.0-alpha] - 2015-12-03 + + ### Added [Unreleased]: https://github.com/truthencode/ddo-calc/0.1.0-alpha...HEAD diff --git a/archived/app/src/test/kotlin/io/truthencode/poc/kantlr/app/ParserTest.kt b/archived/app/src/test/kotlin/io/truthencode/poc/kantlr/app/ParserTest.kt new file mode 100644 index 00000000..0ed23e2f --- /dev/null +++ b/archived/app/src/test/kotlin/io/truthencode/poc/kantlr/app/ParserTest.kt @@ -0,0 +1,29 @@ +/* + * This Kotlin source file was generated by the Gradle "init" task. + */ +package io.truthencode.poc.kantlr.app + +import org.antlr.v4.runtime.CharStreams +import org.antlr.v4.runtime.CommonTokenStream +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class ParserTest { + @Test + fun testGetMessage() { + val ar = "(init { (value 4) , (value 5) , (value 323) })" + val input = CharStreams.fromString("{4,5,323}", "lary") + val lexer = io.truthencode.poc.kantlr.app.ArrayInitLexer(input) + val tokens = CommonTokenStream(lexer) + val parser = io.truthencode.poc.kantlr.app.ArrayInitParser(tokens) + + val tree = parser.init() + + assertEquals(ar, tree.toStringTree(parser)) + } + + @Test + fun testRefEnchantmentParser() { + val p: io.truthencode.ddo.grammar.antlr.EnchantmentsParser + } +} \ No newline at end of file diff --git a/archived/poc-reactive/src/main/docker/Dockerfile.legacy-jar b/archived/poc-reactive/src/main/docker/Dockerfile.legacy-jar new file mode 100644 index 00000000..b8f3748e --- /dev/null +++ b/archived/poc-reactive/src/main/docker/Dockerfile.legacy-jar @@ -0,0 +1,93 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./gradlew build -Dquarkus.package.type=legacy-jar +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/poc-reactive-legacy-jar . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/poc-reactive-legacy-jar +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/poc-reactive-legacy-jar +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.16 + +ENV LANGUAGE='en_US:en' + + +COPY build/lib/* /deployments/lib/ +COPY build/*-runner.jar /deployments/quarkus-run.jar + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] diff --git a/archived/toad-api/README.md b/archived/toad-api/README.md index 31190689..629e73f2 100644 --- a/archived/toad-api/README.md +++ b/archived/toad-api/README.md @@ -15,9 +15,7 @@ ## Overview -``` -DDO Calculations, Planner and Plotting -``` +### DDO Calculations, Planner and Plotting This is a macro service that I am creating to become more familiar with alternative JVM languages and multiple platforms. diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 16442a1a..a5e1f364 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -37,6 +37,8 @@ val defaultJavaToolChainVersion: String? by project val kasechangeVersion: String by project dependencies { + // enable gradle catalog for included convention plugins + implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) // tool languages // node implementation("com.github.node-gradle:gradle-node-plugin:7.0.0") @@ -70,7 +72,8 @@ dependencies { // implementation("com.strumenta.antlr-kotlin:antlr-kotlin-gradle-plugin:70d79b7eb1") // quarkus related - implementation("io.quarkus:gradle-application-plugin:$quarkusPlatformVersion") + // quarkus incompatible with avrohugger (old scala 12.1) used by ddo-modeling. Need to separate build. +// implementation("io.quarkus:gradle-application-plugin:$quarkusPlatformVersion") implementation("org.kordamp.gradle:jandex-gradle-plugin:$jandexPluginVersion") // Database diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties index 9e9d39a4..c404e0b3 100644 --- a/build-logic/gradle.properties +++ b/build-logic/gradle.properties @@ -26,10 +26,10 @@ scalaVersions=2.12.18,2.11.12,2.13.12 # Quarkus quarkusPluginId=io.quarkus -quarkusPluginVersion=3.2.0.Final +quarkusPluginVersion=3.3.3.Final quarkusPlatformGroupId=io.quarkus.platform quarkusPlatformArtifactId=qu -quarkusPlatformVersion=2.7.0.Final +quarkusPlatformVersion=3.3.3 jandexPluginVersion=0.11.0 testSetsPluginVersion=2.1.1 diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts index a5c2529a..27847493 100644 --- a/build-logic/settings.gradle.kts +++ b/build-logic/settings.gradle.kts @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +// build-logic pluginManagement { repositories { mavenCentral() @@ -29,6 +29,7 @@ pluginManagement { val foojayResolverPluginVersionversion: String by settings val palantirPluginVersion: String by settings + val quarkusPlatformVersion: String by settings plugins { // id("org.kordamp.gradle.project") version kordampGradlePluginVersion @@ -40,6 +41,7 @@ pluginManagement { id("com.palantir.baseline-config") version palantirPluginVersion id("org.inferred.processors") version "3.7.0" id("org.scoverage") version "8.0.3" + id("io.quarkus") version quarkusPlatformVersion // id("ru.vyarus.mkdocs") version "3.0.0" } } @@ -49,6 +51,59 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") } +/* Hackathon to use catalogs in convention plugin +Tracked in [github.com/gradle/gradle/issues/17863] +SO [stackoverflow.com/questions/69080927/gradle-7-2-gradle-kotlin-dsl-how-to-use-catalogs-in-convention-plugin] +Add custom code in included-builds build.gradle(.kts) +Add custom code in convention plugins settings.gradle(.kts) + +``` kotlin +./build-src/build.gradle.kts +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} + +println("from build-src build script: ${libs.versions.bb.get()}") + +dependencies { + implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) +} + +// ./build-src/settings.gradle.kts +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +// ./build-src/src/main/kotlin/foo.gradle.kts +import org.gradle.accessors.dm.LibrariesForLibs + +val libs = the() +println("from pre compiled script plugin: ${libs.versions.bb.get()}") + +// ./build.gradle.kts +plugins { + id("foo") +} + +println("from main build script: ${libs.versions.bb.get()}") + +// ./gradle/libs.versions.toml +[versions] +bb = "3.2.1" + +// ./settings.gradle.kts +rootProject.name = "showcase" +includeBuild("build-src") + +*/ dependencyResolutionManagement { versionCatalogs { // declares an additional catalog, named 'testLibs', from the 'test-libs.versions.toml' file diff --git a/build-logic/src/main/kotlin/djaxonomy.test-conventions.gradle.kts b/build-logic/src/main/kotlin/djaxonomy.test-conventions.gradle.kts index aab3a2b6..65dafa62 100644 --- a/build-logic/src/main/kotlin/djaxonomy.test-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/djaxonomy.test-conventions.gradle.kts @@ -19,11 +19,19 @@ import io.truthencode.djaxonomy.etc.TestTypes * See the License for the specific language governing permissions and * limitations under the License. */ +import org.gradle.accessors.dm.LibrariesForLibs + plugins { id("djaxonomy.java-common-conventions") `jvm-test-suite` } +tasks.withType(Test::class.java) { + systemProperties["concordion.output.dir"] = "${reporting.baseDir}/tests" +} + +val libs = the() + val extension = project.extensions.create("KotlinTestKits") extension.useKotlinTestKit.convention( KotlinTestKits.KoTest, @@ -33,7 +41,7 @@ fun JvmTestSuite.applyKoTest() { val koTestVersion: String = (findProperty("koTestVersion") ?: embeddedKotlinVersion).toString() dependencies { - implementation("io.kotest:kotest-runner-junit5:$koTestVersion") + implementation(libs.kotest.runner.junit.jvm) implementation("io.kotest:kotest-assertions-core:$koTestVersion") implementation("io.kotest:kotest-property:$koTestVersion") } @@ -43,72 +51,49 @@ fun JvmTestSuite.applyKotlinTest() { useKotlinTest() } -val junitScalaTestVersion: String by project -val junitPlatformVersion: String by project - -val scalaLibraryVersion: String by project -val enumeratumVersion: String by project -val logbackVersion: String by project - -val scalaTestPlusMockitoVersion: String by project -val scalaCheckVersion: String by project -val scalaTestVersion: String by project -val accordVersion: String by project -val scalaMajorVersion: String by project -val scalaLoggingVersion: String by project - -val mockitoVersion: String by project -val concordionVersion: String by project -val flexmarkVersion: String by project -val typeSafeConfigVersion: String by project - fun JvmTestSuite.applyConcordionAcceptanceTest() { dependencies { implementation(project()) - implementation("org.concordion:concordion:$concordionVersion") + implementation(libs.concordion) // flexmark (mostly for concordion / markdown) - implementation("com.vladsch.flexmark:flexmark-all:$flexmarkVersion") // 0.62.2 -> 0.64.8 -// implementation("com.vladsch.flexmark:ext-gfm-strikethrough:$flexmarkVersion") -// implementation("com.vladsch.flexmark:flexmark-ext-emoji:$flexmarkVersion") -// implementation("com.vladsch.flexmark:flexmark-ext-yaml-front-matter:$flexmarkVersion") -// implementation("com.vladsch.flexmark:flexmark-ext-gfm-tasklist:$flexmarkVersion") + implementation(libs.flexmark.all) } } fun JvmTestSuite.applyScalaDepends() { dependencies { - implementation("org.scala-lang:scala-library:$scalaLibraryVersion") - implementation("ch.qos.logback:logback-classic:$logbackVersion") - implementation("com.typesafe.scala-logging:scala-logging_$scalaMajorVersion:$scalaLoggingVersion") - implementation("com.beachape:enumeratum_$scalaMajorVersion:$enumeratumVersion") - implementation("com.typesafe:config:$typeSafeConfigVersion") + implementation(libs.scala2.library) + implementation(libs.logback.classic) + implementation(libs.typesafe.scala.logging.s213) + implementation(libs.enumeratum.s213) + implementation(libs.typesafe.config) } } fun JvmTestSuite.applyVintageEngine() { dependencies { - runtimeOnly("org.junit.vintage:junit-vintage-engine:$junitPlatformVersion") + runtimeOnly(libs.junit.vintage.engine) } } fun JvmTestSuite.applyJupiterEngine() { dependencies { - runtimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitPlatformVersion") + runtimeOnly(libs.junit.jupiter.engine) } } fun JvmTestSuite.applyScalaTest() { dependencies { - runtimeOnly("co.helmethair:scalatest-junit-runner:$junitScalaTestVersion") - + runtimeOnly(libs.scalatest.plus.junit) // runtimeOnly("org.junit.vintage:junit-vintage-engine:5.10.0") + implementation(libs.scalatest.s213) + implementation(libs.scalatest.plus.mockito.s213) - implementation("org.scalatest:scalatest_$scalaMajorVersion:$scalaTestVersion") - implementation("org.scalacheck:scalacheck_$scalaMajorVersion:$scalaCheckVersion") - implementation("org.scalatestplus:mockito-3-4_$scalaMajorVersion:$scalaTestPlusMockitoVersion") - implementation("org.mockito:mockito-core:$mockitoVersion") - implementation("com.wix:accord-core_$scalaMajorVersion:$accordVersion") - implementation("com.wix:accord-scalatest_$scalaMajorVersion:$accordVersion") + implementation(libs.mockito.core) + implementation(libs.wix.accord.core.s213) + implementation(libs.wix.accord.scalatest.s213) + + implementation(libs.scalatest.plus.scalacheck) // JUnit } @@ -138,17 +123,17 @@ project.testing { // Kotlin specific if (project.plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { - logger.error("Configuring Kotlin Testing for ${project.name}") + logger.info("Configuring Kotlin Testing for ${project.name}") when (extension.useKotlinTestKit.get()) { KotlinTestKits.KoTest -> { logger.warn("configuring KoTest for Unit testing") - test.applyKoTest() + this.applyKoTest() } KotlinTestKits.KotlinTest -> { logger.warn("configuring KotlinTest for Unit testing") - test.applyKotlinTest() + this.applyKotlinTest() } else -> {} @@ -158,11 +143,11 @@ project.testing { // Scala Specific if (project.plugins.hasPlugin("scala")) { - logger.error("Configuring ${project.name} for Scala ${tt.name} Testing : ${this.name} ") + logger.info("Configuring ${project.name} for Scala ${tt.name} Testing : ${this.name} ") when (tt) { TestTypes.Unit -> { - logger.error(("Configuring standard Unit Test for scala")) + logger.info(("Configuring standard Unit Test for scala")) this.applyScalaTest() } @@ -171,9 +156,9 @@ project.testing { this.applyScalaDepends() this.applyJupiterEngine() this.applyVintageEngine() - logger.error("adding scala acceptance stuff") + logger.info("adding scala acceptance stuff") dependencies { - implementation("de.neuland-bfi:jade4j:1.2.7") + implementation(libs.jade4j) } targets.all { testTask.configure { @@ -189,7 +174,7 @@ project.testing { } else -> { - logger.error("no config ATM (applying Jupiter as default") + logger.info("no config ATM (applying Jupiter as default") useJUnitJupiter() } } @@ -197,7 +182,9 @@ project.testing { // Concordian BDD Acceptance if (tt == TestTypes.Acceptance) { - logger.error("applying Concordion Acceptance") + logger.info("applying Concordion Acceptance") + + // systemProperties["concordion.output.dir"] = "${reporting.baseDir}/spec" this.applyConcordionAcceptanceTest() this.applyVintageEngine() this.applyJupiterEngine() diff --git a/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-application-conventions.gradle.kts b/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-application-conventions.gradle.kts new file mode 100644 index 00000000..289bf829 --- /dev/null +++ b/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-application-conventions.gradle.kts @@ -0,0 +1,11 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + // Apply the common convention plugin for shared build configuration between library and application projects. + id("io.truthencode.poc.kantlr.kotlin-common-conventions") + + // Apply the application plugin to add support for building a CLI application in Java. + application +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-common-conventions.gradle.kts b/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-common-conventions.gradle.kts new file mode 100644 index 00000000..b53b2a83 --- /dev/null +++ b/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-common-conventions.gradle.kts @@ -0,0 +1,30 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. + id("org.jetbrains.kotlin.jvm") +} + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +dependencies { + constraints { + // Define dependency versions as constraints + implementation("org.apache.commons:commons-text:1.10.0") + } + + // Use JUnit Jupiter for testing. + testImplementation("org.junit.jupiter:junit-jupiter:5.9.3") + + testRuntimeOnly("org.junit.platform:junit-platform-launcher") +} + +tasks.named("test") { + // Use JUnit Platform for unit tests. + useJUnitPlatform() +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-library-conventions.gradle.kts b/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-library-conventions.gradle.kts new file mode 100644 index 00000000..03c4f73b --- /dev/null +++ b/build-logic/src/main/kotlin/io.truthencode.poc.kantlr.kotlin-library-conventions.gradle.kts @@ -0,0 +1,11 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +plugins { + // Apply the common convention plugin for shared build configuration between library and application projects. + id("io.truthencode.poc.kantlr.kotlin-common-conventions") + + // Apply the java-library plugin for API and implementation separation. + `java-library` +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/scala-conventions.gradle.kts b/build-logic/src/main/kotlin/scala-conventions.gradle.kts index 740b8937..c4e251d9 100644 --- a/build-logic/src/main/kotlin/scala-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/scala-conventions.gradle.kts @@ -1,3 +1,5 @@ +import org.gradle.accessors.dm.LibrariesForLibs + /* * SPDX-License-Identifier: Apache-2.0 * @@ -23,6 +25,7 @@ plugins { // java // apply (false) id("org.scoverage") } +val libs = the() // dependencies { // val scalaLibraryVersion: String by project @@ -33,19 +36,20 @@ plugins { // // } -// configure { -// scoverageVersion.set("2.0.10") -// val cfgs = mapOf( -// Pair(org.scoverage.CoverageType.Branch, 0.5.toBigDecimal()), -// Pair(org.scoverage.CoverageType.Statement, 0.75.toBigDecimal()) -// ).map { p -> -// val cfg = org.scoverage.ScoverageExtension.CheckConfig() -// cfg.setProperty("coverageType", p.key) -// cfg.setProperty("minimumRate", p.value) -// cfg -// } -// checks.plusAssign(cfgs) -// } +configure { + scoverageVersion.set(libs.versions.scoverage) + val cfgs = + mapOf( + Pair(org.scoverage.CoverageType.Branch, 0.5.toBigDecimal()), + Pair(org.scoverage.CoverageType.Statement, 0.75.toBigDecimal()), + ).map { p -> + val cfg = org.scoverage.ScoverageExtension.CheckConfig() + cfg.setProperty("coverageType", p.key) + cfg.setProperty("minimumRate", p.value) + cfg + } + checks.plusAssign(cfgs) +} // // diff --git a/build.gradle.kts b/build.gradle.kts index 24fce21d..f4dc2c16 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -69,6 +69,14 @@ mkdocs { } } +/* TODO: Docuemtation Task +Include Acceptance tests and possibly coverage in mkdocs + +depend on testAggregateTestReport (needs check) and aggregateScoverage +scoverage aggregates to ./build/reports/scoverage/ +testAggregateTestReport aggregates to ./subprojects/common/ddo-test-results/build/reports/tests/[test-type] + */ + val devRequirementsIn = listOf( "pip-tools:7.3.0", @@ -317,6 +325,14 @@ allprojects { mavenCentral() } + tasks.register("printConfigurations") { + doLast { + println("Project Name: $project.name configurations:") + configurations.forEach { + println("\t$it.name") + } + } + } // val syncVersionFiles by tasks.registering(Copy::class) { // if (rootProject != project) { // logger.warn("We are updating properties file in ${project.name}") diff --git a/doc/components/core/docs/about/history.md b/doc/components/core/docs/about/history.md index 2b5988fb..9124d11e 100644 --- a/doc/components/core/docs/about/history.md +++ b/doc/components/core/docs/about/history.md @@ -1,3 +1,5 @@ + + ### 1.0.0 (2017.11.01) - Initial release diff --git a/docs/about/Tasks.md b/docs/about/Tasks.md index c3fe427e..27d1c683 100644 --- a/docs/about/Tasks.md +++ b/docs/about/Tasks.md @@ -1,9 +1,9 @@ -# Resources: +# Resources - [Apimatic](https://apimatic.io) Spec Toolkit (Swagger, API Blueprint) -- [Codacy](http://codacy.com) Code quality metrics -- [Travis-CI](http://travis-ci.com) Continuous Integration -- [Github](http://github.com) Code Repository / Issue tracking +- [Codacy](https://codacy.com) Code quality metrics +- [Travis-CI](https://circleci.com) Continuous Integration +- [Github](https://github.com) Code Repository / Issue tracking - [ ] Generate All Models (Swagger 2.0) - - [ ] Items diff --git a/docs/developers_guide/EffectZen.mmd b/docs/developers_guide/EffectZen.mmd new file mode 100644 index 00000000..819ea8da --- /dev/null +++ b/docs/developers_guide/EffectZen.mmd @@ -0,0 +1,8 @@ +zenuml + title Effect Value Routing and Adjustment + @Actor Alice + @Database Bob + @Database Mongo + Alice->Bob: Hi Bob + Bob->Alice: Hi Alice + Mongo->Bob: Auditing diff --git a/docs/developers_guide/Tech_Concepts.md b/docs/developers_guide/Tech_Concepts.md index 6adcbe70..bceca3d6 100644 --- a/docs/developers_guide/Tech_Concepts.md +++ b/docs/developers_guide/Tech_Concepts.md @@ -15,6 +15,28 @@ Initial Data population / object builder These entities can be persisted in one or more databases. +## Validation + +### [Wix-Accord](https://github.com/wix-incubator/accord) + +My first choice for object validation (Scala). +It has since been retired. + +### [Octopus](https://github.com/krzemin/octopus) + +Appears similar with integration with Catz / Scalaz but not scala 3 and last active 3 years ago. + +### [Parisksha](https://github.com/ayushworks/pariksha) + +Same as above with Catz and 4 years since last active. + +## Transformation + +### Chimney (https://github.com/scalalandio/chimney) + +Scala Object mangler / mapper to assist going from similar forms. +Useful where User DTO ~= User Db Entity ~= User Login etc + ## Packaging ### Layrry - A Launcher and API for Modularized Java Applications @@ -54,6 +76,12 @@ There are also a handful of Proof of concept polygot notebooks out there, mostly ## Front End +### Endpoints + +[Tapir](https://github.com/softwaremill/tapir) +allows defining and documentation of http endpoints that can be implemented via other technologies +such as Vert.x or Akka. + Front End Using Kafka streams, we can update running totals and properties in an event-driven manner for character builders such as feats possessed, stances / abilities toggled, items equipped to dynamically show average damage, DR breaking, crit profiles, hit-points etc. without having to re-evaluate every effect in place. diff --git a/docs/developers_guide/project-dependencies.dot b/docs/developers_guide/project-dependencies.dot index 6a2de14c..cf1ef417 100644 --- a/docs/developers_guide/project-dependencies.dot +++ b/docs/developers_guide/project-dependencies.dot @@ -1,9 +1,15 @@ strict digraph { splines=ortho +"ddo-web" -> "ddo-platform" +"ddo-web" -> "ddo-core" "ddo-modeling" -> "ddo-platform-scala" +"ddo-antlr" -> "ddo-platform" +"ddo-core" -> "ddo-modeling" "ddo-core" -> "ddo-platform-scala" "ddo-core" -> "ddo-util" -"ddo-core" -> "ddo-modeling" "ddo-etl" -> "ddo-platform-scala" +"ddo-etl" -> "ddo-antlr" +"ddo-etl" -> "ddo-web" +"ddo-etl" -> "ddo-core" "ddo-util" -> "ddo-platform-scala" } diff --git a/docs/developers_guide/roadmap.md b/docs/developers_guide/roadmap.md index b92c75ee..793c0fba 100644 --- a/docs/developers_guide/roadmap.md +++ b/docs/developers_guide/roadmap.md @@ -27,8 +27,7 @@ When combined, you should be able to truly see what a given toon does. - Reverse build selection: Most people have a Legendary in mind, then start from level 1 trying to muddle through seeing what they end up with. Start by Adding how you want to end up. - i.e. At level 30, I want a Power-striking, Bastard sword swinging, Self - repairing automaton. So I start by selecting + i.e. At level 30, I want a Power-striking, Bastard sword swinging, self-repairing automaton. So I start by selecting [Scion of Mechanus](https://ddowiki.com/page/Scion_of_Mechanus), [Power Attack](https://ddowiki.com/page/Power_Attack) and [Proficiency: Bastard Sword](https://ddowiki.com/page/Proficiency:_Bastard_Sword) @@ -40,55 +39,55 @@ When combined, you should be able to truly see what a given toon does. [Tenser's Transformation](https://ddowiki.com/page/Tenser%27s_Transformation). Who knows? Tucows can rise again! -# Stages +## Stages The order of operations will be the Backbone API / core, followed by the clients. Although I would like to make the world's best character planner, I believe a comprehensive framework would be more beneficial to the DDO world at large. -## Backbone +### Backbone Backbone should be a restful API. Ideally swagger / open API endpoints by OData internally using Apache Avro as a common serializer / storage. This should allow Client options to develop third parties without the need to wait for an official client. -### API +#### API [OpenAPI (Swagger)](https://www.openapis.org/) / [OData](https://www.odata.org/) This specification will drive development and serve as the public facing API with documentation. Third parties can interact by viewing / downloading the swagger document and or querying the odata $metadata. -### Core +#### Core Mostly internal, it contains object logic that contains meta-data such as stacking rules, damage etc. -### Data +#### Data TBD: Data storage. A central store for core internal aspects as well as user-local data stores such as storing individual characters / builds etc. -### Misc +#### Misc Additional support / utility / ETL libraries -## Clients +### Clients Client apps and services that allow users to interact with the API in a more friendly fashion. -### CLI (Command Line Interface) +#### CLI (Command Line Interface) a command line client will be likely be priority. This allows the more tech savvy to progress while also making intregration / regression and test client automation maintainable. -### GUI +#### GUI -#### Web clients +##### Web clients Browser A web client may be the next feasible client. While not the end goal, a browser based site with mobile in mind would allow the most widespread access to desktop (windows / Linux / Mac), mobile and tablet users. -### Rich clients +#### Rich clients The end goal of this project. To keep a more consistent look and feel, a more universal client will be pursued. The client may add richer feature such as importing / exporting characters to other formats such as the commonly accepted forum post format and hopefully a format that will allow importing or exporting to other popular DDO Clients so users may try this without the need to start from scratch or feel locked into this tool. -### Targets +#### Targets - Mobile / Tablet An Android client for mobile and or tablet. diff --git a/fixle.sh b/fixle.sh new file mode 100755 index 00000000..3f5be0ef --- /dev/null +++ b/fixle.sh @@ -0,0 +1,44 @@ +##################### +# +# Use this with or without the .gitattributes snippet with this Gist +# create a fixle.sh file, paste this in and run it. +# Why do you want this ? Because Git will see diffs between files shared between Linux and Windows due to differences in line ending handling ( Windows uses CRLF and Unix LF) +# This Gist normalizes handling by forcing everything to use Unix style. +##################### + +# Fix Line Endings - Force All Line Endings to LF and Not Windows Default CR or CRLF +# Taken largely from: https://help.github.com/articles/dealing-with-line-endings/ +# With the exception that we are forcing LF instead of converting to windows style. + +#Set LF as your line ending default. +git config --global core.eol lf + +#Set autocrlf to false to stop converting between windows style (CRLF) and Unix style (LF) +git config --global core.autocrlf false + +#Save your current files in Git, so that none of your work is lost. +git add . -u +git commit -m "Saving files before refreshing line endings" + +#Remove the index and force Git to rescan the working directory. +rm .git/index + +#Rewrite the Git index to pick up all the new line endings. +git reset + +#Show the rewritten, normalized files. + +git status + +#Add all your changed files back, and prepare them for a commit. This is your chance to inspect which files, if any, were unchanged. + +git add -u +# It is perfectly safe to see a lot of messages here that read +# "warning: CRLF will be replaced by LF in file." + +#Rewrite the .gitattributes file. +git add .gitattributes + +#Commit the changes to your repository. + +git commit -m "Normalize all the line endings" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 529836e4..5f2a9437 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,33 +1,73 @@ [versions] -com-wix = "0.7.6" +accord = "0.7.6" +antlr = "4.13.1" +flexmark = "0.64.8" getquill = "4.6.1" +# TODO: jade4j became pug, should check for an update at some point +jade4j = "1.3.2" junit-engine = "5.10.0" junit-jupiter = "5.10.0" junit-platform = "1.10.0" +kotest = "5.7.2" # @pin We all move together kotlin = "1.9.0" logback = "1.4.11" mockito = "5.5.0" monix = "3.4.1" +moshi = "1.15.0" org-scoverage = "2.0.11" # @keep -> scalaMajorVersion scala2-suffix = "2.13" # @pin -> scalaLibraryVersion scala2-version = "2.13.10" +scalaFmt = "3.1.1" +scalacheck = "1.17.0" +scalatest = "3.3.0.0-SNAP3" +scalatestplus = "3.2.17.0" +scoverage = "2.0.11" +quarkus-s3 = "0.0.1" +scala3-version = "3.1.0" +quarkus = "3.4.0" + +# Scala Jackson at time of writing doesn't support Scala 3 Enum's natively. It requires another library. +# That library doesn't support same version of Jackson that Quarkus BOM uses (2.12.5), so this is the best compromise +# https://search.maven.org/artifact/com.github.pjfanning/jackson-module-scala3-enum_3/2.12.3/jar +# @pin +jackson = "2.12.3" [libraries] +#Gradle properties +quarkiverse-scala-s3 = { module = "io.quarkiverse.scala:quarkus-scala3", version.ref = "quarkus-s3" } +quarkus-bom = { module = "io.quarkus.platform:quarkus-bom", version.ref = "quarkus" } +quarkus-arc = { module = "io.quarkus:quarkus-arc", version.ref = "quarkus" } +quarkus-resteasy-reactive = { module = "io.quarkus:quarkus-resteasy-reactive", version.ref = "quarkus" } +fasterxml-jackson-module = { module = "com.fasterxml.jackson.module:jackson-module-scala_3", version.ref = "jackson" } +jackson-module-enum = { module = "com.github.pjfanning:jackson-module-scala3-enum_3", version.ref = "jackson" } +# quarkus-junit5 = {module="io.quarkus:quarkus-junit5", version.ref="quarkus"} # -- versioned transitively via quarkus bom +# rest-assured-core = {module"io.rest-assured:rest-assured", version.ref="rest-assured"} # -- versioned transitively via quarkus bom +scala-compiler-s3 = { module = "org.scala-lang:scala3-compiler_3", version.ref = "scala3-version" } +scala-library-s3 = { module = "org.scala-lang:scala3-library_3", version.ref = "scala3-version" } + +antlr4 = { module = "org.antlr:antlr4", version.ref = "antlr" } apache-logging-log4j-log4j-core = "org.apache.logging.log4j:log4j-core:3.0.0-alpha1" concordion = "org.concordion:concordion:4.0.1" concordion-collapse-output-extension = "org.concordion:concordion-collapse-output-extension:1.0.0" concordion-embed-extension = "org.concordion:concordion-embed-extension:1.2.0" +chimney-s213 = "io.scalaland:chimney_2.13:0.8.0-M1" enumeratum-s213 = "com.beachape:enumeratum_2.13:1.7.3" -jade4j = "de.neuland-bfi:jade4j:1.3.2" +flexmark-all = { module = "com.vladsch.flexmark:flexmark-all", version.ref = "flexmark" } +jade4j = { module = "de.neuland-bfi:jade4j", version.ref = "jade4j" } json4s-native-s213 = "org.json4s:json4s-native_2.13:4.1.0-M3" junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } +junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-engine" } junit-platform-engine = { module = "org.junit.platform:junit-platform-engine", version.ref = "junit-platform" } junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit-platform" } junit-platform-runner = { module = "org.junit.platform:junit-platform-runner", version.ref = "junit-engine" } junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit-engine" } +kotest-assertions-core-jvm = { module = "io.kotest:kotest-assertions-core-jvm", version.ref = "kotest" } +kotest-property-jvm = { module = "io.kotest:kotest-property-jvm", version.ref = "kotest" } +kotest-runner-junit-jvm = { module = "io.kotest:kotest-runner-junit5-jvm", version.ref = "kotest" } +kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" } kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } kotlin-stdlib-common = { module = "org.jetbrains.kotlin:kotlin-stdlib-common", version.ref = "kotlin" } @@ -44,16 +84,22 @@ quill-monix-s213 = { module = "io.getquill:quill-monix_2.13", version.ref = "get quill-sql-s213 = { module = "io.getquill:quill-sql_2.13", version.ref = "getquill" } ruippeixotog-scala-scraper-s213 = "net.ruippeixotog:scala-scraper_2.13:3.1.0" scala2-library = { module = "org.scala-lang:scala-library", version.ref = "scala2-version" } -scalacheck-s213 = "org.scalacheck:scalacheck_2.13:1.17.0" -scalafmt-core-s213 = "com.geirsson:scalafmt-core_2.13:3.1.1" +scalacheck-s213 = { module = "org.scalacheck:scalacheck_2.13", version.ref = "scalacheck" } +scalafmt-core-s213 = { module = "com.geirsson:scalafmt-core_2.13", version.ref = "scalaFmt" } scalatest-junit-runner = "co.helmethair:scalatest-junit-runner:0.2.0" -scalatest-plus-mockito-s213 = "org.scalatestplus:mockito-3-4_2.13:3.3.0.0-SNAP3" +scalatest-plus-mockito-s213 = { module = "org.scalatestplus:mockito-3-4_2.13", version.ref = "scalatest" } +scalatest-plus-junit = { module = "org.scalatestplus:junit-5-10_2.13", version.ref = "scalatestplus" } +scalatest-plus-scalacheck = { module = "org.scalatestplus:scalacheck-1-17_2.13", version.ref = "scalatestplus" } scalatest-s213 = "org.scalatest:scalatest_2.13:3.3.0-SNAP4" scoverage-runtime-s213 = { module = "org.scoverage:scalac-scoverage-runtime_2.13", version.ref = "org-scoverage" } +squareup-moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" } +squareup-moshi-adapters = { module = "com.squareup.moshi:moshi-adapters", version.ref = "moshi" } +squareup-moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } +squareup-moshi-kotlin-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" } typesafe-config = "com.typesafe:config:1.4.2" typesafe-scala-logging-s213 = "com.typesafe.scala-logging:scala-logging_2.13:3.9.5" -wix-accord-core-s213 = { module = "com.wix:accord-core_2.13", version.ref = "com-wix" } -wix-accord-scalatest-s213 = { module = "com.wix:accord-scalatest_2.13", version.ref = "com-wix" } +wix-accord-core-s213 = { module = "com.wix:accord-core_2.13", version.ref = "accord" } +wix-accord-scalatest-s213 = { module = "com.wix:accord-scalatest_2.13", version.ref = "accord" } [bundles] concordion = [ @@ -61,6 +107,11 @@ concordion = [ "concordion-collapse-output-extension", "concordion-embed-extension", ] +kotest = [ + "kotest-assertions-core-jvm", + "kotest-property-jvm", + "kotest-runner-junit-jvm", +] #scala-logging = ["typesafe-scala-logging-s213", "typesafe-config"] scala-wix = ["wix-accord-core-s213", "wix-accord-scalatest-s213"] diff --git a/include/ddo-avro/.gitattributes b/include/ddo-avro/.gitattributes new file mode 100644 index 00000000..00a51aff --- /dev/null +++ b/include/ddo-avro/.gitattributes @@ -0,0 +1,6 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf + diff --git a/include/ddo-avro/.gitignore b/include/ddo-avro/.gitignore new file mode 100644 index 00000000..1b6985c0 --- /dev/null +++ b/include/ddo-avro/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/include/ddo-avro/build.gradle.kts b/include/ddo-avro/build.gradle.kts new file mode 100644 index 00000000..f37b2ca3 --- /dev/null +++ b/include/ddo-avro/build.gradle.kts @@ -0,0 +1,249 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2015-2021 Andre White. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + scala + `java-library` +// id("scala-library-profile") +// id("djaxonomy.test-conventions") + id("com.zlad.gradle.avrohugger") +// id("com.github.lkishalmi.gatling") version "3.2.9" + // id("io.gatling.gradle") version "3.9.5.5" replaces above +// id("org.openapi.generator") +} + +repositories { + + mavenCentral() +} + +dependencies { + /* + https://github.com/fthomas/refined + check out refined library for compile time constraints + unsure how helpful this will be as most data will need runtime validation (aka wix) + */ + // Use Scala $scalaMajorVersion in our library project + implementation("org.scala-lang:scala-library:2.13.10") + +// val scalaLibraryVersion: String by project +// val scalaMajorVersion: String by project + +// implementation(enforcedPlatform(project(":ddo-platform-scala"))) +// implementation(libs.scala2.library) { +// version { +// strictly("2.13.10") +// } +// } +// implementation(libs.enumeratum.s213) +// implementation(libs.typesafe.config) +// implementation(libs.kxbmap.configs.s213) +// +// implementation(libs.json4s.native.s213) +// +// // validation and rules +// implementation(libs.wix.accord.core.s213) +// implementation(libs.logback.classic) +// implementation(libs.typesafe.scala.logging.s213) +// testImplementation(group = "org.scalatest", name = "scalatest_$scalaMajorVersion") +// testImplementation(group = "org.mockito", name = "mockito-core") +// +// // JUnit 5 +// testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-engine") +// testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-launcher") +// testRuntimeOnly(group = "co.helmethair", name = "scalatest-junit-runner") +} + +// OpenApi code / schema generation + +val apiSpec: FileCollection = project.rootProject.layout.files("$rootDir/specs/ddo-fatespinner-oas3-swagger.yaml") +// Location of Avro schema files +val schemaDir: FileCollection = layout.files("src/main/resources/schemas/avro") +// Location of ?? +// val generatedScalaSourceDir = layout.buildDirectory.files("src/main/avro") +val generatedScalaSourceDir = project.rootProject.layout.files("../../subprojects/common/ddo-modeling/build/avro-gen") +// /** +// * Api spec OpenAPI specification generation information +// * +// * @property spec Name of the specification +// * @property schemaDir Directory of schema files +// * @property generatedSrcDir destination for generated source code directory +// * @constructor a new instance +// */ +// data class ApiSpec( +// val spec: String, +// val schemaDir: String, +// val generatedSrcDir: String, +// ) +// +// /** +// * Package spec holds the basic header information for the API +// * +// * @property basePackage base java package i.e. com.acme +// * @property apiPackage package name for generated source. This will be appended to basePackage. +// * @property invokerPackage package name for invoker classes +// * @property modelPackage package name for entity models +// * @constructor Creates a new API specification +// */ +// @Suppress("CUSTOM_GETTERS_SETTERS", "NO_CORRESPONDING_PROPERTY") +// data class PackageSpec( +// val basePackage: String = "io.truthencode.ddo", +// val apiPackage: String = "api", +// val invokerPackage: String = "invoker", +// val modelPackage: String = "models.model", +// ) { +// /** +// * Api qualified api package name +// */ +// val api: String +// get() { +// return "$basePackage.$apiPackage" +// } +// +// /** +// * Invoker qualified invoker package +// */ +// val invoker: String +// get() { +// return "$basePackage.$invokerPackage" +// } +// +// /** +// * Model qualified model package +// * +// */ +// val model: String +// get() { +// return "$basePackage.$modelPackage" +// } +// } +// +// val defaultApiSpec = ApiSpec(apiSpec.asPath, schemaDir.asPath, generatedScalaSourceDir.asPath) +// // val defaultPackageSpec = +// // PackageSpec("io.truthencode.ddo.api","io.truthencode.ddo.invoker","io.truthencode.ddo.models.model") +// val schemas = +// mapOf("ddoModel" to defaultApiSpec, "parseHub" to defaultApiSpec.copy(spec = "$rootDir/specs/parsehub.yaml")) +// val specs = mapOf("parseHub" to PackageSpec(basePackage = "io.truthencode.ddo.etl.parsehub")) +// +// openApiValidate { +// inputSpec.set(apiSpec.asPath) +// } +// +avrohugger { + this.sourceDirectories { + this.from(schemaDir) + } + // TODO: Copy generated files to 'properly included build directory'. + // Likely ddo-modeling build directory + this.destinationDirectory.set(generatedScalaSourceDir.singleFile) + typeMapping { + protocolType = com.zlad.gradle.avrohugger.AvrohuggerExtension.ScalaADT + enumType = com.zlad.gradle.avrohugger.AvrohuggerExtension.ScalaCaseObjectEnum + } +} +// val schemaList = listOf("parseHub") +// +// // Create Tasks to generate Avro Schemas for our OpenAPI specs +// +// val genAvroSchemaTask = +// task("genAvroSchema") { +// this.group = "OpenAPI Tools" +// dependsOn("openApiValidate") +// } +// +// run { +// @Suppress("IDENTIFIER_LENGTH") +// schemaList.forEach { id -> +// val name = "genAvroSchema$id" +// tasks.create(name, org.openapitools.generator.gradle.plugin.tasks.GenerateTask::class).apply { +// generatorName.set("avro-schema") +// schemas[id]?.let { s -> +// inputSpec.set(s.spec) +// outputDir.set(s.schemaDir) +// } +// specs[id]?.let { p -> +// apiPackage.set(p.api) +// invokerPackage.set(p.invoker) +// modelPackage.set(p.model) +// } +// this.group = "OpenAPI Tools" +// dependsOn("openApiValidate") +// genAvroSchemaTask.dependsOn(this) +// } +// } +// } +// +// task("genModel", org.openapitools.generator.gradle.plugin.tasks.GenerateTask::class) { +// verbose.set(true) +// generatorName.set("scala-lagom-server") +// inputSpec.set(apiSpec.asPath) +// outputDir.set(layout.buildDirectory.dir("generated/lagom").get().asFile.path) +// +// apiPackage.set("io.truthencode.ddo.api") +// invokerPackage.set("io.truthencode.ddo.invoker") +// modelPackage.set("io.truthencode.ddo.models.model") +// } +// +// task("genGatling", org.openapitools.generator.gradle.plugin.tasks.GenerateTask::class) { +// verbose.set(true) +// val id = "scala-gatling" +// generatorName.set(id) +// inputSpec.set(apiSpec.asPath) +// outputDir.set(layout.buildDirectory.dir("generated/$id").get().asFile.path) +// +// apiPackage.set("io.truthencode.ddo.api") +// invokerPackage.set("io.truthencode.ddo.invoker") +// modelPackage.set("io.truthencode.ddo.models.model") +// } +// +// tasks.register("cleanAvroSchema") { +// description = "Clears generated Schemas Directory" +// group = "source generation" +// delete = setOf(schemaDir) +// } +// +// tasks.register("cleanGeneratedScala") { +// description = "Cleans generated scala directory" +// group = "source generation" +// delete = setOf(generatedScalaSourceDir) +// } +// +// val cleanTask = tasks.named("clean") +// +// if (cleanTask.isPresent) { +// cleanTask.get().dependsOn("cleanGeneratedScala") +// } +// +// tasks { +// // Use the built-in JUnit support of Gradle. +// "test"(Test::class) { +// useJUnitPlatform { +// includeEngines = setOf("scalatest") +// testLogging { +// events("passed", "skipped", "failed") +// } +// } +// } +// val sv = named("syncVersionFiles").get() +// // BUG: should not need to declare task dependencies when tasks use non-conflicting outputs +// val gas = named("generateAvroScala").get() +// gas.mustRunAfter(named("syncVersionFiles")) +// withType { +// mustRunAfter(gas) +// } +// } \ No newline at end of file diff --git a/include/ddo-avro/gradle.properties b/include/ddo-avro/gradle.properties new file mode 100644 index 00000000..74ac4791 --- /dev/null +++ b/include/ddo-avro/gradle.properties @@ -0,0 +1,7 @@ +# TODO: Replace with Catalog reference +#Avro related +avroHuggerPluginVersion = 0.7.0 +foojayResolverPluginVersionversion=0.4.0 + +# semver and deployment +mooltiverseNyxPluginVersion=1.0.1-fix81.1 \ No newline at end of file diff --git a/include/ddo-avro/settings.gradle.kts b/include/ddo-avro/settings.gradle.kts new file mode 100644 index 00000000..046ff96a --- /dev/null +++ b/include/ddo-avro/settings.gradle.kts @@ -0,0 +1,49 @@ + +rootProject.name = "ddo-avro-generator" + +pluginManagement { + // Scala + // Coverage +// val scoveragePluginVersion: String by settings + // Avro + val avroHuggerPluginVersion: String by settings +// val openApiGeneratorPluginVersion: String by settings + +// val kordampGradlePluginVersion: String by settings +// val semVerPluginVersion: String by settings + val mooltiverseNyxPluginVersion: String by settings + val foojayResolverPluginVersionversion: String by settings + + plugins { +// id("com.github.hierynomus.license") version "0.16.1" + id("com.zlad.gradle.avrohugger") version avroHuggerPluginVersion + // id("com.chudsaviet.gradle.avrohugger") version avroHuggerPluginVersion +// id("org.openapi.generator") version openApiGeneratorPluginVersion +// id("org.scoverage") version scoveragePluginVersion +// id("com.mooltiverse.oss.nyx") version mooltiverseNyxPluginVersion + id("org.gradle.toolchains.foojay-resolver-convention") version foojayResolverPluginVersionversion + +// id("org.kordamp.gradle.project") version kordampGradlePluginVersion +// id("net.thauvin.erik.gradle.semver") version semVerPluginVersion +// id("ru.vyarus.mkdocs") version "3.0.0" + } + + repositories { + gradlePluginPortal() + mavenCentral() + } +} + +plugins { +// id("com.mooltiverse.oss.nyx") + id("org.gradle.toolchains.foojay-resolver-convention") +} + +dependencyResolutionManagement { + versionCatalogs { + // declares an additional catalog, named 'testLibs', from the 'test-libs.versions.toml' file + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} \ No newline at end of file diff --git a/include/ddo-avro/src/main/backup/CriticalThreatRange.avsc b/include/ddo-avro/src/main/backup/CriticalThreatRange.avsc new file mode 100644 index 00000000..5e8fbef9 --- /dev/null +++ b/include/ddo-avro/src/main/backup/CriticalThreatRange.avsc @@ -0,0 +1,23 @@ +{ + "namespace": "model", + "type": "record", + "doc": "", + "name": "CriticalThreatRange", + "fields": [ + { + "name": "min", + "type": ["null", "int"], + "doc": "Lower bound for critical multiplier" + }, + { + "name": "max", + "type": ["null", "int"], + "doc": "Upper bound for critical multiplier" + }, + { + "name": "multiplier", + "type": ["null", "int"], + "doc": "Number to multiply the damage roll by" + } + ] +} diff --git a/include/ddo-avro/src/main/backup/Skill.avsc b/include/ddo-avro/src/main/backup/Skill.avsc new file mode 100644 index 00000000..46b8882a --- /dev/null +++ b/include/ddo-avro/src/main/backup/Skill.avsc @@ -0,0 +1,56 @@ +{ + "namespace": "model", + "type": "record", + "doc": "Specific skills such as haggling which are affected by a related ability score", + "name": "Skill", + "fields": [ + { + "name": "name", + "type": ["null", { + "type": "enum", + "name": "Skill_name", + "symbols": [ + "Balance", + "Bluff", + "Concentration", + "Diplomacy", + "Disable Device", + "Haggle", + "Heal", + "Hide", + "Intimidate", + "Jump", + "Listen", + "Move Silently", + "Open Lock", + "Perform", + "Repair", + "Search", + "Spellcraft", + "Spot", + "Swim", + "Tumble", + "Use Magic Device" + ] + }], + "doc": "Name of the skill" + }, + { + "name": "skillType", + "type": ["null", { + "type": "enum", + "name": "Skill_skillType", + "symbols": [ + "Passive", + "Active" + ] + }], + "doc": "Determines whether a skill is active or passive" + }, + { + "name": "RelatedAbility", + "type": ["null", "io.truthencode.ddo.models.model.Race"], + "doc": "" + } + ] +} diff --git a/include/ddo-avro/src/main/backup/Weapon.avsc b/include/ddo-avro/src/main/backup/Weapon.avsc new file mode 100644 index 00000000..28790c85 --- /dev/null +++ b/include/ddo-avro/src/main/backup/Weapon.avsc @@ -0,0 +1,285 @@ +{ + "namespace": "model", + "type": "record", + "doc": "", + "name": "Weapon", + "fields": [ + { + "name": "name", + "type": ["null", "string"], + "doc": "Name of the Item" + }, + { + "name": "proficiency_class", + "type": ["null", { + "type": "enum", + "name": "Weapon_proficiencyUnderscoreclass", + "symbols": [ + "Simple", + "Martial", + "Exotic" + ] + }], + "doc": "General Level of Martial training required to wield" + }, + { + "name": "image", + "type": ["null", "string"], + "doc": "Screen shot or image URI" + }, + { + "name": "damage", + "type": ["null", "io.truthencode.ddo.model.protocol.Damage"], + "doc": "" + }, + { + "name": "damage_type", + "type": ["null", "io.truthencode.ddo.model.protocol.DamageType"], + "doc": "" + }, + { + "name": "critical_threat_range", + "type": ["null", "io.truthencode.ddo.model.protocol.CriticalThreatRange"], + "doc": "" + }, + { + "name": "weapon_category", + "type": ["null", { + "type": "enum", + "name": "Weapon_weaponUnderscorecategory", + "symbols": [ + "BastardSword", + "BattleAxe", + "Club", + "Dagger", + "Dart", + "DwarvenWarAxe", + "Falchion", + "GreatAxe", + "GreatClub", + "GreatCrossbow", + "GreatSword", + "HandAxe", + "Handwrap", + "HeavyCrossbow", + "HeavyMace", + "HeavyPick", + "Kama", + "Khopesh", + "Kukris", + "LightCrossbow", + "LightHammer", + "LightMace", + "LightPick", + "Longbow", + "Longsword", + "Maul", + "Morningstar", + "Quarterstaff", + "Rapier", + "RepeatingHeavyCrossbow", + "RepeatingLightCrossbow", + "Scimitar", + "Shortbow", + "ShortSword", + "Shuriken", + "Sickle", + "SimpleProjectile", + "ThrowingAxe", + "ThrowingDagger", + "ThrowingHammer", + "WarHammer" + ] + }], + "doc": "The type of weapon such as long sword Axe etc" + }, + { + "name": "required_race", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Race required to use item without a UMD Check" + }, + { + "name": "abs_required_race", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Race absolutely required (no bypass) to use item" + }, + { + "name": "abs_restricted_race", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Races specifically not allowed to use" + }, + { + "name": "min_level", + "type": ["null", "int"], + "doc": "Minimum character level required to use item" + }, + { + "name": "abs_min_level", + "type": ["null", "int"], + "doc": "Altered minimum level usually caused as a side-effect of additional enchantments which may increase the requirement" + }, + { + "name": "required_trait", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Trait such as Lawful needed to use item" + }, + { + "name": "umd", + "type": ["null", "string"], + "doc": "Use Magical Device DC" + }, + { + "name": "handedness", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Allowed slots such as one handed (main or off hand) / two handed" + }, + { + "name": "attack_mod", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Attribute(s) that modify the attack roll" + }, + { + "name": "damage_mod", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Attribute(s) that modify the damage roll" + }, + { + "name": "binding", + "type": ["null", "string"], + "doc": "Character or Account binding, if any" + }, + { + "name": "durability", + "type": ["null", "int"], + "doc": "tensile strength, how hard it is to damage" + }, + { + "name": "wear_location", + "type": ["null", { + "type": "enum", + "name": "Weapon_wearUnderscorelocation", + "symbols": [ + "MainHand", + "OffHand", + "TwoHand" + ] + }], + "doc": "Allowed slots for the item to be equipped" + }, + { + "name": "material", + "type": ["null", { + "type": "enum", + "name": "Weapon_material", + "symbols": [ + "Adamantine", + "Blueshine", + "Bone", + "Byeshk", + "Cloth", + "Cold_Iron", + "Crystal", + "Darkleaf", + "Darkwood", + "Densewood", + "Dwarven_Iron", + "Feyleather", + "Flametouched_Iron", + "Flesh", + "Force", + "Gem", + "Glass", + "Ice", + "Leather", + "Light", + "Magesteel", + "Mithral", + "Planeforged_Steel", + "Rust", + "Silver", + "Spiritcraft_Leather", + "Spiritforged_Iron", + "Steel", + "Stone", + "Wood" + ] + }], + "doc": "material made from" + }, + { + "name": "hardness", + "type": ["null", "int"], + "doc": "physical toughness of the item" + }, + { + "name": "base_value", + "type": ["null", "string"], + "doc": "Monetary value of item" + }, + { + "name": "weight", + "type": ["null", "int"], + "doc": "weight in pounds" + }, + { + "name": "location", + "type": ["null", "string"], + "doc": "Text describing the location of the item" + }, + { + "name": "enchantments", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Collection of Enchantments on the item." + }, + { + "name": "enchantments_choice", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Used to support One of the following" + }, + { + "name": "upgradeable", + "type": ["null", "string"], + "doc": "If an item can be upgraded, instructions or the name of the upgraded item may appear here." + }, + { + "name": "description_text", + "type": ["null", "string"], + "doc": "descriptive text of the item" + }, + { + "name": "sets", + "type": ["null", { + "type": "array", + "items": "string" + }], + "doc": "Any sets this item belongs to that give bonuses when all items are equipped." + } + ] +} diff --git a/include/ddo-avro/src/main/java/io/truthencode/ddo/modeling/ModulePlaceHolder.java b/include/ddo-avro/src/main/java/io/truthencode/ddo/modeling/ModulePlaceHolder.java new file mode 100644 index 00000000..3ce512d6 --- /dev/null +++ b/include/ddo-avro/src/main/java/io/truthencode/ddo/modeling/ModulePlaceHolder.java @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2015-2021 Andre White. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.truthencode.ddo.modeling; + +public interface ModulePlaceHolder { +} diff --git a/include/ddo-avro/src/main/resources/schemas/avro/ChangeValueInt.avdl b/include/ddo-avro/src/main/resources/schemas/avro/ChangeValueInt.avdl new file mode 100644 index 00000000..392d0c68 --- /dev/null +++ b/include/ddo-avro/src/main/resources/schemas/avro/ChangeValueInt.avdl @@ -0,0 +1,11 @@ +@namespace("io.truthencode.ddo.model.protocol") +protocol ValueChange { + enum ChangeType {INCREASE, DECREASE, NOCHANGE} + + record ChangeValueInt { + string id; + int currentValue; + int prevValue; + ChangeType changeType; + } +} \ No newline at end of file diff --git a/include/ddo-avro/src/main/resources/schemas/avro/CriticalThreatRange.avdl b/include/ddo-avro/src/main/resources/schemas/avro/CriticalThreatRange.avdl new file mode 100644 index 00000000..e534eff6 --- /dev/null +++ b/include/ddo-avro/src/main/resources/schemas/avro/CriticalThreatRange.avdl @@ -0,0 +1,12 @@ +@namespace("io.truthencode.ddo.model.protocol.parsers") +protocol CriticalThreatRange { + /** */ + record CriticalThreatRange { + /** Lower bound for critical multiplier */ + int? min; + /** Upper bound for critical multiplier */ + int? max; + /** Number to multiply the damage roll by */ + int? multiplier; + } +} diff --git a/include/ddo-avro/src/main/resources/schemas/avro/DamageInfo.avdl b/include/ddo-avro/src/main/resources/schemas/avro/DamageInfo.avdl new file mode 100644 index 00000000..880f12cd --- /dev/null +++ b/include/ddo-avro/src/main/resources/schemas/avro/DamageInfo.avdl @@ -0,0 +1,16 @@ +@namespace("io.truthencode.ddo.model.protocol.parsers") +protocol DamageParserInfo { + /** A most basic encapsulation of damage information. */ + record DamageInfo { + /** Multiplier for the dice */ + union{null, int} dice_modifier; + /** Dice expression in the form of nDm */ + union{null, string} dice; + /** Additional Damage after the dice */ + union{null, int} extra; + /** Includes both Physical and Magical Damage types */ + DamageTrait damage_type; + } + + enum DamageTrait {Acid, Fire, Cold, Electric, Force, Sonic, Poison, Evil, Good, UnTyped, Special, Bludgeon, Pierce, Slash, Magic} +} diff --git a/include/ddo-avro/src/main/resources/schemas/avro/Weapon.avdl b/include/ddo-avro/src/main/resources/schemas/avro/Weapon.avdl new file mode 100644 index 00000000..789b2ceb --- /dev/null +++ b/include/ddo-avro/src/main/resources/schemas/avro/Weapon.avdl @@ -0,0 +1,82 @@ +@namespace("io.truthencode.ddo.model.protocol.parsers") +protocol WeaponInfo { + import idl "DamageInfo.avdl"; + import idl "CriticalThreatRange.avdl"; + + /** */ + record Weapon { + /** Name of the Item */ + string? name; + /** General Level of Martial training required to wield */ + Weapon_proficiencyUnderscoreclass? proficiency_class; + /** Screen shot or image URI */ + string? image; + DamageTrait? damage; + DamageInfo? damage_type; + CriticalThreatRange? critical_threat_range; + /** The type of weapon such as long sword Axe etc */ + Weapon_weaponUnderscorecategory? weapon_category; + /** Race required to use item without a UMD Check */ + union{null, array} required_race; + /** Race absolutely required (no bypass) to use item */ + union{null, array} abs_required_race; + /** Races specifically not allowed to use */ + union{null, array} abs_restricted_race; + /** Minimum character level required to use item */ + int? min_level; + /** Altered minimum level usually caused as a side-effect of additional enchantments which may increase the requirement */ + int? abs_min_level; + /** Trait such as Lawful needed to use item */ + union{null, array} required_trait; + /** Use Magical Device DC */ + string? umd; + /** Allowed slots such as one handed (main or off hand) / two handed */ + union{null, array} handedness; + /** Attribute(s) that modify the attack roll */ + union{null, array} attack_mod; + /** Attribute(s) that modify the damage roll */ + union{null, array} damage_mod; + /** Character or Account binding, if any */ + string? binding; + /** tensile strength, how hard it is to damage */ + int? durability; + /** Allowed slots for the item to be equipped */ + Weapon_wearUnderscorelocation? wear_location; + /** material made from */ + Weapon_material? material; + /** physical toughness of the item */ + int? hardness; + /** Monetary value of item */ + string? base_value; + /** weight in pounds */ + int? weight; + /** Text describing the location of the item */ + string? location; + /** Collection of Enchantments on the item. */ + union{null, array} enchantments; + /** Used to support One of the following */ + union{null, array} enchantments_choice; + /** If an item can be upgraded, instructions or the name of the upgraded item may appear here. */ + string? upgradeable; + /** descriptive text of the item */ + string? description_text; + /** Any sets this item belongs to that give bonuses when all items are equipped. */ + union{null, array} sets; + } + + enum Weapon_proficiencyUnderscoreclass {Simple, Martial, Exotic} + + enum Weapon_weaponUnderscorecategory { + BastardSword, BattleAxe, Club, Dagger, Dart, DwarvenWarAxe, Falchion, GreatAxe, GreatClub, GreatCrossbow, + GreatSword, HandAxe, Handwrap, HeavyCrossbow, HeavyMace, HeavyPick, Kama, Khopesh, Kukris, LightCrossbow, + LightHammer, LightMace, LightPick, Longbow, Longsword, Maul, Morningstar, Quarterstaff, Rapier, + RepeatingHeavyCrossbow, RepeatingLightCrossbow, Scimitar, Shortbow, ShortSword, Shuriken, Sickle, + SimpleProjectile, ThrowingAxe, ThrowingDagger, ThrowingHammer, WarHammer} + + enum Weapon_wearUnderscorelocation {MainHand, OffHand, TwoHand} + + enum Weapon_material { + Adamantine, Blueshine, Bone, Byeshk, Cloth, Cold_Iron, Crystal, Darkleaf, Darkwood, Densewood, Dwarven_Iron, + Feyleather, Flametouched_Iron, Flesh, Force, Gem, Glass, Ice, Leather, Light, Magesteel, Mithral, + Planeforged_Steel, Rust, Silver, Spiritcraft_Leather, Spiritforged_Iron, Steel, Stone, Wood} +} diff --git a/include/ddo-avro/src/test/resources/sampledata/10pageweaponclubsnap.json b/include/ddo-avro/src/test/resources/sampledata/10pageweaponclubsnap.json new file mode 100644 index 00000000..ec68a767 --- /dev/null +++ b/include/ddo-avro/src/test/resources/sampledata/10pageweaponclubsnap.json @@ -0,0 +1,577 @@ +{ + "item": [ + { + "weapon": [ + { + "name": "Madstone Rod", + "damangeAndType": "1d6 + 1 Bludgeon, Magic", + "minLevel": "1", + "binding": "Unbound", + "quest": "Gianthold Tor, At the end of each dragon fight", + "criticalProfile": "", + "enchantments": "+1 Enhancement Bonus", + "enchantments_url": "https://ddowiki.com/page/Enhancement_bonus", + "errata": "", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Madstone Rod", + "damangeAndType": "No", + "criticalThreatRange": "1d6 + 1 Bludgeon, Magic", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "Wizard, Sorcerer, Bard", + "handedness": "Can't be UMD'd", + "damageMod": "STR", + "durability": "Unbound", + "hardness": "Wood", + "baseValue": "13", + "weight": "1cp", + "upgradable": "+1 Enhancement Bonus\nDispel Madstone Effects — 50 Charges\nMythic Weapon Boost +2 or +4", + "enchantments": [ + { + "enchantment": [ + { + "name": "+1 Enhancement Bonus", + "name_url": "https://ddowiki.com/page/Enhancement_bonus", + "fullText": "+1 Enhancement Bonus" + } + ] + }, + { + "enchantment": [ + { + "name": "Dispel Madstone Effects", + "name_url": "https://ddowiki.com/page/Dispel_Madstone_Effects", + "fullText": "—" + } + ] + }, + { + "enchantment": [ + { + "name": "Mythic Weapon Boost", + "name_url": "https://ddowiki.com/page/Mythic_Boost", + "fullText": "Mythic Weapon Boost +2 or +4" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + }, + { + "enchantment": [ + { + "fullText": "Stormreaver", + "fullText_url": "https://ddowiki.com/page/Stormreaver" + } + ] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Scepter of Siberys", + "damangeAndType": "1 + 0 Bludgeon", + "minLevel": "1", + "binding": "Unbound", + "quest": "Special event items, Hide and Seek", + "criticalProfile": "", + "enchantments": "Use Magic Device +1", + "enchantments_url": "https://ddowiki.com/page/Use_Magic_Device", + "errata": "", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Scepter of Siberys", + "damangeAndType": "Yes", + "criticalThreatRange": "1 + 0 Bludgeon", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "None", + "handedness": "No UMD needed", + "damageMod": "STR", + "durability": "Unbound", + "hardness": "None", + "baseValue": "Unbreakable", + "weight": "1cp", + "upgradable": "Use Magic Device +1\nMythic Weapon Boost +2 or +4", + "enchantments": [ + { + "enchantment": [ + { + "name": "Use Magic Device +1", + "name_url": "https://ddowiki.com/page/Use_Magic_Device", + "fullText": "Use Magic Device +1" + } + ] + }, + { + "enchantment": [ + { + "name": "Mythic Weapon Boost", + "name_url": "https://ddowiki.com/page/Mythic_Boost", + "fullText": "Mythic Weapon Boost +2 or +4" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Bouquet of Flowers", + "damangeAndType": "[1d2] + 0, Slash", + "minLevel": "1", + "binding": "Bound to Character on Equip", + "quest": "DDO Store, general buffs", + "criticalProfile": "Damage Modifier: CHA\nAttack Modifier: CHA", + "enchantments": "Good Hope", + "enchantments_url": "https://ddowiki.com/page/Good_Hope", + "errata": "Damage Modifier: CHA\nAttack Modifier: CHA", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Bouquet of Flowers", + "damangeAndType": "No", + "criticalThreatRange": "[1d2] + 0, Slash", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "None", + "handedness": "No UMD needed", + "damageMod": "CHA", + "durability": "Bound to Character on Equip", + "hardness": "Wood", + "baseValue": "8", + "weight": "1cp", + "upgradable": "Good Hope — 20 Charges", + "enchantments": [ + { + "enchantment": [ + { + "name": "Good Hope", + "name_url": "https://ddowiki.com/page/Good_Hope", + "fullText": "—" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Rod of Greater Teleport", + "damangeAndType": "[1d6] +1 Bludgeoning, Magic", + "minLevel": "1", + "binding": "Bound to Account on Acquire", + "quest": "DDO Store, Fast Travel", + "criticalProfile": "", + "enchantments": "+2 Enhancement Bonus", + "enchantments_url": "https://ddowiki.com/page/Enhancement_bonus", + "errata": "", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Rod of Greater Teleport", + "damangeAndType": "No", + "criticalThreatRange": "[1d6] +1 Bludgeoning, Magic", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "None", + "handedness": "No UMD needed", + "damageMod": "STR", + "durability": "Bound to Account on Acquire", + "hardness": "Wood", + "baseValue": "9", + "weight": "1cp", + "upgradable": "+2 Enhancement Bonus\nGreater Teleport — 50 Charges (Recharged/Day:0)\nMythic Weapon Boost +2 or +4", + "tips": [ + { + "tip": "Greater Teleport" + } + ], + "enchantments": [ + { + "enchantment": [ + { + "name": "+2 Enhancement Bonus", + "name_url": "https://ddowiki.com/page/Enhancement_bonus", + "fullText": "+2 Enhancement Bonus" + } + ] + }, + { + "enchantment": [ + { + "name": "Greater Teleport", + "name_url": "https://ddowiki.com/page/Greater_Teleport", + "fullText": "—" + } + ] + }, + { + "enchantment": [ + { + "name": "Mythic Weapon Boost", + "name_url": "https://ddowiki.com/page/Mythic_Boost", + "fullText": "Mythic Weapon Boost +2 or +4" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Wayfinder's Scepter", + "damangeAndType": "[1] + 0 Bludgeon", + "minLevel": "1", + "binding": "Unbound", + "quest": "Special event items, Item Finding Reward", + "criticalProfile": "", + "enchantments": "Search +1", + "enchantments_url": "https://ddowiki.com/page/Search", + "errata": "", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Wayfinder's Scepter", + "damangeAndType": "Yes", + "criticalThreatRange": "[1] + 0 Bludgeon", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "None", + "handedness": "No UMD needed", + "damageMod": "STR", + "durability": "Unbound", + "hardness": "Wood", + "baseValue": "Unbreakable", + "weight": "1cp", + "upgradable": "Search +1", + "enchantments": [ + { + "enchantment": [ + { + "name": "Search +1", + "name_url": "https://ddowiki.com/page/Search", + "fullText": "Search +1" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + }, + { + "enchantment": [{}] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Romag's Club of Earthen Dominion", + "damangeAndType": "[1d6] +0 Bludgeon", + "minLevel": "1", + "binding": "Unbound, Drops on leaving adventure", + "quest": "Temple of Elemental Evil Part One, Romag's Chamber or Prison chest", + "criticalProfile": "", + "errata": "", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Romag's Club of Earthen Dominion", + "damangeAndType": "No", + "criticalThreatRange": "[1d6] +0 Bludgeon", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "None", + "handedness": "No UMD needed", + "damageMod": "STR", + "durability": "Unbound, Drops on leaving adventure", + "hardness": "Wood", + "baseValue": "5", + "weight": "1cp", + "upgradable": "Mastery over Earth Elementals", + "enchantments": [ + { + "enchantment": [ + { + "fullText": "Mastery over Earth Elementals" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Short Broom of Mystery", + "damangeAndType": "[1d6] +0 Bludgeoning", + "minLevel": "1", + "binding": "Bound to Account on Acquire, Exclusive", + "quest": "The Night Revels", + "criticalProfile": "", + "enchantments": "Purple Faerie Fire", + "enchantments_url": "https://ddowiki.com/page/Purple_Faerie_Fire", + "errata": "", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Short Broom of Mystery", + "damangeAndType": "No", + "criticalThreatRange": "[1d6] +0 Bludgeoning", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "None", + "handedness": "No UMD needed", + "damageMod": "STR", + "durability": "Bound to Account on Acquire, Exclusive", + "hardness": "Wood", + "baseValue": "5", + "weight": "20pp", + "upgradable": "Purple Faerie Fire — 3 Charges (Recharged/Day:1)", + "enchantments": [ + { + "enchantment": [ + { + "name": "Purple Faerie Fire", + "name_url": "https://ddowiki.com/page/Purple_Faerie_Fire", + "fullText": "—" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + }, + { + "enchantment": [{}] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Smoldering Cudgel", + "damangeAndType": "[1d6] + 0 Bludgeon", + "minLevel": "1", + "binding": "Unbound, Drops on death", + "quest": "Ghost of a Chance, Found in Fire Pit", + "criticalProfile": "", + "enchantments": "Fire Touch", + "enchantments_url": "https://ddowiki.com/page/Fire_Touch", + "errata": "", + "weaponDetail": [ + { + "proficiency": "Simple Weapon Proficiency", + "name": "Smoldering Cudgel", + "damangeAndType": "No", + "criticalThreatRange": "[1d6] + 0 Bludgeon", + "weaponType": [ + { + "damageCategory": "20 / x2" + } + ], + "absRaceRequired": "Club / Bludgeoning weapons", + "minLevel": "None", + "requiredTrait": "None", + "umd": "None", + "handedness": "No UMD needed", + "damageMod": "STR", + "durability": "Unbound, Drops on death", + "hardness": "Wood", + "baseValue": "6", + "weight": "1cp", + "upgradable": "Fire Touch\nSpot -5\nCommand +2\nPerform +1", + "enchantments": [ + { + "enchantment": [ + { + "name": "Fire Touch", + "name_url": "https://ddowiki.com/page/Fire_Touch", + "fullText": "Fire Touch" + } + ] + }, + { + "enchantment": [ + { + "name": "Spot -5", + "name_url": "https://ddowiki.com/page/Spot", + "fullText": "Spot -5" + } + ] + }, + { + "enchantment": [ + { + "name": "Command +2", + "name_url": "https://ddowiki.com/page/Command_(enchantment)", + "fullText": "Command +2" + } + ] + }, + { + "enchantment": [ + { + "name": "Perform +1", + "name_url": "https://ddowiki.com/page/Perform", + "fullText": "Perform +1" + } + ] + }, + { + "enchantment": [ + { + "fullText": "This item cannot be fed to sentient jewels." + } + ] + }, + { + "enchantment": [ + { + "fullText": "Brekik", + "fullText_url": "https://ddowiki.com/page/Brekik" + } + ] + } + ], + "locationInformation": [{}] + } + ] + } + ] + }, + { + "weapon": [ + { + "name": "Rod of Teleport", + "damangeAndType": "[1d6] +1 Bludgeoning, Magic", + "minLevel": "1", + "quest": "Anniversary Card Collection", + "criticalProfile": "", + "enchantments": "+1 Enhancement Bonus", + "enchantments_url": "https://ddowiki.com/page/Enhancement_bonus", + "errata": "" + } + ] + } + ] +} diff --git a/incubating/amqp-quickstart-producer/.dockerignore b/incubating/amqp-quickstart-producer/.dockerignore new file mode 100644 index 00000000..4361d2fb --- /dev/null +++ b/incubating/amqp-quickstart-producer/.dockerignore @@ -0,0 +1,5 @@ +* +!build/*-runner +!build/*-runner.jar +!build/lib/* +!build/quarkus-app/* \ No newline at end of file diff --git a/incubating/amqp-quickstart-producer/.gitignore b/incubating/amqp-quickstart-producer/.gitignore new file mode 100644 index 00000000..216783d7 --- /dev/null +++ b/incubating/amqp-quickstart-producer/.gitignore @@ -0,0 +1,39 @@ +# Gradle +.gradle/ +build/ + +# Eclipse +.project +.classpath +.settings/ +bin/ + +# IntelliJ +.idea +*.ipr +*.iml +*.iws + +# NetBeans +nb-configuration.xml + +# Visual Studio Code +.vscode +.factorypath + +# OSX +.DS_Store + +# Vim +*.swp +*.swo + +# patch +*.orig +*.rej + +# Local environment +.env + +# Plugin directory +/.quarkus/cli/plugins/ diff --git a/incubating/amqp-quickstart-producer/README.md b/incubating/amqp-quickstart-producer/README.md new file mode 100644 index 00000000..711140a4 --- /dev/null +++ b/incubating/amqp-quickstart-producer/README.md @@ -0,0 +1,58 @@ +# amqp-quickstart-producer + +This project uses Quarkus, the Supersonic Subatomic Java Framework. + +If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ . + +## Running the application in dev mode + +You can run your application in dev mode that enables live coding using: + +```shell script +./gradlew quarkusDev +``` + +> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. + +## Packaging and running the application + +The application can be packaged using: + +```shell script +./gradlew build +``` + +It produces the `quarkus-run.jar` file in the `build/quarkus-app/` directory. +Be aware that it’s not an _über-jar_ as the dependencies are copied into the `build/quarkus-app/lib/` directory. + +The application is now runnable using `java -jar build/quarkus-app/quarkus-run.jar`. + +If you want to build an _über-jar_, execute the following command: + +```shell script +./gradlew build -Dquarkus.package.type=uber-jar +``` + +The application, packaged as an _über-jar_, is now runnable using `java -jar build/*-runner.jar`. + +## Creating a native executable + +You can create a native executable using: + +```shell script +./gradlew build -Dquarkus.package.type=native +``` + +Or, if you don't have GraalVM installed, you can run the native executable build in a container using: + +```shell script +./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true +``` + +You can then execute your native executable with: `./build/amqp-quickstart-producer-1.0.0-SNAPSHOT-runner` + +If you want to learn more about building native executables, please consult https://quarkus.io/guides/gradle-tooling. + +## Related Guides + +- SmallRye Reactive Messaging - AMQP Connector ([guide](https://quarkus.io/guides/amqp)): Connect to AMQP with Reactive Messaging diff --git a/incubating/amqp-quickstart-producer/build.gradle.kts b/incubating/amqp-quickstart-producer/build.gradle.kts new file mode 100644 index 00000000..5a5a0f37 --- /dev/null +++ b/incubating/amqp-quickstart-producer/build.gradle.kts @@ -0,0 +1,37 @@ +plugins { + java + id("io.quarkus") +} + +repositories { + mavenCentral() + mavenLocal() +} + +val quarkusPlatformGroupId: String by project +val quarkusPlatformArtifactId: String by project +val quarkusPlatformVersion: String by project + +dependencies { + implementation(enforcedPlatform("$quarkusPlatformGroupId:$quarkusPlatformArtifactId:$quarkusPlatformVersion")) + implementation("io.quarkus:quarkus-smallrye-reactive-messaging-amqp") + implementation("io.quarkus:quarkus-resteasy-reactive-jackson") + implementation("io.quarkus:quarkus-arc") + testImplementation("io.quarkus:quarkus-junit5") +} + +group = "org.acme" +version = "1.0.0-SNAPSHOT" + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +tasks.withType { + systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager") +} +tasks.withType { + options.encoding = "UTF-8" + options.compilerArgs.add("-parameters") +} \ No newline at end of file diff --git a/incubating/amqp-quickstart-producer/gradle.properties b/incubating/amqp-quickstart-producer/gradle.properties new file mode 100644 index 00000000..6dcf8d7f --- /dev/null +++ b/incubating/amqp-quickstart-producer/gradle.properties @@ -0,0 +1,6 @@ +#Gradle properties +quarkusPluginId=io.quarkus +quarkusPluginVersion=3.3.3 +quarkusPlatformGroupId=io.quarkus.platform +quarkusPlatformArtifactId=quarkus-bom +quarkusPlatformVersion=3.3.3 \ No newline at end of file diff --git a/incubating/amqp-quickstart-producer/gradle/wrapper/gradle-wrapper.jar b/incubating/amqp-quickstart-producer/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..62d4c053 Binary files /dev/null and b/incubating/amqp-quickstart-producer/gradle/wrapper/gradle-wrapper.jar differ diff --git a/incubating/amqp-quickstart-producer/gradle/wrapper/gradle-wrapper.properties b/incubating/amqp-quickstart-producer/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..db9a6b82 --- /dev/null +++ b/incubating/amqp-quickstart-producer/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/incubating/amqp-quickstart-producer/gradlew b/incubating/amqp-quickstart-producer/gradlew new file mode 100755 index 00000000..fda12f76 --- /dev/null +++ b/incubating/amqp-quickstart-producer/gradlew @@ -0,0 +1,184 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ]; do + ls=$(ls -ld "$PRG") + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then + PRG="$link" + else + PRG=$(dirname "$PRG")"/$link" + fi +done +SAVED="$(pwd)" +cd "$(dirname \"$PRG\")/" >/dev/null +APP_HOME="$(pwd -P)" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=$(basename "$0") + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn() { + echo "$*" +} + +die() { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$(uname)" in +CYGWIN*) + cygwin=true + ;; +Darwin*) + darwin=true + ;; +MINGW*) + msys=true + ;; +NONSTOP*) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ]; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then + MAX_FD_LIMIT=$(ulimit -H -n) + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; then + APP_HOME=$(cygpath --path --mixed "$APP_HOME") + CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") + + JAVACMD=$(cygpath --unix "$JAVACMD") + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) + SEP="" + for dir in $ROOTDIRSRAW; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ]; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@"; do + CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) + CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition + eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") + else + eval $(echo args$i)="\"$arg\"" + fi + i=$(expr $i + 1) + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save() { + for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/incubating/amqp-quickstart-producer/gradlew.bat b/incubating/amqp-quickstart-producer/gradlew.bat new file mode 100644 index 00000000..5093609d --- /dev/null +++ b/incubating/amqp-quickstart-producer/gradlew.bat @@ -0,0 +1,104 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/incubating/amqp-quickstart-producer/settings.gradle.kts b/incubating/amqp-quickstart-producer/settings.gradle.kts new file mode 100644 index 00000000..0990139d --- /dev/null +++ b/incubating/amqp-quickstart-producer/settings.gradle.kts @@ -0,0 +1,13 @@ +pluginManagement { + val quarkusPluginVersion: String by settings + val quarkusPluginId: String by settings + repositories { + mavenCentral() + gradlePluginPortal() + mavenLocal() + } + plugins { + id(quarkusPluginId) version quarkusPluginVersion + } +} +rootProject.name = "amqp-quickstart-producer" \ No newline at end of file diff --git a/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.jvm b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.jvm new file mode 100644 index 00000000..952d1a75 --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.jvm @@ -0,0 +1,97 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./gradlew build +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/amqp-quickstart-producer-jvm . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/amqp-quickstart-producer-jvm +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/amqp-quickstart-producer-jvm +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.16 + +ENV LANGUAGE='en_US:en' + + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --chown=185 build/quarkus-app/lib/ /deployments/lib/ +COPY --chown=185 build/quarkus-app/*.jar /deployments/ +COPY --chown=185 build/quarkus-app/app/ /deployments/app/ +COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] + diff --git a/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.legacy-jar b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.legacy-jar new file mode 100644 index 00000000..cc8e5b51 --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.legacy-jar @@ -0,0 +1,93 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./gradlew build -Dquarkus.package.type=legacy-jar +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/amqp-quickstart-producer-legacy-jar . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/amqp-quickstart-producer-legacy-jar +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/amqp-quickstart-producer-legacy-jar +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.16 + +ENV LANGUAGE='en_US:en' + + +COPY build/lib/* /deployments/lib/ +COPY build/*-runner.jar /deployments/quarkus-run.jar + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] diff --git a/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.native b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.native new file mode 100644 index 00000000..2a7836cb --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.native @@ -0,0 +1,27 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# +# Before building the container image run: +# +# ./gradlew build -Dquarkus.package.type=native +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native -t quarkus/amqp-quickstart-producer . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/amqp-quickstart-producer +# +### +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root build/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.native-micro b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.native-micro new file mode 100644 index 00000000..0f55bd8b --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/docker/Dockerfile.native-micro @@ -0,0 +1,30 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# It uses a micro base image, tuned for Quarkus native executables. +# It reduces the size of the resulting container image. +# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. +# +# Before building the container image run: +# +# ./gradlew build -Dquarkus.package.type=native +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/amqp-quickstart-producer . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/amqp-quickstart-producer +# +### +FROM quay.io/quarkus/quarkus-micro-image:2.0 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root build/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/model/Quote.java b/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/model/Quote.java new file mode 100644 index 00000000..8d7202da --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/model/Quote.java @@ -0,0 +1,28 @@ +package io.truthcode.amqp.model; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +@RegisterForReflection +public class Quote { + + public String id; + public int price; + + /** + * Default constructor required for Jackson serializer + */ + public Quote() { } + + public Quote(String id, int price) { + this.id = id; + this.price = price; + } + + @Override + public String toString() { + return "Quote{" + + "id='" + id + '\'' + + ", price=" + price + + '}'; + } +} \ No newline at end of file diff --git a/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/processor/QuoteProcessor.java b/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/processor/QuoteProcessor.java new file mode 100644 index 00000000..e4e24fb1 --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/processor/QuoteProcessor.java @@ -0,0 +1,30 @@ +package io.truthcode.amqp.processor; + + +import io.smallrye.reactive.messaging.annotations.Blocking; +import io.truthcode.amqp.model.Quote; +import jakarta.enterprise.context.ApplicationScoped; + +import org.eclipse.microprofile.reactive.messaging.Incoming; +import org.eclipse.microprofile.reactive.messaging.Outgoing; + +import java.util.Random; + +/** + * A bean consuming data from the "request" AMQP queue and giving out a random quote. + * The result is pushed to the "quotes" AMQP queue. + */ +@ApplicationScoped +public class QuoteProcessor { + + private Random random = new Random(); + + @Incoming("requests") + @Outgoing("quotes") + @Blocking + public Quote process(String quoteRequest) throws InterruptedException { + // simulate some hard-working task + Thread.sleep(200); + return new Quote(quoteRequest, random.nextInt(100)); + } +} \ No newline at end of file diff --git a/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/producer/QuotesResource.java b/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/producer/QuotesResource.java new file mode 100644 index 00000000..e2ac3649 --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/java/io/truthcode/amqp/producer/QuotesResource.java @@ -0,0 +1,47 @@ +package io.truthcode.amqp.producer; + + +import java.util.UUID; + +import io.truthcode.amqp.model.Quote; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + + +import org.eclipse.microprofile.reactive.messaging.Channel; +import org.eclipse.microprofile.reactive.messaging.Emitter; + +import io.smallrye.mutiny.Multi; + +@Path("/quotes") +public class QuotesResource { + + @Channel("quote-requests") Emitter quoteRequestEmitter; + + + + @Channel("quotes") Multi quotes; + + /** + * Endpoint retrieving the "quotes" queue and sending the items to a server sent event. + */ + @GET + @Produces(MediaType.SERVER_SENT_EVENTS) + public Multi stream() { + return quotes; + } + /** + * Endpoint to generate a new quote request id and send it to "quote-requests" AMQP queue using the emitter. + */ + @POST + @Path("/request") + @Produces(MediaType.TEXT_PLAIN) + public String createRequest() { + UUID uuid = UUID.randomUUID(); + quoteRequestEmitter.send(uuid.toString()); + return uuid.toString(); + } +} diff --git a/incubating/amqp-quickstart-producer/src/main/resources/META-INF/resources/quotes.html b/incubating/amqp-quickstart-producer/src/main/resources/META-INF/resources/quotes.html new file mode 100644 index 00000000..b0aeedae --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/resources/META-INF/resources/quotes.html @@ -0,0 +1,49 @@ + + + + + Quotes + + + + + +
+
+
+

Quotes

+ +
+
+
+
+ + + + diff --git a/incubating/amqp-quickstart-producer/src/main/resources/application.properties b/incubating/amqp-quickstart-producer/src/main/resources/application.properties new file mode 100644 index 00000000..138f285b --- /dev/null +++ b/incubating/amqp-quickstart-producer/src/main/resources/application.properties @@ -0,0 +1 @@ +mp.messaging.incoming.requests.address=quote-requests \ No newline at end of file diff --git a/incubating/ddo-antlr/mkdocs.yml b/incubating/ddo-antlr/mkdocs.yml deleted file mode 100644 index ec81cbc5..00000000 --- a/incubating/ddo-antlr/mkdocs.yml +++ /dev/null @@ -1,11 +0,0 @@ -site_name: Parsing - -# Meta tags (placed in header) -site_description: Core DDO Objects - -nav: - - Home: index.md - - User guide: - - Installation: guide/installation.md - - About: - - Release notes: about/history.md \ No newline at end of file diff --git a/incubating/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 b/incubating/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 deleted file mode 100644 index fd51e059..00000000 --- a/incubating/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 +++ /dev/null @@ -1,41 +0,0 @@ -lexer grammar EnchantmentsLexer; - -LineBreak - : ('\r'? '\n' - | '\r') -> skip - ; - - -//VALIDID : ENCHANTMENT | UNKNOWN_ID; - -//prefixedDecl : NUM ENCHANTMENT | ENCHANTMENT PCT | ENCHANTMENT + NUM | ENCHANTMENT; - -// Known, named enchantments -ENCHANTMENT : FORT | AUGMENTSLOT | ENHANCEMENT_BONUS | SHELTERING; - -AUGMENTSLOT : AUGMENTCOLOR ' ' LBL_AUGMENT_SLOT ' ' AUGMENTOPTION; -LBL_AUGMENT_SLOT : 'Augment Slot:'; -ENHANCEMENT_BONUS : 'Enhancement Bonus'; -FORT : 'Fortification'; -SHELTERING : SHELTERTYPE ' ' 'Sheltering'; -SHELTERTYPE : 'Physical and Magical' | 'Physical' | 'Magical'; -AUGMENTCOLOR : 'Blue' | 'Orange' | 'Yellow' | 'Red' | 'Green' | 'Purple' | 'Colorless'; -AUGMENTOPTION: EmptyAugmentSlot | FilledAugmentSlot; - -FilledAugmentSlot: 'todo:MARKER '; // can be empty or filled with any named or crafted augment -EmptyAugmentSlot: 'Empty'; -//r : 'hello' ID ; // match keyword hello followed by an identifier -//ID : [a-zA-Z]+ ; // match lower-case identifiers -WS : [ \t\r\n]+ -> channel(HIDDEN) ; // skip spaces, tabs, newlines -PCT : NUM + '%'; // SIGNED percent -NUM : SIGN + UNUM; // signed num - -SIGN : '+' | '-'; -fragment UNUM : [0-9]+; // unsigned numbers - - -// catch-all word blobs MUST LIST AFTER OTHER RULES -UNKNOWN_ID : MULTI_WORDS | SIMPLE_WORD | MULTI_WORD; -fragment MULTI_WORDS : MULTI_WORD + (' ' + SIMPLE_WORD); -fragment MULTI_WORD: SIMPLE_WORD + ' ' + SIMPLE_WORD; -fragment SIMPLE_WORD: [A-Za-z] + [a-z]+; diff --git a/incubating/ddo-antlr/src/main/antlr/EnchantmentsParser.g4 b/incubating/ddo-antlr/src/main/antlr/EnchantmentsParser.g4 deleted file mode 100644 index 0dcb7aef..00000000 --- a/incubating/ddo-antlr/src/main/antlr/EnchantmentsParser.g4 +++ /dev/null @@ -1,18 +0,0 @@ -parser grammar EnchantmentsParser; - -@header { package io.truthencode.ddo.grammar.antlar; } - -options { tokenVocab = EnchantmentsLexer; } - -parse returns [List row] -@init { - $row = new ArrayList(); -} - : (idDecl {$row.add($idDecl.text);})+ (LineBreak | EOF) - ; - -//thing : PCT ENCHANTMENT; - -idDecl : PCT enchantmentType | enchantmentType PCT | NUM enchantmentType | enchantmentType NUM | enchantmentType; - -enchantmentType : (ENCHANTMENT | UNKNOWN_ID); \ No newline at end of file diff --git a/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.interp b/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.interp deleted file mode 100644 index a48cc5bf..00000000 --- a/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.interp +++ /dev/null @@ -1,72 +0,0 @@ -token literal names: -null -null -null -null -'Augment Slot:' -'Enhancement Bonus' -'Fortification' -null -null -null -null -'todo:MARKER ' -'Empty' -null -null -null -null -null - -token symbolic names: -null -LineBreak -ENCHANTMENT -AUGMENTSLOT -LBL_AUGMENT_SLOT -ENHANCEMENT_BONUS -FORT -SHELTERING -SHELTERTYPE -AUGMENTCOLOR -AUGMENTOPTION -FilledAugmentSlot -EmptyAugmentSlot -WS -PCT -NUM -SIGN -UNKNOWN_ID - -rule names: -LineBreak -ENCHANTMENT -AUGMENTSLOT -LBL_AUGMENT_SLOT -ENHANCEMENT_BONUS -FORT -SHELTERING -SHELTERTYPE -AUGMENTCOLOR -AUGMENTOPTION -FilledAugmentSlot -EmptyAugmentSlot -WS -PCT -NUM -SIGN -UNUM -UNKNOWN_ID -MULTI_WORDS -MULTI_WORD -SIMPLE_WORD - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[4, 0, 17, 291, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 1, 0, 3, 0, 45, 8, 0, 1, 0, 1, 0, 3, 0, 49, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 57, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 159, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 200, 8, 8, 1, 9, 1, 9, 3, 9, 204, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 4, 12, 226, 8, 12, 11, 12, 12, 12, 227, 1, 12, 1, 12, 1, 13, 4, 13, 233, 8, 13, 11, 13, 12, 13, 234, 1, 13, 1, 13, 1, 14, 4, 14, 240, 8, 14, 11, 14, 12, 14, 241, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 4, 16, 249, 8, 16, 11, 16, 12, 16, 250, 1, 17, 1, 17, 1, 17, 3, 17, 256, 8, 17, 1, 18, 4, 18, 259, 8, 18, 11, 18, 12, 18, 260, 1, 18, 4, 18, 264, 8, 18, 11, 18, 12, 18, 265, 1, 18, 1, 18, 1, 19, 4, 19, 271, 8, 19, 11, 19, 12, 19, 272, 1, 19, 4, 19, 276, 8, 19, 11, 19, 12, 19, 277, 1, 19, 1, 19, 1, 20, 4, 20, 283, 8, 20, 11, 20, 12, 20, 284, 1, 20, 4, 20, 288, 8, 20, 11, 20, 12, 20, 289, 0, 0, 21, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 0, 35, 17, 37, 0, 39, 0, 41, 0, 1, 0, 5, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 43, 43, 45, 45, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 1, 0, 97, 122, 312, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 1, 48, 1, 0, 0, 0, 3, 56, 1, 0, 0, 0, 5, 58, 1, 0, 0, 0, 7, 64, 1, 0, 0, 0, 9, 78, 1, 0, 0, 0, 11, 96, 1, 0, 0, 0, 13, 110, 1, 0, 0, 0, 15, 158, 1, 0, 0, 0, 17, 199, 1, 0, 0, 0, 19, 203, 1, 0, 0, 0, 21, 205, 1, 0, 0, 0, 23, 218, 1, 0, 0, 0, 25, 225, 1, 0, 0, 0, 27, 232, 1, 0, 0, 0, 29, 239, 1, 0, 0, 0, 31, 245, 1, 0, 0, 0, 33, 248, 1, 0, 0, 0, 35, 255, 1, 0, 0, 0, 37, 258, 1, 0, 0, 0, 39, 270, 1, 0, 0, 0, 41, 282, 1, 0, 0, 0, 43, 45, 5, 13, 0, 0, 44, 43, 1, 0, 0, 0, 44, 45, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 49, 5, 10, 0, 0, 47, 49, 5, 13, 0, 0, 48, 44, 1, 0, 0, 0, 48, 47, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 51, 6, 0, 0, 0, 51, 2, 1, 0, 0, 0, 52, 57, 3, 11, 5, 0, 53, 57, 3, 5, 2, 0, 54, 57, 3, 9, 4, 0, 55, 57, 3, 13, 6, 0, 56, 52, 1, 0, 0, 0, 56, 53, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 56, 55, 1, 0, 0, 0, 57, 4, 1, 0, 0, 0, 58, 59, 3, 17, 8, 0, 59, 60, 5, 32, 0, 0, 60, 61, 3, 7, 3, 0, 61, 62, 5, 32, 0, 0, 62, 63, 3, 19, 9, 0, 63, 6, 1, 0, 0, 0, 64, 65, 5, 65, 0, 0, 65, 66, 5, 117, 0, 0, 66, 67, 5, 103, 0, 0, 67, 68, 5, 109, 0, 0, 68, 69, 5, 101, 0, 0, 69, 70, 5, 110, 0, 0, 70, 71, 5, 116, 0, 0, 71, 72, 5, 32, 0, 0, 72, 73, 5, 83, 0, 0, 73, 74, 5, 108, 0, 0, 74, 75, 5, 111, 0, 0, 75, 76, 5, 116, 0, 0, 76, 77, 5, 58, 0, 0, 77, 8, 1, 0, 0, 0, 78, 79, 5, 69, 0, 0, 79, 80, 5, 110, 0, 0, 80, 81, 5, 104, 0, 0, 81, 82, 5, 97, 0, 0, 82, 83, 5, 110, 0, 0, 83, 84, 5, 99, 0, 0, 84, 85, 5, 101, 0, 0, 85, 86, 5, 109, 0, 0, 86, 87, 5, 101, 0, 0, 87, 88, 5, 110, 0, 0, 88, 89, 5, 116, 0, 0, 89, 90, 5, 32, 0, 0, 90, 91, 5, 66, 0, 0, 91, 92, 5, 111, 0, 0, 92, 93, 5, 110, 0, 0, 93, 94, 5, 117, 0, 0, 94, 95, 5, 115, 0, 0, 95, 10, 1, 0, 0, 0, 96, 97, 5, 70, 0, 0, 97, 98, 5, 111, 0, 0, 98, 99, 5, 114, 0, 0, 99, 100, 5, 116, 0, 0, 100, 101, 5, 105, 0, 0, 101, 102, 5, 102, 0, 0, 102, 103, 5, 105, 0, 0, 103, 104, 5, 99, 0, 0, 104, 105, 5, 97, 0, 0, 105, 106, 5, 116, 0, 0, 106, 107, 5, 105, 0, 0, 107, 108, 5, 111, 0, 0, 108, 109, 5, 110, 0, 0, 109, 12, 1, 0, 0, 0, 110, 111, 3, 15, 7, 0, 111, 112, 5, 32, 0, 0, 112, 113, 5, 83, 0, 0, 113, 114, 5, 104, 0, 0, 114, 115, 5, 101, 0, 0, 115, 116, 5, 108, 0, 0, 116, 117, 5, 116, 0, 0, 117, 118, 5, 101, 0, 0, 118, 119, 5, 114, 0, 0, 119, 120, 5, 105, 0, 0, 120, 121, 5, 110, 0, 0, 121, 122, 5, 103, 0, 0, 122, 14, 1, 0, 0, 0, 123, 124, 5, 80, 0, 0, 124, 125, 5, 104, 0, 0, 125, 126, 5, 121, 0, 0, 126, 127, 5, 115, 0, 0, 127, 128, 5, 105, 0, 0, 128, 129, 5, 99, 0, 0, 129, 130, 5, 97, 0, 0, 130, 131, 5, 108, 0, 0, 131, 132, 5, 32, 0, 0, 132, 133, 5, 97, 0, 0, 133, 134, 5, 110, 0, 0, 134, 135, 5, 100, 0, 0, 135, 136, 5, 32, 0, 0, 136, 137, 5, 77, 0, 0, 137, 138, 5, 97, 0, 0, 138, 139, 5, 103, 0, 0, 139, 140, 5, 105, 0, 0, 140, 141, 5, 99, 0, 0, 141, 142, 5, 97, 0, 0, 142, 159, 5, 108, 0, 0, 143, 144, 5, 80, 0, 0, 144, 145, 5, 104, 0, 0, 145, 146, 5, 121, 0, 0, 146, 147, 5, 115, 0, 0, 147, 148, 5, 105, 0, 0, 148, 149, 5, 99, 0, 0, 149, 150, 5, 97, 0, 0, 150, 159, 5, 108, 0, 0, 151, 152, 5, 77, 0, 0, 152, 153, 5, 97, 0, 0, 153, 154, 5, 103, 0, 0, 154, 155, 5, 105, 0, 0, 155, 156, 5, 99, 0, 0, 156, 157, 5, 97, 0, 0, 157, 159, 5, 108, 0, 0, 158, 123, 1, 0, 0, 0, 158, 143, 1, 0, 0, 0, 158, 151, 1, 0, 0, 0, 159, 16, 1, 0, 0, 0, 160, 161, 5, 66, 0, 0, 161, 162, 5, 108, 0, 0, 162, 163, 5, 117, 0, 0, 163, 200, 5, 101, 0, 0, 164, 165, 5, 79, 0, 0, 165, 166, 5, 114, 0, 0, 166, 167, 5, 97, 0, 0, 167, 168, 5, 110, 0, 0, 168, 169, 5, 103, 0, 0, 169, 200, 5, 101, 0, 0, 170, 171, 5, 89, 0, 0, 171, 172, 5, 101, 0, 0, 172, 173, 5, 108, 0, 0, 173, 174, 5, 108, 0, 0, 174, 175, 5, 111, 0, 0, 175, 200, 5, 119, 0, 0, 176, 177, 5, 82, 0, 0, 177, 178, 5, 101, 0, 0, 178, 200, 5, 100, 0, 0, 179, 180, 5, 71, 0, 0, 180, 181, 5, 114, 0, 0, 181, 182, 5, 101, 0, 0, 182, 183, 5, 101, 0, 0, 183, 200, 5, 110, 0, 0, 184, 185, 5, 80, 0, 0, 185, 186, 5, 117, 0, 0, 186, 187, 5, 114, 0, 0, 187, 188, 5, 112, 0, 0, 188, 189, 5, 108, 0, 0, 189, 200, 5, 101, 0, 0, 190, 191, 5, 67, 0, 0, 191, 192, 5, 111, 0, 0, 192, 193, 5, 108, 0, 0, 193, 194, 5, 111, 0, 0, 194, 195, 5, 114, 0, 0, 195, 196, 5, 108, 0, 0, 196, 197, 5, 101, 0, 0, 197, 198, 5, 115, 0, 0, 198, 200, 5, 115, 0, 0, 199, 160, 1, 0, 0, 0, 199, 164, 1, 0, 0, 0, 199, 170, 1, 0, 0, 0, 199, 176, 1, 0, 0, 0, 199, 179, 1, 0, 0, 0, 199, 184, 1, 0, 0, 0, 199, 190, 1, 0, 0, 0, 200, 18, 1, 0, 0, 0, 201, 204, 3, 23, 11, 0, 202, 204, 3, 21, 10, 0, 203, 201, 1, 0, 0, 0, 203, 202, 1, 0, 0, 0, 204, 20, 1, 0, 0, 0, 205, 206, 5, 116, 0, 0, 206, 207, 5, 111, 0, 0, 207, 208, 5, 100, 0, 0, 208, 209, 5, 111, 0, 0, 209, 210, 5, 58, 0, 0, 210, 211, 5, 77, 0, 0, 211, 212, 5, 65, 0, 0, 212, 213, 5, 82, 0, 0, 213, 214, 5, 75, 0, 0, 214, 215, 5, 69, 0, 0, 215, 216, 5, 82, 0, 0, 216, 217, 5, 32, 0, 0, 217, 22, 1, 0, 0, 0, 218, 219, 5, 69, 0, 0, 219, 220, 5, 109, 0, 0, 220, 221, 5, 112, 0, 0, 221, 222, 5, 116, 0, 0, 222, 223, 5, 121, 0, 0, 223, 24, 1, 0, 0, 0, 224, 226, 7, 0, 0, 0, 225, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 225, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 230, 6, 12, 1, 0, 230, 26, 1, 0, 0, 0, 231, 233, 3, 29, 14, 0, 232, 231, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 232, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 237, 5, 37, 0, 0, 237, 28, 1, 0, 0, 0, 238, 240, 3, 31, 15, 0, 239, 238, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 244, 3, 33, 16, 0, 244, 30, 1, 0, 0, 0, 245, 246, 7, 1, 0, 0, 246, 32, 1, 0, 0, 0, 247, 249, 7, 2, 0, 0, 248, 247, 1, 0, 0, 0, 249, 250, 1, 0, 0, 0, 250, 248, 1, 0, 0, 0, 250, 251, 1, 0, 0, 0, 251, 34, 1, 0, 0, 0, 252, 256, 3, 37, 18, 0, 253, 256, 3, 41, 20, 0, 254, 256, 3, 39, 19, 0, 255, 252, 1, 0, 0, 0, 255, 253, 1, 0, 0, 0, 255, 254, 1, 0, 0, 0, 256, 36, 1, 0, 0, 0, 257, 259, 3, 39, 19, 0, 258, 257, 1, 0, 0, 0, 259, 260, 1, 0, 0, 0, 260, 258, 1, 0, 0, 0, 260, 261, 1, 0, 0, 0, 261, 263, 1, 0, 0, 0, 262, 264, 5, 32, 0, 0, 263, 262, 1, 0, 0, 0, 264, 265, 1, 0, 0, 0, 265, 263, 1, 0, 0, 0, 265, 266, 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 268, 3, 41, 20, 0, 268, 38, 1, 0, 0, 0, 269, 271, 3, 41, 20, 0, 270, 269, 1, 0, 0, 0, 271, 272, 1, 0, 0, 0, 272, 270, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 275, 1, 0, 0, 0, 274, 276, 5, 32, 0, 0, 275, 274, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 275, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 280, 3, 41, 20, 0, 280, 40, 1, 0, 0, 0, 281, 283, 7, 3, 0, 0, 282, 281, 1, 0, 0, 0, 283, 284, 1, 0, 0, 0, 284, 282, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 1, 0, 0, 0, 286, 288, 7, 4, 0, 0, 287, 286, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 287, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 42, 1, 0, 0, 0, 18, 0, 44, 48, 56, 158, 199, 203, 227, 234, 241, 250, 255, 260, 265, 272, 277, 284, 289, 2, 6, 0, 0, 0, 1, 0] \ No newline at end of file diff --git a/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.java b/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.java deleted file mode 100644 index 008f924f..00000000 --- a/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.java +++ /dev/null @@ -1,307 +0,0 @@ -// Generated from /home/adarro/IdeaProjects/ddo-calc/incubating/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 by ANTLR 4.10.1 -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class EnchantmentsLexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.10.1", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - LineBreak=1, ENCHANTMENT=2, AUGMENTSLOT=3, LBL_AUGMENT_SLOT=4, ENHANCEMENT_BONUS=5, - FORT=6, SHELTERING=7, SHELTERTYPE=8, AUGMENTCOLOR=9, AUGMENTOPTION=10, - FilledAugmentSlot=11, EmptyAugmentSlot=12, WS=13, PCT=14, NUM=15, SIGN=16, - UNKNOWN_ID=17; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE" - }; - - private static String[] makeRuleNames() { - return new String[] { - "LineBreak", "ENCHANTMENT", "AUGMENTSLOT", "LBL_AUGMENT_SLOT", "ENHANCEMENT_BONUS", - "FORT", "SHELTERING", "SHELTERTYPE", "AUGMENTCOLOR", "AUGMENTOPTION", - "FilledAugmentSlot", "EmptyAugmentSlot", "WS", "PCT", "NUM", "SIGN", - "UNUM", "UNKNOWN_ID", "MULTI_WORDS", "MULTI_WORD", "SIMPLE_WORD" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, null, null, null, "'Augment Slot:'", "'Enhancement Bonus'", "'Fortification'", - null, null, null, null, "'todo:MARKER '", "'Empty'" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "LineBreak", "ENCHANTMENT", "AUGMENTSLOT", "LBL_AUGMENT_SLOT", - "ENHANCEMENT_BONUS", "FORT", "SHELTERING", "SHELTERTYPE", "AUGMENTCOLOR", - "AUGMENTOPTION", "FilledAugmentSlot", "EmptyAugmentSlot", "WS", "PCT", - "NUM", "SIGN", "UNKNOWN_ID" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public EnchantmentsLexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "EnchantmentsLexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - public static final String _serializedATN = - "\u0004\u0000\u0011\u0123\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+ - "\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+ - "\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+ - "\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+ - "\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+ - "\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+ - "\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+ - "\u0001\u0000\u0003\u0000-\b\u0000\u0001\u0000\u0001\u0000\u0003\u0000"+ - "1\b\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001"+ - "\u0001\u0001\u0003\u00019\b\u0001\u0001\u0002\u0001\u0002\u0001\u0002"+ - "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003"+ - "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ - "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004"+ - "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ - "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ - "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005"+ - "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ - "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ - "\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ - "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ - "\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0003\u0007\u009f\b\u0007\u0001\b\u0001\b\u0001\b\u0001\b"+ - "\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+ - "\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+ - "\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+ - "\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0003"+ - "\b\u00c8\b\b\u0001\t\u0001\t\u0003\t\u00cc\b\t\u0001\n\u0001\n\u0001\n"+ - "\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+ - "\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\f\u0004\f\u00e2\b\f\u000b\f\f\f\u00e3\u0001\f\u0001"+ - "\f\u0001\r\u0004\r\u00e9\b\r\u000b\r\f\r\u00ea\u0001\r\u0001\r\u0001\u000e"+ - "\u0004\u000e\u00f0\b\u000e\u000b\u000e\f\u000e\u00f1\u0001\u000e\u0001"+ - "\u000e\u0001\u000f\u0001\u000f\u0001\u0010\u0004\u0010\u00f9\b\u0010\u000b"+ - "\u0010\f\u0010\u00fa\u0001\u0011\u0001\u0011\u0001\u0011\u0003\u0011\u0100"+ - "\b\u0011\u0001\u0012\u0004\u0012\u0103\b\u0012\u000b\u0012\f\u0012\u0104"+ - "\u0001\u0012\u0004\u0012\u0108\b\u0012\u000b\u0012\f\u0012\u0109\u0001"+ - "\u0012\u0001\u0012\u0001\u0013\u0004\u0013\u010f\b\u0013\u000b\u0013\f"+ - "\u0013\u0110\u0001\u0013\u0004\u0013\u0114\b\u0013\u000b\u0013\f\u0013"+ - "\u0115\u0001\u0013\u0001\u0013\u0001\u0014\u0004\u0014\u011b\b\u0014\u000b"+ - "\u0014\f\u0014\u011c\u0001\u0014\u0004\u0014\u0120\b\u0014\u000b\u0014"+ - "\f\u0014\u0121\u0000\u0000\u0015\u0001\u0001\u0003\u0002\u0005\u0003\u0007"+ - "\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b"+ - "\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0000#\u0011%\u0000"+ - "\'\u0000)\u0000\u0001\u0000\u0005\u0003\u0000\t\n\r\r \u0002\u0000++"+ - "--\u0001\u000009\u0002\u0000AZaz\u0001\u0000az\u0138\u0000\u0001\u0001"+ - "\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001"+ - "\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000"+ - "\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000"+ - "\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011\u0001\u0000\u0000"+ - "\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000"+ - "\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000"+ - "\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000"+ - "\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000"+ - "\u00010\u0001\u0000\u0000\u0000\u00038\u0001\u0000\u0000\u0000\u0005:"+ - "\u0001\u0000\u0000\u0000\u0007@\u0001\u0000\u0000\u0000\tN\u0001\u0000"+ - "\u0000\u0000\u000b`\u0001\u0000\u0000\u0000\rn\u0001\u0000\u0000\u0000"+ - "\u000f\u009e\u0001\u0000\u0000\u0000\u0011\u00c7\u0001\u0000\u0000\u0000"+ - "\u0013\u00cb\u0001\u0000\u0000\u0000\u0015\u00cd\u0001\u0000\u0000\u0000"+ - "\u0017\u00da\u0001\u0000\u0000\u0000\u0019\u00e1\u0001\u0000\u0000\u0000"+ - "\u001b\u00e8\u0001\u0000\u0000\u0000\u001d\u00ef\u0001\u0000\u0000\u0000"+ - "\u001f\u00f5\u0001\u0000\u0000\u0000!\u00f8\u0001\u0000\u0000\u0000#\u00ff"+ - "\u0001\u0000\u0000\u0000%\u0102\u0001\u0000\u0000\u0000\'\u010e\u0001"+ - "\u0000\u0000\u0000)\u011a\u0001\u0000\u0000\u0000+-\u0005\r\u0000\u0000"+ - ",+\u0001\u0000\u0000\u0000,-\u0001\u0000\u0000\u0000-.\u0001\u0000\u0000"+ - "\u0000.1\u0005\n\u0000\u0000/1\u0005\r\u0000\u00000,\u0001\u0000\u0000"+ - "\u00000/\u0001\u0000\u0000\u000012\u0001\u0000\u0000\u000023\u0006\u0000"+ - "\u0000\u00003\u0002\u0001\u0000\u0000\u000049\u0003\u000b\u0005\u0000"+ - "59\u0003\u0005\u0002\u000069\u0003\t\u0004\u000079\u0003\r\u0006\u0000"+ - "84\u0001\u0000\u0000\u000085\u0001\u0000\u0000\u000086\u0001\u0000\u0000"+ - "\u000087\u0001\u0000\u0000\u00009\u0004\u0001\u0000\u0000\u0000:;\u0003"+ - "\u0011\b\u0000;<\u0005 \u0000\u0000<=\u0003\u0007\u0003\u0000=>\u0005"+ - " \u0000\u0000>?\u0003\u0013\t\u0000?\u0006\u0001\u0000\u0000\u0000@A\u0005"+ - "A\u0000\u0000AB\u0005u\u0000\u0000BC\u0005g\u0000\u0000CD\u0005m\u0000"+ - "\u0000DE\u0005e\u0000\u0000EF\u0005n\u0000\u0000FG\u0005t\u0000\u0000"+ - "GH\u0005 \u0000\u0000HI\u0005S\u0000\u0000IJ\u0005l\u0000\u0000JK\u0005"+ - "o\u0000\u0000KL\u0005t\u0000\u0000LM\u0005:\u0000\u0000M\b\u0001\u0000"+ - "\u0000\u0000NO\u0005E\u0000\u0000OP\u0005n\u0000\u0000PQ\u0005h\u0000"+ - "\u0000QR\u0005a\u0000\u0000RS\u0005n\u0000\u0000ST\u0005c\u0000\u0000"+ - "TU\u0005e\u0000\u0000UV\u0005m\u0000\u0000VW\u0005e\u0000\u0000WX\u0005"+ - "n\u0000\u0000XY\u0005t\u0000\u0000YZ\u0005 \u0000\u0000Z[\u0005B\u0000"+ - "\u0000[\\\u0005o\u0000\u0000\\]\u0005n\u0000\u0000]^\u0005u\u0000\u0000"+ - "^_\u0005s\u0000\u0000_\n\u0001\u0000\u0000\u0000`a\u0005F\u0000\u0000"+ - "ab\u0005o\u0000\u0000bc\u0005r\u0000\u0000cd\u0005t\u0000\u0000de\u0005"+ - "i\u0000\u0000ef\u0005f\u0000\u0000fg\u0005i\u0000\u0000gh\u0005c\u0000"+ - "\u0000hi\u0005a\u0000\u0000ij\u0005t\u0000\u0000jk\u0005i\u0000\u0000"+ - "kl\u0005o\u0000\u0000lm\u0005n\u0000\u0000m\f\u0001\u0000\u0000\u0000"+ - "no\u0003\u000f\u0007\u0000op\u0005 \u0000\u0000pq\u0005S\u0000\u0000q"+ - "r\u0005h\u0000\u0000rs\u0005e\u0000\u0000st\u0005l\u0000\u0000tu\u0005"+ - "t\u0000\u0000uv\u0005e\u0000\u0000vw\u0005r\u0000\u0000wx\u0005i\u0000"+ - "\u0000xy\u0005n\u0000\u0000yz\u0005g\u0000\u0000z\u000e\u0001\u0000\u0000"+ - "\u0000{|\u0005P\u0000\u0000|}\u0005h\u0000\u0000}~\u0005y\u0000\u0000"+ - "~\u007f\u0005s\u0000\u0000\u007f\u0080\u0005i\u0000\u0000\u0080\u0081"+ - "\u0005c\u0000\u0000\u0081\u0082\u0005a\u0000\u0000\u0082\u0083\u0005l"+ - "\u0000\u0000\u0083\u0084\u0005 \u0000\u0000\u0084\u0085\u0005a\u0000\u0000"+ - "\u0085\u0086\u0005n\u0000\u0000\u0086\u0087\u0005d\u0000\u0000\u0087\u0088"+ - "\u0005 \u0000\u0000\u0088\u0089\u0005M\u0000\u0000\u0089\u008a\u0005a"+ - "\u0000\u0000\u008a\u008b\u0005g\u0000\u0000\u008b\u008c\u0005i\u0000\u0000"+ - "\u008c\u008d\u0005c\u0000\u0000\u008d\u008e\u0005a\u0000\u0000\u008e\u009f"+ - "\u0005l\u0000\u0000\u008f\u0090\u0005P\u0000\u0000\u0090\u0091\u0005h"+ - "\u0000\u0000\u0091\u0092\u0005y\u0000\u0000\u0092\u0093\u0005s\u0000\u0000"+ - "\u0093\u0094\u0005i\u0000\u0000\u0094\u0095\u0005c\u0000\u0000\u0095\u0096"+ - "\u0005a\u0000\u0000\u0096\u009f\u0005l\u0000\u0000\u0097\u0098\u0005M"+ - "\u0000\u0000\u0098\u0099\u0005a\u0000\u0000\u0099\u009a\u0005g\u0000\u0000"+ - "\u009a\u009b\u0005i\u0000\u0000\u009b\u009c\u0005c\u0000\u0000\u009c\u009d"+ - "\u0005a\u0000\u0000\u009d\u009f\u0005l\u0000\u0000\u009e{\u0001\u0000"+ - "\u0000\u0000\u009e\u008f\u0001\u0000\u0000\u0000\u009e\u0097\u0001\u0000"+ - "\u0000\u0000\u009f\u0010\u0001\u0000\u0000\u0000\u00a0\u00a1\u0005B\u0000"+ - "\u0000\u00a1\u00a2\u0005l\u0000\u0000\u00a2\u00a3\u0005u\u0000\u0000\u00a3"+ - "\u00c8\u0005e\u0000\u0000\u00a4\u00a5\u0005O\u0000\u0000\u00a5\u00a6\u0005"+ - "r\u0000\u0000\u00a6\u00a7\u0005a\u0000\u0000\u00a7\u00a8\u0005n\u0000"+ - "\u0000\u00a8\u00a9\u0005g\u0000\u0000\u00a9\u00c8\u0005e\u0000\u0000\u00aa"+ - "\u00ab\u0005Y\u0000\u0000\u00ab\u00ac\u0005e\u0000\u0000\u00ac\u00ad\u0005"+ - "l\u0000\u0000\u00ad\u00ae\u0005l\u0000\u0000\u00ae\u00af\u0005o\u0000"+ - "\u0000\u00af\u00c8\u0005w\u0000\u0000\u00b0\u00b1\u0005R\u0000\u0000\u00b1"+ - "\u00b2\u0005e\u0000\u0000\u00b2\u00c8\u0005d\u0000\u0000\u00b3\u00b4\u0005"+ - "G\u0000\u0000\u00b4\u00b5\u0005r\u0000\u0000\u00b5\u00b6\u0005e\u0000"+ - "\u0000\u00b6\u00b7\u0005e\u0000\u0000\u00b7\u00c8\u0005n\u0000\u0000\u00b8"+ - "\u00b9\u0005P\u0000\u0000\u00b9\u00ba\u0005u\u0000\u0000\u00ba\u00bb\u0005"+ - "r\u0000\u0000\u00bb\u00bc\u0005p\u0000\u0000\u00bc\u00bd\u0005l\u0000"+ - "\u0000\u00bd\u00c8\u0005e\u0000\u0000\u00be\u00bf\u0005C\u0000\u0000\u00bf"+ - "\u00c0\u0005o\u0000\u0000\u00c0\u00c1\u0005l\u0000\u0000\u00c1\u00c2\u0005"+ - "o\u0000\u0000\u00c2\u00c3\u0005r\u0000\u0000\u00c3\u00c4\u0005l\u0000"+ - "\u0000\u00c4\u00c5\u0005e\u0000\u0000\u00c5\u00c6\u0005s\u0000\u0000\u00c6"+ - "\u00c8\u0005s\u0000\u0000\u00c7\u00a0\u0001\u0000\u0000\u0000\u00c7\u00a4"+ - "\u0001\u0000\u0000\u0000\u00c7\u00aa\u0001\u0000\u0000\u0000\u00c7\u00b0"+ - "\u0001\u0000\u0000\u0000\u00c7\u00b3\u0001\u0000\u0000\u0000\u00c7\u00b8"+ - "\u0001\u0000\u0000\u0000\u00c7\u00be\u0001\u0000\u0000\u0000\u00c8\u0012"+ - "\u0001\u0000\u0000\u0000\u00c9\u00cc\u0003\u0017\u000b\u0000\u00ca\u00cc"+ - "\u0003\u0015\n\u0000\u00cb\u00c9\u0001\u0000\u0000\u0000\u00cb\u00ca\u0001"+ - "\u0000\u0000\u0000\u00cc\u0014\u0001\u0000\u0000\u0000\u00cd\u00ce\u0005"+ - "t\u0000\u0000\u00ce\u00cf\u0005o\u0000\u0000\u00cf\u00d0\u0005d\u0000"+ - "\u0000\u00d0\u00d1\u0005o\u0000\u0000\u00d1\u00d2\u0005:\u0000\u0000\u00d2"+ - "\u00d3\u0005M\u0000\u0000\u00d3\u00d4\u0005A\u0000\u0000\u00d4\u00d5\u0005"+ - "R\u0000\u0000\u00d5\u00d6\u0005K\u0000\u0000\u00d6\u00d7\u0005E\u0000"+ - "\u0000\u00d7\u00d8\u0005R\u0000\u0000\u00d8\u00d9\u0005 \u0000\u0000\u00d9"+ - "\u0016\u0001\u0000\u0000\u0000\u00da\u00db\u0005E\u0000\u0000\u00db\u00dc"+ - "\u0005m\u0000\u0000\u00dc\u00dd\u0005p\u0000\u0000\u00dd\u00de\u0005t"+ - "\u0000\u0000\u00de\u00df\u0005y\u0000\u0000\u00df\u0018\u0001\u0000\u0000"+ - "\u0000\u00e0\u00e2\u0007\u0000\u0000\u0000\u00e1\u00e0\u0001\u0000\u0000"+ - "\u0000\u00e2\u00e3\u0001\u0000\u0000\u0000\u00e3\u00e1\u0001\u0000\u0000"+ - "\u0000\u00e3\u00e4\u0001\u0000\u0000\u0000\u00e4\u00e5\u0001\u0000\u0000"+ - "\u0000\u00e5\u00e6\u0006\f\u0001\u0000\u00e6\u001a\u0001\u0000\u0000\u0000"+ - "\u00e7\u00e9\u0003\u001d\u000e\u0000\u00e8\u00e7\u0001\u0000\u0000\u0000"+ - "\u00e9\u00ea\u0001\u0000\u0000\u0000\u00ea\u00e8\u0001\u0000\u0000\u0000"+ - "\u00ea\u00eb\u0001\u0000\u0000\u0000\u00eb\u00ec\u0001\u0000\u0000\u0000"+ - "\u00ec\u00ed\u0005%\u0000\u0000\u00ed\u001c\u0001\u0000\u0000\u0000\u00ee"+ - "\u00f0\u0003\u001f\u000f\u0000\u00ef\u00ee\u0001\u0000\u0000\u0000\u00f0"+ - "\u00f1\u0001\u0000\u0000\u0000\u00f1\u00ef\u0001\u0000\u0000\u0000\u00f1"+ - "\u00f2\u0001\u0000\u0000\u0000\u00f2\u00f3\u0001\u0000\u0000\u0000\u00f3"+ - "\u00f4\u0003!\u0010\u0000\u00f4\u001e\u0001\u0000\u0000\u0000\u00f5\u00f6"+ - "\u0007\u0001\u0000\u0000\u00f6 \u0001\u0000\u0000\u0000\u00f7\u00f9\u0007"+ - "\u0002\u0000\u0000\u00f8\u00f7\u0001\u0000\u0000\u0000\u00f9\u00fa\u0001"+ - "\u0000\u0000\u0000\u00fa\u00f8\u0001\u0000\u0000\u0000\u00fa\u00fb\u0001"+ - "\u0000\u0000\u0000\u00fb\"\u0001\u0000\u0000\u0000\u00fc\u0100\u0003%"+ - "\u0012\u0000\u00fd\u0100\u0003)\u0014\u0000\u00fe\u0100\u0003\'\u0013"+ - "\u0000\u00ff\u00fc\u0001\u0000\u0000\u0000\u00ff\u00fd\u0001\u0000\u0000"+ - "\u0000\u00ff\u00fe\u0001\u0000\u0000\u0000\u0100$\u0001\u0000\u0000\u0000"+ - "\u0101\u0103\u0003\'\u0013\u0000\u0102\u0101\u0001\u0000\u0000\u0000\u0103"+ - "\u0104\u0001\u0000\u0000\u0000\u0104\u0102\u0001\u0000\u0000\u0000\u0104"+ - "\u0105\u0001\u0000\u0000\u0000\u0105\u0107\u0001\u0000\u0000\u0000\u0106"+ - "\u0108\u0005 \u0000\u0000\u0107\u0106\u0001\u0000\u0000\u0000\u0108\u0109"+ - "\u0001\u0000\u0000\u0000\u0109\u0107\u0001\u0000\u0000\u0000\u0109\u010a"+ - "\u0001\u0000\u0000\u0000\u010a\u010b\u0001\u0000\u0000\u0000\u010b\u010c"+ - "\u0003)\u0014\u0000\u010c&\u0001\u0000\u0000\u0000\u010d\u010f\u0003)"+ - "\u0014\u0000\u010e\u010d\u0001\u0000\u0000\u0000\u010f\u0110\u0001\u0000"+ - "\u0000\u0000\u0110\u010e\u0001\u0000\u0000\u0000\u0110\u0111\u0001\u0000"+ - "\u0000\u0000\u0111\u0113\u0001\u0000\u0000\u0000\u0112\u0114\u0005 \u0000"+ - "\u0000\u0113\u0112\u0001\u0000\u0000\u0000\u0114\u0115\u0001\u0000\u0000"+ - "\u0000\u0115\u0113\u0001\u0000\u0000\u0000\u0115\u0116\u0001\u0000\u0000"+ - "\u0000\u0116\u0117\u0001\u0000\u0000\u0000\u0117\u0118\u0003)\u0014\u0000"+ - "\u0118(\u0001\u0000\u0000\u0000\u0119\u011b\u0007\u0003\u0000\u0000\u011a"+ - "\u0119\u0001\u0000\u0000\u0000\u011b\u011c\u0001\u0000\u0000\u0000\u011c"+ - "\u011a\u0001\u0000\u0000\u0000\u011c\u011d\u0001\u0000\u0000\u0000\u011d"+ - "\u011f\u0001\u0000\u0000\u0000\u011e\u0120\u0007\u0004\u0000\u0000\u011f"+ - "\u011e\u0001\u0000\u0000\u0000\u0120\u0121\u0001\u0000\u0000\u0000\u0121"+ - "\u011f\u0001\u0000\u0000\u0000\u0121\u0122\u0001\u0000\u0000\u0000\u0122"+ - "*\u0001\u0000\u0000\u0000\u0012\u0000,08\u009e\u00c7\u00cb\u00e3\u00ea"+ - "\u00f1\u00fa\u00ff\u0104\u0109\u0110\u0115\u011c\u0121\u0002\u0006\u0000"+ - "\u0000\u0000\u0001\u0000"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.tokens b/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.tokens deleted file mode 100644 index 1f157da0..00000000 --- a/incubating/ddo-antlr/src/main/gen/EnchantmentsLexer.tokens +++ /dev/null @@ -1,22 +0,0 @@ -LineBreak=1 -ENCHANTMENT=2 -AUGMENTSLOT=3 -LBL_AUGMENT_SLOT=4 -ENHANCEMENT_BONUS=5 -FORT=6 -SHELTERING=7 -SHELTERTYPE=8 -AUGMENTCOLOR=9 -AUGMENTOPTION=10 -FilledAugmentSlot=11 -EmptyAugmentSlot=12 -WS=13 -PCT=14 -NUM=15 -SIGN=16 -UNKNOWN_ID=17 -'Augment Slot:'=4 -'Enhancement Bonus'=5 -'Fortification'=6 -'todo:MARKER '=11 -'Empty'=12 diff --git a/incubating/ddo-antlr/src/test/kotlin/BasicTest.kt b/incubating/ddo-antlr/src/test/kotlin/BasicTest.kt deleted file mode 100644 index bbab9132..00000000 --- a/incubating/ddo-antlr/src/test/kotlin/BasicTest.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.truthencode.ddo.grammar.antlr - -open class BasicTest { - fun doSomething(): String { - return "Okies" - } - - fun hasRef() { - var p: EnchantmentsParser - } -} \ No newline at end of file diff --git a/incubating/poc-scala-quarkus/README.md b/incubating/poc-scala-quarkus/README.md new file mode 100644 index 00000000..aeb4232b --- /dev/null +++ b/incubating/poc-scala-quarkus/README.md @@ -0,0 +1,64 @@ +# code-with-quarkus + +This project uses Quarkus, the Supersonic Subatomic Java Framework. + +If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ . + +## Running the application in dev mode + +You can run your application in dev mode that enables live coding using: + +```shell script +./gradlew quarkusDev +``` + +> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. + +## Packaging and running the application + +The application can be packaged using: + +```shell script +./gradlew build +``` + +It produces the `quarkus-run.jar` file in the `build/quarkus-app/` directory. +Be aware that it’s not an _über-jar_ as the dependencies are copied into the `build/quarkus-app/lib/` directory. + +The application is now runnable using `java -jar build/quarkus-app/quarkus-run.jar`. + +If you want to build an _über-jar_, execute the following command: + +```shell script +./gradlew build -Dquarkus.package.type=uber-jar +``` + +The application, packaged as an _über-jar_, is now runnable using `java -jar build/*-runner.jar`. + +## Creating a native executable + +You can create a native executable using: + +```shell script +./gradlew build -Dquarkus.package.type=native +``` + +Or, if you don't have GraalVM installed, you can run the native executable build in a container using: + +```shell script +./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true +``` + +You can then execute your native executable with: `./build/code-with-quarkus-1.0.0-SNAPSHOT-runner` + +If you want to learn more about building native executables, please consult https://quarkus.io/guides/gradle-tooling. + +## Related Guides + +## Provided Code + +### RESTEasy Reactive + +Easily start your Reactive RESTful Web Services + +[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources) diff --git a/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.jvm b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.jvm new file mode 100644 index 00000000..74ddda65 --- /dev/null +++ b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.jvm @@ -0,0 +1,98 @@ +# trunk-ignore-all(checkov/CKV_DOCKER_2) + +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./gradlew build +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/code-with-quarkus-jvm . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-jvm +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-jvm +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.16 + +ENV LANGUAGE='en_US:en' + + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --chown=185 build/quarkus-app/lib/ /deployments/lib/ +COPY --chown=185 build/quarkus-app/*.jar /deployments/ +COPY --chown=185 build/quarkus-app/app/ /deployments/app/ +COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] \ No newline at end of file diff --git a/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.legacy-jar b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.legacy-jar new file mode 100644 index 00000000..70233e49 --- /dev/null +++ b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.legacy-jar @@ -0,0 +1,93 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./gradlew build -Dquarkus.package.type=legacy-jar +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/code-with-quarkus-legacy-jar . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-legacy-jar +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005. +# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005 +# when running the container +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-legacy-jar +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi8/openjdk-17:1.16 + +ENV LANGUAGE='en_US:en' + + +COPY build/lib/* /deployments/lib/ +COPY build/*-runner.jar /deployments/quarkus-run.jar + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] diff --git a/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.native b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.native new file mode 100644 index 00000000..6f894572 --- /dev/null +++ b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.native @@ -0,0 +1,27 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# +# Before building the container image run: +# +# ./gradlew build -Dquarkus.package.type=native +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native -t quarkus/code-with-quarkus . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus +# +### +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root build/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.native-micro b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.native-micro new file mode 100644 index 00000000..9a4058bb --- /dev/null +++ b/incubating/poc-scala-quarkus/src/main/docker/Dockerfile.native-micro @@ -0,0 +1,30 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# It uses a micro base image, tuned for Quarkus native executables. +# It reduces the size of the resulting container image. +# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. +# +# Before building the container image run: +# +# ./gradlew build -Dquarkus.package.type=native +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/code-with-quarkus . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus +# +### +FROM quay.io/quarkus/quarkus-micro-image:2.0 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root build/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/incubating/poc-scala-quarkus/src/main/resources/META-INF/resources/index.html b/incubating/poc-scala-quarkus/src/main/resources/META-INF/resources/index.html new file mode 100644 index 00000000..af197216 --- /dev/null +++ b/incubating/poc-scala-quarkus/src/main/resources/META-INF/resources/index.html @@ -0,0 +1,394 @@ + + + + + code-with-quarkus - 1.0.0-SNAPSHOT + + + +
+
+
+ + + + + quarkus_logo_horizontal_rgb_1280px_reverse + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+

You just made a Quarkus application.

+

This page is served by Quarkus.

+ Visit the Dev UI +

+ This page: + src/main/resources/META-INF/resources/index.html +

+

+ App configuration: + src/main/resources/application.properties +

+

+ Static assets: src/main/resources/META-INF/resources/ +

+

Code: src/main/scala

+

Dev UI V1: /q/dev-v1

+

Generated starter code:

+
    +
  • + RESTEasy Reactive Easily start your Reactive RESTful + Web Services
    › + @Path: + /hello +
    › + Related guide +
  • +
+
+
+

Selected extensions

+
    +
  • Scala
  • +
+
Documentation
+

+ Practical step-by-step guides to help you achieve a specific goal. + Use them to help get your work done. +

+
+ Set up your IDE +
+

+ Everyone has a favorite IDE they like to use to code. Learn how to + configure yours to maximize your Quarkus productivity. +

+
+
+
+ + diff --git a/incubating/poc-scala-quarkus/src/main/resources/application.properties b/incubating/poc-scala-quarkus/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/incubating/poc-scala-quarkus/src/main/scala/org/acme/GreetingResource.scala b/incubating/poc-scala-quarkus/src/main/scala/org/acme/GreetingResource.scala new file mode 100644 index 00000000..3f0f0ca7 --- /dev/null +++ b/incubating/poc-scala-quarkus/src/main/scala/org/acme/GreetingResource.scala @@ -0,0 +1,12 @@ +package org.acme + +import jakarta.ws.rs.{GET, Path, Produces} +import jakarta.ws.rs.core.MediaType + +@Path("/hello") +class GreetingResource { + + @GET + @Produces(Array[String](MediaType.TEXT_PLAIN)) + def hello() = "Hello from RESTEasy Reactive" +} diff --git a/incubating/poc-scala-quarkus/src/native-test/scala/org/acme/GreetingResourceIT.scala b/incubating/poc-scala-quarkus/src/native-test/scala/org/acme/GreetingResourceIT.scala new file mode 100644 index 00000000..ca48dd4e --- /dev/null +++ b/incubating/poc-scala-quarkus/src/native-test/scala/org/acme/GreetingResourceIT.scala @@ -0,0 +1,6 @@ +package org.acme + +import io.quarkus.test.junit.QuarkusIntegrationTest + +@QuarkusIntegrationTest +class GreetingResourceIT extends GreetingResourceTest diff --git a/incubating/poc-scala-quarkus/src/test/scala/org/acme/GreetingResourceTest.scala b/incubating/poc-scala-quarkus/src/test/scala/org/acme/GreetingResourceTest.scala new file mode 100644 index 00000000..c79e879a --- /dev/null +++ b/incubating/poc-scala-quarkus/src/test/scala/org/acme/GreetingResourceTest.scala @@ -0,0 +1,21 @@ +package org.acme + +import io.quarkus.test.junit.QuarkusTest +import io.restassured.RestAssured.given +import org.hamcrest.CoreMatchers.`is` +import org.junit.jupiter.api.Test + +@QuarkusTest +class GreetingResourceTest { + + @Test + def testHelloEndpoint() = { + given() + .`when`() + .get("/hello") + .then() + .statusCode(200) + .body(`is`("Hello from RESTEasy Reactive")) + } + +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 6f83ca4b..0b1b7052 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -47,6 +47,7 @@ pluginManagement { // id("org.kordamp.gradle.project") version kordampGradlePluginVersion // id("net.thauvin.erik.gradle.semver") version semVerPluginVersion id("ru.vyarus.mkdocs") version "3.0.0" + id("io.quarkus") version "3.3.3" } repositories { @@ -128,4 +129,5 @@ if (System.getenv("enableCompositeBuild") == "true") { } } -includeBuild("build-logic") \ No newline at end of file +includeBuild("build-logic") +// includeBuild("include/ddo-avro") \ No newline at end of file diff --git a/incubating/ddo-antlr/build.gradle.kts b/subprojects/common/ddo-antlr/build.gradle.kts similarity index 51% rename from incubating/ddo-antlr/build.gradle.kts rename to subprojects/common/ddo-antlr/build.gradle.kts index 3f771461..23b2309a 100644 --- a/incubating/ddo-antlr/build.gradle.kts +++ b/subprojects/common/ddo-antlr/build.gradle.kts @@ -1,32 +1,35 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { // kotlin("jvm") version "1.9.10" - id("djaxonomy.kotlin-library-conventions") + id("io.truthencode.poc.kantlr.kotlin-library-conventions") antlr // id("java-library-conventions") // id("be.vbgn.ci-detect") id("code-quality") + // id("djaxonomy.test-conventions") idea -// id("djaxonomy.kotlin-test-conventions") + id("djaxonomy.kotlin-test-conventions") } dependencies { + implementation(enforcedPlatform(project(":ddo-platform"))) + antlr(libs.antlr4) // use ANTLR version 4 + implementation(libs.logback.classic) +// // implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.5.31")) +// // testImplementation(enforcedPlatform("org.junit:junit-bom:5.8.2")) - testImplementation(enforcedPlatform("org.junit:junit-bom:5.8.2")) - - antlr("org.antlr:antlr4:4.10.1") // use ANTLR version 4 - implementation("ch.qos.logback:logback-core:1.2.11") - implementation("ch.qos.logback:logback-classic:1.2.11") - implementation("org.slf4j:slf4j-api:1.7.36") - // JUnit 5 - testImplementation(group = "org.junit.jupiter", name = "junit-jupiter-api") - testImplementation(group = "org.junit.platform", name = "junit-platform-runner") - testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-engine") - testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-launcher") -// testRuntimeOnly(group = "co.helmethair", name = "scalatest-junit-runner") - testRuntimeOnly(group = "org.junit.vintage", name = "junit-vintage-engine") - testRuntimeOnly(group = "org.junit.jupiter", name = "junit-jupiter-engine") +// antlr("org.antlr:antlr4") // use ANTLR version 4 +// implementation("ch.qos.logback:logback-core") +// implementation("ch.qos.logback:logback-classic") +// implementation("org.slf4j:slf4j-api") +// // JUnit 5 +// // testImplementation(group = "org.junit.jupiter", name = "junit-jupiter-api") +// // testImplementation(group = "org.junit.platform", name = "junit-platform-runner") +// // testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-engine") +// // testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-launcher") +// // // testRuntimeOnly(group = "co.helmethair", name = "scalatest-junit-runner") +// // testRuntimeOnly(group = "org.junit.vintage", name = "junit-vintage-engine") +// // testRuntimeOnly(group = "org.junit.jupiter", name = "junit-jupiter-engine") +// } } repositories { @@ -54,25 +57,36 @@ data class PackagePath(val source: String, val packageName: String) { get() = packageToPath(packageName) } // src/generated/java/EnchantmentsParserVisitor.java -sourceSets { - named("main") { - java.sourceDirectories.files.plus(antlrJavaPath.baseOutputFolder) - } -} +// sourceSets { +// named("main") { +// java.sourceDirectories.files.plus(antlrJavaPath.baseOutputFolder) +// } +// } // Intellij -idea { - module { - sourceDirs.add(antlrJavaPath.baseOutputFolder) - generatedSourceDirs.add(antlrJavaPath.baseOutputFolder) - // .addAll(listOf(javaGenPath)) - } -} +// idea { +// module { +// sourceDirs.add(antlrJavaPath.baseOutputFolder) +// generatedSourceDirs.add(antlrJavaPath.baseOutputFolder) +// // .addAll(listOf(javaGenPath)) +// } +// } kotlin { + logger.error("we are here") + this.sourceSets.named("main") { // kotlin.srcDir(antlrJavaPath.baseOutputFolder) - this.kotlin.sourceDirectories.plus(antlrJavaPath.baseOutputFolder) +// logger.error("value of baseOutput (path) ${antlrJavaPath.baseOutputFolder.path}") +// this.kotlin.sourceDirectories.plus(antlrJavaPath.baseOutputFolder) +// +// // this.kotlin.sourceDirectories.plus(java.sourceSets.map{it.java.sourceDirectories.files}.flatten()) +// +// +// logger.error("Kotlin Enumerating source set files") + kotlin.sourceDirectories.forEach { + logger.error(it.name) + } } } @@ -80,12 +94,16 @@ tasks { generateGrammarSource { maxHeapSize = "64m" // arguments = arguments + listOf("-visitor", "-long-messages", "-lib", antlrJavaPath.packageFolder.absolutePath) - arguments = arguments + listOf("-visitor", "-long-messages", "-package", "io.truthencode.ddo.grammer.antlr") - outputDirectory = antlrJavaPath.packageFolder + arguments = arguments + listOf("-visitor", "-long-messages") + // outputDirectory = antlrJavaPath.packageFolder // logger.error("outputting generated antlr classes to ${antlrJavaPath.packageFolder}") } - withType(KotlinCompile::class) { + // withType(KotlinCompile::class) { + // dependsOn(generateGrammarSource) + // } + + named("compileKotlin") { dependsOn(generateGrammarSource) } diff --git a/incubating/ddo-antlr/docs/about/history.md b/subprojects/common/ddo-antlr/docs/about/history.md similarity index 100% rename from incubating/ddo-antlr/docs/about/history.md rename to subprojects/common/ddo-antlr/docs/about/history.md diff --git a/incubating/ddo-antlr/docs/guide/installation.md b/subprojects/common/ddo-antlr/docs/guide/installation.md similarity index 100% rename from incubating/ddo-antlr/docs/guide/installation.md rename to subprojects/common/ddo-antlr/docs/guide/installation.md diff --git a/incubating/ddo-antlr/docs/index.md b/subprojects/common/ddo-antlr/docs/index.md similarity index 100% rename from incubating/ddo-antlr/docs/index.md rename to subprojects/common/ddo-antlr/docs/index.md diff --git a/subprojects/common/ddo-antlr/mkdocs.yml b/subprojects/common/ddo-antlr/mkdocs.yml new file mode 100644 index 00000000..40d4790d --- /dev/null +++ b/subprojects/common/ddo-antlr/mkdocs.yml @@ -0,0 +1,11 @@ +site_name: Parsing + +# Meta tags (placed in header) +site_description: Core DDO Objects + +nav: + - Home: index.md + - User guide: + - Installation: guide/installation.md + - About: + - Release notes: about/history.md diff --git a/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 b/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 new file mode 100644 index 00000000..89fd8f05 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 @@ -0,0 +1,213 @@ +lexer grammar EnchantmentsLexer; + +@header {package io.truthencode.ddo.grammar.antlr; } +/* Lexer */ + +import RomanNumeralsLexer; + +LineBreak + : ('\r'? '\n' + | '\r') -> skip + ; + + + + +// Known, named enchantments +ITEM_ENCHANTMENT : FALSE_LIFE | HEALING_AMPLIFICATION | CONCEALMENT | SAVES | UPGRADABLE_FLAG | ELEMENTAL_ABSORBTION | LORE | AUGMENTATION | FORT | AUGMENTSLOT | ENHANCEMENT_BONUS | SHELTERING | DAMAGE_TYPE | MYTHIC_BOOST | CONTINUOUS_SPELL_POWER | SPELL_SCHOOL_FOCUS; +// TODO: grammar - Unique Item effects +// https://ddowiki.com/page/Category:Unique_item_enchantments + +// TODO: grammar - Set bonuses +// https://ddowiki.com/page/Named_item_sets +// Also needed for filigree sets +// Epic Elemental Evil Set + + + + +// TODO: Upgradable / craftable flags +UPGRADABLE_FLAG : ATTUNED; + +ATTUNED: ATTUNED_PREFIX ' ' (ATTUNED_THINGS_WITH_TIER | ATTUNED_THINGS); +ATTUNED_THINGS_WITH_TIER: ATTUNED_PREFIX HEROISM COLON ' ' TIER; +ATTUNED_THINGS: ATTUNED_PREFIX HEROISM; +// TODO: grammar for: Upgradeable Item (Temple of Elemental Evil) +HCOL : ATTUNED_PREFIX HEROISM COLON ' ' TIER; + +fragment ATTUNED_PREFIX : 'Attuned ' (TO|BY); +fragment TO : 'to'; +fragment BY : 'by'; +fragment ATTUNED_HEROISM: HEROISM; + +HEROISM : 'Heroism'; + + +fragment TIER : 'Tier'; +LORE : SPELL_LORE; + + + +// Spell power / potency et all +// Potency adds + to each spell power. i.e. potency 10 = combustion + 10, glaciation + 10 etc +// Continuous (always on) +CONTINUOUS_SPELL_POWER : POTENCY | CORROSION | DEVOTION | GLACIATION | IMPULSE | MAGNETISM | NULLIFICATION | RADIANCE | RECONSTRUCTION | RESONANCE; +POTENCY : 'Potency'; +CORROSION : 'Corrosion'; +DEVOTION : 'Devotion'; +GLACIATION : 'Glaciation'; +IMPULSE : 'Impulse'; +MAGNETISM : 'Magnetism'; +NULLIFICATION : 'Nullification'; +RADIANCE : 'Radiance'; +RECONSTRUCTION : 'Reconstruction'; +RESONANCE : 'Resonance'; + + +TEMPORARY_SPELL_POWER : INFERNO | EROSION | ARDOR | FREEZE | IMPACT | SPARK | NIHIL | EFFICACY | BRILLIANCE | MENDING | CACOPHONY; +// Temporary (Buff / clicky / potion etc) +INFERNO : 'Inferno'; +EROSION : 'Erosion'; +ARDOR : 'Ardor'; +FREEZE : 'Freeze'; +IMPACT : 'Impact'; +SPARK : 'Spark'; +NIHIL : 'Nihil'; +EFFICACY : 'Efficacy'; +BRILLIANCE : 'Brilliance'; +MENDING : 'Mending'; +CACOPHONY : 'Cacophony'; + +// Healing Amp +HEALING_AMPLIFICATION : BONUS_TYPE ' ' HEALING ' ' AMPLICIATION; + + +fragment HEALING : 'Healing'; +fragment AMPLICIATION : 'Amplification'; +fragment POSITIVE_HEALING : 'Positive'; +fragment NEGATIVE_HEALING : 'Negative'; +fragment REPAIR_HEALING : 'Repair'; + +// Life / vitality +FALSE_LIFE : (GREATER_LESSER_MODIFIER ' ')? FALSE_LIFE_ID; + +FALSE_LIFE_ID: 'False Life'; + + +GREATER_LESSER_MODIFIER : GREATER | LESSER; + +fragment GREATER: 'Greater'; +fragment LESSER : 'Lesser'; + +// TODO: craftsmanship (i.e. wonderous) +SPELL_SCHOOL_FOCUS : SPELL_SCHOOL ' ' 'Focus'; + +// Spell Schools / DC's +SPELL_SCHOOL : ABJURATION | CONJURATION | DIVINATION | ENCHANTMENT | EVOCATION | ILLUSION | NECROMANCY | TRANSMUTATION; +ABJURATION : 'Abjuration'; +CONJURATION : 'Conjuration'; +DIVINATION : 'Divination'; +ENCHANTMENT : 'Enchantment'; +EVOCATION : 'Evocation'; +ILLUSION : 'Illusion'; +NECROMANCY : 'Necromancy'; +TRANSMUTATION : 'Transmutation'; + +// Augmentation +AUGMENTATION : POWER_SOURCE ' ' 'Augmentation'; +POWER_SOURCE : 'Arcane' | 'Divine'; + +ARCHANE_AUGMENTATION : 'Arcane Augmentation'; +SPELL_LORE : 'Spell Lore'; + +// Mythic boost items +// https://ddowiki.com/page/Mythic_bonus +MYTHIC_BOOST : MYTHIC_KEYWORD ' ' MYTHIC_SLOT ' Boost'; +fragment MYTHIC_KEYWORD : 'Mythic'; +fragment MYTHIC_SLOT : CORE_BODY_SLOT; +// Main body slots, explicitly not including quiver / cosmetics +CORE_BODY_SLOT : 'Armor' | 'Belt' | 'Boot' | 'Cloak' | 'Google' | 'Hands' | 'Head' | 'Neck' | 'Ring' | 'Trinket' | 'Wrist' | MAIN_HAND | OFF_HAND; +HAND_SLOT : MAIN_HAND | OFF_HAND; +fragment MAIN_HAND : 'Weapon'; +// TODO: grammer / nomenclature for main / off-hand slots +fragment OFF_HAND : 'Shield' | 'Off-hand'; +AUXILLARY_BODY_SLOT: 'Quiver'; +// TODO: Cosmetic slots +// Late milestone if any to support it. + +// Damage Type (bypasses damage reduction of same) i.e. slashing, magic, silver bypasses DR/Slashing DR/Magic DR/Silver etc. +// Types can be determined by material (silver), shape (slash), magic enhancement (+1 or greater) / elemental or alignment and also 'untyped' which bypasses all DR but DR- +DAMAGE_TYPE : ALIGNMENT_DAMAGE_TYPE | MATERIAL_DAMAGE_TYPE | PHYSICAL_DAMAGE_TYPE | ELEMENTAL_DAMAGE_TYPE | ELEMENTAL_SUB_TYPE; +fragment ALIGNMENT_DAMAGE_TYPE : 'Chaotic' | 'Evil' | 'Good' | 'Lawful'; +fragment MATERIAL_DAMAGE_TYPE : 'Silver' | 'Byshek' | 'Adamantine' | 'Cold iron' | 'Crystal' | 'Mithral'; +fragment PHYSICAL_DAMAGE_TYPE : 'Slash' | 'Pierce' | 'Bludgeon'; +// NOTE: Air, Earth and Water types aren't currently directly implemented, +// i.e. no sword does 'Earth' damage, but might do Acid damage which could be amplified by some Earth affinity. +fragment ELEMENTAL_DAMAGE_TYPE : 'Air' | 'Earth' | FIRE | 'Force' | 'Light' | 'Poison' | SONIC | 'Water' | 'Negative' | 'Positive'; +fragment ELEMENTAL_SUB_TYPE : ACID | COLD; + +ELEMENTAL_ABSORBTION : ELEMENTS ' ' ABSORPTION; + +ABSORPTION: 'Absorption'; + +fragment ELEMENTS : FIRE | ACID | ELECTRIC | COLD | SONIC; +fragment FIRE : 'Fire'; +fragment ACID : 'Acid'; +fragment ELECTRIC : 'Electric'; +fragment COLD : 'Cold'; +fragment SONIC : 'Sonic'; + +// Augments +AUGMENTSLOT : AUGMENTCOLOR ' ' LBL_AUGMENT_SLOT ' ' AUGMENTOPTION; +LBL_AUGMENT_SLOT : 'Augment Slot:'; +ENHANCEMENT_BONUS : 'Enhancement Bonus'; + +fragment UNCATEGORIZED_ENCHANTMENTS : FORT; + +// dodge, concealment, ethereal miss-chance +CONCEALMENT : DISPLACEMENT; +DISPLACEMENT : (LESSER ' ' DISPLACED) | 'DISPLACEMENT'; +fragment DISPLACED : 'Displacement'; + +// Basic one-offs +// Defense +// SAVES +SAVES : RESISTANCE; +fragment RESISTANCE : 'Resistance'; +FORT : 'Fortification'; +SHELTERING : SHELTERTYPE ' ' 'Sheltering'; +SHELTERTYPE : 'Physical and Magical' | 'Physical' | 'Magical'; +AUGMENTCOLOR : 'Blue' | 'Orange' | 'Yellow' | 'Red' | 'Green' | 'Purple' | 'Colorless'; +AUGMENTOPTION: EmptyAugmentSlot | FilledAugmentSlot; + +FilledAugmentSlot: 'todo:MARKER '; // can be empty or filled with any named or crafted augment +EmptyAugmentSlot: 'Empty'; + +BONUS_TYPE: BONUS_TYPE_COMPETENCE; +BONUS_TYPE_COMPETENCE : 'Competence'; +BONUS_TYPE_EXCEPTIONAL : 'Exceptional'; +BONUS_TYPE_INSIGHTFUL : 'Insightful'; + +//ID : [a-zA-Z]+ ; // match lower-case identifiers +WS : [ \t\r\n]+ -> channel(HIDDEN) ; // skip spaces, tabs, newlines +NUMBER_WITH_OPTIONS : NUMERIC ' ' OR ' ' NUMERIC; +NUMERIC : PCT | NUM; +PCT : NUM + '%'; // SIGNED percent +NUM : (SIGN + UNUM) | UNUM; // signed num +SELECTOR_WORD : OR; + +OR: 'or'; +SIGN : '+' | '-'; +fragment UNUM : [0-9]+; // unsigned numbers +fragment COLON: ':'; +//INDENT : [ \t]+ {System.out.println("INDENT")>} {this.getCharPositionInLine()==0}? ; +// catch-all word blobs MUST LIST AFTER OTHER RULES +UNKNOWN_ID : MULTI_WORDS | SIMPLE_WORD | MULTI_WORD; +fragment MULTI_WORDS : MULTI_WORD + (' ' + SIMPLE_WORD); +fragment MULTI_WORD: SIMPLE_WORD + ' ' + SIMPLE_WORD; +fragment SIMPLE_WORD: START_CHARS + [a-z]+; +fragment START_CHARS : LOWERCASE_LETTERS | NON_ROMAN_LETTERS; +fragment LOWERCASE_LETTERS : [a-z]; +fragment NON_ROMAN_LETTERS : [ABEFGHJKNOPQRSTUWYZ]; +// ['A', 'B', 'E', 'F', 'G', 'H', 'J', 'K', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'W', 'Y', 'Z']; + \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsLexer.tokens b/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsLexer.tokens new file mode 100644 index 00000000..cc559382 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsLexer.tokens @@ -0,0 +1,165 @@ +LineBreak=1 +ITEM_ENCHANTMENT=2 +UPGRADABLE_FLAG=3 +ATTUNED=4 +ATTUNED_THINGS_WITH_TIER=5 +ATTUNED_THINGS=6 +HCOL=7 +HEROISM=8 +LORE=9 +CONTINUOUS_SPELL_POWER=10 +POTENCY=11 +CORROSION=12 +DEVOTION=13 +GLACIATION=14 +IMPULSE=15 +MAGNETISM=16 +NULLIFICATION=17 +RADIANCE=18 +RECONSTRUCTION=19 +RESONANCE=20 +TEMPORARY_SPELL_POWER=21 +INFERNO=22 +EROSION=23 +ARDOR=24 +FREEZE=25 +IMPACT=26 +SPARK=27 +NIHIL=28 +EFFICACY=29 +BRILLIANCE=30 +MENDING=31 +CACOPHONY=32 +HEALING_AMPLIFICATION=33 +FALSE_LIFE=34 +FALSE_LIFE_ID=35 +GREATER_LESSER_MODIFIER=36 +SPELL_SCHOOL_FOCUS=37 +SPELL_SCHOOL=38 +ABJURATION=39 +CONJURATION=40 +DIVINATION=41 +ENCHANTMENT=42 +EVOCATION=43 +ILLUSION=44 +NECROMANCY=45 +TRANSMUTATION=46 +AUGMENTATION=47 +POWER_SOURCE=48 +ARCHANE_AUGMENTATION=49 +SPELL_LORE=50 +MYTHIC_BOOST=51 +CORE_BODY_SLOT=52 +HAND_SLOT=53 +AUXILLARY_BODY_SLOT=54 +DAMAGE_TYPE=55 +ELEMENTAL_ABSORBTION=56 +ABSORPTION=57 +AUGMENTSLOT=58 +LBL_AUGMENT_SLOT=59 +ENHANCEMENT_BONUS=60 +CONCEALMENT=61 +DISPLACEMENT=62 +SAVES=63 +FORT=64 +SHELTERING=65 +SHELTERTYPE=66 +AUGMENTCOLOR=67 +AUGMENTOPTION=68 +FilledAugmentSlot=69 +EmptyAugmentSlot=70 +BONUS_TYPE=71 +BONUS_TYPE_COMPETENCE=72 +BONUS_TYPE_EXCEPTIONAL=73 +BONUS_TYPE_INSIGHTFUL=74 +WS=75 +NUMBER_WITH_OPTIONS=76 +NUMERIC=77 +PCT=78 +NUM=79 +SELECTOR_WORD=80 +OR=81 +SIGN=82 +UNKNOWN_ID=83 +M=84 +CD=85 +D=86 +CM=87 +C=88 +CC=89 +CCC=90 +XL=91 +L=92 +XC=93 +X=94 +XX=95 +XXX=96 +IV=97 +V=98 +IX=99 +I=100 +II=101 +III=102 +'Heroism'=8 +'Potency'=11 +'Corrosion'=12 +'Devotion'=13 +'Glaciation'=14 +'Impulse'=15 +'Magnetism'=16 +'Nullification'=17 +'Radiance'=18 +'Reconstruction'=19 +'Resonance'=20 +'Inferno'=22 +'Erosion'=23 +'Ardor'=24 +'Freeze'=25 +'Impact'=26 +'Spark'=27 +'Nihil'=28 +'Efficacy'=29 +'Brilliance'=30 +'Mending'=31 +'Cacophony'=32 +'False Life'=35 +'Abjuration'=39 +'Conjuration'=40 +'Divination'=41 +'Enchantment'=42 +'Evocation'=43 +'Illusion'=44 +'Necromancy'=45 +'Transmutation'=46 +'Arcane Augmentation'=49 +'Spell Lore'=50 +'Quiver'=54 +'Absorption'=57 +'Augment Slot:'=59 +'Enhancement Bonus'=60 +'Fortification'=64 +'todo:MARKER '=69 +'Empty'=70 +'Competence'=72 +'Exceptional'=73 +'Insightful'=74 +'or'=81 +'M'=84 +'CD'=85 +'D'=86 +'CM'=87 +'C'=88 +'CC'=89 +'CCC'=90 +'XL'=91 +'L'=92 +'XC'=93 +'X'=94 +'XX'=95 +'XXX'=96 +'IV'=97 +'V'=98 +'IX'=99 +'I'=100 +'II'=101 +'III'=102 diff --git a/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsParser.g4 b/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsParser.g4 new file mode 100644 index 00000000..6c942489 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsParser.g4 @@ -0,0 +1,30 @@ +parser grammar EnchantmentsParser; + +@header {package io.truthencode.ddo.grammar.antlr; } + +options { tokenVocab = EnchantmentsLexer; + } +// roman numerals taken fro PHP example BSD https://github.com/gabriele-tomassetti/getting-started-antlr-php/blob/4a7ce18e63766087f50dab881c99000124f2016c/RomanNumerals.g4 +import RomanNumeralsParser; + +parse returns [List row] +@init { + $row = new ArrayList(); +} + : (idDecl {$row.add($idDecl.text);})+ (LineBreak | EOF) + ; + +//thing : PCT ENCHANTMENT; + +//idDecl : PCT; +idDecl : numberOrPctPrefix? enchantmentType numberOrRomanSuffix?; +//idDecl : enchantmentType numberOrRomanSuffix?; +//| enchantmentType numberOrRomanSuffix | enchantmentType; + +numberOrPctPrefix : NUMERIC; +//numberOrPctPrefix : (NUM | PCT); +numberOrRomanSuffix : NUMBER_WITH_OPTIONS | NUMERIC | numeral; + +enchantmentType : (ITEM_ENCHANTMENT); + + diff --git a/incubating/ddo-antlr/src/main/antlr/Number.g4 b/subprojects/common/ddo-antlr/src/main/antlr/Number.g4 similarity index 100% rename from incubating/ddo-antlr/src/main/antlr/Number.g4 rename to subprojects/common/ddo-antlr/src/main/antlr/Number.g4 diff --git a/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsLexer.g4 b/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsLexer.g4 new file mode 100644 index 00000000..55a2543b --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsLexer.g4 @@ -0,0 +1,24 @@ +lexer grammar RomanNumeralsLexer; + +M : 'M'; +CD : 'CD'; +D : 'D' ; +CM : 'CM'; +C : 'C'; +CC : 'CC'; +CCC : 'CCC' ; +XL : 'XL' ; +L : 'L' ; +XC : 'XC' ; +X : 'X' ; +XX : 'XX' ; +XXX : 'XXX' ; +IV : 'IV' ; +V : 'V' ; +IX : 'IX' ; +I : 'I' ; +II : 'II' ; +III : 'III' ; + +//WS : [ \r\n\t]+ ; +//ANY : ~[ \r\n\t] ; \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsLexer.tokens b/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsLexer.tokens new file mode 100644 index 00000000..5b16f225 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsLexer.tokens @@ -0,0 +1,38 @@ +M=1 +CD=2 +D=3 +CM=4 +C=5 +CC=6 +CCC=7 +XL=8 +L=9 +XC=10 +X=11 +XX=12 +XXX=13 +IV=14 +V=15 +IX=16 +I=17 +II=18 +III=19 +'M'=1 +'CD'=2 +'D'=3 +'CM'=4 +'C'=5 +'CC'=6 +'CCC'=7 +'XL'=8 +'L'=9 +'XC'=10 +'X'=11 +'XX'=12 +'XXX'=13 +'IV'=14 +'V'=15 +'IX'=16 +'I'=17 +'II'=18 +'III'=19 diff --git a/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 b/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 new file mode 100644 index 00000000..ad6aace0 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 @@ -0,0 +1,112 @@ +/* +BSD License + +Copyright (c) 2017, Tom Everett +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of Tom Everett nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* +* Essentials of the grammar from here: https://compilers.iecc.com/comparch/article/07-03-118 +*/ + +parser grammar RomanNumeralsParser; + +//options { tokenVocab = RomanNumeralsLexer; } + +//expression +// : words* (numeral words+)* EOF +// ; + +//words +// : ANY+ +// | WS +// ; + +numeral + : thous_part hundreds + | thous_part + | hundreds + ; + +thous_part + : thous_part M + | M + ; + +hundreds + : hun_part tens + | hun_part + | tens + ; + +hun_part + : CM + | CD + | D hun_rep + | D + | hun_rep + ; + +hun_rep + : C + | CC + | CCC + ; + +tens + : tens_part ones + | tens_part + | ones + ; + +tens_part + : XC + | XL + | L tens_rep + | L + | tens_rep + ; + +tens_rep + : X + | XX + | XXX + ; + +ones + : ones_rep + | IV + | V ones_rep + | V + | IX + ; + +ones_rep + : I + | I I + | III + ; diff --git a/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.interp b/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.interp new file mode 100644 index 00000000..4b253464 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.interp @@ -0,0 +1,96 @@ +token literal names: +null +null +null +null +null +null +'Quiver' +null +null +'Augment Slot:' +'Enhancement Bonus' +'Fortification' +null +null +null +null +'todo:MARKER ' +'Empty' +null +null +null +null +null + +token symbolic names: +null +LineBreak +ENCHANTMENT +MYTHIC_BOOST +CORE_BODY_SLOT +HAND_SLOT +AUXILLARY_BODY_SLOT +DAMAGE_TYPE +AUGMENTSLOT +LBL_AUGMENT_SLOT +ENHANCEMENT_BONUS +FORT +SHELTERING +SHELTERTYPE +AUGMENTCOLOR +AUGMENTOPTION +FilledAugmentSlot +EmptyAugmentSlot +WS +PCT +NUM +SIGN +UNKNOWN_ID + +rule names: +LineBreak +ENCHANTMENT +MYTHIC_BOOST +MYTHIC_KEYWORD +MYTHIC_SLOT +CORE_BODY_SLOT +HAND_SLOT +MAIN_HAND +OFF_HAND +AUXILLARY_BODY_SLOT +DAMAGE_TYPE +ALIGNMENT_DAMAGE_TYPE +MATERIAL_DAMAGE_TYPE +PHYSICAL_DAMAGE_TYPE +ELEMENTAL_DAMAGE_TYPE +ELEMENTAL_SUB_TYPE +AUGMENTSLOT +LBL_AUGMENT_SLOT +ENHANCEMENT_BONUS +FORT +SHELTERING +SHELTERTYPE +AUGMENTCOLOR +AUGMENTOPTION +FilledAugmentSlot +EmptyAugmentSlot +WS +PCT +NUM +SIGN +UNUM +UNKNOWN_ID +MULTI_WORDS +MULTI_WORD +SIMPLE_WORD + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 22, 595, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 1, 0, 3, 0, 73, 8, 0, 1, 0, 1, 0, 3, 0, 77, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 87, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 163, 8, 5, 1, 6, 1, 6, 3, 6, 167, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 190, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 204, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 227, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 274, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 295, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 351, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 361, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 463, 8, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 3, 22, 504, 8, 22, 1, 23, 1, 23, 3, 23, 508, 8, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 4, 26, 530, 8, 26, 11, 26, 12, 26, 531, 1, 26, 1, 26, 1, 27, 4, 27, 537, 8, 27, 11, 27, 12, 27, 538, 1, 27, 1, 27, 1, 28, 4, 28, 544, 8, 28, 11, 28, 12, 28, 545, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 4, 30, 553, 8, 30, 11, 30, 12, 30, 554, 1, 31, 1, 31, 1, 31, 3, 31, 560, 8, 31, 1, 32, 4, 32, 563, 8, 32, 11, 32, 12, 32, 564, 1, 32, 4, 32, 568, 8, 32, 11, 32, 12, 32, 569, 1, 32, 1, 32, 1, 33, 4, 33, 575, 8, 33, 11, 33, 12, 33, 576, 1, 33, 4, 33, 580, 8, 33, 11, 33, 12, 33, 581, 1, 33, 1, 33, 1, 34, 4, 34, 587, 8, 34, 11, 34, 12, 34, 588, 1, 34, 4, 34, 592, 8, 34, 11, 34, 12, 34, 593, 0, 0, 35, 1, 1, 3, 2, 5, 3, 7, 0, 9, 0, 11, 4, 13, 5, 15, 0, 17, 0, 19, 6, 21, 7, 23, 0, 25, 0, 27, 0, 29, 0, 31, 0, 33, 8, 35, 9, 37, 10, 39, 11, 41, 12, 43, 13, 45, 14, 47, 15, 49, 16, 51, 17, 53, 18, 55, 19, 57, 20, 59, 21, 61, 0, 63, 22, 65, 0, 67, 0, 69, 0, 1, 0, 5, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 43, 43, 45, 45, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 1, 0, 97, 122, 647, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 1, 76, 1, 0, 0, 0, 3, 86, 1, 0, 0, 0, 5, 88, 1, 0, 0, 0, 7, 98, 1, 0, 0, 0, 9, 105, 1, 0, 0, 0, 11, 162, 1, 0, 0, 0, 13, 166, 1, 0, 0, 0, 15, 168, 1, 0, 0, 0, 17, 189, 1, 0, 0, 0, 19, 191, 1, 0, 0, 0, 21, 203, 1, 0, 0, 0, 23, 226, 1, 0, 0, 0, 25, 273, 1, 0, 0, 0, 27, 294, 1, 0, 0, 0, 29, 350, 1, 0, 0, 0, 31, 360, 1, 0, 0, 0, 33, 362, 1, 0, 0, 0, 35, 368, 1, 0, 0, 0, 37, 382, 1, 0, 0, 0, 39, 400, 1, 0, 0, 0, 41, 414, 1, 0, 0, 0, 43, 462, 1, 0, 0, 0, 45, 503, 1, 0, 0, 0, 47, 507, 1, 0, 0, 0, 49, 509, 1, 0, 0, 0, 51, 522, 1, 0, 0, 0, 53, 529, 1, 0, 0, 0, 55, 536, 1, 0, 0, 0, 57, 543, 1, 0, 0, 0, 59, 549, 1, 0, 0, 0, 61, 552, 1, 0, 0, 0, 63, 559, 1, 0, 0, 0, 65, 562, 1, 0, 0, 0, 67, 574, 1, 0, 0, 0, 69, 586, 1, 0, 0, 0, 71, 73, 5, 13, 0, 0, 72, 71, 1, 0, 0, 0, 72, 73, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 77, 5, 10, 0, 0, 75, 77, 5, 13, 0, 0, 76, 72, 1, 0, 0, 0, 76, 75, 1, 0, 0, 0, 77, 78, 1, 0, 0, 0, 78, 79, 6, 0, 0, 0, 79, 2, 1, 0, 0, 0, 80, 87, 3, 39, 19, 0, 81, 87, 3, 33, 16, 0, 82, 87, 3, 37, 18, 0, 83, 87, 3, 41, 20, 0, 84, 87, 3, 21, 10, 0, 85, 87, 3, 5, 2, 0, 86, 80, 1, 0, 0, 0, 86, 81, 1, 0, 0, 0, 86, 82, 1, 0, 0, 0, 86, 83, 1, 0, 0, 0, 86, 84, 1, 0, 0, 0, 86, 85, 1, 0, 0, 0, 87, 4, 1, 0, 0, 0, 88, 89, 3, 7, 3, 0, 89, 90, 5, 32, 0, 0, 90, 91, 3, 9, 4, 0, 91, 92, 5, 32, 0, 0, 92, 93, 5, 66, 0, 0, 93, 94, 5, 111, 0, 0, 94, 95, 5, 111, 0, 0, 95, 96, 5, 115, 0, 0, 96, 97, 5, 116, 0, 0, 97, 6, 1, 0, 0, 0, 98, 99, 5, 77, 0, 0, 99, 100, 5, 121, 0, 0, 100, 101, 5, 116, 0, 0, 101, 102, 5, 104, 0, 0, 102, 103, 5, 105, 0, 0, 103, 104, 5, 99, 0, 0, 104, 8, 1, 0, 0, 0, 105, 106, 3, 11, 5, 0, 106, 10, 1, 0, 0, 0, 107, 108, 5, 65, 0, 0, 108, 109, 5, 114, 0, 0, 109, 110, 5, 109, 0, 0, 110, 111, 5, 111, 0, 0, 111, 163, 5, 114, 0, 0, 112, 113, 5, 66, 0, 0, 113, 114, 5, 101, 0, 0, 114, 115, 5, 108, 0, 0, 115, 163, 5, 116, 0, 0, 116, 117, 5, 66, 0, 0, 117, 118, 5, 111, 0, 0, 118, 119, 5, 111, 0, 0, 119, 163, 5, 116, 0, 0, 120, 121, 5, 67, 0, 0, 121, 122, 5, 108, 0, 0, 122, 123, 5, 111, 0, 0, 123, 124, 5, 97, 0, 0, 124, 163, 5, 107, 0, 0, 125, 126, 5, 71, 0, 0, 126, 127, 5, 111, 0, 0, 127, 128, 5, 111, 0, 0, 128, 129, 5, 103, 0, 0, 129, 130, 5, 108, 0, 0, 130, 163, 5, 101, 0, 0, 131, 132, 5, 72, 0, 0, 132, 133, 5, 97, 0, 0, 133, 134, 5, 110, 0, 0, 134, 135, 5, 100, 0, 0, 135, 163, 5, 115, 0, 0, 136, 137, 5, 72, 0, 0, 137, 138, 5, 101, 0, 0, 138, 139, 5, 97, 0, 0, 139, 163, 5, 100, 0, 0, 140, 141, 5, 78, 0, 0, 141, 142, 5, 101, 0, 0, 142, 143, 5, 99, 0, 0, 143, 163, 5, 107, 0, 0, 144, 145, 5, 82, 0, 0, 145, 146, 5, 105, 0, 0, 146, 147, 5, 110, 0, 0, 147, 163, 5, 103, 0, 0, 148, 149, 5, 84, 0, 0, 149, 150, 5, 114, 0, 0, 150, 151, 5, 105, 0, 0, 151, 152, 5, 110, 0, 0, 152, 153, 5, 107, 0, 0, 153, 154, 5, 101, 0, 0, 154, 163, 5, 116, 0, 0, 155, 156, 5, 87, 0, 0, 156, 157, 5, 114, 0, 0, 157, 158, 5, 105, 0, 0, 158, 159, 5, 115, 0, 0, 159, 163, 5, 116, 0, 0, 160, 163, 3, 15, 7, 0, 161, 163, 3, 17, 8, 0, 162, 107, 1, 0, 0, 0, 162, 112, 1, 0, 0, 0, 162, 116, 1, 0, 0, 0, 162, 120, 1, 0, 0, 0, 162, 125, 1, 0, 0, 0, 162, 131, 1, 0, 0, 0, 162, 136, 1, 0, 0, 0, 162, 140, 1, 0, 0, 0, 162, 144, 1, 0, 0, 0, 162, 148, 1, 0, 0, 0, 162, 155, 1, 0, 0, 0, 162, 160, 1, 0, 0, 0, 162, 161, 1, 0, 0, 0, 163, 12, 1, 0, 0, 0, 164, 167, 3, 15, 7, 0, 165, 167, 3, 17, 8, 0, 166, 164, 1, 0, 0, 0, 166, 165, 1, 0, 0, 0, 167, 14, 1, 0, 0, 0, 168, 169, 5, 87, 0, 0, 169, 170, 5, 101, 0, 0, 170, 171, 5, 97, 0, 0, 171, 172, 5, 112, 0, 0, 172, 173, 5, 111, 0, 0, 173, 174, 5, 110, 0, 0, 174, 16, 1, 0, 0, 0, 175, 176, 5, 83, 0, 0, 176, 177, 5, 104, 0, 0, 177, 178, 5, 105, 0, 0, 178, 179, 5, 101, 0, 0, 179, 180, 5, 108, 0, 0, 180, 190, 5, 100, 0, 0, 181, 182, 5, 79, 0, 0, 182, 183, 5, 102, 0, 0, 183, 184, 5, 102, 0, 0, 184, 185, 5, 45, 0, 0, 185, 186, 5, 104, 0, 0, 186, 187, 5, 97, 0, 0, 187, 188, 5, 110, 0, 0, 188, 190, 5, 100, 0, 0, 189, 175, 1, 0, 0, 0, 189, 181, 1, 0, 0, 0, 190, 18, 1, 0, 0, 0, 191, 192, 5, 81, 0, 0, 192, 193, 5, 117, 0, 0, 193, 194, 5, 105, 0, 0, 194, 195, 5, 118, 0, 0, 195, 196, 5, 101, 0, 0, 196, 197, 5, 114, 0, 0, 197, 20, 1, 0, 0, 0, 198, 204, 3, 23, 11, 0, 199, 204, 3, 25, 12, 0, 200, 204, 3, 27, 13, 0, 201, 204, 3, 29, 14, 0, 202, 204, 3, 31, 15, 0, 203, 198, 1, 0, 0, 0, 203, 199, 1, 0, 0, 0, 203, 200, 1, 0, 0, 0, 203, 201, 1, 0, 0, 0, 203, 202, 1, 0, 0, 0, 204, 22, 1, 0, 0, 0, 205, 206, 5, 67, 0, 0, 206, 207, 5, 104, 0, 0, 207, 208, 5, 97, 0, 0, 208, 209, 5, 111, 0, 0, 209, 210, 5, 116, 0, 0, 210, 211, 5, 105, 0, 0, 211, 227, 5, 99, 0, 0, 212, 213, 5, 69, 0, 0, 213, 214, 5, 118, 0, 0, 214, 215, 5, 105, 0, 0, 215, 227, 5, 108, 0, 0, 216, 217, 5, 71, 0, 0, 217, 218, 5, 111, 0, 0, 218, 219, 5, 111, 0, 0, 219, 227, 5, 100, 0, 0, 220, 221, 5, 76, 0, 0, 221, 222, 5, 97, 0, 0, 222, 223, 5, 119, 0, 0, 223, 224, 5, 102, 0, 0, 224, 225, 5, 117, 0, 0, 225, 227, 5, 108, 0, 0, 226, 205, 1, 0, 0, 0, 226, 212, 1, 0, 0, 0, 226, 216, 1, 0, 0, 0, 226, 220, 1, 0, 0, 0, 227, 24, 1, 0, 0, 0, 228, 229, 5, 83, 0, 0, 229, 230, 5, 105, 0, 0, 230, 231, 5, 108, 0, 0, 231, 232, 5, 118, 0, 0, 232, 233, 5, 101, 0, 0, 233, 274, 5, 114, 0, 0, 234, 235, 5, 66, 0, 0, 235, 236, 5, 121, 0, 0, 236, 237, 5, 115, 0, 0, 237, 238, 5, 104, 0, 0, 238, 239, 5, 101, 0, 0, 239, 274, 5, 107, 0, 0, 240, 241, 5, 65, 0, 0, 241, 242, 5, 100, 0, 0, 242, 243, 5, 97, 0, 0, 243, 244, 5, 109, 0, 0, 244, 245, 5, 97, 0, 0, 245, 246, 5, 110, 0, 0, 246, 247, 5, 116, 0, 0, 247, 248, 5, 105, 0, 0, 248, 249, 5, 110, 0, 0, 249, 274, 5, 101, 0, 0, 250, 251, 5, 67, 0, 0, 251, 252, 5, 111, 0, 0, 252, 253, 5, 108, 0, 0, 253, 254, 5, 100, 0, 0, 254, 255, 5, 32, 0, 0, 255, 256, 5, 105, 0, 0, 256, 257, 5, 114, 0, 0, 257, 258, 5, 111, 0, 0, 258, 274, 5, 110, 0, 0, 259, 260, 5, 67, 0, 0, 260, 261, 5, 114, 0, 0, 261, 262, 5, 121, 0, 0, 262, 263, 5, 115, 0, 0, 263, 264, 5, 116, 0, 0, 264, 265, 5, 97, 0, 0, 265, 274, 5, 108, 0, 0, 266, 267, 5, 77, 0, 0, 267, 268, 5, 105, 0, 0, 268, 269, 5, 116, 0, 0, 269, 270, 5, 104, 0, 0, 270, 271, 5, 114, 0, 0, 271, 272, 5, 97, 0, 0, 272, 274, 5, 108, 0, 0, 273, 228, 1, 0, 0, 0, 273, 234, 1, 0, 0, 0, 273, 240, 1, 0, 0, 0, 273, 250, 1, 0, 0, 0, 273, 259, 1, 0, 0, 0, 273, 266, 1, 0, 0, 0, 274, 26, 1, 0, 0, 0, 275, 276, 5, 83, 0, 0, 276, 277, 5, 108, 0, 0, 277, 278, 5, 97, 0, 0, 278, 279, 5, 115, 0, 0, 279, 295, 5, 104, 0, 0, 280, 281, 5, 80, 0, 0, 281, 282, 5, 105, 0, 0, 282, 283, 5, 101, 0, 0, 283, 284, 5, 114, 0, 0, 284, 285, 5, 99, 0, 0, 285, 295, 5, 101, 0, 0, 286, 287, 5, 66, 0, 0, 287, 288, 5, 108, 0, 0, 288, 289, 5, 117, 0, 0, 289, 290, 5, 100, 0, 0, 290, 291, 5, 103, 0, 0, 291, 292, 5, 101, 0, 0, 292, 293, 5, 111, 0, 0, 293, 295, 5, 110, 0, 0, 294, 275, 1, 0, 0, 0, 294, 280, 1, 0, 0, 0, 294, 286, 1, 0, 0, 0, 295, 28, 1, 0, 0, 0, 296, 297, 5, 65, 0, 0, 297, 298, 5, 105, 0, 0, 298, 351, 5, 114, 0, 0, 299, 300, 5, 69, 0, 0, 300, 301, 5, 97, 0, 0, 301, 302, 5, 114, 0, 0, 302, 303, 5, 116, 0, 0, 303, 351, 5, 104, 0, 0, 304, 305, 5, 70, 0, 0, 305, 306, 5, 105, 0, 0, 306, 307, 5, 114, 0, 0, 307, 351, 5, 101, 0, 0, 308, 309, 5, 70, 0, 0, 309, 310, 5, 111, 0, 0, 310, 311, 5, 114, 0, 0, 311, 312, 5, 99, 0, 0, 312, 351, 5, 101, 0, 0, 313, 314, 5, 76, 0, 0, 314, 315, 5, 105, 0, 0, 315, 316, 5, 103, 0, 0, 316, 317, 5, 104, 0, 0, 317, 351, 5, 116, 0, 0, 318, 319, 5, 80, 0, 0, 319, 320, 5, 111, 0, 0, 320, 321, 5, 105, 0, 0, 321, 322, 5, 115, 0, 0, 322, 323, 5, 111, 0, 0, 323, 351, 5, 110, 0, 0, 324, 325, 5, 83, 0, 0, 325, 326, 5, 111, 0, 0, 326, 327, 5, 110, 0, 0, 327, 328, 5, 105, 0, 0, 328, 351, 5, 99, 0, 0, 329, 330, 5, 87, 0, 0, 330, 331, 5, 97, 0, 0, 331, 332, 5, 116, 0, 0, 332, 333, 5, 101, 0, 0, 333, 351, 5, 114, 0, 0, 334, 335, 5, 78, 0, 0, 335, 336, 5, 101, 0, 0, 336, 337, 5, 103, 0, 0, 337, 338, 5, 97, 0, 0, 338, 339, 5, 116, 0, 0, 339, 340, 5, 105, 0, 0, 340, 341, 5, 118, 0, 0, 341, 351, 5, 101, 0, 0, 342, 343, 5, 80, 0, 0, 343, 344, 5, 111, 0, 0, 344, 345, 5, 115, 0, 0, 345, 346, 5, 105, 0, 0, 346, 347, 5, 116, 0, 0, 347, 348, 5, 105, 0, 0, 348, 349, 5, 118, 0, 0, 349, 351, 5, 101, 0, 0, 350, 296, 1, 0, 0, 0, 350, 299, 1, 0, 0, 0, 350, 304, 1, 0, 0, 0, 350, 308, 1, 0, 0, 0, 350, 313, 1, 0, 0, 0, 350, 318, 1, 0, 0, 0, 350, 324, 1, 0, 0, 0, 350, 329, 1, 0, 0, 0, 350, 334, 1, 0, 0, 0, 350, 342, 1, 0, 0, 0, 351, 30, 1, 0, 0, 0, 352, 353, 5, 65, 0, 0, 353, 354, 5, 99, 0, 0, 354, 355, 5, 105, 0, 0, 355, 361, 5, 100, 0, 0, 356, 357, 5, 67, 0, 0, 357, 358, 5, 111, 0, 0, 358, 359, 5, 108, 0, 0, 359, 361, 5, 100, 0, 0, 360, 352, 1, 0, 0, 0, 360, 356, 1, 0, 0, 0, 361, 32, 1, 0, 0, 0, 362, 363, 3, 45, 22, 0, 363, 364, 5, 32, 0, 0, 364, 365, 3, 35, 17, 0, 365, 366, 5, 32, 0, 0, 366, 367, 3, 47, 23, 0, 367, 34, 1, 0, 0, 0, 368, 369, 5, 65, 0, 0, 369, 370, 5, 117, 0, 0, 370, 371, 5, 103, 0, 0, 371, 372, 5, 109, 0, 0, 372, 373, 5, 101, 0, 0, 373, 374, 5, 110, 0, 0, 374, 375, 5, 116, 0, 0, 375, 376, 5, 32, 0, 0, 376, 377, 5, 83, 0, 0, 377, 378, 5, 108, 0, 0, 378, 379, 5, 111, 0, 0, 379, 380, 5, 116, 0, 0, 380, 381, 5, 58, 0, 0, 381, 36, 1, 0, 0, 0, 382, 383, 5, 69, 0, 0, 383, 384, 5, 110, 0, 0, 384, 385, 5, 104, 0, 0, 385, 386, 5, 97, 0, 0, 386, 387, 5, 110, 0, 0, 387, 388, 5, 99, 0, 0, 388, 389, 5, 101, 0, 0, 389, 390, 5, 109, 0, 0, 390, 391, 5, 101, 0, 0, 391, 392, 5, 110, 0, 0, 392, 393, 5, 116, 0, 0, 393, 394, 5, 32, 0, 0, 394, 395, 5, 66, 0, 0, 395, 396, 5, 111, 0, 0, 396, 397, 5, 110, 0, 0, 397, 398, 5, 117, 0, 0, 398, 399, 5, 115, 0, 0, 399, 38, 1, 0, 0, 0, 400, 401, 5, 70, 0, 0, 401, 402, 5, 111, 0, 0, 402, 403, 5, 114, 0, 0, 403, 404, 5, 116, 0, 0, 404, 405, 5, 105, 0, 0, 405, 406, 5, 102, 0, 0, 406, 407, 5, 105, 0, 0, 407, 408, 5, 99, 0, 0, 408, 409, 5, 97, 0, 0, 409, 410, 5, 116, 0, 0, 410, 411, 5, 105, 0, 0, 411, 412, 5, 111, 0, 0, 412, 413, 5, 110, 0, 0, 413, 40, 1, 0, 0, 0, 414, 415, 3, 43, 21, 0, 415, 416, 5, 32, 0, 0, 416, 417, 5, 83, 0, 0, 417, 418, 5, 104, 0, 0, 418, 419, 5, 101, 0, 0, 419, 420, 5, 108, 0, 0, 420, 421, 5, 116, 0, 0, 421, 422, 5, 101, 0, 0, 422, 423, 5, 114, 0, 0, 423, 424, 5, 105, 0, 0, 424, 425, 5, 110, 0, 0, 425, 426, 5, 103, 0, 0, 426, 42, 1, 0, 0, 0, 427, 428, 5, 80, 0, 0, 428, 429, 5, 104, 0, 0, 429, 430, 5, 121, 0, 0, 430, 431, 5, 115, 0, 0, 431, 432, 5, 105, 0, 0, 432, 433, 5, 99, 0, 0, 433, 434, 5, 97, 0, 0, 434, 435, 5, 108, 0, 0, 435, 436, 5, 32, 0, 0, 436, 437, 5, 97, 0, 0, 437, 438, 5, 110, 0, 0, 438, 439, 5, 100, 0, 0, 439, 440, 5, 32, 0, 0, 440, 441, 5, 77, 0, 0, 441, 442, 5, 97, 0, 0, 442, 443, 5, 103, 0, 0, 443, 444, 5, 105, 0, 0, 444, 445, 5, 99, 0, 0, 445, 446, 5, 97, 0, 0, 446, 463, 5, 108, 0, 0, 447, 448, 5, 80, 0, 0, 448, 449, 5, 104, 0, 0, 449, 450, 5, 121, 0, 0, 450, 451, 5, 115, 0, 0, 451, 452, 5, 105, 0, 0, 452, 453, 5, 99, 0, 0, 453, 454, 5, 97, 0, 0, 454, 463, 5, 108, 0, 0, 455, 456, 5, 77, 0, 0, 456, 457, 5, 97, 0, 0, 457, 458, 5, 103, 0, 0, 458, 459, 5, 105, 0, 0, 459, 460, 5, 99, 0, 0, 460, 461, 5, 97, 0, 0, 461, 463, 5, 108, 0, 0, 462, 427, 1, 0, 0, 0, 462, 447, 1, 0, 0, 0, 462, 455, 1, 0, 0, 0, 463, 44, 1, 0, 0, 0, 464, 465, 5, 66, 0, 0, 465, 466, 5, 108, 0, 0, 466, 467, 5, 117, 0, 0, 467, 504, 5, 101, 0, 0, 468, 469, 5, 79, 0, 0, 469, 470, 5, 114, 0, 0, 470, 471, 5, 97, 0, 0, 471, 472, 5, 110, 0, 0, 472, 473, 5, 103, 0, 0, 473, 504, 5, 101, 0, 0, 474, 475, 5, 89, 0, 0, 475, 476, 5, 101, 0, 0, 476, 477, 5, 108, 0, 0, 477, 478, 5, 108, 0, 0, 478, 479, 5, 111, 0, 0, 479, 504, 5, 119, 0, 0, 480, 481, 5, 82, 0, 0, 481, 482, 5, 101, 0, 0, 482, 504, 5, 100, 0, 0, 483, 484, 5, 71, 0, 0, 484, 485, 5, 114, 0, 0, 485, 486, 5, 101, 0, 0, 486, 487, 5, 101, 0, 0, 487, 504, 5, 110, 0, 0, 488, 489, 5, 80, 0, 0, 489, 490, 5, 117, 0, 0, 490, 491, 5, 114, 0, 0, 491, 492, 5, 112, 0, 0, 492, 493, 5, 108, 0, 0, 493, 504, 5, 101, 0, 0, 494, 495, 5, 67, 0, 0, 495, 496, 5, 111, 0, 0, 496, 497, 5, 108, 0, 0, 497, 498, 5, 111, 0, 0, 498, 499, 5, 114, 0, 0, 499, 500, 5, 108, 0, 0, 500, 501, 5, 101, 0, 0, 501, 502, 5, 115, 0, 0, 502, 504, 5, 115, 0, 0, 503, 464, 1, 0, 0, 0, 503, 468, 1, 0, 0, 0, 503, 474, 1, 0, 0, 0, 503, 480, 1, 0, 0, 0, 503, 483, 1, 0, 0, 0, 503, 488, 1, 0, 0, 0, 503, 494, 1, 0, 0, 0, 504, 46, 1, 0, 0, 0, 505, 508, 3, 51, 25, 0, 506, 508, 3, 49, 24, 0, 507, 505, 1, 0, 0, 0, 507, 506, 1, 0, 0, 0, 508, 48, 1, 0, 0, 0, 509, 510, 5, 116, 0, 0, 510, 511, 5, 111, 0, 0, 511, 512, 5, 100, 0, 0, 512, 513, 5, 111, 0, 0, 513, 514, 5, 58, 0, 0, 514, 515, 5, 77, 0, 0, 515, 516, 5, 65, 0, 0, 516, 517, 5, 82, 0, 0, 517, 518, 5, 75, 0, 0, 518, 519, 5, 69, 0, 0, 519, 520, 5, 82, 0, 0, 520, 521, 5, 32, 0, 0, 521, 50, 1, 0, 0, 0, 522, 523, 5, 69, 0, 0, 523, 524, 5, 109, 0, 0, 524, 525, 5, 112, 0, 0, 525, 526, 5, 116, 0, 0, 526, 527, 5, 121, 0, 0, 527, 52, 1, 0, 0, 0, 528, 530, 7, 0, 0, 0, 529, 528, 1, 0, 0, 0, 530, 531, 1, 0, 0, 0, 531, 529, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 533, 1, 0, 0, 0, 533, 534, 6, 26, 1, 0, 534, 54, 1, 0, 0, 0, 535, 537, 3, 57, 28, 0, 536, 535, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 536, 1, 0, 0, 0, 538, 539, 1, 0, 0, 0, 539, 540, 1, 0, 0, 0, 540, 541, 5, 37, 0, 0, 541, 56, 1, 0, 0, 0, 542, 544, 3, 59, 29, 0, 543, 542, 1, 0, 0, 0, 544, 545, 1, 0, 0, 0, 545, 543, 1, 0, 0, 0, 545, 546, 1, 0, 0, 0, 546, 547, 1, 0, 0, 0, 547, 548, 3, 61, 30, 0, 548, 58, 1, 0, 0, 0, 549, 550, 7, 1, 0, 0, 550, 60, 1, 0, 0, 0, 551, 553, 7, 2, 0, 0, 552, 551, 1, 0, 0, 0, 553, 554, 1, 0, 0, 0, 554, 552, 1, 0, 0, 0, 554, 555, 1, 0, 0, 0, 555, 62, 1, 0, 0, 0, 556, 560, 3, 65, 32, 0, 557, 560, 3, 69, 34, 0, 558, 560, 3, 67, 33, 0, 559, 556, 1, 0, 0, 0, 559, 557, 1, 0, 0, 0, 559, 558, 1, 0, 0, 0, 560, 64, 1, 0, 0, 0, 561, 563, 3, 67, 33, 0, 562, 561, 1, 0, 0, 0, 563, 564, 1, 0, 0, 0, 564, 562, 1, 0, 0, 0, 564, 565, 1, 0, 0, 0, 565, 567, 1, 0, 0, 0, 566, 568, 5, 32, 0, 0, 567, 566, 1, 0, 0, 0, 568, 569, 1, 0, 0, 0, 569, 567, 1, 0, 0, 0, 569, 570, 1, 0, 0, 0, 570, 571, 1, 0, 0, 0, 571, 572, 3, 69, 34, 0, 572, 66, 1, 0, 0, 0, 573, 575, 3, 69, 34, 0, 574, 573, 1, 0, 0, 0, 575, 576, 1, 0, 0, 0, 576, 574, 1, 0, 0, 0, 576, 577, 1, 0, 0, 0, 577, 579, 1, 0, 0, 0, 578, 580, 5, 32, 0, 0, 579, 578, 1, 0, 0, 0, 580, 581, 1, 0, 0, 0, 581, 579, 1, 0, 0, 0, 581, 582, 1, 0, 0, 0, 582, 583, 1, 0, 0, 0, 583, 584, 3, 69, 34, 0, 584, 68, 1, 0, 0, 0, 585, 587, 7, 3, 0, 0, 586, 585, 1, 0, 0, 0, 587, 588, 1, 0, 0, 0, 588, 586, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 591, 1, 0, 0, 0, 590, 592, 7, 4, 0, 0, 591, 590, 1, 0, 0, 0, 592, 593, 1, 0, 0, 0, 593, 591, 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 70, 1, 0, 0, 0, 27, 0, 72, 76, 86, 162, 166, 189, 203, 226, 273, 294, 350, 360, 462, 503, 507, 531, 538, 545, 554, 559, 564, 569, 576, 581, 588, 593, 2, 6, 0, 0, 0, 1, 0] \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.java b/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.java new file mode 100644 index 00000000..909a681a --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.java @@ -0,0 +1,512 @@ +// Generated from /home/adarro/projects/ddo-calc/subprojects/common/ddo-antlr/src/main/antlr/EnchantmentsLexer.g4 by ANTLR 4.12.0 +package io.truthencode.ddo.grammar.antlr; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class EnchantmentsLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.12.0", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + LineBreak=1, ENCHANTMENT=2, MYTHIC_BOOST=3, CORE_BODY_SLOT=4, HAND_SLOT=5, + AUXILLARY_BODY_SLOT=6, DAMAGE_TYPE=7, AUGMENTSLOT=8, LBL_AUGMENT_SLOT=9, + ENHANCEMENT_BONUS=10, FORT=11, SHELTERING=12, SHELTERTYPE=13, AUGMENTCOLOR=14, + AUGMENTOPTION=15, FilledAugmentSlot=16, EmptyAugmentSlot=17, WS=18, PCT=19, + NUM=20, SIGN=21, UNKNOWN_ID=22; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "LineBreak", "ENCHANTMENT", "MYTHIC_BOOST", "MYTHIC_KEYWORD", "MYTHIC_SLOT", + "CORE_BODY_SLOT", "HAND_SLOT", "MAIN_HAND", "OFF_HAND", "AUXILLARY_BODY_SLOT", + "DAMAGE_TYPE", "ALIGNMENT_DAMAGE_TYPE", "MATERIAL_DAMAGE_TYPE", "PHYSICAL_DAMAGE_TYPE", + "ELEMENTAL_DAMAGE_TYPE", "ELEMENTAL_SUB_TYPE", "AUGMENTSLOT", "LBL_AUGMENT_SLOT", + "ENHANCEMENT_BONUS", "FORT", "SHELTERING", "SHELTERTYPE", "AUGMENTCOLOR", + "AUGMENTOPTION", "FilledAugmentSlot", "EmptyAugmentSlot", "WS", "PCT", + "NUM", "SIGN", "UNUM", "UNKNOWN_ID", "MULTI_WORDS", "MULTI_WORD", "SIMPLE_WORD" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, "'Quiver'", null, null, "'Augment Slot:'", + "'Enhancement Bonus'", "'Fortification'", null, null, null, null, "'todo:MARKER '", + "'Empty'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "LineBreak", "ENCHANTMENT", "MYTHIC_BOOST", "CORE_BODY_SLOT", "HAND_SLOT", + "AUXILLARY_BODY_SLOT", "DAMAGE_TYPE", "AUGMENTSLOT", "LBL_AUGMENT_SLOT", + "ENHANCEMENT_BONUS", "FORT", "SHELTERING", "SHELTERTYPE", "AUGMENTCOLOR", + "AUGMENTOPTION", "FilledAugmentSlot", "EmptyAugmentSlot", "WS", "PCT", + "NUM", "SIGN", "UNKNOWN_ID" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public EnchantmentsLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "EnchantmentsLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\u0004\u0000\u0016\u0253\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+ + "\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+ + "\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+ + "\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+ + "\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+ + "\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+ + "\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+ + "\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+ + "\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+ + "\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+ + "\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"+ + "\u0007!\u0002\"\u0007\"\u0001\u0000\u0003\u0000I\b\u0000\u0001\u0000\u0001"+ + "\u0000\u0003\u0000M\b\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0001W\b"+ + "\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+ + "\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001"+ + "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+ + "\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00a3\b\u0005\u0001\u0006\u0001"+ + "\u0006\u0003\u0006\u00a7\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001"+ + "\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001"+ + "\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+ + "\b\u0001\b\u0003\b\u00be\b\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+ + "\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0003\n\u00cc\b\n\u0001"+ + "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+ + "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+ + "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001"+ + "\u000b\u0001\u000b\u0001\u000b\u0003\u000b\u00e3\b\u000b\u0001\f\u0001"+ + "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+ + "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+ + "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+ + "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+ + "\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0003\f\u0112"+ + "\b\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ + "\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ + "\r\u0001\r\u0003\r\u0127\b\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0003\u000e\u015f\b\u000e\u0001\u000f\u0001"+ + "\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+ + "\u000f\u0003\u000f\u0169\b\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001"+ + "\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001"+ + "\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001"+ + "\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001"+ + "\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001"+ + "\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001"+ + "\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0013\u0001"+ + "\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001"+ + "\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001"+ + "\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001"+ + "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001"+ + "\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ + "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ + "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ + "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ + "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ + "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ + "\u0015\u0003\u0015\u01cf\b\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+ + "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+ + "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+ + "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+ + "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+ + "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+ + "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0003"+ + "\u0016\u01f8\b\u0016\u0001\u0017\u0001\u0017\u0003\u0017\u01fc\b\u0017"+ + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018"+ + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018"+ + "\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+ + "\u0001\u0019\u0001\u001a\u0004\u001a\u0212\b\u001a\u000b\u001a\f\u001a"+ + "\u0213\u0001\u001a\u0001\u001a\u0001\u001b\u0004\u001b\u0219\b\u001b\u000b"+ + "\u001b\f\u001b\u021a\u0001\u001b\u0001\u001b\u0001\u001c\u0004\u001c\u0220"+ + "\b\u001c\u000b\u001c\f\u001c\u0221\u0001\u001c\u0001\u001c\u0001\u001d"+ + "\u0001\u001d\u0001\u001e\u0004\u001e\u0229\b\u001e\u000b\u001e\f\u001e"+ + "\u022a\u0001\u001f\u0001\u001f\u0001\u001f\u0003\u001f\u0230\b\u001f\u0001"+ + " \u0004 \u0233\b \u000b \f \u0234\u0001 \u0004 \u0238\b \u000b \f \u0239"+ + "\u0001 \u0001 \u0001!\u0004!\u023f\b!\u000b!\f!\u0240\u0001!\u0004!\u0244"+ + "\b!\u000b!\f!\u0245\u0001!\u0001!\u0001\"\u0004\"\u024b\b\"\u000b\"\f"+ + "\"\u024c\u0001\"\u0004\"\u0250\b\"\u000b\"\f\"\u0251\u0000\u0000#\u0001"+ + "\u0001\u0003\u0002\u0005\u0003\u0007\u0000\t\u0000\u000b\u0004\r\u0005"+ + "\u000f\u0000\u0011\u0000\u0013\u0006\u0015\u0007\u0017\u0000\u0019\u0000"+ + "\u001b\u0000\u001d\u0000\u001f\u0000!\b#\t%\n\'\u000b)\f+\r-\u000e/\u000f"+ + "1\u00103\u00115\u00127\u00139\u0014;\u0015=\u0000?\u0016A\u0000C\u0000"+ + "E\u0000\u0001\u0000\u0005\u0003\u0000\t\n\r\r \u0002\u0000++--\u0001"+ + "\u000009\u0002\u0000AZaz\u0001\u0000az\u0287\u0000\u0001\u0001\u0000\u0000"+ + "\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000"+ + "\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000"+ + "\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000"+ + "\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%"+ + "\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001"+ + "\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000"+ + "\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u0000"+ + "3\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001"+ + "\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000"+ + "\u0000\u0000?\u0001\u0000\u0000\u0000\u0001L\u0001\u0000\u0000\u0000\u0003"+ + "V\u0001\u0000\u0000\u0000\u0005X\u0001\u0000\u0000\u0000\u0007b\u0001"+ + "\u0000\u0000\u0000\ti\u0001\u0000\u0000\u0000\u000b\u00a2\u0001\u0000"+ + "\u0000\u0000\r\u00a6\u0001\u0000\u0000\u0000\u000f\u00a8\u0001\u0000\u0000"+ + "\u0000\u0011\u00bd\u0001\u0000\u0000\u0000\u0013\u00bf\u0001\u0000\u0000"+ + "\u0000\u0015\u00cb\u0001\u0000\u0000\u0000\u0017\u00e2\u0001\u0000\u0000"+ + "\u0000\u0019\u0111\u0001\u0000\u0000\u0000\u001b\u0126\u0001\u0000\u0000"+ + "\u0000\u001d\u015e\u0001\u0000\u0000\u0000\u001f\u0168\u0001\u0000\u0000"+ + "\u0000!\u016a\u0001\u0000\u0000\u0000#\u0170\u0001\u0000\u0000\u0000%"+ + "\u017e\u0001\u0000\u0000\u0000\'\u0190\u0001\u0000\u0000\u0000)\u019e"+ + "\u0001\u0000\u0000\u0000+\u01ce\u0001\u0000\u0000\u0000-\u01f7\u0001\u0000"+ + "\u0000\u0000/\u01fb\u0001\u0000\u0000\u00001\u01fd\u0001\u0000\u0000\u0000"+ + "3\u020a\u0001\u0000\u0000\u00005\u0211\u0001\u0000\u0000\u00007\u0218"+ + "\u0001\u0000\u0000\u00009\u021f\u0001\u0000\u0000\u0000;\u0225\u0001\u0000"+ + "\u0000\u0000=\u0228\u0001\u0000\u0000\u0000?\u022f\u0001\u0000\u0000\u0000"+ + "A\u0232\u0001\u0000\u0000\u0000C\u023e\u0001\u0000\u0000\u0000E\u024a"+ + "\u0001\u0000\u0000\u0000GI\u0005\r\u0000\u0000HG\u0001\u0000\u0000\u0000"+ + "HI\u0001\u0000\u0000\u0000IJ\u0001\u0000\u0000\u0000JM\u0005\n\u0000\u0000"+ + "KM\u0005\r\u0000\u0000LH\u0001\u0000\u0000\u0000LK\u0001\u0000\u0000\u0000"+ + "MN\u0001\u0000\u0000\u0000NO\u0006\u0000\u0000\u0000O\u0002\u0001\u0000"+ + "\u0000\u0000PW\u0003\'\u0013\u0000QW\u0003!\u0010\u0000RW\u0003%\u0012"+ + "\u0000SW\u0003)\u0014\u0000TW\u0003\u0015\n\u0000UW\u0003\u0005\u0002"+ + "\u0000VP\u0001\u0000\u0000\u0000VQ\u0001\u0000\u0000\u0000VR\u0001\u0000"+ + "\u0000\u0000VS\u0001\u0000\u0000\u0000VT\u0001\u0000\u0000\u0000VU\u0001"+ + "\u0000\u0000\u0000W\u0004\u0001\u0000\u0000\u0000XY\u0003\u0007\u0003"+ + "\u0000YZ\u0005 \u0000\u0000Z[\u0003\t\u0004\u0000[\\\u0005 \u0000\u0000"+ + "\\]\u0005B\u0000\u0000]^\u0005o\u0000\u0000^_\u0005o\u0000\u0000_`\u0005"+ + "s\u0000\u0000`a\u0005t\u0000\u0000a\u0006\u0001\u0000\u0000\u0000bc\u0005"+ + "M\u0000\u0000cd\u0005y\u0000\u0000de\u0005t\u0000\u0000ef\u0005h\u0000"+ + "\u0000fg\u0005i\u0000\u0000gh\u0005c\u0000\u0000h\b\u0001\u0000\u0000"+ + "\u0000ij\u0003\u000b\u0005\u0000j\n\u0001\u0000\u0000\u0000kl\u0005A\u0000"+ + "\u0000lm\u0005r\u0000\u0000mn\u0005m\u0000\u0000no\u0005o\u0000\u0000"+ + "o\u00a3\u0005r\u0000\u0000pq\u0005B\u0000\u0000qr\u0005e\u0000\u0000r"+ + "s\u0005l\u0000\u0000s\u00a3\u0005t\u0000\u0000tu\u0005B\u0000\u0000uv"+ + "\u0005o\u0000\u0000vw\u0005o\u0000\u0000w\u00a3\u0005t\u0000\u0000xy\u0005"+ + "C\u0000\u0000yz\u0005l\u0000\u0000z{\u0005o\u0000\u0000{|\u0005a\u0000"+ + "\u0000|\u00a3\u0005k\u0000\u0000}~\u0005G\u0000\u0000~\u007f\u0005o\u0000"+ + "\u0000\u007f\u0080\u0005o\u0000\u0000\u0080\u0081\u0005g\u0000\u0000\u0081"+ + "\u0082\u0005l\u0000\u0000\u0082\u00a3\u0005e\u0000\u0000\u0083\u0084\u0005"+ + "H\u0000\u0000\u0084\u0085\u0005a\u0000\u0000\u0085\u0086\u0005n\u0000"+ + "\u0000\u0086\u0087\u0005d\u0000\u0000\u0087\u00a3\u0005s\u0000\u0000\u0088"+ + "\u0089\u0005H\u0000\u0000\u0089\u008a\u0005e\u0000\u0000\u008a\u008b\u0005"+ + "a\u0000\u0000\u008b\u00a3\u0005d\u0000\u0000\u008c\u008d\u0005N\u0000"+ + "\u0000\u008d\u008e\u0005e\u0000\u0000\u008e\u008f\u0005c\u0000\u0000\u008f"+ + "\u00a3\u0005k\u0000\u0000\u0090\u0091\u0005R\u0000\u0000\u0091\u0092\u0005"+ + "i\u0000\u0000\u0092\u0093\u0005n\u0000\u0000\u0093\u00a3\u0005g\u0000"+ + "\u0000\u0094\u0095\u0005T\u0000\u0000\u0095\u0096\u0005r\u0000\u0000\u0096"+ + "\u0097\u0005i\u0000\u0000\u0097\u0098\u0005n\u0000\u0000\u0098\u0099\u0005"+ + "k\u0000\u0000\u0099\u009a\u0005e\u0000\u0000\u009a\u00a3\u0005t\u0000"+ + "\u0000\u009b\u009c\u0005W\u0000\u0000\u009c\u009d\u0005r\u0000\u0000\u009d"+ + "\u009e\u0005i\u0000\u0000\u009e\u009f\u0005s\u0000\u0000\u009f\u00a3\u0005"+ + "t\u0000\u0000\u00a0\u00a3\u0003\u000f\u0007\u0000\u00a1\u00a3\u0003\u0011"+ + "\b\u0000\u00a2k\u0001\u0000\u0000\u0000\u00a2p\u0001\u0000\u0000\u0000"+ + "\u00a2t\u0001\u0000\u0000\u0000\u00a2x\u0001\u0000\u0000\u0000\u00a2}"+ + "\u0001\u0000\u0000\u0000\u00a2\u0083\u0001\u0000\u0000\u0000\u00a2\u0088"+ + "\u0001\u0000\u0000\u0000\u00a2\u008c\u0001\u0000\u0000\u0000\u00a2\u0090"+ + "\u0001\u0000\u0000\u0000\u00a2\u0094\u0001\u0000\u0000\u0000\u00a2\u009b"+ + "\u0001\u0000\u0000\u0000\u00a2\u00a0\u0001\u0000\u0000\u0000\u00a2\u00a1"+ + "\u0001\u0000\u0000\u0000\u00a3\f\u0001\u0000\u0000\u0000\u00a4\u00a7\u0003"+ + "\u000f\u0007\u0000\u00a5\u00a7\u0003\u0011\b\u0000\u00a6\u00a4\u0001\u0000"+ + "\u0000\u0000\u00a6\u00a5\u0001\u0000\u0000\u0000\u00a7\u000e\u0001\u0000"+ + "\u0000\u0000\u00a8\u00a9\u0005W\u0000\u0000\u00a9\u00aa\u0005e\u0000\u0000"+ + "\u00aa\u00ab\u0005a\u0000\u0000\u00ab\u00ac\u0005p\u0000\u0000\u00ac\u00ad"+ + "\u0005o\u0000\u0000\u00ad\u00ae\u0005n\u0000\u0000\u00ae\u0010\u0001\u0000"+ + "\u0000\u0000\u00af\u00b0\u0005S\u0000\u0000\u00b0\u00b1\u0005h\u0000\u0000"+ + "\u00b1\u00b2\u0005i\u0000\u0000\u00b2\u00b3\u0005e\u0000\u0000\u00b3\u00b4"+ + "\u0005l\u0000\u0000\u00b4\u00be\u0005d\u0000\u0000\u00b5\u00b6\u0005O"+ + "\u0000\u0000\u00b6\u00b7\u0005f\u0000\u0000\u00b7\u00b8\u0005f\u0000\u0000"+ + "\u00b8\u00b9\u0005-\u0000\u0000\u00b9\u00ba\u0005h\u0000\u0000\u00ba\u00bb"+ + "\u0005a\u0000\u0000\u00bb\u00bc\u0005n\u0000\u0000\u00bc\u00be\u0005d"+ + "\u0000\u0000\u00bd\u00af\u0001\u0000\u0000\u0000\u00bd\u00b5\u0001\u0000"+ + "\u0000\u0000\u00be\u0012\u0001\u0000\u0000\u0000\u00bf\u00c0\u0005Q\u0000"+ + "\u0000\u00c0\u00c1\u0005u\u0000\u0000\u00c1\u00c2\u0005i\u0000\u0000\u00c2"+ + "\u00c3\u0005v\u0000\u0000\u00c3\u00c4\u0005e\u0000\u0000\u00c4\u00c5\u0005"+ + "r\u0000\u0000\u00c5\u0014\u0001\u0000\u0000\u0000\u00c6\u00cc\u0003\u0017"+ + "\u000b\u0000\u00c7\u00cc\u0003\u0019\f\u0000\u00c8\u00cc\u0003\u001b\r"+ + "\u0000\u00c9\u00cc\u0003\u001d\u000e\u0000\u00ca\u00cc\u0003\u001f\u000f"+ + "\u0000\u00cb\u00c6\u0001\u0000\u0000\u0000\u00cb\u00c7\u0001\u0000\u0000"+ + "\u0000\u00cb\u00c8\u0001\u0000\u0000\u0000\u00cb\u00c9\u0001\u0000\u0000"+ + "\u0000\u00cb\u00ca\u0001\u0000\u0000\u0000\u00cc\u0016\u0001\u0000\u0000"+ + "\u0000\u00cd\u00ce\u0005C\u0000\u0000\u00ce\u00cf\u0005h\u0000\u0000\u00cf"+ + "\u00d0\u0005a\u0000\u0000\u00d0\u00d1\u0005o\u0000\u0000\u00d1\u00d2\u0005"+ + "t\u0000\u0000\u00d2\u00d3\u0005i\u0000\u0000\u00d3\u00e3\u0005c\u0000"+ + "\u0000\u00d4\u00d5\u0005E\u0000\u0000\u00d5\u00d6\u0005v\u0000\u0000\u00d6"+ + "\u00d7\u0005i\u0000\u0000\u00d7\u00e3\u0005l\u0000\u0000\u00d8\u00d9\u0005"+ + "G\u0000\u0000\u00d9\u00da\u0005o\u0000\u0000\u00da\u00db\u0005o\u0000"+ + "\u0000\u00db\u00e3\u0005d\u0000\u0000\u00dc\u00dd\u0005L\u0000\u0000\u00dd"+ + "\u00de\u0005a\u0000\u0000\u00de\u00df\u0005w\u0000\u0000\u00df\u00e0\u0005"+ + "f\u0000\u0000\u00e0\u00e1\u0005u\u0000\u0000\u00e1\u00e3\u0005l\u0000"+ + "\u0000\u00e2\u00cd\u0001\u0000\u0000\u0000\u00e2\u00d4\u0001\u0000\u0000"+ + "\u0000\u00e2\u00d8\u0001\u0000\u0000\u0000\u00e2\u00dc\u0001\u0000\u0000"+ + "\u0000\u00e3\u0018\u0001\u0000\u0000\u0000\u00e4\u00e5\u0005S\u0000\u0000"+ + "\u00e5\u00e6\u0005i\u0000\u0000\u00e6\u00e7\u0005l\u0000\u0000\u00e7\u00e8"+ + "\u0005v\u0000\u0000\u00e8\u00e9\u0005e\u0000\u0000\u00e9\u0112\u0005r"+ + "\u0000\u0000\u00ea\u00eb\u0005B\u0000\u0000\u00eb\u00ec\u0005y\u0000\u0000"+ + "\u00ec\u00ed\u0005s\u0000\u0000\u00ed\u00ee\u0005h\u0000\u0000\u00ee\u00ef"+ + "\u0005e\u0000\u0000\u00ef\u0112\u0005k\u0000\u0000\u00f0\u00f1\u0005A"+ + "\u0000\u0000\u00f1\u00f2\u0005d\u0000\u0000\u00f2\u00f3\u0005a\u0000\u0000"+ + "\u00f3\u00f4\u0005m\u0000\u0000\u00f4\u00f5\u0005a\u0000\u0000\u00f5\u00f6"+ + "\u0005n\u0000\u0000\u00f6\u00f7\u0005t\u0000\u0000\u00f7\u00f8\u0005i"+ + "\u0000\u0000\u00f8\u00f9\u0005n\u0000\u0000\u00f9\u0112\u0005e\u0000\u0000"+ + "\u00fa\u00fb\u0005C\u0000\u0000\u00fb\u00fc\u0005o\u0000\u0000\u00fc\u00fd"+ + "\u0005l\u0000\u0000\u00fd\u00fe\u0005d\u0000\u0000\u00fe\u00ff\u0005 "+ + "\u0000\u0000\u00ff\u0100\u0005i\u0000\u0000\u0100\u0101\u0005r\u0000\u0000"+ + "\u0101\u0102\u0005o\u0000\u0000\u0102\u0112\u0005n\u0000\u0000\u0103\u0104"+ + "\u0005C\u0000\u0000\u0104\u0105\u0005r\u0000\u0000\u0105\u0106\u0005y"+ + "\u0000\u0000\u0106\u0107\u0005s\u0000\u0000\u0107\u0108\u0005t\u0000\u0000"+ + "\u0108\u0109\u0005a\u0000\u0000\u0109\u0112\u0005l\u0000\u0000\u010a\u010b"+ + "\u0005M\u0000\u0000\u010b\u010c\u0005i\u0000\u0000\u010c\u010d\u0005t"+ + "\u0000\u0000\u010d\u010e\u0005h\u0000\u0000\u010e\u010f\u0005r\u0000\u0000"+ + "\u010f\u0110\u0005a\u0000\u0000\u0110\u0112\u0005l\u0000\u0000\u0111\u00e4"+ + "\u0001\u0000\u0000\u0000\u0111\u00ea\u0001\u0000\u0000\u0000\u0111\u00f0"+ + "\u0001\u0000\u0000\u0000\u0111\u00fa\u0001\u0000\u0000\u0000\u0111\u0103"+ + "\u0001\u0000\u0000\u0000\u0111\u010a\u0001\u0000\u0000\u0000\u0112\u001a"+ + "\u0001\u0000\u0000\u0000\u0113\u0114\u0005S\u0000\u0000\u0114\u0115\u0005"+ + "l\u0000\u0000\u0115\u0116\u0005a\u0000\u0000\u0116\u0117\u0005s\u0000"+ + "\u0000\u0117\u0127\u0005h\u0000\u0000\u0118\u0119\u0005P\u0000\u0000\u0119"+ + "\u011a\u0005i\u0000\u0000\u011a\u011b\u0005e\u0000\u0000\u011b\u011c\u0005"+ + "r\u0000\u0000\u011c\u011d\u0005c\u0000\u0000\u011d\u0127\u0005e\u0000"+ + "\u0000\u011e\u011f\u0005B\u0000\u0000\u011f\u0120\u0005l\u0000\u0000\u0120"+ + "\u0121\u0005u\u0000\u0000\u0121\u0122\u0005d\u0000\u0000\u0122\u0123\u0005"+ + "g\u0000\u0000\u0123\u0124\u0005e\u0000\u0000\u0124\u0125\u0005o\u0000"+ + "\u0000\u0125\u0127\u0005n\u0000\u0000\u0126\u0113\u0001\u0000\u0000\u0000"+ + "\u0126\u0118\u0001\u0000\u0000\u0000\u0126\u011e\u0001\u0000\u0000\u0000"+ + "\u0127\u001c\u0001\u0000\u0000\u0000\u0128\u0129\u0005A\u0000\u0000\u0129"+ + "\u012a\u0005i\u0000\u0000\u012a\u015f\u0005r\u0000\u0000\u012b\u012c\u0005"+ + "E\u0000\u0000\u012c\u012d\u0005a\u0000\u0000\u012d\u012e\u0005r\u0000"+ + "\u0000\u012e\u012f\u0005t\u0000\u0000\u012f\u015f\u0005h\u0000\u0000\u0130"+ + "\u0131\u0005F\u0000\u0000\u0131\u0132\u0005i\u0000\u0000\u0132\u0133\u0005"+ + "r\u0000\u0000\u0133\u015f\u0005e\u0000\u0000\u0134\u0135\u0005F\u0000"+ + "\u0000\u0135\u0136\u0005o\u0000\u0000\u0136\u0137\u0005r\u0000\u0000\u0137"+ + "\u0138\u0005c\u0000\u0000\u0138\u015f\u0005e\u0000\u0000\u0139\u013a\u0005"+ + "L\u0000\u0000\u013a\u013b\u0005i\u0000\u0000\u013b\u013c\u0005g\u0000"+ + "\u0000\u013c\u013d\u0005h\u0000\u0000\u013d\u015f\u0005t\u0000\u0000\u013e"+ + "\u013f\u0005P\u0000\u0000\u013f\u0140\u0005o\u0000\u0000\u0140\u0141\u0005"+ + "i\u0000\u0000\u0141\u0142\u0005s\u0000\u0000\u0142\u0143\u0005o\u0000"+ + "\u0000\u0143\u015f\u0005n\u0000\u0000\u0144\u0145\u0005S\u0000\u0000\u0145"+ + "\u0146\u0005o\u0000\u0000\u0146\u0147\u0005n\u0000\u0000\u0147\u0148\u0005"+ + "i\u0000\u0000\u0148\u015f\u0005c\u0000\u0000\u0149\u014a\u0005W\u0000"+ + "\u0000\u014a\u014b\u0005a\u0000\u0000\u014b\u014c\u0005t\u0000\u0000\u014c"+ + "\u014d\u0005e\u0000\u0000\u014d\u015f\u0005r\u0000\u0000\u014e\u014f\u0005"+ + "N\u0000\u0000\u014f\u0150\u0005e\u0000\u0000\u0150\u0151\u0005g\u0000"+ + "\u0000\u0151\u0152\u0005a\u0000\u0000\u0152\u0153\u0005t\u0000\u0000\u0153"+ + "\u0154\u0005i\u0000\u0000\u0154\u0155\u0005v\u0000\u0000\u0155\u015f\u0005"+ + "e\u0000\u0000\u0156\u0157\u0005P\u0000\u0000\u0157\u0158\u0005o\u0000"+ + "\u0000\u0158\u0159\u0005s\u0000\u0000\u0159\u015a\u0005i\u0000\u0000\u015a"+ + "\u015b\u0005t\u0000\u0000\u015b\u015c\u0005i\u0000\u0000\u015c\u015d\u0005"+ + "v\u0000\u0000\u015d\u015f\u0005e\u0000\u0000\u015e\u0128\u0001\u0000\u0000"+ + "\u0000\u015e\u012b\u0001\u0000\u0000\u0000\u015e\u0130\u0001\u0000\u0000"+ + "\u0000\u015e\u0134\u0001\u0000\u0000\u0000\u015e\u0139\u0001\u0000\u0000"+ + "\u0000\u015e\u013e\u0001\u0000\u0000\u0000\u015e\u0144\u0001\u0000\u0000"+ + "\u0000\u015e\u0149\u0001\u0000\u0000\u0000\u015e\u014e\u0001\u0000\u0000"+ + "\u0000\u015e\u0156\u0001\u0000\u0000\u0000\u015f\u001e\u0001\u0000\u0000"+ + "\u0000\u0160\u0161\u0005A\u0000\u0000\u0161\u0162\u0005c\u0000\u0000\u0162"+ + "\u0163\u0005i\u0000\u0000\u0163\u0169\u0005d\u0000\u0000\u0164\u0165\u0005"+ + "C\u0000\u0000\u0165\u0166\u0005o\u0000\u0000\u0166\u0167\u0005l\u0000"+ + "\u0000\u0167\u0169\u0005d\u0000\u0000\u0168\u0160\u0001\u0000\u0000\u0000"+ + "\u0168\u0164\u0001\u0000\u0000\u0000\u0169 \u0001\u0000\u0000\u0000\u016a"+ + "\u016b\u0003-\u0016\u0000\u016b\u016c\u0005 \u0000\u0000\u016c\u016d\u0003"+ + "#\u0011\u0000\u016d\u016e\u0005 \u0000\u0000\u016e\u016f\u0003/\u0017"+ + "\u0000\u016f\"\u0001\u0000\u0000\u0000\u0170\u0171\u0005A\u0000\u0000"+ + "\u0171\u0172\u0005u\u0000\u0000\u0172\u0173\u0005g\u0000\u0000\u0173\u0174"+ + "\u0005m\u0000\u0000\u0174\u0175\u0005e\u0000\u0000\u0175\u0176\u0005n"+ + "\u0000\u0000\u0176\u0177\u0005t\u0000\u0000\u0177\u0178\u0005 \u0000\u0000"+ + "\u0178\u0179\u0005S\u0000\u0000\u0179\u017a\u0005l\u0000\u0000\u017a\u017b"+ + "\u0005o\u0000\u0000\u017b\u017c\u0005t\u0000\u0000\u017c\u017d\u0005:"+ + "\u0000\u0000\u017d$\u0001\u0000\u0000\u0000\u017e\u017f\u0005E\u0000\u0000"+ + "\u017f\u0180\u0005n\u0000\u0000\u0180\u0181\u0005h\u0000\u0000\u0181\u0182"+ + "\u0005a\u0000\u0000\u0182\u0183\u0005n\u0000\u0000\u0183\u0184\u0005c"+ + "\u0000\u0000\u0184\u0185\u0005e\u0000\u0000\u0185\u0186\u0005m\u0000\u0000"+ + "\u0186\u0187\u0005e\u0000\u0000\u0187\u0188\u0005n\u0000\u0000\u0188\u0189"+ + "\u0005t\u0000\u0000\u0189\u018a\u0005 \u0000\u0000\u018a\u018b\u0005B"+ + "\u0000\u0000\u018b\u018c\u0005o\u0000\u0000\u018c\u018d\u0005n\u0000\u0000"+ + "\u018d\u018e\u0005u\u0000\u0000\u018e\u018f\u0005s\u0000\u0000\u018f&"+ + "\u0001\u0000\u0000\u0000\u0190\u0191\u0005F\u0000\u0000\u0191\u0192\u0005"+ + "o\u0000\u0000\u0192\u0193\u0005r\u0000\u0000\u0193\u0194\u0005t\u0000"+ + "\u0000\u0194\u0195\u0005i\u0000\u0000\u0195\u0196\u0005f\u0000\u0000\u0196"+ + "\u0197\u0005i\u0000\u0000\u0197\u0198\u0005c\u0000\u0000\u0198\u0199\u0005"+ + "a\u0000\u0000\u0199\u019a\u0005t\u0000\u0000\u019a\u019b\u0005i\u0000"+ + "\u0000\u019b\u019c\u0005o\u0000\u0000\u019c\u019d\u0005n\u0000\u0000\u019d"+ + "(\u0001\u0000\u0000\u0000\u019e\u019f\u0003+\u0015\u0000\u019f\u01a0\u0005"+ + " \u0000\u0000\u01a0\u01a1\u0005S\u0000\u0000\u01a1\u01a2\u0005h\u0000"+ + "\u0000\u01a2\u01a3\u0005e\u0000\u0000\u01a3\u01a4\u0005l\u0000\u0000\u01a4"+ + "\u01a5\u0005t\u0000\u0000\u01a5\u01a6\u0005e\u0000\u0000\u01a6\u01a7\u0005"+ + "r\u0000\u0000\u01a7\u01a8\u0005i\u0000\u0000\u01a8\u01a9\u0005n\u0000"+ + "\u0000\u01a9\u01aa\u0005g\u0000\u0000\u01aa*\u0001\u0000\u0000\u0000\u01ab"+ + "\u01ac\u0005P\u0000\u0000\u01ac\u01ad\u0005h\u0000\u0000\u01ad\u01ae\u0005"+ + "y\u0000\u0000\u01ae\u01af\u0005s\u0000\u0000\u01af\u01b0\u0005i\u0000"+ + "\u0000\u01b0\u01b1\u0005c\u0000\u0000\u01b1\u01b2\u0005a\u0000\u0000\u01b2"+ + "\u01b3\u0005l\u0000\u0000\u01b3\u01b4\u0005 \u0000\u0000\u01b4\u01b5\u0005"+ + "a\u0000\u0000\u01b5\u01b6\u0005n\u0000\u0000\u01b6\u01b7\u0005d\u0000"+ + "\u0000\u01b7\u01b8\u0005 \u0000\u0000\u01b8\u01b9\u0005M\u0000\u0000\u01b9"+ + "\u01ba\u0005a\u0000\u0000\u01ba\u01bb\u0005g\u0000\u0000\u01bb\u01bc\u0005"+ + "i\u0000\u0000\u01bc\u01bd\u0005c\u0000\u0000\u01bd\u01be\u0005a\u0000"+ + "\u0000\u01be\u01cf\u0005l\u0000\u0000\u01bf\u01c0\u0005P\u0000\u0000\u01c0"+ + "\u01c1\u0005h\u0000\u0000\u01c1\u01c2\u0005y\u0000\u0000\u01c2\u01c3\u0005"+ + "s\u0000\u0000\u01c3\u01c4\u0005i\u0000\u0000\u01c4\u01c5\u0005c\u0000"+ + "\u0000\u01c5\u01c6\u0005a\u0000\u0000\u01c6\u01cf\u0005l\u0000\u0000\u01c7"+ + "\u01c8\u0005M\u0000\u0000\u01c8\u01c9\u0005a\u0000\u0000\u01c9\u01ca\u0005"+ + "g\u0000\u0000\u01ca\u01cb\u0005i\u0000\u0000\u01cb\u01cc\u0005c\u0000"+ + "\u0000\u01cc\u01cd\u0005a\u0000\u0000\u01cd\u01cf\u0005l\u0000\u0000\u01ce"+ + "\u01ab\u0001\u0000\u0000\u0000\u01ce\u01bf\u0001\u0000\u0000\u0000\u01ce"+ + "\u01c7\u0001\u0000\u0000\u0000\u01cf,\u0001\u0000\u0000\u0000\u01d0\u01d1"+ + "\u0005B\u0000\u0000\u01d1\u01d2\u0005l\u0000\u0000\u01d2\u01d3\u0005u"+ + "\u0000\u0000\u01d3\u01f8\u0005e\u0000\u0000\u01d4\u01d5\u0005O\u0000\u0000"+ + "\u01d5\u01d6\u0005r\u0000\u0000\u01d6\u01d7\u0005a\u0000\u0000\u01d7\u01d8"+ + "\u0005n\u0000\u0000\u01d8\u01d9\u0005g\u0000\u0000\u01d9\u01f8\u0005e"+ + "\u0000\u0000\u01da\u01db\u0005Y\u0000\u0000\u01db\u01dc\u0005e\u0000\u0000"+ + "\u01dc\u01dd\u0005l\u0000\u0000\u01dd\u01de\u0005l\u0000\u0000\u01de\u01df"+ + "\u0005o\u0000\u0000\u01df\u01f8\u0005w\u0000\u0000\u01e0\u01e1\u0005R"+ + "\u0000\u0000\u01e1\u01e2\u0005e\u0000\u0000\u01e2\u01f8\u0005d\u0000\u0000"+ + "\u01e3\u01e4\u0005G\u0000\u0000\u01e4\u01e5\u0005r\u0000\u0000\u01e5\u01e6"+ + "\u0005e\u0000\u0000\u01e6\u01e7\u0005e\u0000\u0000\u01e7\u01f8\u0005n"+ + "\u0000\u0000\u01e8\u01e9\u0005P\u0000\u0000\u01e9\u01ea\u0005u\u0000\u0000"+ + "\u01ea\u01eb\u0005r\u0000\u0000\u01eb\u01ec\u0005p\u0000\u0000\u01ec\u01ed"+ + "\u0005l\u0000\u0000\u01ed\u01f8\u0005e\u0000\u0000\u01ee\u01ef\u0005C"+ + "\u0000\u0000\u01ef\u01f0\u0005o\u0000\u0000\u01f0\u01f1\u0005l\u0000\u0000"+ + "\u01f1\u01f2\u0005o\u0000\u0000\u01f2\u01f3\u0005r\u0000\u0000\u01f3\u01f4"+ + "\u0005l\u0000\u0000\u01f4\u01f5\u0005e\u0000\u0000\u01f5\u01f6\u0005s"+ + "\u0000\u0000\u01f6\u01f8\u0005s\u0000\u0000\u01f7\u01d0\u0001\u0000\u0000"+ + "\u0000\u01f7\u01d4\u0001\u0000\u0000\u0000\u01f7\u01da\u0001\u0000\u0000"+ + "\u0000\u01f7\u01e0\u0001\u0000\u0000\u0000\u01f7\u01e3\u0001\u0000\u0000"+ + "\u0000\u01f7\u01e8\u0001\u0000\u0000\u0000\u01f7\u01ee\u0001\u0000\u0000"+ + "\u0000\u01f8.\u0001\u0000\u0000\u0000\u01f9\u01fc\u00033\u0019\u0000\u01fa"+ + "\u01fc\u00031\u0018\u0000\u01fb\u01f9\u0001\u0000\u0000\u0000\u01fb\u01fa"+ + "\u0001\u0000\u0000\u0000\u01fc0\u0001\u0000\u0000\u0000\u01fd\u01fe\u0005"+ + "t\u0000\u0000\u01fe\u01ff\u0005o\u0000\u0000\u01ff\u0200\u0005d\u0000"+ + "\u0000\u0200\u0201\u0005o\u0000\u0000\u0201\u0202\u0005:\u0000\u0000\u0202"+ + "\u0203\u0005M\u0000\u0000\u0203\u0204\u0005A\u0000\u0000\u0204\u0205\u0005"+ + "R\u0000\u0000\u0205\u0206\u0005K\u0000\u0000\u0206\u0207\u0005E\u0000"+ + "\u0000\u0207\u0208\u0005R\u0000\u0000\u0208\u0209\u0005 \u0000\u0000\u0209"+ + "2\u0001\u0000\u0000\u0000\u020a\u020b\u0005E\u0000\u0000\u020b\u020c\u0005"+ + "m\u0000\u0000\u020c\u020d\u0005p\u0000\u0000\u020d\u020e\u0005t\u0000"+ + "\u0000\u020e\u020f\u0005y\u0000\u0000\u020f4\u0001\u0000\u0000\u0000\u0210"+ + "\u0212\u0007\u0000\u0000\u0000\u0211\u0210\u0001\u0000\u0000\u0000\u0212"+ + "\u0213\u0001\u0000\u0000\u0000\u0213\u0211\u0001\u0000\u0000\u0000\u0213"+ + "\u0214\u0001\u0000\u0000\u0000\u0214\u0215\u0001\u0000\u0000\u0000\u0215"+ + "\u0216\u0006\u001a\u0001\u0000\u02166\u0001\u0000\u0000\u0000\u0217\u0219"+ + "\u00039\u001c\u0000\u0218\u0217\u0001\u0000\u0000\u0000\u0219\u021a\u0001"+ + "\u0000\u0000\u0000\u021a\u0218\u0001\u0000\u0000\u0000\u021a\u021b\u0001"+ + "\u0000\u0000\u0000\u021b\u021c\u0001\u0000\u0000\u0000\u021c\u021d\u0005"+ + "%\u0000\u0000\u021d8\u0001\u0000\u0000\u0000\u021e\u0220\u0003;\u001d"+ + "\u0000\u021f\u021e\u0001\u0000\u0000\u0000\u0220\u0221\u0001\u0000\u0000"+ + "\u0000\u0221\u021f\u0001\u0000\u0000\u0000\u0221\u0222\u0001\u0000\u0000"+ + "\u0000\u0222\u0223\u0001\u0000\u0000\u0000\u0223\u0224\u0003=\u001e\u0000"+ + "\u0224:\u0001\u0000\u0000\u0000\u0225\u0226\u0007\u0001\u0000\u0000\u0226"+ + "<\u0001\u0000\u0000\u0000\u0227\u0229\u0007\u0002\u0000\u0000\u0228\u0227"+ + "\u0001\u0000\u0000\u0000\u0229\u022a\u0001\u0000\u0000\u0000\u022a\u0228"+ + "\u0001\u0000\u0000\u0000\u022a\u022b\u0001\u0000\u0000\u0000\u022b>\u0001"+ + "\u0000\u0000\u0000\u022c\u0230\u0003A \u0000\u022d\u0230\u0003E\"\u0000"+ + "\u022e\u0230\u0003C!\u0000\u022f\u022c\u0001\u0000\u0000\u0000\u022f\u022d"+ + "\u0001\u0000\u0000\u0000\u022f\u022e\u0001\u0000\u0000\u0000\u0230@\u0001"+ + "\u0000\u0000\u0000\u0231\u0233\u0003C!\u0000\u0232\u0231\u0001\u0000\u0000"+ + "\u0000\u0233\u0234\u0001\u0000\u0000\u0000\u0234\u0232\u0001\u0000\u0000"+ + "\u0000\u0234\u0235\u0001\u0000\u0000\u0000\u0235\u0237\u0001\u0000\u0000"+ + "\u0000\u0236\u0238\u0005 \u0000\u0000\u0237\u0236\u0001\u0000\u0000\u0000"+ + "\u0238\u0239\u0001\u0000\u0000\u0000\u0239\u0237\u0001\u0000\u0000\u0000"+ + "\u0239\u023a\u0001\u0000\u0000\u0000\u023a\u023b\u0001\u0000\u0000\u0000"+ + "\u023b\u023c\u0003E\"\u0000\u023cB\u0001\u0000\u0000\u0000\u023d\u023f"+ + "\u0003E\"\u0000\u023e\u023d\u0001\u0000\u0000\u0000\u023f\u0240\u0001"+ + "\u0000\u0000\u0000\u0240\u023e\u0001\u0000\u0000\u0000\u0240\u0241\u0001"+ + "\u0000\u0000\u0000\u0241\u0243\u0001\u0000\u0000\u0000\u0242\u0244\u0005"+ + " \u0000\u0000\u0243\u0242\u0001\u0000\u0000\u0000\u0244\u0245\u0001\u0000"+ + "\u0000\u0000\u0245\u0243\u0001\u0000\u0000\u0000\u0245\u0246\u0001\u0000"+ + "\u0000\u0000\u0246\u0247\u0001\u0000\u0000\u0000\u0247\u0248\u0003E\""+ + "\u0000\u0248D\u0001\u0000\u0000\u0000\u0249\u024b\u0007\u0003\u0000\u0000"+ + "\u024a\u0249\u0001\u0000\u0000\u0000\u024b\u024c\u0001\u0000\u0000\u0000"+ + "\u024c\u024a\u0001\u0000\u0000\u0000\u024c\u024d\u0001\u0000\u0000\u0000"+ + "\u024d\u024f\u0001\u0000\u0000\u0000\u024e\u0250\u0007\u0004\u0000\u0000"+ + "\u024f\u024e\u0001\u0000\u0000\u0000\u0250\u0251\u0001\u0000\u0000\u0000"+ + "\u0251\u024f\u0001\u0000\u0000\u0000\u0251\u0252\u0001\u0000\u0000\u0000"+ + "\u0252F\u0001\u0000\u0000\u0000\u001b\u0000HLV\u00a2\u00a6\u00bd\u00cb"+ + "\u00e2\u0111\u0126\u015e\u0168\u01ce\u01f7\u01fb\u0213\u021a\u0221\u022a"+ + "\u022f\u0234\u0239\u0240\u0245\u024c\u0251\u0002\u0006\u0000\u0000\u0000"+ + "\u0001\u0000"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.tokens b/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.tokens new file mode 100644 index 00000000..6923c500 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/EnchantmentsLexer.tokens @@ -0,0 +1,28 @@ +LineBreak=1 +ENCHANTMENT=2 +MYTHIC_BOOST=3 +CORE_BODY_SLOT=4 +HAND_SLOT=5 +AUXILLARY_BODY_SLOT=6 +DAMAGE_TYPE=7 +AUGMENTSLOT=8 +LBL_AUGMENT_SLOT=9 +ENHANCEMENT_BONUS=10 +FORT=11 +SHELTERING=12 +SHELTERTYPE=13 +AUGMENTCOLOR=14 +AUGMENTOPTION=15 +FilledAugmentSlot=16 +EmptyAugmentSlot=17 +WS=18 +PCT=19 +NUM=20 +SIGN=21 +UNKNOWN_ID=22 +'Quiver'=6 +'Augment Slot:'=9 +'Enhancement Bonus'=10 +'Fortification'=11 +'todo:MARKER '=16 +'Empty'=17 diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.interp b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.interp new file mode 100644 index 00000000..02ac6422 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.interp @@ -0,0 +1,74 @@ +token literal names: +null +'M' +'CD' +'D' +'CM' +'C' +'CC' +'CCC' +'XL' +'L' +'XC' +'X' +'XX' +'XXX' +'IV' +'V' +'IX' +'I' +'II' +'III' + +token symbolic names: +null +M +CD +D +CM +C +CC +CCC +XL +L +XC +X +XX +XXX +IV +V +IX +I +II +III + +rule names: +M +CD +D +CM +C +CC +CCC +XL +L +XC +X +XX +XXX +IV +V +IX +I +II +III + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 19, 92, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 0, 0, 19, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 1, 0, 0, 91, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 1, 39, 1, 0, 0, 0, 3, 41, 1, 0, 0, 0, 5, 44, 1, 0, 0, 0, 7, 46, 1, 0, 0, 0, 9, 49, 1, 0, 0, 0, 11, 51, 1, 0, 0, 0, 13, 54, 1, 0, 0, 0, 15, 58, 1, 0, 0, 0, 17, 61, 1, 0, 0, 0, 19, 63, 1, 0, 0, 0, 21, 66, 1, 0, 0, 0, 23, 68, 1, 0, 0, 0, 25, 71, 1, 0, 0, 0, 27, 75, 1, 0, 0, 0, 29, 78, 1, 0, 0, 0, 31, 80, 1, 0, 0, 0, 33, 83, 1, 0, 0, 0, 35, 85, 1, 0, 0, 0, 37, 88, 1, 0, 0, 0, 39, 40, 5, 77, 0, 0, 40, 2, 1, 0, 0, 0, 41, 42, 5, 67, 0, 0, 42, 43, 5, 68, 0, 0, 43, 4, 1, 0, 0, 0, 44, 45, 5, 68, 0, 0, 45, 6, 1, 0, 0, 0, 46, 47, 5, 67, 0, 0, 47, 48, 5, 77, 0, 0, 48, 8, 1, 0, 0, 0, 49, 50, 5, 67, 0, 0, 50, 10, 1, 0, 0, 0, 51, 52, 5, 67, 0, 0, 52, 53, 5, 67, 0, 0, 53, 12, 1, 0, 0, 0, 54, 55, 5, 67, 0, 0, 55, 56, 5, 67, 0, 0, 56, 57, 5, 67, 0, 0, 57, 14, 1, 0, 0, 0, 58, 59, 5, 88, 0, 0, 59, 60, 5, 76, 0, 0, 60, 16, 1, 0, 0, 0, 61, 62, 5, 76, 0, 0, 62, 18, 1, 0, 0, 0, 63, 64, 5, 88, 0, 0, 64, 65, 5, 67, 0, 0, 65, 20, 1, 0, 0, 0, 66, 67, 5, 88, 0, 0, 67, 22, 1, 0, 0, 0, 68, 69, 5, 88, 0, 0, 69, 70, 5, 88, 0, 0, 70, 24, 1, 0, 0, 0, 71, 72, 5, 88, 0, 0, 72, 73, 5, 88, 0, 0, 73, 74, 5, 88, 0, 0, 74, 26, 1, 0, 0, 0, 75, 76, 5, 73, 0, 0, 76, 77, 5, 86, 0, 0, 77, 28, 1, 0, 0, 0, 78, 79, 5, 86, 0, 0, 79, 30, 1, 0, 0, 0, 80, 81, 5, 73, 0, 0, 81, 82, 5, 88, 0, 0, 82, 32, 1, 0, 0, 0, 83, 84, 5, 73, 0, 0, 84, 34, 1, 0, 0, 0, 85, 86, 5, 73, 0, 0, 86, 87, 5, 73, 0, 0, 87, 36, 1, 0, 0, 0, 88, 89, 5, 73, 0, 0, 89, 90, 5, 73, 0, 0, 90, 91, 5, 73, 0, 0, 91, 38, 1, 0, 0, 0, 1, 0, 0] \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.java b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.java new file mode 100644 index 00000000..b3d2a985 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.java @@ -0,0 +1,171 @@ +// Generated from /home/adarro/projects/ddo-calc/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsLexer.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) +public class RomanNumeralsLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + M=1, CD=2, D=3, CM=4, C=5, CC=6, CCC=7, XL=8, L=9, XC=10, X=11, XX=12, + XXX=13, IV=14, V=15, IX=16, I=17, II=18, III=19; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "M", "CD", "D", "CM", "C", "CC", "CCC", "XL", "L", "XC", "X", "XX", "XXX", + "IV", "V", "IX", "I", "II", "III" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'M'", "'CD'", "'D'", "'CM'", "'C'", "'CC'", "'CCC'", "'XL'", "'L'", + "'XC'", "'X'", "'XX'", "'XXX'", "'IV'", "'V'", "'IX'", "'I'", "'II'", + "'III'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "M", "CD", "D", "CM", "C", "CC", "CCC", "XL", "L", "XC", "X", "XX", + "XXX", "IV", "V", "IX", "I", "II", "III" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public RomanNumeralsLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "RomanNumeralsLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\u0004\u0000\u0013\\\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+ + "\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+ + "\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+ + "\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+ + "\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002"+ + "\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002"+ + "\u0012\u0007\u0012\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+ + "\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001"+ + "\u0006\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001"+ + "\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\u000b\u0001\u000b"+ + "\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001"+ + "\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001"+ + "\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001"+ + "\u0012\u0001\u0012\u0000\u0000\u0013\u0001\u0001\u0003\u0002\u0005\u0003"+ + "\u0007\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015"+ + "\u000b\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012"+ + "%\u0013\u0001\u0000\u0000[\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003"+ + "\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007"+ + "\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001"+ + "\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000"+ + "\u0000\u0000\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000"+ + "\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000"+ + "\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000"+ + "\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000"+ + "\u0000\u0000\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000"+ + "\u0000%\u0001\u0000\u0000\u0000\u0001\'\u0001\u0000\u0000\u0000\u0003"+ + ")\u0001\u0000\u0000\u0000\u0005,\u0001\u0000\u0000\u0000\u0007.\u0001"+ + "\u0000\u0000\u0000\t1\u0001\u0000\u0000\u0000\u000b3\u0001\u0000\u0000"+ + "\u0000\r6\u0001\u0000\u0000\u0000\u000f:\u0001\u0000\u0000\u0000\u0011"+ + "=\u0001\u0000\u0000\u0000\u0013?\u0001\u0000\u0000\u0000\u0015B\u0001"+ + "\u0000\u0000\u0000\u0017D\u0001\u0000\u0000\u0000\u0019G\u0001\u0000\u0000"+ + "\u0000\u001bK\u0001\u0000\u0000\u0000\u001dN\u0001\u0000\u0000\u0000\u001f"+ + "P\u0001\u0000\u0000\u0000!S\u0001\u0000\u0000\u0000#U\u0001\u0000\u0000"+ + "\u0000%X\u0001\u0000\u0000\u0000\'(\u0005M\u0000\u0000(\u0002\u0001\u0000"+ + "\u0000\u0000)*\u0005C\u0000\u0000*+\u0005D\u0000\u0000+\u0004\u0001\u0000"+ + "\u0000\u0000,-\u0005D\u0000\u0000-\u0006\u0001\u0000\u0000\u0000./\u0005"+ + "C\u0000\u0000/0\u0005M\u0000\u00000\b\u0001\u0000\u0000\u000012\u0005"+ + "C\u0000\u00002\n\u0001\u0000\u0000\u000034\u0005C\u0000\u000045\u0005"+ + "C\u0000\u00005\f\u0001\u0000\u0000\u000067\u0005C\u0000\u000078\u0005"+ + "C\u0000\u000089\u0005C\u0000\u00009\u000e\u0001\u0000\u0000\u0000:;\u0005"+ + "X\u0000\u0000;<\u0005L\u0000\u0000<\u0010\u0001\u0000\u0000\u0000=>\u0005"+ + "L\u0000\u0000>\u0012\u0001\u0000\u0000\u0000?@\u0005X\u0000\u0000@A\u0005"+ + "C\u0000\u0000A\u0014\u0001\u0000\u0000\u0000BC\u0005X\u0000\u0000C\u0016"+ + "\u0001\u0000\u0000\u0000DE\u0005X\u0000\u0000EF\u0005X\u0000\u0000F\u0018"+ + "\u0001\u0000\u0000\u0000GH\u0005X\u0000\u0000HI\u0005X\u0000\u0000IJ\u0005"+ + "X\u0000\u0000J\u001a\u0001\u0000\u0000\u0000KL\u0005I\u0000\u0000LM\u0005"+ + "V\u0000\u0000M\u001c\u0001\u0000\u0000\u0000NO\u0005V\u0000\u0000O\u001e"+ + "\u0001\u0000\u0000\u0000PQ\u0005I\u0000\u0000QR\u0005X\u0000\u0000R \u0001"+ + "\u0000\u0000\u0000ST\u0005I\u0000\u0000T\"\u0001\u0000\u0000\u0000UV\u0005"+ + "I\u0000\u0000VW\u0005I\u0000\u0000W$\u0001\u0000\u0000\u0000XY\u0005I"+ + "\u0000\u0000YZ\u0005I\u0000\u0000Z[\u0005I\u0000\u0000[&\u0001\u0000\u0000"+ + "\u0000\u0001\u0000\u0000"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.tokens b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.tokens new file mode 100644 index 00000000..5b16f225 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsLexer.tokens @@ -0,0 +1,38 @@ +M=1 +CD=2 +D=3 +CM=4 +C=5 +CC=6 +CCC=7 +XL=8 +L=9 +XC=10 +X=11 +XX=12 +XXX=13 +IV=14 +V=15 +IX=16 +I=17 +II=18 +III=19 +'M'=1 +'CD'=2 +'D'=3 +'CM'=4 +'C'=5 +'CC'=6 +'CCC'=7 +'XL'=8 +'L'=9 +'XC'=10 +'X'=11 +'XX'=12 +'XXX'=13 +'IV'=14 +'V'=15 +'IX'=16 +'I'=17 +'II'=18 +'III'=19 diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.interp b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.interp new file mode 100644 index 00000000..efd747cb --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.interp @@ -0,0 +1,57 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +M +CM +CD +D +C +CC +CCC +XC +XL +L +X +XX +XXX +IV +V +IX +I +III + +rule names: +numeral +thous_part +hundreds +hun_part +hun_rep +tens +tens_part +tens_rep +ones +ones_rep + + +atn: +[4, 1, 18, 86, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 26, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 33, 8, 1, 10, 1, 12, 1, 36, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 43, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 51, 8, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 60, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 68, 8, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 78, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 84, 8, 9, 1, 9, 0, 1, 2, 10, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 0, 2, 1, 0, 5, 7, 1, 0, 11, 13, 96, 0, 25, 1, 0, 0, 0, 2, 27, 1, 0, 0, 0, 4, 42, 1, 0, 0, 0, 6, 50, 1, 0, 0, 0, 8, 52, 1, 0, 0, 0, 10, 59, 1, 0, 0, 0, 12, 67, 1, 0, 0, 0, 14, 69, 1, 0, 0, 0, 16, 77, 1, 0, 0, 0, 18, 83, 1, 0, 0, 0, 20, 21, 3, 2, 1, 0, 21, 22, 3, 4, 2, 0, 22, 26, 1, 0, 0, 0, 23, 26, 3, 2, 1, 0, 24, 26, 3, 4, 2, 0, 25, 20, 1, 0, 0, 0, 25, 23, 1, 0, 0, 0, 25, 24, 1, 0, 0, 0, 26, 1, 1, 0, 0, 0, 27, 28, 6, 1, -1, 0, 28, 29, 5, 1, 0, 0, 29, 34, 1, 0, 0, 0, 30, 31, 10, 2, 0, 0, 31, 33, 5, 1, 0, 0, 32, 30, 1, 0, 0, 0, 33, 36, 1, 0, 0, 0, 34, 32, 1, 0, 0, 0, 34, 35, 1, 0, 0, 0, 35, 3, 1, 0, 0, 0, 36, 34, 1, 0, 0, 0, 37, 38, 3, 6, 3, 0, 38, 39, 3, 10, 5, 0, 39, 43, 1, 0, 0, 0, 40, 43, 3, 6, 3, 0, 41, 43, 3, 10, 5, 0, 42, 37, 1, 0, 0, 0, 42, 40, 1, 0, 0, 0, 42, 41, 1, 0, 0, 0, 43, 5, 1, 0, 0, 0, 44, 51, 5, 2, 0, 0, 45, 51, 5, 3, 0, 0, 46, 47, 5, 4, 0, 0, 47, 51, 3, 8, 4, 0, 48, 51, 5, 4, 0, 0, 49, 51, 3, 8, 4, 0, 50, 44, 1, 0, 0, 0, 50, 45, 1, 0, 0, 0, 50, 46, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 50, 49, 1, 0, 0, 0, 51, 7, 1, 0, 0, 0, 52, 53, 7, 0, 0, 0, 53, 9, 1, 0, 0, 0, 54, 55, 3, 12, 6, 0, 55, 56, 3, 16, 8, 0, 56, 60, 1, 0, 0, 0, 57, 60, 3, 12, 6, 0, 58, 60, 3, 16, 8, 0, 59, 54, 1, 0, 0, 0, 59, 57, 1, 0, 0, 0, 59, 58, 1, 0, 0, 0, 60, 11, 1, 0, 0, 0, 61, 68, 5, 8, 0, 0, 62, 68, 5, 9, 0, 0, 63, 64, 5, 10, 0, 0, 64, 68, 3, 14, 7, 0, 65, 68, 5, 10, 0, 0, 66, 68, 3, 14, 7, 0, 67, 61, 1, 0, 0, 0, 67, 62, 1, 0, 0, 0, 67, 63, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 66, 1, 0, 0, 0, 68, 13, 1, 0, 0, 0, 69, 70, 7, 1, 0, 0, 70, 15, 1, 0, 0, 0, 71, 78, 3, 18, 9, 0, 72, 78, 5, 14, 0, 0, 73, 74, 5, 15, 0, 0, 74, 78, 3, 18, 9, 0, 75, 78, 5, 15, 0, 0, 76, 78, 5, 16, 0, 0, 77, 71, 1, 0, 0, 0, 77, 72, 1, 0, 0, 0, 77, 73, 1, 0, 0, 0, 77, 75, 1, 0, 0, 0, 77, 76, 1, 0, 0, 0, 78, 17, 1, 0, 0, 0, 79, 84, 5, 17, 0, 0, 80, 81, 5, 17, 0, 0, 81, 84, 5, 17, 0, 0, 82, 84, 5, 18, 0, 0, 83, 79, 1, 0, 0, 0, 83, 80, 1, 0, 0, 0, 83, 82, 1, 0, 0, 0, 84, 19, 1, 0, 0, 0, 8, 25, 34, 42, 50, 59, 67, 77, 83] \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.java b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.java new file mode 100644 index 00000000..8074d644 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.java @@ -0,0 +1,891 @@ +// Generated from /home/adarro/projects/ddo-calc/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class RomanNumeralsParser extends Parser { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + M=1, CM=2, CD=3, D=4, C=5, CC=6, CCC=7, XC=8, XL=9, L=10, X=11, XX=12, + XXX=13, IV=14, V=15, IX=16, I=17, III=18; + public static final int + RULE_numeral = 0, RULE_thous_part = 1, RULE_hundreds = 2, RULE_hun_part = 3, + RULE_hun_rep = 4, RULE_tens = 5, RULE_tens_part = 6, RULE_tens_rep = 7, + RULE_ones = 8, RULE_ones_rep = 9; + private static String[] makeRuleNames() { + return new String[] { + "numeral", "thous_part", "hundreds", "hun_part", "hun_rep", "tens", "tens_part", + "tens_rep", "ones", "ones_rep" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "M", "CM", "CD", "D", "C", "CC", "CCC", "XC", "XL", "L", "X", "XX", + "XXX", "IV", "V", "IX", "I", "III" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "RomanNumeralsParser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public RomanNumeralsParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class NumeralContext extends ParserRuleContext { + public Thous_partContext thous_part() { + return getRuleContext(Thous_partContext.class,0); + } + public HundredsContext hundreds() { + return getRuleContext(HundredsContext.class,0); + } + public NumeralContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_numeral; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterNumeral(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitNumeral(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitNumeral(this); + else return visitor.visitChildren(this); + } + } + + public final NumeralContext numeral() throws RecognitionException { + NumeralContext _localctx = new NumeralContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_numeral); + try { + setState(25); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(20); + thous_part(0); + setState(21); + hundreds(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(23); + thous_part(0); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(24); + hundreds(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class Thous_partContext extends ParserRuleContext { + public TerminalNode M() { return getToken(RomanNumeralsParser.M, 0); } + public Thous_partContext thous_part() { + return getRuleContext(Thous_partContext.class,0); + } + public Thous_partContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_thous_part; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterThous_part(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitThous_part(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitThous_part(this); + else return visitor.visitChildren(this); + } + } + + public final Thous_partContext thous_part() throws RecognitionException { + return thous_part(0); + } + + private Thous_partContext thous_part(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + Thous_partContext _localctx = new Thous_partContext(_ctx, _parentState); + Thous_partContext _prevctx = _localctx; + int _startState = 2; + enterRecursionRule(_localctx, 2, RULE_thous_part, _p); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + { + setState(28); + match(M); + } + _ctx.stop = _input.LT(-1); + setState(34); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,1,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + { + _localctx = new Thous_partContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_thous_part); + setState(30); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(31); + match(M); + } + } + } + setState(36); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,1,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class HundredsContext extends ParserRuleContext { + public Hun_partContext hun_part() { + return getRuleContext(Hun_partContext.class,0); + } + public TensContext tens() { + return getRuleContext(TensContext.class,0); + } + public HundredsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_hundreds; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterHundreds(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitHundreds(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitHundreds(this); + else return visitor.visitChildren(this); + } + } + + public final HundredsContext hundreds() throws RecognitionException { + HundredsContext _localctx = new HundredsContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_hundreds); + try { + setState(42); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(37); + hun_part(); + setState(38); + tens(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(40); + hun_part(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(41); + tens(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class Hun_partContext extends ParserRuleContext { + public TerminalNode CM() { return getToken(RomanNumeralsParser.CM, 0); } + public TerminalNode CD() { return getToken(RomanNumeralsParser.CD, 0); } + public TerminalNode D() { return getToken(RomanNumeralsParser.D, 0); } + public Hun_repContext hun_rep() { + return getRuleContext(Hun_repContext.class,0); + } + public Hun_partContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_hun_part; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterHun_part(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitHun_part(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitHun_part(this); + else return visitor.visitChildren(this); + } + } + + public final Hun_partContext hun_part() throws RecognitionException { + Hun_partContext _localctx = new Hun_partContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_hun_part); + try { + setState(50); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(44); + match(CM); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(45); + match(CD); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(46); + match(D); + setState(47); + hun_rep(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(48); + match(D); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(49); + hun_rep(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class Hun_repContext extends ParserRuleContext { + public TerminalNode C() { return getToken(RomanNumeralsParser.C, 0); } + public TerminalNode CC() { return getToken(RomanNumeralsParser.CC, 0); } + public TerminalNode CCC() { return getToken(RomanNumeralsParser.CCC, 0); } + public Hun_repContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_hun_rep; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterHun_rep(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitHun_rep(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitHun_rep(this); + else return visitor.visitChildren(this); + } + } + + public final Hun_repContext hun_rep() throws RecognitionException { + Hun_repContext _localctx = new Hun_repContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_hun_rep); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(52); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 224L) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class TensContext extends ParserRuleContext { + public Tens_partContext tens_part() { + return getRuleContext(Tens_partContext.class,0); + } + public OnesContext ones() { + return getRuleContext(OnesContext.class,0); + } + public TensContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_tens; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterTens(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitTens(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitTens(this); + else return visitor.visitChildren(this); + } + } + + public final TensContext tens() throws RecognitionException { + TensContext _localctx = new TensContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_tens); + try { + setState(59); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(54); + tens_part(); + setState(55); + ones(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(57); + tens_part(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(58); + ones(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class Tens_partContext extends ParserRuleContext { + public TerminalNode XC() { return getToken(RomanNumeralsParser.XC, 0); } + public TerminalNode XL() { return getToken(RomanNumeralsParser.XL, 0); } + public TerminalNode L() { return getToken(RomanNumeralsParser.L, 0); } + public Tens_repContext tens_rep() { + return getRuleContext(Tens_repContext.class,0); + } + public Tens_partContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_tens_part; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterTens_part(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitTens_part(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitTens_part(this); + else return visitor.visitChildren(this); + } + } + + public final Tens_partContext tens_part() throws RecognitionException { + Tens_partContext _localctx = new Tens_partContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_tens_part); + try { + setState(67); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(61); + match(XC); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(62); + match(XL); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(63); + match(L); + setState(64); + tens_rep(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(65); + match(L); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(66); + tens_rep(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class Tens_repContext extends ParserRuleContext { + public TerminalNode X() { return getToken(RomanNumeralsParser.X, 0); } + public TerminalNode XX() { return getToken(RomanNumeralsParser.XX, 0); } + public TerminalNode XXX() { return getToken(RomanNumeralsParser.XXX, 0); } + public Tens_repContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_tens_rep; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterTens_rep(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitTens_rep(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitTens_rep(this); + else return visitor.visitChildren(this); + } + } + + public final Tens_repContext tens_rep() throws RecognitionException { + Tens_repContext _localctx = new Tens_repContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_tens_rep); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(69); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 14336L) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class OnesContext extends ParserRuleContext { + public Ones_repContext ones_rep() { + return getRuleContext(Ones_repContext.class,0); + } + public TerminalNode IV() { return getToken(RomanNumeralsParser.IV, 0); } + public TerminalNode V() { return getToken(RomanNumeralsParser.V, 0); } + public TerminalNode IX() { return getToken(RomanNumeralsParser.IX, 0); } + public OnesContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_ones; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterOnes(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitOnes(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitOnes(this); + else return visitor.visitChildren(this); + } + } + + public final OnesContext ones() throws RecognitionException { + OnesContext _localctx = new OnesContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_ones); + try { + setState(77); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(71); + ones_rep(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(72); + match(IV); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(73); + match(V); + setState(74); + ones_rep(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(75); + match(V); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(76); + match(IX); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class Ones_repContext extends ParserRuleContext { + public List I() { return getTokens(RomanNumeralsParser.I); } + public TerminalNode I(int i) { + return getToken(RomanNumeralsParser.I, i); + } + public TerminalNode III() { return getToken(RomanNumeralsParser.III, 0); } + public Ones_repContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_ones_rep; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).enterOnes_rep(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof RomanNumeralsParserListener ) ((RomanNumeralsParserListener)listener).exitOnes_rep(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof RomanNumeralsParserVisitor ) return ((RomanNumeralsParserVisitor)visitor).visitOnes_rep(this); + else return visitor.visitChildren(this); + } + } + + public final Ones_repContext ones_rep() throws RecognitionException { + Ones_repContext _localctx = new Ones_repContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_ones_rep); + try { + setState(83); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(79); + match(I); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(80); + match(I); + setState(81); + match(I); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(82); + match(III); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 1: + return thous_part_sempred((Thous_partContext)_localctx, predIndex); + } + return true; + } + private boolean thous_part_sempred(Thous_partContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 2); + } + return true; + } + + public static final String _serializedATN = + "\u0004\u0001\u0012V\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ + "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ + "\b\u0007\b\u0002\t\u0007\t\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+ + "\u0001\u0000\u0003\u0000\u001a\b\u0000\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0005\u0001!\b\u0001\n\u0001\f\u0001$\t\u0001"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0003\u0002"+ + "+\b\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0003\u00033\b\u0003\u0001\u0004\u0001\u0004\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005<\b\u0005"+ + "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ + "\u0003\u0006D\b\u0006\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b"+ + "\u0001\b\u0001\b\u0001\b\u0003\bN\b\b\u0001\t\u0001\t\u0001\t\u0001\t"+ + "\u0003\tT\b\t\u0001\t\u0000\u0001\u0002\n\u0000\u0002\u0004\u0006\b\n"+ + "\f\u000e\u0010\u0012\u0000\u0002\u0001\u0000\u0005\u0007\u0001\u0000\u000b"+ + "\r`\u0000\u0019\u0001\u0000\u0000\u0000\u0002\u001b\u0001\u0000\u0000"+ + "\u0000\u0004*\u0001\u0000\u0000\u0000\u00062\u0001\u0000\u0000\u0000\b"+ + "4\u0001\u0000\u0000\u0000\n;\u0001\u0000\u0000\u0000\fC\u0001\u0000\u0000"+ + "\u0000\u000eE\u0001\u0000\u0000\u0000\u0010M\u0001\u0000\u0000\u0000\u0012"+ + "S\u0001\u0000\u0000\u0000\u0014\u0015\u0003\u0002\u0001\u0000\u0015\u0016"+ + "\u0003\u0004\u0002\u0000\u0016\u001a\u0001\u0000\u0000\u0000\u0017\u001a"+ + "\u0003\u0002\u0001\u0000\u0018\u001a\u0003\u0004\u0002\u0000\u0019\u0014"+ + "\u0001\u0000\u0000\u0000\u0019\u0017\u0001\u0000\u0000\u0000\u0019\u0018"+ + "\u0001\u0000\u0000\u0000\u001a\u0001\u0001\u0000\u0000\u0000\u001b\u001c"+ + "\u0006\u0001\uffff\uffff\u0000\u001c\u001d\u0005\u0001\u0000\u0000\u001d"+ + "\"\u0001\u0000\u0000\u0000\u001e\u001f\n\u0002\u0000\u0000\u001f!\u0005"+ + "\u0001\u0000\u0000 \u001e\u0001\u0000\u0000\u0000!$\u0001\u0000\u0000"+ + "\u0000\" \u0001\u0000\u0000\u0000\"#\u0001\u0000\u0000\u0000#\u0003\u0001"+ + "\u0000\u0000\u0000$\"\u0001\u0000\u0000\u0000%&\u0003\u0006\u0003\u0000"+ + "&\'\u0003\n\u0005\u0000\'+\u0001\u0000\u0000\u0000(+\u0003\u0006\u0003"+ + "\u0000)+\u0003\n\u0005\u0000*%\u0001\u0000\u0000\u0000*(\u0001\u0000\u0000"+ + "\u0000*)\u0001\u0000\u0000\u0000+\u0005\u0001\u0000\u0000\u0000,3\u0005"+ + "\u0002\u0000\u0000-3\u0005\u0003\u0000\u0000./\u0005\u0004\u0000\u0000"+ + "/3\u0003\b\u0004\u000003\u0005\u0004\u0000\u000013\u0003\b\u0004\u0000"+ + "2,\u0001\u0000\u0000\u00002-\u0001\u0000\u0000\u00002.\u0001\u0000\u0000"+ + "\u000020\u0001\u0000\u0000\u000021\u0001\u0000\u0000\u00003\u0007\u0001"+ + "\u0000\u0000\u000045\u0007\u0000\u0000\u00005\t\u0001\u0000\u0000\u0000"+ + "67\u0003\f\u0006\u000078\u0003\u0010\b\u00008<\u0001\u0000\u0000\u0000"+ + "9<\u0003\f\u0006\u0000:<\u0003\u0010\b\u0000;6\u0001\u0000\u0000\u0000"+ + ";9\u0001\u0000\u0000\u0000;:\u0001\u0000\u0000\u0000<\u000b\u0001\u0000"+ + "\u0000\u0000=D\u0005\b\u0000\u0000>D\u0005\t\u0000\u0000?@\u0005\n\u0000"+ + "\u0000@D\u0003\u000e\u0007\u0000AD\u0005\n\u0000\u0000BD\u0003\u000e\u0007"+ + "\u0000C=\u0001\u0000\u0000\u0000C>\u0001\u0000\u0000\u0000C?\u0001\u0000"+ + "\u0000\u0000CA\u0001\u0000\u0000\u0000CB\u0001\u0000\u0000\u0000D\r\u0001"+ + "\u0000\u0000\u0000EF\u0007\u0001\u0000\u0000F\u000f\u0001\u0000\u0000"+ + "\u0000GN\u0003\u0012\t\u0000HN\u0005\u000e\u0000\u0000IJ\u0005\u000f\u0000"+ + "\u0000JN\u0003\u0012\t\u0000KN\u0005\u000f\u0000\u0000LN\u0005\u0010\u0000"+ + "\u0000MG\u0001\u0000\u0000\u0000MH\u0001\u0000\u0000\u0000MI\u0001\u0000"+ + "\u0000\u0000MK\u0001\u0000\u0000\u0000ML\u0001\u0000\u0000\u0000N\u0011"+ + "\u0001\u0000\u0000\u0000OT\u0005\u0011\u0000\u0000PQ\u0005\u0011\u0000"+ + "\u0000QT\u0005\u0011\u0000\u0000RT\u0005\u0012\u0000\u0000SO\u0001\u0000"+ + "\u0000\u0000SP\u0001\u0000\u0000\u0000SR\u0001\u0000\u0000\u0000T\u0013"+ + "\u0001\u0000\u0000\u0000\b\u0019\"*2;CMS"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.tokens b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.tokens new file mode 100644 index 00000000..ec02b493 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParser.tokens @@ -0,0 +1,18 @@ +M=1 +CM=2 +CD=3 +D=4 +C=5 +CC=6 +CCC=7 +XC=8 +XL=9 +L=10 +X=11 +XX=12 +XXX=13 +IV=14 +V=15 +IX=16 +I=17 +III=18 diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserBaseListener.java b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserBaseListener.java new file mode 100644 index 00000000..7ff2ee8a --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserBaseListener.java @@ -0,0 +1,159 @@ +// Generated from /home/adarro/projects/ddo-calc/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 by ANTLR 4.13.1 + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link RomanNumeralsParserListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +@SuppressWarnings("CheckReturnValue") +public class RomanNumeralsParserBaseListener implements RomanNumeralsParserListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterNumeral(RomanNumeralsParser.NumeralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitNumeral(RomanNumeralsParser.NumeralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterThous_part(RomanNumeralsParser.Thous_partContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitThous_part(RomanNumeralsParser.Thous_partContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterHundreds(RomanNumeralsParser.HundredsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitHundreds(RomanNumeralsParser.HundredsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterHun_part(RomanNumeralsParser.Hun_partContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitHun_part(RomanNumeralsParser.Hun_partContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterHun_rep(RomanNumeralsParser.Hun_repContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitHun_rep(RomanNumeralsParser.Hun_repContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTens(RomanNumeralsParser.TensContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTens(RomanNumeralsParser.TensContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTens_part(RomanNumeralsParser.Tens_partContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTens_part(RomanNumeralsParser.Tens_partContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTens_rep(RomanNumeralsParser.Tens_repContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTens_rep(RomanNumeralsParser.Tens_repContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterOnes(RomanNumeralsParser.OnesContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitOnes(RomanNumeralsParser.OnesContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterOnes_rep(RomanNumeralsParser.Ones_repContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitOnes_rep(RomanNumeralsParser.Ones_repContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserBaseVisitor.java b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserBaseVisitor.java new file mode 100644 index 00000000..de9a5ffd --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserBaseVisitor.java @@ -0,0 +1,84 @@ +// Generated from /home/adarro/projects/ddo-calc/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link RomanNumeralsParserVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +@SuppressWarnings("CheckReturnValue") +public class RomanNumeralsParserBaseVisitor extends AbstractParseTreeVisitor implements RomanNumeralsParserVisitor { + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNumeral(RomanNumeralsParser.NumeralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitThous_part(RomanNumeralsParser.Thous_partContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitHundreds(RomanNumeralsParser.HundredsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitHun_part(RomanNumeralsParser.Hun_partContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitHun_rep(RomanNumeralsParser.Hun_repContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTens(RomanNumeralsParser.TensContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTens_part(RomanNumeralsParser.Tens_partContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTens_rep(RomanNumeralsParser.Tens_repContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitOnes(RomanNumeralsParser.OnesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitOnes_rep(RomanNumeralsParser.Ones_repContext ctx) { return visitChildren(ctx); } +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserListener.java b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserListener.java new file mode 100644 index 00000000..cfdafb1f --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserListener.java @@ -0,0 +1,109 @@ +// Generated from /home/adarro/projects/ddo-calc/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link RomanNumeralsParser}. + */ +public interface RomanNumeralsParserListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#numeral}. + * @param ctx the parse tree + */ + void enterNumeral(RomanNumeralsParser.NumeralContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#numeral}. + * @param ctx the parse tree + */ + void exitNumeral(RomanNumeralsParser.NumeralContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#thous_part}. + * @param ctx the parse tree + */ + void enterThous_part(RomanNumeralsParser.Thous_partContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#thous_part}. + * @param ctx the parse tree + */ + void exitThous_part(RomanNumeralsParser.Thous_partContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#hundreds}. + * @param ctx the parse tree + */ + void enterHundreds(RomanNumeralsParser.HundredsContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#hundreds}. + * @param ctx the parse tree + */ + void exitHundreds(RomanNumeralsParser.HundredsContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#hun_part}. + * @param ctx the parse tree + */ + void enterHun_part(RomanNumeralsParser.Hun_partContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#hun_part}. + * @param ctx the parse tree + */ + void exitHun_part(RomanNumeralsParser.Hun_partContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#hun_rep}. + * @param ctx the parse tree + */ + void enterHun_rep(RomanNumeralsParser.Hun_repContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#hun_rep}. + * @param ctx the parse tree + */ + void exitHun_rep(RomanNumeralsParser.Hun_repContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#tens}. + * @param ctx the parse tree + */ + void enterTens(RomanNumeralsParser.TensContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#tens}. + * @param ctx the parse tree + */ + void exitTens(RomanNumeralsParser.TensContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#tens_part}. + * @param ctx the parse tree + */ + void enterTens_part(RomanNumeralsParser.Tens_partContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#tens_part}. + * @param ctx the parse tree + */ + void exitTens_part(RomanNumeralsParser.Tens_partContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#tens_rep}. + * @param ctx the parse tree + */ + void enterTens_rep(RomanNumeralsParser.Tens_repContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#tens_rep}. + * @param ctx the parse tree + */ + void exitTens_rep(RomanNumeralsParser.Tens_repContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#ones}. + * @param ctx the parse tree + */ + void enterOnes(RomanNumeralsParser.OnesContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#ones}. + * @param ctx the parse tree + */ + void exitOnes(RomanNumeralsParser.OnesContext ctx); + /** + * Enter a parse tree produced by {@link RomanNumeralsParser#ones_rep}. + * @param ctx the parse tree + */ + void enterOnes_rep(RomanNumeralsParser.Ones_repContext ctx); + /** + * Exit a parse tree produced by {@link RomanNumeralsParser#ones_rep}. + * @param ctx the parse tree + */ + void exitOnes_rep(RomanNumeralsParser.Ones_repContext ctx); +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserVisitor.java b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserVisitor.java new file mode 100644 index 00000000..dbfdbc2e --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/gen/RomanNumeralsParserVisitor.java @@ -0,0 +1,72 @@ +// Generated from /home/adarro/projects/ddo-calc/subprojects/common/ddo-antlr/src/main/antlr/RomanNumeralsParser.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link RomanNumeralsParser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface RomanNumeralsParserVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#numeral}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNumeral(RomanNumeralsParser.NumeralContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#thous_part}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitThous_part(RomanNumeralsParser.Thous_partContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#hundreds}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitHundreds(RomanNumeralsParser.HundredsContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#hun_part}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitHun_part(RomanNumeralsParser.Hun_partContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#hun_rep}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitHun_rep(RomanNumeralsParser.Hun_repContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#tens}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTens(RomanNumeralsParser.TensContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#tens_part}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTens_part(RomanNumeralsParser.Tens_partContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#tens_rep}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTens_rep(RomanNumeralsParser.Tens_repContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#ones}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitOnes(RomanNumeralsParser.OnesContext ctx); + /** + * Visit a parse tree produced by {@link RomanNumeralsParser#ones_rep}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitOnes_rep(RomanNumeralsParser.Ones_repContext ctx); +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/main/java/io/truthencode/ddo/visibla/javaClass/PojoDefaultJava.java b/subprojects/common/ddo-antlr/src/main/java/io/truthencode/ddo/visibla/javaClass/PojoDefaultJava.java new file mode 100644 index 00000000..767c46cd --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/java/io/truthencode/ddo/visibla/javaClass/PojoDefaultJava.java @@ -0,0 +1,3 @@ +package io.truthencode.ddo.visibla.javaClass; +public class PojoDefaultJava { +} diff --git a/subprojects/common/ddo-antlr/src/main/kotlin/io/truthencode/ddo/visibla/kotlinClass/PojoDefaultKotlin.kt b/subprojects/common/ddo-antlr/src/main/kotlin/io/truthencode/ddo/visibla/kotlinClass/PojoDefaultKotlin.kt new file mode 100644 index 00000000..4c2ab6de --- /dev/null +++ b/subprojects/common/ddo-antlr/src/main/kotlin/io/truthencode/ddo/visibla/kotlinClass/PojoDefaultKotlin.kt @@ -0,0 +1,3 @@ +package io.truthencode.ddo.visibla.kotlinClass + +class PojoDefaultKotlin \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/BasicTestJavaSamePackage.java b/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/BasicTestJavaSamePackage.java new file mode 100644 index 00000000..dd6239e3 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/BasicTestJavaSamePackage.java @@ -0,0 +1,8 @@ +package io.truthencode.ddo.grammar.antlr; + +public class BasicTestJavaSamePackage { + + public void referenceParserFromJavaSamePackage() { + io.truthencode.ddo.grammar.antlr.EnchantmentsParser parser = null; + } +} diff --git a/incubating/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/DdoItemParserTest.java b/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/DdoItemParserTest.java similarity index 100% rename from incubating/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/DdoItemParserTest.java rename to subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/DdoItemParserTest.java diff --git a/incubating/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/TextSnippets.java b/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/TextSnippets.java similarity index 100% rename from incubating/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/TextSnippets.java rename to subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/antlr/TextSnippets.java diff --git a/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/diff/BasicTestJavaDifferent.java b/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/diff/BasicTestJavaDifferent.java new file mode 100644 index 00000000..5ae08027 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/test/java/io/truthencode/ddo/grammar/diff/BasicTestJavaDifferent.java @@ -0,0 +1,8 @@ +package io.truthencode.ddo.grammar.diff; + +public class BasicTestJavaDifferent { + + public void referenceParserFromJavaSamePackage() { + // io.truthencode.ddo.grammer.antlr.EnchantmentsParser parser = null; + } +} diff --git a/subprojects/common/ddo-antlr/src/test/kotlin/io/truthencode/ddo/grammar/antlr/BasicTestKotlin.kt b/subprojects/common/ddo-antlr/src/test/kotlin/io/truthencode/ddo/grammar/antlr/BasicTestKotlin.kt new file mode 100644 index 00000000..12981c67 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/test/kotlin/io/truthencode/ddo/grammar/antlr/BasicTestKotlin.kt @@ -0,0 +1,16 @@ +package io.truthencode.ddo.grammar.antlr + +import io.truthencode.ddo.visibla.javaClass.PojoDefaultJava +import io.truthencode.ddo.visibla.kotlinClass.PojoDefaultKotlin + +open class BasicTestKotlin { + fun doSomething(): String { + return "Okies" + } + + fun refParserFromKotlinSamePackage() { + var p: EnchantmentsParser + val jc: PojoDefaultJava + val kc: PojoDefaultKotlin + } +} \ No newline at end of file diff --git a/subprojects/common/ddo-antlr/src/test/kotlin/io/truthencode/ddo/grammar/different/BasicTestKotlinDifferent.kt b/subprojects/common/ddo-antlr/src/test/kotlin/io/truthencode/ddo/grammar/different/BasicTestKotlinDifferent.kt new file mode 100644 index 00000000..a0f8ecb8 --- /dev/null +++ b/subprojects/common/ddo-antlr/src/test/kotlin/io/truthencode/ddo/grammar/different/BasicTestKotlinDifferent.kt @@ -0,0 +1,11 @@ +package io.truthencode.ddo.grammar.different + +open class BasicTestKotlinDifferent { + fun doSomething(): String { + return "Okies" + } + + fun referenceParserFromKotlinDifferentPackage() { + // var p: EnchantmentsParser + } +} \ No newline at end of file diff --git a/incubating/ddo-antlr/src/test/resources/example_enhancements.txt b/subprojects/common/ddo-antlr/src/test/resources/example_enhancements.txt similarity index 100% rename from incubating/ddo-antlr/src/test/resources/example_enhancements.txt rename to subprojects/common/ddo-antlr/src/test/resources/example_enhancements.txt diff --git a/subprojects/common/ddo-core/build.gradle.kts b/subprojects/common/ddo-core/build.gradle.kts index 84a8d4f2..8f0b8bef 100644 --- a/subprojects/common/ddo-core/build.gradle.kts +++ b/subprojects/common/ddo-core/build.gradle.kts @@ -1,120 +1,118 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * Copyright 2015-2021 Andre White. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// ddo-core -plugins { - id("scala-library-profile") -// id("ru.vyarus.mkdocs") // version "3.0.0" - id("djaxonomy.test-conventions") -// id("doc-uml") -} - -tasks.named("check") { - dependsOn(testing.suites.named("integrationTest")) -} - -description = "Core DDO Objects" - -dependencies { - val concordionVersion: String by project - - dependencies { - implementation(enforcedPlatform(project(":ddo-platform-scala"))) - implementation(project(":ddo-util")) - implementation(project(":ddo-modeling")) - - val scalaLibraryVersion: String by project - val scalaMajorVersion: String by project - // Platform dependent - // https://mvnrepository.com/artifact/org.json4s/json4s-native - implementation(group = "org.json4s", name = "json4s-native_$scalaMajorVersion") - -// annotationProcessor("net.thauvin.erik:semver:1.2.0") -// compileOnly("net.thauvin.erik:semver:1.2.0") - - implementation(libs.scala2.library) - implementation(group = "com.beachape", name = "enumeratum_$scalaMajorVersion") - implementation(group = "com.typesafe", name = "config") - implementation(group = "com.github.kxbmap", name = "configs_$scalaMajorVersion") - // validation and rules - implementation(group = "com.wix", name = "accord-core_$scalaMajorVersion") - - implementation(group = "ch.qos.logback", name = "logback-classic") - implementation(group = "com.typesafe.scala-logging", name = "scala-logging_$scalaMajorVersion") - testImplementation(project(":ddo-testing-util")) - // testImplementation(group = "org.scalatest", name = "scalatest_$scalaMajorVersion") - // testImplementation(group = "org.scalacheck", name = "scalacheck_$scalaMajorVersion") - // testImplementation(group = "org.scalatestplus", "mockito-3-4_$scalaMajorVersion") - // testImplementation(group = "com.wix", name = "accord-scalatest_$scalaMajorVersion") - - // // JUnit 5 - // testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-engine") - // testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-launcher") - // testRuntimeOnly(group = "co.helmethair", name = "scalatest-junit-runner") - // testRuntimeOnly(group = "org.junit.vintage", name = "junit-vintage-engine") - - // Concordion BDD -// val acceptanceTestImplementation by configurations.getting -// acceptanceTestImplementation.extendsFrom(configurations["testCompileClasspath"]) -// acceptanceTestImplementation(group = "org.concordion", name = "concordion", version = concordionVersion) -// // flexmark (mostly for concordion / markdown) -// acceptanceTestImplementation("com.vladsch.flexmark:flexmark-all:0.62.2") - -// acceptanceTestImplementation( -// group = "com.vladsch.flexmark", -// name = "flexmark-ext-gfm-strikethrough", -// version = "0.62.2" -// ) -// acceptanceTestImplementation(group = "com.vladsch.flexmark", name = "flexmark-ext-emoji", version = "0.62.2") -// acceptanceTestImplementation ("com.vladsch.flexmark:flexmark-ext-yaml-front-matter:0.62.2") -// // https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-gfm-tasklist -// acceptanceTestImplementation( -// group = "com.vladsch.flexmark", -// name = "flexmark-ext-gfm-tasklist", -// version = "0.62.2" -// ) - - // testImplementation(group = "de.neuland-bfi", name = "jade4j", version = "1.2.7") - // testImplementation(group = "net.ruippeixotog", name = "scala-scraper_$scalaMajorVersion", version = "2.2.1") - // testCompileOnly(group = "org.jetbrains", name = "annotations", version = "17.0.0") - - implementation(group = "org.jetbrains", name = "annotations", version = "17.0.0") - } -} - -testing { - suites { - withType(JvmTestSuite::class).matching { it.name in listOf("acceptanceTest") }.configureEach { - - dependencies { - implementation(project(":ddo-modeling")) - } - } - } -} - -// sourceSets { -// this.getByName("acceptanceTest") { -// java { -// setSrcDirs(listOf()) -// } -// scala { -// setSrcDirs(listOf("test/scala")) -// } -// } +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2015-2021 Andre White. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ddo-core +plugins { + id("scala-library-profile") +// id("ru.vyarus.mkdocs") // version "3.0.0" + id("djaxonomy.test-conventions") +// id("doc-uml") +} + +tasks.named("check") { + dependsOn(testing.suites.named("integrationTest")) +} + +description = "Core DDO Objects" + +val concordionVersion: String by project + +dependencies { + implementation(enforcedPlatform(project(":ddo-platform-scala"))) + implementation(project(":ddo-util")) + implementation(project(":ddo-modeling")) + + val scalaLibraryVersion: String by project + val scalaMajorVersion: String by project + // Platform dependent + // https://mvnrepository.com/artifact/org.json4s/json4s-native + implementation(libs.json4s.native.s213) + +// annotationProcessor("net.thauvin.erik:semver:1.2.0") +// compileOnly("net.thauvin.erik:semver:1.2.0") + + implementation(libs.scala2.library) + implementation(libs.enumeratum.s213) + implementation(libs.typesafe.config) + implementation(group = "com.github.kxbmap", name = "configs_$scalaMajorVersion") + // validation and rules + implementation(libs.wix.accord.core.s213) + + implementation(libs.logback.classic) + implementation(libs.typesafe.scala.logging.s213) + testImplementation(project(":ddo-testing-util")) + // testImplementation(group = "org.scalatest", name = "scalatest_$scalaMajorVersion") + // testImplementation(group = "org.scalacheck", name = "scalacheck_$scalaMajorVersion") + // testImplementation(group = "org.scalatestplus", "mockito-3-4_$scalaMajorVersion") + // testImplementation(group = "com.wix", name = "accord-scalatest_$scalaMajorVersion") + + // // JUnit 5 + // testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-engine") + // testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-launcher") + // testRuntimeOnly(group = "co.helmethair", name = "scalatest-junit-runner") + // testRuntimeOnly(group = "org.junit.vintage", name = "junit-vintage-engine") + + // Concordion BDD +// val acceptanceTestImplementation by configurations.getting +// acceptanceTestImplementation.extendsFrom(configurations["testCompileClasspath"]) +// acceptanceTestImplementation(group = "org.concordion", name = "concordion", version = concordionVersion) +// // flexmark (mostly for concordion / markdown) +// acceptanceTestImplementation("com.vladsch.flexmark:flexmark-all:0.62.2") + +// acceptanceTestImplementation( +// group = "com.vladsch.flexmark", +// name = "flexmark-ext-gfm-strikethrough", +// version = "0.62.2" +// ) +// acceptanceTestImplementation(group = "com.vladsch.flexmark", name = "flexmark-ext-emoji", version = "0.62.2") +// acceptanceTestImplementation ("com.vladsch.flexmark:flexmark-ext-yaml-front-matter:0.62.2") +// // https://mvnrepository.com/artifact/com.vladsch.flexmark/flexmark-ext-gfm-tasklist +// acceptanceTestImplementation( +// group = "com.vladsch.flexmark", +// name = "flexmark-ext-gfm-tasklist", +// version = "0.62.2" +// ) + + // testImplementation(group = "de.neuland-bfi", name = "jade4j", version = "1.2.7") + // testImplementation(group = "net.ruippeixotog", name = "scala-scraper_$scalaMajorVersion", version = "2.2.1") + // testCompileOnly(group = "org.jetbrains", name = "annotations", version = "17.0.0") + + implementation(group = "org.jetbrains", name = "annotations", version = "17.0.0") +} + +testing { + suites { + withType(JvmTestSuite::class).matching { it.name in listOf("acceptanceTest") }.configureEach { + + dependencies { + implementation(project(":ddo-modeling")) + } + } + } +} + +// sourceSets { +// this.getByName("acceptanceTest") { +// java { +// setSrcDirs(listOf()) +// } +// scala { +// setSrcDirs(listOf("test/scala")) +// } +// } // } \ No newline at end of file diff --git a/subprojects/common/ddo-core/src/acceptanceTest/resources/io/truthencode/ddo/model/alignment/LawAxisSpec.html b/subprojects/common/ddo-core/src/acceptanceTest/resources/io/truthencode/ddo/model/alignment/LawAxisSpec.html index 5a508d51..0b7c84f3 100644 --- a/subprojects/common/ddo-core/src/acceptanceTest/resources/io/truthencode/ddo/model/alignment/LawAxisSpec.html +++ b/subprojects/common/ddo-core/src/acceptanceTest/resources/io/truthencode/ddo/model/alignment/LawAxisSpec.html @@ -17,7 +17,7 @@ limitations under the License. --> - + Math.abs(value) - case "-" => -1 * (value) + case "-" => -1 * value } override def toString: String = value match { @@ -36,3 +36,24 @@ case class ExtraInfo(symbol: String, value: Int) { case _ => s" $symbol $value" } } + +object ExtraInfo { + + /** + * Creates an ExtraInfo object, adding the symbol based on the value of the Int. + * @param i + * Additional value to add. + * @return + * signed ExtraInfo object + */ + def apply(i: Int): ExtraInfo = { + val sym = + if (i < 0) { + "-" + } else { + "+" + } + + ExtraInfo(sym, i) + } +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StackingRule.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StackingRule.scala index 645d4a89..a0752a0f 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StackingRule.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StackingRule.scala @@ -37,4 +37,4 @@ trait NonStacking extends StackingRule /** * Miscellaneous bonuses coming from the same source don't stack (ie - 2 paladins' aura). */ -trait StacksWithAllButSame extends StackingRule +trait StacksWithUnique extends StackingRule diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StoreLocation.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StoreLocation.scala index ec472be2..6393d3eb 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StoreLocation.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/StoreLocation.scala @@ -19,6 +19,7 @@ package io.truthencode.ddo import enumeratum.{Enum, EnumEntry} import io.truthencode.ddo.enumeration.{BitSupport, BitWise} +import io.truthencode.ddo.support.slots.{EquipmentSlot, WearLocation} import scala.collection.immutable @@ -147,7 +148,9 @@ object StoreLocation extends Enum[StoreLocation] with BitSupport { case class FiligreeSlotLocation(filigreeLocation: FiligreeLocation) extends Filigree with FiligreeLocation - case class EquippedLocation(wearLocation: WearLocation) extends ItemEquip with EquipmentSlot + case class EquippedLocation(wearLocation: WearLocation) extends ItemEquip with EquipmentSlot { + override def displaySource: String = wearLocation.displaySource + } case object Equipped extends Inventory diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/Wearable.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/Wearable.scala index 92eee78f..17f45a16 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/Wearable.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/Wearable.scala @@ -17,7 +17,8 @@ */ package io.truthencode.ddo import enumeratum.EnumEntry -import io.truthencode.ddo.enumeration.EnumExtensions._ +import io.truthencode.ddo.enumeration.EnumExtensions.{E2, EnumCompanionOps} +import io.truthencode.ddo.support.slots.WearLocation /** * Indicates the given object can be equipped / wielded etc. diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/BonusType.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/BonusType.scala index 9a112f86..8fa63e0b 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/BonusType.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/BonusType.scala @@ -18,7 +18,10 @@ package io.truthencode.ddo.enhancement import enumeratum.{Enum, EnumEntry} -import io.truthencode.ddo.{NonStacking, StackingRule, StacksWithAllButSame, StacksWithAny} +import io.truthencode.ddo.support.StringUtils.Extensions +import io.truthencode.ddo.support.naming.{DisplayName, FriendlyDisplay, Prefix} +import io.truthencode.ddo.support.slots.{Cosmetic, EquipmentSlot, WearLocation} +import io.truthencode.ddo.{NonStacking, StackingRule, StacksWithAny, StacksWithUnique} import scala.collection.immutable @@ -29,9 +32,10 @@ import scala.collection.immutable * your total armor class. (Overlapping can sometimes still benefit as the shield spell may provide * less armor class than equipping a tower shield, but it also protects against magic missiles. */ -sealed trait BonusType extends EnumEntry { +sealed trait BonusType extends EnumEntry with DisplayName with FriendlyDisplay { self: StackingRule => + override protected def nameSource: String = entryName.splitByCase } /** @@ -47,7 +51,37 @@ trait Armor extends BonusType { */ // scalastyle:off number.of.methods object BonusType extends Enum[BonusType] { - override def values: immutable.IndexedSeq[BonusType] = findValues + override def values: immutable.IndexedSeq[BonusType] = findValues ++ mythicSlotAny + + val fnStackNone: PartialFunction[BonusType, BonusType with NonStacking] = { case x: NonStacking => + x + } + + val fnStackAny: PartialFunction[BonusType, BonusType with StacksWithAny] = { + case x: StacksWithAny => + x + } + + val fnStackUnique: PartialFunction[BonusType, BonusType with StacksWithUnique] = { + case x: StacksWithUnique => + x + } + + /** + * List of bonus types that stack with all but the same type and value. Highest wins. + */ + lazy val UniqueBonusTypes: Seq[BonusType with StacksWithUnique] = values.collect(fnStackUnique) + + /** + * List of bonus types that stack with everything. Generally limited to rare 'Misc' bonus and + * Feats. + */ + lazy val AnyBonusTypes: Seq[BonusType with StacksWithAny] = values.collect(fnStackAny) + + /** + * List of bonus types that don't stack. + */ + lazy val NonStackingBonusTypes: Seq[BonusType with NonStacking] = values.collect(fnStackNone) case object ActionBoost extends BonusType with NonStacking /** @@ -216,7 +250,7 @@ object BonusType extends Enum[BonusType] { * miscellaneous bonuses to Armor Class stack with each other in DDO, but miscellaneous bonuses * coming from the same source don't stack (ie - 2 paladins' aura). */ - case object Miscellaneous extends BonusType with Armor with StacksWithAllButSame + case object Miscellaneous extends BonusType with Armor with StacksWithUnique /** * A [[https://ddowiki.com/page/Morale_bonus morale bonus]] represents the effects of greater @@ -236,9 +270,39 @@ object BonusType extends Enum[BonusType] { /** * [[https://ddowiki.com/page/Mythic_bonus Mythic bonus]] was introduced in Update 25. Mythic * bonuses stack differently than most bonus types: see quote below. The Mythic bonuses from each - * slot stack with one another + * slot stack with one another Weapons, belts, gloves, goggles, rings, and trinkets grant Mythic + * bonus to Melee, Ranged, and Universal Spell Power. Armor, boots, bracers, cloaks, headwear, + * necklaces, shields grant Mythic bonus to Physical and Magical Resistance Rating. Orbs, rune + * arms, and collars can appear Shield and/or Weapon boost. (Some) ToEE items can appear with two + * mythic bonuses, e.g., Weapon and Shield. + * + * Magnatude Weapons, armor, shields can have +2 or +4 bonus, +4 is rarer. Clothing and jewelry + * can have +1 or +3 bonus, +3 is rarer. + * + * Unlike most bonus types, all sources of Mythic bonus stack. */ - case object Mythic extends BonusType with StacksWithAny + case class Mythic(slot: EquipmentSlot) extends BonusType with StacksWithAny with Prefix { + override def displaySource: String = slot.displaySource + + /** + * Optional Prefix, used to separate sub-items such as Spell Critical Schools and also to + * disambiguate certain entities such as Feat: precision. + * + * @return + * The optional prefix. + */ + override def prefix: Option[String] = Some("Mythic") + +// override protected def nameSource: String = slot.displayText + } + + def mythicSlotAny: Seq[Mythic] = { + val wls = WearLocation.values + val wsl = WearLocation.values + .withFilter(_.isInstanceOf[EquipmentSlot]) + .withFilter(!_.isInstanceOf[Cosmetic]) + for { wc <- WearLocation.values } yield Mythic(wc.asInstanceOf[EquipmentSlot]) + } /** * [[https://ddowiki.com/page/Natural_armor_bonus Natural armor]] represents a creature's hide or @@ -341,4 +405,10 @@ object BonusType extends Enum[BonusType] { */ // case object Unique extends BonusType + /** + * Untyped bonuses stack. Note that a bonus without a keyword isn't necessarily an untyped bonus, + * the description might just be lacking. + */ + case object Untyped extends BonusType with StacksWithAny + } diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/SubBonusInformation.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/SubBonusInformation.scala new file mode 100644 index 00000000..2caca0b7 --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/SubBonusInformation.scala @@ -0,0 +1,14 @@ +package io.truthencode.ddo.enhancement + +/** + * Flag used for determining if this is a Sub-category of Bonus type having a common parent This is + * mainly useful when looking up odd stacking effects such as Mythic bonuses + * + * @return + * true if this is a Sub-category otherwise false (the default value). + */ +trait SubBonusInformation { + + def isSubCategory: Boolean = false + +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/SubBonusType.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/SubBonusType.scala new file mode 100644 index 00000000..b1f513ca --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/enhancement/SubBonusType.scala @@ -0,0 +1,8 @@ +package io.truthencode.ddo.enhancement + +/** + * Denotes this bonus type is broken down into sub-categories. + */ +trait SubBonusType extends SubBonusInformation { + override def isSubCategory: Boolean = true +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Orb.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Orb.scala new file mode 100644 index 00000000..9e77cbac --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Orb.scala @@ -0,0 +1,13 @@ +package io.truthencode.ddo.model.item.HeldItem + +import io.truthencode.ddo.Wearable +import io.truthencode.ddo.model.item.WearableItem +import io.truthencode.ddo.support.slots.WearLocation + +trait Orb extends WearableItem with Wearable { + + /** + * A bitmask that corresponds to one or more [io.truthencode.ddo.WearLocation] values. + */ + override def allowedWearLocationFlags: Int = WearLocation.OffHand.bitValue +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/RuneArm.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/RuneArm.scala index 7a93f61f..ff0d81b6 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/RuneArm.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/RuneArm.scala @@ -17,8 +17,9 @@ */ package io.truthencode.ddo.model.item.HeldItem +import io.truthencode.ddo.Wearable import io.truthencode.ddo.model.item.WearableItem -import io.truthencode.ddo.{WearLocation, Wearable} +import io.truthencode.ddo.support.slots.WearLocation trait RuneArm extends WearableItem with Wearable { diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Shield.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Shield.scala index 0f5fa562..4d5c01bf 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Shield.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Shield.scala @@ -17,11 +17,12 @@ */ package io.truthencode.ddo.model.item.HeldItem +import io.truthencode.ddo.Wearable import io.truthencode.ddo.model.item.WearableItem -import io.truthencode.ddo.{WearLocation, Wearable} +import io.truthencode.ddo.support.slots.WearLocation /** - * Includes Bucklers / and Towershields + * Includes Bucklers / and Tower shields */ trait Shield extends WearableItem with Wearable { diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Wand.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Wand.scala index ef7ced2f..29555267 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Wand.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/HeldItem/Wand.scala @@ -17,8 +17,9 @@ */ package io.truthencode.ddo.model.item.HeldItem +import io.truthencode.ddo.Wearable import io.truthencode.ddo.model.item.WearableItem -import io.truthencode.ddo.{WearLocation, Wearable} +import io.truthencode.ddo.support.slots.WearLocation trait Wand extends WearableItem with Wearable { diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ItemClassification.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ItemClassification.scala new file mode 100644 index 00000000..a5cd407f --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ItemClassification.scala @@ -0,0 +1,35 @@ +package io.truthencode.ddo.model.item + +import enumeratum.{Enum, EnumEntry} + +/** + * Classifies an item by types + * + * Can be used to denote concepts such as wearable, craftable etc. + */ +sealed trait ItemClassification extends EnumEntry + +object ItemClassification extends Enum[ItemClassification] { + override def values: IndexedSeq[ItemClassification] = findValues + + /** + * Includes potions, cakes, food, one-use items etc + */ + case object Consumable extends ItemClassification + + /** + * Item can be equipped / worn. + */ + case object Equipment extends ItemClassification + + /** + * Ingredients include many items that can be used in crafting + */ + case object Ingredient extends ItemClassification + + /** + * Physical part of a spell component + */ + case object MaterialComponent extends ItemClassification + +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ItemType.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ItemType.scala new file mode 100644 index 00000000..fab10abf --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ItemType.scala @@ -0,0 +1,11 @@ +package io.truthencode.ddo.model.item + +import enumeratum.{Enum, EnumEntry} + +sealed trait ItemType extends EnumEntry { + val classifications: List[ItemClassification] +} + +object ItemType extends Enum[ItemType] { + override def values: IndexedSeq[ItemType] = findValues +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/armor/Armor.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/armor/Armor.scala index 5b731c0e..0644f369 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/armor/Armor.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/armor/Armor.scala @@ -17,8 +17,9 @@ */ package io.truthencode.ddo.model.item.armor +import io.truthencode.ddo.Wearable import io.truthencode.ddo.model.item.WearableItem -import io.truthencode.ddo.{WearLocation, Wearable} +import io.truthencode.ddo.support.slots.WearLocation /** * Represents body armor such as Breast plates, Chainmail etc. diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/clothing/Gloves.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/clothing/Gloves.scala index 5131d288..ba5b0082 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/clothing/Gloves.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/clothing/Gloves.scala @@ -17,7 +17,8 @@ */ package io.truthencode.ddo.model.item.clothing -import io.truthencode.ddo.{WearLocation, Wearable} +import io.truthencode.ddo.Wearable +import io.truthencode.ddo.support.slots.WearLocation trait Gloves extends Clothing with Wearable { diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ingredients/Ingredient.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ingredients/Ingredient.scala index d973277b..247a15e2 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ingredients/Ingredient.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/ingredients/Ingredient.scala @@ -20,6 +20,6 @@ package io.truthencode.ddo.model.item.ingredients import io.truthencode.ddo.model.item.Item /** - * Ingrediants are primarily used in crafting to create shards and apply them to items. + * Ingredients are primarily used in crafting to create shards and apply them to items. */ trait Ingredient extends Item diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/weapon/Weapon.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/weapon/Weapon.scala index b998092d..bb510e3b 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/weapon/Weapon.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/item/weapon/Weapon.scala @@ -19,10 +19,11 @@ package io.truthencode.ddo.model.item.weapon import enumeratum.EnumEntry import io.truthencode.ddo._ -import io.truthencode.ddo.enumeration.EnumExtensions._ +import io.truthencode.ddo.enumeration.EnumExtensions.EnumCompanionOps import io.truthencode.ddo.model.attribute.Attribute import io.truthencode.ddo.model.item.WearableItem import io.truthencode.ddo.support.dice.DamageDice +import io.truthencode.ddo.support.slots.WearLocation import scala.language.implicitConversions diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/stats/Category.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/stats/Category.scala index 0d6ddcb3..00840e8c 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/stats/Category.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/model/stats/Category.scala @@ -65,7 +65,7 @@ trait SpecialAttack extends Category /** * A very general category that applies to general and specific spell casting. These should include * casting costs, cool-downs, stopping ability (silence / deafness) Spell power MAY fall under this - * or possibly split into another category as Critical Multiplier / Potentcy and Universal spell + * or possibly split into another category as Critical Multiplier / Potently and Universal spell * power like effects */ trait SpellCasting extends Category diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/dice/Dice.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/dice/Dice.scala index 02f47751..e45103fd 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/dice/Dice.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/dice/Dice.scala @@ -46,4 +46,8 @@ object Dice { override val sides: Int = s override val number: Int = n } + + def parse(s: String): Unit = { + val regx = """\[\d+d\d+\]""".r + } } diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustableNumber.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustableNumber.scala new file mode 100644 index 00000000..22ec93ff --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustableNumber.scala @@ -0,0 +1,50 @@ +package io.truthencode.ddo.support.numbers + +import io.truthencode.ddo.{NonStacking, StacksWithAny, StacksWithUnique} + +trait AdjustableNumber { + + val baseValue: Int + + val basePercent: Int + + def adjust(adjustment: Adjustment*): (Int, Int) = { + + val bases = adjustment.filter { _.kind == AdjustmentType.Base } + val amt = adjustment.filter { _.kind == AdjustmentType.Value } + val pct = adjustment.filter { _.kind == AdjustmentType.Percent } +// TODO: Implement + val r: (Int, Int) = ??? + r + } +} + +object AdjustableNumber { + val fnStackAny: PartialFunction[Adjustment, Adjustment] = { + case x if x.bonusType.isInstanceOf[StacksWithAny] => + x + } + + /** + * Stacks with others but not same. i.e. shield bonus stacks with any but other shield bonuses + */ + val fnStackNone: PartialFunction[Adjustment, Adjustment] = { + case x if x.bonusType.isInstanceOf[NonStacking] => + x + } + + /** + * Stacks with others but not same. i.e. shield bonus stacks with any but other shield bonuses + */ + val fnStackDifferent: PartialFunction[Adjustment, Adjustment] = { + case x if x.bonusType.isInstanceOf[StacksWithUnique] => + x + } + def calculateSingleType(adjustment: Adjustment*): Unit = { + val anyStacks = adjustment.collect(fnStackAny) + val nonStacking = adjustment.collect(fnStackNone) + val diffStack = adjustment.collect(fnStackDifferent) + val fl = anyStacks.foldLeft(0)((x, y) => x + y.value) + + } +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustableNumberSet.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustableNumberSet.scala new file mode 100644 index 00000000..5a99114c --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustableNumberSet.scala @@ -0,0 +1,3 @@ +package io.truthencode.ddo.support.numbers + +trait AdjustableNumberSet {} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/Adjustment.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/Adjustment.scala new file mode 100644 index 00000000..28477c9e --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/Adjustment.scala @@ -0,0 +1,21 @@ +package io.truthencode.ddo.support.numbers + +import io.truthencode.ddo.enhancement.BonusType + +/** + * Adjustment parameters for attempting to change the value of a given Adjustable Number. + * @param value + * value to add / subtract or set + * @param kind + * determines whether this operation will augment by value, percent or replace existing values + * @param bonusType + * used to determine stacking rules + * @param sourceId + * provides context for some stacking rules in addition to the ability to lookup / add remove + * stacks + */ +case class Adjustment( + value: Int, + kind: AdjustmentType, + bonusType: BonusType, + sourceId: Option[String] = None) diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustmentType.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustmentType.scala new file mode 100644 index 00000000..ef7d2313 --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/AdjustmentType.scala @@ -0,0 +1,28 @@ +package io.truthencode.ddo.support.numbers + +import enumeratum.{Enum, EnumEntry} + +sealed trait AdjustmentType extends EnumEntry + +/** + * Flags the adjustment to annotate the type of change affected. + */ +object AdjustmentType extends Enum[AdjustmentType] { + override def values: IndexedSeq[AdjustmentType] = findValues + + /** + * Changes (sets) the base value + */ + case object Base extends AdjustmentType + + /** + * Adjusts the value by a given number such as Magical Sheltering + 2 + */ + case object Value extends AdjustmentType + + /** + * Adjusts the value by a percentage such as Max Hit Points + 5% + */ + case object Percent extends AdjustmentType + +} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/NumberAdjustment.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/NumberAdjustment.scala new file mode 100644 index 00000000..22e2af78 --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/numbers/NumberAdjustment.scala @@ -0,0 +1,3 @@ +package io.truthencode.ddo.support.numbers + +trait NumberAdjustment {} diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/Cosmetic.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/Cosmetic.scala new file mode 100644 index 00000000..04fad2ed --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/Cosmetic.scala @@ -0,0 +1,6 @@ +package io.truthencode.ddo.support.slots + +/** + * Flag indicating this item is cosmetic. + */ +trait Cosmetic diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/Finger.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/Finger.scala new file mode 100644 index 00000000..f7fff0e0 --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/Finger.scala @@ -0,0 +1,6 @@ +package io.truthencode.ddo.support.slots + +/** + * Rings etc + */ +trait Finger extends EquipmentSlot diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/HeldItem.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/HeldItem.scala new file mode 100644 index 00000000..9357fa1a --- /dev/null +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/HeldItem.scala @@ -0,0 +1,6 @@ +package io.truthencode.ddo.support.slots + +/** + * Includes items that can be held or wielded from swords to wands to shields and orbs / rune arms + */ +trait HeldItem extends EquipmentSlot diff --git a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/WearLocation.scala b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/WearLocation.scala similarity index 63% rename from subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/WearLocation.scala rename to subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/WearLocation.scala index 1cb10930..dc1a9ed0 100644 --- a/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/WearLocation.scala +++ b/subprojects/common/ddo-core/src/main/scala/io/truthencode/ddo/support/slots/WearLocation.scala @@ -1,51 +1,30 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * Copyright 2015-2021 Andre White. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.truthencode.ddo +package io.truthencode.ddo.support.slots import enumeratum.{Enum, EnumEntry} import io.truthencode.ddo.enumeration.{BitSupport, BitWise} +import io.truthencode.ddo.support.StringUtils.Extensions +import io.truthencode.ddo.support.naming.{DisplayName, FriendlyDisplay} import scala.collection.immutable +trait EquipmentSlot extends WearLocation { + override def displaySource: String = entryName +} + /** * Constrains the places items can be used. */ -sealed trait WearLocation extends EnumEntry with BitWise { +sealed trait WearLocation extends EnumEntry with BitWise with DisplayName with FriendlyDisplay { override lazy val bitValue: Int = bitValues(this) private lazy val bitValues = WearLocation.valuesToIndex.map { x => x._1 -> toBitMask(x._2) } + override protected def nameSource: String = entryName.splitByCase +// abstract override def displaySource: String = super.displaySource } -trait EquipmentSlot extends WearLocation - -/** - * Rings etc - */ -trait Finger extends EquipmentSlot - -/** - * Includes items that can be held or wielded from swords to wands to shields and orbs / rune arms - */ -trait HeldItem extends EquipmentSlot - /** * Distinct values for location slots. */ @@ -62,7 +41,9 @@ object WearLocation extends Enum[WearLocation] with BitSupport { /** * Headwear such as Helmets */ - case object Head extends EquipmentSlot + case object Head extends EquipmentSlot { + override def displaySource: String = entryName + } /** * Necklaces @@ -72,7 +53,9 @@ object WearLocation extends Enum[WearLocation] with BitSupport { /** * Cloaks etc */ - case object Back extends EquipmentSlot + case object Back extends EquipmentSlot { + override def displaySource: String = "Cloak" + } /** * Includes Armbands / bracers etc @@ -129,9 +112,9 @@ object WearLocation extends Enum[WearLocation] with BitSupport { */ case object Trinket extends EquipmentSlot - case object HeadDecoration extends EquipmentSlot + case object HeadDecoration extends EquipmentSlot with Cosmetic - case object BodyDecoration extends EquipmentSlot + case object BodyDecoration extends EquipmentSlot with Cosmetic case object Ammo extends EquipmentSlot diff --git a/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/classes/AlchemistClassFeatSpec.md b/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/classes/AlchemistClassFeatSpec.md index 15dd8e5d..0770820d 100644 --- a/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/classes/AlchemistClassFeatSpec.md +++ b/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/classes/AlchemistClassFeatSpec.md @@ -145,7 +145,7 @@ Bonus Feat: An artificer can select a feat from the Artificer Bonus Feat list. Bonus Feat: An artificer can select a feat from the Artificer Bonus Feat list. |Sneak Attack| -### Artificer Bonus Feats: +### Artificer Bonus Feats | [ ][bonusFeats] [Feats][result] | Type | Description | Prerequisite | | ----------------------------------------------------------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/races/WarforgedFeatSpec.md b/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/races/WarforgedFeatSpec.md index a0e74520..664e6008 100644 --- a/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/races/WarforgedFeatSpec.md +++ b/subprojects/common/ddo-core/src/specs/resources/io/truthencode/ddo/model/feats/races/WarforgedFeatSpec.md @@ -23,12 +23,19 @@ [light_fort]: http://www.ddowiki.com/page/Light_Fortification_%28feat%29 "Light Fortification (feat)" [grantedFeats]: - "c:verify-rows=#feat:verifyGrantedFeats()" [availableFeats]: - "c:verify-rows=#feat:verifyAvailableFeats()" + + + [_matchStrategy_]: - "c:matchStrategy=KeyMatch" [result]: - "?=#feat" [elf_feat]: http://www.ddowiki.com/edit/Elf_(feat)?redlink=1 "Elf (feat) (page does not exist)" [elf_race]: http://www.ddowiki.com/page/Elf "Elf" [sunelf_race]: http://www.ddowiki.com/page/Sun_Elf_(Morninglord) "Sun Elf (Morninglord)" + + ![Attribution-ShareAlike 2.5](/images/somerights20.png) [Attribution-ShareAlike 2.5](https://creativecommons.org/licenses/by-sa/2.5/) Images and general information available from http://ddowiki.com + +[//,_matchStrategy_]: # "This behaves like a comment" diff --git a/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/ExtraInfoTest.scala b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/ExtraInfoTest.scala new file mode 100644 index 00000000..bda45036 --- /dev/null +++ b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/ExtraInfoTest.scala @@ -0,0 +1,33 @@ +package io.truthencode.ddo + +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.model.spells.SpellPower.Positive +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.funsuite.AnyFunSuiteLike +import org.scalatest.matchers.should.Matchers +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks + +class ExtraInfoTest + extends AnyFunSpec with Matchers with LazyLogging with ScalaCheckPropertyChecks { + final val Positive = "+" + final val Negative = "-" + describe("Extra Info should support numbers") { + describe("Positive Numbers") { + forAll { (n: Int) => + whenever(n > -1) { + val ei = ExtraInfo(n) + ei.symbol shouldEqual Positive + } + } + } + describe("Negative Numbers") { + forAll { (n: Int) => + whenever(n < -1) { + val ei = ExtraInfo(n) + ei.symbol shouldEqual Negative + } + } + } + } + +} diff --git a/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/StoreLocationTest.scala b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/StoreLocationTest.scala index 228e9570..c6620396 100644 --- a/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/StoreLocationTest.scala +++ b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/StoreLocationTest.scala @@ -17,6 +17,7 @@ */ package io.truthencode.ddo +import io.truthencode.ddo.support.slots.WearLocation import org.scalatest.funspec.AnyFunSpec import org.scalatest.matchers.should.Matchers diff --git a/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/enhancement/BonusTypeTest.scala b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/enhancement/BonusTypeTest.scala new file mode 100644 index 00000000..b2d20800 --- /dev/null +++ b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/enhancement/BonusTypeTest.scala @@ -0,0 +1,68 @@ +package io.truthencode.ddo.enhancement + +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.support.slots.WearLocation +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.prop.TableFor1 +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks + +import scala.collection.immutable.HashMap + +class BonusTypeTest + extends AnyFunSpec with Matchers with ScalaCheckPropertyChecks with LazyLogging { + // https://ddowiki.com/page/Category:Mythic_Boost_items + val boosts: Seq[String] = List( + "Armor", + "Belt", + "Boot", + "Cloak", + "Goggle", + "Hands", + "Head", + "Weapon", + "Neck", + "Ring", + "Shield", + "Trinket", + "Wrist").map { s => s"Mythic $s Boost" } + val expectedMythicBoosts: TableFor1[String] = Table("Boost_Type", boosts: _*) + describe("Mythic Boosts") { + /* + * Weapons, belts, gloves, goggles, rings, and trinkets grant Mythic bonus to Melee, Ranged, and Universal Spell Power. + * Armor, boots, bracers, cloaks, headwear, necklaces, shields grant Mythic bonus to Physical and Magical Resistance Rating. + * Orbs, rune arms, and collars can appear Shield and/or Weapon boost. + * (Some) ToEE items can appear with two mythic bonuses, e.g., Weapon and Shield. + */ + they("Should apply to a specific set of item slots") { + // TODO: Mythic Boost validation Dyanmically / programmatically link location to boost. + // Some ToEE items can have both Weapon and Shield bonuses. + // bonus constrained between 1 to 3 and 2 to 4 depending on level and item type. + val nameMap = HashMap( + WearLocation.MainHand -> "Weapon", + WearLocation.OffHand -> "Shield", + WearLocation.Belt -> "Belt", + WearLocation.Gloves -> "Hands", + WearLocation.Goggles -> "Goggle", + WearLocation.FirstFinger -> "Ring", + WearLocation.SecondFinger -> "Ring", + WearLocation.Trinket -> "Trinket", + WearLocation.Body -> "Armor", + WearLocation.Feet -> "Boot", + WearLocation.Wrist -> "Wrist", + WearLocation.Back -> "Cloak", + WearLocation.Head -> "Head", + WearLocation.Neck -> "Neck" + ) + val boostsFromWearLocation = nameMap.map { n => s"Mythic ${n._2} Boost" } + logger.warn(s"bootsFromWear head ${boostsFromWearLocation.head} ") + forAll(expectedMythicBoosts) { (b: String) => + logger.warn(s"testing $b") + boostsFromWearLocation should contain(b) + + } + + } + + } +} diff --git a/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/model/attribute/AttributeTest.scala b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/model/attribute/AttributeTest.scala new file mode 100644 index 00000000..fc14657c --- /dev/null +++ b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/model/attribute/AttributeTest.scala @@ -0,0 +1,31 @@ +package io.truthencode.ddo.model.attribute + +import com.typesafe.scalalogging.LazyLogging +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.prop.TableFor2 +import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks + +class AttributeTest + extends AnyFunSpec with ScalaCheckPropertyChecks with Matchers with LazyLogging { + val nameMap: TableFor2[String, String] = + Table( + ("abbr", "name"), + ("STR", "Strength"), + ("WIS", "Wisdom"), + ("INT", "Intelligence"), + ("CON", "Constitution"), + ("DEX", "Dexterity"), + ("CHA", "Charisma") + ) + + describe("Should support both abbreviations and full words") { + + forAll(nameMap) { (abbr: String, name: String) => + val atr = Attribute.withName(name) + atr.abbr shouldEqual abbr + atr.toFullWord shouldEqual (name) + } + + } +} diff --git a/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/support/numbers/AdjustableNumberTest.scala b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/support/numbers/AdjustableNumberTest.scala new file mode 100644 index 00000000..bad2c01d --- /dev/null +++ b/subprojects/common/ddo-core/src/test/scala/io/truthencode/ddo/support/numbers/AdjustableNumberTest.scala @@ -0,0 +1,113 @@ +package io.truthencode.ddo.support.numbers + +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.enhancement.BonusType +import io.truthencode.ddo.support.TraverseOps.Crossable +import org.scalatest.OptionValues.convertOptionToValuable +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers + +class AdjustableNumberTest extends AnyFunSpec with Matchers with LazyLogging { + private def fixture = new { + val bitListOf3 = List(1, 2, 4) + val anyStack = (1 to 3).map { x => + Adjustment(x, AdjustmentType.Value, BonusType.Untyped) + } + + val noneStack = List(1, 2, 4).map { x => + Adjustment(x, AdjustmentType.Value, BonusType.ActionBoost) + } + + val diffStack = List(8, 16, 32).map { x => + Adjustment(x, AdjustmentType.Value, BonusType.Miscellaneous) + } + + val allValueStacks = anyStack ++ noneStack ++ diffStack + + val anyOrNoneValueStacks = anyStack ++ noneStack + + val noneStackMany = bitListOf3.cross(BonusType.NonStackingBonusTypes.take(3)).map { b => + Adjustment(b._1, AdjustmentType.Value, b._2) + } + + val anyStackMany = bitListOf3.cross(BonusType.AnyBonusTypes.take(3)).map { b => + Adjustment(b._1, AdjustmentType.Value, b._2) + } + + val uniqueStackMany = bitListOf3.cross(BonusType.UniqueBonusTypes.take(3)).map { b => + Adjustment(b._1, AdjustmentType.Value, b._2, Some(s"KEY:${b._2.displayText}")) + + } + } + + describe("AdjustableNumberTest") { + + describe("It should filter") { + it("by Stacks with Any") { + val anyFilter = fixture.anyOrNoneValueStacks.collect(AdjustableNumber.fnStackAny) + anyFilter should have size 3 + } + + it("by stacks with other") { + val diffFilter = fixture.allValueStacks.collect(AdjustableNumber.fnStackDifferent) + diffFilter should have size 3 + } + + it("by stacks with none") { + val noneFilter = fixture.allValueStacks.collect(AdjustableNumber.fnStackNone) + noneFilter should have size 3 + } + } + + describe("it should add") { + describe("fully stacking values") { + it("Add all 'Any Stacking' values ") { + val fl = fixture.anyStack.foldLeft(0)((x, y) => x + y.value) + fl should equal(6) + } + } + describe("Unique stacking values") { + it("takes the highest value of a given type with a given key") { + val fl = fixture.uniqueStackMany + val ff = fl.map { f => + (f.bonusType, f.sourceId) -> f + } + .groupBy(_._1) + + val btg = fl.groupBy(_.bonusType) + val uniqueTypes = btg.size + val btg2 = btg.groupBy(_._2.groupBy(_.sourceId)) + val bb = btg.groupBy { x => + (x._1, x._2.groupBy(_.sourceId)) + } + for (bt <- btg.groupBy(_._2.groupBy(_.sourceId))) yield bt +// val btg2 = btg.groupMap(_._1)(_._2.) + } + } + describe("Non-stacking values") { + it("Only take the highest of a given value") { + val fl = fixture.noneStack.sortBy(_.value).reverse.headOption + fl.value.value should equal(4) + } + it("Sum the highest of each unique non-stacking value") { + // should be 3 types with 3 values each, highest being 4 + val fl = fixture.noneStackMany + val btg = fl.groupBy(_.bonusType) + val uniqueTypes = btg.size // max of 3, currently only 1 (Misc) exists + val max = fixture.bitListOf3.max + val mAdjust = btg.map { btm => + (btm._1, btm._2.toList.sortBy(_.value).reverse.headOption) + } + val rslt = mAdjust.foldLeft(0)((x, y) => + x + (y._2 match { + case Some(x) => x.value + case _ => 0 + })) + logger.info(s"max: $max*\ttypes: $uniqueTypes") + rslt should equal(max * uniqueTypes) + + } + } + } + } +} diff --git a/subprojects/common/ddo-etl/build.gradle.kts b/subprojects/common/ddo-etl/build.gradle.kts index dfeb632f..e6c32f74 100644 --- a/subprojects/common/ddo-etl/build.gradle.kts +++ b/subprojects/common/ddo-etl/build.gradle.kts @@ -15,14 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Scala library project to get you started. - * For more details take a look at the Scala plugin chapter in the Gradle - * User Manual available at https://docs.gradle.org/6.1.1/userguide/scala_plugin.html - */ - plugins { id("scala-conventions") // id("acceptance-test-conventions") @@ -33,6 +25,11 @@ description = "Common ETL module for storing / loading data from web / user etc" dependencies { implementation(enforcedPlatform(project(":ddo-platform-scala"))) + implementation(project(":ddo-antlr")) + implementation(project(":ddo-web")) { + because("ddo-web is used for web scraping") + } + implementation(project(":ddo-core")) /* might use https://github.com/nrinaudo for etl regex support @@ -45,28 +42,28 @@ dependencies { val scalaLibraryVersion: String by project val scalaMajorVersion: String by project // https://mvnrepository.com/artifact/org.json4s/json4s-native - implementation(group = "org.json4s", name = "json4s-native_$scalaMajorVersion") + implementation(libs.json4s.native.s213) - implementation("org.scala-lang:scala-library:$scalaLibraryVersion") - implementation(group = "com.beachape", name = "enumeratum_$scalaMajorVersion") - implementation(group = "com.typesafe", name = "config") - implementation(group = "com.github.kxbmap", name = "configs_$scalaMajorVersion") + implementation(libs.scala2.library) + implementation(libs.enumeratum.s213) + implementation(libs.typesafe.config) + implementation(libs.kxbmap.configs.s213) /* DB, Query etc // Quill Scala Query QSQL https://github.com/getquill/quill */ - implementation(group = "io.getquill", name = "quill-core_$scalaMajorVersion") + implementation(libs.quill.core.s213) /* Quill - Monix Integration Monix Task / Eval https://monix.io/docs/current/intro/hello-world.html */ - implementation(group = "io.getquill", name = "quill-monix_$scalaMajorVersion") - implementation(group = "io.getquill", name = "quill-sql_$scalaMajorVersion") - implementation(group = "io.monix", name = "monix-eval_$scalaMajorVersion") - implementation(group = "io.monix", name = "monix-reactive_$scalaMajorVersion") + implementation(libs.quill.monix.s213) + implementation(libs.quill.sql.s213) + implementation(libs.monix.eval.s213) + implementation(libs.monix.reactive.s213) // validation and rules - implementation(group = "com.wix", name = "accord-core_$scalaMajorVersion") - implementation(group = "ch.qos.logback", name = "logback-classic") - implementation(group = "com.typesafe.scala-logging", name = "scala-logging_$scalaMajorVersion") + implementation(libs.wix.accord.core.s213) + implementation(libs.logback.classic) + implementation(libs.typesafe.scala.logging.s213) // testImplementation(group = "org.scalatest", name = "scalatest_$scalaMajorVersion") // testImplementation(group = "org.scalacheck", name = "scalacheck_$scalaMajorVersion", version = "1.14.0") // testImplementation(group = "org.mockito", name = "mockito-core") diff --git a/subprojects/common/ddo-modeling/build.gradle.kts b/subprojects/common/ddo-modeling/build.gradle.kts index 81329e67..c9b243b1 100644 --- a/subprojects/common/ddo-modeling/build.gradle.kts +++ b/subprojects/common/ddo-modeling/build.gradle.kts @@ -19,50 +19,81 @@ plugins { id("scala-library-profile") id("djaxonomy.test-conventions") - id("com.zlad.gradle.avrohugger") +// id("com.zlad.gradle.avrohugger") // id("com.github.lkishalmi.gatling") version "3.2.9" // id("io.gatling.gradle") version "3.9.5.5" replaces above id("org.openapi.generator") +// id("io.quarkus")// version "3.3.3" } +// apply { +// plugin("io.quarkus")// version "3.3.3" +// } -dependencies { - /* - https://github.com/fthomas/refined - check out refined library for compile time constraints - unsure how helpful this will be as most data will need runtime validation (aka wix) - */ - // Use Scala $scalaMajorVersion in our library project - val scalaLibraryVersion: String by project - val scalaMajorVersion: String by project +// OpenApi code / schema generation - implementation(enforcedPlatform(project(":ddo-platform-scala"))) - implementation("org.scala-lang:scala-library:$scalaLibraryVersion") - implementation(group = "com.beachape", name = "enumeratum_$scalaMajorVersion") - implementation(group = "com.typesafe", name = "config") - implementation(group = "com.github.kxbmap", name = "configs_$scalaMajorVersion") +val apiSpec: FileCollection = project.rootProject.layout.files("$rootDir/specs/ddo-fatespinner-oas3-swagger.yaml") +// Location of Avro schema files +val schemaDir: FileCollection = layout.files("src/main/resources/schemas/avro") +// Location of Avro generated Scala files from ddo-avro external build +val generatedScalaSourceDir = layout.buildDirectory.files("avro-gen") +// val ff =project.rootProject.layout.files("../../subprojects/common/ddo-model/build/avro-gen") +val CODE_GEN = "codeGen" +// External builds +// Calling as external build due to scala library version incompatibilities +// between AvroHugger (scala 2.12.1?) and Quarkus 2.13.x / 3) +tasks.register("generateAvroSchemas", GradleBuild::class) { + val output = layout.buildDirectory.dir("avro-gen") + outputs.dir(output) + val input = rootProject.layout.projectDirectory.file("include/ddo-avro").asFile + inputs.dir(input) + dir = rootProject.layout.projectDirectory.file("include/ddo-avro").asFile - implementation(group = "org.json4s", name = "json4s-native_$scalaMajorVersion") + tasks = listOf("generateAvroScala") +} - // validation and rules - implementation(group = "com.wix", name = "accord-core_$scalaMajorVersion") - implementation(group = "ch.qos.logback", name = "logback-classic") - implementation(group = "com.typesafe.scala-logging", name = "scala-logging_$scalaMajorVersion") -// testImplementation(group = "org.scalatest", name = "scalatest_$scalaMajorVersion") -// testImplementation(group = "org.mockito", name = "mockito-core") -// -// // JUnit 5 -// testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-engine") -// testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-launcher") -// testRuntimeOnly(group = "co.helmethair", name = "scalatest-junit-runner") +tasks.register("cleanAvroSchemas", GradleBuild::class) { + dir = rootProject.layout.projectDirectory.file("include/ddo-avro").asFile + + tasks = listOf("clean") } -// OpenApi code / schema generation +configurations { + val codeGen by configurations.creating { + isCanBeConsumed = false + isCanBeResolved = true + } +} -val apiSpec: FileCollection = project.rootProject.layout.files("$rootDir/specs/ddo-fatespinner-oas3-swagger.yaml") -// Location of Avro schema files -val schemaDir: FileCollection = layout.files("src/main/resources/schemas/avro") -// Location of ?? -val generatedScalaSourceDir = layout.files("src/main/avro") +sourceSets { + this.configureEach { + scala { + + this.srcDir(tasks.named("generateAvroSchemas")) + } + } +// scala { +// this.srcDir(tasks.named("generateAvroSchemas")) +// } +// val codeGen by creating { +// scala { +// this.srcDir(tasks.named("generateAvroSchemas")) +// } +// } +} + +// tasks.named("compileCodeGenScala",ScalaCompile::class) { +// classpath = configurations.named(CODE_GEN).get() +// } + +// TODO: Build Chore +// Configure proper task dependency and remove explicit depends on for Avro Generation +tasks.named("clean") { + dependsOn("cleanAvroSchemas") +} + +tasks.named("compileScala") { + dependsOn("generateAvroSchemas") +} /** * Api spec OpenAPI specification generation information @@ -131,16 +162,16 @@ openApiValidate { inputSpec.set(apiSpec.asPath) } -avrohugger { - this.sourceDirectories { - this.from(schemaDir) - } - this.destinationDirectory.set(generatedScalaSourceDir.singleFile) - typeMapping { - protocolType = com.zlad.gradle.avrohugger.AvrohuggerExtension.ScalaADT - enumType = com.zlad.gradle.avrohugger.AvrohuggerExtension.ScalaCaseObjectEnum - } -} +// avrohugger { +// this.sourceDirectories { +// this.from(schemaDir) +// } +// this.destinationDirectory.set(generatedScalaSourceDir.singleFile) +// typeMapping { +// protocolType = com.zlad.gradle.avrohugger.AvrohuggerExtension.ScalaADT +// enumType = com.zlad.gradle.avrohugger.AvrohuggerExtension.ScalaCaseObjectEnum +// } +// } val schemaList = listOf("parseHub") // Create Tasks to generate Avro Schemas for our OpenAPI specs @@ -231,4 +262,43 @@ tasks { // withType { // mustRunAfter(gas) // } +} + +dependencies { + /* + https://github.com/fthomas/refined + check out refined library for compile time constraints + unsure how helpful this will be as most data will need runtime validation (aka wix) + */ + // Use Scala $scalaMajorVersion in our library project + val scalaLibraryVersion: String by project + val scalaMajorVersion: String by project + + implementation(enforcedPlatform(project(":ddo-platform-scala"))) + implementation(libs.scala2.library) { + version { + strictly("2.13.10") + } + } + implementation(libs.enumeratum.s213) + implementation(libs.typesafe.config) + implementation(libs.kxbmap.configs.s213) + + implementation(libs.json4s.native.s213) + + // validation and rules + implementation(libs.wix.accord.core.s213) + implementation(libs.logback.classic) + implementation(libs.typesafe.scala.logging.s213) +// val codeGenImplementation by configurations.getting { +// extendsFrom(configurations.named("implementation").get()) +// } + +// testImplementation(group = "org.scalatest", name = "scalatest_$scalaMajorVersion") +// testImplementation(group = "org.mockito", name = "mockito-core") +// +// // JUnit 5 +// testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-engine") +// testRuntimeOnly(group = "org.junit.platform", name = "junit-platform-launcher") +// testRuntimeOnly(group = "co.helmethair", name = "scalatest-junit-runner") } \ No newline at end of file diff --git a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/ValueChange.scala b/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/ValueChange.scala deleted file mode 100644 index 6fffa999..00000000 --- a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/ValueChange.scala +++ /dev/null @@ -1,14 +0,0 @@ -/** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */ -package io.truthencode.ddo.model.protocol - -sealed trait ValueChange - -sealed trait ChangeType extends ValueChange - -object ChangeType { - case object INCREASE extends ChangeType - case object DECREASE extends ChangeType - case object NOCHANGE extends ChangeType -} - -final case class ChangeValueInt(id: String, currentValue: Int, prevValue: Int, changeType: ChangeType) extends ValueChange \ No newline at end of file diff --git a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/CriticalThreatRange.scala b/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/CriticalThreatRange.scala deleted file mode 100644 index 9e11f1b0..00000000 --- a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/CriticalThreatRange.scala +++ /dev/null @@ -1,9 +0,0 @@ -/** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */ -package io.truthencode.ddo.model.protocol.parsers - -/** - * @param min Lower bound for critical multiplier - * @param max Upper bound for critical multiplier - * @param multiplier Number to multiply the damage roll by - */ -final case class CriticalThreatRange(min: Option[Int], max: Option[Int], multiplier: Option[Int]) \ No newline at end of file diff --git a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/DamageParserInfo.scala b/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/DamageParserInfo.scala deleted file mode 100644 index a3c7dc32..00000000 --- a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/DamageParserInfo.scala +++ /dev/null @@ -1,33 +0,0 @@ -/** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */ -package io.truthencode.ddo.model.protocol.parsers - -sealed trait DamageParserInfo - -/** - * A most basic encapsulation of damage information. - * @param dice_modifier Multiplier for the dice - * @param dice Dice expression in the form of nDm - * @param extra Additional Damage after the dice - * @param damage_type Includes both Physical and Magical Damage types - */ -final case class DamageInfo(dice_modifier: Option[Int], dice: Option[String], extra: Option[Int], damage_type: DamageTrait) extends DamageParserInfo - -sealed trait DamageTrait extends DamageParserInfo - -object DamageTrait { - case object Acid extends DamageTrait - case object Fire extends DamageTrait - case object Cold extends DamageTrait - case object Electric extends DamageTrait - case object Force extends DamageTrait - case object Sonic extends DamageTrait - case object Poison extends DamageTrait - case object Evil extends DamageTrait - case object Good extends DamageTrait - case object UnTyped extends DamageTrait - case object Special extends DamageTrait - case object Bludgeon extends DamageTrait - case object Pierce extends DamageTrait - case object Slash extends DamageTrait - case object Magic extends DamageTrait -} \ No newline at end of file diff --git a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/WeaponInfo.scala b/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/WeaponInfo.scala deleted file mode 100644 index fb249744..00000000 --- a/subprojects/common/ddo-modeling/src/main/avro/io/truthencode/ddo/model/protocol/parsers/WeaponInfo.scala +++ /dev/null @@ -1,135 +0,0 @@ -/** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */ -package io.truthencode.ddo.model.protocol.parsers - -sealed trait WeaponInfo - -/** - * @param name Name of the Item - * @param proficiency_class General Level of Martial training required to wield - * @param image Screen shot or image URI - * @param damage - * @param damage_type - * @param critical_threat_range - * @param weapon_category The type of weapon such as long sword Axe etc - * @param required_race Race required to use item without a UMD Check - * @param abs_required_race Race absolutely required (no bypass) to use item - * @param abs_restricted_race Races specifically not allowed to use - * @param min_level Minimum character level required to use item - * @param abs_min_level Altered minimum level usually caused as a side-effect of additional enchantments which may increase the requirement - * @param required_trait Trait such as Lawful needed to use item - * @param umd Use Magical Device DC - * @param handedness Allowed slots such as one handed (main or off hand) / two handed - * @param attack_mod Attribute(s) that modify the attack roll - * @param damage_mod Attribute(s) that modify the damage roll - * @param binding Character or Account binding, if any - * @param durability tensile strength, how hard it is to damage - * @param wear_location Allowed slots for the item to be equipped - * @param material material made from - * @param hardness physical toughness of the item - * @param base_value Monetary value of item - * @param weight weight in pounds - * @param location Text describing the location of the item - * @param enchantments Collection of Enchantments on the item. - * @param enchantments_choice Used to support One of the following - * @param upgradeable If an item can be upgraded, instructions or the name of the upgraded item may appear here. - * @param description_text descriptive text of the item - * @param sets Any sets this item belongs to that give bonuses when all items are equipped. - */ -final case class Weapon(name: Option[String], proficiency_class: Option[Weapon_proficiencyUnderscoreclass], image: Option[String], damage: Option[DamageTrait], damage_type: Option[DamageInfo], critical_threat_range: Option[CriticalThreatRange], weapon_category: Option[Weapon_weaponUnderscorecategory], required_race: Option[Seq[String]], abs_required_race: Option[Seq[String]], abs_restricted_race: Option[Seq[String]], min_level: Option[Int], abs_min_level: Option[Int], required_trait: Option[Seq[String]], umd: Option[String], handedness: Option[Seq[String]], attack_mod: Option[Seq[String]], damage_mod: Option[Seq[String]], binding: Option[String], durability: Option[Int], wear_location: Option[Weapon_wearUnderscorelocation], material: Option[Weapon_material], hardness: Option[Int], base_value: Option[String], weight: Option[Int], location: Option[String], enchantments: Option[Seq[String]], enchantments_choice: Option[Seq[String]], upgradeable: Option[String], description_text: Option[String], sets: Option[Seq[String]]) extends WeaponInfo - -sealed trait Weapon_proficiencyUnderscoreclass extends WeaponInfo - -object Weapon_proficiencyUnderscoreclass { - case object Simple extends Weapon_proficiencyUnderscoreclass - case object Martial extends Weapon_proficiencyUnderscoreclass - case object Exotic extends Weapon_proficiencyUnderscoreclass -} - -sealed trait Weapon_weaponUnderscorecategory extends WeaponInfo - -object Weapon_weaponUnderscorecategory { - case object BastardSword extends Weapon_weaponUnderscorecategory - case object BattleAxe extends Weapon_weaponUnderscorecategory - case object Club extends Weapon_weaponUnderscorecategory - case object Dagger extends Weapon_weaponUnderscorecategory - case object Dart extends Weapon_weaponUnderscorecategory - case object DwarvenWarAxe extends Weapon_weaponUnderscorecategory - case object Falchion extends Weapon_weaponUnderscorecategory - case object GreatAxe extends Weapon_weaponUnderscorecategory - case object GreatClub extends Weapon_weaponUnderscorecategory - case object GreatCrossbow extends Weapon_weaponUnderscorecategory - case object GreatSword extends Weapon_weaponUnderscorecategory - case object HandAxe extends Weapon_weaponUnderscorecategory - case object Handwrap extends Weapon_weaponUnderscorecategory - case object HeavyCrossbow extends Weapon_weaponUnderscorecategory - case object HeavyMace extends Weapon_weaponUnderscorecategory - case object HeavyPick extends Weapon_weaponUnderscorecategory - case object Kama extends Weapon_weaponUnderscorecategory - case object Khopesh extends Weapon_weaponUnderscorecategory - case object Kukris extends Weapon_weaponUnderscorecategory - case object LightCrossbow extends Weapon_weaponUnderscorecategory - case object LightHammer extends Weapon_weaponUnderscorecategory - case object LightMace extends Weapon_weaponUnderscorecategory - case object LightPick extends Weapon_weaponUnderscorecategory - case object Longbow extends Weapon_weaponUnderscorecategory - case object Longsword extends Weapon_weaponUnderscorecategory - case object Maul extends Weapon_weaponUnderscorecategory - case object Morningstar extends Weapon_weaponUnderscorecategory - case object Quarterstaff extends Weapon_weaponUnderscorecategory - case object Rapier extends Weapon_weaponUnderscorecategory - case object RepeatingHeavyCrossbow extends Weapon_weaponUnderscorecategory - case object RepeatingLightCrossbow extends Weapon_weaponUnderscorecategory - case object Scimitar extends Weapon_weaponUnderscorecategory - case object Shortbow extends Weapon_weaponUnderscorecategory - case object ShortSword extends Weapon_weaponUnderscorecategory - case object Shuriken extends Weapon_weaponUnderscorecategory - case object Sickle extends Weapon_weaponUnderscorecategory - case object SimpleProjectile extends Weapon_weaponUnderscorecategory - case object ThrowingAxe extends Weapon_weaponUnderscorecategory - case object ThrowingDagger extends Weapon_weaponUnderscorecategory - case object ThrowingHammer extends Weapon_weaponUnderscorecategory - case object WarHammer extends Weapon_weaponUnderscorecategory -} - -sealed trait Weapon_wearUnderscorelocation extends WeaponInfo - -object Weapon_wearUnderscorelocation { - case object MainHand extends Weapon_wearUnderscorelocation - case object OffHand extends Weapon_wearUnderscorelocation - case object TwoHand extends Weapon_wearUnderscorelocation -} - -sealed trait Weapon_material extends WeaponInfo - -object Weapon_material { - case object Adamantine extends Weapon_material - case object Blueshine extends Weapon_material - case object Bone extends Weapon_material - case object Byeshk extends Weapon_material - case object Cloth extends Weapon_material - case object Cold_Iron extends Weapon_material - case object Crystal extends Weapon_material - case object Darkleaf extends Weapon_material - case object Darkwood extends Weapon_material - case object Densewood extends Weapon_material - case object Dwarven_Iron extends Weapon_material - case object Feyleather extends Weapon_material - case object Flametouched_Iron extends Weapon_material - case object Flesh extends Weapon_material - case object Force extends Weapon_material - case object Gem extends Weapon_material - case object Glass extends Weapon_material - case object Ice extends Weapon_material - case object Leather extends Weapon_material - case object Light extends Weapon_material - case object Magesteel extends Weapon_material - case object Mithral extends Weapon_material - case object Planeforged_Steel extends Weapon_material - case object Rust extends Weapon_material - case object Silver extends Weapon_material - case object Spiritcraft_Leather extends Weapon_material - case object Spiritforged_Iron extends Weapon_material - case object Steel extends Weapon_material - case object Stone extends Weapon_material - case object Wood extends Weapon_material -} \ No newline at end of file diff --git a/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/CriticalThreatRange.avdl b/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/CriticalThreatRange.avdl index 7a8f2c1c..e534eff6 100644 --- a/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/CriticalThreatRange.avdl +++ b/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/CriticalThreatRange.avdl @@ -3,10 +3,10 @@ protocol CriticalThreatRange { /** */ record CriticalThreatRange { /** Lower bound for critical multiplier */ - union{null, int} min; + int? min; /** Upper bound for critical multiplier */ - union{null, int} max; + int? max; /** Number to multiply the damage roll by */ - union{null, int} multiplier; + int? multiplier; } } diff --git a/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/Weapon.avdl b/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/Weapon.avdl index d9d20a96..789b2ceb 100644 --- a/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/Weapon.avdl +++ b/subprojects/common/ddo-modeling/src/main/resources/schemas/avro/Weapon.avdl @@ -6,16 +6,16 @@ protocol WeaponInfo { /** */ record Weapon { /** Name of the Item */ - union{null, string} name; + string? name; /** General Level of Martial training required to wield */ - union{null, Weapon_proficiencyUnderscoreclass} proficiency_class; + Weapon_proficiencyUnderscoreclass? proficiency_class; /** Screen shot or image URI */ - union{null, string} image; - union{null, DamageTrait} damage; - union{null, DamageInfo} damage_type; - union{null, CriticalThreatRange} critical_threat_range; + string? image; + DamageTrait? damage; + DamageInfo? damage_type; + CriticalThreatRange? critical_threat_range; /** The type of weapon such as long sword Axe etc */ - union{null, Weapon_weaponUnderscorecategory} weapon_category; + Weapon_weaponUnderscorecategory? weapon_category; /** Race required to use item without a UMD Check */ union{null, array} required_race; /** Race absolutely required (no bypass) to use item */ @@ -23,13 +23,13 @@ protocol WeaponInfo { /** Races specifically not allowed to use */ union{null, array} abs_restricted_race; /** Minimum character level required to use item */ - union{null, int} min_level; + int? min_level; /** Altered minimum level usually caused as a side-effect of additional enchantments which may increase the requirement */ - union{null, int} abs_min_level; + int? abs_min_level; /** Trait such as Lawful needed to use item */ union{null, array} required_trait; /** Use Magical Device DC */ - union{null, string} umd; + string? umd; /** Allowed slots such as one handed (main or off hand) / two handed */ union{null, array} handedness; /** Attribute(s) that modify the attack roll */ @@ -37,29 +37,29 @@ protocol WeaponInfo { /** Attribute(s) that modify the damage roll */ union{null, array} damage_mod; /** Character or Account binding, if any */ - union{null, string} binding; + string? binding; /** tensile strength, how hard it is to damage */ - union{null, int} durability; + int? durability; /** Allowed slots for the item to be equipped */ - union{null, Weapon_wearUnderscorelocation} wear_location; + Weapon_wearUnderscorelocation? wear_location; /** material made from */ - union{null, Weapon_material} material; + Weapon_material? material; /** physical toughness of the item */ - union{null, int} hardness; + int? hardness; /** Monetary value of item */ - union{null, string} base_value; + string? base_value; /** weight in pounds */ - union{null, int} weight; + int? weight; /** Text describing the location of the item */ - union{null, string} location; + string? location; /** Collection of Enchantments on the item. */ union{null, array} enchantments; /** Used to support One of the following */ union{null, array} enchantments_choice; /** If an item can be upgraded, instructions or the name of the upgraded item may appear here. */ - union{null, string} upgradeable; + string? upgradeable; /** descriptive text of the item */ - union{null, string} description_text; + string? description_text; /** Any sets this item belongs to that give bonuses when all items are equipped. */ union{null, array} sets; } diff --git a/subprojects/common/ddo-modeling/src/main/scala/io/truthencode/ddo/model/meta/PhysicalDamageType.scala b/subprojects/common/ddo-modeling/src/main/scala/io/truthencode/ddo/model/meta/PhysicalDamageType.scala index 3713e249..a2be18d5 100644 --- a/subprojects/common/ddo-modeling/src/main/scala/io/truthencode/ddo/model/meta/PhysicalDamageType.scala +++ b/subprojects/common/ddo-modeling/src/main/scala/io/truthencode/ddo/model/meta/PhysicalDamageType.scala @@ -22,7 +22,8 @@ import io.truthencode.ddo.NoDefault import io.truthencode.ddo.model.effect._ /** - * Basic damage for (generally) physical damage + * Basic damage for (generally) physical damage such as melee weapons or projectiles (arrows / + * bolts) in addition to physical components to spells such as bludgeon damage from 'Ice Storm'. */ sealed trait PhysicalDamageType extends EnumEntry with Damage with NoDefault[PhysicalDamageType] { self: DamageType => diff --git a/subprojects/common/ddo-modeling/src/test/scala/io/truthencode/ddo/modeling/LibrarySuite.scala b/subprojects/common/ddo-modeling/src/test/scala/io/truthencode/ddo/modeling/LibrarySuite.scala index cb0891ff..fa9c7de6 100644 --- a/subprojects/common/ddo-modeling/src/test/scala/io/truthencode/ddo/modeling/LibrarySuite.scala +++ b/subprojects/common/ddo-modeling/src/test/scala/io/truthencode/ddo/modeling/LibrarySuite.scala @@ -20,11 +20,17 @@ */ package io.truthencode.ddo.modeling -import org.scalatest.funsuite.AnyFunSuite +import org.scalatest.funspec.AnyFunSpec -class LibrarySuite extends AnyFunSuite { - test("someLibraryMethod is always true") { +class LibrarySuite extends AnyFunSpec { + describe("someLibraryMethod is always true") { def library: Library = new Library() assert(library.someLibraryMethod()) } + + describe("Something magical") { + it("can fluctuate") { + val vc = io.truthencode.ddo.model.protocol.ChangeType + } + } } diff --git a/subprojects/common/ddo-test-results/build.gradle.kts b/subprojects/common/ddo-test-results/build.gradle.kts index 1b9f0e0c..7508e76f 100644 --- a/subprojects/common/ddo-test-results/build.gradle.kts +++ b/subprojects/common/ddo-test-results/build.gradle.kts @@ -6,25 +6,89 @@ plugins { } dependencies { + // projectList().map { it -> testReportAggregation(project("$it")) } + + testReportAggregation(project(":ddo-antlr")) testReportAggregation(project(":ddo-core")) + testReportAggregation(project(":ddo-etl")) + testReportAggregation(project(":ddo-modeling")) + testReportAggregation(project(":ddo-platform")) + testReportAggregation(project(":ddo-platform-kotlin")) + testReportAggregation(project(":ddo-platform-scala")) + testReportAggregation(project(":ddo-util")) + // acceptanceTestReportAggregation(project(":ddo-core")) } reporting { reports { val testAggregateTestReport by creating(AggregateTestReport::class) { - testType.set(TestSuiteType.UNIT_TEST) +// testType.set(TestSuiteType.UNIT_TEST) + testType.set("acceptance-test") + } + // val testAggregateAcceptanceTestReport by creating(AggregateTestReport::class) { + // testType.set("acceptance-test") + // } + } +} + +/** +Task simply prints out a list of projects to be used in the testReportAggregation +this list isn't immideately available in the configuration phase, so we have to cut and paste +from a manually run listProjects task + */ +tasks.register("listProjects") { + doLast { + val pl = projectList() + pl.sort() + val types = listOf("acceptance", "") + types.forEach { t -> + pl.forEach { p -> + if (t == "") { + println("testReportAggregation(project(\"$p\"))") + } else { + println("${t}TestReportAggregation(project(\"$p\"))") + } + } } } } description = "Utility class for aggregating Reports" -// Transliterated Groovy -> Kotlin from -// https://gist.githubusercontent.com/nikialeksey/7cefae6b3104ce9a2c765197343bc436/raw/fb61c7d35480f9ae16650aefbb31c9c11420bec4/dependency-report.gradle -// Inspired by https://gist.github.com/tzachz/419478fc8b009e953f5e5dc39f3f3a2a -// Task creates a .dot file with all inter-module dependencies -// Supports any depth of nested modules +fun projectList(): MutableList { + logger.error("projectList called") + val sb = mutableListOf() + findProjects(sb, project.rootProject) + logger.debug("findProject results: {}", sb) + return sb +} + +// create a list of non-test projects +fun findProjects( + writer: MutableList, + project: Project, +) { + if (!project.name + .contains("test") && project.name.startsWith("ddo") && project != project.rootProject + ) { + writer.add(":${project.name}") + logger.info("found ${project.childProjects.size} child projects in ${project.name}") + } + project.childProjects.forEach { (_, childProject) -> findProjects(writer, childProject) } +} + +/** +Should be called with mdDocsBuild task + + Transliterated Groovy -> Kotlin from + https://gist.githubusercontent.com/nikialeksey/7cefae6b3104ce9a2c765197343bc436/raw/fb61c7d35480f9ae16650aefbb31c9c11420bec4/dependency-report.gradle + Inspired by https://gist.github.com/tzachz/419478fc8b009e953f5e5dc39f3f3a2a + Task creates a .dot file with all inter-module dependencies + Supports any depth of nested modules + + */ tasks.register("moduleDependencyReport") { + description = "Creates a .dot file with all inter-module dependencies" doLast { val file = rootProject.layout.projectDirectory.file("docs/developers_guide/project-dependencies.dot").asFile file.delete() @@ -37,8 +101,18 @@ tasks.register("moduleDependencyReport") { w.write("}\n") } } +// // val t = this +// tasks.withType(ru.vyarus.gradle.plugin.mkdocs.task.MkdocsBuildTask::class) { +// // dependsOn(t) +// // dependsOn(tasks.named(":ddo-test-results:moduleDependencyReport")) +// dependsOn(tasks.named("moduleDependencyReport")) +// } } +// tasks.named("mkDocsBuild") { +// dependsOn(tasks.named("moduleDependencyReport")) +// } + // recursively print dependencies to file and move on to child projects fun printDeps( writer: Writer, @@ -54,9 +128,15 @@ fun printDeps( .toSet() .filterIsInstance(ProjectDependency::class.java) .filterNot { it.name.contains("test") || it.name == project.name } - .map { "\"${project.name}\" -> \"${it.name}\"\n" } + .map { + logger.error("Mapping project: $project -> ${it.name}") + "\"${project.name}\" -> \"${it.name}\"\n" + } .forEach(writer::write) logger.info("found ${project.childProjects.size} child projects in ${project.name}") } - project.childProjects.forEach { (_, childProject) -> printDeps(writer, childProject) } + project.childProjects.forEach { (_, childProject) -> + logger.error("recursive call for $childProject") + printDeps(writer, childProject) + } } \ No newline at end of file diff --git a/subprojects/common/ddo-util/build.gradle.kts b/subprojects/common/ddo-util/build.gradle.kts index 480d2cbe..f63efe8a 100644 --- a/subprojects/common/ddo-util/build.gradle.kts +++ b/subprojects/common/ddo-util/build.gradle.kts @@ -34,15 +34,15 @@ dependencies { // https://mvnrepository.com/artifact/org.json4s/json4s-native // implementation(group = "org.json4s", name = "json4s-native_$scalaMajorVersion") // implementation(group = "org.scala-lang", name = "scala-library") - implementation("org.scala-lang:scala-library:$scalaLibraryVersion") + implementation(libs.scala2.library) - implementation(group = "com.beachape", name = "enumeratum_$scalaMajorVersion") + implementation(libs.enumeratum.s213) // implementation(group = "com.typesafe", name = "config") // implementation(group = "com.github.kxbmap", name = "configs_$scalaMajorVersion") // // validation and rules // implementation(group = "com.wix", name = "accord-core_$scalaMajorVersion") - implementation(group = "ch.qos.logback", name = "logback-classic") - implementation(group = "com.typesafe.scala-logging", name = "scala-logging_$scalaMajorVersion") + implementation(libs.logback.classic) + implementation(libs.typesafe.scala.logging.s213) // testImplementation(group = "org.scalatest", name = "scalatest_$scalaMajorVersion") // testImplementation(group = "org.mockito", name = "mockito-core") // diff --git a/subprojects/common/ddo-web/build.gradle.kts b/subprojects/common/ddo-web/build.gradle.kts new file mode 100644 index 00000000..87b3bcf9 --- /dev/null +++ b/subprojects/common/ddo-web/build.gradle.kts @@ -0,0 +1,41 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2015-2021 Andre White. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +plugins { + + id("scala-library-profile") +// id("ru.vyarus.mkdocs") // version "3.0.0" + id("djaxonomy.test-conventions") +} + +description = "DDO Web ETL for wiki data" +dependencies { + implementation(enforcedPlatform(project(":ddo-platform"))) + implementation(project(":ddo-core")) + implementation(project(":ddo-modeling")) + implementation(project(":ddo-util")) { + because("Implicits with string matching etc") + } + implementation(libs.scala2.library) + implementation(libs.ruippeixotog.scala.scraper.s213) + implementation(libs.typesafe.config) + implementation(libs.typesafe.scala.logging.s213) + implementation(libs.logback.classic) + implementation(libs.enumeratum.s213) + + // implementation(group = "com.typesafe.scala-logging", name = "scala-logging_$scalaMajorVersion") +} \ No newline at end of file diff --git a/subprojects/common/ddo-web/pom.xml b/subprojects/common/ddo-web/pom.xml new file mode 100644 index 00000000..6080bc48 --- /dev/null +++ b/subprojects/common/ddo-web/pom.xml @@ -0,0 +1,200 @@ + + + 4.0.0 + + ddo-calc + ddo-calc-parent + 0.1.0-alpha + + ddo-web + DDO Web + API for setting and retrieving information via HTTP + + + + net.ruippeixotog + scala-scraper_${scala.tools.version} + + + + com.typesafe + config + + + + com.typesafe.scala-logging + scala-logging_${scala.tools.version} + + + ch.qos.logback + logback-classic + + + ${project.groupId} + ddo-core + ${project.version} + + + + org.scalatest + scalatest_${scala.tools.version} + test + + + org.mockito + mockito-all + test + + + junit + junit + test + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-source + + add-source + + generate-sources + + + src/main/java + src/main/scala + + + + + add-test-source + + add-test-source + + generate-test-sources + + + src/test/java + src/test/scala + + + + + + + + + + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + + + + net.alchim31.maven + scala-maven-plugin + + + + + -dependencyfile + -deprecation + -feature + -Ywarn-unused + + + + + + + + + scala-compile + + + + compile + + + + scala-test-compile + + testCompile + + + test-compile + + + **/*Test.scala + **/*IT.scala + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + org.scalatest + scalatest-maven-plugin + + + + + diff --git a/subprojects/common/ddo-web/src/main/resources/reference.conf b/subprojects/common/ddo-web/src/main/resources/reference.conf new file mode 100644 index 00000000..9cf3fcca --- /dev/null +++ b/subprojects/common/ddo-web/src/main/resources/reference.conf @@ -0,0 +1,3 @@ +ddowiki-lib { + item = "http://ddowiki.com/page/Item:" +} \ No newline at end of file diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/HtmlTag.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/HtmlTag.scala new file mode 100644 index 00000000..ed8b7ce0 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/HtmlTag.scala @@ -0,0 +1,23 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web + +sealed trait Tag +object HtmlTag { + final val ListItem = "li" + final val UnorderedList = "ul" + final val TableHeader = "th" + final val TableRow = "tr" + final val TableData = "td" +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/HtmlTreeNode.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/HtmlTreeNode.scala new file mode 100644 index 00000000..632c2a3d --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/HtmlTreeNode.scala @@ -0,0 +1,112 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web + +import net.ruippeixotog.scalascraper.model.Element + +/** + * @author + * Andre White Represents a TreeNode like list derived from an HTML fragment. + * + * Generally this will be extracted from structures like lists (UL/OL) or Tables + */ +sealed abstract class HtmlTreeNode { + + /** + * when true, indicates that this item has no leaves or branches. + */ + val isStump: Boolean + + /** + * a collection of leaves directly attached to this level. + * + * There may be more leaves nested within the branches collection. + */ + val leaves: Option[Iterable[Leaf]] + + /** + * a collection of Branches that may contain additional leaves or branches. + */ + val branches: Option[Iterable[Branch]] + +} + +/** + * Represents an end node with no branches + * @param text + * the value of the leaf + */ +case class Leaf(text: String) extends HtmlTreeNode with UnBranchable { + val isStump = false +} + +object Leaf { + def apply(element: Element): Leaf = { + Leaf(element.text) + } +} + +/** + * Represents a node that can have additional leaves and branches + * @param branches + * nested branches, if any + * @param leaves + * any leaves on the branch + */ +case class Branch(branches: Option[Iterable[Branch]] = None, leaves: Option[Iterable[Leaf]] = None) + extends HtmlTreeNode { + val isStump = false +} + +/** + * The base tree node that may contain branches or leaves + */ +case class Tree(root: HtmlTreeNode) extends HtmlTreeNode { + val isStump = { + root match { + case Stump() => true + case _ => false + } + } + val leaves = root match { + case Leaf(x) => Some(List(Leaf(x))) + case _ => None + } + val branches = root match { + case Branch(x, y) => Some(List(Branch(x, y))) + case _ => None + } +} + +/** + * Represents a node with no leaves or branches + */ +case class Stump() extends HtmlTreeNode with UnBranchable { val isStump = true } + +/** + * @author + * Andre White Represents an object with no leaves or branches. + */ +trait UnBranchable { + + /** + * Represents no leaves by setting this val to [[None]] + */ + val leaves = None + + /** + * Represents no branches by setting this val to [[None]] + */ + val branches = None +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/Retriever.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/Retriever.scala new file mode 100644 index 00000000..8cd90299 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/Retriever.scala @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web + +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.model.item.Item + +object Retriever extends LazyLogging { + + /** + * When overridden, returns an Option[Item] using web resources + * @return + * A ddo Item + */ + def findFromWeb: Option[Item] = { + None + } +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/Warehouse.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/Warehouse.scala new file mode 100644 index 00000000..efe2aa18 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/Warehouse.scala @@ -0,0 +1,227 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web + +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.support.matching.WordMatchStrategy +import io.truthencode.ddo.web.mapping.FieldMapper +import net.ruippeixotog.scalascraper.browser.JsoupBrowser +import net.ruippeixotog.scalascraper.dsl.DSL.Extract._ +import net.ruippeixotog.scalascraper.dsl.DSL._ +import net.ruippeixotog.scalascraper.model._ + +import scala.collection.mutable.ListBuffer +// import org.jsoup.nodes.{Document, Element} + +import scala.collection.mutable +import scala.languageFeature.postfixOps + +/** + * Provides a Storage Area for DDO Items. + * + * @author + * Andre White + */ +object Warehouse extends LazyLogging { + private val context = new WebContext() + lazy val MsgNoReadableLists = "no readable lists detected" + lazy val MsgErrCantParseField = "could not parse field" + + /** + * Extracts Multi-values and nested values from an element. + * + * @param e + * HTML fragment containing desired text + * @return + * a Collection of found elements or an empty list if none are found. + */ + protected[web] def byExploding(e: Element): List[String] = { + e >?> elements(HtmlTag.ListItem) match { + case Some(_) => + for { ele <- e >> elementList(HtmlTag.ListItem) } yield ele.text + case _ => Nil + } + } + + /** + * Convenience object that holds some HTML extractor patterns. + */ + object Filter { + // TODO: Move this to its own file + /** + * HTML pattern to determine an initial leaf level. + * + * Filters out the .tooltip CSS in a span. + */ + val FirstLevelLeaf = ":root > li > span:has(:not(.tooltip)) > a" + } + + /** + * Attempts to format elements into a list of [[io.truthencode.ddo.web.Leaf]] + * + * @param fragment + * source HTML fragment + * @param branchTag + * HTML tag for the branch. Defaults to unordered list (ul) + * @param leafTag + * HTML tag for leaf nodes. Defaults to 'List Item' (li) + * @return + * an [[scala.Option]] [[mutable.Buffer]] of [[io.truthencode.ddo.web.Leaf]] of one or more + * leaves, or None if none were found. + */ + def makeLeaves( + fragment: Element, + branchTag: String = HtmlTag.UnorderedList, + leafTag: String = HtmlTag.ListItem): Option[mutable.Buffer[Leaf]] = { + fragment >?> element(branchTag) match { + case Some(ele) => + val firstLevelItemsWithToolTips = ele.select(Filter.FirstLevelLeaf) + lazy val msgLeafCount = + s"Leaf count ${firstLevelItemsWithToolTips.size}" + logger.info(msgLeafCount) + + val buf = new ListBuffer[Leaf] + firstLevelItemsWithToolTips.foreach { x => + buf.append(Leaf(x.text)) + } + Some(buf) + case _ => + logger.warn(MsgNoReadableLists) + None + } + } + + /** + * Extracts text from an html fragment and attempts to format it in a TreeNode like structure. + * + * @param fragment + * source html + * @param branchTag + * html tag for the branch. Defaults to unordered list (ul) + * @param leafTag + * html tag for leaf nodes. Defaults to 'List Item' (li) + * @return + * an [[io.truthencode.ddo.web.HtmlTreeNode]] populated from the source text. + */ + def readHtmlList( + fragment: Element, + branchTag: String = HtmlTag.UnorderedList, + leafTag: String = HtmlTag.ListItem): HtmlTreeNode = { + fragment >?> element(branchTag) match { + case Some(ele) => + val leaves = makeLeaves(ele, branchTag, leafTag) + val b: Iterable[Leaf] = for { + c: Element <- ele.children + r: Element <- c >> elementList(s":root > $branchTag ") + firstLevel <- r >> Filter.FirstLevelLeaf + } yield Leaf(firstLevel) + val branchedLeaves = if (b.nonEmpty) Some(b) else None + Branch( + branchedLeaves match { + case Some(_) => Some(List(Branch(leaves = branchedLeaves))) + case _ => None + }, + leaves) + case _ => Stump() + } + } + + /** + * Loads a web page based on the key + * + * @param key + * the ID of the item to lookup + * @param wc + * [[WebContext]] used to locate the page + */ + def loadDoc(key: String, wc: WebContext = new WebContext()): Document = { + // logger.info(s"url: ${wc.Url(key)}") + JsoupBrowser().get(wc.url(key)) + } + + /** + * Scrapes the DDOWiki page and parses the table / list values into a keyed Map + * + * @return + * Mapped key values which can be passed to helper methods to extract specific values + */ + def htmlToMappedValues(doc: Document): Option[Map[String, Element]] = { + // : Option[Map[String, List[String]]] + // scalastyle:on import.grouping underscore.import + // TODO: Items with multiple level instances i.e. jeweled cloak with ML12-14 and Epic 23-25 + // need to have alternate search mapping + + // FIXME: Pattern is not exhaustive, multiple level items and non-weapons still need to be tested. + // logger.info(s"call for ${key} has size ${doc.html().length()}") + // We need to add the sibling h2 to allow for the update warning template + doc >?> element("#mw-content-text > h2 + table") match { + case Some(tables) => + val nameRows = tables >> elementList(HtmlTag.TableRow) + logger.info(s"found ${nameRows.size} name rows") + val namedRow = nameRows.map { row => + val r = row >> element(HtmlTag.TableHeader) + r.text.trim -> row + }.toMap + Some(namedRow) + case _ => None + } + } + + /** + * Scrapes the DDOWiki page and parses the table / list values into a keyed Map + * + * @return + * Mapped key values which can be passed to helper methods to extract specific values + */ + def htmlToMappedValuesOld(doc: Document)(implicit + strategy: WordMatchStrategy): Option[Map[String, List[String]]] = { + + // scalastyle:on import.grouping underscore.import + // TODO: Items with multiple level instances i.e. jeweled cloak with ML12-14 and Epic 23-25 + // need to have alternate search mapping + + // logger.info(s"url: ${wc.Url(key)}") + // logger.info(s"call for ${key} has size ${doc.html().length()}") + // We need to add the sibling h2 to allow for the update warning template + doc >?> element("#mw-content-text > h2 + table") match { + case Some(tables) => + val nameRows = tables >> elementList(HtmlTag.TableRow) + logger.info(s"found ${nameRows.size} name rows") + val namedRow = nameRows.map { row => + (row >> element(HtmlTag.TableHeader)).text.trim -> row + }.toMap + val fields = nameRows.map { row => + (row >> element(HtmlTag.TableHeader)).text.trim + }.toSet + val field = FieldMapper.fieldType(fields) + + val result = field match { + case Some(fld) => + lazy val msgItemType = s"item is of type $fld " + logger.info(msgItemType) + val r = FieldMapper.wikiToItem(namedRow) + None + case _ => + logger.info(MsgErrCantParseField) + None + } + namedRow.foreach { x => + logger.info(s"\nnamedRow: ${x._1} data: ${x._2.innerHtml}") + } + result + case _ => None + } + } + +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/ElementSupport.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/ElementSupport.scala new file mode 100644 index 00000000..aec3cf48 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/ElementSupport.scala @@ -0,0 +1,26 @@ +package io.truthencode.ddo.web.mapping + +import java.util + +import net.ruippeixotog.scalascraper.model.Element +import org.jsoup.Jsoup +import org.jsoup.nodes.{Element => JElement, TextNode} + +/** + * Conversion from Scala-scraper Element to JSoup Elements. + * + * @note + * This was added as the original scala-scraper implementation used JSoup transparently, but has + * since internalized it to implement their own CSSQuery vs JSoups CSSQuery with XPath elements. + * Specifically, capturing TextNodes is not a CSSQuery function, which JSoup supported and is + * sometimes needed. + */ +object ElementSupport { + + implicit class ElementToElementOps(source: Element) { + def textNodes: util.List[TextNode] = { + Jsoup.parse(source.innerHtml).textNodes() + } + } + +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/Extractor.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/Extractor.scala new file mode 100644 index 00000000..8b9a5513 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/Extractor.scala @@ -0,0 +1,133 @@ +package io.truthencode.ddo.web.mapping + +import net.ruippeixotog.scalascraper.dsl.DSL.Extract._ +import net.ruippeixotog.scalascraper.dsl.DSL._ +import net.ruippeixotog.scalascraper.model.Element +import io.truthencode.ddo.support.StringUtils.{Comma, EmptyString, Space} +import io.truthencode.ddo.support.dice.DamageInfo + +import scala.language.postfixOps +// import org.jsoup.nodes.Element +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.web.HtmlTag + +object Extractor extends LazyLogging { + + /** + * parser that extracts the text portion from a possibly HTML wrapped string. + * + * @param textOrElement + * fragment of HTML or Text + * @param tagSelector + * tag to extract. defaults to 'td' + * @return + * extracted text or None if tag was not found or input was not of expected type. + */ + def simpleExtractor( + textOrElement: Option[Any], + tagSelector: String = HtmlTag.TableData): Option[String] = { + textOrElement match { + case Some(data: String) => + logger.info(msgRawStringData) + Some(data) + case Some(data: Element) => + val rslt = data >> element(s"$tagSelector:first-child") + lazy val MsgExtraction = s"returning element extraction $rslt.text" + logger.info(MsgExtraction) + Some(rslt.text) + case Some(data) => + logger.warn( + s"Data was not of expected type (text or Element) - found ${data.getClass.toString}") + None + case _ => logger.warn(msgNoData); None + } + + } + + /** + * Extracts the critical profile information from a string representation. + * + * @param infoText + * text containing a min - max x: Multiplier, i.e. 19-20 x3 + * @return + * a [[critProfile]] or None if there was no parsable value found. + */ + def extractCriticalProfile(infoText: String): Some[critProfile] = { + + /** + * Regular expression used to translate D & D text to object notation. + */ + val regCritical = + """(?\d+)?-?(?\d+)\s*/\s*x(?\d+)""".r + infoText match { + case regCritical(min, max, multiplier) => + logger.info(s"critical profile: $infoText") + Some(critProfile(Option(min).getOrElse(max).toInt, max toInt, multiplier toInt)) + case _ => + logger.error(s"argument could not be parsed: $infoText"); + throw new IllegalArgumentException + } + } + + /** + * Helper object to hold extended damage information + * + * @param wMod + * Weapon Modifier information + * @param dice + * D & D Dice + * @param extra + * Extra damage beyond dice + * @param damageType + * List of Damage types + */ + case class damageExtractor(wMod: Int, dice: String, extra: Int, damageType: List[String]) + + /** + * Wraps text into an extractor object as an intermediate object to extract additional damage + * information. + * + * @param infoText + * structured text read from the Wiki HTML + * @return + * wrapped damageExtractor object with parsed properties. + */ + def extractDamageInfo(infoText: String): Option[DamageInfo] = { + val damageInfo = + """(?\d(?:\.\d+)?)?\s*(?\[\d+d\d+\])(?\s\+\s\d+)?\s(.*)""".r + // val damageInfo = """(?\d+.\d+)?(?\[\d+d\d+\])(?\s\+\s\d+)?\s(.*)""".r + infoText match { + case damageInfo(wDamage, dice, extra, damageType) => + logger.trace(s"$infoText matched") + Some(DamageInfo(infoText)) + case _ => + logger.warn(s"Could not match infostring to damage extractor $infoText") + None + } + } + + /** + * Extracts Enchantment data from ddowiki html + * + * @param source + * wiki scrapped html + * @return + * sequence of possibly nested Leafs containing any enchantments + */ + def enchantmentExtractor(source: Map[String, Element]): Seq[io.truthencode.ddo.web.Leaf] = { + val maybeTree = for { + e <- source.get(Field.Enchantments) + } yield io.truthencode.ddo.web.Warehouse.readHtmlList(e) + + maybeTree match { + case Some(tree) => + for { + branches <- tree.branches.toSeq + branch <- branches + leaves <- branch.leaves.toSeq + leaf <- leaves + } yield leaf + case _ => Nil + } + } +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/Field.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/Field.scala new file mode 100644 index 00000000..1d4e4e5f --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/Field.scala @@ -0,0 +1,153 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web.mapping + +/** + * Storage object used to contain text matches when scraping HTML text. + */ +object Field { + + /** + * Extracts proficiency information, such as 'Simple Weapon Proficiency' + */ + final val ProficiencyClass = "Proficiency Class" + + /** + * Extracts Damage and Type information such as '1.50[1d4] + 3 Slash, Pierce, Magic' + */ + final val DamageAndType = "Damage and Type" + + /** + * Extracts Critical Threat Range, i.e. '19-20/x2' + */ + final val CriticalThreatRange = "Critical threat range" + + /** + * Extracts Weapon Type information, i.e. 'Dagger / Piercing weapons' + */ + final val WeaponTypeAndDamageType = "Weapon Type" + + /** + * Extracts Required Race information, i.e. 'Shadar-Kai' + */ + final val RaceAbsRequired = "Race Absolutely Required" + + /** + * Extracts Minimum Level, i.e. '15' + */ + final val ML = "Minimum Level" + + /** + * Extracts Required traits such as 'Good' + */ + final val RequiredTrait = "Required Trait" + + /** + * Extracts UMD check information + * + * i.e. Wiz(39) indicating a Wizard class can use or equip this item despite restrictions with a + * successful UMD check of 39 or greater. + */ + final val UMD = "Use Magical Device DC" + + /** + * Extracts Handedness for weapons / shields + * + * i.e. main hand, off hand or two-handed + */ + final val Handedness = "Handedness" + + /** + * Extracts Attribute used to determine Attack modifier for Weapons + * + * Typically this will be STR (Strength) for Melee weapons and Dex for some Missile weapons. + */ + final val AttackMod = "Attack Mod" + + /** + * Extracts Attribute used to determine Damage Modifier for Weapons + * + * Typically this will be STR (Strength) for Melee weapons and Dex for some Missile weapons. + */ + final val DamageMod = "Damage Mod" + + /** + * Reads any binding enformation. + * + * i.e. Bound to Character / Account on Acquire or equipping + */ + final val Binding = "Binding" + + /** + * Reads the durability of the item + * + * Should be a number + */ + final val Durability = "Durability" + + /** + * Reads the material item is made from. + * + * i.e. Steel, Crystal etc. + */ + final val Material = "Made from" + + /** + * Reads the number representing the Hardness of an item. + * + * i.e. Steel will have a higher hardness than glass. + */ + final val Hardness = "Hardness" + + /** + * Reds the Base monetary value of the item. + * + * Generally expressed in platinum pieces. i.e. 6,000 pp 2 gp + */ + final val BaseValue = "Base Value" + + /** + * Reads the weight in pounds. + * + * i.e. 3 lbs + */ + final val Weight = "Weight" + + /** + * String description of where the item is located or how to obtain. + * + * i.e. Advance to level 15, End reward + */ + final val Location = "Location" + + /** + * Array of zero or more Enchantments + * + * Can be many different effects such a bonus to a stat, skill or ability etc. + */ + final val Enchantments = "Enchantments" + + /** + * Determines if an item can be upgraded to a better version. + * + * Generally, non-upgradeable items will be indicated by 'Not upgradeable' while upgradeable items + * will have text descriptions and possibly a link on what / how to upgrade. + */ + final val Upgradeable = "Upgradeable?" + + /** + * Basic text with a description of the item. + */ + final val Description = "Description" // likely multi-line text +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/FieldMapper.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/FieldMapper.scala new file mode 100644 index 00000000..31382d9d --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/FieldMapper.scala @@ -0,0 +1,189 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web.mapping + +import com.typesafe.scalalogging.LazyLogging +import enumeratum.{Enum => SmartEnum, EnumEntry} +import io.truthencode.ddo.DDOObject +import io.truthencode.ddo.model.item.{Item, Potion} +import io.truthencode.ddo.model.item.armor.Armor +import io.truthencode.ddo.model.item.clothing.Clothing +import io.truthencode.ddo.support.matching.WordMatchStrategy + +import scala.collection.immutable +import scala.language.{existentials, postfixOps} + +/** + * Utility object for mapping DDOWiki tables and fields to objects + */ +object FieldMapper extends LazyLogging { + + /** + * Convenience class to hold a list or single value string list. + */ + sealed abstract class ItemType(words: Either[String, List[String]]) extends EnumEntry { + val wordList: List[String] = words match { + case Right(x) => x + case Left(x) => List(x) + } + } + + /** + * Enumeration to hold the possible item type values along with keywords used to map the fields + */ + object ItemType extends SmartEnum[ItemType] { + val values: immutable.IndexedSeq[ItemType] = findValues + + /** + * A wieldable weapon + */ + case object Weapon extends ItemType(Left("Proficiency Class")) + + /** + * An equipable armor + */ + case object Armor extends ItemType(Left("Armor Type")) + + /** + * A potion + */ + case object Potion extends ItemType(Right(List("Acquired from", "Located in"))) + + /** + * Bracers, Boots, Belts etc. + */ + case object Clothing extends ItemType(Left("Item Type")) + + /** + * Rings etc. + */ + case object Jewelery extends ItemType(Left("Item Type")) + + } + + // +3 Enhancement Bonus + // Vampirism + // Bloodletter III + // Risk and Reward + /** + * Determines the type of Item from a set up keywords. + * + * @param words + * list of words pulled from various fields using the mapping provided by + * [[FieldMapper.ItemType.values]] + * @return + * an [[ItemType]] if found, otherwise None + */ + def fieldType(words: Set[String]): Option[ItemType] = + FieldMapper.ItemType.values.find { x => + words.intersect(x.wordList.toSet).nonEmpty + } + + /** + * Extracts weapon information from the DDOWiki site. + * + * @param source + * HTML data from the site + * @return + * A Weapon object scrapped from the site or None + */ + def weaponFromWiki(source: Map[String, Any])(implicit + strategy: WordMatchStrategy): Option[DDOObject.Weapon] = { + val keys = source.keySet + val types = fieldType(keys) + logger.info(s"Filtered type: $types") + types match { + case Some(x: ItemType) if x == ItemType.Weapon => + logger.info("Item type of weapon found") + val damageAndTypeString = WikiParser.damage(source) +// val damageDie: Option[String] = +// WikiParser.damageDie(damageAndTypeString) // replace with damageinfo + // TODO: damageAppliedType is not mapped to weapon object +// val damageAppliedType = +// WikiParser.damageAppliedType(damageAndTypeString) // replace with damageinfo + // val weaponModifier = damageAndTypeString + // val extraDamage = WikiParser.weaponModifier(damageAndTypeString) + val weaponCategory = WikiParser.weaponCategoryInfo(source) + // val absReqRace = WikiParser.requiredRace(source) + // val reqTrait = WikiParser.requiredTrait(source) + // val binding = WikiParser.binding(source) + // val loc = WikiParser.location(source) + // = "Enchantments" + // TODO: mapping enchantments, as these are nearly any effect. + // Need to refactor it out to a separate method once we have effects. + // val enchantments = WikiParser.enchantments(source) + // TODO: Need to add Item Sets , + // they are included under Enchantments and should be handled / extracted separately + + val weapon = DDOObject.Weapon( + absoluteMinimumLevel = None, + baseValue = WikiParser.monetaryValue(WikiParser.baseValue(source)), + description = WikiParser.description(source), + durability = WikiParser.durability(source), + hardness = WikiParser.hardness(source), + binding = WikiParser.binding(source), + material = WikiParser.madeFrom(source), + minimumLevel = WikiParser.minimumLevel(source), + umd = WikiParser.umdDc(source), + weight = WikiParser.weight(source), // Members declared in io.truthencode.ddo.Weapon + attackModifier = WikiParser.attackModifier(source), + critical = WikiParser.criticalProfile(WikiParser.criticalThreat(source)), + damage = WikiParser.damage(source), + damageModifier = WikiParser.damageModifier(source), + handedness = WikiParser.handedness(source), + proficiency = WikiParser.proficiency(source), + upgradeable = WikiParser.upgradable(source), + weaponCategory = weaponCategory, + weaponType = WikiParser.weaponType(weaponCategory), + enchantments = WikiParser.enchantments(source) + ) + Some(weapon) + case _ => None + } + } + + /** + * WikiToProperty Reads sourced data from DDOWiki and attempts to mangle it into readable + * properties. + * + * @param source + * a collection of properties that should generally be in the form of simple strings or JSoup + * Elements. + * @return + * A DDO Item wrapped in an Option + * @note + * Breaking cases: Divine Vengeance has multiple versions based on level and class that equips + * it. (RealmsofDespair terms.. a morph) http://ddowiki.com/page/Item:Divine_Vengeance Sun blade + * is a slashing short sword, but has 'see note' in the damage type field + * http://ddowiki.com/page/Item:Sun_Blade + */ + def wikiToItem[T <: Item](source: Map[String, Any])(implicit + strategy: WordMatchStrategy): Option[Item] = { + + val keys = source.keySet + val types = fieldType(keys) + logger.info(s"Filtered type: $types") + types match { + case Some(x: ItemType) if x == ItemType.Weapon => weaponFromWiki(source) + case Some(_: Armor) => + throw new NotImplementedError + case Some(_: Potion) => + throw new NotImplementedError + case Some(_: Clothing) => + throw new NotImplementedError + case _ => None + + } + } +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/TextManipulator.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/TextManipulator.scala new file mode 100644 index 00000000..cf497b24 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/TextManipulator.scala @@ -0,0 +1,5 @@ +package io.truthencode.ddo.web.mapping + +trait TextManipulator[T] { + def mangle[S](source: Map[String, Any]): Option[S] +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/WeaponClassInfo.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/WeaponClassInfo.scala new file mode 100644 index 00000000..e9e4cdea --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/WeaponClassInfo.scala @@ -0,0 +1,14 @@ +package io.truthencode.ddo.web.mapping + +import io.truthencode.ddo.model.item.weapon.WeaponCategory +import io.truthencode.ddo.model.meta.PhysicalDamageType + +/** + * Encapsulates Weapon Category and Damage Information + * + * @param category + * The category such as Club or Bastard Sword + * @param physicalDamageType + * The type of damage such as Bludgeon or Pierce + */ +case class WeaponClassInfo(category: WeaponCategory, physicalDamageType: PhysicalDamageType) diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/WikiParser.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/WikiParser.scala new file mode 100644 index 00000000..94cb16c0 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/WikiParser.scala @@ -0,0 +1,639 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web.mapping + +import java.text.NumberFormat +import com.typesafe.scalalogging.LazyLogging +import net.ruippeixotog.scalascraper.dsl.DSL._ +import net.ruippeixotog.scalascraper.dsl.DSL.Extract._ +import net.ruippeixotog.scalascraper.model.Element +import io.truthencode.ddo._ +import io.truthencode.ddo.enumeration.EnumExtensions.EnumCompanionOps +import io.truthencode.ddo.model.attribute.Attribute +import io.truthencode.ddo.model.item.weapon._ +import io.truthencode.ddo.model.meta.PhysicalDamageType +import io.truthencode.ddo.model.misc.Material +import io.truthencode.ddo.support.StringUtils.{ + Comma, + EmptyString, + ForwardSlash, + Space, + StringImprovements +} +import io.truthencode.ddo.support.dice.{DamageInfo, Dice} +import io.truthencode.ddo.support.matching.{WordMatchStrategies, WordMatchStrategy} +import io.truthencode.ddo.web.mapping.ElementSupport.ElementToElementOps +import io.truthencode.ddo.web.mapping.Extractor._ +import scala.jdk.CollectionConverters._ +//import scala.collection.JavaConverters._ +import scala.language.{existentials, postfixOps, reflectiveCalls} +import scala.util.Try + +/** + * Contains functions used to scrape DDOWiki when needed. + */ +//noinspection ScalaStyle +object WikiParser extends LazyLogging { + + /** + * Extracts the proficiency such as Martial Weapon + * + * @param source + * Text or HTML fragment containing the information + * @return + * Proficiency Class or None if invalid or missing + */ + def proficiency(source: Map[String, Any]): Option[ProficiencyClass] = { + source.get(Field.ProficiencyClass) match { + // Simple Weapon Proficiency + case Some(name: String) => + ProficiencyClass.withName(name, true) match { + case Some(pc) => Some(pc.asInstanceOf[ProficiencyClass]) + case _ => logger.error(s"Invalid Proficiency Class $name"); None + } + case Some(x: Element) => + ProficiencyClass.withName(x.text, true) match { + case Some(pc) => Some(pc.asInstanceOf[ProficiencyClass]) + case _ => logger.error(s"Invalid Proficiency Class $x"); None + } + case _ => None + } + } + + /** + * Extracts damage information from text or HTML Fragment + * + * @param source + * Text or HTML fragment containing the information + * @return + * Damage information or None if missing or invalid data. + */ + def damage(source: Map[String, Any]): Option[DamageInfo] = { + simpleExtractor(source.get(Field.DamageAndType)) match { + case Some(data) => + logger.info(s"extracting damageInfo from $data") + extractDamageInfo(data) + case _ => None + } + } + + /** + * Extracts the Critical Threat information + * + * @param source + * Text or HTML fragment containing source information + * @return + * Critical Information or None if missing or invalid data + */ + def criticalThreat(source: Map[String, Any]): Option[CriticalThreatRange] = { + simpleExtractor(source.get(Field.CriticalThreatRange)) match { + // "Critical threat range"// 19-20/x2 + case Some(x: String) => + extractCriticalProfile(x) match { + case Some(profile) => + Some(CriticalThreatRange(profile.min to profile.max, profile.multiplier)) + case _ => None + } + case _ => None + } + } + + /** + * Extracts Weapon Category information + * + * @param source + * Text or HTML fragment containing desired information + * @return + * Weapon Category information or None if missing / invalid data + */ + def weaponCategoryInfo(source: Map[String, Any]): Option[WeaponCategory] = { + simpleExtractor(source.get(Field.WeaponTypeAndDamageType)) match { + case Some(x: String) => + val s = x.split(ForwardSlash) + + WeaponCategory.withName(s(0).replace(Space, EmptyString), true) match { + case Some(category) => Some(category.asInstanceOf[WeaponCategory]) + case _ => logger.error(s"Unknown Weapon Category $s"); None + } + case _ => + logger.error(s"Failed to parse ${Field.WeaponTypeAndDamageType} (No result)") + None + } + } + + /** + * Extracts Race Requirements, if any + * + * @param source + * Text or HTML fragment containing desired information + * @return + * Collection of Race ID's or empty list if none found + */ + def requiredRace(source: Map[String, Any]): List[String] = { + // TODO: Should we return an Option vs empty list? + simpleExtractor(source.get(Field.RaceAbsRequired)) match { + case Some(x: String) => + x.split(Comma).toList + case Some(x) => + logger.error(s"Failed to parse ${Field.RaceAbsRequired} from $x"); Nil + case _ => + logger.error(s"Failed to parse ${Field.RaceAbsRequired} (No result)") + Nil + } + } + + /** + * Extracts Minimum level information + * + * @param source + * Text or HTML fragment containing desired information + * @return + * Int value of minimum level. + */ + def minimumLevel(source: Map[String, Any]): Int = { + // TODO: Should we return Option vs default zero assumption? + simpleExtractor(source.get(Field.ML)) match { + case Some(x) => + // import io.truthencode.ddo.web.StringUtils._ + x.toIntOpt match { + case Some(x: Int) => x + case _ => logger.error(s"Failed to parse ${Field.ML} with $x"); 0 + } + case _ => + logger.info("No ML value specified for object, assuming zero"); 0 + } + } + + /** + * Extracts Required traits, if any + * + * @param source + * Text or HTML fragment with desired information + * @return + * Collection of Trait IDs or empty list if none found + * @note + * Currently treating this as a list, I believe there is only one value at most, but taking the + * performance hit over code breaking. MustContainAtLeastOne potential use case is a aligned + * race restricted item. Will try to update and streamline this once we can locate better source + * data + * + * Also, the value 'None' may be included in the text and is filtered out. + */ + def requiredTrait(source: Map[String, Any]): List[String] = { + // TODO: Return Option instead of empty list + source.get(Field.RequiredTrait) match { + case Some(x: String) if x != "None" => + x.split(Comma).toList + case Some(x: String) => + logger.info(s"No required traits assigned, excluded value was $x"); Nil + case _ => logger.info("No required traits discovered"); Nil + } + } + + /** + * Extracts Use Magical Device information, if any + * + * @param source + * Text or HTML fragment with desired information + * @return + * Int or UMD check, defaulting to zero if none found. + */ + def umdDc(source: Map[String, Any]): Int = { + // TODO: Return Option if none listed + source.get(Field.UMD) match { + case Some(x: Int) => + x + case _ => logger.info("No UMD specified, assuming zero"); 0 + } + } + + /** + * Extracts handedness (Off-hand, main-hand, two-handed etc) from source + * + * @param source + * Text or HTML fragment + * @return + * list of valid equip locations. + */ + def handedness(source: Map[String, Any]): List[Handedness] = { + // TODO: Handedness should throw an error or option, likely error + source.get(Field.Handedness) match { + case Some(x: String) => + logger.info(s"Handedness located!!! $x") + x.split(Comma) + .filter { name => + Handedness.withName(name, true).isDefined + } + .map { name => + Handedness + .withName(name, true) + .asInstanceOf[Handedness] + } + .toList + case _ => logger.error("Failed to retrieve Handedness"); Nil + } + } + + /** + * Extracts Attack Modifier Attribute + * + * @param source + * Text or HTML fragment with desired information + * @return + * List of Attribute or empty list if none found. + */ + def attackModifier(source: Map[String, Any]): List[Attribute] = { + for { + e <- List(simpleExtractor(source.get(Field.AttackMod))).flatten + x <- e.split(Comma) + y <- Attribute.values.find(a => a.toString == x) + } yield y + } + + /** + * Extracts Attribute used to determine Damage Modifier + * + * @param source + * Text or HTML fragment with desired information + * @return + * List of Attribute or empty list if none found. + */ + def damageModifier(source: Map[String, Any]): List[Attribute] = { + for { + e <- List(simpleExtractor(source.get(Field.DamageMod))).flatten + x <- e.split(Comma) + y <- Attribute.values.find(a => a.toString == x) + } yield y + } + + /** + * Extracts binding information (i.e. bound to Character etc) + * + * @param source + * Text or HTML fragment with desired information + * @return + * Binding status or None if missing / invalid data + */ + def binding(source: Map[String, Any])(implicit + strategy: WordMatchStrategy): Option[BindingFlags] = { + simpleExtractor(source.get(Field.Binding), "a") match { + case Some(x: String) => + BindingFlags.fromWords(x) + case _ => + logger.debug(s"Failed to retrieve ${Field.Binding}"); + None // TODO: Do we return default binding if none specified? + } + } + + /** + * Extracts durability for item. + * + * @param source + * Text or HTML fragment with desired information + * @return + * Int value of durability, defaults to zero if none found. + */ + def durability(source: Map[String, Any]): Int = { + simpleExtractor(source.get(Field.Durability)) match { + case Some(x: String) => + tryToInt(x.replace(" ", "")) match { + case Some(x: Int) => + x + case _ => + logger.warn(s"None numeric value found for ${Field.Durability} ($x), defaulting to 0") + 0 + } + case _ => + logger.warn(s"No value found for ${Field.Durability}, defaulting to 0") + 0 + } + } + + // Implicit to safely attempt String to Int conversion + private def tryToInt(s: String) = Try(s.toInt).toOption + + /** + * Extracts material information + * + * @param source + * Text or HTML fragment with desired information + * @return + * Material or None if missing / invalid data + */ + def madeFrom(source: Map[String, Any]): Option[Material] = { + // TODO: may need to throw error for unknown or unspecified materials + simpleExtractor(source.get(Field.Material), "a") match { + case Some(x: String) => + Material.withNameOption(x) match { + case Some(name) => + Some(name) + case _ => + logger.warn( + s"No material found by name of $x, if this is a new material, it needs to be added to the enumeration") + None + } + case _ => + logger.warn(s"No value supplied for ${Field.Material}") + None + } + } + + /** + * Extracts Hardness information + * + * @param source + * Text or HTML fragment with desired information + * @return + * Int value for hardness , defaulting to zero if missing / invalid data + */ + def hardness(source: Map[String, Any]): Int = { + simpleExtractor(source.get(Field.Hardness)) match { + case Some(x: String) => + tryToInt(x.replace(" ", "")) match { + case Some(x: Int) => + x + case _ => + logger.warn(s"None numeric value found for ${Field.Hardness} ($x), defaulting to 0") + 0 + } + case _ => + logger.warn(s"No value found for ${Field.Hardness}, defaulting to 0") + 0 + } + } + + /** + * Extracts the base monetary value + * + * @param source + * Text or HTML fragment + * @return + * Base value in platinum or None if missing / invalid data + */ + def baseValue(source: Map[String, Any]): Option[Int] = { + // TODO: BaseValue - Need a sensible default for base value or make option if none supplied + val rex = + """(?\d+,?\d+)""".r + source.get(Field.BaseValue) match { + case Some(x: Element) => + val ele = x >> element("td:first-child") + val filtered = ele.textNodes.asScala.map { x => + x.text match { + case rex(num) => + Some(NumberFormat.getInstance(java.util.Locale.US).parse(num)) + case _ => None + } + }.filter { x => + x.isDefined + }.map { x => + x.get + }.toList + filtered.size match { + case 1 => Some(filtered.head.intValue()) + case 0 => + logger.info(s"could not extract number from $x"); None + case _ => + logger.warn(s"Multiple values returned for basevalue $x, returning the first") + Some(filtered.head.intValue()) + } + case _ => logger.info(s"${Field.BaseValue} was not supplied"); None + } + } + + /** + * Wraps an Int value into a Coin object + * + * @param baseValue + * amount of platinum pieces + * @return + * wrapped object using given value. + */ + def monetaryValue(baseValue: Option[Int]): Option[MonetaryValue.Coins] = { + baseValue match { + case Some(plat) => Some(MonetaryValue.Coins(plat = plat)) + case _ => None + } + } + + /** + * Item weight + * + * @param source + * Text or HTML fragment + * @return + * Weight in pounds, if supplied + */ + def weight(source: Map[String, Any]): Option[Int] = { + simpleExtractor(source.get(Field.Weight)) match { + case Some(x: String) => + val rex = """(?\d+,?\d*) lbs""".r + x match { + case rex(num) => + Some( + NumberFormat + .getInstance(java.util.Locale.US) + .parse(num) + .intValue()) + case _ => None + } + case _ => logger.info(s"${Field.Weight} not supplied"); None + } + } + + /** + * Item source location + * + * @param source + * Text or HTML fragment + * @return + * location text, if found + */ + def location(source: Map[String, Any]): Option[String] = { + // TODO: Location - Need a sensible default for base value or make option if none supplied + simpleExtractor(source.get(Field.Location)) match { + case Some(x: String) => + Some(x) + case _ => logger.info(s"${Field.Location} was not supplied"); None + } + } + + /** + * item effects + * + * @param source + * Source Text or HTML fragment + * @return + * collection of enchantments + */ + def enchantments(source: Map[String, Any]): Option[Seq[String]] = { + // TODO: Do we want to alter this from Any to Either[String,Element]? + val eSource = source + .filter(e => e._2.isInstanceOf[Element]) + .map(f => f._1 -> f._2.asInstanceOf[Element]) + val leaves = enchantmentExtractor(eSource).map { x => + x.text + } + if (leaves.isEmpty) None + else Some(leaves) + } + + /** + * Extracts any upgrade information text + * + * @param source + * Text or HTML fragment + * @return + * Upgrade info with any information text found + */ + def upgradable(source: Map[String, Any]): UpgradeInfo = { + simpleExtractor(source.get(Field.Upgradeable)) match { + case Some(x: String) => + new UpgradeInfo { + val text = Some(x) + } + case _ => + logger.warn(s"Failed to retrieve ${Field.Upgradeable}") + new UpgradeInfo { + val text: Option[String] = None + } // TODO: Message should only warn if no upgrade value was specified + } + } + + /** + * Extracts any descriptive text + * + * @param source + * Text or HTML fragment + * @return + * Descriptive text if found. + */ + def description(source: Map[String, Any]): Option[String] = { + simpleExtractor(source.get(Field.Description)) match { + case Some(x: String) => + Some(x) + case _ => + logger.warn(s"Failed to retrieve ${Field.Description}"); + None // TODO: Message should only warn or info? if no description was specified + } + } + + /** + * Extracts Weapon type (Melee, Ranged, thrown etc) + * + * @param wc + * Wrapper generally retrieved through [[WeaponCategory]] information + * @return + */ + def weaponType(wc: Option[WeaponCategory]): Option[DeliveryType] = { + wc match { + case Some(_: MeleeDamage) => Some(DeliveryType.Melee) + case Some(_: RangeDamage) => Some(DeliveryType.Ranged) + case Some(_: ThrownDamage) => Some(DeliveryType.Thrown) + case Some(_: SpecialDamage) => Some(DeliveryType.Special) + case _ => None + } + } + + /** + * Wraps Threat information into a Profile object + * + * @param ctr + * Threat Information + * @return + */ + def criticalProfile(ctr: Option[CriticalThreatRange]): Option[CriticalProfile] = { + ctr match { + case Some(profile) => + Some(new CriticalProfile { + val min: Int = profile.range.min + val max: Int = profile.range.max + val multiplier: Int = profile.multiplier + }) + case _ => None + } + } + + /** + * Extracts damage dice + * + * @param dts + * Damage extraction helper object + * @return + * Damage dice as string + */ + def damageDie(dts: Option[damageExtractor]): Option[String] = { + dts match { + case Some(x) => Some(x.dice) + case _ => None + } + } + + /** + * Extracts the Damage type from the extraction helper object + * + * @param dts + * utility helper object + * @return + * List of damage types + */ + def damageAppliedType(dts: Option[damageExtractor]): List[String] = { + dts match { + case Some(x) => x.damageType + case _ => Nil + } + } + + /** + * Extracts the weapon modifier value from the utility helper object + * + * @param dts + * utility helper object + * @return + * Int value of the modifier, defaulting to 0 + */ + def weaponModifier(dts: Option[damageExtractor]): Int = { + dts match { + // TODO: Use optInt for weaponModifier? + case Some(x) => x.wMod + case _ => 0 + } + } + + /** + * Populates a DamageInfo object from a helper object + * + * @param dts + * helper object + * @return + * populated [[DamageInfo]] object + */ + def damageValue(dts: Option[damageExtractor]): Option[DamageInfo] = { + dts match { + case Some(dmg) => + val w = dmg.wMod +// val d = Dice(dmg.dice) + val e = ExtraInfo(dmg.extra) + val dt = dmg.damageType.flatMap(PhysicalDamageType.withNameInsensitiveOption) + Some( + DamageInfo( + w = dmg.wMod, + d = Dice(1, 1), // TODO: Replace with actual implementation + e = ExtraInfo(dmg.extra), + dt = dmg.damageType.flatMap(PhysicalDamageType.withNameInsensitiveOption) + )) + case _ => None + } + } + +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/critProfile.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/critProfile.scala new file mode 100644 index 00000000..32a57ddb --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/critProfile.scala @@ -0,0 +1,25 @@ +package io.truthencode.ddo.web.mapping + +/** + * encapsulates the critical damage profile + * + * @example + * a typical weapon may have a damage range of 1-20 with a bonus for certain high rolls. The + * scimatar for example may have 1-20, with 18-20 receiving a bonus damage multiplier of double + * damage. This is written in terms of 18-20 x3. + * + * programatically, this would be represented as + * {{{ + * val cp = critProfile(min = 18, max=20, multiplier = 2) + * }}} + * @param min + * minimum damage roll + * @param max + * maximum damage roll + * @param multiplier + * amount to multiply when a given roll is within the min / max range. + * + * @todo + * may move this to core package + */ +case class critProfile(min: Int, max: Int, multiplier: Int) diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/package.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/package.scala new file mode 100644 index 00000000..2fbab457 --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/mapping/package.scala @@ -0,0 +1,9 @@ +package io.truthencode.ddo.web + +/** + * Created by adarr on 2/17/2017. + */ +package object mapping { + lazy val msgNoData = "No Data available to extract" + lazy val msgRawStringData = "returning raw string data" +} diff --git a/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/package.scala b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/package.scala new file mode 100644 index 00000000..7556d0dd --- /dev/null +++ b/subprojects/common/ddo-web/src/main/scala/io/truthencode/ddo/web/package.scala @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo + +import java.net.URLEncoder + +import io.truthencode.ddo.support.StringUtils.{Space, UnderScore} + +import com.typesafe.config.{Config, ConfigFactory} +import com.typesafe.scalalogging.LazyLogging + +package object web { + + /** + * Takes an ID string and translates it to URL escaped and wiki specific format. + * + * @param s + * \- the input string + * @return + * Url Escaped string + * @example + * {{{ + * val key = "Brigand's Cutlass" + * val escaped = ToWikiUrlString(key) + * + * /res: Brigand'_Cutlass + * }}} + * @note + * some items are actually URL escaped, but may appear at both. i.e. Anger's Wrath is linked to + * Anger%27s_Step AND Anger's_Step + * @todo + * may need to see if any are on one but not the other. It appears the un-escaped apostrophe is + * more common. + */ + def toWikiUrlString(s: String, escapeApostrophe: Boolean = false): String = { + val x = s.replace(Space, UnderScore).trim() + if (escapeApostrophe) URLEncoder.encode(x, "UTF-8") else x + } + + // Whenever you write a library, allow people to supply a Config but + // also default to ConfigFactory.load if they don't supply one. + // Libraries generally have some kind of Context or other object + // where it's convenient to place the configuration. + + // we have a constructor allowing the app to provide a custom Config + /** + * WebContext Convenience class to read formatted URI's + * + * @param config + * \- Configuration Resource + * @param lib + * \- Resource Group (defaults to ddowiki-lib) + * @param id + * \- key within the resource group containing the URL defaults to "item" + */ + class WebContext(config: Config, lib: String = "ddowiki-lib", id: String = "item") + extends LazyLogging { + + // This verifies that the Config is sane and has our + // reference config. Importantly, we specify the "simple-lib" + // path so we only validate settings that belong to this + // library. Otherwise, we might throw mistaken errors about + // settings we know nothing about. + config.checkValid(ConfigFactory.defaultReference(), id) + + // This uses the standard default Config, if none is provided, + // which simplifies apps willing to use the defaults + def this() = { + this(ConfigFactory.load()) + } + + val source: String = config.getString(s"$lib.$id") + + def url(id: String): String = "%s%s".format(source, id) + + // this is the amazing functionality provided by simple-lib + def printSetting(path: String): Unit = { + logger.info(s"The setting '$path' is: ${config.getString(path)}") + } + } + +} diff --git a/subprojects/common/ddo-web/src/test/resources/Drow_Scimitar_of_the_Weapon_Master.html b/subprojects/common/ddo-web/src/test/resources/Drow_Scimitar_of_the_Weapon_Master.html new file mode 100644 index 00000000..9a47f59e --- /dev/null +++ b/subprojects/common/ddo-web/src/test/resources/Drow_Scimitar_of_the_Weapon_Master.html @@ -0,0 +1,2032 @@ + + + + + Item:Drow Scimitar of the Weapon Master - DDO wiki + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+

+ Game mechanics + • + Newbie guide + • + In development + • + DDO Store • + IRC Chat +

+
+

+ Challenges • + Classes • + Collectables • + Crafting • + Enhancements + • + Epic Destinies + • Favor +

+

+ Feats • + Glossary • + Items • + Maps • + Monsters • + Places • + Quests • + Races • + Skills • + Spells +

+
+

+ Please + create an account + or + log in + to build a reputation and unlock more editing + privileges, and then visit DDO wiki's + IRC Chat if + you need any help! +

+
+
+
+

+ Item:Drow Scimitar of the Weapon Master +

+
+
From DDO wiki
+
+ (Redirected from + Drow Scimitar of the Weapon Master) +
+
+ Jump to: navigation, + search +
+
+

+ Drow Scimitar of the Weapon Master +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Proficiency Class + Martial Weapon Proficiency + +
+
+ Drow Scimitar of the Weapon Master shown.jpg +
+
+
Damage and Type3 [1d6] + 6 Slash, Magic
+ Critical threat range + 16-20 / x2
Weapon Type + Scimitar / Slashing weapons +
Race Absolutely RequiredNone
Minimum Level21
Required TraitNone
+ Use Magical Device + DC + No UMD needed
Handedness
Attack ModSTR
Damage ModSTR
Binding + Bound to Character on EquipBound to Character on Equip: This item is Bound to Character on Equip +
Durability180
Made from + SteelSteel: + Steel is the common metal used to make weapons and + armor. +
Hardness22
Base Value + 00084020008,402ppPlatinum Piece  +
Weight4 lbs
Location + The House of Rusted Blades, End chest +
Enchantments + +
Upgradeable? +

Not upgradeable

+
Description + Although Drow craftsmanship is among the finest in Faerun, + few are foolhardy enough to steal from the owner of such a + weapon. +
Tips +
+
+ Drow Scimitar of the Weapon Master.png +
+
+
+ + + + +
+ + +
+ + +
+ + +
+
+
+
+

Navigation menu

+
+ +
+ + +
+
+ + + +
+
+
+ + + + + +
+
+ + + + + + + + + + + + + diff --git a/subprojects/common/ddo-web/src/test/resources/Elyd_Edge.html b/subprojects/common/ddo-web/src/test/resources/Elyd_Edge.html new file mode 100644 index 00000000..581cb935 --- /dev/null +++ b/subprojects/common/ddo-web/src/test/resources/Elyd_Edge.html @@ -0,0 +1,1867 @@ + + + + + Item:Elyd Edge - DDO wiki + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+

+ Game mechanics + • + Newbie guide + • + In development + • + DDO Store • + IRC Chat +

+
+

+ Challenges • + Classes • + Collectables • + Crafting • + Enhancements + • + Epic Destinies + • Favor +

+

+ Feats • + Glossary • + Items • + Maps • + Monsters • + Places • + Quests • + Races • + Skills • + Spells +

+
+

+ Please + create an account + or + log in + to build a reputation and unlock more editing + privileges, and then visit DDO wiki's + IRC Chat if + you need any help! +

+
+
+
+

+ Item:Elyd Edge +

+
+
From DDO wiki
+
+
+ Jump to: navigation, + search +
+
+

Elyd Edge

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Proficiency Class + Martial Weapon Proficiency + +
+
+ Elyd Edge shown.jpg +
+
+
Damage and Type[1d6] + 1 Pierce, Silver, Magic
+ Critical threat range + 18-20 / x2
Weapon TypeRapier / Piercing weapons
Race Absolutely RequiredNone
Minimum Level5
Required TraitNone
+ Use Magical Device + DC + No UMD needed
Handedness
Attack ModSTR, CHA
Damage ModSTR
Binding + Bound to Account on AcquireBound to Account on Acquire: This item is Bound to Account on Acquire +
Durability75
Made from + SteelSteel: + Steel is the common metal used to make weapons and + armor. +
Hardness11
Base Value + 00018110001,811ppPlatinum Piece  +
Weight2 lbs
Location + Unraveling Enchantments, upgrade of + Corroded Rapier +
Enchantments + +
Upgradeable? +

+ Epic Crafting + to + Epic Elyd Edge +

+
Description + Elven script on this fine silver blade reads 'Anthem of the + heart; Anthem of the mind'. +
Tips +
+
+ Elyd Edge.png +
+
+
+ + + + +
+ + +
+ + +
+ + +
+
+
+
+

Navigation menu

+
+ +
+ + +
+
+ + + +
+
+
+ + + + + +
+
+ + + + + + + + + + + + + + diff --git a/subprojects/common/ddo-web/src/test/resources/Epic_Sword_of_Shadow.html b/subprojects/common/ddo-web/src/test/resources/Epic_Sword_of_Shadow.html new file mode 100644 index 00000000..b323e1ef --- /dev/null +++ b/subprojects/common/ddo-web/src/test/resources/Epic_Sword_of_Shadow.html @@ -0,0 +1,1990 @@ + + + + + Item:Epic Sword of Shadow - DDO wiki + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+
+
+

+ Game mechanics + • + Newbie guide + • + In development + • + DDO Store • + IRC Chat +

+
+

+ Challenges • + Classes • + Collectables • + Crafting • + Enhancements + • + Epic Destinies + • Favor +

+

+ Feats • + Glossary • + Items • + Maps • + Monsters • + Places • + Quests • + Races • + Skills • + Spells +

+
+

+ Please + create an account + or + log in + to build a reputation and unlock more editing + privileges, and then visit DDO wiki's + IRC Chat if + you need any help! +

+
+
+
+

+ Item:Epic Sword of Shadow +

+
+
From DDO wiki
+
+
+ Jump to: navigation, + search +
+
+

+ Epic Sword of Shadow +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Proficiency Class + Martial Weapon Proficiency + +
+
+ Sword of Shadow shown.jpg +
+
+
Damage and Type + 2.5[2d6] + 10 Slash, Adamantine, Magic +
+ Critical threat range + 17-20 / x3
Weapon Type + Great Sword / Slashing weapons +
Race Absolutely RequiredNone
Minimum Level20
Required TraitNone
+ Use Magical Device + DC + No UMD needed
Handedness
Attack ModSTR
Damage ModSTR
Binding + Bound to Character on AcquireBound to Character on Acquire: This item is Bound to Character on Acquire +
Durability200
Made from + SteelSteel: + Steel is the common metal used to make weapons and + armor. +
Hardness30
Base Value + 002030500020,305ppPlatinum Piece  +
Weight8 lbs
Location + Epic version + of + Sword of Shadow +
Enchantments + +
Upgradeable? +

Fully upgraded

+
Description + This great sword was forged inside + The Vault of Night + itself. The essence of Shadow has seeped into this sword + granting it exceptional death-dealing abilities. +
Tips +

+ Note that in addition to the awesome base damage, this + greatsword has both the expanded critical threat of a falchion + and the multiplier of a greataxe. This makes it the ultimate + two-handed weapon in the game.
+ Minor bug: Material type listed as Steel in the durability + box, but the weapon is actually Adamantine in terms of + everything else - appearance, enchantment, DR breaking and + hardness. +

+
+
+
+ Epic Sword of Shadow.png +
+
+
+ + + + +
+ + +
+ + +
+ + +
+
+
+
+

Navigation menu

+
+ +
+ + +
+
+ + + +
+
+
+ + + + + +
+
+ + + + + + + + + + + + + + diff --git a/subprojects/common/ddo-web/src/test/resources/drowsword_enh.html b/subprojects/common/ddo-web/src/test/resources/drowsword_enh.html new file mode 100644 index 00000000..b1737aff --- /dev/null +++ b/subprojects/common/ddo-web/src/test/resources/drowsword_enh.html @@ -0,0 +1,298 @@ + + Enchantments + + + + diff --git a/subprojects/common/ddo-web/src/test/resources/eld_edge_bb.html b/subprojects/common/ddo-web/src/test/resources/eld_edge_bb.html new file mode 100644 index 00000000..69274565 --- /dev/null +++ b/subprojects/common/ddo-web/src/test/resources/eld_edge_bb.html @@ -0,0 +1,226 @@ + + + diff --git a/subprojects/common/ddo-web/src/test/resources/esossnippet.html b/subprojects/common/ddo-web/src/test/resources/esossnippet.html new file mode 100644 index 00000000..e3f19740 --- /dev/null +++ b/subprojects/common/ddo-web/src/test/resources/esossnippet.html @@ -0,0 +1,304 @@ + diff --git a/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/DDoWikiScrapingIT.scala b/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/DDoWikiScrapingIT.scala new file mode 100644 index 00000000..4c21a243 --- /dev/null +++ b/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/DDoWikiScrapingIT.scala @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web.mapping + +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.web.{Tree, Warehouse} +import net.ruippeixotog.scalascraper.browser.JsoupBrowser +import net.ruippeixotog.scalascraper.model.Document +import org.scalatest.OptionValues._ +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers +import org.scalatestplus.mockito.MockitoSugar + +import java.io.File +import scala.language.reflectiveCalls + +class DDoWikiScrapingIT extends AnyFunSpec with Matchers with MockitoSugar with LazyLogging { + lazy val defaultEncoding = "UTF-8" + lazy val baseUri = "http://www.ddowiki.com" + lazy val nestedPath = "Drow_Scimitar_of_the_Weapon_Master.html" + lazy val simplePath = "Elyd_Edge.html" + lazy val multiLevelPath = "" + val browser = JsoupBrowser() + + private def fixture = new { + + // Drow X of the Weapon Master + val nestedListDoc: Document = loadLocalTestHtml(nestedPath) + // Eyld Edge + val simpleListDoc: Document = loadLocalTestHtml(simplePath) + } + + protected def loadLocalTestHtml( + fileName: String, + charsetName: String = defaultEncoding, + baseUri: String = baseUri): Document = { + val url = Thread.currentThread().getContextClassLoader.getResource(fileName) + logger.info(s"Local file: ${url.getPath}") + val in = new File(url.getPath) + if (!in.exists()) logger.warn("can not load file!!") + browser.parseFile(in, charsetName) + + } + + describe("Effect / enhancement List") { + it("Should read a Simple list") { + // This example has 6 items in a Simple list, so we should have one branch with 6 leaves + val fragment = fixture.simpleListDoc.root + val result = Tree(Warehouse.readHtmlList(fragment)) + result.isStump should be(false) + result.leaves shouldBe empty + result.branches.value should have size 1 + result.branches.value.head.leaves.value should have size 6 + + } + + it("Should read a nested UL list") { + // This example has 2 items in a Simple list, plus 5 nested ones + + val fragment = fixture.nestedListDoc.root + val result = Tree(Warehouse.readHtmlList(fragment)) + result.isStump should be(false) + result.leaves shouldBe empty + result.branches shouldBe defined + result.branches.value should have size 1 + val branches = result.branches.getOrElse(Nil) + val leaves = branches.head.leaves.value should have size 2 + result.branches.value.head.leaves.value should have size 2 + val nestedBranches = branches.head.branches.value.toList + (nestedBranches should have).length(1) + nestedBranches.head.leaves shouldBe defined + nestedBranches.head.branches shouldBe empty + nestedBranches.head.leaves.value should have size 5 + + } + + it("Should read a Multi level item")(pending) + } +} diff --git a/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/ItemQueryIT.scala b/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/ItemQueryIT.scala new file mode 100644 index 00000000..544e5fa6 --- /dev/null +++ b/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/ItemQueryIT.scala @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2015 Andre White (adarro@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package io.truthencode.ddo.web.mapping + +import com.typesafe.scalalogging.LazyLogging +import io.truthencode.ddo.web.{toWikiUrlString, Warehouse} +import org.scalatest.Tag +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers +import org.scalatestplus.mockito.MockitoSugar + +import scala.language.reflectiveCalls + +object SlowTest extends Tag("io.truthencode.ddo.tags.SlowTest") + +class QueryItemIT extends AnyFunSpec with Matchers with MockitoSugar with LazyLogging { + val lblWeapon: String = "Weapon" + val msgMissing: String = "Missing!!!" + protected def fixture = new { + val typeList = { + val idWeapon = "Drow Scimitar of the Weapon Master" + Map(lblWeapon -> idWeapon) + } + val defaultItemId = "Epic Elyd Edge" + } + + describe("A named weapon") { + + it("should be retrievable from ddo wiki")({ + val f = fixture + val id = toWikiUrlString(f.typeList.getOrElse(lblWeapon, f.defaultItemId)) + lazy val msgDataFound = "weapon data found" + lazy val msgRetrieve = s"Attempting to retrieve item $id" + lazy val extracted = s"No Data for $id" + + logger.info(msgRetrieve) + val doc = Warehouse.loadDoc(id) + val weaponDoc = Warehouse.htmlToMappedValues(doc) + weaponDoc match { + case Some(x) => + logger.info(msgDataFound) + x.keys.foreach { key => + { + val v = { + x.getOrElse(key, msgMissing) + } + lazy val msgKv = s"\n$key: $v" + logger.info(msgKv) + } + } + case _ => logger.warn(extracted) + } + }) + } + +} diff --git a/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/WikiParserTest.scala b/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/WikiParserTest.scala new file mode 100644 index 00000000..3585ee3b --- /dev/null +++ b/subprojects/common/ddo-web/src/test/scala/io/truthencode/ddo/web/mapping/WikiParserTest.scala @@ -0,0 +1,67 @@ +package io.truthencode.ddo.web.mapping + +import com.typesafe.scalalogging.LazyLogging +import org.scalatest.funspec.AnyFunSpec + +class WikiParserTest extends AnyFunSpec with LazyLogging { + + describe("WikiParserTest") { + + it("should weaponModifier") {} + + it("should attackModifier") {} + + it("should binding") {} + + it("should proficiency") {} + + it("should baseValue") {} + + it("should upgradable") {} + + it("should minimumLevel") {} + + it("should damageAppliedType") {} + + it("should handedness") {} + + it("should durability") {} + + it("should weight") {} + + it("should damageModifier") {} + + it("should madeFrom") {} + + it("should hardness") {} + + it("should weaponCategoryInfo") {} + + it("should requiredTrait") {} + + it("should weaponType") {} + + it("should damage") {} + + it("should damageValue") {} + + it("should umdDc") {} + + it("should criticalProfile") {} + + it("should description") {} + + it("should damageDie") {} + + it("should monetaryValue") {} + + it("should enchantments") {} + + it("should criticalThreat") {} + + it("should location") {} + + it("should requiredRace") {} + + } +} diff --git a/subprojects/ddo-platform/build.gradle.kts b/subprojects/ddo-platform/build.gradle.kts index bbbb2fae..17b2a69a 100644 --- a/subprojects/ddo-platform/build.gradle.kts +++ b/subprojects/ddo-platform/build.gradle.kts @@ -15,18 +15,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -group = "io.truthencode" -version = "0.1-SNAPSHOT" +// group = "io.truthencode" +// version = "0.1-SNAPSHOT" plugins { `java-platform` } -val scalaLibraryVersion: String by project +description = "Project BOM. Contains common dependencies for projects." + +javaPlatform { + allowDependencies() +} dependencies { -// constraints { -// // this. -// api(group = "org.scala-lang", name = "scala-library", version = scalaLibraryVersion) -// } + constraints { + api(libs.logback.classic) + api(libs.org.jetbrains.annotations) + // JUnit + api(libs.junit.jupiter) + } + + // api(platform(":ddo-platform-scala")) + // api(platform(":ddo-platform-kotlin")) } \ No newline at end of file diff --git a/subprojects/ddo-platform/ddo-platform-kotlin/build.gradle.kts b/subprojects/ddo-platform/ddo-platform-kotlin/build.gradle.kts index aa529d2e..f7372054 100644 --- a/subprojects/ddo-platform/ddo-platform-kotlin/build.gradle.kts +++ b/subprojects/ddo-platform/ddo-platform-kotlin/build.gradle.kts @@ -22,16 +22,21 @@ plugins { `java-platform` } -val scalaLibraryVersion: String by project +description = "Project BOM. Contains common dependencies for scala projects." dependencies { constraints { - + api(libs.kotlin.bom) api(libs.kotlin.reflect) api(libs.kotlin.stdlib) api(libs.kotlin.stdlib.jdk8) api(libs.kotlin.stdlib.jdk7) api(libs.kotlin.stdlib.common) // TODO: Add moshi-kotlin / reflect et all to kotlin-platform + api(libs.bundles.kotest) + api(libs.squareup.moshi.kotlin) + api(libs.squareup.moshi) + api(libs.squareup.moshi.adapters) + api(libs.squareup.moshi.kotlin.codegen) } } \ No newline at end of file diff --git a/subprojects/ddo-platform/ddo-platform-scala/build.gradle.kts b/subprojects/ddo-platform/ddo-platform-scala/build.gradle.kts index a9f19733..3583840b 100644 --- a/subprojects/ddo-platform/ddo-platform-scala/build.gradle.kts +++ b/subprojects/ddo-platform/ddo-platform-scala/build.gradle.kts @@ -19,6 +19,8 @@ plugins { `java-platform` } +description = "Project BOM. Contains common dependencies for scala projects." + val scalaLibraryVersion: String by project val scalaMajorVersion: String by project val scalaTestVersion: String by project @@ -73,11 +75,6 @@ dependencies { api(libs.wix.accord.core.s213) api(libs.wix.accord.scalatest.s213) - // TODO: Pull this constraints out of scala and into common - api(libs.org.jetbrains.annotations) - // JUnit - api(libs.junit.jupiter) - // A library providing a DSL for loading and extracting content from HTML pages. api(libs.ruippeixotog.scala.scraper.s213) api(libs.enumeratum.s213)