Misc minor fixes

This commit is contained in:
Anuken
2026-06-03 18:25:58 -04:00
parent ab69f947ef
commit 39cc6cfd6d
11 changed files with 30 additions and 26 deletions
+1 -1
View File
@@ -334,7 +334,7 @@ reconnecting = [accent]Reconnecting...
connecting.establish = [accent]Establishing connection... connecting.establish = [accent]Establishing connection...
receiving.world = [accent]Receiving world data ({0})... receiving.world = [accent]Receiving world data ({0})...
receiving.assets = [accent]Receiving assets ({0})... receiving.assets = [accent]Receiving assets ({0})...
receiving.assets.fail = Error occurred while receiving assets. receiving.assets.fail = I/O error occurred while receiving assets.
server.port = Port: server.port = Port:
server.invalidport = Invalid port number! server.invalidport = Invalid port number!
+6 -2
View File
@@ -3,8 +3,9 @@ package mindustry.ctype;
import arc.files.*; import arc.files.*;
import arc.util.*; import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.mod.*; import mindustry.annotations.Annotations.*;
import mindustry.mod.Mods.*; import mindustry.mod.Mods.*;
import mindustry.mod.*;
import mindustry.mod.data.*; import mindustry.mod.data.*;
/** Base class for a content type that is loaded in {@link mindustry.core.ContentLoader}. */ /** Base class for a content type that is loaded in {@link mindustry.core.ContentLoader}. */
@@ -13,6 +14,8 @@ public abstract class Content implements Comparable<Content>{
public short id; public short id;
/** Info on which mod this content was loaded from. */ /** Info on which mod this content was loaded from. */
public ModContentInfo minfo = new ModContentInfo(); public ModContentInfo minfo = new ModContentInfo();
/** If true, this content is invalid (added in a data patch and then removed). */
public boolean removed;
public Content(){ public Content(){
this.id = (short)Vars.content.getBy(getContentType()).size; this.id = (short)Vars.content.getBy(getContentType()).size;
@@ -26,7 +29,8 @@ public abstract class Content implements Comparable<Content>{
public abstract ContentType getContentType(); public abstract ContentType getContentType();
/** Called when this content is removed in a data patch. */ /** Called when this content is removed in a data patch. */
public void remove(){} @CallSuper
public void removeContent(){}
/** Called after all content and modules are created. Do not use to load regions or texture data! */ /** Called after all content and modules are created. Do not use to load regions or texture data! */
public void init(){} public void init(){}
+6 -5
View File
@@ -48,14 +48,15 @@ public class DataAssetCache{
return get(encodeHash(shaHash)); return get(encodeHash(shaHash));
} }
//base32 without padding //base32 without padding; data must be exactly 32 bytes
public static String encodeHash(byte[] data) { public static String encodeHash(byte[] data){
if(data.length != 32) throw new IllegalArgumentException("Data must be exactly 32 bytes (length: " + data.length + ")");
char[] out = new char[52]; char[] out = new char[52];
int di = 0, oi = 0; int di = 0, oi = 0;
long bits;
for(int i = 0; i < 6; i++){ for(int i = 0; i < 6; i++){
bits = ((long)(data[di++] & 0xFF) << 32) | long bits =
((long)(data[di++] & 0xFF) << 32) |
((long)(data[di++] & 0xFF) << 24) | ((long)(data[di++] & 0xFF) << 24) |
((long)(data[di++] & 0xFF) << 16) | ((long)(data[di++] & 0xFF) << 16) |
((long)(data[di++] & 0xFF) << 8) | ((long)(data[di++] & 0xFF) << 8) |
@@ -77,7 +78,7 @@ public class DataAssetCache{
out[oi++] = base32Alphabet[(b0 >>> 3) & 0x1F]; out[oi++] = base32Alphabet[(b0 >>> 3) & 0x1F];
out[oi++] = base32Alphabet[((b0 << 2) & 0x1C) | ((b1 >>> 6) & 0x03)]; out[oi++] = base32Alphabet[((b0 << 2) & 0x1C) | ((b1 >>> 6) & 0x03)];
out[oi++] = base32Alphabet[(b1 >>> 1) & 0x1F]; out[oi++] = base32Alphabet[(b1 >>> 1) & 0x1F];
out[oi++] = base32Alphabet[(b1 << 4) & 0x10]; out[oi++] = base32Alphabet[(b1 << 4) & 0x1F];
return new String(out); return new String(out);
} }
-3
View File
@@ -6,9 +6,6 @@ import mindustry.mod.data.*;
/** /**
* TODO: * TODO:
* - Patchset names are weird and broken with the new path system (no unique file name)
* - Test planets and make sure remove() works properly
* - Try really hard to make the game crash or misbehave
* - Unit tests * - Unit tests
*/ */
public class DataManager{ public class DataManager{
+2 -1
View File
@@ -264,7 +264,8 @@ public class DataPatcher{
for(var arr : Vars.content.getContentMap()){ for(var arr : Vars.content.getContentMap()){
for(var value : arr){ for(var value : arr){
if(value.isModded() && value.minfo.mod == dpMod){ if(value.isModded() && value.minfo.mod == dpMod){
value.remove(); value.removed = true;
value.removeContent();
} }
} }
} }
+3 -3
View File
@@ -1,7 +1,6 @@
package mindustry.mod.data; package mindustry.mod.data;
import arc.files.*; import arc.files.*;
import arc.math.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.serialization.*; import arc.util.serialization.*;
@@ -9,6 +8,7 @@ import arc.util.serialization.JsonWriter.*;
import arc.util.serialization.Jval.*; import arc.util.serialization.Jval.*;
import java.io.*; import java.io.*;
import java.util.*;
public class PatchAsset extends DataAsset{ public class PatchAsset extends DataAsset{
private static final JsonValue emptyValue = new JsonValue("error"); private static final JsonValue emptyValue = new JsonValue("error");
@@ -23,8 +23,8 @@ public class PatchAsset extends DataAsset{
public Seq<String> warnings = new Seq<>(); public Seq<String> warnings = new Seq<>();
public PatchAsset(String patch){ public PatchAsset(String patch){
//patches don't have a path by default, so make it something random when reading. TODO: this is a temporary measure. //patches don't have a path by default, so make it something random when reading. TODO: this is a temporary measure until a proper editor is added.
setPath("patch-" + Mathf.rand.nextLong() + ".json"); setPath("patch-" + UUID.randomUUID() + ".json");
this.patch = patch; this.patch = patch;
} }
+2 -6
View File
@@ -111,10 +111,6 @@ public class Streamable extends Packet{
if(isClosed) throw new ClosedChannelException(); if(isClosed) throw new ClosedChannelException();
if(currentBuffer == null || currentOffset >= currentBuffer.length){ if(currentBuffer == null || currentOffset >= currentBuffer.length){
//after a finish(), reads are allowed, but only if the queue isn't empty (otherwise it's a EOF)
//throwing EOF is against convention, but I don't care, this is invalid state, and you shouldn't be here
if(isFinished && queue.isEmpty()) throw new EOFException();
try{ try{
currentBuffer = queue.take(); currentBuffer = queue.take();
currentOffset = 0; currentOffset = 0;
@@ -123,7 +119,7 @@ public class Streamable extends Packet{
if(currentBuffer == closedSignal){ if(currentBuffer == closedSignal){
queue.add(closedSignal); queue.add(closedSignal);
//if the queue was finished, and you were trying to read something, you should get a EOF instead (invalid state) //if the queue was finished, and you were trying to read something, you should get a EOF instead (invalid state)
if(isFinished) throw new EOFException(); if(isFinished) return -1;
throw new ClosedChannelException(); throw new ClosedChannelException();
} }
}catch(InterruptedException e){ }catch(InterruptedException e){
@@ -146,7 +142,7 @@ public class Streamable extends Packet{
return result == -1 ? -1 : (singleByte[0] & 0xFF); return result == -1 ? -1 : (singleByte[0] & 0xFF);
} }
/** unlike close(), this allows the stream to finish reading whatever it's reading, but if it tries to read more, it will return -1 (EOF) */ /** unlike close(), this allows the stream to finish reading whatever it's reading, but if it tries to read more, it will throw EOF */
public void finish(){ public void finish(){
isFinished = true; isFinished = true;
queue.add(closedSignal); queue.add(closedSignal);
+5 -1
View File
@@ -237,10 +237,14 @@ public class Planet extends UnlockableContent{
} }
@Override @Override
public void remove(){ public void removeContent(){
super.removeContent();
if(parent != null){ if(parent != null){
parent.children.remove(this); parent.children.remove(this);
parent.updateTotalRadius(); parent.updateTotalRadius();
if(mesh != null) mesh.dispose();
if(cloudMesh != null) cloudMesh.dispose();
} }
} }
+2 -2
View File
@@ -95,8 +95,8 @@ public class SectorPreset extends UnlockableContent{
} }
@Override @Override
public void remove(){ public void removeContent(){
super.remove(); super.removeContent();
if(sector != null && sector.preset == this){ if(sector != null && sector.preset == this){
sector.preset = null; sector.preset = null;
} }
@@ -605,6 +605,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
} }
boolean selectable(Planet planet){ boolean selectable(Planet planet){
if(planet.removed) return false;
if(mode == select) return planet == state.planet; if(mode == select) return planet == state.planet;
if(mode == planetLaunch) return launchSector != null && (launchCandidates.contains(planet) || (planet == launchSector.planet && planet.allowSelfSectorLaunch)); if(mode == planetLaunch) return launchSector != null && (launchCandidates.contains(planet) || (planet == launchSector.planet && planet.allowSelfSectorLaunch));
return (planet.alwaysUnlocked && planet.isLandable()) || planet.sectors.contains(Sector::hasBase) || debugSelect; return (planet.alwaysUnlocked && planet.isLandable()) || planet.sectors.contains(Sector::hasBase) || debugSelect;
@@ -578,10 +578,10 @@ public class ServerControl implements ApplicationListener{
info("Map directory: &fi@", customMapDirectory.file().getAbsoluteFile().toString()); info("Map directory: &fi@", customMapDirectory.file().getAbsoluteFile().toString());
}); });
handler.register("reloadpatches", "Reload all patch files from disk.", arg -> { handler.register("reloadassets", "Reload all content/patch asset files from disk.", arg -> {
loadDataAssets(); loadDataAssets();
if(dataAssets.isEmpty()){ if(dataAssets.isEmpty()){
err("No valid content patch files found."); err("No valid asset files found.");
} }
}); });