Compare commits

...

18 Commits

Author SHA1 Message Date
Tad Hunt 3202b2dd33
Merge 42a45e02f5 into 29c5d7f56d 2024-01-05 23:06:22 -07:00
Andreas Troelsen 29c5d7f56d Release 0.108. 2024-01-01 20:15:55 +01:00
Andreas Troelsen e40fc6ef84 Add `publish-hangar` GitHub Actions workflow.
Introduces a new workflow that runs when a new build has been published
on GitHub Releases. It converts the release notes to Hangar Markdown and
sends it to Hangar along with the jar-file.

Note: The workflow currently relies on the version string being appended
to the filename of the jar-file. Without it, the file reference in the
`curl` request that uploads the build would need to change.

The workflow references a new secret, `HANGAR_TOKEN`, which is just an
API key for the Hangar API. The token was created in the Hangar profile
settings (API Keys), and its only permission is `create_version`.

In order to properly upload a new build to Hangar, we need to construct
a somewhat complex JSON object. This is because the Hangar API allows
for publishing releases on multiple platforms and for multiple versions,
which makes the simple use case for MobArena's single file upload look a
bit overcomplicated. Unlike the CurseForge API, the Hangar API supports
"normal" platform version strings, so we don't need to map anything. It
also supports patch version wildcards, so we can get away with `1.18.x`,
`1.19.x`, etc. for each version supported. The API only uses the API key
for authentication, which means we need to grab a JWT and use that for
the actual upload request. Note that the `pluginDependencies` property
is currently required, but it can be left empty.

The workflow can be invoked directly via the `workflow_dispatch` event,
which might come in handy if something in the pipeline breaks.

The Hangar base URL and project slug are both hardcoded, and things
would probably be cleaner if they were made into variables, but we don't
need this workflow anywhere else, so it's fine for now.
2024-01-01 17:05:41 +01:00
Andreas Troelsen be6fd85a6d Add `publish-curseforge` GitHub Actions workflow.
Introduces a new workflow that runs when a new build has been published
on GitHub Releases. It converts the release notes to CurseForge HTML and
sends it to CurseForge along with the jar-file.

Note: The workflow currently relies on the version string being appended
to the filename of the jar-file. Without it, the file reference in the
`curl` request that uploads the build would need to change.

The workflow references a new secret, `CURSEFORGE_TOKEN`, which is just
an API key for the CurseForge API. The token was created on CurseForge
under profile settings (My API Tokens).

In order to properly upload a new build to CurseForge, we need a list of
"game version IDs", which isn't completely trivial. The API gives us a
means of looking up _all_ Minecraft game version IDs, but we then have
to manually filter out the ones that don't apply to Bukkit plugins, as
there are duplicate entries for each Minecraft version, and only some of
them work for Bukkit plugins (which turns out to be the ones with game
version type ID 1). The structure of the `metadata` field combined with
how incredibly difficult bash can be to work with has resulted in some
gnarly text processing trying to filter the JSON response and turning it
into a list for use in the `jq` template, but it gets the job done.

The CurseForge base URL and project ID are both hardcoded, and things
would probably be cleaner if they were made into variables, but we don't
need this workflow anywhere else, so it's fine for now.

The workflow can be invoked directly via the `workflow_dispatch` event,
which might come in handy if something in the pipeline breaks.

Lots of inspiration was found in the probably really great GitHub Action
`curseforge-upload` [1]. We could have probably just used that, but it's
nice to have full control of the process. At any rate, thanks to itsmeow
and NotMyFault for publishing their work.

---

[1] https://github.com/itsmeow/curseforge-upload
2024-01-01 16:46:38 +01:00
Andreas Troelsen b881943656 Add `hangar` format to release note script.
Hangar uses Markdown, so this is a very easy release note "conversion"
just like GitHub Releases.
2023-12-31 15:14:25 +01:00
Andreas Troelsen 8e5d2f0d23 Make InventoryThingParser package-private.
We don't need the parser exposed outside of the `things` package, and
none of the other thing parsers are public anyway. Coincidentally, this
fixes a warning about exposing InventoryThing outside of its visibility
scope, so yay.
2024-01-01 18:34:20 +01:00
Andreas Troelsen 3b7b638b00 Make LexeMatcher package-private.
We don't need it outside of the `formula` package.

This fixes warnings about exposing Lexeme outside of its visibility
scope, so yay.
2024-01-01 18:26:44 +01:00
Andreas Troelsen eb51a31720 Remove unused ThingManager constructor.
This fixes a warning about exposing ItemStackThingParser outside of its
visibility scope, but really it's just a good little cleanup step, since
the constructor in question is never used for anything. We might want to
eventually expose the ItemStackThingParser and use it in more places in
the code base, but in that case, and in that case it would probably make
sense to re-introduce the constructor, but I'm calling YAGNI on this in
order to nuke a warning.
2024-01-01 18:23:54 +01:00
Andreas Troelsen 82f00c5535 Fix "unary operator" warnings in FormulaManagerIT.
Okay, the reason the code included the unary plus was to more directly
represent the resulting expression, but I'm guessing the compiler isn't
going to respect that intent even if it could somehow understand it, so
it will probably remove the symbols and just parse it all the same.

Unlike with the unary plus, the unary minus can be "fixed" by wrapping
it in parentheses. The end result is of course the exact same, but the
intent is perhaps a bit clearer this way. We want to try to coerce the
compiler into creating an expression with "add a negative value", just
for the sake of "correctness" at the runtime evaluation level, but even
if that isn't what will actually happen, the explicit code is still a
bit easier to read. While unary plus is easy to disregard, "fixing" an
unnecessary unary minus would mean having to change the binary operator
before it, which muddies the intent of the expression.
2024-01-01 17:49:21 +01:00
Andreas Troelsen d8fdbb80c0 Simplify formula operation interfaces.
This commit releases the BinaryOperation and UnaryOperation interfaces
of the `formula` package from their `java.util.function` supertypes and
redeclares the previously inherited functions directly in the operation
interfaces, but also reifies them by explicitly using primitive doubles
instead of generics and wrapper classes. Doing so does not change the
functionality or any other code at all, but it makes the interfaces much
"stronger", since they no longer need to consider `null` values, which
they didn't actually take into account anyway. This fixes a warning in
Visual Studio Code (not sure how to get the same warning in IntelliJ)
about the operator registrations in the default formula environment
factory method being unsafe.
2024-01-01 19:39:59 +01:00
Andreas Troelsen e5ffe169a1 Create release drafts from "Release ..." commits.
This commit adds a second job to the build workflow that runs after the
build job has completed. The job creates a GitHub Releases _draft_ that
needs to be manually published in order to be publicly available.

The job runs if, and only if, the following conditions are met:

- The build job has completed _successfully_, i.e. if the Gradle `build`
  task fails, the draft job doesn't run.

- The `push` event that triggered the workflow happened on the `master`
  branch, i.e. releases will never be created from temporary branches.

- The commit message of the most recent commit in the `push` event that
  triggered the workflow starts with `"Release "`, i.e. there must be a
  commit that explicitly tries to "release" a build.

- The version string does _not_ end with `-SNAPSHOT`, i.e. development
  builds will not be released.

All of these conditions act as safeguards, so we don't end up releasing
something we don't want to release, but they also prevent bloating the
Releases page with a bunch of useless drafts.

The job uses the `version` output variable from the build job that was
introduced in a recent commit to extract release notes using the script
that was also introduced recently, as well as for the name of the _tag_
to create when the release is published.

Note that the `GITHUB_TOKEN` environment variable is required to be set
when we want to use the GitHub CLI in a workflow [1]. The job also has
an explicit `contents: write` permission, which is required for creating
releases from GitHub Actions.
2023-12-31 04:43:53 +01:00
Andreas Troelsen 798ae0f578 Output version string in build workflow.
This commit makes the build workflow output the version string as found
in the `version` property in `build.gradle.kts`. The version string will
be necessary further down the pipeline when we need to extract release
notes and create tags.

There are many ways to extract the version string:

- Use `grep` to grab it from `build.gradle.kts` directly. This is pretty
  brittle, since we don't really know for sure if the structure of the
  file will change in the future.

- Create a Gradle task in `build.gradle.kts` that prints the version
  string. This is probably the most direct approach we could take, but
  such a hyper-specific task feels like a code smell. It also requires
  running Gradle again, which is a bit slow.

- Use the built-in `properties` task in Gradle to print the `version`
  property and `grep` it. We avoid changing `build.gradle.kts`, which is
  a plus, but we still have to actually run Gradle.

- Parse the filename of the resulting jar-file in `build/libs/`, since
  it now contains the version string. This is also brittle, because we
  don't know if we're gonna continue to append the version string to the
  jar-file, and depending so much on it being there is a little scary.

- Extract `plugin.yml` from the resulting jar-file and `grep` it. This
  is perhaps a little crude, but it is much faster than running Gradle,
  and as a bonus, we get a bit closer to "what's inside the jar-file",
  which should give us a bit more confidence that any given release is
  actually the version it claims to be.

It may seem like a small thing to invest so much text on, but from an
automation standpoint, it is much easier to be confident in automations
with predictable and robust mechanisms for deriving input variables.
2023-12-31 04:16:08 +01:00
Andreas Troelsen 84776990b9 Add release note extraction script.
Introduces a crude Python script that can extract release notes from the
changelog for a given version and convert it to one of three different
output formats:

- `github` for GitHub Releases. This is just the Markdown itself, but
  with the very first line (the version) removed, because the version is
also the title of the release itself.

- `spigot` for Spigot Resources. This is the BBCode format used on the
  forums and in the resource descriptions.

- `curse` for CurseForge File Uploads. Curse uses a so-called "WYSIWYG"
  format that's really just HTML underneath.

The formats for Spigot and CurseForge are straightforward to convert to
as long as we only use simple text formatting, bullet lists, and links,
but that is really all the changelog should consist of anyway.

While this script already makes the release process quite a bit easier
on its own, the end goal is to _automate_ releases as much as possible,
and to do that, we need to be able to extract release notes, and we need
to be able to do it from GitHub Actions, which is quite a bit simpler if
we don't use third-party libraries.

Publishing releases on GitHub is almost trivial, while CurseForge is
pretty easy, and Hangar should be very doable as well. Spigot, on the
other hand, is stuck in the dark ages, so we must continue to upload
files manually there.
2023-12-31 03:25:14 +01:00
Andreas Troelsen 590f877756 Build on push to branches, not tags.
According to the documentation, by not specifying anything in the `push`
event, GitHub Actions will run the workflow for both branches and tags,
but by specifying `branches` alone, it will _only_ run the workflow for
branches and _not_ tags [1].

We want to build on pushes to _all_ branches so we can give folks a jar
to try out for feature requests and bug fixes. We don't want to build on
tags, however, because they don't provide any value in the current build
pipeline. If the version was derived from Git tags, it could make sense
to build on tags, but that's not where we are.

As for the `**` glob pattern instead of just `*`, the documentation says
that the latter does not match forward slashes [2], and while our naming
convention for branches doesn't use slashes right now, there's no reason
that they shouldn't be viable later down the road.

---

[1] https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore
[2] https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
2023-12-31 02:25:41 +01:00
Andreas Troelsen 932b9de8f2 Minor tweaks to build workflow.
Removes trailing whitespace and simplifies some step names.
2023-12-31 02:24:53 +01:00
Andreas Troelsen 614d95683e Update `upload-artifact` to v4.
Apparently there are numerous performance and behavioral improvements.
2023-12-30 23:49:03 +01:00
Andreas Troelsen 4c855e6705 Include version in artifact filename.
Removes the "archive version" override for the `shadowJar` task in the
build file, resulting in a jar-file that contains the current version
number in the filename. It's mostly a convenience tradeoff; either we
can see the version directly in the filename and avoid assumptions, or
we can easily overwrite an existing jar-file with a new one.

Also updates the upload step of the build workflow to a glob pattern so
we grab the file regardless of the version.
2023-12-30 23:36:07 +01:00
Tad Hunt 42a45e02f5 Fix possible null indirection warnings 2023-09-19 08:33:19 -06:00
14 changed files with 471 additions and 28 deletions

View File

@ -1,15 +1,20 @@
name: build
on:
on:
workflow_dispatch:
push:
branches:
- '**'
jobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: 'Checkout source code'
- name: 'Checkout'
uses: actions/checkout@v4
- name: 'Set up JDK'
@ -19,11 +24,56 @@ jobs:
distribution: 'adopt'
cache: 'gradle'
- name: 'Build, test, and package'
- name: 'Build'
run: ./gradlew build --no-daemon
- name: 'Upload artifact'
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: MobArena.jar
path: build/libs/MobArena.jar
path: build/libs/MobArena-*.jar
- name: 'Output version'
id: version
run: |
version=$(
unzip -p build/libs/MobArena-*.jar plugin.yml \
| grep '^version: ' \
| awk '{printf $2}' \
| tr -d "'" \
)
echo "version=${version}" >> "${GITHUB_OUTPUT}"
draft:
needs: build
if: |
needs.build.result == 'success' &&
github.ref_name == 'master' &&
startsWith(github.event.head_commit.message, 'Release ') &&
!endsWith(needs.build.outputs.version, '-SNAPSHOT')
runs-on: ubuntu-latest
permissions:
contents: write
env:
VERSION: ${{ needs.build.outputs.version }}
steps:
- name: 'Checkout'
uses: actions/checkout@v4
- name: 'Download artifact'
uses: actions/download-artifact@v4
with:
name: MobArena.jar
- name: 'Extract release notes'
run: scripts/extract-release-notes -f github "${VERSION}" > release-notes.md
- name: 'Create release draft'
run: gh release create "${VERSION}" --draft --notes-file release-notes.md MobArena-*.jar
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@ -0,0 +1,77 @@
name: publish-curseforge
on:
release:
types:
- 'released'
workflow_dispatch:
inputs:
tag_name:
description: 'The tag name of the release to publish'
required: true
type: string
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
env:
TAG_NAME: ${{ github.event.release.tag_name || inputs.tag_name }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download release assets
run: gh release download "${TAG_NAME}"
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Publish to CurseForge
run: |
echo 'Extract release notes'
changelog=$(scripts/extract-release-notes -f curse "${TAG_NAME}")
echo 'Look up game version IDs'
game_version_type_id=1
game_version_names='"1.20","1.19","1.18","1.17","1.16","1.15","1.14","1.13"'
type_condition="(.gameVersionTypeID == ${game_version_type_id})"
name_condition="(.name | startswith(${game_version_names}))"
game_version_ids=$(
curl -s -X GET 'https://minecraft.curseforge.com/api/game/versions' \
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
| jq -c ".[] | select(${type_condition} and ${name_condition}) | .id" \
| paste -sd, - \
)
echo 'Create metadata file'
cat << EOF > metadata.jq
{
changelog: \$changelog,
changelogType: "html",
displayName: \$displayName,
gameVersions: \$gameVersions,
releaseType: "beta"
}
EOF
jq -c -n \
--arg changelog "${changelog}" \
--arg displayName "MobArena v${TAG_NAME}" \
--argjson gameVersions "[${game_version_ids}]" \
-f metadata.jq \
> metadata.json
echo 'Publish build to CurseForge'
base_url='https://minecraft.curseforge.com'
project_id=31265
curl -s -X POST "${base_url}/api/projects/${project_id}/upload-file" \
-H "X-Api-Token: ${{ secrets.CURSEFORGE_TOKEN }}" \
-F 'metadata=<metadata.json' \
-F "file=@MobArena-${TAG_NAME}.jar"

79
.github/workflows/publish-hangar.yml vendored Normal file
View File

@ -0,0 +1,79 @@
name: publish-hangar
on:
release:
types:
- 'released'
workflow_dispatch:
inputs:
tag_name:
description: 'The tag name of the release to publish'
required: true
type: string
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
env:
TAG_NAME: ${{ github.event.release.tag_name || inputs.tag_name }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download release assets
run: gh release download "${TAG_NAME}"
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Publish to Hangar
run: |
echo 'Extract release notes'
changelog=$(scripts/extract-release-notes -f hangar "${TAG_NAME}")
echo 'Create version upload file'
cat << EOF > version-upload.jq
{
version: \$version,
channel: "Release",
description: \$changelog,
platformDependencies: {
"PAPER": [
"1.13.x",
"1.14.x",
"1.15.x",
"1.16.x",
"1.17.x",
"1.18.x",
"1.19.x",
"1.20.x"
]
},
pluginDependencies: {},
files: [
{ platforms: ["PAPER"] }
]
}
EOF
jq -c -n \
--arg version "${TAG_NAME}" \
--arg changelog "${changelog}" \
-f version-upload.jq \
> version-upload.json
echo 'Authenticate with Hangar'
base_url='https://hangar.papermc.io/api/v1'
key=${{ secrets.HANGAR_TOKEN }}
jwt=$(curl -s -X POST "${base_url}/authenticate?apiKey=${key}" | jq -r '.token')
echo 'Publish build to Hangar'
project_slug='MobArena'
curl -s -X POST "${base_url}/projects/${project_slug}/upload" \
-H "Authorization: ${jwt}" \
-F 'versionUpload=<version-upload.json;type=application/json' \
-F "files=@MobArena-${TAG_NAME}.jar"

View File

@ -4,7 +4,7 @@ plugins {
}
group = "com.garbagemule"
version = "0.107.1-SNAPSHOT"
version = "0.108"
repositories {
mavenLocal()
@ -58,7 +58,6 @@ tasks {
archiveBaseName = "MobArena"
archiveClassifier = ""
archiveVersion = ""
}
// We're using shadowJar, so we can skip the regular jar task.

View File

@ -11,6 +11,8 @@ These changes will (most likely) be included in the next version.
## [Unreleased]
## [0.108] - 2024-01-01
### Added
- Support for chest references in item syntax. The new `inv` syntax allows for referencing container indices in the config-file. This should help bridge the gap between class chests and various other parts of the config-file, such as rewards and upgrade waves.
- Support for saved items. The new `/ma save-item` command can be used to save the currently held item to disk, which allows it to be used in various places in the config-file. This should help bridge the gap between the config-file and class chests for config-file centric setups.
@ -259,7 +261,8 @@ Thanks to:
- Swatacular for help with testing bug fixes
- Haileykins for contributions to the code base
[Unreleased]: https://github.com/garbagemule/MobArena/compare/0.107...HEAD
[Unreleased]: https://github.com/garbagemule/MobArena/compare/0.108...HEAD
[0.108]: https://github.com/garbagemule/MobArena/compare/0.107...0.108
[0.107]: https://github.com/garbagemule/MobArena/compare/0.106...0.107
[0.106]: https://github.com/garbagemule/MobArena/compare/0.105...0.106
[0.105]: https://github.com/garbagemule/MobArena/compare/0.104.2...0.105

235
scripts/extract-release-notes Executable file
View File

@ -0,0 +1,235 @@
#!/usr/bin/env python3
import argparse
import os
import re
import sys
VERSION_PREFIX = '## '
SECTION_PREFIX = '### '
LIST_ITEM_PREFIX = '- '
def main():
args = parse_args()
lines = extract(args.version)
output(lines, args.format)
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument(
'version',
help='the version to extract release notes from the changelog for',
)
parser.add_argument(
'--format',
'-f',
choices=['github', 'hangar', 'spigot', 'curse'],
help='the format to output the release notes in',
)
return parser.parse_args()
def extract(target):
filename = 'changelog.md'
if not os.path.isfile(filename):
filename = os.path.join('..', filename)
if not os.path.isfile(filename):
print('error: changelog.md not found!')
sys.exit(1)
lines = []
with open(filename) as changelog:
found = False
for entry in changelog:
if entry.startswith(VERSION_PREFIX):
if found:
break
i = entry.find('[') + 1
j = entry.find(']')
version = entry[i:j]
if version == target:
if version[0].isdigit():
version = f'v{version}'
lines.append(f'{VERSION_PREFIX}{version}')
lines.append('')
found = True
continue
if not found:
continue
lines.append(entry.strip())
if not found:
print(f'error: version {target} not found!')
sys.exit(1)
return lines
def output(lines, fmt):
if fmt == 'github':
output_as_github_markdown(lines)
elif fmt == 'hangar':
output_as_hangar_markdown(lines)
elif fmt == 'spigot':
output_as_spigot_bbcode(lines)
elif fmt == 'curse':
output_as_curseforge_html(lines)
else:
output_raw(lines)
def output_as_github_markdown(lines):
"""
GitHub Releases Markdown is printed as the raw output from the changelog
except for the version header (the first line), because the version number
is already used as the release title, so we don't want it to appear twice.
"""
output_raw(lines[1:])
def output_as_hangar_markdown(lines):
"""
Hangar Versions use Markdown in the same format as GitHub Releases, so we
don't actually need to do anything else here either. Just strip the first
line so we don't get a duplicate header.
"""
output_raw(lines[1:])
def output_as_spigot_bbcode(lines):
"""
Spigot uses BBCode for resource update descriptions. It's very similar to
regular HTML, which makes it fairly easy to convert from Markdown. We just
need to use a [FONT] tag with Courier New for code bits.
"""
listing = False
for line in lines:
line = line.strip()
if line.startswith(VERSION_PREFIX):
i = len(VERSION_PREFIX)
version = line[i:]
print(f'[B]{version}[/B]')
continue
if line.startswith(SECTION_PREFIX):
if listing:
print('[/LIST]')
listing = False
i = len(SECTION_PREFIX)
section = line[i:]
print(f'[B]{section}:[/B]')
continue
if line.startswith(LIST_ITEM_PREFIX):
if not listing:
print('[LIST]')
listing = True
i = len(LIST_ITEM_PREFIX)
item = line[i:]
# Replace **bold** text
item = re.sub(r'\*\*(.*?)\*\*', r'[B]\1[/B]', item)
# Replace _italic_ text
item = re.sub(r'_(.*?)_', r'[I]\1[/I]', item)
# Replace `code` text
item = re.sub(r'`(.*?)`', r'[FONT=Courier New]\1[/FONT]', item)
# Replace [links](url)
item = re.sub(r'\[([^\]]+)]\(([^)]+)\)', r'[URL=\2]\1[/URL]', item)
print(f'[*]{item}')
continue
if len(line) > 0:
print(line)
if listing:
print('[/LIST]')
def output_as_curseforge_html(lines):
"""
CurseForge uses regular HTML for file update descriptions, which makes it
fairly easy to convert from Markdown. Angled brackets need to be replaced
with their HTML entity equivalents, but other than that it's very similar
to the Spigot BBCode conversion.
"""
listing = False
for line in lines:
line = line.strip()
if line.startswith(VERSION_PREFIX):
i = len(VERSION_PREFIX)
version = line[i:]
print(f'<p><strong>{version}</strong></p>')
continue
if line.startswith(SECTION_PREFIX):
if listing:
print('</ul>')
listing = False
i = len(SECTION_PREFIX)
section = line[i:]
print(f'<p><strong>{section}:</strong></p>')
continue
if line.startswith(LIST_ITEM_PREFIX):
if not listing:
print('<ul>')
listing = True
i = len(LIST_ITEM_PREFIX)
item = line[i:]
# Replace angled brackets
item = item.replace('<', '&lt;')
item = item.replace('>', '&gt;')
# Replace **bold** text
item = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', item)
# Replace _italic_ text
item = re.sub(r'_(.*?)_', r'<emph>\1</emph>', item)
# Replace `code` text
item = re.sub(r'`(.*?)`', r'<code>\1</code>', item)
# Replace [links](url)
item = re.sub(r'\[([^\]]+)]\(([^)]+)\)', r'<a href="\2">\1</a>', item)
print(f'<li>{item}</li>')
continue
if len(line) > 0:
print(line)
if listing:
print('</ul>')
def output_raw(lines):
[print(line.strip()) for line in lines]
if __name__ == '__main__':
main()

View File

@ -1,7 +1,8 @@
package com.garbagemule.MobArena.formula;
import java.util.function.BiFunction;
@FunctionalInterface
public interface BinaryOperation extends BiFunction<Double, Double, Double> {
public interface BinaryOperation {
double apply(double left, double right);
}

View File

@ -1,7 +1,8 @@
package com.garbagemule.MobArena.formula;
import java.util.function.Function;
@FunctionalInterface
public interface UnaryOperation extends Function<Double, Double> {
public interface UnaryOperation {
double apply(double value);
}

View File

@ -524,8 +524,8 @@ public class ArenaRegion
}
// Set the coords and save
if (lower != null) setLocation(coords, r1.name().toLowerCase(), lower);
if (upper != null) setLocation(coords, r2.name().toLowerCase(), upper);
if (lower != null && r1 != null) setLocation(coords, r1.name().toLowerCase(), lower);
if (upper != null && r2 != null) setLocation(coords, r2.name().toLowerCase(), upper);
save();
// Reload regions and verify data

View File

@ -6,7 +6,7 @@ import org.bukkit.World;
import java.util.function.Supplier;
public class InventoryThingParser implements ThingParser {
class InventoryThingParser implements ThingParser {
private static final String PREFIX = "inv(";
private static final String SUFFIX = ")";

View File

@ -10,21 +10,17 @@ public class ThingManager implements ThingParser {
private final List<ThingParser> parsers;
private final ItemStackThingParser items;
public ThingManager(MobArena plugin, ItemStackThingParser parser) {
public ThingManager(MobArena plugin) {
parsers = new ArrayList<>();
parsers.add(new CommandThingParser());
parsers.add(new MoneyThingParser(plugin));
parsers.add(new PermissionThingParser(plugin));
parsers.add(new PotionEffectThingParser());
parsers.add(new InventoryThingParser(plugin.getServer()));
items = parser;
items = new ItemStackThingParser();
items.register(new SavedItemParser(plugin));
}
public ThingManager(MobArena plugin) {
this(plugin, new ItemStackThingParser());
}
/**
* Register a new thing parser in the manager.
*

View File

@ -98,6 +98,8 @@ public class WaveParser
case BOSS:
result = parseBossWave(arena, name, config);
break;
default:
throw new ConfigError("Unknown wave type for wave " + name + " of arena " + arena.configName() + ": " + t);
}
// Grab the branch-specific nodes.

View File

@ -230,8 +230,8 @@ public class FormulaManagerIT {
@Parameters(name = "{0} = {1}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{"1 + +1.2", 1 + +1.2},
{"1 + -1.2", 1 + -1.2},
{"1 + +1.2", 1 + 1.2},
{"1 + -1.2", 1 + (-1.2)},
});
}
@ -259,8 +259,8 @@ public class FormulaManagerIT {
@Parameters(name = "{0} = {1}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{"1+-2", 1 + -2},
{"3-+4", 3 - +4},
{"1+-2", 1 + (-2)},
{"3-+4", 3 - 4},
{"3*7.5", 3 * 7.5},
{"10/2.5", 10 / 2.5},
{"9%4", 9 % 4},

View File

@ -6,7 +6,7 @@ import org.hamcrest.TypeSafeMatcher;
import java.util.Objects;
public class LexemeMatcher extends TypeSafeMatcher<Lexeme> {
class LexemeMatcher extends TypeSafeMatcher<Lexeme> {
private final TokenType type;
private final String value;