Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Build and test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: 17
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup gradle cache
uses: burrunan/gradle-cache-action@v1
with:
save-generated-gradle-jars: false
save-local-build-cache: false
save-gradle-dependencies-cache: true
save-maven-dependencies-cache: true
# Ignore some of the paths when caching Maven Local repository
maven-local-ignore-paths: |
starlight/mmo/
- name: Build
run: ./gradlew classes testClasses
- name: Run tests
run: ./gradlew test
21 changes: 21 additions & 0 deletions .github/workflows/sync_docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Sync Docs

on:
push:
paths:
- docs/**
branches:
- master

jobs:
deploy-wiki:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Sync Wiki Changes
uses: Andrew-Chen-Wang/github-wiki-action@v2
env:
WIKI_DIR: docs/
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_MAIL: ${{ github.triggering_actor }}
GH_NAME: ${{ github.repository_owner }}
2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions docs/Home.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# HollowCube Common

2 changes: 1 addition & 1 deletion modules/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ subprojects {
apply(plugin = "java")
apply(plugin = "net.ltgt.errorprone")

group = "net.hollowcube.libmmo"
group = "net.hollowcube.common"

repositories {
mavenCentral()
Expand Down
11 changes: 11 additions & 0 deletions modules/common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## common

Common libraries for other modules in the project.

Included by all other projects, so this must be kept small with minimal dependencies.

```
data: Data parsing abstraction
registry: Resource registry for various data driven modules
util: Common utilities
```
17 changes: 17 additions & 0 deletions modules/common/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugins {
`java-library`
}

dependencies {
api("com.github.minestommmo:DataFixerUpper:cf58e926a6")
api("net.kyori:adventure-text-minimessage:4.11.0")

implementation("org.tinylog:tinylog-impl:2.4.1")

implementation("io.github.cdimascio:dotenv-java:2.2.4")

// Optional components
compileOnly("org.mongodb:mongodb-driver-sync:4.7.0")


}
28 changes: 28 additions & 0 deletions modules/common/src/main/java/net/hollowcube/Env.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package net.hollowcube;

import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.Supplier;

public class Env {
/**
* Strict mode is enabled in production, but may be disabled during tests.
* <p>
* It should be used to check cases which are fine during development but are a fatal problem in production. For
* example, if a registry is empty for any reason in production the server should not be allowed to start.
*/
public static final Boolean STRICT_MODE = Boolean.valueOf(System.getProperty("starlight.strict", "false"));


private static final Logger STRICT_LOGGER = LoggerFactory.getLogger("STRICT");

public static void strictValidation(@NotNull String message, @NotNull Supplier<Boolean> predicate) {
if (STRICT_MODE && predicate.get()) {
STRICT_LOGGER.error(message);
System.exit(1);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package net.hollowcube.config;

import com.mojang.serialization.Codec;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import net.hollowcube.dfu.EnvVarOps;

import java.util.Locale;

public final class ConfigProvider {

public static <T> @NotNull T load(@NotNull String prefix, @NotNull Codec<T> codec) {
var result = EnvVarOps.DOTENV.withDecoder(codec)
.apply(prefix.toUpperCase(Locale.ROOT))
.result()
.orElse(null);
Check.notNull(result, "Config unable to load");
return result.getFirst();
}
}
24 changes: 24 additions & 0 deletions modules/common/src/main/java/net/hollowcube/data/NumberSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.hollowcube.data;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.ThreadLocalRandom;

/**
* A source of numbers, implementations decide where the numbers come from
*/
@FunctionalInterface
public interface NumberSource {

static @NotNull NumberSource constant(double value) {
return () -> value;
}

static @NotNull NumberSource threadLocalRandom() {
return () -> ThreadLocalRandom.current().nextDouble();
}


double random();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package net.hollowcube.data.number;

import com.google.auto.service.AutoService;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.hollowcube.data.NumberSource;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import net.hollowcube.dfu.ExtraCodecs;

record ConstantNumberProvider(
@NotNull Number value
) implements NumberProvider {

public static Codec<ConstantNumberProvider> CODEC = RecordCodecBuilder.create(i -> i.group(
ExtraCodecs.NUMBER.fieldOf("value").forGetter(ConstantNumberProvider::value)
).apply(i, ConstantNumberProvider::new));


@Override
public long nextLong(@NotNull NumberSource numbers) {
return value().longValue();
}

@Override
public double nextDouble(@NotNull NumberSource numbers) {
return value().doubleValue();
}


@AutoService(NumberProvider.Factory.class)
public static final class Factory extends NumberProvider.Factory {
public Factory() {
super(
NamespaceID.from("starlight:constant"),
ConstantNumberProvider.class,
ConstantNumberProvider.CODEC
);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package net.hollowcube.data.number;

import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import net.hollowcube.registry.Registry;
import net.hollowcube.registry.ResourceFactory;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import net.hollowcube.data.NumberSource;
import net.hollowcube.dfu.DFUUtil;
import net.hollowcube.dfu.ExtraCodecs;

/**
* A source of numbers, see <a href="https://minecraft.fandom.com/wiki/Loot_table#Number_Providers">Number
* Providers</a>.
* <p>
* Implementing a new number source requires a few steps:
* <ol>
* <li>Create a class inheriting from {@link NumberProvider}</li>
* <li>Write a {@link Codec} for the class</li>
* <li>Create an inner factory class inheriting from {@link NumberProvider.Factory}, filling in the required constructor params</li>
* <li>Annotate the factory class with {@link com.google.auto.service.AutoService} for {@link NumberProvider.Factory}</li>
* </ol>
* <p>
* Would like to look into a simplification of this process & removal of the Factory class. I would prefer if it was something like the following
* <pre>{@code
* // This, where the annotation generates an entry for the superclass
* @BasicRegistryItem("minecraft:constant")
* public record ConstantNumberProvider(
* Number value
* ) implements NumberProvider {
*
* Codec<ConstantNumberProvider> CODEC = ...;
*
* // Or alternatively something like this, where it finds the descriptor element
* Descriptor DESCRIPTOR = new Descriptor("minecraft:constant", CODEC){}
*
* }
* }</pre>
*
* @see ConstantNumberProvider
*/
public interface NumberProvider {

static @NotNull NumberProvider constant(@NotNull Number value) {
return new ConstantNumberProvider(value);
}

Codec<NumberProvider> CODEC = Codec.either(
Factory.CODEC.<NumberProvider>dispatch(Factory::from, Factory::codec),
// Handle the case of providing a single value value. If serialized back it will
// come out as a full {"type": "constant", "value": ...}
ExtraCodecs.NUMBER.xmap(ConstantNumberProvider::new, ConstantNumberProvider::value)
).xmap(DFUUtil::value, Either::left);


// Impl

long nextLong(@NotNull NumberSource numbers);

double nextDouble(@NotNull NumberSource numbers);


abstract class Factory extends ResourceFactory<NumberProvider> {
static Registry<Factory> REGISTRY = Registry.service("number_providers", NumberProvider.Factory.class);
static Registry.Index<Class<?>, NumberProvider.Factory> TYPE_REGISTRY = REGISTRY.index(NumberProvider.Factory::type);

public static final Codec<Factory> CODEC = Codec.STRING.xmap(ns -> REGISTRY.get(ns), Factory::name);

public Factory(NamespaceID namespace, Class<? extends NumberProvider> type, Codec<? extends NumberProvider> codec) {
super(namespace, type, codec);
}

static @NotNull Factory from(@NotNull NumberProvider provider) {
return TYPE_REGISTRY.get(provider.getClass());
}
}

}
25 changes: 25 additions & 0 deletions modules/common/src/main/java/net/hollowcube/dfu/DFUUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.hollowcube.dfu;

import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public final class DFUUtil {

public static <T, S> Map<T, S> pairListToMap(List<Pair<T, S>> pairList) {
return pairList.stream().collect(Collectors.toMap(Pair::getFirst, Pair::getSecond));
}

public static <T, S> List<Pair<T, S>> mapToPairList(Map<T, S> map) {
return map.entrySet().stream().map(entry -> new Pair<>(entry.getKey(), entry.getValue())).toList();
}

public static <T> @NotNull T value(@NotNull Either<? extends T, ? extends T> either) {
return either.map(Function.identity(), Function.identity());
}
}
Loading