/* * Copyright (C) 2024 Minecon724 * Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file * in the project root for the full license text. */ package eu.m724.tweaks.updater; import eu.m724.tweaks.updater.cache.ResourceVersion; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashSet; import java.util.Set; public class VersionCheckCache { private static final byte FILE_VERSION = 1; public static Set loadAll(FileInputStream inputStream) throws IOException { byte fileVersion = (byte) inputStream.read(); if (fileVersion != FILE_VERSION) throw new FileVersionMismatchException(fileVersion, FILE_VERSION); Set versions = new HashSet<>(); int i = 0; byte[] buffer = new byte[8]; // 3 + 2 + 3 while (inputStream.available() > 0) { int read = inputStream.read(buffer); if (read < 8) break; // end of file if (++i > 10000) throw new RuntimeException("Cache file is too large"); ResourceVersion resourceVersion = getResourceVersion(buffer); versions.add(resourceVersion); } return versions; } private static ResourceVersion getResourceVersion(byte[] bytes) { int resourceId = ((bytes[0] & 0xFF) << 16) | ((bytes[1] & 0xFF) << 8) | (bytes[2] & 0xFF); int page = ((bytes[3] & 0xFF) << 8) | (bytes[4] & 0xFF); int versionId = ((bytes[5] & 0xFF) << 16) | ((bytes[6] & 0xFF) << 8) | (bytes[7] & 0xFF); return new ResourceVersion(resourceId, page, versionId, null, null); } private static void writeResourceVersion(ResourceVersion resourceVersion, OutputStream outputStream) throws IOException { int resourceId = resourceVersion.resourceId(); outputStream.write((resourceId >> 16) & 0xFF); outputStream.write((resourceId >> 8) & 0xFF); outputStream.write(resourceId & 0xFF); int page = resourceVersion.page(); outputStream.write((page >> 8) & 0xFF); outputStream.write(page & 0xFF); int versionId = resourceVersion.updateId(); outputStream.write((versionId >> 16) & 0xFF); outputStream.write((versionId >> 8) & 0xFF); outputStream.write(versionId & 0xFF); } public static void writeAll(FileOutputStream outputStream, Set versions) throws IOException { outputStream.write(FILE_VERSION); for (ResourceVersion version : versions) { writeResourceVersion(version, outputStream); } } public static class FileVersionMismatchException extends RuntimeException { public final byte fileVersion, expectedVersion; public FileVersionMismatchException(byte fileVersion, byte expectedVersion) { this.fileVersion = fileVersion; this.expectedVersion = expectedVersion; } } }