diff --git a/.gitignore b/.gitignore index 4e59ef8187..9968b90f8e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,8 +23,6 @@ saves/ steam_appid.txt /test_files/ /annotations/build/ -/desktop-sdl/build/ -desktop-sdl/build/ /android/assets/mindustry-maps/ /android/assets/mindustry-saves/ /core/assets/gifexport/ @@ -35,6 +33,7 @@ desktop-sdl/build/ ios/robovm.properties packr-out/ config/ +changelog *.gif version.properties diff --git a/.travis.yml b/.travis.yml index 171280c268..f0586c145c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ deploy: api_key: secure: Cv5wFtWt62/A24EvSEQvMow7gKPbZ3oATEFPuSghhB2TQz1dA40Zee3Qvk4LFlpLrhYo4K0ZSczCZRGpR+hCd8+Dpww52bheYEvWuh3ZQfvu/fXtEx2j5PwP1qMpmIgSxETV/gkD7l9FImdh0VzktYiAvQfmi0bEocG9/D4QwjFpNat7iwBdcMiw1MvAygpdIWRsjiw0RKlB2mWarmoHhQ7Gu7qlU3j50uaEvcrtmU0pBUPggNQwQRv32i9NPvNFxrqqlUjDLIS8JFea99zCkp8BwYqbEvBIMzd+Qip1/stLJJA3+cDUClbsDtg8rAVetzpOrdLEEBmqShFe5MDl2yEHcsgpN9CFsyTaUfvB3P3rVjizvycMm42IsUkXQiarm5xTQ/TIA8Rd8AHiSKuweNCg1Fd5SFaRtKy8JVLXuxyfUccmyje6hhz2L4lS2Wfj3mAG7sqZUCXhWP79EKdGkiPOjKv4CwXEKmuH3BMVqPlNUZJr9Eg3sV1FG0h2l+MVOOnR635qdUbb49sYojYxVruMLX0BH1c4ZCu230m8CUoWA1Em1QNI75ya7+9Y5T6AsgWDVpBvdUo9fWNbdp+VQ0GskFQsJD5wtnxbcbHeFiERAgGBm7z6qt9u9LrQpBH+dsW52ADvYsu3L4nQEa+sdMHwTTwmGY+iUvsxu0DqxGg= file: - - desktop/build/libs/desktop-release.jar + - desktop/build/libs/Mindustry.jar - server/build/libs/server-release.jar on: repo: Anuken/Mindustry diff --git a/README.md b/README.md index 791a99452b..b0ec7c49e3 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ 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.
-After building, the output .JAR file should be in `/desktop/build/libs/desktop-release.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. ### Downloads diff --git a/android/build.gradle b/android/build.gradle index e24bbab771..b1b9ef5628 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript{ } dependencies{ - classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.android.tools.build:gradle:3.5.0' } } diff --git a/build.gradle b/build.gradle index b743d32379..11c75a5436 100644 --- a/build.gradle +++ b/build.gradle @@ -146,23 +146,6 @@ allprojects{ project(":desktop"){ apply plugin: "java" - dependencies{ - compile project(":core") - compile project(":net") - - if(debugged()) compile project(":debug") - - compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" - compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" - - compile arcModule("backends:backend-lwjgl3") - compile 'com.github.MinnDevelopment:java-discord-rpc:v2.0.2' - } -} - -project(":desktop-sdl"){ - apply plugin: "java" - dependencies{ compile project(":core") compile project(":net") @@ -318,3 +301,24 @@ project(":net"){ compile "org.lz4:lz4-java:1.4.1" } } + +task deployAll{ + task cleanDeployOutput{ + doFirst{ + if("${getBuildVersion()}" == "custom build" || "${getBuildVersion()}" == "") throw new IllegalArgumentException("----\n\nSET A BUILD NUMBER FIRST!\n\n----") + if(!project.hasProperty("release")) throw new IllegalArgumentException("----\n\nSET THE RELEASE PROJECT PROPERTY FIRST!\n\n----") + + delete{ + delete "deploy/" + } + } + } + + dependsOn cleanDeployOutput + dependsOn "desktop:packrLinux64" + dependsOn "desktop:packrWindows64" + dependsOn "desktop:packrWindows32" + dependsOn "desktop:packrMacOS" + dependsOn "server:deploy" + dependsOn "android:deploy" +} \ No newline at end of file diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 4f6f4be95d..9fe58d1b1b 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -75,6 +75,7 @@ server.kicked.nameEmpty = Your chosen name is invalid. server.kicked.idInUse = You are already on this server! Connecting with two accounts is not permitted. server.kicked.customClient = This server does not support custom builds. Download an official version. server.kicked.gameover = Game over! +server.versions = Your version:[accent] {0}[]\nServer version:[accent] {1}[] host.info = The [accent]host[] button hosts a server on port [scarlet]6567[]. \nAnybody on the same [lightgray]wifi or local network[] should be able to see your server in their server list.\n\nIf you want people to be able to connect from anywhere by IP, [accent]port forwarding[] is required.\n\n[lightgray]Note: If someone is experiencing trouble connecting to your LAN game, make sure you have allowed Mindustry access to your local network in your firewall settings. Note that public networks sometimes do not allow server discovery. join.info = Here, you can enter a [accent]server IP[] to connect to, or discover [accent]local network[] servers to connect to.\nBoth LAN and WAN multiplayer is supported.\n\n[lightgray]Note: There is no automatic global server list; if you want to connect to someone by IP, you would need to ask the host for their IP. hostserver = Host Multiplayer Game diff --git a/core/assets/maps/veins.msav b/core/assets/maps/veins.msav index 87e62486c7..133d783abc 100644 Binary files a/core/assets/maps/veins.msav and b/core/assets/maps/veins.msav differ diff --git a/core/src/io/anuke/mindustry/content/TechTree.java b/core/src/io/anuke/mindustry/content/TechTree.java index 6ca60ed2c1..10930e51a5 100644 --- a/core/src/io/anuke/mindustry/content/TechTree.java +++ b/core/src/io/anuke/mindustry/content/TechTree.java @@ -227,12 +227,14 @@ public class TechTree implements ContentList{ node(turbineGenerator, () -> { node(thermalGenerator, () -> { - node(rtgGenerator, () -> { - node(differentialGenerator, () -> { - node(thoriumReactor, () -> { - node(impactReactor, () -> { + node(differentialGenerator, () -> { + node(thoriumReactor, () -> { + node(impactReactor, () -> { + + }); + + node(rtgGenerator, () -> { - }); }); }); }); diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index b4fbdc2151..2406ca7556 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -84,7 +84,7 @@ public class Control implements ApplicationListener{ }); Events.on(PlayEvent.class, event -> { - player.setTeam(state.rules.pvp ? netServer.assignTeam(playerGroup.all()) : defaultTeam); + player.setTeam(state.rules.pvp ? netServer.assignTeam(player, playerGroup.all()) : defaultTeam); player.setDead(true); player.add(); diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index ede04df856..8d210cb930 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -176,7 +176,7 @@ public class NetServer implements ApplicationListener{ //playing in pvp mode automatically assigns players to teams if(state.rules.pvp){ - player.setTeam(assignTeam(playerGroup.all())); + player.setTeam(assignTeam(player, playerGroup.all())); Log.info("Auto-assigned player {0} to team {1}.", player.name, player.getTeam()); } @@ -194,13 +194,13 @@ public class NetServer implements ApplicationListener{ }); } - public Team assignTeam(Iterable players){ + public Team assignTeam(Player current, Iterable players){ //find team with minimum amount of players and auto-assign player to that. return Structs.findMin(Team.all, team -> { if(state.teams.isActive(team) && !state.teams.get(team).cores.isEmpty()){ int count = 0; for(Player other : players){ - if(other.getTeam() == team){ + if(other.getTeam() == team && other != current){ count++; } } diff --git a/core/src/io/anuke/mindustry/entities/type/Player.java b/core/src/io/anuke/mindustry/entities/type/Player.java index dbc26c34fb..6d0ab81cc5 100644 --- a/core/src/io/anuke/mindustry/entities/type/Player.java +++ b/core/src/io/anuke/mindustry/entities/type/Player.java @@ -527,7 +527,9 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{ spawner = null; } - avoidOthers(); + if(isLocal || Net.server()){ + avoidOthers(); + } Tile tile = world.tileWorld(x, y); diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index e2360e16e5..aebe5859b0 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -214,7 +214,12 @@ public class Maps implements Disposable{ return filters; }else{ - return JsonIO.read(Array.class, str); + try{ + return JsonIO.read(Array.class, str); + }catch(Exception e){ + e.printStackTrace(); + return readFilters(""); + } } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index 71f72577fc..7b1486c270 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -1,21 +1,20 @@ package io.anuke.mindustry.ui.dialogs; -import io.anuke.annotations.Annotations.Serialize; -import io.anuke.arc.Core; -import io.anuke.arc.collection.Array; -import io.anuke.arc.graphics.Color; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.scene.style.Drawable; +import io.anuke.annotations.Annotations.*; +import io.anuke.arc.*; +import io.anuke.arc.collection.*; +import io.anuke.arc.graphics.*; +import io.anuke.arc.math.*; +import io.anuke.arc.scene.style.*; import io.anuke.arc.scene.ui.*; -import io.anuke.arc.scene.ui.layout.Cell; -import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.arc.util.Strings; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.core.Platform; -import io.anuke.mindustry.game.Version; -import io.anuke.mindustry.net.Host; +import io.anuke.arc.scene.ui.layout.*; +import io.anuke.arc.util.*; +import io.anuke.mindustry.*; +import io.anuke.mindustry.core.*; +import io.anuke.mindustry.game.*; import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.net.*; +import io.anuke.mindustry.net.Packets.*; import static io.anuke.mindustry.Vars.*; @@ -97,9 +96,14 @@ public class JoinDialog extends FloatingDialog{ TextButton button = buttons[0] = remote.addButton("[accent]" + server.displayIP(), "clear", () -> { if(!buttons[0].childrenPressed()){ - connect(server.ip, server.port); + if(server.lastHost != null && server.lastHost.version != Version.build && Version.build != -1 && server.lastHost.version != -1){ + ui.showInfo("[scarlet]" + (server.lastHost.version > Version.build ? KickReason.clientOutdated : KickReason.serverOutdated).toString() + "\n[]" + + Core.bundle.format("server.versions", Version.build, server.lastHost.version)); + }else{ + connect(server.ip, server.port); + } } - }).width(targetWidth()).height(130f).pad(4f).get(); + }).width(targetWidth()).pad(4f).get(); button.getLabel().setWrap(true); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java index 36baa4125f..55de763cc2 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ZoneInfoDialog.java @@ -113,9 +113,16 @@ public class ZoneInfoDialog extends FloatingDialog{ t.add("$zone.resources").padRight(6); if(zone.resources.length > 0){ - for(Item item : zone.resources){ - t.addImage(item.icon(Item.Icon.medium)).size(8 * 3); - } + t.table(r -> { + t.left(); + int i = 0; + for(Item item : zone.resources){ + r.addImage(item.icon(Item.Icon.medium)).size(8 * 3); + if(++i % 4 == 0){ + r.row(); + } + } + }); }else{ t.add("$none"); } diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 6c6b0beaaf..72a01f3070 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -242,9 +242,9 @@ public class HudFragment extends Fragment{ IntFormat fps = new IntFormat("fps"); IntFormat ping = new IntFormat("ping"); - info.label(() -> fps.get(Core.graphics.getFramesPerSecond())).left(); + info.label(() -> fps.get(Core.graphics.getFramesPerSecond())).left().style("outline"); info.row(); - info.label(() -> ping.get(Net.getPing())).visible(Net::client).left(); + info.label(() -> ping.get(Net.getPing())).visible(Net::client).left().style("outline"); }).top().left(); }); diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 577d40771e..189911c66f 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -294,9 +294,7 @@ public class Block extends BlockStorage{ /** Called after the block is placed by this client. */ @CallSuper public void playerPlaced(Tile tile){ - if(outputsPower && !consumesPower){ - PowerNode.lastPlaced = tile.pos(); - } + } /** Called after the block is placed by anyone. */ diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java index 86220b6acc..358fb27a43 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.annotations.Annotations.*; import io.anuke.arc.*; +import io.anuke.arc.collection.*; import io.anuke.arc.function.*; import io.anuke.arc.graphics.*; import io.anuke.arc.graphics.g2d.*; @@ -20,9 +21,7 @@ import io.anuke.mindustry.world.meta.*; import static io.anuke.mindustry.Vars.*; public class PowerNode extends PowerBlock{ - //last distribution block placed - public static int lastPlaced = -1; - + protected ObjectSet graphs = new ObjectSet<>(); protected Vector2 t1 = new Vector2(), t2 = new Vector2(); protected TextureRegion laser, laserEnd; @@ -99,23 +98,11 @@ public class PowerNode extends PowerBlock{ () -> Mathf.clamp(entity.power.graph.getPowerProduced() / entity.power.graph.getPowerNeeded()))); } - @Override - public void playerPlaced(Tile tile){ - Tile before = world.tile(lastPlaced); - - if(linkValid(tile, before) && !before.entity.proximity().contains(tile)){ - Call.linkPowerNodes(null, tile, before); - } - - lastPlaced = tile.pos(); - super.playerPlaced(tile); - } - @Override public void placed(Tile tile){ if(Net.client()) return; - Predicate valid = other -> other != null && other != tile && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower)) && linkValid(tile, other) + Predicate valid = other -> other != null && other != tile && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(tile, other) && !other.entity.proximity().contains(tile) && other.entity.power.graph != tile.entity.power.graph; tempTiles.clear(); @@ -132,6 +119,28 @@ public class PowerNode extends PowerBlock{ super.placed(tile); } + private void getPotentialLinks(Tile tile, Consumer others){ + Predicate valid = other -> other != null && other != tile && other.entity != null && other.entity.power != null && + ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && + overlaps(tile.x * tilesize + offset(), tile.y *tilesize + offset(), other, laserRange * tilesize) + && !other.entity.proximity().contains(tile) && !graphs.contains(other.entity.power.graph); + + tempTiles.clear(); + graphs.clear(); + Geometry.circle(tile.x, tile.y, (int)(laserRange + 1), (x, y) -> { + Tile other = world.ltile(x, y); + if(valid.test(other)){ + tempTiles.add(other); + } + }); + + tempTiles.sort(Structs.comparingFloat(t -> t.dst2(tile))); + tempTiles.each(valid, t -> { + graphs.add(t.entity.power.graph); + others.accept(t); + }); + } + @Override public void setStats(){ super.setStats(); @@ -213,6 +222,11 @@ public class PowerNode extends PowerBlock{ Draw.color(Pal.placing); Drawf.circles(x * tilesize + offset(), y * tilesize + offset(), laserRange * tilesize); + getPotentialLinks(tile, other -> { + Drawf.square(other.drawx(), other.drawy(), other.block().size * tilesize / 2f + 2f, Pal.place); + }); + + /* for(int cx = (int)(x - laserRange - 1); cx <= x + laserRange + 1; cx++){ for(int cy = (int)(y - laserRange - 1); cy <= y + laserRange + 1; cy++){ Tile link = world.ltile(cx, cy); @@ -221,7 +235,7 @@ public class PowerNode extends PowerBlock{ Drawf.square(link.drawx(), link.drawy(), link.block().size * tilesize / 2f + 2f, link.pos() == lastPlaced ? Pal.place : Pal.accent); } } - } + }*/ Draw.reset(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java b/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java index d53f6268c0..7c9da8619d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/LiquidConverter.java @@ -12,6 +12,11 @@ public class LiquidConverter extends GenericCrafter{ hasLiquids = true; } + @Override + public boolean outputsItems(){ + return false; + } + @Override public void init(){ ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid); diff --git a/desktop-sdl/build.gradle b/desktop-sdl/build.gradle deleted file mode 100644 index 08cf179196..0000000000 --- a/desktop-sdl/build.gradle +++ /dev/null @@ -1,99 +0,0 @@ -apply plugin: "java" - -sourceCompatibility = 1.8 -sourceSets.main.java.srcDirs = [ "src/" ] - -project.ext.mainClassName = "io.anuke.mindustry.desktopsdl.DesktopLauncher" -project.ext.assetsDir = new File("../core/assets") - -def IKVM_DIR = System.env.IKVM_HOME -def getTarget = { return project.hasProperty("target") ? project.properties["target"] : "windows" } - -task run(dependsOn: classes, type: JavaExec){ - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - workingDir = project.assetsDir - ignoreExitValue = true - - if(System.getProperty("os.name").toLowerCase().contains("mac")){ - jvmArgs("-XstartOnFirstThread", "-Djava.awt.headless=true") - } - - if(project.hasProperty("args")){ - args Eval.me(project.getProperties()["args"]) - } - - if(args.contains("debug")){ - main = "io.anuke.mindustry.DebugLauncher" - } -} - -task dist(type: Jar, dependsOn: classes){ - from files(sourceSets.main.output.classesDirs) - from files(sourceSets.main.output.resourcesDir) - from {configurations.compile.collect {zipTree(it)}} - from files(project.assetsDir) - - //use target = all for all platforms - def target = getTarget() - if(target.contains("windows")) exclude('**.so', "**.dylib") - if(target == "mac") exclude('**.so', "**.dll") - if(target == "linux") exclude('**.dll', "**.dylib") - archivesBaseName = appName + "-" + target - - manifest{ - attributes 'Main-Class': project.mainClassName - } -} - -task steamdist(dependsOn: dist){ - doLast{ - copy{ - from "build/libs/Mindustry-linux-release.jar" - into "/home/anuke/.steam/steam/steamapps/common/Mindustry" - rename { String fileName -> - fileName.replace("Mindustry-linux-release", "desktop-release") - } - } - } -} - -task ikZip(type: Zip){ - def filename = "$appName-${getTarget()}-${version}" - - from "build/libs/$filename" - archiveName = "${generateDeployName(getTarget())}.zip" -} - -task ikdist{ - dependsOn dist - finalizedBy ikZip - - doLast{ - def filename = "$appName-${getTarget()}-${version}" - def folder = "build/libs/$filename" - def baseArgs = System.properties['os.name'].toLowerCase().contains('windows') ? [] : ["mono"] - def args = baseArgs + ["$IKVM_DIR/ikvmc.exe", "-target:winexe", "-out:build/libs/${filename}.exe", "build/libs/${filename}.jar"] - if(file("../core/assets/sprites/icon.ico").exists()){ - args += ["-win32icon:../core/assets/sprites/icon.ico"] - }else if(file("../core/assets/icons/icon.ico").exists()){ - args += ["-win32icon:../core/assets/icons/icon.ico"] - } - - exec{ - commandLine args - } - - copy{ - from file("build/libs/${filename}.exe") - into file(folder) - } - - copy{ - from(getTarget().contains("32") ? "$IKVM_DIR/libraries_32" : "$IKVM_DIR/libraries") - into folder - } - } -} - diff --git a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/DesktopLauncher.java b/desktop-sdl/src/io/anuke/mindustry/desktopsdl/DesktopLauncher.java deleted file mode 100644 index 260cde9c7a..0000000000 --- a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/DesktopLauncher.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.anuke.mindustry.desktopsdl; -import io.anuke.arc.Files.*; -import io.anuke.arc.backends.sdl.*; -import io.anuke.mindustry.*; -import io.anuke.mindustry.core.*; -import io.anuke.mindustry.desktopsdl.steam.*; -import io.anuke.mindustry.net.*; - -public class DesktopLauncher{ - - public static void main(String[] arg){ - try{ - Platform.instance = new DesktopPlatform(arg); - - Net.setClientProvider(new ArcNetClient()); - Net.setServerProvider(new ServerSteam(new ArcNetServer())); - - new SdlApplication(new Mindustry(), new SdlConfig(){{ - title = "Mindustry"; - maximized = true; - depth = 0; - stencil = 0; - width = 900; - height = 700; - setWindowIcon(FileType.Internal, "icons/icon_64.png"); - }}); - }catch(Throwable e){ - DesktopPlatform.handleCrash(e); - } - } -} diff --git a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/DesktopPlatform.java b/desktop-sdl/src/io/anuke/mindustry/desktopsdl/DesktopPlatform.java deleted file mode 100644 index 98f7a07175..0000000000 --- a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/DesktopPlatform.java +++ /dev/null @@ -1,180 +0,0 @@ -package io.anuke.mindustry.desktopsdl; - -import club.minnced.discord.rpc.*; -import com.codedisaster.steamworks.*; -import io.anuke.arc.*; -import io.anuke.arc.backends.sdl.jni.*; -import io.anuke.arc.collection.*; -import io.anuke.arc.files.*; -import io.anuke.arc.function.*; -import io.anuke.arc.util.*; -import io.anuke.arc.util.serialization.*; -import io.anuke.mindustry.*; -import io.anuke.mindustry.core.GameState.*; -import io.anuke.mindustry.core.*; -import io.anuke.mindustry.desktopsdl.steam.*; -import io.anuke.mindustry.game.EventType.*; -import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.net.*; -import io.anuke.mindustry.ui.dialogs.*; - -import java.net.*; -import java.util.*; - -import static io.anuke.mindustry.Vars.*; - - -public class DesktopPlatform extends Platform{ - static boolean useDiscord = OS.is64Bit, useSteam = true; - final static String applicationId = "610508934456934412"; - String[] args; - - public DesktopPlatform(String[] args){ - this.args = args; - - testMobile = Array.with(args).contains("-testMobile"); - - if(useDiscord){ - try{ - DiscordEventHandlers handlers = new DiscordEventHandlers(); - DiscordRPC.INSTANCE.Discord_Initialize(applicationId, handlers, true, ""); - - Runtime.getRuntime().addShutdownHook(new Thread(DiscordRPC.INSTANCE::Discord_Shutdown)); - }catch(Throwable t){ - useDiscord = false; - Log.err("Failed to initialize discord.", t); - } - } - - if(useSteam){ - Vars.steam = true; - try{ - SteamAPI.loadLibraries(); - if(!SteamAPI.init()){ - Log.info("Steam client not running. Make sure Steam is running!"); - }else{ - //times per second - float interval = 20f; - Interval i = new Interval(); - - //run steam callbacks - Events.on(GameLoadEvent.class, event -> { - //update callbacks - Core.app.addListener(new ApplicationListener(){ - @Override - public void update(){ - if(i.get(interval)){ - if(SteamAPI.isSteamRunning()){ - SteamAPI.runCallbacks(); - } - } - } - }); - - Core.app.post(() -> new ClientSteam()); - }); - //steam shutdown hook - Runtime.getRuntime().addShutdownHook(new Thread(SteamAPI::shutdown)); - } - }catch(Exception e){ - Log.err("Failed to load Steam native libraries."); - e.printStackTrace(); - } - } - } - - static void handleCrash(Throwable e){ - Consumer dialog = Runnable::run; - boolean badGPU = false; - - if(e.getMessage() != null && (e.getMessage().contains("Couldn't create window") || e.getMessage().contains("OpenGL 2.0 or higher"))){ - - dialog.accept(() -> message( - e.getMessage().contains("Couldn't create window") ? "A graphics initialization error has occured! Try to update your graphics drivers:\n" + e.getMessage() : - "Your graphics card does not support OpenGL 2.0!\n" + - "Try to update your graphics drivers.\n\n" + - "(If that doesn't work, your computer just doesn't support Mindustry.)")); - badGPU = true; - } - - boolean fbgp = badGPU; - - CrashSender.send(e, file -> { - if(!fbgp){ - dialog.accept(() -> message("A crash has occured. It has been saved in:\n" + file.getAbsolutePath() + "\n" + (e.getMessage() == null ? "" : "\n" + e.getMessage()))); - } - }); - } - - @Override - public void showFileChooser(String text, String content, Consumer cons, boolean open, Predicate filetype){ - new FileChooser(text, file -> filetype.test(file.extension().toLowerCase()), open, cons).show(); - } - - @Override - public void updateRPC(){ - - if(!useDiscord) return; - - DiscordRichPresence presence = new DiscordRichPresence(); - - if(!state.is(State.menu)){ - String map = world.getMap() == null ? "Unknown Map" : world.isZone() ? world.getZone().localizedName : Strings.capitalize(world.getMap().name()); - String mode = state.rules.pvp ? "PvP" : state.rules.attackMode ? "Attack" : "Survival"; - String players = Net.active() && playerGroup.size() > 1 ? " | " + playerGroup.size() + " Players" : ""; - - presence.state = mode + players; - - if(!state.rules.waves){ - presence.details = map; - }else{ - presence.details = map + " | Wave " + state.wave; - presence.largeImageText = "Wave " + state.wave; - } - }else{ - if(ui.editor != null && ui.editor.isShown()){ - presence.state = "In Editor"; - }else if(ui.deploy != null && ui.deploy.isShown()){ - presence.state = "In Launch Selection"; - }else{ - presence.state = "In Menu"; - } - } - - presence.largeImageKey = "logo"; - - DiscordRPC.INSTANCE.Discord_UpdatePresence(presence); - } - - @Override - public String getUUID(){ - try{ - Enumeration e = NetworkInterface.getNetworkInterfaces(); - NetworkInterface out; - for(out = e.nextElement(); (out.getHardwareAddress() == null || !validAddress(out.getHardwareAddress())) && e.hasMoreElements(); out = e.nextElement()) ; - - byte[] bytes = out.getHardwareAddress(); - byte[] result = new byte[8]; - System.arraycopy(bytes, 0, result, 0, bytes.length); - - String str = new String(Base64Coder.encode(result)); - - if(str.equals("AAAAAAAAAOA=") || str.equals("AAAAAAAAAAA=")) throw new RuntimeException("Bad UUID."); - - return str; - }catch(Exception e){ - return super.getUUID(); - } - } - - private static void message(String message){ - SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MESSAGEBOX_ERROR, "oh no", message); - } - - private boolean validAddress(byte[] bytes){ - if(bytes == null) return false; - byte[] result = new byte[8]; - System.arraycopy(bytes, 0, result, 0, bytes.length); - return !new String(Base64Coder.encode(result)).equals("AAAAAAAAAOA=") && !new String(Base64Coder.encode(result)).equals("AAAAAAAAAAA="); - } -} diff --git a/desktop/build.gradle b/desktop/build.gradle index 65139a81c3..76adfe2684 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -1,43 +1,28 @@ +import com.badlogicgames.packr.Packr +import com.badlogicgames.packr.PackrConfig + apply plugin: "java" sourceCompatibility = 1.8 -sourceSets.main.java.srcDirs = ["src/"] +sourceSets.main.java.srcDirs = [ "src/" ] project.ext.mainClassName = "io.anuke.mindustry.desktop.DesktopLauncher" project.ext.assetsDir = new File("../core/assets") -def IKVM_DIR = System.env.IKVM_HOME - -import com.badlogicgames.packr.Packr -import com.badlogicgames.packr.PackrConfig - def JDK_DIR = "$System.env.PACKR_DIR" def ICON_DIR = new File("core/assets/icons/icon.icns") -ext.getPlatform = { - def lc = project.hasProperty("platform") ? platform.toLowerCase() : "" - if(lc == "windows64"){ - return PackrConfig.Platform.Windows64 - }else if(lc == "windows32"){ - return PackrConfig.Platform.Windows32 - }else if(lc == "linux"){ - return PackrConfig.Platform.Linux64 - }else if(lc == "mac"){ - return PackrConfig.Platform.MacOS - }else{ - throw new InvalidUserDataException("Invalid platform. Set platform with -Pplatform=windows64/windows32/linux/mac") - } -} - task run(dependsOn: classes, type: JavaExec){ main = project.mainClassName classpath = sourceSets.main.runtimeClasspath standardInput = System.in workingDir = project.assetsDir - if(System.getProperty("os.name").toLowerCase().contains("mac")){ - jvmArgs "-XstartOnFirstThread" - } ignoreExitValue = true + + if(System.getProperty("os.name").toLowerCase().contains("mac")){ + jvmArgs("-XstartOnFirstThread", "-Djava.awt.headless=true") + } + if(project.hasProperty("args")){ args Eval.me(project.getProperties()["args"]) } @@ -47,132 +32,122 @@ task run(dependsOn: classes, type: JavaExec){ } } -task debug(dependsOn: classes, type: JavaExec){ - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - workingDir = project.assetsDir - ignoreExitValue = true - debug = true -} - -task dist(type: Jar){ - dependsOn classes - - writeVersion() +task dist(type: Jar, dependsOn: classes){ from files(sourceSets.main.output.classesDirs) from files(sourceSets.main.output.resourcesDir) - from{ configurations.compile.collect{ zipTree(it) } } + from {configurations.compile.collect {zipTree(it)}} from files(project.assetsDir) + archiveName = "${appName}.jar" + manifest{ attributes 'Main-Class': project.mainClassName } } -//note: call desktop:dist beforehand -task packrCmd(){ - +task steamdist(dependsOn: dist){ doLast{ - def config = new PackrConfig() - config.with{ - config.executable = appName - verbose = true - platform = getPlatform() - bundleIdentifier = getPackage() + ".mac" - iconResource = ICON_DIR - outDir = file("packr-out/") - mainClass = project.ext.mainClassName - classpath = ["desktop/build/libs/desktop-release.jar"] - removePlatformLibs = ["desktop/build/libs/desktop-release.jar"] - - vmArgs = ["Djava.net.preferIPv4Stack=true"] - minimizeJre = "desktop/packr_minimize.json" - jdk = JDK_DIR + "jdk-${getPlatform().toString().toLowerCase()}.zip" - - if(getPlatform() == PackrConfig.Platform.MacOS){ - vmArgs += "XstartOnFirstThread" + copy{ + from "build/libs/Mindustry-linux-release.jar" + into "/home/anuke/.steam/steam/steamapps/common/Mindustry" + rename { String fileName -> + fileName.replace("Mindustry-linux-release", "desktop-release") } } - - new Packr().pack(config) - } -} - -task copyTemplate(){ - doLast{ - copy{ - into "packr-out/" - from "${JDK_DIR}/templates/${getPlatform().toString().toLowerCase()}" - } - - copy{ - into "packr-out/" - from "build/libs/desktop-release.jar" - } } } -task packrZip(){ - task clearOut(type: Delete){ - doLast{ - delete "packr-out/" - } - } +PackrConfig.Platform.values().each{ platform -> + task "packr${platform.toString()}"{ + def platformName = platform.toString().replace('64', '').replace('32', '').replace('MacOS', 'Mac') - task fixMac(type: Copy){ - dependsOn "packrCmd" - - into "packr-out/" + appName + ".app/Contents/" - from "packr-out/Contents/" - - doLast{ - delete{ - delete "packr-out/Contents/" - } - } - } - - task fixWindows32(type: Copy){ - dependsOn "packrCmd" - - into "packr-out/jre/bin/" - from JDK_DIR + "zip.dll" - rename("zip.dll", "ojdkbuild_zlib.dll") + dependsOn dist doLast{ copy{ - into "packr-out/jre/bin/" - from JDK_DIR + "zip.dll" + into "build/packr/" + rename("${appName}.jar", "desktop.jar") + from "build/libs/${appName}.jar" + } + + delete{ + delete "build/packr/output/" + } + + if(platform == PackrConfig.Platform.Windows32 || platform == PackrConfig.Platform.Windows64){ + copy{ + into "build/packr/output" + from "${JDK_DIR}/templates/${platform.toString().toLowerCase()}" + } + + copy{ + into "build/packr/output/jre" + rename("${appName}.jar", "desktop.jar") + from "build/libs/${appName}.jar" + } + }else{ + def config = new PackrConfig() + config.with{ + config.executable = appName + config.platform = platform + verbose = true + bundleIdentifier = getPackage() + ".mac" + iconResource = ICON_DIR + outDir = file("build/packr/output") + mainClass = project.ext.mainClassName + classpath = ["desktop/build/packr/desktop.jar"] + removePlatformLibs = ["desktop/build/packr/desktop.jar"] + + vmArgs = ["Djava.net.preferIPv4Stack=true"] + minimizeJre = "desktop/packr_minimize.json" + jdk = JDK_DIR + "jdk-${platform.toString().toLowerCase()}.zip" + + if(platform == PackrConfig.Platform.MacOS){ + vmArgs += "XstartOnFirstThread" + } + } + + new Packr().pack(config) + + if(platform == PackrConfig.Platform.Linux64){ + copy{ + into "build/packr/output/jre/" + from "build/packr/output/desktop.jar" + } + + delete{ + delete "build/packr/output/desktop.jar" + } + + file("build/packr/output/config.json").text = file("build/packr/output/config.json").text.replace("desktop.jar", "jre/desktop.jar") + } + + if(platform == PackrConfig.Platform.MacOS){ + copy{ + into "build/packr/${appName}.app/Contents/" + from "build/packr/Contents/" + } + + delete{ + delete "build/packr/Contents/" + } + } } } + + task "zip${platform.toString()}"(type: Zip){ + from "build/packr/output" + archiveName "${generateDeployName(platform.toString())}.zip" + destinationDir(file("../deploy")) + + doLast{ + delete{ + delete "build/packr/" + } + } + } + + finalizedBy "zip${platform.toString()}" } - - finalizedBy "clearOut" - - if(project.hasProperty("platform")){ - def plat = getPlatform() - if(plat == PackrConfig.Platform.Windows32 || plat == PackrConfig.Platform.Windows64){ - dependsOn "copyTemplate" - }else{ - dependsOn "packrCmd" - - if(getPlatform() == PackrConfig.Platform.MacOS){ - dependsOn "fixMac" - } - - if(getPlatform() == PackrConfig.Platform.Windows32){ - dependsOn "fixWindows32" - } - } - - task rzip(type: Zip){ - from "packr-out/" - archiveName "${generateDeployName(getPlatform().toString())}.zip" - destinationDir(file("packr-export")) - } - - finalizedBy 'rzip' - } -} \ No newline at end of file +} diff --git a/desktop/packr_minimize.json b/desktop/packr_minimize.json index 8be61942cc..a9e19bc83a 100644 --- a/desktop/packr_minimize.json +++ b/desktop/packr_minimize.json @@ -27,13 +27,25 @@ "com/sun/jndi", "com/sun/xml", "com/sun/script", - "sum/awt", + "sun/awt", "sun/java2d", "sun/font", "sun/rmi", "sun/swing", "java/util/stream", "com/sun/media", + "sun/print", + "sun/awt", + "sun/instrument", + "sun/security/tools", + "sun/security/smartcardio", + "sun/audio", + "javax/xml", + "javax/sound", + "javax/script", + "java/beans", + "java/applet", + "java/rmi", "com/sun/naming", "java/awt", "com/sun/org/apache/xpath", diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index d87a547712..571b7a752e 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -1,27 +1,30 @@ package io.anuke.mindustry.desktop; -import io.anuke.arc.backends.lwjgl3.Lwjgl3Application; -import io.anuke.arc.backends.lwjgl3.Lwjgl3ApplicationConfiguration; -import io.anuke.mindustry.Mindustry; -import io.anuke.mindustry.core.Platform; +import io.anuke.arc.Files.*; +import io.anuke.arc.backends.sdl.*; +import io.anuke.mindustry.*; +import io.anuke.mindustry.core.*; +import io.anuke.mindustry.desktop.steam.*; import io.anuke.mindustry.net.*; public class DesktopLauncher{ public static void main(String[] arg){ try{ - Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); - config.setTitle("Mindustry"); - config.setMaximized(true); - config.setBackBufferConfig(8, 8, 8, 8, 0, 0, 0); - config.setWindowedMode(900, 600); - config.setWindowIcon("icons/icon_64.png"); - Platform.instance = new DesktopPlatform(arg); Net.setClientProvider(new ArcNetClient()); - Net.setServerProvider(new ArcNetServer()); - new Lwjgl3Application(new Mindustry(), config); + Net.setServerProvider(new SteamServerImpl(new ArcNetServer())); + + new SdlApplication(new Mindustry(), new SdlConfig(){{ + title = "Mindustry"; + maximized = true; + depth = 0; + stencil = 0; + width = 900; + height = 700; + setWindowIcon(FileType.Internal, "icons/icon_64.png"); + }}); }catch(Throwable e){ DesktopPlatform.handleCrash(e); } diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java index 92da3ecb1c..357a735494 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java @@ -1,26 +1,30 @@ package io.anuke.mindustry.desktop; import club.minnced.discord.rpc.*; -import io.anuke.arc.collection.Array; -import io.anuke.arc.files.FileHandle; -import io.anuke.arc.function.Consumer; -import io.anuke.arc.function.Predicate; +import com.codedisaster.steamworks.*; +import io.anuke.arc.*; +import io.anuke.arc.backends.sdl.jni.*; +import io.anuke.arc.collection.*; +import io.anuke.arc.files.*; +import io.anuke.arc.function.*; import io.anuke.arc.util.*; -import io.anuke.arc.util.serialization.Base64Coder; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.core.Platform; -import io.anuke.mindustry.net.CrashSender; +import io.anuke.arc.util.serialization.*; +import io.anuke.mindustry.*; +import io.anuke.mindustry.core.GameState.*; +import io.anuke.mindustry.core.*; +import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.ui.dialogs.FileChooser; -import org.lwjgl.util.tinyfd.TinyFileDialogs; +import io.anuke.mindustry.net.*; +import io.anuke.mindustry.ui.dialogs.*; -import java.net.NetworkInterface; +import java.net.*; import java.util.*; import static io.anuke.mindustry.Vars.*; + public class DesktopPlatform extends Platform{ - static boolean useDiscord = OS.is64Bit; + static boolean useDiscord = OS.is64Bit, useSteam = true; final static String applicationId = "610508934456934412"; String[] args; @@ -40,19 +44,55 @@ public class DesktopPlatform extends Platform{ Log.err("Failed to initialize discord.", t); } } + + if(useSteam){ + Vars.steam = true; + try{ + SteamAPI.loadLibraries(); + if(!SteamAPI.init()){ + Log.info("Steam client not running. Make sure Steam is running!"); + }else{ + //times per second + float interval = 20f; + Interval i = new Interval(); + + //run steam callbacks + Events.on(GameLoadEvent.class, event -> { + //update callbacks + Core.app.addListener(new ApplicationListener(){ + @Override + public void update(){ + if(i.get(interval)){ + if(SteamAPI.isSteamRunning()){ + SteamAPI.runCallbacks(); + } + } + } + }); + + //Core.app.post(() -> new ClientSteam()); + }); + //steam shutdown hook + Runtime.getRuntime().addShutdownHook(new Thread(SteamAPI::shutdown)); + } + }catch(Exception e){ + Log.err("Failed to load Steam native libraries."); + e.printStackTrace(); + } + } } static void handleCrash(Throwable e){ - Consumer dialog = r -> new Thread(r).start(); + Consumer dialog = Runnable::run; boolean badGPU = false; if(e.getMessage() != null && (e.getMessage().contains("Couldn't create window") || e.getMessage().contains("OpenGL 2.0 or higher"))){ - dialog.accept(() -> TinyFileDialogs.tinyfd_messageBox("oh no", + dialog.accept(() -> message( e.getMessage().contains("Couldn't create window") ? "A graphics initialization error has occured! Try to update your graphics drivers:\n" + e.getMessage() : "Your graphics card does not support OpenGL 2.0!\n" + "Try to update your graphics drivers.\n\n" + - "(If that doesn't work, your computer just doesn't support Mindustry.)", "ok", "error", true)); + "(If that doesn't work, your computer just doesn't support Mindustry.)")); badGPU = true; } @@ -60,7 +100,7 @@ public class DesktopPlatform extends Platform{ CrashSender.send(e, file -> { if(!fbgp){ - dialog.accept(() -> TinyFileDialogs.tinyfd_messageBox("oh no", "A crash has occured. It has been saved in:\n" + file.getAbsolutePath(), "ok", "error", true)); + dialog.accept(() -> message("A crash has occured. It has been saved in:\n" + file.getAbsolutePath() + "\n" + (e.getMessage() == null ? "" : "\n" + e.getMessage()))); } }); } @@ -118,7 +158,7 @@ public class DesktopPlatform extends Platform{ String str = new String(Base64Coder.encode(result)); - if(str.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID."); + if(str.equals("AAAAAAAAAOA=") || str.equals("AAAAAAAAAAA=")) throw new RuntimeException("Bad UUID."); return str; }catch(Exception e){ @@ -126,10 +166,14 @@ public class DesktopPlatform extends Platform{ } } + private static void message(String message){ + SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MESSAGEBOX_ERROR, "oh no", message); + } + private boolean validAddress(byte[] bytes){ if(bytes == null) return false; byte[] result = new byte[8]; System.arraycopy(bytes, 0, result, 0, bytes.length); - return !new String(Base64Coder.encode(result)).equals("AAAAAAAAAOA="); + return !new String(Base64Coder.encode(result)).equals("AAAAAAAAAOA=") && !new String(Base64Coder.encode(result)).equals("AAAAAAAAAAA="); } } diff --git a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/ClientSteam.java b/desktop/src/io/anuke/mindustry/desktop/steam/SteamClientImpl.java similarity index 74% rename from desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/ClientSteam.java rename to desktop/src/io/anuke/mindustry/desktop/steam/SteamClientImpl.java index cecb90e97c..8f8a90cbd6 100644 --- a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/ClientSteam.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SteamClientImpl.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.desktopsdl.steam; +package io.anuke.mindustry.desktop.steam; import com.codedisaster.steamworks.*; import com.codedisaster.steamworks.SteamFriends.*; @@ -6,12 +6,11 @@ import com.codedisaster.steamworks.SteamMatchmaking.*; import com.codedisaster.steamworks.SteamNetworking.*; import io.anuke.arc.collection.*; import io.anuke.arc.util.*; -import io.anuke.mindustry.net.Net.*; -import io.anuke.mindustry.net.*; +import io.anuke.mindustry.desktop.steam.SteamServerImpl.*; import java.nio.*; -public class ClientSteam implements SteamNetworkingCallback, SteamMatchmakingCallback{ +public class SteamClientImpl implements SteamNetworkingCallback, SteamMatchmakingCallback{ private SteamNetworking snet; private SteamMatchmaking smat; @@ -19,7 +18,7 @@ public class ClientSteam implements SteamNetworkingCallback, SteamMatchmakingCal //maps steam ID -> valid net connection private IntMap connections = new IntMap<>(); - public ClientSteam(){ + public SteamClientImpl(){ //snet = new SteamNetworking(this); //smat = new SteamMatchmaking(this); @@ -53,46 +52,6 @@ public class ClientSteam implements SteamNetworkingCallback, SteamMatchmakingCal snet.acceptP2PSessionWithUser(steamIDRemote); } - class SteamConnection extends NetConnection{ - public final SteamID connection; - - public SteamConnection(int id, String address, SteamID connection){ - super(id, address); - this.connection = connection; - } - - @Override - public boolean isConnected(){ - return false;//connection.isConnected(); - } - - @Override - public void send(Object object, SendMode mode){ - //TODO - /* - try{ - if(mode == SendMode.tcp){ - connection.sendTCP(object); - }else{ - connection.sendUDP(object); - } - }catch(Exception e){ - Log.err(e); - Log.info("Error sending packet. Disconnecting invalid client!"); - connection.close(); - - ArcNetServer.KryoConnection k = getByKryoID(connection.getID()); - if(k != null) connections.remove(k); - }*/ - } - - @Override - public void close(){ - //TODO - //if(connection.isConnected()) connection.close(); - } - } - @Override public void onFavoritesListChanged(int ip, int queryPort, int connPort, int appID, int flags, boolean add, int accountID){ @@ -185,8 +144,8 @@ public class ClientSteam implements SteamNetworkingCallback, SteamMatchmakingCal } }); - friends.activateGameOverlay(OverlayDialog.Friends); - //friends.activateGameOverlayInviteDialog(steamIDLobby); + //friends.activateGameOverlay(OverlayDialog.Friends); + friends.activateGameOverlayInviteDialog(steamIDLobby); } } diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SteamFriendsImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/SteamFriendsImpl.java new file mode 100644 index 0000000000..1497508ebf --- /dev/null +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SteamFriendsImpl.java @@ -0,0 +1,52 @@ +package io.anuke.mindustry.desktop.steam; + +import com.codedisaster.steamworks.*; +import com.codedisaster.steamworks.SteamFriends.*; + +public class SteamFriendsImpl implements SteamFriendsCallback{ + public final SteamFriends friends; + + public SteamFriendsImpl(){ + friends = new SteamFriends(this); + } + + @Override + public void onSetPersonaNameResponse(boolean b, boolean b1, SteamResult steamResult){ + + } + + @Override + public void onPersonaStateChange(SteamID steamID, PersonaChange personaChange){ + + } + + @Override + public void onGameOverlayActivated(boolean b){ + + } + + @Override + public void onGameLobbyJoinRequested(SteamID steamID, SteamID steamID1){ + + } + + @Override + public void onAvatarImageLoaded(SteamID steamID, int i, int i1, int i2){ + + } + + @Override + public void onFriendRichPresenceUpdate(SteamID steamID, int i){ + + } + + @Override + public void onGameRichPresenceJoinRequested(SteamID steamID, String s){ + + } + + @Override + public void onGameServerChangeRequested(String s, String s1){ + + } +} diff --git a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/ServerSteam.java b/desktop/src/io/anuke/mindustry/desktop/steam/SteamServerImpl.java similarity index 67% rename from desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/ServerSteam.java rename to desktop/src/io/anuke/mindustry/desktop/steam/SteamServerImpl.java index 229735504a..a9cc0f4bfd 100644 --- a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/ServerSteam.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SteamServerImpl.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.desktopsdl.steam; +package io.anuke.mindustry.desktop.steam; import com.codedisaster.steamworks.*; import com.codedisaster.steamworks.SteamMatchmaking.*; @@ -6,28 +6,28 @@ import com.codedisaster.steamworks.SteamNetworking.*; import io.anuke.arc.*; import io.anuke.arc.collection.*; import io.anuke.arc.util.*; -import io.anuke.mindustry.desktopsdl.steam.ClientSteam.*; import io.anuke.mindustry.net.Net.*; import io.anuke.mindustry.net.*; import java.io.*; import java.nio.*; -public class ServerSteam implements ServerProvider, SteamNetworkingCallback, SteamMatchmakingCallback{ +public class SteamServerImpl implements ServerProvider, SteamNetworkingCallback, SteamMatchmakingCallback{ private final static int maxLobbyPlayers = 32; + private final PacketSerializer serializer = new PacketSerializer(); + private final ByteBuffer writeBuffer = ByteBuffer.allocateDirect(1024 * 4); private final SteamNetworking snet = new SteamNetworking(this); private final SteamMatchmaking smat = new SteamMatchmaking(this); + private final SteamFriendsImpl friends = new SteamFriendsImpl(); private final ServerProvider server; - //buffer for steam API calls - private ByteBuffer steamBuffer = ByteBuffer.allocateDirect(1024 * 128); //maps steam ID -> valid net connection private IntMap steamConnections = new IntMap<>(); private SteamID currentLobby; - public ServerSteam(ServerProvider server){ + public SteamServerImpl(ServerProvider server){ this.server = server; } @@ -39,26 +39,6 @@ public class ServerSteam implements ServerProvider, SteamNetworkingCallback, Ste smat.createLobby(LobbyType.values()[Core.settings.getInt("lobbytype", 1)], maxLobbyPlayers); } - @Override - public void sendStream(int id, Streamable stream){ - server.sendStream(id, stream); - } - - @Override - public void send(Object object, SendMode mode){ - server.send(object, mode); - } - - @Override - public void sendTo(int id, Object object, SendMode mode){ - server.sendTo(id, object, mode); - } - - @Override - public void sendExcept(int id, Object object, SendMode mode){ - server.sendExcept(id, object, mode); - } - @Override public void close(){ server.close(); @@ -66,6 +46,9 @@ public class ServerSteam implements ServerProvider, SteamNetworkingCallback, Ste //TODO kick everyone who is in this lobby? smat.leaveLobby(currentLobby); currentLobby = null; + for(SteamConnection con : steamConnections.values()){ + con.close(); + } } } @@ -75,7 +58,7 @@ public class ServerSteam implements ServerProvider, SteamNetworkingCallback, Ste } @Override - public Array getConnections(){ + public Iterable getConnections(){ return server.getConnections(); } @@ -157,4 +140,37 @@ public class ServerSteam implements ServerProvider, SteamNetworkingCallback, Ste //accept users on request snet.acceptP2PSessionWithUser(steamIDRemote); } + + public class SteamConnection extends NetConnection{ + final SteamID sid; + + public SteamConnection(SteamID sid){ + super(sid.getAccountID() + ""); + this.sid = sid; + } + + @Override + public void send(Object object, SendMode mode){ + try{ + writeBuffer.limit(writeBuffer.capacity()); + writeBuffer.position(0); + serializer.write(writeBuffer, object); + writeBuffer.flip(); + + snet.sendP2PPacket(sid, writeBuffer, mode == SendMode.tcp ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0); + }catch(Exception e){ + Log.err(e); + Log.info("Error sending packet. Disconnecting invalid client!"); + close(); + + SteamConnection k = steamConnections.get(sid.getAccountID()); + if(k != null) steamConnections.remove(sid.getAccountID()); + } + } + + @Override + public void close(){ + snet.closeP2PSessionWithUser(sid); + } + } } diff --git a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/WorkshopImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/WorkshopImpl.java similarity index 97% rename from desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/WorkshopImpl.java rename to desktop/src/io/anuke/mindustry/desktop/steam/WorkshopImpl.java index a4e59a9b54..e106cf97ad 100644 --- a/desktop-sdl/src/io/anuke/mindustry/desktopsdl/steam/WorkshopImpl.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/WorkshopImpl.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.desktopsdl.steam; +package io.anuke.mindustry.desktop.steam; import com.codedisaster.steamworks.*; import com.codedisaster.steamworks.SteamRemoteStorage.*; diff --git a/fastlane/Appfile b/fastlane/Appfile new file mode 100644 index 0000000000..3aad746bc0 --- /dev/null +++ b/fastlane/Appfile @@ -0,0 +1,2 @@ +json_key_file(ENV["FASTLANE_KEY_FILE"]) +package_name("io.anuke.mindustry") diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 0000000000..17a304bf4f --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,46 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:android) + +platform :android do + desc "Runs all the tests" + lane :test do + gradle(task: "test") + end + + desc "Submit a new Beta Build to Crashlytics Beta" + lane :beta do + gradle(task: "clean assembleRelease") + crashlytics + + # sh "your_script.sh" + # You can also use other beta testing services here + end + + desc "Deploy a new version to the Google Play" + lane :deploy do + gradle(task: "clean assembleRelease") + upload_to_play_store + end + + #lane :playstore do + # gradle( + # task: 'assemble', + # build_type: 'Release' + # ) + # upload_to_play_store # Uploads the APK built in the gradle step above and releases it to all production users + #end +end diff --git a/fastlane/metadata/android/en-US/changelogs/12203.txt b/fastlane/metadata/android/en-US/changelogs/12203.txt new file mode 100644 index 0000000000..942424c5ea --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/12203.txt @@ -0,0 +1,3 @@ +- Fixed incorrect attribution in credits; music was made by "A Drop A Day" +- Removed unneeded 3.5 upgrade dialog that sometimes showed up in main menu +- Added information dialog regarding v4 beta \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/12205.txt b/fastlane/metadata/android/en-US/changelogs/12205.txt new file mode 100644 index 0000000000..70bcab4bfc --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/12205.txt @@ -0,0 +1,4 @@ +- Fixed incorrect attribution in credits; music was made by "A Drop A Day" +- Removed unneeded 3.5 upgrade dialog that sometimes showed up in main menu +- Added information dialog regarding v4 beta +- Fixed Discord link \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/26593.txt b/fastlane/metadata/android/en-US/changelogs/26593.txt new file mode 100644 index 0000000000..610563a652 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/26593.txt @@ -0,0 +1 @@ +sound. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/27434.txt b/fastlane/metadata/android/en-US/changelogs/27434.txt new file mode 100644 index 0000000000..5240303123 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/27434.txt @@ -0,0 +1 @@ +everything \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/27476.txt b/fastlane/metadata/android/en-US/changelogs/27476.txt new file mode 100644 index 0000000000..ec779fbdba --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/27476.txt @@ -0,0 +1 @@ +Fixed some minor sound/multiplayer issues \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/27689.txt b/fastlane/metadata/android/en-US/changelogs/27689.txt new file mode 100644 index 0000000000..92e8a8c47e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/27689.txt @@ -0,0 +1 @@ +Bugfixes \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/27770.txt b/fastlane/metadata/android/en-US/changelogs/27770.txt new file mode 100644 index 0000000000..04d19b551f --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/27770.txt @@ -0,0 +1 @@ +Added ambient sounds for machines. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/27997.txt b/fastlane/metadata/android/en-US/changelogs/27997.txt new file mode 100644 index 0000000000..2b2809c72d --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/27997.txt @@ -0,0 +1,2 @@ +The first release of version 4.0; an update that has been in the works for over a year. +Extensive changes, including new gamemodes, customizable rules, a new editor, new graphics, new enemies, unit production, new progression, a campaign, and more. See the in-game changelog link for specific details of what has been added and removed over the past year. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/28409.txt b/fastlane/metadata/android/en-US/changelogs/28409.txt new file mode 100644 index 0000000000..670c65cc45 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/28409.txt @@ -0,0 +1,2 @@ +Fixed multiplayer not syncing positions and shots correctly on certain networks or situations. +Various other bugfixes. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/721.txt b/fastlane/metadata/android/en-US/changelogs/721.txt new file mode 100644 index 0000000000..8361896cef --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/721.txt @@ -0,0 +1,5 @@ +- Fixed most formatted numbers being missing from Spanish translation +- Fixed wave timer being extremely slow at high TPS with multithreading enabled +- Fixed scrolling on player menu causing the whole screen to pan +- Updated Polish translation +- Updated Russian translation with new text (Thanks to @Prosta4okua) \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt new file mode 100644 index 0000000000..b9958053f1 --- /dev/null +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -0,0 +1,14 @@ +Create elaborate supply chains of conveyor belts to feed ammo into your turrets, produce materials to use for building, and defend your structures from waves of enemies. Play with your friends in cross-platform multiplayer co-op games, or challenge them in team-based PvP matches. + +Feature include: +- 24 built-in maps +- A campaign, complete with a tech tree and unlockable areas +- 4 powerful wave bosses to defeat +- Energy, liquid and item transportation systems +- 19 different types of drones, mechs and ships +- 120+ technology blocks to master +- 75+ different environmental blocks +- Cross-platform multiplayer via local networks or dedicated servers +- Custom game rules: Change block costs, enemy stats, starting items, wave timing and more +- A powerful editor, with tools to randomly generate ores, terrain, decoration and apply symmetry to maps +- Customizable map wave layouts \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/images/featureGraphic.png b/fastlane/metadata/android/en-US/images/featureGraphic.png new file mode 100644 index 0000000000..90e27dddca Binary files /dev/null and b/fastlane/metadata/android/en-US/images/featureGraphic.png differ diff --git a/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png new file mode 100644 index 0000000000..705e880a20 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/icon.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png new file mode 100644 index 0000000000..44949de11d Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png new file mode 100644 index 0000000000..7d37a27105 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png new file mode 100644 index 0000000000..53525bbd13 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png new file mode 100644 index 0000000000..091f53243c Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png new file mode 100644 index 0000000000..952aa2aa54 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png new file mode 100644 index 0000000000..3830432e4f Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png new file mode 100644 index 0000000000..8fa92e537d Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1.png b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1.png new file mode 100644 index 0000000000..286795f87f Binary files /dev/null and b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2.png b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2.png new file mode 100644 index 0000000000..7d37a27105 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2.png differ diff --git a/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3.png b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3.png new file mode 100644 index 0000000000..091f53243c Binary files /dev/null and b/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3.png differ diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt new file mode 100644 index 0000000000..b6b5a942cd --- /dev/null +++ b/fastlane/metadata/android/en-US/short_description.txt @@ -0,0 +1 @@ +A factory-based sandbox tower defense game. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt new file mode 100644 index 0000000000..2beb939017 --- /dev/null +++ b/fastlane/metadata/android/en-US/title.txt @@ -0,0 +1 @@ +Mindustry \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/video.txt b/fastlane/metadata/android/en-US/video.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fastlane/metadata/android/ru-RU/full_description.txt b/fastlane/metadata/android/ru-RU/full_description.txt new file mode 100644 index 0000000000..03219413cc --- /dev/null +++ b/fastlane/metadata/android/ru-RU/full_description.txt @@ -0,0 +1,15 @@ +Создавайте сложные логистические сети для переноса боеприпасов для турелей, добывайте ресурсы для строительства, и защищайте их от различных волн врагов. +Играйте с друзьями в кроссплатформенные кооперативные игры, или бросьте им вызов в командных PvP-матчах. + +Особенности игры: +- 24 встроенные карты +- Кампания, с полноценным технологическим древом и прогрессией карт +- 4 вида мощных боссов +- Системы для транспорта электроэнергии, жидкостей и ресурсов +- 19 видов дронов, кораблей и наземных боевых единиц +- Более 120 блоков в техногическом древе +- Более 75 видов натуральных блоков +- Кроссплатформенный мультиплеер с поддержкой как и локальных сетей, так и серверов +- Пользовательские настройки игры — изменяйте цену блоков, силу врагов, количество стартовых ресурсов, интервал между волнами и т.д. +- Редактор карт с бесчисленными возможностями, инструментами для случайной генерации руд, рельефа, декораций, а также для симметрии карт +- Настраиваемые раскладки волн для карт \ No newline at end of file diff --git a/fastlane/metadata/android/ru-RU/short_description.txt b/fastlane/metadata/android/ru-RU/short_description.txt new file mode 100644 index 0000000000..b6b5a942cd --- /dev/null +++ b/fastlane/metadata/android/ru-RU/short_description.txt @@ -0,0 +1 @@ +A factory-based sandbox tower defense game. \ No newline at end of file diff --git a/fastlane/metadata/android/ru-RU/title.txt b/fastlane/metadata/android/ru-RU/title.txt new file mode 100644 index 0000000000..2beb939017 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/title.txt @@ -0,0 +1 @@ +Mindustry \ No newline at end of file diff --git a/fastlane/metadata/android/ru-RU/video.txt b/fastlane/metadata/android/ru-RU/video.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ios/data/Default-568h@2x~iphone.png b/ios/data/Default-568h@2x~iphone.png index 153c6efdf4..9a0e377f65 100644 Binary files a/ios/data/Default-568h@2x~iphone.png and b/ios/data/Default-568h@2x~iphone.png differ diff --git a/ios/data/Default-667h.png b/ios/data/Default-667h.png index b3acc10e67..b5a4b57681 100644 Binary files a/ios/data/Default-667h.png and b/ios/data/Default-667h.png differ diff --git a/ios/data/Default-736h.png b/ios/data/Default-736h.png index f5a22468a3..8d05a25f44 100644 Binary files a/ios/data/Default-736h.png and b/ios/data/Default-736h.png differ diff --git a/ios/data/Default-Landscape-736h.png b/ios/data/Default-Landscape-736h.png index 04e32d4d7e..70badabb86 100644 Binary files a/ios/data/Default-Landscape-736h.png and b/ios/data/Default-Landscape-736h.png differ diff --git a/ios/data/Default-Landscape@2x~ipad.png b/ios/data/Default-Landscape@2x~ipad.png index 239e218934..da2884cfd1 100644 Binary files a/ios/data/Default-Landscape@2x~ipad.png and b/ios/data/Default-Landscape@2x~ipad.png differ diff --git a/ios/data/Default-Landscape~ipad.png b/ios/data/Default-Landscape~ipad.png index 7374a80f75..3b101edc7e 100644 Binary files a/ios/data/Default-Landscape~ipad.png and b/ios/data/Default-Landscape~ipad.png differ diff --git a/ios/data/Default-Portrait@2x~ipad.png b/ios/data/Default-Portrait@2x~ipad.png index c00e06f4e4..0989e62081 100644 Binary files a/ios/data/Default-Portrait@2x~ipad.png and b/ios/data/Default-Portrait@2x~ipad.png differ diff --git a/ios/data/Default-Portrait~ipad.png b/ios/data/Default-Portrait~ipad.png index 030e88c898..9f980c961a 100644 Binary files a/ios/data/Default-Portrait~ipad.png and b/ios/data/Default-Portrait~ipad.png differ diff --git a/ios/data/Default@2x~iphone.png b/ios/data/Default@2x~iphone.png index 5724809f89..710599b407 100644 Binary files a/ios/data/Default@2x~iphone.png and b/ios/data/Default@2x~iphone.png differ diff --git a/ios/data/Default~iphone.png b/ios/data/Default~iphone.png index fa72316347..527d691cc0 100644 Binary files a/ios/data/Default~iphone.png and b/ios/data/Default~iphone.png differ diff --git a/ios/src/io/anuke/mindustry/IOSLauncher.java b/ios/src/io/anuke/mindustry/IOSLauncher.java index 15988c3424..4161d44017 100644 --- a/ios/src/io/anuke/mindustry/IOSLauncher.java +++ b/ios/src/io/anuke/mindustry/IOSLauncher.java @@ -40,7 +40,7 @@ public class IOSLauncher extends IOSApplication.Delegate{ @Override public void shareFile(FileHandle file){ Log.info("Attempting to share file " + file); - FileHandle to = Core.files.absolute(getDocumentsDirectory()).child(file.name()/* + ".png"*/); + FileHandle to = Core.files.absolute(getDocumentsDirectory()).child(file.name()); file.copyTo(to); NSURL url = new NSURL(to.file()); @@ -53,7 +53,6 @@ public class IOSLauncher extends IOSApplication.Delegate{ @Override public void beginForceLandscape(){ - Log.info("begin force landscape"); forced = true; UINavigationController.attemptRotationToDeviceOrientation(); } diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 0cffac9591..42bc75d0ef 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -700,10 +700,11 @@ public class ServerControl implements ApplicationListener{ run.run(); logic.play(); state.rules = world.getMap().applyRules(lastMode); + for(Player p : players){ p.reset(); if(state.rules.pvp){ - p.setTeam(netServer.assignTeam(new ArrayIterable<>(players))); + p.setTeam(netServer.assignTeam(p, new ArrayIterable<>(players))); } netServer.sendWorldData(p, p.con.id); } diff --git a/settings.gradle b/settings.gradle index 20085aa2fb..41b5080058 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,4 @@ -include 'desktop', 'desktop-sdl', 'core', 'net', 'server', 'ios', 'annotations', 'tools', 'tests' +include 'desktop', 'core', 'net', 'server', 'ios', 'annotations', 'tools', 'tests' def use = { String name -> include(name)