commit
7755843923
@ -0,0 +1,9 @@
|
||||
# Set default behaviour, in case users don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files we want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.java text
|
||||
*.xml text
|
||||
*.yml text
|
||||
README.md text
|
@ -0,0 +1,34 @@
|
||||
# Maven generated files
|
||||
target
|
||||
*.jar
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# Mac OSX generated files
|
||||
.DS_Store
|
||||
|
||||
# Eclipse generated files
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
|
||||
# IntelliJ IDEA
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
# Vim generated files
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# XCode 3 and 4 generated files
|
||||
*.mode1
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.perspective
|
||||
*.perspectivev3
|
||||
*.pbxuser
|
||||
*.xcworkspace
|
||||
xcuserdata
|
||||
*class
|
||||
|
||||
# CrowdIn
|
||||
Commons/core/src/main/i18n/translations/*
|
@ -0,0 +1,95 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>tc.oc</groupId>
|
||||
<artifactId>api-parent</artifactId>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<version>1.11-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>API</name>
|
||||
<description>ProjectAres API layer</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- Our stuff -->
|
||||
|
||||
<dependency>
|
||||
<groupId>tc.oc</groupId>
|
||||
<artifactId>util-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Network stuff -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.http-client</groupId>
|
||||
<artifactId>google-http-client</artifactId>
|
||||
<version>1.18.0-rc</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.http-client</groupId>
|
||||
<artifactId>google-http-client-gson</artifactId>
|
||||
<version>1.18.0-rc</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.damnhandy</groupId>
|
||||
<artifactId>handy-uri-templates</artifactId>
|
||||
<version>2.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rabbitmq</groupId>
|
||||
<artifactId>amqp-client</artifactId>
|
||||
<version>3.3.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Testing -->
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/resources/</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>tc.oc:util-core</include>
|
||||
|
||||
<include>com.google.http-client:google-http-client</include>
|
||||
<include>com.google.http-client:google-http-client-gson</include>
|
||||
<include>com.damnhandy:handy-uri-templates</include>
|
||||
<include>com.rabbitmq:amqp-client</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,48 @@
|
||||
package tc.oc.api;
|
||||
|
||||
import tc.oc.api.connectable.ConnectablesManifest;
|
||||
import tc.oc.api.document.DocumentsManifest;
|
||||
import tc.oc.api.engagement.EngagementModelManifest;
|
||||
import tc.oc.api.games.GameModelManifest;
|
||||
import tc.oc.api.maps.MapModelManifest;
|
||||
import tc.oc.api.match.MatchModelManifest;
|
||||
import tc.oc.api.message.MessagesManifest;
|
||||
import tc.oc.api.model.ModelsManifest;
|
||||
import tc.oc.api.punishments.PunishmentModelManifest;
|
||||
import tc.oc.api.reports.ReportModelManifest;
|
||||
import tc.oc.api.serialization.SerializationManifest;
|
||||
import tc.oc.api.servers.ServerModelManifest;
|
||||
import tc.oc.api.sessions.SessionModelManifest;
|
||||
import tc.oc.api.tourney.TournamentModelManifest;
|
||||
import tc.oc.api.trophies.TrophyModelManifest;
|
||||
import tc.oc.api.users.UserModelManifest;
|
||||
import tc.oc.api.whispers.WhisperModelManifest;
|
||||
import tc.oc.commons.core.inject.HybridManifest;
|
||||
import tc.oc.commons.core.logging.LoggingManifest;
|
||||
|
||||
public final class ApiManifest extends HybridManifest {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new LoggingManifest()); // Load this right away, so we don't get log spam
|
||||
|
||||
publicBinder().install(new SerializationManifest());
|
||||
install(new DocumentsManifest());
|
||||
install(new MessagesManifest());
|
||||
install(new ModelsManifest());
|
||||
install(new ConnectablesManifest());
|
||||
|
||||
install(new ServerModelManifest());
|
||||
install(new UserModelManifest());
|
||||
install(new SessionModelManifest());
|
||||
install(new GameModelManifest());
|
||||
install(new ReportModelManifest());
|
||||
install(new PunishmentModelManifest());
|
||||
install(new MapModelManifest());
|
||||
install(new MatchModelManifest());
|
||||
install(new EngagementModelManifest());
|
||||
install(new WhisperModelManifest());
|
||||
install(new TrophyModelManifest());
|
||||
install(new TournamentModelManifest());
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package tc.oc.api.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
/**
|
||||
* Generic annotation for something that requires an API connection,
|
||||
* and should be ommitted or cause an error if not connected.
|
||||
*
|
||||
* (maybe we should make that distinction explicit?)
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ApiRequired {}
|
@ -0,0 +1,19 @@
|
||||
package tc.oc.api.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import tc.oc.api.docs.virtual.Document;
|
||||
|
||||
/**
|
||||
* Anything descended from {@link Document} can use this annotation to indicate that a method,
|
||||
* field, or entire class/interface should be included in serialization.
|
||||
* Applying it to a class is equivalent to applying it to every method declared in that class.
|
||||
*
|
||||
* Serialized methods must return a value and take no parameters. The returned value will be
|
||||
* serialized using the method name.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Serialize {
|
||||
boolean value() default true;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package tc.oc.api.config;
|
||||
|
||||
public interface ApiConfiguration {
|
||||
String primaryQueueName();
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package tc.oc.api.config;
|
||||
|
||||
public final class ApiConstants {
|
||||
private ApiConstants() {}
|
||||
|
||||
public static final int PROTOCOL_VERSION = 4;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package tc.oc.api.connectable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import tc.oc.minecraft.api.event.Activatable;
|
||||
import tc.oc.commons.core.plugin.PluginFacet;
|
||||
|
||||
/**
|
||||
* Service that needs to be connected and disconnected along with the API.
|
||||
*
|
||||
* Use a {@link ConnectableBinder} to register these.
|
||||
*
|
||||
* TODO: This should probably extend {@link PluginFacet},
|
||||
* but to do that, API needs to be able to find the services bound in other plugins.
|
||||
*/
|
||||
public interface Connectable extends Activatable {
|
||||
default void connect() throws IOException {};
|
||||
default void disconnect() throws IOException {};
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package tc.oc.api.connectable;
|
||||
|
||||
import com.google.inject.Binder;
|
||||
import tc.oc.commons.core.inject.SetBinder;
|
||||
|
||||
public class ConnectableBinder extends SetBinder<Connectable> {
|
||||
public ConnectableBinder(Binder binder) {
|
||||
super(binder);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package tc.oc.api.connectable;
|
||||
|
||||
import tc.oc.commons.core.inject.HybridManifest;
|
||||
import tc.oc.commons.core.plugin.PluginFacetBinder;
|
||||
|
||||
public class ConnectablesManifest extends HybridManifest {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindAndExpose(Connector.class);
|
||||
new PluginFacetBinder(binder())
|
||||
.add(Connector.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package tc.oc.api.connectable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import tc.oc.commons.core.exception.ExceptionHandler;
|
||||
import tc.oc.commons.core.logging.Loggers;
|
||||
import tc.oc.commons.core.plugin.PluginFacet;
|
||||
import tc.oc.commons.core.util.ExceptionUtils;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static tc.oc.commons.core.IterableUtils.reverseForEach;
|
||||
import static tc.oc.commons.core.exception.LambdaExceptionUtils.rethrowConsumer;
|
||||
|
||||
@Singleton
|
||||
public class Connector implements PluginFacet {
|
||||
|
||||
protected final Logger logger;
|
||||
private final ExceptionHandler exceptionHandler;
|
||||
private final Set<Connectable> services;
|
||||
private boolean connected;
|
||||
|
||||
@Inject
|
||||
Connector(Loggers loggers, ExceptionHandler exceptionHandler, Set<Connectable> services) {
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
this.services = services;
|
||||
this.logger = loggers.get(getClass());
|
||||
}
|
||||
|
||||
private void connect(Connectable service) throws IOException {
|
||||
if(service.isActive()) {
|
||||
logger.fine(() -> "Connecting " + service.getClass().getName());
|
||||
service.connect();
|
||||
}
|
||||
}
|
||||
|
||||
private void disconnect(Connectable service) throws IOException {
|
||||
if(service.isActive()) {
|
||||
logger.fine(() -> "Disconnecting " + service.getClass().getName());
|
||||
service.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
checkState(!connected, "already connected");
|
||||
connected = true;
|
||||
logger.fine(() -> "Connecting all services");
|
||||
ExceptionUtils.propagate(() -> services.forEach(rethrowConsumer(this::connect)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
checkState(connected, "not connected");
|
||||
connected = false;
|
||||
logger.fine(() -> "Disconnecting all services");
|
||||
reverseForEach(services, service -> exceptionHandler.run(() -> disconnect(service)));
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
import tc.oc.api.serialization.Pretty;
|
||||
|
||||
/**
|
||||
* Implements some boilerplate stuff for {@link Model}
|
||||
*/
|
||||
public abstract class AbstractModel implements Model {
|
||||
|
||||
protected @Inject @Pretty Gson prettyGson;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(this == o)
|
||||
return true;
|
||||
if(!(o instanceof Model))
|
||||
return false;
|
||||
|
||||
return _id().equals(((Model) o)._id());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return _id().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(prettyGson == null) return super.toString();
|
||||
|
||||
try {
|
||||
return prettyGson.toJson(this);
|
||||
} catch(Exception e) {
|
||||
return super.toString() + " (exception trying to inspect fields: " + e + ")";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
@Serialize
|
||||
public interface Arena extends Model {
|
||||
@Nonnull String game_id();
|
||||
@Nonnull String datacenter();
|
||||
int num_playing();
|
||||
int num_queued();
|
||||
@Nullable String next_server_id();
|
||||
|
||||
@Override @Serialize(false)
|
||||
default String toShortString() {
|
||||
return game_id() + "[" + datacenter() + "]";
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import java.time.Instant;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.DeletableModel;
|
||||
|
||||
public class BasicDeletableModel extends BasicModel implements DeletableModel {
|
||||
|
||||
@Serialize private Instant died_at;
|
||||
|
||||
@Override public @Nullable Instant died_at() {
|
||||
return died_at;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dead() {
|
||||
return died_at() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alive() {
|
||||
return died_at() == null;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
/**
|
||||
* Implements {@link Model#_id()} as a public field.
|
||||
*/
|
||||
public class BasicModel extends AbstractModel {
|
||||
|
||||
@Serialize public String _id;
|
||||
|
||||
public BasicModel() {
|
||||
}
|
||||
|
||||
public BasicModel(String _id) {
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String _id() {
|
||||
return _id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return _id;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.docs.virtual.DeathDoc;
|
||||
|
||||
public interface Death extends DeathDoc.Complete {}
|
@ -0,0 +1,16 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.team.Team;
|
||||
import tc.oc.api.docs.virtual.MatchDoc;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
@Serialize
|
||||
public interface Entrant extends Model {
|
||||
@Nonnull Team team();
|
||||
@Nonnull List<PlayerId> members();
|
||||
@Nonnull List<MatchDoc> matches();
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
import tc.oc.api.docs.virtual.ServerDoc;
|
||||
|
||||
@Serialize
|
||||
public interface Game extends Model {
|
||||
@Nonnull String name();
|
||||
int priority();
|
||||
@Nonnull ServerDoc.Visibility visibility();
|
||||
|
||||
@Override @Serialize(false)
|
||||
default String toShortString() {
|
||||
return name();
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.MapDoc;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Serialize
|
||||
public class MapRating {
|
||||
public final String player_id;
|
||||
public final @Nullable String map_id;
|
||||
public final String map_name;
|
||||
public final String map_version;
|
||||
public final int score;
|
||||
public final String comment;
|
||||
|
||||
public MapRating(UserId player, MapDoc map, int score, String comment) {
|
||||
this.player_id = player.player_id();
|
||||
this.map_id = map._id();
|
||||
this.map_name = map.name();
|
||||
this.map_version = map.version().toString();
|
||||
this.score = score;
|
||||
this.comment = comment;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
public enum MatchState {
|
||||
IDLE,
|
||||
STARTING,
|
||||
HUDDLE,
|
||||
RUNNING,
|
||||
FINISHED
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import java.time.Instant;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Serialize
|
||||
public interface Objective extends Model {
|
||||
|
||||
@Nonnull String name();
|
||||
@Nonnull String type();
|
||||
@Nonnull String feature_id();
|
||||
@Nonnull Instant date();
|
||||
@Nonnull String match_id();
|
||||
@Nonnull String server_id();
|
||||
@Nonnull String family();
|
||||
@Nullable Double x();
|
||||
@Nullable Double y();
|
||||
@Nullable Double z();
|
||||
@Nullable String team();
|
||||
@Nullable String player();
|
||||
|
||||
@Serialize
|
||||
interface Colored extends Objective {
|
||||
@Nonnull String color();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface DestroyableDestroy extends Objective {
|
||||
default String type() { return "destroyable_destroy"; }
|
||||
int blocks_broken();
|
||||
double blocks_broken_percentage();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface CoreBreak extends Objective {
|
||||
default String type() { return "core_break"; }
|
||||
@Nonnull String material();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface FlagCapture extends Colored {
|
||||
default String type() { return "flag_capture"; }
|
||||
@Nullable String net_id();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface WoolPlace extends Colored {
|
||||
default String type() { return "wool_place"; }
|
||||
}
|
||||
|
||||
@Override @Serialize(false)
|
||||
default String toShortString() {
|
||||
return name() + "[" + type() + "]";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.time.Instant;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
import tc.oc.api.model.ModelName;
|
||||
|
||||
public interface Participation {
|
||||
interface Partial extends Model {} // Partials always have _id()
|
||||
|
||||
@Serialize
|
||||
interface Start extends Partial {
|
||||
@Nonnull Instant start();
|
||||
@Nullable String team_id();
|
||||
@Nullable String league_team_id();
|
||||
@Nonnull String player_id();
|
||||
@Nonnull String family();
|
||||
@Nonnull String match_id();
|
||||
@Nonnull String server_id();
|
||||
@Nonnull String session_id();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface Finish extends Partial {
|
||||
@Nullable Instant end();
|
||||
}
|
||||
|
||||
@ModelName("Participation")
|
||||
interface Complete extends Start, Finish {}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.CompetitorDoc;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
/**
|
||||
* Subclass of {@link UserId} that adds a {@link #username()} field, which contains
|
||||
* the most recently seen username for the player. It also extends {@link Model},
|
||||
* so the {@link #_id()} field is available.
|
||||
*
|
||||
* This class is used to pass an ID and username around together, so that it can both be
|
||||
* displayed and used in the DB (like we used to be able to do with usernames alone).
|
||||
*/
|
||||
@Serialize
|
||||
public interface PlayerId extends UserId, Model, CompetitorDoc {
|
||||
@Nonnull String username();
|
||||
|
||||
@Override @Serialize(false)
|
||||
default String toShortString() {
|
||||
return username();
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.docs.virtual.PunishmentDoc;
|
||||
|
||||
public interface Punishment extends PunishmentDoc.Complete {}
|
@ -0,0 +1,5 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.docs.virtual.ReportDoc;
|
||||
|
||||
public interface Report extends ReportDoc.Complete {}
|
@ -0,0 +1,82 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
public class SemanticVersion {
|
||||
protected final int major;
|
||||
protected final int minor;
|
||||
protected final int patch;
|
||||
|
||||
public SemanticVersion(int major, int minor, int patch) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
}
|
||||
|
||||
public int major() {
|
||||
return this.major;
|
||||
}
|
||||
|
||||
public int minor() {
|
||||
return this.minor;
|
||||
}
|
||||
|
||||
public int patch() {
|
||||
return this.patch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(patch == 0) {
|
||||
return major + "." + minor;
|
||||
} else {
|
||||
return major + "." + minor + "." + patch;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the major versions match and the minor version
|
||||
* and patch levels are less or equal to the given version
|
||||
*/
|
||||
public boolean isNoNewerThan(SemanticVersion spec) {
|
||||
return this.major == spec.major &&
|
||||
(this.minor < spec.minor ||
|
||||
(this.minor == spec.minor &&
|
||||
this.patch <= spec.patch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the major versions match and the minor version
|
||||
* and patch levels are greater than the given version
|
||||
*/
|
||||
public boolean isNewerThan(SemanticVersion spec) {
|
||||
return this.major == spec.major &&
|
||||
(this.minor > spec.minor ||
|
||||
(this.minor == spec.minor &&
|
||||
this.patch > spec.patch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the major versions match and the minor version
|
||||
* and patch levels are greater or equal to the given version
|
||||
*/
|
||||
public boolean isNoOlderThan(SemanticVersion spec) {
|
||||
return this.major == spec.major &&
|
||||
(this.minor > spec.minor ||
|
||||
(this.minor == spec.minor &&
|
||||
this.patch >= spec.patch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the major versions match and the minor version
|
||||
* and patch levels are less than the given version
|
||||
*/
|
||||
public boolean isOlderThan(SemanticVersion spec) {
|
||||
return this.major == spec.major &&
|
||||
(this.minor < spec.minor ||
|
||||
(this.minor == spec.minor &&
|
||||
this.patch < spec.patch));
|
||||
}
|
||||
|
||||
public int[] toArray() {
|
||||
return new int[] {major, minor, patch};
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.docs.virtual.ServerDoc;
|
||||
|
||||
public interface Server extends ServerDoc.Complete {}
|
@ -0,0 +1,5 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.docs.virtual.SessionDoc;
|
||||
|
||||
public interface Session extends SessionDoc.Complete {}
|
@ -0,0 +1,56 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SimplePlayerId extends SimpleUserId implements PlayerId {
|
||||
|
||||
@Serialize private String _id;
|
||||
@Serialize private String username;
|
||||
|
||||
public SimplePlayerId(String _id, String player_id, String username) {
|
||||
super(player_id);
|
||||
this._id = checkNotNull(_id);
|
||||
this.username = checkNotNull(username);
|
||||
}
|
||||
|
||||
public SimplePlayerId(PlayerId playerId) {
|
||||
this(playerId._id(), playerId.player_id(), playerId.username());
|
||||
}
|
||||
|
||||
/** For deserialization only */
|
||||
protected SimplePlayerId() {
|
||||
super();
|
||||
this._id = this.username = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link SimplePlayerId} equal to the given {@link PlayerId}
|
||||
*/
|
||||
public static SimplePlayerId copyOf(PlayerId playerId) {
|
||||
return playerId.getClass().equals(SimplePlayerId.class) ? (SimplePlayerId) playerId
|
||||
: new SimplePlayerId(playerId);
|
||||
}
|
||||
|
||||
@Serialize
|
||||
@Override
|
||||
public String _id() {
|
||||
return _id;
|
||||
}
|
||||
|
||||
@Serialize
|
||||
@Override
|
||||
public String username() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() +
|
||||
"{_id=" + _id() +
|
||||
" player_id=" + player_id() +
|
||||
" username=" + username() +
|
||||
"}";
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SimpleUserId implements UserId {
|
||||
|
||||
@Serialize private String player_id;
|
||||
|
||||
public SimpleUserId(String player_id) {
|
||||
this.player_id = checkNotNull(player_id);
|
||||
}
|
||||
|
||||
/** For deserialization only */
|
||||
protected SimpleUserId() {
|
||||
this.player_id = null;
|
||||
}
|
||||
|
||||
public static SimpleUserId copyOf(UserId userId) {
|
||||
return userId.getClass().equals(SimpleUserId.class) ? (SimpleUserId) userId
|
||||
: new SimpleUserId(userId.player_id());
|
||||
}
|
||||
|
||||
@Serialize
|
||||
@Override
|
||||
public String player_id() {
|
||||
return this.player_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public boolean equals(Object obj) {
|
||||
return obj instanceof UserId && ((UserId) obj).player_id().equals(this.player_id());
|
||||
}
|
||||
|
||||
@Override
|
||||
final public int hashCode() {
|
||||
return this.player_id().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() +
|
||||
"{player_id=" + player_id() + "}";
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.time.Instant;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
@Serialize
|
||||
public interface Ticket extends Model {
|
||||
@Nonnull PlayerId user();
|
||||
@Nonnull String arena_id();
|
||||
@Nullable String server_id();
|
||||
@Nullable Instant dispatched_at();
|
||||
|
||||
@Override @Serialize(false)
|
||||
default String toShortString() {
|
||||
return user().toShortString();
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Document;
|
||||
import tc.oc.api.docs.virtual.MapDoc;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
@Serialize
|
||||
public interface Tournament extends Model {
|
||||
|
||||
String name();
|
||||
Instant start();
|
||||
Instant end();
|
||||
|
||||
int min_players_per_match();
|
||||
int max_players_per_match();
|
||||
|
||||
List<team.Id> accepted_teams();
|
||||
|
||||
default List<String> acceptedTeamNames() {
|
||||
return Lists.transform(accepted_teams(), team.Id::name);
|
||||
}
|
||||
|
||||
/**
|
||||
* game type -> [map ids]
|
||||
*
|
||||
* Key is some kind of string identifying game type e.g. "core", "wool", "tdm"
|
||||
*
|
||||
* Value is a set of {@link MapDoc#_id()}
|
||||
*/
|
||||
List<MapClassification> map_classifications();
|
||||
|
||||
@Serialize
|
||||
interface MapClassification extends Document {
|
||||
String name();
|
||||
Set<String> map_ids();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Serialize
|
||||
public interface Trophy extends Model {
|
||||
|
||||
@Nonnull String name();
|
||||
@Nonnull String description();
|
||||
|
||||
@Override @Serialize(false)
|
||||
default String toShortString() {
|
||||
return _id();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.docs.virtual.UserDoc;
|
||||
|
||||
public interface User extends UserDoc.Login {}
|
@ -0,0 +1,21 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.UserDoc;
|
||||
|
||||
/**
|
||||
* Wrapper for user.player_id values. It identifies a player stored in the DB,
|
||||
* but contains no username, which has a few ramifications:
|
||||
*
|
||||
* - You cannot display this to the user
|
||||
* - You cannot directly associate this with an online player
|
||||
*
|
||||
* Doing either of the above requires a lookup in the DB or PlayerIdMap.
|
||||
* See the subclasses of this class for more explanation.
|
||||
*/
|
||||
@Serialize
|
||||
public interface UserId extends UserDoc.Partial {
|
||||
@Nonnull String player_id();
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.WhisperDoc;
|
||||
|
||||
@Serialize
|
||||
public interface Whisper extends WhisperDoc.Complete {}
|
@ -0,0 +1,28 @@
|
||||
package tc.oc.api.docs;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.virtual.Model;
|
||||
import tc.oc.api.docs.virtual.PartialModel;
|
||||
|
||||
public interface team {
|
||||
|
||||
interface Partial extends PartialModel {}
|
||||
|
||||
@Serialize
|
||||
interface Id extends Partial, Model {
|
||||
@Nonnull String name();
|
||||
@Nonnull String name_normalized();
|
||||
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface Members extends Partial {
|
||||
@Nonnull PlayerId leader();
|
||||
@Nonnull List<PlayerId> members();
|
||||
}
|
||||
|
||||
interface Team extends Id, Members {}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
public class BasicDocument implements Document {
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
public interface CompetitorDoc extends Model {}
|
@ -0,0 +1,50 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import java.time.Instant;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.PlayerId;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface DeathDoc {
|
||||
|
||||
interface Partial extends PartialModel {}
|
||||
|
||||
@Serialize
|
||||
interface Complete extends Base {
|
||||
@Nonnull PlayerId victim();
|
||||
@Nullable PlayerId killer();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface Creation extends Base {
|
||||
@Nonnull String victim();
|
||||
@Nullable String killer();
|
||||
int raindrops();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface Base extends Model, Partial {
|
||||
double x();
|
||||
double y();
|
||||
double z();
|
||||
@Nonnull String server_id();
|
||||
@Nonnull String match_id();
|
||||
@Nonnull String family();
|
||||
@Nonnull Instant date();
|
||||
@Nullable String entity_killer();
|
||||
@Nullable String block_killer();
|
||||
@Nullable Boolean player_killer();
|
||||
@Nullable Boolean teamkill();
|
||||
@Nullable String victim_class();
|
||||
@Nullable String killer_class();
|
||||
@Nullable Double distance();
|
||||
@Nullable Boolean enchanted();
|
||||
@Nullable String weapon();
|
||||
@Nullable String from();
|
||||
@Nullable String action();
|
||||
@Nullable String cause();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import java.time.Instant;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
|
||||
public interface DeletableModel extends Model {
|
||||
@Serialize @Nullable Instant died_at();
|
||||
boolean dead();
|
||||
boolean alive();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
|
||||
@Serialize
|
||||
public interface DeployInfo extends Document {
|
||||
@Serialize
|
||||
interface Version extends Document {
|
||||
String branch();
|
||||
String commit();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface Nextgen extends Document {
|
||||
String path();
|
||||
Version version();
|
||||
}
|
||||
|
||||
Nextgen nextgen();
|
||||
Map<String, Version> packages();
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.document.DocumentMeta;
|
||||
import tc.oc.api.document.DocumentRegistry;
|
||||
import tc.oc.api.message.Message;
|
||||
import tc.oc.api.document.DocumentSerializer;
|
||||
|
||||
/**
|
||||
* Base interface for serializable API documents, including documents stored
|
||||
* in the database ({@link Model}s and {@link PartialModel}s) and directives
|
||||
* exchanged through the API ({@link Message}s).
|
||||
*
|
||||
* {@link Document}s are serialized differently than normal objects. No fields
|
||||
* are included in serialization by default. Rather, the {@link Serialize}
|
||||
* annotation is used to mark serialized fields. Methods can also be annotated
|
||||
* with {@link Serialize} to mark them as getters or setters. Getter methods
|
||||
* must return a value and take no parameters, while setter methods must take
|
||||
* exactly one parameter. If a class or interface is annotated with
|
||||
* {@link Serialize}, all fields and methods declared in that class will be
|
||||
* included in serialization.
|
||||
*
|
||||
* {@link DocumentSerializer} is responsible for serializing and deserializing
|
||||
* {@link Document}s. It uses {@link DocumentRegistry} to get a {@link DocumentMeta}
|
||||
* for a class, which knows about all the getters and setters. Registration
|
||||
* happens on demand and is entirely automatic.
|
||||
*/
|
||||
public interface Document {}
|
@ -0,0 +1,48 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.SemanticVersion;
|
||||
import tc.oc.api.model.ModelName;
|
||||
|
||||
@Serialize
|
||||
@ModelName("Engagement")
|
||||
public interface EngagementDoc extends Model {
|
||||
String family_id();
|
||||
String server_id();
|
||||
String user_id();
|
||||
MapDoc.Genre genre();
|
||||
|
||||
String match_id();
|
||||
Instant match_started_at();
|
||||
Instant match_joined_at();
|
||||
@Nullable Instant match_finished_at();
|
||||
@Nullable Duration match_length();
|
||||
@Nullable Duration match_participation();
|
||||
|
||||
boolean committed();
|
||||
|
||||
String map_id();
|
||||
SemanticVersion map_version();
|
||||
|
||||
int player_count();
|
||||
int competitor_count();
|
||||
|
||||
@Nullable String team_pgm_id();
|
||||
@Nullable Integer team_size();
|
||||
@Nullable Duration team_participation();
|
||||
|
||||
@Nullable Integer rank();
|
||||
@Nullable Integer tied_count();
|
||||
|
||||
enum ForfeitReason {
|
||||
ABSENCE,
|
||||
PARTICIPATION_PERCENT,
|
||||
CUMULATIVE_ABSENCE,
|
||||
CONTINUOUS_ABSENCE
|
||||
}
|
||||
@Nullable ForfeitReason forfeit_reason();
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import tc.oc.api.docs.BasicModel;
|
||||
import tc.oc.api.docs.SemanticVersion;
|
||||
|
||||
public abstract class EngagementDocBase extends BasicModel implements EngagementDoc {
|
||||
|
||||
protected final MatchDoc matchDocument;
|
||||
|
||||
protected EngagementDocBase(String _id, MatchDoc matchDocument) {
|
||||
super(_id);
|
||||
this.matchDocument = matchDocument;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String server_id() {
|
||||
return matchDocument.server_id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String family_id() {
|
||||
return matchDocument.family_id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapDoc.Genre genre() {
|
||||
return matchDocument.map().genre();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String match_id() {
|
||||
return matchDocument._id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant match_started_at() {
|
||||
return matchDocument.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Instant match_finished_at() {
|
||||
return matchDocument.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Duration match_length() {
|
||||
Instant start = matchDocument.start();
|
||||
Instant end = matchDocument.end();
|
||||
if(start != null && end != null) {
|
||||
return Duration.between(start, end);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String map_id() {
|
||||
return matchDocument.map()._id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SemanticVersion map_version() {
|
||||
return matchDocument.map().version();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int player_count() {
|
||||
return matchDocument.player_count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int competitor_count() {
|
||||
return matchDocument.competitors().size();
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.docs.SemanticVersion;
|
||||
import tc.oc.api.model.ModelName;
|
||||
|
||||
@Serialize
|
||||
@Nonnull
|
||||
@ModelName("Map")
|
||||
public interface MapDoc extends Model {
|
||||
String slug();
|
||||
String name();
|
||||
@Nullable String url();
|
||||
@Nullable Path path();
|
||||
Collection<String> images();
|
||||
SemanticVersion version();
|
||||
int min_players();
|
||||
int max_players();
|
||||
String objective();
|
||||
|
||||
enum Phase {
|
||||
DEVELOPMENT, PRODUCTION;
|
||||
public static final Phase DEFAULT = PRODUCTION;
|
||||
}
|
||||
Phase phase();
|
||||
|
||||
enum Edition {
|
||||
STANDARD, RANKED, TOURNAMENT;
|
||||
public static final Edition DEFAULT = STANDARD;
|
||||
}
|
||||
Edition edition();
|
||||
|
||||
enum Genre { OBJECTIVES, DEATHMATCH, OTHER }
|
||||
Genre genre();
|
||||
|
||||
enum Gamemode { tdm, ctw, ctf, dtc, dtm, ad, koth, blitz, rage, scorebox, arcade, gs, ffa, mixed, skywars, survival }
|
||||
Set<Gamemode> gamemode();
|
||||
|
||||
List<Team> teams();
|
||||
|
||||
Collection<UUID> author_uuids();
|
||||
Collection<UUID> contributor_uuids();
|
||||
|
||||
@Serialize
|
||||
interface Team extends Model {
|
||||
@Nonnull String name();
|
||||
|
||||
// Fields below shouldn't be nullable, but data is missing in some old match documents
|
||||
@Nullable Integer min_players();
|
||||
@Nullable Integer max_players();
|
||||
@Nullable ChatColor color();
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package tc.oc.api.docs.virtual;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.time.Instant;
|
||||
import tc.oc.api.annotations.Serialize;
|
||||
import tc.oc.api.model.ModelName;
|
||||
|
||||
@Serialize
|
||||
@ModelName(value = "Match", plural = "matches")
|
||||
public interface MatchDoc extends Model {
|
||||
String server_id();
|
||||
String family_id();
|
||||
|
||||
// Can be null if doc was generated by the API and the map is not in the DB
|
||||
MapDoc map();
|
||||
Collection<? extends Team> competitors();
|
||||
Collection<? extends Goal> objectives();
|
||||
|
||||
Instant load();
|
||||
@Nullable Instant start();
|
||||
@Nullable Instant end();
|
||||
@Nullable Instant unload();
|
||||
|
||||
boolean join_mid_match();
|
||||
int player_count();
|
||||
|
||||
Collection<String> winning_team_ids();
|
||||
Collection<String> winning_user_ids();
|
||||
|
||||
enum Mutation {
|
||||
BLITZ, UHC, EXPLOSIVES, NO_FALL, MOBS, STRENGTH, DOUBLE_JUMP, INVISIBILITY, LIGHTNING, RAGE, ELYTRA;
|
||||
}
|
||||
|
||||
Set<Mutation> mutations();
|
||||
|
||||
@Serialize
|
||||
interface Team extends MapDoc.Team, CompetitorDoc {
|
||||
@Nullable Integer size(); // Shouldn't be nullable, but data is missing in some old match documents
|
||||
String league_team_id();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface Goal extends Model {
|
||||
String type();
|
||||
String name();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface OwnedGoal extends Goal {
|
||||
@Nullable String owner_id();
|
||||
@Nullable String owner_name();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface IncrementalGoal extends Goal {
|
||||
double completion();
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface TouchableGoal extends OwnedGoal {
|
||||
Collection<? extends Proximity> proximities();
|
||||
|
||||
@Serialize
|
||||
interface Proximity extends Model {
|
||||
boolean touched();
|
||||
@Nullable Metric metric();
|
||||
double distance();
|
||||
|
||||
enum Metric {
|
||||
CLOSEST_PLAYER, CLOSEST_PLAYER_HORIZONTAL,
|
||||
CLOSEST_BLOCK, CLOSEST_BLOCK_HORIZONTAL,
|
||||
CLOSEST_KILL, CLOSEST_KILL_HORIZONTAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serialize
|
||||
interface Destroyable extends TouchableGoal, IncrementalGoal {
|
||||
int total_blocks();
|
||||
int breaks_required();
|
||||
int breaks();
|
||||
}
|
||||
}
|