Committing annotation-processor v2 experimentation

This commit is contained in:
Collin Smith
2020-12-15 12:07:38 -08:00
parent 5ee10cdfcc
commit fa819b0b9b
29 changed files with 1141 additions and 0 deletions

View File

@ -9,6 +9,11 @@ include 'excel:annotations'
include 'excel:excel-test'
include 'excel:annotation-processor'
include 'table:core'
include 'table:annotations'
include 'table:integration'
include 'table:annotation-processor'
include 'server:bnls'
include 'server:bncs'
include 'server:mcp'

View File

@ -0,0 +1,10 @@
dependencies {
annotationProcessor "com.google.auto.service:auto-service:1.0-rc7"
implementation "com.google.auto.service:auto-service-annotations:1.0-rc7"
implementation "com.squareup:javapoet:1.13.0"
api project(':table:annotations')
api project(':table:core')
implementation "org.apache.commons:commons-text:1.8"
}

View File

@ -0,0 +1,12 @@
package com.riiablo.table.annotation;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
final class Constants {
private Constants() {}
static final ClassName STRING = ClassName.get(String.class);
static final TypeName[] PRIMARY_KEY_TYPES = { TypeName.INT, STRING };
}

View File

@ -0,0 +1,85 @@
package com.riiablo.table.annotation;
import java.lang.annotation.Annotation;
import java.util.Objects;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.text.TextStringBuilder;
class Context {
final ProcessingEnvironment processingEnvironment;
final Messager messager;
final Types typeUtils;
final Elements elementUtils;
Context(ProcessingEnvironment processingEnvironment) {
this.processingEnvironment = processingEnvironment;
messager = processingEnvironment.getMessager();
typeUtils = processingEnvironment.getTypeUtils();
elementUtils = processingEnvironment.getElementUtils();
}
void log(
Diagnostic.Kind kind,
Element element,
AnnotationMirror annotationMirror,
AnnotationValue annotationValue,
String message, Object... args) {
TextStringBuilder builder = new TextStringBuilder(message);
builder.replaceAll("{element}", Objects.toString(element));
builder.replaceAll("{annotationMirror}", Objects.toString(annotationMirror));
builder.replaceAll("{annotationValue}", Objects.toString(annotationValue));
for (Object arg : args) {
if (arg instanceof Class && Annotation.class.isAssignableFrom((Class<?>) arg)) {
builder.replaceFirst("{}", "@" + ((Class<?>) arg).getSimpleName());
} else if (arg instanceof Element) {
builder.replaceFirst("{}", ((Element) arg).getSimpleName().toString());
} else if (arg != null && arg.getClass().isArray()) {
builder.replaceFirst("{}", ArrayUtils.toString(arg));
} else {
builder.replaceFirst("{}", Objects.toString(arg));
}
}
messager.printMessage(kind, builder);
}
void error(String message, Object... args) {
log(Diagnostic.Kind.ERROR, null, null, null, message, args);
}
void error(Element element, String message, Object... args) {
log(Diagnostic.Kind.ERROR, element, null, null, message, args);
}
void error(Element element, AnnotationMirror annotationMirror, String message, Object... args) {
log(Diagnostic.Kind.ERROR, element, annotationMirror, null, message, args);
}
void error(Element element, AnnotationMirror annotationMirror, AnnotationValue annotationValue, String message, Object... args) {
log(Diagnostic.Kind.ERROR, element, annotationMirror, annotationValue, message, args);
}
void warn(String message, Object... args) {
log(Diagnostic.Kind.WARNING, null, null, null, message, args);
}
void warn(Element element, String message, Object... args) {
log(Diagnostic.Kind.WARNING, element, null, null, message, args);
}
void warn(Element element, AnnotationMirror annotationMirror, String message, Object... args) {
log(Diagnostic.Kind.WARNING, element, annotationMirror, null, message, args);
}
void warn(Element element, AnnotationMirror annotationMirror, AnnotationValue annotationValue, String message, Object... args) {
log(Diagnostic.Kind.WARNING, element, annotationMirror, annotationValue, message, args);
}
}

View File

@ -0,0 +1,59 @@
package com.riiablo.table.annotation;
import com.squareup.javapoet.ClassName;
import java.util.Collection;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
class PrimaryKeyElement {
static PrimaryKeyElement find(
Context context,
TypeElement element,
Collection<VariableElement> elements
) {
VariableElement firstAcceptableElement = null, primaryKeyElement = null;
for (VariableElement e : elements) {
if (firstAcceptableElement == null
&& ArrayUtils.contains(Constants.PRIMARY_KEY_TYPES, ClassName.get(e.asType()))) {
firstAcceptableElement = e;
}
PrimaryKey annotation = e.getAnnotation(PrimaryKey.class);
if (annotation != null) {
if (primaryKeyElement == null) {
primaryKeyElement = e;
} else {
context.error(e, "{} already declared as {}", primaryKeyElement, PrimaryKey.class);
}
}
}
if (primaryKeyElement == null) {
if (firstAcceptableElement == null) {
context.error(element, "{element} did not declare any {}", PrimaryKey.class);
return null;
}
context.warn(element, "{element} did not declare any {}, using {}",
PrimaryKey.class, firstAcceptableElement);
primaryKeyElement = firstAcceptableElement;
}
return new PrimaryKeyElement(primaryKeyElement);
}
final VariableElement element;
PrimaryKeyElement(VariableElement element) {
this.element = element;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("element", element)
.toString();
}
}

View File

@ -0,0 +1,75 @@
package com.riiablo.table.annotation;
import com.squareup.javapoet.ClassName;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import org.apache.commons.lang3.builder.ToStringBuilder;
final class SchemaElement {
static SchemaElement get(
Context context,
Element element) {
TypeElement typeElement = (TypeElement) element;
List<VariableElement> columns = collectColumns(context, typeElement);
PrimaryKeyElement primaryKeyElement = PrimaryKeyElement.find(context, typeElement, columns);
// for (VariableElement e : columns) {
// System.out.println(e);
// }
TableElement tableElement = TableElement.get(context, typeElement);
SerializerElement serializerElement = SerializerElement.get(context, typeElement);
return new SchemaElement(typeElement, tableElement, serializerElement);
}
static List<VariableElement> collectColumns(
Context context,
TypeElement typeElement) {
List<VariableElement> columns = new ArrayList<>();
TypeElement superclassElement = typeElement;
for (;;) {
for (Element e : superclassElement.getEnclosedElements()) {
switch (e.getKind()) {
case FIELD:
columns.add((VariableElement) e);
break;
}
}
TypeMirror superclassMirror = superclassElement.getSuperclass();
superclassElement = (TypeElement) context.typeUtils.asElement(superclassMirror);
if (ClassName.OBJECT.equals(ClassName.get(superclassMirror))) {
break;
}
}
return columns;
}
final TypeElement element;
final TableElement tableElement;
final SerializerElement serializerElement;
SchemaElement(
TypeElement element,
TableElement tableElement,
SerializerElement serializerElement) {
this.element = element;
this.tableElement = tableElement;
this.serializerElement = serializerElement;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("element", element)
.append("tableElement", tableElement)
.append("serializerElement", serializerElement)
.toString();
}
}

View File

@ -0,0 +1,79 @@
package com.riiablo.table.annotation;
import com.google.auto.service.AutoService;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import org.apache.commons.lang3.ArrayUtils;
@AutoService(Processor.class)
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class SchemaProcessor extends AbstractProcessor {
static final Set<String> SUPPORTED_ANNOTATIONS;
static {
Set<String> set = new LinkedHashSet<>();
set.add(Schema.class.getCanonicalName());
set.add(PrimaryKey.class.getCanonicalName());
SUPPORTED_ANNOTATIONS = set;
}
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
}
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv
) {
final Context context = new Context(processingEnv);
for (Element element : roundEnv.getElementsAnnotatedWith(PrimaryKey.class)) {
VariableElement variableElement = (VariableElement) element;
TypeName typeName = ClassName.get(variableElement.asType());
if (!ArrayUtils.contains(Constants.PRIMARY_KEY_TYPES, typeName)) {
context.error(variableElement, "{} must be one of {}",
PrimaryKey.class, Constants.PRIMARY_KEY_TYPES);
}
}
for (Element element : roundEnv.getElementsAnnotatedWith(Schema.class)) {
if (element.getKind() != ElementKind.CLASS) {
context.error(element, "{} can only be applied to classes", Schema.class);
continue;
}
SchemaElement schemaElement = SchemaElement.get(context, element);
// if (schemaElement.serializerElement.serializerElement != null) {
// SerializerElement serializerElement = schemaElement.serializerElement;
// ExecutableElement readRecordElement = serializerElement.getMethod("readRecord");
// MethodSpec readRecord = MethodSpec
// .overriding(readRecordElement, serializerElement.declaredType, typeUtils)
// .build();
// System.out.println(readRecord);
// System.out.println(readRecord.parameters.get(0));
// System.out.println(readRecord.parameters.get(1));
// }
}
return true;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return SUPPORTED_ANNOTATIONS;
}
}

View File

@ -0,0 +1,5 @@
package com.riiablo.table.annotation;
final class SchemaProcessorUtils {
private SchemaProcessorUtils() {}
}

View File

@ -0,0 +1,85 @@
package com.riiablo.table.annotation;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;
import org.apache.commons.lang3.builder.ToStringBuilder;
final class SerializerElement {
static SerializerElement get(
Context context,
Element element
) {
Serializer annotation = element.getAnnotation(Serializer.class);
final TypeElement serializerElement, serializerImplElement;
final DeclaredType declaredType;
if (annotation == null) {
// Only need serializerElement if generating Serializer impl
serializerElement = context.elementUtils.getTypeElement(com.riiablo.table.Serializer.class.getCanonicalName());
declaredType = context.typeUtils.getDeclaredType(serializerElement, element.asType());
serializerImplElement = null;
} else {
// Only need serializerImplElement if @Serializer present
serializerImplElement = getSerializerImpl(context, annotation);
serializerElement = null;
declaredType = null;
}
return new SerializerElement(annotation, declaredType, serializerElement, serializerImplElement);
}
static TypeElement getSerializerImpl(
Context context,
Serializer annotation
) {
if (annotation == null) return null;
try {
Class<?> serializerImpl = annotation.value();
return context.elementUtils.getTypeElement(serializerImpl.getCanonicalName());
} catch (MirroredTypeException t) {
DeclaredType serializerImplMirror = (DeclaredType) t.getTypeMirror();
return (TypeElement) serializerImplMirror.asElement();
}
}
final Serializer annotation;
final DeclaredType declaredType;
final TypeElement serializerElement;
final TypeElement serializerImplElement;
SerializerElement(
Serializer annotation,
DeclaredType declaredType,
TypeElement serializerElement,
TypeElement serializerImplElement) {
this.annotation = annotation;
this.declaredType = declaredType;
this.serializerElement = serializerElement;
this.serializerImplElement = serializerImplElement;
}
ExecutableElement getMethod(CharSequence methodName) {
for (Element e : serializerElement.getEnclosedElements()) {
if (e.getKind() == ElementKind.METHOD) {
ExecutableElement methodElement = (ExecutableElement) e;
if (methodElement.getSimpleName().contentEquals(methodName)) {
return methodElement;
}
}
}
throw new AssertionError(serializerElement + " does not contain " + methodName);
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("annotation", annotation)
.append("declaredType", declaredType)
.append("serializerElement", serializerElement)
.append("serializerImplElement", serializerImplElement)
.toString();
}
}

View File

@ -0,0 +1,64 @@
package com.riiablo.table.annotation;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.MirroredTypeException;
import org.apache.commons.lang3.builder.ToStringBuilder;
final class TableElement {
static TableElement get(
Context context,
Element element
) {
Table annotation = element.getAnnotation(Table.class);
final TypeElement tableElement, tableImplElement;
if (annotation == null) {
// Only need tableElement if generating Table impl
tableElement = context.elementUtils.getTypeElement(com.riiablo.table.Table.class.getCanonicalName());
tableImplElement = null;
} else {
// Only need tableImplElement if @Table present
tableImplElement = getTableImpl(context, annotation);
tableElement = null;
}
return new TableElement(annotation, tableElement, tableImplElement);
}
static TypeElement getTableImpl(
Context context,
Table annotation
) {
if (annotation == null) return null;
try {
Class<?> tableImpl = annotation.value();
return context.elementUtils.getTypeElement(tableImpl.getCanonicalName());
} catch (MirroredTypeException t) {
DeclaredType tableImplMirror = (DeclaredType) t.getTypeMirror();
return (TypeElement) tableImplMirror.asElement();
}
}
final Table annotation;
final TypeElement tableElement; // Class<Table>
final TypeElement tableImplElement; // Class<? extends Table<?>>
TableElement(
Table annotation,
TypeElement tableElement,
TypeElement tableImplElement) {
this.annotation = annotation;
this.tableElement = tableElement;
this.tableImplElement = tableImplElement;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("annotation", annotation)
.append("tableElement", tableElement)
.append("tableImplElement", tableImplElement)
.toString();
}
}

View File

@ -0,0 +1,3 @@
dependencies {
api project(':table:core')
}

View File

@ -0,0 +1,55 @@
package com.riiablo.table.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that a field has a custom format when determining matching column
* names in the parent {@link Schema schema}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface Format {
/**
* Start index of {@link #format()} (inclusive).
*/
int startIndex() default 0;
/**
* End index of {@link #format()} (exclusive).
*/
int endIndex() default 0;
/**
* String format of column name, {@code ""} to use field name.
* <p>
* Examples:
* <ul>
* <li>{@code "class"}
* <li>{@code "Transform Color"}
* <li>{@code "Level%s"}
* <li>{@code "Skill %d"}
*/
String format() default "";
/**
* Index values of format in the case of non-numerical indexes.
* <p>
* Examples:
* <ul>
* <li>{@code {"", "(N)", "(H)"}}
* <li>{@code {"r", "g", "b"}}
* <li>{@code {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}}
*/
String[] values() default {};
/**
* Manually sets the column index. This property overrides all other
* properties. {@code -1} indicates that there is no custom column index.
*/
int columnIndex() default -1;
}

View File

@ -0,0 +1,16 @@
package com.riiablo.table.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that a field should be used as the primary key in a
* {@link Schema schema}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface PrimaryKey {}

View File

@ -0,0 +1,26 @@
package com.riiablo.table.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the specified type is a record schema.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Schema {
/**
* Offset of the first record.
*/
int offset() default 0;
/**
* Whether or not records are indexed in their natural ordering. Setting this
* will override any set {@link PrimaryKey primary key}.
*/
boolean indexed() default false;
}

View File

@ -0,0 +1,23 @@
package com.riiablo.table.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the specified {@link Schema schema} should use the given
* {@link #value() serializer} in lieu of generating one. The serializer
* implementation should have the schema set as its generic parameter.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Serializer {
/**
* A serializer implementation that should be used by this
* {@link Schema schema} in lieu of generating one.
*/
Class<? extends com.riiablo.table.Serializer<?>> value();
}

View File

@ -0,0 +1,23 @@
package com.riiablo.table.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that the specified {@link Schema schema} should use the given
* {@link #value() table} in lieu of generating one. The table implementation
* should have the schema set as its generic parameter.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Table {
/**
* A table implementation that should be used by this {@link Schema schema}
* in lieu of generating one.
*/
Class<? extends com.riiablo.table.Table<?>> value();
}

2
table/core/build.gradle Normal file
View File

@ -0,0 +1,2 @@
dependencies {
}

View File

@ -0,0 +1,10 @@
package com.riiablo.table;
public interface DataInput {
byte read8();
short read16();
int read32();
long read64();
boolean readBoolean();
String readString();
}

View File

@ -0,0 +1,10 @@
package com.riiablo.table;
public interface DataOutput {
void write8(int value);
void write16(int value);
void write32(int value);
void write64(long value);
void writeBoolean(boolean value);
void writeString(CharSequence chars);
}

View File

@ -0,0 +1,14 @@
package com.riiablo.table;
/**
* Defines behaviors necessary to serialize a record to and from a binary
* format.
*
* @param <T> record type
*/
public interface Serializer<T> {
void readRecord(T record, DataInput in);
void writeRecord(T record, DataOutput out);
boolean equals(T e1, T e2);
Iterable<Throwable> compare(T e1, T e2);
}

View File

@ -0,0 +1,9 @@
package com.riiablo.table;
/**
* Stores a set of records.
*
* @param <R> record type
*/
public interface Table<R> extends Iterable<R> {
}

View File

@ -0,0 +1,12 @@
sourceSets.main.java.srcDirs += compileJava.options.annotationProcessorGeneratedSourcesDirectory
idea.module.generatedSourceDirs += compileJava.options.annotationProcessorGeneratedSourcesDirectory
dependencies {
annotationProcessor project(':table:annotation-processor')
implementation project(':table:annotation-processor')
implementation project(':table:annotations')
}
dependencies {
testImplementation "junit:junit:4.12"
}

View File

@ -0,0 +1,94 @@
package com.riiablo.table.schema;
import com.riiablo.table.annotation.Format;
import com.riiablo.table.annotation.PrimaryKey;
@SuppressWarnings("unused")
public class ItemEntry {
@Override
public String toString() {
return name;
}
@PrimaryKey
public String code;
public String name;
public String namestr;
public boolean compactsave;
public int version;
public String alternateGfx;
public String type;
public String type2;
public int component;
public String flippyfile;
public String invfile;
public String uniqueinvfile;
public String setinvfile;
public int Transform;
public int InvTrans;
public int invwidth;
public int invheight;
public String dropsound;
public int dropsfxframe;
public boolean stackable;
public int minstack;
public int maxstack;
public int spawnstack;
public boolean useable;
public String usesound;
public int quest;
public boolean nodurability;
public int level;
public int levelreq;
public int mindam;
public int maxdam;
public int speed;
public int gemsockets;
public int gemapplytype;
public boolean PermStoreItem;
public boolean multibuy;
@Format(format = "Charsi%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] charsi;
@Format(format = "Gheed%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] gheed;
@Format(format = "Akara%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] akara;
@Format(format = "Fara%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] fara;
@Format(format = "Lysander%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] lysander;
@Format(format = "Drognan%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] drognan;
/**
* FIXME: Hratli mislabeled within tables as Hralti in many places -- may require custom code per
* sheet NOTE: This is the only discrepancy between these columns weapons: HraltiMin HraltiMax
* HraltiMagicMin HraltiMagicMax HratliMagicLvl armor: HraltiMin HraltiMax HraltiMagicMin
* HraltiMagicMax HratliMagicLvl misc: HraltiMin HraltiMax HraltiMagicMin HraltiMagicMax
* HraltiMagicLvl
*/
@Format(format = "Hralti%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] hratli;
@Format(format = "Alkor%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] alkor;
@Format(format = "Ormus%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] ormus;
@Format(format = "Elzix%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] elzix;
@Format(format = "Asheara%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] asheara;
@Format(format = "Halbu%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] halbu;
@Format(format = "Jamella%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] jamella;
@Format(format = "Malah%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] malah;
@Format(format = "Larzuk%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] larzuk;
@Format(format = "Drehya%s", values = {"Min", "Max", "MagicMin", "MagicMax", "MagicLvl"}, endIndex = 5)
public int[] drehya;
}

View File

@ -0,0 +1,226 @@
package com.riiablo.table.schema;
import com.riiablo.table.annotation.Format;
import com.riiablo.table.annotation.PrimaryKey;
import com.riiablo.table.annotation.Schema;
import com.riiablo.table.annotation.Serializer;
import com.riiablo.table.annotation.Table;
@Schema
@Table(MonStatsTableImpl.class)
@Serializer(MonStatsSerializerImpl.class)
@SuppressWarnings("unused")
public class MonStats {
@Override
public String toString() {
return NameStr;
}
@PrimaryKey
public String Id;
public int hcIdx;
public String BaseId;
public String NextInClass;
public int TransLvl;
public String NameStr;
public String MonStatsEx;
public String MonProp;
public String MonType;
public String AI;
public String DescStr;
public String Code;
public boolean enabled;
public boolean rangedtype;
public boolean placespawn;
public String spawn;
public int spawnx;
public int spawny;
public String spawnmode;
public String minion1;
public String minion2;
public boolean SetBoss;
public boolean BossXfer;
public int PartyMin;
public int PartyMax;
public int MinGrp;
public int MaxGrp;
public int sparsePopulate;
public int Velocity;
public int Run;
public int Rarity;
public String MonSound;
public String UMonSound;
public int threat;
public String MissA1;
public String MissA2;
public String MissS1;
public String MissS2;
public String MissS3;
public String MissS4;
public String MissC;
public String MissSQ;
public int Align;
public boolean isSpawn;
public boolean isMelee;
public boolean npc;
public boolean interact;
public boolean inventory;
public boolean inTown;
public boolean lUndead;
public boolean hUndead;
public boolean demon;
public boolean flying;
public boolean opendoors;
public boolean boss;
public boolean primeevil;
public boolean killable;
public boolean switchai;
public boolean noAura;
public boolean nomultishot;
public boolean neverCount;
public boolean petIgnore;
public boolean deathDmg;
public boolean genericSpawn;
public boolean zoo;
public int SendSkills;
public String Skill1;
public String Sk1mode;
public int Sk1lvl;
public String Skill2;
public String Sk2mode;
public int Sk2lvl;
public String Skill3;
public String Sk3mode;
public int Sk3lvl;
public String Skill4;
public String Sk4mode;
public int Sk4lvl;
public String Skill5;
public String Sk5mode;
public int Sk5lvl;
public String Skill6;
public String Sk6mode;
public int Sk6lvl;
public String Skill7;
public String Sk7mode;
public int Sk7lvl;
public String Skill8;
public String Sk8mode;
public int Sk8lvl;
public int DamageRegen;
public String SkillDamage;
public boolean noRatio;
public boolean NoShldBlock;
public int Crit;
public String El1Mode;
public String El1Type;
public String El2Mode;
public String El2Type;
public String El3Mode;
public String El3Type;
public int TCQuestId;
public int TCQuestCP;
public int SplEndDeath;
public boolean SplGetModeChart;
public boolean SplEndGeneric;
public boolean SplClientEnd;
@Format(format = "Level%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] Level;
@Format(format = "aidel%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aidel;
@Format(format = "aidist%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aidist;
@Format(format = "aip1%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip1;
@Format(format = "aip2%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip2;
@Format(format = "aip3%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip3;
@Format(format = "aip4%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip4;
@Format(format = "aip5%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip5;
@Format(format = "aip6%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip6;
@Format(format = "aip7%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip7;
@Format(format = "aip8%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] aip8;
@Format(format = "Drain%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] Drain;
@Format(format = "coldeffect%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] coldeffect;
@Format(format = "ResDm%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] ResDm;
@Format(format = "ResMa%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] ResMa;
@Format(format = "ResFi%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] ResFi;
@Format(format = "ResLi%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] ResLi;
@Format(format = "ResCo%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] ResCo;
@Format(format = "ResPo%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] ResPo;
@Format(format = "ToBlock%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] ToBlock;
@Format(format = "minHP%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] minHP;
@Format(format = "maxHP%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] maxHP;
@Format(format = "AC%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] AC;
@Format(format = "Exp%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] Exp;
@Format(format = "A1MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] A1MinD;
@Format(format = "A1MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] A1MaxD;
@Format(format = "A1TH%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] A1TH;
@Format(format = "A2MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] A2MinD;
@Format(format = "A2MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] A2MaxD;
@Format(format = "A2TH%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] A2TH;
@Format(format = "S1MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] S1MinD;
@Format(format = "S1MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] S1MaxD;
@Format(format = "S1TH%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] S1TH;
@Format(format = "El1Pct%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El1Pct;
@Format(format = "El1MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El1MinD;
@Format(format = "El1MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El1MaxD;
@Format(format = "El1Dur%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El1Dur;
@Format(format = "El2Pct%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El2Pct;
@Format(format = "El2MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El2MinD;
@Format(format = "El2MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El2MaxD;
@Format(format = "El2Dur%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El2Dur;
@Format(format = "El3Pct%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El3Pct;
@Format(format = "El3MinD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El3MinD;
@Format(format = "El3MaxD%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El3MaxD;
@Format(format = "El3Dur%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public int[] El3Dur;
@Format(format = "TreasureClass1%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public String[] TreasureClass1;
@Format(format = "TreasureClass2%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public String[] TreasureClass2;
@Format(format = "TreasureClass3%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public String[] TreasureClass3;
@Format(format = "TreasureClass4%s", values = {"", "(N)", "(H)"}, endIndex = 3)
public String[] TreasureClass4;
}

View File

@ -0,0 +1,89 @@
package com.riiablo.table.schema;
public class MonStats2 {
// @Override
// public String toString() {
// return Id;
// }
//
// @Key
// @Column public String Id;
// @Column public int Height;
// @Column public int OverlayHeight;
// @Column public int pixHeight;
// @Column public int SizeX;
// @Column public int SizeY;
// @Column public int spawnCol;
// @Column public int MeleeRng;
// @Column public String BaseW;
// @Column public int HitClass;
// @Column(format = "%sv", endIndex = 16, values = {
// "HD", "TR", "LG", "RA", "LA", "RH", "LH", "SH", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8"
// })
// public String ComponentV[];
// @Column(endIndex = 16, values = {
// "HD", "TR", "LG", "RA", "LA", "RH", "LH", "SH", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8"
// })
// public boolean Components[];
// @Column public int TotalPieces;
// @Column(format = "m%s", endIndex = 16, values = {
// "DT", "NU", "WL", "GH", "A1", "A2", "BL", "SC", "S1", "S2", "S3", "S4", "DD", "KB", "SQ", "RN"
// })
// public boolean mMode[];
// @Column(format = "d%s", endIndex = 16, values = {
// "DT", "NU", "WL", "GH", "A1", "A2", "BL", "SC", "S1", "S2", "S3", "S4", "DD", "KB", "SQ", "RN"
// })
// public int dMode[];
// @Column(format = "%smv", endIndex = 16, values = {
// "DT", "NU", "WL", "GH", "A1", "A2", "BL", "SC", "S1", "S2", "S3", "S4", "DD", "KB", "SQ", "RN"
// })
// public boolean Modemv[];
// //@Column public int A1mv;
// //@Column public int A2mv;
// //@Column public int SCmv;
// //@Column public int S1mv;
// //@Column public int S2mv;
// //@Column public int S3mv;
// //@Column public int S4mv;
// @Column public boolean noGfxHitTest;
// @Column public int htTop;
// @Column public int htLeft;
// @Column public int htWidth;
// @Column public int htHeight;
// @Column public int restore;
// @Column public int automapCel;
// @Column public boolean noMap;
// @Column public boolean noOvly;
// @Column public boolean isSel;
// @Column public boolean alSel;
// @Column public boolean noSel;
// @Column public boolean shiftSel;
// @Column public boolean corpseSel;
// @Column public boolean isAtt;
// @Column public boolean revive;
// @Column public boolean critter;
// @Column public boolean small;
// @Column public boolean large;
// @Column public boolean soft;
// @Column public boolean inert;
// @Column public boolean objCol;
// @Column public boolean deadCol;
// @Column public boolean unflatDead;
// @Column public boolean Shadow;
// @Column public boolean noUniqueShift;
// @Column public boolean compositeDeath;
// @Column public int localBlood;
// @Column public int Bleed;
// @Column public int Light;
// @Column(format = "light-%s", values = {"r", "g", "b"}, endIndex = 3)
// public int light[];
// @Column(format = "Utrans%s", values = {"", "(N)", "(H)"}, endIndex = 3)
// public int Utrans[];
// @Column public String Heart;
// @Column public String BodyPart;
// @Column public int InfernoLen;
// @Column public int InfernoAnim;
// @Column public int InfernoRollback;
// @Column public String ResurrectMode;
// @Column public String ResurrectSkill;
}

View File

@ -0,0 +1,7 @@
package com.riiablo.table.schema;
import com.riiablo.table.Serializer;
public abstract class MonStatsSerializerImpl implements Serializer<MonStats> {
}

View File

@ -0,0 +1,6 @@
package com.riiablo.table.schema;
import com.riiablo.table.Table;
public abstract class MonStatsTableImpl implements Table<MonStats> {
}

View File

@ -0,0 +1,29 @@
package com.riiablo.table.schema;
import com.riiablo.table.annotation.Format;
import com.riiablo.table.annotation.Schema;
@Schema
public class Weapons extends ItemEntry {
public String wclass;
public int minmisdam;
public int maxmisdam;
public int reqstr;
public int reqdex;
public int durability;
@Format(format = "2handedwclass")
public String _2handedwclass;
@Format(format = "1or2handed")
public boolean _1or2handed;
@Format(format = "2handed")
public boolean _2handed;
@Format(format = "2handmindam")
public int _2handmindam;
@Format(format = "2handmaxdam")
public int _2handmaxdam;
}

View File

@ -0,0 +1,8 @@
package com.riiablo.table;
import org.junit.Test;
public class IntegrationTest {
@Test
public void test() {}
}