diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 22b5902ff6..b26968cd34 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -1,8 +1,6 @@ + package="io.anuke.mindustry"> diff --git a/android/build.gradle b/android/build.gradle index 6f2e209045..d6565684cb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -12,6 +12,14 @@ dependencies { implementation 'org.sufficientlysecure:donations:2.5' } +task deploy(type: Copy){ + dependsOn "assembleRelease" + + from "build/outputs/apk/google/release/android-google-release.apk" + into "../deploy/"; + rename ("android-google-release.apk", appName + "-android-" + getVersionString() + ".apk"); +} + android { buildToolsVersion '26.0.2' compileSdkVersion 26 @@ -31,10 +39,21 @@ android { packagingOptions { exclude 'META-INF/robovm/ios/robovm.xml' } + defaultConfig { + def vfile = file('../core/assets/version.properties') + def props = new Properties() + props.load(new FileInputStream(vfile)) + + def code = props['androidBuildCode'].toInteger() + 1 + props['androidBuildCode'] = code.toString() + props.store(vfile.newWriter(), "Autogenerated file. Do not modify.") + applicationId "io.anuke.mindustry" minSdkVersion 9 targetSdkVersion 26 + versionCode code + versionName "$versionNumber-$versionType-${props['build'].replace(" ", "-")}" } compileOptions { @@ -49,6 +68,21 @@ android { buildConfigField "boolean", "DONATIONS_GOOGLE", "true" } } + + signingConfigs { + release { + storeFile file(RELEASE_STORE_FILE) + storePassword RELEASE_STORE_PASSWORD + keyAlias RELEASE_KEY_ALIAS + keyPassword RELEASE_KEY_PASSWORD + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + } + } } // called every time gradle gets executed, takes the native dependencies of // the natives configuration, and extracts them to the proper libs/ folders diff --git a/build.gradle b/build.gradle index eba5f5987f..8d85801fc5 100644 --- a/build.gradle +++ b/build.gradle @@ -19,10 +19,26 @@ allprojects { version = 'release' ext { - appName = "Mindustry" + versionNumber = '3.3' + versionType = 'beta' + appName = 'Mindustry' gdxVersion = '1.9.8' aiVersion = '1.8.1' uCoreVersion = 'a480029' + + getVersionString = { + String buildVersion = getBuildVersion() + return "$versionNumber-$versionType-$buildVersion" + } + + getBuildVersion = { + if(!project.hasProperty("buildversion")) return "custom build" + return project.getProperties()["buildversion"] + } + + getPackage = { + return project.ext.mainClassName.substring(0, project.ext.mainClassName.indexOf("desktop") - 1) + } } repositories { diff --git a/core/assets-raw/sprites/blocks/fluxpump.png b/core/assets-raw/sprites/blocks/fluxpump.png index 34f0bd0bd2..042ee86214 100644 Binary files a/core/assets-raw/sprites/blocks/fluxpump.png and b/core/assets-raw/sprites/blocks/fluxpump.png differ diff --git a/core/assets-raw/sprites/blocks/pulseconduitbottom.png b/core/assets-raw/sprites/blocks/pulseconduitbottom.png index 9516c4df01..304dc71403 100644 Binary files a/core/assets-raw/sprites/blocks/pulseconduitbottom.png and b/core/assets-raw/sprites/blocks/pulseconduitbottom.png differ diff --git a/core/assets-raw/sprites/blocks/pulseconduittop.png b/core/assets-raw/sprites/blocks/pulseconduittop.png index aa94217f1d..a2d6cc9c54 100644 Binary files a/core/assets-raw/sprites/blocks/pulseconduittop.png and b/core/assets-raw/sprites/blocks/pulseconduittop.png differ diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 94daf26dec..75a3e8ef73 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/version.properties b/core/assets/version.properties new file mode 100644 index 0000000000..8703f4dbfb --- /dev/null +++ b/core/assets/version.properties @@ -0,0 +1,7 @@ +#Autogenerated file. Do not modify. +#Thu Feb 08 23:39:41 EST 2018 +version=beta +androidBuildCode=124 +name=Mindustry +code=3.3 +build=custom build diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 3e6b6d593f..8d7734d025 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -22,11 +22,6 @@ import io.anuke.ucore.scene.ui.layout.Unit; import java.util.Locale; public class Vars{ - public static final String versionName = "Mindustry"; - public static final String versionType = "Beta"; - public static final byte versionBuild = 20; - public static final byte versionMajor = 3; - public static final byte versionMinor = 3; public static final boolean testAndroid = false; //shorthand for whether or not this is running on android diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 8658182f9a..767174c5d4 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -304,12 +304,12 @@ public class NetClient extends Module { } private void finishConnecting(){ - Net.send(new ConnectConfirmPacket(), SendMode.tcp); state.set(State.playing); connecting = false; ui.loadfrag.hide(); ui.join.hide(); Net.setClientLoaded(true); + Timers.runTask(1f, () -> Net.send(new ConnectConfirmPacket(), SendMode.tcp)); } public void beginConnecting(){ diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 3faaa890a6..a05dc75a4e 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -9,6 +9,7 @@ import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.SyncEntity; import io.anuke.mindustry.game.EventType.GameOverEvent; import io.anuke.mindustry.io.Platform; +import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.NetworkIO; @@ -47,8 +48,8 @@ public class NetServer extends Module{ Net.handleServer(ConnectPacket.class, (id, packet) -> { - if(packet.version != versionBuild){ - Net.kickConnection(id, packet.version > versionBuild ? KickReason.serverOutdated : KickReason.clientOutdated); + if(packet.version != Version.build && packet.version != -1){ //ignore 'custom builds' + Net.kickConnection(id, packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated); return; } diff --git a/core/src/io/anuke/mindustry/core/ThreadHandler.java b/core/src/io/anuke/mindustry/core/ThreadHandler.java index 885c48f99d..44ecb52beb 100644 --- a/core/src/io/anuke/mindustry/core/ThreadHandler.java +++ b/core/src/io/anuke/mindustry/core/ThreadHandler.java @@ -42,7 +42,7 @@ public class ThreadHandler { synchronized (updateLock) { rendered = true; - updateLock.notify(); + impl.notify(updateLock); } } @@ -83,7 +83,7 @@ public class ThreadHandler { synchronized(updateLock) { while(!rendered) { - updateLock.wait(); + impl.wait(updateLock); } rendered = false; } @@ -105,5 +105,7 @@ public class ThreadHandler { void sleep(long ms) throws InterruptedException; void start(Runnable run); void stop(); + void wait(Object object) throws InterruptedException; + void notify(Object object); } } diff --git a/core/src/io/anuke/mindustry/io/Maps.java b/core/src/io/anuke/mindustry/io/Maps.java index 26eec2fbe1..d4e80ec4b9 100644 --- a/core/src/io/anuke/mindustry/io/Maps.java +++ b/core/src/io/anuke/mindustry/io/Maps.java @@ -168,8 +168,8 @@ public class Maps implements Disposable{ } return true; }catch(Exception e){ - if(!android) Log.err(e); - Gdx.app.error("Mindustry-Maps", "Failed loading map file: " + file); + Log.err(e); + Log.err("Failed loading map file: {0}", file); return false; } } diff --git a/core/src/io/anuke/mindustry/io/Platform.java b/core/src/io/anuke/mindustry/io/Platform.java index 9c0aab5fdd..2bc70a6ef4 100644 --- a/core/src/io/anuke/mindustry/io/Platform.java +++ b/core/src/io/anuke/mindustry/io/Platform.java @@ -30,25 +30,12 @@ public abstract class Platform { public boolean isDebug(){return false;} public ThreadProvider getThreadProvider(){ return new ThreadProvider() { - @Override - public boolean isOnThread() { - return true; - } - - @Override - public void sleep(long ms) { - - } - - @Override - public void start(Runnable run) { - - } - - @Override - public void stop() { - - } + @Override public boolean isOnThread() {return true;} + @Override public void sleep(long ms) {} + @Override public void start(Runnable run) {} + @Override public void stop() {} + @Override public void notify(Object object) {} + @Override public void wait(Object object) {} }; } } diff --git a/core/src/io/anuke/mindustry/io/Version.java b/core/src/io/anuke/mindustry/io/Version.java new file mode 100644 index 0000000000..6328d20ba6 --- /dev/null +++ b/core/src/io/anuke/mindustry/io/Version.java @@ -0,0 +1,35 @@ +package io.anuke.mindustry.io; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.PropertiesUtils; +import io.anuke.ucore.util.Strings; + +import java.io.IOException; + +public class Version { + public static final String name; + public static final String type; + public static final String code; + public static final int build; + public static final String buildName; + + static{ + try { + FileHandle file = Gdx.files.internal("version.properties"); + + ObjectMap map = new ObjectMap<>(); + PropertiesUtils.load(map, file.reader()); + + name = map.get("name"); + type = map.get("version"); + code = map.get("code"); + build = Strings.canParseInt(map.get("build")) ? Integer.parseInt(map.get("build")) : -1; + buildName = build == -1 ? map.get("build") : "build " + build; + + }catch (IOException e){ + throw new RuntimeException(e); + } + } +} diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index 2df3c05475..91de4fd6d2 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.ReflectionException; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.SyncEntity; +import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Packet.ImportantPacket; import io.anuke.mindustry.resource.Item; import io.anuke.ucore.entities.Entities; @@ -11,8 +12,6 @@ import io.anuke.ucore.entities.EntityGroup; import java.nio.ByteBuffer; -import static io.anuke.mindustry.Vars.versionBuild; - /**Class for storing all packets.*/ public class Packets { @@ -58,7 +57,7 @@ public class Packets { @Override public void write(ByteBuffer buffer) { - buffer.putInt(versionBuild); + buffer.putInt(Version.build); buffer.put((byte)name.getBytes().length); buffer.put(name.getBytes()); buffer.put(android ? (byte)1 : 0); diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index 03af96f574..9dd218414c 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.io.Platform; +import io.anuke.mindustry.io.Version; import io.anuke.mindustry.ui.MenuButton; import io.anuke.mindustry.ui.PressGroup; import io.anuke.ucore.scene.builders.imagebutton; @@ -99,7 +100,7 @@ public class MenuFragment implements Fragment{ new table(){{ visible(() -> state.is(State.menu)); abottom().aleft(); - new label(versionName + " " + versionMajor + "." + versionMinor + " " + versionType + " / build " + versionBuild); + new label("Mindustry " + Version.code + " " + Version.type + " / " + Version.buildName); }}.end(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java b/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java index 6fd170fda9..9e96bcb4d9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/distribution/TunnelConveyor.java @@ -30,6 +30,8 @@ public class TunnelConveyor extends Block{ public void handleItem(Item item, Tile tile, Tile source){ TunnelEntity entity = tile.entity(); + if(entity.index >= entity.buffer.length) return; + Tile tunnel = getDestTunnel(tile, item); if(tunnel == null) return; Tile to = tunnel.getNearby(tunnel.getRotation()); diff --git a/desktop/build.gradle b/desktop/build.gradle index 6b7aed7e95..e124270646 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -4,11 +4,45 @@ sourceCompatibility = 1.8 sourceSets.main.java.srcDirs = [ "src/" ] project.ext.mainClassName = "io.anuke.mindustry.desktop.DesktopLauncher" -project.ext.assetsDir = new File("../core/assets"); +project.ext.assetsDir = new File("../core/assets") def PACKR_DIR = "$System.env.PACKR_DIR" def ICON_DIR = new File("core/assets/sprites/icon.icns") +ext.writeVersion = { + def pfile = new File('core/assets/version.properties') + def props = new Properties() + props.load(new FileInputStream(pfile)) + + String code = getBuildVersion() + + props["name"] = appName + props["version"] = versionType + props["code"] = versionNumber + props["build"] = code + + props.store(pfile.newWriter(), "Autogenerated file. Do not modify.") +} + +ext.getPlatform = { + if (project.hasProperty("platform")) { + def lc = platform.toLowerCase() + if (lc == "windows64") { + return "windows64" + } else if (lc == "windows32") { + return "windows32" + } else if (lc == "linux") { + return "linux64" + } else if (lc == "mac") { + return "mac" + } else { + throw new InvalidUserDataException("Invalid platform. Set platform with -Pplatform=windows/linux/mac") + } + } else { + throw new InvalidUserDataException("No platform defined. Set platform with -Pplatform=windows/linux/mac") + } +} + task run(dependsOn: classes, type: JavaExec) { main = project.mainClassName classpath = sourceSets.main.runtimeClasspath @@ -30,80 +64,50 @@ task debug(dependsOn: classes, type: JavaExec) { } task dist(type: Jar) { + dependsOn classes + + writeVersion() + from files(sourceSets.main.output.classesDirs) from files(sourceSets.main.output.resourcesDir) from {configurations.compile.collect {zipTree(it)}} - from files(project.assetsDir); - + from files(project.assetsDir) + manifest { attributes 'Main-Class': project.mainClassName } } -dist.dependsOn classes - task clearOut(type: Delete){ - delete "packr-out/" -} - -ext.getPlatform = { - if(project.gradle.startParameter.taskNames.size() == 0 || !project.gradle.startParameter.taskNames.first().contains("packr")) return; - - if(!project.hasProperty("version")){ - throw new InvalidUserDataException("No version set. Set version with -Pversion=name"); + doLast { + delete "packr-out/" } - - if (project.hasProperty("platform")) { - def lc = platform.toLowerCase() - if(lc.equals("windows64")) { - return "windows64"; - }else if(lc.equals("windows32")){ - return "windows32"; - }else if(lc.equals("linux")){ - return "linux64"; - }else if(lc.equals("mac")){ - return "mac"; - }else{ - throw new InvalidUserDataException("Invalid platform. Set platform with -Pplatform=windows/linux/mac"); - } - }else{ - throw new InvalidUserDataException("No platform defined. Set platform with -Pplatform=windows/linux/mac"); - } -} - -ext.getDeployVersion = { - if(project.gradle.startParameter.taskNames.size() == 0 || !project.gradle.startParameter.taskNames.first().contains("packr")) return; - - if(!project.hasProperty("deployversion")){ - throw new InvalidUserDataException("No version set. Set version with -Pdeployversion=name"); - } - - return deployversion; -} - -ext.getPackage = { - return project.ext.mainClassName.substring(0, project.ext.mainClassName.indexOf("desktop") - 1) } //note: call desktop:dist beforehand -task packrCmd(type: Exec) { +task packrCmd() { - copy{ - into PACKR_DIR - from "build/libs/desktop-release.jar" - } + doLast { - commandLine "java", "-jar", PACKR_DIR+"packr.jar", - "--verbose", - "--bundle", getPackage(), - "--platform", getPlatform(), - "--executable", appName, - "--output", "packr-out/", - "--mainclass", project.ext.mainClassName, - "--jdk", PACKR_DIR+"jdk-"+getPlatform()+".zip", - "--icon", ICON_DIR.getAbsolutePath(), - "--classpath", "--", PACKR_DIR+"config.json" - + copy { + into PACKR_DIR + from "build/libs/desktop-release.jar" + } + + exec { + + commandLine "java", "-jar", PACKR_DIR + "packr.jar", + "--verbose", + "--bundle", getPackage(), + "--platform", getPlatform(), + "--executable", appName, + "--output", "packr-out/", + "--mainclass", project.ext.mainClassName, + "--jdk", PACKR_DIR + "jdk-" + getPlatform() + ".zip", + "--icon", ICON_DIR.getAbsolutePath(), + "--classpath", "--", PACKR_DIR + "config.json" + } + } } task fixMac (type: Copy){ @@ -134,26 +138,27 @@ task fixWindows32 (type: Copy){ } } -task packrZip(type: Zip) { - dependsOn "packrCmd" - finalizedBy "clearOut" +task packrZip() { + dependsOn "packrCmd" + finalizedBy "clearOut" - if(getPlatform().equals("mac")){ - dependsOn "fixMac" - } + if(project.hasProperty("platform")) { - if(getPlatform().equals("windows32")){ - dependsOn "fixWindows32" - } - - from "packr-out/" - archiveName appName + "-" + getPlatform() + "-" + getDeployVersion() + ".zip" - destinationDir(file("packr-export")) - - doLast{ - delete{ - delete "null/" + if (getPlatform() == "mac") { + dependsOn "fixMac" } + + if (getPlatform() == "windows32") { + dependsOn "fixWindows32" + } + + task zip (type: Zip){ + from "packr-out/" + archiveName "$appName-${getPlatform()}-${getVersionString()}.zip" + destinationDir(file("packr-export")) + } + + finalizedBy 'zip' } } @@ -167,7 +172,7 @@ eclipse { task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { doLast { def classpath = new XmlParser().parse(file(".classpath")) - new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]); + new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]) def writer = new FileWriter(file(".classpath")) def printer = new XmlNodePrinter(new PrintWriter(writer)) printer.setPreserveWhitespace(true) diff --git a/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java b/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java index 64e8b62240..1cc8fe072f 100644 --- a/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java +++ b/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java @@ -37,4 +37,14 @@ public class DefaultThreadImpl implements ThreadProvider { thread = null; } } + + @Override + public void wait(Object object) throws InterruptedException{ + object.wait(); + } + + @Override + public void notify(Object object) { + object.notify(); + } } diff --git a/server/build.gradle b/server/build.gradle index 3ea6be98dc..0ea3b61d79 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -6,16 +6,6 @@ sourceSets.main.java.srcDirs = [ "src/" ] project.ext.mainClassName = "io.anuke.mindustry.server.ServerLauncher" project.ext.assetsDir = new File("../core/assets"); -ext.getDeployVersion = { - if(project.gradle.startParameter.taskNames.size() == 0 || !project.gradle.startParameter.taskNames.first().contains("deploy")) return; - - if(!project.hasProperty("deployversion")){ - throw new InvalidUserDataException("No version set. Set version with -Pdeployversion=name"); - } - - return deployversion; -} - task run(dependsOn: classes, type: JavaExec) { main = project.mainClassName classpath = sourceSets.main.runtimeClasspath @@ -52,7 +42,7 @@ task deploy(type: Copy){ from "build/libs/server-release.jar" into "../deploy/"; - rename ("server-release.jar", appName + "-server-" + getDeployVersion() + ".jar"); + rename ("server-release.jar", appName + "-server-" + getVersionString() + ".jar"); } dist.dependsOn classes