Merge branch 'master' into master

This commit is contained in:
Vanguard
2020-03-10 05:44:57 +03:00
committed by GitHub
761 changed files with 5143 additions and 3288 deletions

View File

@@ -1,6 +1,10 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help fix an issue. about: Create a report to help fix an issue.
title: ''
labels: ''
assignees: ''
--- ---
**Platform**: *Android/iOS/Mac/Windows/Linux* **Platform**: *Android/iOS/Mac/Windows/Linux*

View File

@@ -1,7 +1,11 @@
--- ---
name: Feature request name: Feature request
about: Do not make a new issue for feature requests! Instead, post it on FeatHub, see the README. about: Do not make a new issue for feature requests! Instead, post in the suggestions
repository. See the README.
title: ''
labels: invalid
assignees: ''
--- ---
**Do not make a new issue for feature requests!** Instead, post it on FeatHub: https://feathub.com/Anuken/Mindustry **Do not make a new issue for feature requests!** Instead, post it in suggestions repository: https://github.com/Anuken/Mindustry-Suggestions/issues/new/choose

2
.gitignore vendored
View File

@@ -22,6 +22,7 @@ logs/
/server/build/ /server/build/
changelog changelog
saves/ saves/
/core/assets-raw/fontgen/out/
core/assets/saves/ core/assets/saves/
/core/assets/saves/ /core/assets/saves/
steam_appid.txt steam_appid.txt
@@ -30,6 +31,7 @@ steam_appid.txt
/android/assets/mindustry-maps/ /android/assets/mindustry-maps/
/android/assets/mindustry-saves/ /android/assets/mindustry-saves/
/core/assets/gifexport/ /core/assets/gifexport/
/annotations/src/main/resources/META-INF/services
/core/assets/version.properties /core/assets/version.properties
/core/assets/locales /core/assets/locales
/ios/src/mindustry/gen/ /ios/src/mindustry/gen/

View File

@@ -21,13 +21,15 @@ First, make sure you have [JDK 8](https://adoptopenjdk.net/) installed. Open a t
#### Windows #### Windows
_Running:_ `gradlew desktop:run` _Running:_ `gradlew.bat desktop:run`
_Building:_ `gradlew desktop:dist` _Building:_ `gradlew.bat desktop:dist`
_Sprite Packing:_ `gradlew.bat tools:pack`
#### Linux/Mac OS #### Linux/Mac OS
_Running:_ `./gradlew desktop:run` _Running:_ `./gradlew desktop:run`
_Building:_ `./gradlew desktop:dist` _Building:_ `./gradlew desktop:dist`
_Sprite Packing:_ `./gradlew tools:pack`
#### Server #### Server
@@ -49,6 +51,10 @@ If the terminal returns `Permission denied` or `Command not found` on Mac/Linux,
Gradle may take up to several minutes to download files. Be patient. <br> Gradle may take up to several minutes to download files. Be patient. <br>
After building, the output .JAR file should be in `/desktop/build/libs/Mindustry.jar` for desktop builds, and in `/server/build/libs/server-release.jar` for server builds. After building, the output .JAR file should be in `/desktop/build/libs/Mindustry.jar` for desktop builds, and in `/server/build/libs/server-release.jar` for server builds.
### Feature Requests
Post feature requests and feedback [here](https://github.com/Anuken/Mindustry-Suggestions/issues/new/choose).
### Downloads ### Downloads
[<img src="https://static.itch.io/images/badge.svg" [<img src="https://static.itch.io/images/badge.svg"
@@ -62,7 +68,3 @@ After building, the output .JAR file should be in `/desktop/build/libs/Mindustry
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" [<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid" alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/io.anuke.mindustry/) height="80">](https://f-droid.org/packages/io.anuke.mindustry/)
### Feature Requests
[![Feature Requests](https://feathub.com/Anuken/Mindustry?format=svg)](https://feathub.com/Anuken/Mindustry)

26
SERVERLIST.md Normal file
View File

@@ -0,0 +1,26 @@
### Adding a server to the list
Mindustry now has a public list of servers that everyone can see and connect to.
This is done by letting clients `GET` a [JSON list of servers](https://github.com/Anuken/Mindustry/blob/master/servers.json) in this repository.
You may want to add your server to this list. The steps for getting this done are as follows:
1. **Ensure your server is properly moderated.** For the most part, this applies to survival servers, but PvP servers can be affected as well.
You'll need to either hire some moderators, or make use of (currently non-existent) anti-grief and anti-curse plugins.
*Consider enabling a rate limit:* `config messageRateLimit 2` will make it so that players can only send messages every 2 seconds, for example.
2. **Set an appropriate MOTD, name and description.** This is set with `config <name/desc/motd> <value>`. "Appropriate" means that:
- Your name or description must reflect the type of server you're hosting.
Since new players may be exposed to the server list early on, put in a phrase like "Co-op survival" or "PvP" so players know what they're getting into. Yes, this is also displayed in the server mode info text, but having extra info in the name doesn't hurt.
- Make sure players know where to refer to for server support. It should be fairly clear that the server owner is not me, but you.
- Try to be professional in your text; use common sense.
3. **Get some good maps.** *(optional, but highly recommended)*. Add some maps to your server and set the map rotation to custom-only. You can get maps from the Steam workshop by subscribing and exporting them; using the `#maps` channel on Discord is also an option.
4. **Check your server configuration.** *(optional)* I would recommend adding a message rate limit of 1 second (`config messageRateLimit 1`), and disabling connect/disconnect messages to reduce spam (`config showConnectMessages false`).
5. Finally, **submit a pull request** to add your server's IP to the list.
This should be fairly straightforward: Press the edit button on the [server file](https://github.com/Anuken/Mindustry/blob/master/servers.json), then add a JSON object with a single key, indicating your server address.
For example, if your server address is `google.com`, you would add a comma after the last entry and insert:
```json
{
"address": "google.com"
}
```
Then, press the *'submit pull request'* button and I'll take a look at your server. If I have any issues with it, I'll let you know in the PR comments.

View File

@@ -3,6 +3,7 @@
package="io.anuke.mindustry"> package="io.anuke.mindustry">
<uses-feature android:glEsVersion="0x00020000" android:required="true"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<uses-feature android:name="android.hardware.type.pc" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>

View File

@@ -81,7 +81,7 @@ public class AndroidLauncher extends AndroidApplication{
if(VERSION.SDK_INT >= VERSION_CODES.Q){ if(VERSION.SDK_INT >= VERSION_CODES.Q){
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT); Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE); intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(extension.equals("zip") ? "application/zip" : "*/*"); intent.setType(extension.equals("zip") && !open ? "application/zip" : "*/*");
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> { addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
if(code == Activity.RESULT_OK && in != null && in.getData() != null){ if(code == Activity.RESULT_OK && in != null && in.getData() != null){
Uri uri = in.getData(); Uri uri = in.getData();
@@ -155,16 +155,6 @@ public class AndroidLauncher extends AndroidApplication{
Fi data = Core.files.absolute(getContext().getExternalFilesDir(null).getAbsolutePath()); Fi data = Core.files.absolute(getContext().getExternalFilesDir(null).getAbsolutePath());
Core.settings.setDataDirectory(data); Core.settings.setDataDirectory(data);
//delete old external files due to screwup
if(Core.files.local("files_moved").exists() && !Core.files.local("files_moved_103").exists()){
for(Fi fi : data.list()){
fi.deleteDirectory();
}
Core.files.local("files_moved").delete();
Core.files.local("files_moved_103").writeString("files moved again");
}
//move to internal storage if there's no file indicating that it moved //move to internal storage if there's no file indicating that it moved
if(!Core.files.local("files_moved").exists()){ if(!Core.files.local("files_moved").exists()){
Log.info("Moving files to external storage..."); Log.info("Moving files to external storage...");
@@ -177,6 +167,7 @@ public class AndroidLauncher extends AndroidApplication{
} }
//create marker //create marker
Core.files.local("files_moved").writeString("files moved to " + data); Core.files.local("files_moved").writeString("files moved to " + data);
Core.files.local("files_moved_103").writeString("files moved again");
Log.info("Files moved."); Log.info("Files moved.");
}catch(Throwable t){ }catch(Throwable t){
Log.err("Failed to move files!"); Log.err("Failed to move files!");

View File

@@ -3,10 +3,40 @@ package mindustry.annotations;
import java.lang.annotation.*; import java.lang.annotation.*;
public class Annotations{ public class Annotations{
//region entity interfaces
/** Indicates multiple inheritance on a component type. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Depends{
Class[] value();
}
/** Indicates that a component def is present on all entities. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface BaseComponent{
}
/** Indicates an entity definition. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface EntityDef{
Class[] value();
}
/** Indicates an internal interface for entity components. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface EntityInterface{
}
//endregion
//region misc. utility
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface StyleDefaults { public @interface StyleDefaults{
} }
/** Indicates that a method should always call its super version. */ /** Indicates that a method should always call its super version. */
@@ -16,10 +46,10 @@ public class Annotations{
} }
/** Annotation that allows overriding CallSuper annotation. To be used on method that overrides method with CallSuper annotation from parent class.*/ /** Annotation that allows overriding CallSuper annotation. To be used on method that overrides method with CallSuper annotation from parent class. */
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface OverrideCallSuper { public @interface OverrideCallSuper{
} }
/** Marks a class as serializable. */ /** Marks a class as serializable. */
@@ -29,6 +59,9 @@ public class Annotations{
} }
//endregion
//region struct
/** Marks a class as a special value type struct. Class name must end in 'Struct'. */ /** Marks a class as a special value type struct. Class name must end in 'Struct'. */
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@@ -44,6 +77,9 @@ public class Annotations{
int value(); int value();
} }
//endregion
//region remote
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,
@@ -138,4 +174,6 @@ public class Annotations{
public @interface ReadClass{ public @interface ReadClass{
Class<?> value(); Class<?> value();
} }
//endregion
} }

View File

@@ -1,9 +1,19 @@
package mindustry.annotations; package mindustry.annotations;
import arc.struct.*;
import arc.util.*;
import com.squareup.javapoet.*;
import com.sun.source.util.*;
import mindustry.annotations.util.*;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.*; import javax.lang.model.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.lang.model.util.*; import javax.lang.model.util.*;
import javax.tools.Diagnostic.*;
import javax.tools.*;
import java.io.*;
import java.lang.annotation.*;
import java.util.*; import java.util.*;
@SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedSourceVersion(SourceVersion.RELEASE_8)
@@ -15,8 +25,11 @@ public abstract class BaseProcessor extends AbstractProcessor{
public static Elements elementu; public static Elements elementu;
public static Filer filer; public static Filer filer;
public static Messager messager; public static Messager messager;
public static Trees trees;
protected int round; protected int round;
protected int rounds = 1;
protected RoundEnvironment env;
public static String getMethodName(Element element){ public static String getMethodName(Element element){
return ((TypeElement)element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName(); return ((TypeElement)element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName();
@@ -27,19 +40,80 @@ public abstract class BaseProcessor extends AbstractProcessor{
|| type.equals("long") || type.equals("float") || type.equals("double") || type.equals("char"); || type.equals("long") || type.equals("float") || type.equals("double") || type.equals("char");
} }
@Override public static void write(TypeSpec.Builder builder) throws Exception{
public synchronized void init(ProcessingEnvironment processingEnv){ write(builder, null);
super.init(processingEnv); }
typeu = processingEnv.getTypeUtils(); public static void write(TypeSpec.Builder builder, Array<String> imports) throws Exception{
elementu = processingEnv.getElementUtils(); JavaFile file = JavaFile.builder(packageName, builder.build()).skipJavaLangImports(true).build();
filer = processingEnv.getFiler();
messager = processingEnv.getMessager(); if(imports != null){
String rawSource = file.toString();
Array<String> result = new Array<>();
for (String s : rawSource.split("\n", -1)) {
result.add(s);
if (s.startsWith("package ")) {
result.add("");
for (String i : imports) {
result.add(i);
}
}
}
String out = result.toString("\n");
JavaFileObject object = filer.createSourceFile(file.packageName + "." + file.typeSpec.name, file.typeSpec.originatingElements.toArray(new Element[0]));
OutputStream stream = object.openOutputStream();
stream.write(out.getBytes());
stream.close();
}else{
file.writeTo(filer);
}
}
public Array<Stype> types(Class<? extends Annotation> type){
return Array.with(env.getElementsAnnotatedWith(type)).select(e -> e instanceof TypeElement)
.map(e -> new Stype((TypeElement)e));
}
public Array<Svar> fields(Class<? extends Annotation> type){
return Array.with(env.getElementsAnnotatedWith(type)).select(e -> e instanceof VariableElement)
.map(e -> new Svar((VariableElement)e));
}
public Array<Smethod> methods(Class<? extends Annotation> type){
return Array.with(env.getElementsAnnotatedWith(type)).select(e -> e instanceof ExecutableElement)
.map(e -> new Smethod((ExecutableElement)e));
}
public void err(String message){
messager.printMessage(Kind.ERROR, message);
Log.err("[CODEGEN ERROR] " +message);
}
public void err(String message, Element elem){
messager.printMessage(Kind.ERROR, message, elem);
Log.err("[CODEGEN ERROR] " + message + ": " + elem);
}
public void err(String message, Selement elem){
err(message, elem.e);
}
@Override
public synchronized void init(ProcessingEnvironment env){
super.init(env);
trees = Trees.instance(env);
typeu = env.getTypeUtils();
elementu = env.getElementUtils();
filer = env.getFiler();
messager = env.getMessager();
} }
@Override @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
if(round++ != 0) return false; //only process 1 round if(round++ >= rounds) return false; //only process 1 round
this.env = roundEnv;
try{ try{
process(roundEnv); process(roundEnv);
}catch(Exception e){ }catch(Exception e){

View File

@@ -16,7 +16,7 @@ import javax.tools.*;
import java.util.*; import java.util.*;
@SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults") @SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults")
public class AssetsAnnotationProcessor extends BaseProcessor{ public class AssetsProcess extends BaseProcessor{
private String path; private String path;
@Override @Override
@@ -122,11 +122,11 @@ public class AssetsAnnotationProcessor extends BaseProcessor{
dispose.addStatement("arc.Core.assets.unload(" + filename + ")"); dispose.addStatement("arc.Core.assets.unload(" + filename + ")");
dispose.addStatement(name + " = null"); dispose.addStatement(name + " = null");
type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), name, Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.audio.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1)+ "()").build()); type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), name, Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1)+ "()").build());
}); });
if(classname.equals("Sounds")){ if(classname.equals("Sounds")){
type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), "none", Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.audio.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1)+ "()").build()); type.addField(FieldSpec.builder(ClassName.bestGuess(rtype), "none", Modifier.STATIC, Modifier.PUBLIC).initializer("new arc.mock.Mock" + rtype.substring(rtype.lastIndexOf(".") + 1)+ "()").build());
} }
type.addMethod(loadBegin.build()); type.addMethod(loadBegin.build());

View File

@@ -18,7 +18,7 @@ import java.lang.annotation.*;
import java.util.*; import java.util.*;
@SupportedAnnotationTypes({"java.lang.Override"}) @SupportedAnnotationTypes({"java.lang.Override"})
public class CallSuperAnnotationProcessor extends AbstractProcessor{ public class CallSuperProcess extends AbstractProcessor{
private Trees trees; private Trees trees;
@Override @Override
@@ -122,6 +122,7 @@ public class CallSuperAnnotationProcessor extends AbstractProcessor{
} }
for(Symbol s : it){ for(Symbol s : it){
if(s instanceof MethodSymbol){ if(s instanceof MethodSymbol){
MethodSymbol ms = (MethodSymbol)s; MethodSymbol ms = (MethodSymbol)s;

View File

@@ -1,34 +1,41 @@
package mindustry.annotations.impl; package mindustry.annotations.impl;
import arc.util.serialization.*;
import com.squareup.javapoet.*; import com.squareup.javapoet.*;
import mindustry.annotations.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.annotations.*;
import mindustry.annotations.remote.*; import mindustry.annotations.remote.*;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.lang.model.util.*; import javax.lang.model.util.*;
import javax.tools.*;
import java.io.*; import java.io.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.*; import java.util.*;
import java.util.zip.*; import java.util.zip.*;
@SupportedAnnotationTypes("mindustry.annotations.Annotations.Serialize") @SupportedAnnotationTypes("mindustry.annotations.Annotations.Serialize")
public class SerializeAnnotationProcessor extends BaseProcessor{ public class SerializeProcess extends BaseProcessor{
/** Target class name. */ /** Target class name. */
private static final String className = "Serialization"; private static final String className = "Serialization";
/** Name of the base package to put all the generated classes. */ /** Name of the base package to put all the generated classes. */
private static final String data = "eJztV0tvGzcQvvfQ3zDRIeDCKhsbQVDUsgP5UViH2IHl9BIEBsUdSYxX3C3Jlawm+XH9Z53hUg/bkuOmOfRQwfDuDme++ebBWe6PfwU3/wTwUU2VLJQdSYfDAnWQvxkschjCAUyMzWtPetJikF2nzzG8deXU5OjkW6VvMPTRGVWYP0mgC+W9HGE4Qbp1mEcg0Zo5E9C1sn2AofQYulqj92ZQoAiuxqVc2Loo2iCU03JYWy2PS+v3OndJNF7bDW1rSnk0D3hUD4foDjNRtWGQwU+HQIGZoajAWB+U1VgOYROOZx+Wgm4eMzJ7ghpoyo14Cl5FsQ2I4PsPcE2/XXpssk7kOMw6mEJe9KXxXZu70uTM4Jjz2Hl9CJ79xCc5LN25mqBoqUZPVosy9DEEY0eebnTtMKZ5iaDddgRd2oA2MGO+XqIvi2mq0xJAqQ0ARHzA8dncywWar91QaZwanMkUS7eqCqNVMKW9x+qRuO6wug3R8GGLvsEwLnMYMZBS6z3XrIgWidYhLgYfyQ50IyKrkZbGTssbjHU4Lh1KVVWbvaUNEf8fUFXYX+rt7vnJ5UXv5Lp3Et30g6NagDK55RZpHrNoyUaxwx+PyA+XLtZCaYBabSpoOzlptttX0uM8oen7aJsqnhLkkixmyPlFjlLe1kL0a/ER6YVis4UXKO2YCbYyNkCBnBQv6ToKY5Gt9kauAveZxVkjYc2fYe8DT4bSCTY2tP5iny4dxuGbnQPY4+3Cxu9N1GdODJAJcTxWTmmaOzI3IxOEl5ok3SBM1obdVxl0OvAyA9iB7Zq0uNtoM9cvy9gpvLoIiXAjW+1mnwZi7Ht5pDy+enlc8k5Fq+kqmG8EpBnQIEn8o1aFp25a/C66B60sgzB25Sx6uaxtMBM8vdVYMbBoHakc3r3rnchYvjhdiBGDM1csPD4cMr3Sc8ZSGHVtuJ+X/e8Xk2TZcKLFOtR2rVYizM8EdDqpwlxkDJZKeCcnUfYLl4+f2MFEhbG8pE0uMhqXt4Gntk/hM3Ti8k0JTSgM8zCWqg7LKPiyWcurKYr1PDaYi0x+Wi08gVaOkdYT85paa+Enbubo4NTWE3QRvtO87eg1Qy/gWeluerQd47w9BCRSsHWdfd6XebGcGptMoKw58Dhe4IwrXJYFKkspEKnYfImdRB0R7+GAasezjRIXamdhSP2M+1/rjv7cB5xI5Zya67KaN2BteNFOFvE2CtPUYObJxbN/1Sxb9hw8f/7dgbsMnKoMcAbjlIezWAcecJRxkmHcGacFTmg48xrLuYBnyuUzerl185y8UPkW6YbPn+HZWFJhtmlmMSKUY+XfUC8m8NgBG52uDeXrVFnYhv3Py3u9sb7X9wu8eMUE9x1GArUoAW0rNyVw42r3WwfwanDQHx1+9FhcMYii4y6E/6fvf3T6UiaZLA3BtXO9Zvvf0Xn2MahNEfmv1unr42peYe9Cxk+chD6gU5qcNla8/GQbSwfhJyvXvslmpC2oxOXAUIe9TgegXfgVXizXOSxN4RSlW9nEnK4eGzsGolO9pw+6xXC6d/pa0yDBzs7db6ZHGEczPgSbO+88qBpVMYjSbH/Trgn0vUM8+oE+O67otMbt8uWHvwGqGwCj"; private static final String data = "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";
@Override @Override
public void process(RoundEnvironment env) throws Exception{ public void process(RoundEnvironment env) throws Exception{
Set<TypeElement> elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Serialize.class)); Set<TypeElement> elements = ElementFilter.typesIn(env.getElementsAnnotatedWith(Serialize.class));
JavaFileObject obj = filer.createSourceFile(packageName + ".Injector");
OutputStream stream = obj.openOutputStream();
stream.write(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(Base64Coder.decode(data)))).readUTF().replace("debug", "gen").getBytes());
stream.close();
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC); TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
classBuilder.addStaticBlock(CodeBlock.of(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(data)))).readUTF())); classBuilder.addStaticBlock(CodeBlock.of("Injector.ii();"));
classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build()); classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build());
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning); classBuilder.addJavadoc(RemoteProcess.autogenWarning);
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC); MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);

View File

@@ -20,7 +20,7 @@ import java.util.Set;
@SupportedAnnotationTypes({ @SupportedAnnotationTypes({
"mindustry.annotations.Annotations.Struct" "mindustry.annotations.Annotations.Struct"
}) })
public class StructAnnotationProcessor extends BaseProcessor{ public class StructProcess extends BaseProcessor{
@Override @Override
public void process(RoundEnvironment env) throws Exception{ public void process(RoundEnvironment env) throws Exception{
@@ -41,7 +41,7 @@ public class StructAnnotationProcessor extends BaseProcessor{
try{ try{
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements()); List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum(); int structSize = variables.stream().mapToInt(StructProcess::varSize).sum();
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64); int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
if(variables.size() == 0){ if(variables.size() == 0){

View File

@@ -1,137 +0,0 @@
package mindustry.annotations.remote;
import com.squareup.javapoet.*;
import mindustry.annotations.*;
import mindustry.annotations.Annotations.*;
import mindustry.annotations.remote.IOFinder.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.tools.Diagnostic.*;
import java.util.*;
import java.util.stream.*;
/** The annotation processor for generating remote method call code. */
@SupportedAnnotationTypes({
"mindustry.annotations.Annotations.Remote",
"mindustry.annotations.Annotations.WriteClass",
"mindustry.annotations.Annotations.ReadClass",
})
public class RemoteMethodAnnotationProcessor extends BaseProcessor{
/** Maximum size of each event packet. */
public static final int maxPacketSize = 4096;
/** Warning on top of each autogenerated file. */
public static final String autogenWarning = "Autogenerated file. Do not modify!\n";
/** Name of class that handles reading and invoking packets on the server. */
private static final String readServerName = "RemoteReadServer";
/** Name of class that handles reading and invoking packets on the client. */
private static final String readClientName = "RemoteReadClient";
/** Simple class name of generated class name. */
private static final String callLocation = "Call";
//class serializers
private HashMap<String, ClassSerializer> serializers;
//all elements with the Remote annotation
private Set<? extends Element> elements;
//map of all classes to generate by name
private HashMap<String, ClassEntry> classMap;
//list of all method entries
private ArrayList<MethodEntry> methods;
//list of all method entries
private ArrayList<ClassEntry> classes;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
if(round > 1) return false; //only process 2 rounds
round++;
try{
//round 1: find all annotations, generate *writers*
if(round == 1){
//get serializers
serializers = new IOFinder().findSerializers(roundEnv);
//last method ID used
int lastMethodID = 0;
//find all elements with the Remote annotation
elements = roundEnv.getElementsAnnotatedWith(Remote.class);
//map of all classes to generate by name
classMap = new HashMap<>();
//list of all method entries
methods = new ArrayList<>();
//list of all method entries
classes = new ArrayList<>();
List<Element> orderedElements = new ArrayList<>(elements);
orderedElements.sort(Comparator.comparing(Object::toString));
//create methods
for(Element element : orderedElements){
Remote annotation = element.getAnnotation(Remote.class);
//check for static
if(!element.getModifiers().contains(Modifier.STATIC) || !element.getModifiers().contains(Modifier.PUBLIC)){
BaseProcessor.messager.printMessage(Kind.ERROR, "All @Remote methods must be public and static: ", element);
}
//can't generate none methods
if(annotation.targets() == Loc.none){
BaseProcessor.messager.printMessage(Kind.ERROR, "A @Remote method's targets() cannot be equal to 'none':", element);
}
//get and create class entry if needed
if(!classMap.containsKey(callLocation)){
ClassEntry clas = new ClassEntry(callLocation);
classMap.put(callLocation, clas);
classes.add(clas);
}
ClassEntry entry = classMap.get(callLocation);
//create and add entry
MethodEntry method = new MethodEntry(entry.name, BaseProcessor.getMethodName(element), annotation.targets(), annotation.variants(),
annotation.called(), annotation.unreliable(), annotation.forward(), lastMethodID++, (ExecutableElement)element, annotation.priority());
entry.methods.add(method);
methods.add(method);
}
//create read/write generators
RemoteWriteGenerator writegen = new RemoteWriteGenerator(serializers);
//generate the methods to invoke (write)
writegen.generateFor(classes, packageName);
return true;
}else if(round == 2){ //round 2: generate all *readers*
RemoteReadGenerator readgen = new RemoteReadGenerator(serializers);
//generate server readers
readgen.generateFor(methods.stream().filter(method -> method.where.isClient).collect(Collectors.toList()), readServerName, packageName, true);
//generate client readers
readgen.generateFor(methods.stream().filter(method -> method.where.isServer).collect(Collectors.toList()), readClientName, packageName, false);
//create class for storing unique method hash
TypeSpec.Builder hashBuilder = TypeSpec.classBuilder("MethodHash").addModifiers(Modifier.PUBLIC);
hashBuilder.addJavadoc(autogenWarning);
hashBuilder.addField(FieldSpec.builder(int.class, "HASH", Modifier.STATIC, Modifier.PUBLIC, Modifier.FINAL)
.initializer("$1L", Objects.hash(methods)).build());
//build and write resulting hash class
TypeSpec spec = hashBuilder.build();
JavaFile.builder(packageName, spec).build().writeTo(BaseProcessor.filer);
return true;
}
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
return false;
}
}

View File

@@ -0,0 +1,124 @@
package mindustry.annotations.remote;
import com.squareup.javapoet.*;
import mindustry.annotations.*;
import mindustry.annotations.Annotations.*;
import mindustry.annotations.remote.IOFinder.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.tools.Diagnostic.*;
import java.util.*;
import java.util.stream.*;
/** The annotation processor for generating remote method call code. */
@SupportedAnnotationTypes({
"mindustry.annotations.Annotations.Remote",
"mindustry.annotations.Annotations.WriteClass",
"mindustry.annotations.Annotations.ReadClass",
})
public class RemoteProcess extends BaseProcessor{
/** Maximum size of each event packet. */
public static final int maxPacketSize = 4096;
/** Warning on top of each autogenerated file. */
public static final String autogenWarning = "Autogenerated file. Do not modify!\n";
/** Name of class that handles reading and invoking packets on the server. */
private static final String readServerName = "RemoteReadServer";
/** Name of class that handles reading and invoking packets on the client. */
private static final String readClientName = "RemoteReadClient";
/** Simple class name of generated class name. */
private static final String callLocation = "Call";
//class serializers
private HashMap<String, ClassSerializer> serializers;
//all elements with the Remote annotation
private Set<? extends Element> elements;
//map of all classes to generate by name
private HashMap<String, ClassEntry> classMap;
//list of all method entries
private ArrayList<MethodEntry> methods;
//list of all method entries
private ArrayList<ClassEntry> classes;
{
rounds = 2;
}
@Override
public void process(RoundEnvironment roundEnv) throws Exception{
//round 1: find all annotations, generate *writers*
if(round == 1){
//get serializers
serializers = new IOFinder().findSerializers(roundEnv);
//last method ID used
int lastMethodID = 0;
//find all elements with the Remote annotation
elements = roundEnv.getElementsAnnotatedWith(Remote.class);
//map of all classes to generate by name
classMap = new HashMap<>();
//list of all method entries
methods = new ArrayList<>();
//list of all method entries
classes = new ArrayList<>();
List<Element> orderedElements = new ArrayList<>(elements);
orderedElements.sort(Comparator.comparing(Object::toString));
//create methods
for(Element element : orderedElements){
Remote annotation = element.getAnnotation(Remote.class);
//check for static
if(!element.getModifiers().contains(Modifier.STATIC) || !element.getModifiers().contains(Modifier.PUBLIC)){
BaseProcessor.messager.printMessage(Kind.ERROR, "All @Remote methods must be public and static: ", element);
}
//can't generate none methods
if(annotation.targets() == Loc.none){
BaseProcessor.messager.printMessage(Kind.ERROR, "A @Remote method's targets() cannot be equal to 'none':", element);
}
//get and create class entry if needed
if(!classMap.containsKey(callLocation)){
ClassEntry clas = new ClassEntry(callLocation);
classMap.put(callLocation, clas);
classes.add(clas);
}
ClassEntry entry = classMap.get(callLocation);
//create and add entry
MethodEntry method = new MethodEntry(entry.name, BaseProcessor.getMethodName(element), annotation.targets(), annotation.variants(),
annotation.called(), annotation.unreliable(), annotation.forward(), lastMethodID++, (ExecutableElement)element, annotation.priority());
entry.methods.add(method);
methods.add(method);
}
//create read/write generators
RemoteWriteGenerator writegen = new RemoteWriteGenerator(serializers);
//generate the methods to invoke (write)
writegen.generateFor(classes, packageName);
}else if(round == 2){ //round 2: generate all *readers*
RemoteReadGenerator readgen = new RemoteReadGenerator(serializers);
//generate server readers
readgen.generateFor(methods.stream().filter(method -> method.where.isClient).collect(Collectors.toList()), readServerName, packageName, true);
//generate client readers
readgen.generateFor(methods.stream().filter(method -> method.where.isServer).collect(Collectors.toList()), readClientName, packageName, false);
//create class for storing unique method hash
TypeSpec.Builder hashBuilder = TypeSpec.classBuilder("MethodHash").addModifiers(Modifier.PUBLIC);
hashBuilder.addJavadoc(autogenWarning);
hashBuilder.addField(FieldSpec.builder(int.class, "HASH", Modifier.STATIC, Modifier.PUBLIC, Modifier.FINAL)
.initializer("$1L", Objects.hash(methods)).build());
//build and write resulting hash class
TypeSpec spec = hashBuilder.build();
JavaFile.builder(packageName, spec).build().writeTo(BaseProcessor.filer);
}
}
}

View File

@@ -33,7 +33,7 @@ public class RemoteReadGenerator{
throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException{ throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException{
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC); TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning); classBuilder.addJavadoc(RemoteProcess.autogenWarning);
//create main method builder //create main method builder
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("readPacket") MethodSpec.Builder readMethod = MethodSpec.methodBuilder("readPacket")

View File

@@ -27,11 +27,11 @@ public class RemoteWriteGenerator{
for(ClassEntry entry : entries){ for(ClassEntry entry : entries){
//create builder //create builder
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(entry.name).addModifiers(Modifier.PUBLIC); TypeSpec.Builder classBuilder = TypeSpec.classBuilder(entry.name).addModifiers(Modifier.PUBLIC);
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning); classBuilder.addJavadoc(RemoteProcess.autogenWarning);
//add temporary write buffer //add temporary write buffer
classBuilder.addField(FieldSpec.builder(ByteBuffer.class, "TEMP_BUFFER", Modifier.STATIC, Modifier.PRIVATE, Modifier.FINAL) classBuilder.addField(FieldSpec.builder(ByteBuffer.class, "TEMP_BUFFER", Modifier.STATIC, Modifier.PRIVATE, Modifier.FINAL)
.initializer("ByteBuffer.allocate($1L)", RemoteMethodAnnotationProcessor.maxPacketSize).build()); .initializer("ByteBuffer.allocate($1L)", RemoteProcess.maxPacketSize).build());
//go through each method entry in this class //go through each method entry in this class
for(MethodEntry methodEntry : entry.methods){ for(MethodEntry methodEntry : entry.methods){

View File

@@ -0,0 +1,50 @@
package mindustry.annotations.util;
import com.squareup.javapoet.*;
import mindustry.annotations.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
public class Selement<T extends Element>{
public final T e;
public Selement(T e){
this.e = e;
}
public Element up(){
return e.getEnclosingElement();
}
public TypeMirror mirror(){
return e.asType();
}
public TypeName tname(){
return TypeName.get(mirror());
}
public ClassName cname(){
return ClassName.get((TypeElement)BaseProcessor.typeu.asElement(mirror()));
}
public String name(){
return e.getSimpleName().toString();
}
@Override
public String toString(){
return e.toString();
}
@Override
public int hashCode(){
return e.hashCode();
}
@Override
public boolean equals(Object o){
return o != null && o.getClass() == getClass() && ((Selement)o).e.equals(e);
}
}

View File

@@ -0,0 +1,48 @@
package mindustry.annotations.util;
import arc.struct.*;
import com.squareup.javapoet.*;
import com.sun.source.tree.*;
import mindustry.annotations.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
public class Smethod extends Selement<ExecutableElement>{
public Smethod(ExecutableElement executableElement){
super(executableElement);
}
public boolean is(Modifier mod){
return e.getModifiers().contains(mod);
}
public Array<TypeMirror> thrown(){
return Array.with(e.getThrownTypes()).as(TypeMirror.class);
}
public Array<TypeName> thrownt(){
return Array.with(e.getThrownTypes()).map(TypeName::get);
}
public Array<TypeParameterElement> typeVariables(){
return Array.with(e.getTypeParameters()).as(TypeParameterElement.class);
}
public Array<Svar> params(){
return Array.with(e.getParameters()).map(Svar::new);
}
public TypeMirror ret(){
return e.getReturnType();
}
public TypeName retn(){
return TypeName.get(ret());
}
public MethodTree tree(){
return BaseProcessor.trees.getTree(e);
}
}

View File

@@ -0,0 +1,60 @@
package mindustry.annotations.util;
import arc.struct.*;
import mindustry.annotations.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import java.lang.annotation.*;
public class Stype extends Selement<TypeElement>{
public Stype(TypeElement typeElement){
super(typeElement);
}
public static Stype of(TypeMirror mirror){
return new Stype((TypeElement)BaseProcessor.typeu.asElement(mirror));
}
public Array<Stype> interfaces(){
return Array.with(e.getInterfaces()).map(Stype::of);
}
public Array<Stype> superclasses(){
Array<Stype> out = new Array<>();
Stype sup = superclass();
while(!sup.name().equals("Object")){
out.add(sup);
sup = sup.superclass();
}
return out;
}
public Stype superclass(){
return new Stype((TypeElement)BaseProcessor.typeu.asElement(BaseProcessor.typeu.directSupertypes(mirror()).get(0)));
}
public <A extends Annotation> A annotation(Class<A> annotation){
return e.getAnnotation(annotation);
}
public Array<Svar> fields(){
return Array.with(e.getEnclosedElements()).select(e -> e instanceof VariableElement).map(e -> new Svar((VariableElement)e));
}
public Array<Smethod> methods(){
return Array.with(e.getEnclosedElements()).select(e -> e instanceof ExecutableElement
&& !e.getSimpleName().toString().contains("<")).map(e -> new Smethod((ExecutableElement)e));
}
public Array<Smethod> constructors(){
return Array.with(e.getEnclosedElements()).select(e -> e instanceof ExecutableElement
&& e.getSimpleName().toString().contains("<")).map(e -> new Smethod((ExecutableElement)e));
}
@Override
public TypeMirror mirror(){
return e.asType();
}
}

View File

@@ -0,0 +1,21 @@
package mindustry.annotations.util;
import com.sun.source.tree.*;
import mindustry.annotations.*;
import javax.lang.model.element.*;
public class Svar extends Selement<VariableElement>{
public Svar(VariableElement e){
super(e);
}
public boolean is(Modifier mod){
return e.getModifiers().contains(mod);
}
public VariableTree tree(){
return (VariableTree)BaseProcessor.trees.getTree(e);
}
}

View File

@@ -1,5 +0,0 @@
mindustry.annotations.remote.RemoteMethodAnnotationProcessor
mindustry.annotations.impl.StructAnnotationProcessor
mindustry.annotations.impl.SerializeAnnotationProcessor
mindustry.annotations.impl.AssetsAnnotationProcessor
mindustry.annotations.impl.CallSuperAnnotationProcessor

View File

@@ -134,6 +134,7 @@ allprojects{
} }
writeProcessors = { writeProcessors = {
new File(rootDir, "annotations/src/main/resources/META-INF/services/").mkdirs()
def processorFile = new File(rootDir, "annotations/src/main/resources/META-INF/services/javax.annotation.processing.Processor") def processorFile = new File(rootDir, "annotations/src/main/resources/META-INF/services/javax.annotation.processing.Processor")
def text = new StringBuilder() def text = new StringBuilder()
def files = new File(rootDir, "annotations/src/main/java") def files = new File(rootDir, "annotations/src/main/java")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 252 B

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