mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-30 05:12:58 +00:00
Reformat JSON by wrapping CachedOutput
Rather than mixing-in to CachedOutput, we just wrap our DataProviders to use a custom CachedOutput which reformats the JSON before writing. This allows us to drop mixins for common+non-client code.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.data;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.HashFunction;
|
||||
import com.google.common.hash.Hashing;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Wraps an existing {@link DataProvider}, passing generated JSON through {@link PrettyJsonWriter}.
|
||||
*
|
||||
* @param provider The provider to wrap.
|
||||
* @param <T> The type of the provider to wrap.
|
||||
*/
|
||||
public record PrettyDataProvider<T extends DataProvider>(T provider) implements DataProvider {
|
||||
@Override
|
||||
public CompletableFuture<?> run(CachedOutput cachedOutput) {
|
||||
return provider.run(new Output(cachedOutput));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return provider.getName();
|
||||
}
|
||||
|
||||
private record Output(CachedOutput output) implements CachedOutput {
|
||||
@SuppressWarnings("unused")
|
||||
private static final HashFunction HASH_FUNCTION = Hashing.sha1();
|
||||
|
||||
@Override
|
||||
public void writeIfNeeded(Path path, byte[] bytes, HashCode hashCode) throws IOException {
|
||||
if (path.getFileName().toString().endsWith(".json")) {
|
||||
bytes = PrettyJsonWriter.reformat(bytes);
|
||||
hashCode = HASH_FUNCTION.hashBytes(bytes);
|
||||
}
|
||||
|
||||
output.writeIfNeeded(path, bytes, hashCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,10 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Alternative version of {@link JsonWriter} which attempts to lay out the JSON in a more compact format.
|
||||
* <p>
|
||||
* Yes, this is at least a little deranged.
|
||||
*
|
||||
* @see PrettyDataProvider
|
||||
*/
|
||||
public class PrettyJsonWriter extends JsonWriter {
|
||||
public static final boolean ENABLED = System.getProperty("cct.pretty-json") != null;
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
|
||||
private static final int MAX_WIDTH = 120;
|
||||
@@ -44,17 +43,6 @@ public class PrettyJsonWriter extends JsonWriter {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSON writer. This will either be a pretty or normal version, depending on whether the global flag is
|
||||
* set.
|
||||
*
|
||||
* @param out The writer to emit to.
|
||||
* @return The constructed JSON writer.
|
||||
*/
|
||||
public static JsonWriter createWriter(Writer out) {
|
||||
return ENABLED ? new PrettyJsonWriter(out) : new JsonWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reformat a JSON string with our pretty printer.
|
||||
*
|
||||
@@ -62,8 +50,6 @@ public class PrettyJsonWriter extends JsonWriter {
|
||||
* @return The reformatted string.
|
||||
*/
|
||||
public static byte[] reformat(byte[] contents) {
|
||||
if (!ENABLED) return contents;
|
||||
|
||||
JsonElement object;
|
||||
try (var reader = new InputStreamReader(new ByteArrayInputStream(contents), StandardCharsets.UTF_8)) {
|
||||
object = GSON.fromJson(reader, JsonElement.class);
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.mixin;
|
||||
|
||||
import dan200.computercraft.data.PrettyJsonWriter;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(targets = "net/minecraft/data/HashCache$CacheUpdater")
|
||||
public class CacheUpdaterMixin {
|
||||
@SuppressWarnings("UnusedMethod")
|
||||
@ModifyArg(
|
||||
method = "writeIfNeeded",
|
||||
at = @At(value = "INVOKE", target = "Ljava/nio/file/Files;write(Ljava/nio/file/Path;[B[Ljava/nio/file/OpenOption;)Ljava/nio/file/Path;"),
|
||||
require = 0
|
||||
)
|
||||
private byte[] reformatJson(byte[] contents) {
|
||||
// It would be cleaner to do this inside DataProvider.saveStable, but Forge's version of Mixin doesn't allow us
|
||||
// to inject into interfaces.
|
||||
return PrettyJsonWriter.reformat(contents);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "dan200.computercraft.mixin",
|
||||
"minVersion": "0.8",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"mixins": [
|
||||
"CacheUpdaterMixin"
|
||||
],
|
||||
"refmap": "computercraft.refmap.json"
|
||||
}
|
||||
Reference in New Issue
Block a user