Fixed server crash / Struct annotation begins
This commit is contained in:
@@ -14,6 +14,21 @@ public class Annotations{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Marks a class as a special value type struct. Class name must end in 'Struct'.*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface Struct{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Marks a field of a struct. Optional.*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface StructField{
|
||||||
|
/**Size of a struct field in bits. Not valid on booleans or floating point numbers.*/
|
||||||
|
int value();
|
||||||
|
}
|
||||||
|
|
||||||
public enum PacketPriority{
|
public enum PacketPriority{
|
||||||
/** Gets put in a queue and processed if not connected. */
|
/** Gets put in a queue and processed if not connected. */
|
||||||
normal,
|
normal,
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.JavaFile;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import io.anuke.annotations.Annotations.Struct;
|
||||||
|
import io.anuke.annotations.Annotations.StructField;
|
||||||
|
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.lang.model.element.VariableElement;
|
||||||
|
import javax.lang.model.type.TypeKind;
|
||||||
|
import javax.lang.model.util.ElementFilter;
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
|
@SupportedAnnotationTypes({
|
||||||
|
"io.anuke.annotations.Annotations.Struct"
|
||||||
|
})
|
||||||
|
public class StructAnnotationProcessor extends AbstractProcessor{
|
||||||
|
/** Name of the base package to put all the generated classes. */
|
||||||
|
private static final String packageName = "io.anuke.mindustry.gen";
|
||||||
|
private int round;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||||
|
super.init(processingEnv);
|
||||||
|
//put all relevant utils into utils class
|
||||||
|
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||||
|
Utils.elementUtils = processingEnv.getElementUtils();
|
||||||
|
Utils.filer = processingEnv.getFiler();
|
||||||
|
Utils.messager = processingEnv.getMessager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||||
|
if(round++ != 0) return false; //only process 1 round
|
||||||
|
|
||||||
|
try{
|
||||||
|
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Struct.class));
|
||||||
|
|
||||||
|
for(TypeElement elem : elements){
|
||||||
|
TypeName type = TypeName.get(elem.asType());
|
||||||
|
|
||||||
|
if(!type.toString().endsWith("Struct")){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(packageName + "." + elem.getSimpleName().toString());
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
for(VariableElement var : ElementFilter.fieldsIn(Collections.singletonList(elem))){
|
||||||
|
if(!var.asType().getKind().isPrimitive()){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "All struct fields must be primitives.", var);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
StructField an = var.getAnnotation(StructField.class);
|
||||||
|
int size = an == null ? typeSize(var.asType().getKind()) : an.value();
|
||||||
|
|
||||||
|
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString());
|
||||||
|
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**returns a type's element size in bits.*/
|
||||||
|
static int typeSize(TypeKind kind){
|
||||||
|
switch(kind){
|
||||||
|
case BOOLEAN:
|
||||||
|
return 1;
|
||||||
|
case BYTE:
|
||||||
|
return 8;
|
||||||
|
case SHORT:
|
||||||
|
return 16;
|
||||||
|
case FLOAT:
|
||||||
|
case CHAR:
|
||||||
|
case INT:
|
||||||
|
return 32;
|
||||||
|
case LONG:
|
||||||
|
case DOUBLE:
|
||||||
|
return 64;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Invalid type kind: " + kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
io.anuke.annotations.RemoteMethodAnnotationProcessor
|
io.anuke.annotations.RemoteMethodAnnotationProcessor
|
||||||
io.anuke.annotations.SerializeAnnotationProcessor
|
io.anuke.annotations.SerializeAnnotationProcessor
|
||||||
|
io.anuke.annotations.StructAnnotationProcessor
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ allprojects{
|
|||||||
//get latest commit hash from gtihub since JITPack's '-snapshot' version doesn't work correctly
|
//get latest commit hash from gtihub since JITPack's '-snapshot' version doesn't work correctly
|
||||||
if(arcHash == null){
|
if(arcHash == null){
|
||||||
try{
|
try{
|
||||||
arcHash = 'git ls-remote https://github.com/Anuken/Arc.git'.execute().text.split("\t")[0]//new JsonSlurper().parse(new URL("https://api.github.com/repos/Anuken/Arc/commits/master"))["sha"]
|
arcHash = 'git ls-remote https://github.com/Anuken/Arc.git'.execute().text.split("\t")[0]
|
||||||
}catch(e){
|
}catch(e){
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
arcHash = "-SNAPSHOT";
|
arcHash = "-SNAPSHOT";
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class CustomGameDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void displayGameModeHelp(){
|
private void displayGameModeHelp(){
|
||||||
FloatingDialog d = new FloatingDialog(Core.bundle.get("mode.text.help.title"));
|
FloatingDialog d = new FloatingDialog(Core.bundle.get("mode.help.title"));
|
||||||
d.setFillParent(false);
|
d.setFillParent(false);
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
table.defaults().pad(1f);
|
table.defaults().pad(1f);
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import io.anuke.mindustry.type.StatusEffect;
|
|||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
|
|
||||||
public class Floor extends Block{
|
public class Floor extends Block{
|
||||||
/** number of different variant regions to use */
|
/** number of different variant regions to use */
|
||||||
public int variants;
|
public int variants;
|
||||||
@@ -49,7 +51,8 @@ public class Floor extends Block{
|
|||||||
public float heat = 0f;
|
public float heat = 0f;
|
||||||
/** if true, this block cannot be mined by players. useful for annoying things like sand. */
|
/** if true, this block cannot be mined by players. useful for annoying things like sand. */
|
||||||
public boolean playerUnmineable = false;
|
public boolean playerUnmineable = false;
|
||||||
protected TextureRegion[] variantRegions;
|
protected TextureRegion[] regions;
|
||||||
|
protected TextureRegion[][] edges;
|
||||||
|
|
||||||
public Floor(String name){
|
public Floor(String name){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -62,22 +65,24 @@ public class Floor extends Block{
|
|||||||
|
|
||||||
//load variant regions for drawing
|
//load variant regions for drawing
|
||||||
if(variants > 0){
|
if(variants > 0){
|
||||||
variantRegions = new TextureRegion[variants];
|
regions = new TextureRegion[variants];
|
||||||
|
|
||||||
for(int i = 0; i < variants; i++){
|
for(int i = 0; i < variants; i++){
|
||||||
variantRegions[i] = Core.atlas.find(name + (i + 1));
|
regions[i] = Core.atlas.find(name + (i + 1));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
variantRegions = new TextureRegion[1];
|
regions = new TextureRegion[1];
|
||||||
variantRegions[0] = Core.atlas.find(name);
|
regions[0] = Core.atlas.find(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
region = variantRegions[0];
|
int size = (int)(tilesize / Draw.scl);
|
||||||
|
edges = Core.atlas.find(name + "-edge").split(size, size);
|
||||||
|
region = regions[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureRegion[] variantRegions(){
|
public TextureRegion[] variantRegions(){
|
||||||
return variantRegions;
|
return regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -93,7 +98,7 @@ public class Floor extends Block{
|
|||||||
public void draw(Tile tile){
|
public void draw(Tile tile){
|
||||||
Mathf.random.setSeed(tile.pos());
|
Mathf.random.setSeed(tile.pos());
|
||||||
|
|
||||||
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
|
Draw.rect(regions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, regions.length - 1))], tile.worldx(), tile.worldy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class OreBlock extends Floor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Tile tile){
|
public void draw(Tile tile){
|
||||||
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
|
Draw.rect(regions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, regions.length - 1))], tile.worldx(), tile.worldy());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Block get(Block floor, Item item){
|
public static Block get(Block floor, Item item){
|
||||||
|
|||||||
@@ -101,10 +101,10 @@ public class IOSLauncher extends IOSApplication.Delegate {
|
|||||||
SaveSlot slot = control.saves.importSave(file);
|
SaveSlot slot = control.saves.importSave(file);
|
||||||
ui.load.runLoadSave(slot);
|
ui.load.runLoadSave(slot);
|
||||||
}catch (IOException e){
|
}catch (IOException e){
|
||||||
ui.showError(Core.bundle.format("text.save.import.fail", Strings.parseException(e, false)));
|
ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, false)));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
ui.showError("$text.save.import.invalid");
|
ui.showError("save.import.invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if(file.extension().equalsIgnoreCase(mapExtension)){ //open map
|
}else if(file.extension().equalsIgnoreCase(mapExtension)){ //open map
|
||||||
|
|||||||
@@ -28,11 +28,12 @@ public class MindustryServer implements ApplicationListener{
|
|||||||
BundleLoader.load();
|
BundleLoader.load();
|
||||||
content.verbose(false);
|
content.verbose(false);
|
||||||
content.load();
|
content.load();
|
||||||
content.initialize(Content::init);
|
|
||||||
|
|
||||||
Core.app.addListener(logic = new Logic());
|
Core.app.addListener(logic = new Logic());
|
||||||
Core.app.addListener(world = new World());
|
Core.app.addListener(world = new World());
|
||||||
Core.app.addListener(netServer = new NetServer());
|
Core.app.addListener(netServer = new NetServer());
|
||||||
Core.app.addListener(new ServerControl(args));
|
Core.app.addListener(new ServerControl(args));
|
||||||
|
|
||||||
|
content.initialize(Content::init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import io.anuke.mindustry.core.GameState.State;
|
|||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.game.Difficulty;
|
import io.anuke.mindustry.game.Difficulty;
|
||||||
import io.anuke.mindustry.game.EventType.GameOverEvent;
|
import io.anuke.mindustry.game.EventType.GameOverEvent;
|
||||||
|
import io.anuke.mindustry.game.RulePreset;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.game.Version;
|
import io.anuke.mindustry.game.Version;
|
||||||
import io.anuke.mindustry.gen.Call;
|
import io.anuke.mindustry.gen.Call;
|
||||||
@@ -189,7 +190,7 @@ public class ServerControl implements ApplicationListener{
|
|||||||
info("Stopped server.");
|
info("Stopped server.");
|
||||||
});
|
});
|
||||||
|
|
||||||
handler.register("host", "[mapname]", "Open the server with a specific map.", arg -> {
|
handler.register("host", "<mapname> [mode]", "Open the server with a specific map.", arg -> {
|
||||||
if(state.is(State.playing)){
|
if(state.is(State.playing)){
|
||||||
err("Already hosting. Type 'stop' to stop hosting first.");
|
err("Already hosting. Type 'stop' to stop hosting first.");
|
||||||
return;
|
return;
|
||||||
@@ -197,33 +198,31 @@ public class ServerControl implements ApplicationListener{
|
|||||||
|
|
||||||
if(lastTask != null) lastTask.cancel();
|
if(lastTask != null) lastTask.cancel();
|
||||||
|
|
||||||
Map result = null;
|
Map result = world.maps.all().find(map -> map.name.equalsIgnoreCase(arg[0]));
|
||||||
|
|
||||||
if(arg.length > 0){
|
if(result == null){
|
||||||
|
err("No map with name &y'{0}'&lr found.", arg[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String search = arg[0];
|
RulePreset preset = RulePreset.survival;
|
||||||
for(Map map : world.maps.all()){
|
|
||||||
if(map.name.equalsIgnoreCase(search)) result = map;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result == null){
|
if(arg.length > 1){
|
||||||
err("No map with name &y'{0}'&lr found.", search);
|
try{
|
||||||
|
preset = RulePreset.valueOf(arg[1]);
|
||||||
|
}catch(IllegalArgumentException e){
|
||||||
|
err("No gamemode '{0}' found.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
info("Loading map...");
|
|
||||||
err("TODO select gamemode");
|
|
||||||
|
|
||||||
logic.reset();
|
|
||||||
world.loadMap(result);
|
|
||||||
logic.play();
|
|
||||||
|
|
||||||
}else{
|
|
||||||
//TODO
|
|
||||||
err("TODO play generated map");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info("Loading map...");
|
||||||
|
|
||||||
|
logic.reset();
|
||||||
|
state.rules = preset.get();
|
||||||
|
world.loadMap(result);
|
||||||
|
logic.play();
|
||||||
|
|
||||||
info("Map loaded.");
|
info("Map loaded.");
|
||||||
|
|
||||||
host();
|
host();
|
||||||
|
|||||||
Reference in New Issue
Block a user