This commit is contained in:
Anuken
2019-03-10 22:51:04 -04:00
880 changed files with 19481 additions and 12588 deletions

1
.gitignore vendored
View File

@@ -28,6 +28,7 @@ logs/
/ios/src/io/anuke/mindustry/gen/
/core/src/io/anuke/mindustry/gen/
ios/robovm.properties
packr-out/
config/
*.gif

View File

@@ -2,6 +2,7 @@
jdk:
- openjdk8
script:
- "git clone --depth=1 --branch=master https://github.com/Anuken/Arc ../Arc"
- "./gradlew test"
- "./gradlew desktop:dist -Pbuildversion=${TRAVIS_TAG:1}"
- "./gradlew server:dist -Pbuildversion=${TRAVIS_TAG:1}"
@@ -17,4 +18,4 @@ deploy:
- "server/build/libs/server-release.jar"
on:
repo: Anuken/Mindustry
tags: true
tags: true

View File

@@ -13,21 +13,21 @@ _[Wiki](http://mindustry.wikia.com/wiki/Mindustry_Wiki)_
Bleeding-edge live builds are generated automatically for every commit. You can see them [here](https://jenkins.hellomouse.net/job/mindustry/).
If you'd rather compile on your own, follow these instructions.
First, make sure you have Java 8 and JDK 8 installed. Open a terminal in the root directory, and run the following commands:
First, make sure you have Java 8 and JDK 8 installed. Open a terminal in the root directory, `cd` to the Mindustry folder and run the following commands:
#### Windows
_Running:_ `gradlew desktop:run`
_Building:_ `gradlew desktop:dist`
#### Linux
#### Linux/Mac OS
_Running:_ `./gradlew desktop:run`
_Building:_ `./gradlew desktop:dist`
#### For Server Builds...
#### Server
Server builds are bundled with each released build (in Releases). If you'd rather compile on your own, replace 'desktop' with 'server' i.e. `gradlew server:dist`.
Server builds are bundled with each released build (in Releases). If you'd rather compile on your own, replace 'desktop' with 'server', e.g. `gradlew server:dist`.
---

View File

@@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.android.tools.build:gradle:3.3.2'
}
}

View File

@@ -20,26 +20,10 @@
#}
-verbose
-dontwarn android.support.**
-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication
-dontwarn com.badlogic.gdx.utils.GdxBuild
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
-dontwarn com.badlogic.gdx.graphics.g2d.freetype.FreetypeBuild
-keep class com.badlogic.gdx.controllers.android.AndroidControllers
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {
<init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
}
-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
boolean contactFilter(long, long);
void beginContact(long);
void endContact(long);
void preSolve(long, long);
void postSolve(long, long);
boolean reportFixture(long);
float reportRayFixture(long, float, float, float, float, float);
-verbose
-ignorewarnings
-keep class io.anuke.mindustry.game.Rules
-keep class io.anuke.mindustry.desktop.DesktopLauncher
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}

View File

@@ -172,10 +172,10 @@ public class AndroidLauncher extends AndroidApplication{
SaveSlot slot = control.saves.importSave(file);
ui.load.runLoadSave(slot);
}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{
ui.showError("$text.save.import.invalid");
ui.showError("$save.import.invalid");
}
}else if(map){ //open map
Core.app.post(() -> {

View File

@@ -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.FIELD)
@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{
/** Gets put in a queue and processed if not connected. */
normal,

View File

@@ -2,8 +2,6 @@ package io.anuke.annotations;
import com.squareup.javapoet.*;
import io.anuke.annotations.IOFinder.ClassSerializer;
import io.anuke.annotations.MethodEntry;
import io.anuke.annotations.Utils;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
@@ -52,7 +50,7 @@ public class RemoteReadGenerator{
Constructor<TypeName> cons = TypeName.class.getDeclaredConstructor(String.class);
cons.setAccessible(true);
TypeName playerType = cons.newInstance("io.anuke.mindustry.entities.Player");
TypeName playerType = cons.newInstance("io.anuke.mindustry.entities.type.Player");
//add player parameter
readMethod.addParameter(playerType, "player");
}

View File

@@ -80,7 +80,7 @@ public class RemoteWriteGenerator{
return;
}
if(!elem.getParameters().get(0).asType().toString().equals("io.anuke.mindustry.entities.Player")){
if(!elem.getParameters().get(0).asType().toString().equals("io.anuke.mindustry.entities.type.Player")){
Utils.messager.printMessage(Kind.ERROR, "Client invoke methods should have a first parameter of type Player.", elem);
return;
}

View File

@@ -0,0 +1,229 @@
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.Modifier;
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.List;
import java.util.Set;
/**Generates ""value types"" classes that are packed into integer primitives of the most aproppriate size.
* It would be nice if Java didn't make crazy hacks like this necessary.*/
@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){
if(!elem.getSimpleName().toString().endsWith("Struct")){
Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
continue;
}
String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length());
String structParam = structName.toLowerCase();
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
try{
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum();
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
if(variables.size() == 0){
Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
continue;
}
//obtain type which will be stored
Class<?> structType = typeForSize(structSize);
//[constructor] get(fields...) : structType
MethodSpec.Builder constructor = MethodSpec.methodBuilder("get")
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.returns(structType);
StringBuilder cons = new StringBuilder();
StringBuilder doc = new StringBuilder();
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
int offset = 0;
for(VariableElement var : variables){
int size = varSize(var);
TypeName varType = TypeName.get(var.asType());
String varName = var.getSimpleName().toString();
//add val param to constructor
constructor.addParameter(varType, varName);
//[get] field(structType) : fieldType
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString())
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.returns(varType)
.addParameter(structType, structParam);
//[set] field(structType, fieldType) : structType
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString())
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.returns(structType)
.addParameter(structType, structParam).addParameter(varType, "value");
//[getter]
if(varType == TypeName.BOOLEAN){
//bools: single bit, is simplified
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
}else if(varType == TypeName.FLOAT){
//floats: need conversion
getter.addStatement("return Float.intBitsToFloat((int)(($L >>> $L) & $L))", structParam, offset, bitString(size, structTotalSize));
}else{
//bytes, shorts, chars, ints
getter.addStatement("return ($T)(($L >>> $L) & $L)", varType, structParam, offset, bitString(size, structTotalSize));
}
//[setter] + [constructor building]
if(varType == TypeName.BOOLEAN){
cons.append(" | (").append(varName).append(" ? ").append("1L << ").append(offset).append("L : 0)");
//bools: single bit, needs special case to clear things
setter.beginControlFlow("if(value)");
setter.addStatement("return ($T)(($L & ~(1L << $LL)))", structType, structParam, offset);
setter.nextControlFlow("else");
setter.addStatement("return ($T)(($L & ~(1L << $LL)) | (1L << $LL))", structType, structParam, offset, offset);
setter.endControlFlow();
}else if(varType == TypeName.FLOAT){
cons.append(" | (").append("(").append(structType).append(")").append("Float.floatToIntBits(").append(varName).append(") << ").append(offset).append("L)");
//floats: need conversion
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
}else{
cons.append(" | (").append("(").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)");
//bytes, shorts, chars, ints
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
}
doc.append("<br> ").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n");
//add finished methods
classBuilder.addMethod(getter.build());
classBuilder.addMethod(setter.build());
offset += size;
}
classBuilder.addJavadoc(doc.toString());
//add constructor final statement + add to class and build
constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3));
classBuilder.addMethod(constructor.build());
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
}catch(IllegalArgumentException e){
e.printStackTrace();
Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
}
}
return true;
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
static String bitString(int offset, int size, int totalSize){
StringBuilder builder = new StringBuilder();
for(int i = 0; i < offset; i++) builder.append('0');
for(int i = 0; i < size; i++) builder.append('1');
for(int i = 0; i < totalSize - size - offset; i++) builder.append('0');
return "0b" + builder.reverse().toString() + "L";
}
static String bitString(int size, int totalSize){
StringBuilder builder = new StringBuilder();
for(int i = 0; i < size; i++) builder.append('1');
for(int i = 0; i < totalSize - size; i++) builder.append('0');
return "0b" + builder.reverse().toString() + "L";
}
static int varSize(VariableElement var) throws IllegalArgumentException{
if(!var.asType().getKind().isPrimitive()){
throw new IllegalArgumentException("All struct fields must be primitives: " + var);
}
StructField an = var.getAnnotation(StructField.class);
if(var.asType().getKind() == TypeKind.BOOLEAN && an != null && an.value() != 1){
throw new IllegalArgumentException("Booleans can only be one bit long... why would you do this?");
}
if(var.asType().getKind() == TypeKind.FLOAT && an != null && an.value() != 32){
throw new IllegalArgumentException("Float size can't be changed. Very sad.");
}
return an == null ? typeSize(var.asType().getKind()) : an.value();
}
static Class<?> typeForSize(int size) throws IllegalArgumentException{
if(size <= 8){
return byte.class;
}else if(size <= 16){
return short.class;
}else if(size <= 32){
return int.class;
}else if(size <= 64){
return long.class;
}
throw new IllegalArgumentException("Too many fields, must fit in 64 bits. Curent size: " + size);
}
/**returns a type's element size in bits.*/
static int typeSize(TypeKind kind) throws IllegalArgumentException{
switch(kind){
case BOOLEAN:
return 1;
case BYTE:
return 8;
case SHORT:
return 16;
case FLOAT:
case CHAR:
case INT:
return 32;
default:
throw new IllegalArgumentException("Invalid type kind: " + kind + ". Note that doubles and longs are not supported.");
}
}
}

View File

@@ -1,2 +1,3 @@
io.anuke.annotations.RemoteMethodAnnotationProcessor
io.anuke.annotations.SerializeAnnotationProcessor
io.anuke.annotations.StructAnnotationProcessor

View File

@@ -10,6 +10,7 @@ buildscript{
dependencies{
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.5'
classpath "com.badlogicgames.gdx:gdx-tools:1.9.9"
classpath "com.badlogicgames.packr:packr:2.1-SNAPSHOT"
}
}
@@ -20,12 +21,16 @@ allprojects{
ext{
versionNumber = '4'
versionModifier = 'alpha'
versionModifier = 'beta'
if(!project.hasProperty("versionType")) versionType = 'official'
appName = 'Mindustry'
gdxVersion = '1.9.9'
roboVMVersion = '2.3.0'
arcHash = null
debugged = {
return new File(projectDir.parent, '../debug').exists() && System.properties["release"] == null
}
localArc = {
return (System.properties["release"] == null || System.properties["release"] == "false") && new File(projectDir.parent, '../Arc').exists()
@@ -35,7 +40,7 @@ allprojects{
//get latest commit hash from gtihub since JITPack's '-snapshot' version doesn't work correctly
if(arcHash == null){
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){
e.printStackTrace()
arcHash = "-SNAPSHOT";
@@ -117,7 +122,7 @@ project(":desktop"){
compile project(":core")
compile project(":net")
if(new File(projectDir.parent, '../debug').exists() && System.properties["release"] == null) compile project(":debug")
if(debugged()) compile project(":debug")
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
@@ -194,6 +199,7 @@ project(":core"){
compile arcModule("arc-core")
compile arcModule("extensions:freetype")
if(localArc() && debugged()) compile arcModule("extensions:recorder")
compileOnly project(":annotations")
annotationProcessor project(":annotations")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 B

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 B

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 B

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Some files were not shown because too many files have changed in this diff Show More