diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 2850060061..c47439e4bf 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1824,9 +1824,9 @@ public class Blocks implements ContentList{ }}; illuminator = new LightBlock("illuminator"){{ - requirements(Category.effect, BuildVisibility.lightingOnly, with(Items.graphite, 10, Items.silicon, 8)); + requirements(Category.effect, BuildVisibility.lightingOnly, with(Items.graphite, 12, Items.silicon, 8)); brightness = 0.67f; - radius = 130f; + radius = 140f; consumes.power(0.06f); }}; diff --git a/core/src/mindustry/net/Administration.java b/core/src/mindustry/net/Administration.java index a24610fe3f..0c3b64f512 100644 --- a/core/src/mindustry/net/Administration.java +++ b/core/src/mindustry/net/Administration.java @@ -567,7 +567,10 @@ public class Administration{ socketInputAddress("The bind address for socket input.", "localhost", () -> Events.fire(Trigger.socketConfigChanged)), allowCustomClients("Whether custom clients are allowed to connect.", !headless, "allow-custom"), whitelist("Whether the whitelist is used.", false), - motd("The message displayed to people on connection.", "off"); + motd("The message displayed to people on connection.", "off"), + autosave("Whether the periodically save the map when playing.", false), + autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10), + autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5); public static final Config[] all = values(); diff --git a/server/src/mindustry/server/ServerControl.java b/server/src/mindustry/server/ServerControl.java index 48460aa431..177b16fc51 100644 --- a/server/src/mindustry/server/ServerControl.java +++ b/server/src/mindustry/server/ServerControl.java @@ -39,7 +39,7 @@ public class ServerControl implements ApplicationListener{ private static final int maxLogLength = 1024 * 512; protected static String[] tags = {"&lc&fb[D]", "&lg&fb[I]", "&ly&fb[W]", "&lr&fb[E]", ""}; - protected static DateTimeFormatter dateTime = DateTimeFormatter.ofPattern("MM-dd-yyyy | HH:mm:ss"); + protected static DateTimeFormatter dateTime = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss"); private final CommandHandler handler = new CommandHandler(""); private final Fi logFolder = Core.settings.getDataDirectory().child("logs/"); @@ -49,6 +49,7 @@ public class ServerControl implements ApplicationListener{ private Task lastTask; private Gamemode lastMode = Gamemode.survival; private @Nullable Map nextMapOverride; + private Interval autosaveCount = new Interval(); private Thread socketThread; private ServerSocket serverSocket; @@ -153,12 +154,52 @@ public class ServerControl implements ApplicationListener{ } }); + //reset autosave on world load + Events.on(WorldLoadEvent.class, e -> { + autosaveCount.reset(0, Config.autosaveSpacing.num() * 60); + }); + + //autosave periodically + Events.on(Trigger.update, () -> { + if(state.isPlaying() && Config.autosave.bool()){ + if(autosaveCount.get(Config.autosaveSpacing.num() * 60)){ + int max = Config.autosaveAmount.num(); + + //use map file name to make sure it can be saved + String mapName = (state.map.file == null ? "unknown" : state.map.file.nameWithoutExtension()).replace(" ", "_"); + String date = dateTime.format(LocalDateTime.now()).replace(" ", "_"); + + Seq autosaves = saveDirectory.findAll(f -> f.name().startsWith("auto_")); + autosaves.sort(f -> -f.lastModified()); + + //delete older saves + if(autosaves.size >= max){ + for(int i = max - 1; i < autosaves.size; i++){ + autosaves.get(i).delete(); + } + } + + String fileName = "auto_" + mapName + "_" + date + "." + saveExtension; + Fi file = saveDirectory.child(fileName); + info("&lbAutosaving..."); + + try{ + SaveIO.save(file); + info("&lbAutosave completed."); + }catch(Throwable e){ + err("Autosave failed.", e); + } + } + } + }); + Events.on(Trigger.socketConfigChanged, () -> { toggleSocket(false); toggleSocket(Config.socketInput.bool()); }); Events.on(PlayEvent.class, e -> { + try{ JsonValue value = JsonIO.json().fromJson(null, Core.settings.getString("globalrules")); JsonIO.json().readFields(state.rules, value);