diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index af50b4e377..3ddbc4c7b4 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -89,6 +89,8 @@ public class Vars implements Loadable{ public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md"; /** list of built-in servers.*/ public static final Seq defaultServers = Seq.with(); + /** cached server list - only used if defaultServers have not been fetched*/ + public static final Seq cachedServers = Seq.with(); /** maximum openGL errors logged */ public static final int maxGlErrors = 100; /** maximum size of any block, do not change unless you know what you're doing */ @@ -206,6 +208,10 @@ public class Vars implements Loadable{ public static boolean drawDebugHitboxes = false; /** Whether to draw avoidance fields. */ public static boolean debugDrawAvoidance = false; + /** Whether the on-disk server file cache has been loaded. */ + public static boolean loadedServerCache = false; + /** Whether the server list has been fetched from Github. */ + public static boolean fetchedServers = false; /** application data directory, equivalent to {@link Settings#getDataDirectory()} */ public static Fi dataDirectory; /** data subdirectory used for screenshots */ @@ -226,6 +232,8 @@ public class Vars implements Loadable{ public static Fi bebuildDirectory; /** file used to store launch ID */ public static Fi launchIDFile; + /** local cache of server list */ + public static Fi serverCacheFile; /** empty map, indicates no current map */ public static Map emptyMap; /** empty tile for payloads */ @@ -322,6 +330,7 @@ public class Vars implements Loadable{ modDirectory = dataDirectory.child("mods/"); schematicDirectory = dataDirectory.child("schematics/"); bebuildDirectory = dataDirectory.child("be_builds/"); + serverCacheFile = dataDirectory.child("server_list.json"); emptyMap = new Map(new StringMap()); if(tree == null) tree = new FileTree(); diff --git a/core/src/mindustry/editor/EditorRenderer.java b/core/src/mindustry/editor/EditorRenderer.java index 8770003eb7..75b7c549be 100644 --- a/core/src/mindustry/editor/EditorRenderer.java +++ b/core/src/mindustry/editor/EditorRenderer.java @@ -10,6 +10,7 @@ import arc.util.*; import mindustry.content.*; import mindustry.graphics.*; import mindustry.world.*; +import mindustry.world.blocks.environment.*; import static mindustry.Vars.*; @@ -36,6 +37,16 @@ public class EditorRenderer implements Disposable{ packWidth = width * tilesize + packPad * 2; packHeight = height * tilesize + packPad * 2; + //clear darkness + for(int x = 0; x < width; x++){ + for(int y = 0; y < height; y++){ + Tile tile = world.tile(x, y); + if(tile.block() instanceof StaticWall){ + tile.data = 0; + } + } + } + recache(); } diff --git a/core/src/mindustry/io/versions/LegacyIO.java b/core/src/mindustry/io/versions/LegacyIO.java index f4a865ccb5..011a1cd618 100644 --- a/core/src/mindustry/io/versions/LegacyIO.java +++ b/core/src/mindustry/io/versions/LegacyIO.java @@ -2,9 +2,6 @@ package mindustry.io.versions; import arc.*; import arc.struct.*; -import arc.util.*; -import mindustry.*; -import mindustry.ctype.*; import mindustry.ui.dialogs.JoinDialog.*; import java.io.*; @@ -50,35 +47,4 @@ public class LegacyIO{ } return arr; } - - public static void readResearch(){ - try{ - byte[] bytes = Core.settings.getBytes("unlocks"); - DataInputStream stream = new DataInputStream(new ByteArrayInputStream(bytes)); - - int length = stream.readInt(); - if(length > 0){ - stream.readUTF(); //name of key type - stream.readUTF(); //name of value type - - //each element is an array list - for(int i = 0; i < length; i++){ - ContentType type = ContentType.all[stream.readInt()]; - int arrLength = stream.readInt(); - if(arrLength > 0){ - stream.readUTF(); //type of contents (String) - for(int j = 0; j < arrLength; j++){ - String name = stream.readUTF(); - Content out = Vars.content.getByName(type, name); - if(out instanceof UnlockableContent u){ - u.quietUnlock(); - } - } - } - } - } - }catch(Exception e){ - Log.err(e); - } - } } diff --git a/core/src/mindustry/ui/dialogs/JoinDialog.java b/core/src/mindustry/ui/dialogs/JoinDialog.java index 21bffc1e60..b7f2e8875f 100644 --- a/core/src/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/mindustry/ui/dialogs/JoinDialog.java @@ -25,6 +25,7 @@ import mindustry.ui.*; import static mindustry.Vars.*; public class JoinDialog extends BaseDialog{ + Seq tmpServers = new Seq<>(); Seq servers = new Seq<>(); Dialog add; Server renaming; @@ -110,10 +111,6 @@ public class JoinDialog extends BaseDialog{ keyDown(KeyCode.f5, this::refreshAll); shown(() -> { - if(defaultServers.isEmpty()){ - fetchServers(); - } - setup(); refreshAll(); @@ -394,7 +391,7 @@ public class JoinDialog extends BaseDialog{ global.clear(); global.background(null); - if(defaultServers.isEmpty()){ + if(!fetchedServers){ fetchServers(); } @@ -406,8 +403,12 @@ public class JoinDialog extends BaseDialog{ t.button(Icon.zoom, Styles.emptyi, this::refreshCommunity).size(54f); }).width((targetWidth() + 5f) * columns()).height(70f).pad(4).row(); - for(int i = 0; i < defaultServers.size; i ++){ - ServerGroup group = defaultServers.get((i + defaultServers.size/2) % defaultServers.size); + //if the servers have been fetched, use the fetched list + //otherwise use the cached list + the extra servers that may have been included by mods + var servers = fetchedServers ? defaultServers : tmpServers.clear().addAll(cachedServers).addAll(defaultServers); + + for(int i = 0; i < servers.size; i ++){ + ServerGroup group = servers.get((i + servers.size/2) % servers.size); boolean hidden = group.hidden(); if(hidden && !showHidden){ continue; @@ -661,6 +662,15 @@ public class JoinDialog extends BaseDialog{ var urls = Version.type.equals("bleeding-edge") || Vars.forceBeServers ? serverJsonBeURLs : serverJsonURLs; if(Core.settings.getBool("communityservers", true)){ + try{ + if(!loadedServerCache && serverCacheFile.exists()){ + loadedServerCache = true; + cachedServers.addAll(parseServerString(serverCacheFile.readString())); + } + }catch(Exception e){ + Log.err("Failed to load cached server file", e); + } + fetchServers(urls, 0); } } @@ -678,28 +688,41 @@ public class JoinDialog extends BaseDialog{ } }) .submit(result -> { - Jval val = Jval.read(result.getResultAsString()); - Seq servers = new Seq<>(); - val.asArray().each(child -> { - String name = child.getString("name", ""); - boolean prioritized = child.getBool("prioritized", false); - String[] addresses; - if(child.has("addresses") || (child.has("address") && child.get("address").isArray())){ - addresses = (child.has("addresses") ? child.get("addresses") : child.get("address")).asArray().map(Jval::asString).toArray(String.class); - }else{ - addresses = new String[]{child.getString("address", "")}; - } - servers.add(new ServerGroup(name, addresses, prioritized)); - }); + String text = result.getResultAsString(); + Seq servers = parseServerString(text); //modify default servers on main thread Core.app.post(() -> { - servers.sort(s -> s.name == null ? Integer.MAX_VALUE : s.name.hashCode()); + //cache the server list to a file, so it can be loaded in case of an outage later + try{ + serverCacheFile.writeString(text); + }catch(Exception e){ + Log.err("Failed to write server cache", e); + } defaultServers.addAll(servers); + fetchedServers = true; Log.info("Fetched @ community servers.", defaultServers.sum(s -> s.addresses.length)); }); }); } + private static Seq parseServerString(String str){ + Jval val = Jval.read(str); + Seq servers = new Seq<>(); + val.asArray().each(child -> { + String name = child.getString("name", ""); + boolean prioritized = child.getBool("prioritized", false); + String[] addresses; + if(child.has("addresses") || (child.has("address") && child.get("address").isArray())){ + addresses = (child.has("addresses") ? child.get("addresses") : child.get("address")).asArray().map(Jval::asString).toArray(String.class); + }else{ + addresses = new String[]{child.getString("address", "")}; + } + servers.add(new ServerGroup(name, addresses, prioritized)); + }); + servers.sort(s -> s.name == null ? Integer.MAX_VALUE : s.name.hashCode()); + return servers; + } + private void saveServers(){ Core.settings.putJson("servers", Server.class, servers); } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e1adfb4938..3ae1e2f124 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists