diff --git a/README.md b/README.md index 4cdc73c..870fc70 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ Bedrock resource pack to extend Geyser functionality. Learn more on its [wiki pa - Structure block options that do not exist on Java - 1, 2, 4 and 5 row chests, removing the need for the filler item - Proper attack cooldowns +- Proper combat sounds + - Sweep attacks + - Knockback attacks Download: [GeyserIntegratedPack.mcpack](https://download.geysermc.org/v2/projects/geyserintegratedpack/versions/latest/builds/latest/downloads/geyserintegratedpack) diff --git a/src/main/java/org/geysermc/integratedpack/Constants.java b/src/main/java/org/geysermc/integratedpack/Constants.java index efae706..4af84b7 100644 --- a/src/main/java/org/geysermc/integratedpack/Constants.java +++ b/src/main/java/org/geysermc/integratedpack/Constants.java @@ -4,8 +4,8 @@ import com.google.gson.GsonBuilder; public class Constants { - public static final String JAVA_TARGET_VERSION = "1.21.8"; - public static final String BEDROCK_TARGET_VERSION = "1.21.100.6"; + public static final String JAVA_TARGET_VERSION = "26.1.2"; + public static final String BEDROCK_TARGET_VERSION = "1.26.20.26"; public static final Gson GSON = new GsonBuilder() .setPrettyPrinting() diff --git a/src/main/java/org/geysermc/integratedpack/IntegratedPack.java b/src/main/java/org/geysermc/integratedpack/IntegratedPack.java index dc0ca12..c044299 100644 --- a/src/main/java/org/geysermc/integratedpack/IntegratedPack.java +++ b/src/main/java/org/geysermc/integratedpack/IntegratedPack.java @@ -68,7 +68,7 @@ public static void main(String[] args) { // there are probably better ways to do this, but this is the way im doing it Resources.extractFolder("integratedpack", WORKING_PATH); - // Step 2: Download the 1.21.8 client.jar and copy all files needed to working folder + // Step 2: Download the client jar and copy all files needed to working folder File jarFile = LauncherMetaWrapper.getLatest().toFile(); ZipFile clientJar = new ZipFile(jarFile); diff --git a/src/main/java/org/geysermc/integratedpack/JavaResources.java b/src/main/java/org/geysermc/integratedpack/JavaResources.java index 078c993..2203649 100644 --- a/src/main/java/org/geysermc/integratedpack/JavaResources.java +++ b/src/main/java/org/geysermc/integratedpack/JavaResources.java @@ -25,6 +25,9 @@ package org.geysermc.integratedpack; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; @@ -34,6 +37,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.util.Map; import java.util.zip.ZipFile; public class JavaResources { @@ -48,12 +52,14 @@ public static void extract(ZipFile clientJar) { CLIENT_JAR = clientJar; try { + // Get the assets we need + JsonObject requiredAssets = Resources.getAsJson("required_assets.json").getAsJsonObject(); + // Get the files we need to copy from the jar to the pack. - String str = Resources.getAsText("required_files.txt"); - for (String line : str.lines().toList()) { - String[] paths = line.split(" "); - String jarAssetPath = paths[0]; - String destinationPath = paths[1]; + JsonObject requiredJarFiles = requiredAssets.getAsJsonObject("files"); + for (Map.Entry entry : requiredJarFiles.entrySet()) { + String jarAssetPath = entry.getKey(); + String destinationPath = entry.getValue().getAsString(); InputStream asset = getAsStream(jarAssetPath); IntegratedPack.log("Copying " + jarAssetPath + " to " + destinationPath + "..."); @@ -72,6 +78,44 @@ public static void extract(ZipFile clientJar) { Files.copy(asset, destination, StandardCopyOption.REPLACE_EXISTING); } + // Get other assets which are not included in the jar file + JsonObject requiredRemoteAssets = requiredAssets.getAsJsonObject("assets"); + for (Map.Entry entry : requiredRemoteAssets.entrySet()) { + String remoteAssetPath = entry.getKey(); + String destinationPath = entry.getValue().getAsString(); + + LauncherMetaWrapper.Asset asset = LauncherMetaWrapper.ASSETS.objects().get(remoteAssetPath); + if (asset == null) { + IntegratedPack.log("WARNING: Unable to find %s in the asset index.".formatted(remoteAssetPath)); + continue; + } + + String bytes = asset.hash().substring(0, 2); + + InputStream assetStream = WebUtils.request("https://resources.download.minecraft.net/%s/%s" + .formatted(bytes, asset.hash())); + + IntegratedPack.log("Downloading " + remoteAssetPath + " to " + destinationPath + "..."); + + String assetFileName = Path.of(remoteAssetPath).toFile().getName(); + Path destination = IntegratedPack.WORKING_PATH.resolve(destinationPath).resolve(assetFileName); + + File destinationFolder = IntegratedPack.WORKING_PATH.resolve(destinationPath).toFile(); + if (!destinationFolder.exists()) { + if (!destinationFolder.mkdirs()) { + IntegratedPack.log("Could not make directories for downloading " + remoteAssetPath + " to " + destinationPath + "!"); + continue; + } + } + + Files.copy(assetStream, destination, StandardCopyOption.REPLACE_EXISTING); + try { + assetStream.close(); + } catch (IOException e) { + IntegratedPack.log("Failed to close input stream, see stacktrace below, continuing..."); + e.printStackTrace(); + } + } } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/geysermc/integratedpack/LauncherMetaWrapper.java b/src/main/java/org/geysermc/integratedpack/LauncherMetaWrapper.java index 9eb8155..7dc5a6b 100644 --- a/src/main/java/org/geysermc/integratedpack/LauncherMetaWrapper.java +++ b/src/main/java/org/geysermc/integratedpack/LauncherMetaWrapper.java @@ -3,11 +3,14 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.security.MessageDigest; import java.util.List; import java.util.Map; public class LauncherMetaWrapper { + public static Assets ASSETS = new Assets(Map.of()); + private static final Path CLIENT_JAR = IntegratedPack.TEMP_PATH.resolve("client.jar"); private static final String LAUNCHER_META_URL = "https://launchermeta.mojang.com/mc/game/version_manifest.json"; @@ -23,13 +26,15 @@ public static Path getLatest() { if (!Files.exists(CLIENT_JAR) || !client.sha1.equals(getSha1(CLIENT_JAR))) { // Download the client jar try (InputStream in = WebUtils.request(client.url())) { - Files.copy(in, CLIENT_JAR); + Files.copy(in, CLIENT_JAR, StandardCopyOption.REPLACE_EXISTING); } catch (Exception e) { throw new RuntimeException("Could not download client jar", e); } } else { IntegratedPack.log("Client jar already exists and is up to date."); } + + ASSETS = Constants.GSON.fromJson(WebUtils.getAsString(versionInfo.assetIndex().url()), Assets.class); } } @@ -80,7 +85,8 @@ public record VersionInfo( String type, String time, String releaseTime, - Map downloads + Map downloads, + AssetIndex assetIndex ) {} public record VersionDownload( @@ -88,4 +94,21 @@ public record VersionDownload( int size, String url ) {} + + public record AssetIndex( + String id, + String sha1, + int size, + int totalSize, + String url + ) {} + + public record Assets( + Map objects + ) {} + + public record Asset( + String hash, + int size + ) {} } diff --git a/src/main/java/org/geysermc/integratedpack/Resources.java b/src/main/java/org/geysermc/integratedpack/Resources.java index 328b28e..1ee0a01 100644 --- a/src/main/java/org/geysermc/integratedpack/Resources.java +++ b/src/main/java/org/geysermc/integratedpack/Resources.java @@ -25,6 +25,10 @@ package org.geysermc.integratedpack; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; @@ -88,6 +92,16 @@ public static String getAsText(String resourcePath, Charset charset) throws IOEx return text; } + /** + * Returns a resource as a JsonElement. + * + * @param resourcePath The path to the resource in the JAR file. + * @return The resource as a JsonElement. + */ + public static JsonElement getAsJson(String resourcePath) throws IOException { + return JsonParser.parseString(getAsText(resourcePath)); + } + /** * Returns a resource as a BufferedImage. * diff --git a/src/main/resources/integratedpack/manifest.json b/src/main/resources/integratedpack/manifest.json index fc6c3e2..c1b4483 100644 --- a/src/main/resources/integratedpack/manifest.json +++ b/src/main/resources/integratedpack/manifest.json @@ -4,7 +4,7 @@ "description": "Bedrock resource pack to extend Geyser functionality", "name": "GeyserIntegratedPack", "uuid": "2254393d-8430-45b0-838a-bd397828c765", - "version": [1, 1, 1], + "version": [1, 1, 2], "min_engine_version": [ 1, 16, 0 ] }, "modules": [ @@ -12,7 +12,7 @@ "description": "GeyserIntegratedPack", "type": "resources", "uuid": "4d60881b-e4ed-466f-925c-8abc873151ba", - "version": [1, 1, 1] + "version": [1, 1, 2] } ] } diff --git a/src/main/resources/integratedpack/sounds/sound_definitions.json b/src/main/resources/integratedpack/sounds/sound_definitions.json index 5dfbe0b..1b1465f 100644 --- a/src/main/resources/integratedpack/sounds/sound_definitions.json +++ b/src/main/resources/integratedpack/sounds/sound_definitions.json @@ -20,6 +20,62 @@ "sounds/block/cherry_wood_fence_gate/toggle2", "sounds/block/cherry_wood_fence_gate/toggle3" ] + }, + "geyseropt.entity.player.attack.knockback": { + "category": "player", + "max_distance": null, + "min_distance": null, + "sounds": [ + { + "load_on_low_memory": true, + "name": "sounds/geyser/entity/player/attack/knockback1", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/knockback2", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/knockback3", + "volume": 0.7 + } + ] + }, + "geyseropt.entity.player.attack.sweep": { + "category": "player", + "max_distance": null, + "min_distance": null, + "sounds": [ + { + "load_on_low_memory": true, + "name": "sounds/geyser/entity/player/attack/sweep1", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/sweep2", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/sweep3", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/sweep4", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/sweep5", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/sweep6", + "volume": 0.7 + }, + { + "name": "sounds/geyser/entity/player/attack/sweep7", + "volume": 0.7 + } + ] } } } diff --git a/src/main/resources/required_assets.json b/src/main/resources/required_assets.json new file mode 100644 index 0000000..b40cbf4 --- /dev/null +++ b/src/main/resources/required_assets.json @@ -0,0 +1,27 @@ +{ + "files": { + "assets/minecraft/textures/entity/projectiles/spectral_arrow.png": "textures/geyser/entity/arrow/", + "assets/minecraft/textures/entity/rabbit/caerbannog.png": "textures/geyser/entity/rabbit/", + "assets/minecraft/textures/particle/damage.png": "textures/geyser/particle/", + "assets/minecraft/textures/particle/flash.png": "textures/geyser/particle/", + "assets/minecraft/textures/particle/nautilus.png": "textures/geyser/particle/", + "assets/minecraft/textures/entity/illager/illusioner.png": "textures/geyser/entity/illager/", + "assets/minecraft/textures/gui/sprites/hud/crosshair_attack_indicator_progress.png": "textures/geyser/ui/", + "assets/minecraft/textures/gui/sprites/hud/crosshair_attack_indicator_background.png": "textures/geyser/ui/", + "assets/minecraft/textures/gui/sprites/hud/hotbar_attack_indicator_progress.png": "textures/geyser/ui/", + "assets/minecraft/textures/gui/sprites/hud/hotbar_attack_indicator_background.png": "textures/geyser/ui/" + }, + "assets": { + "minecraft/sounds/entity/player/attack/knockback1.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/knockback2.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/knockback3.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/knockback4.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/sweep1.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/sweep2.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/sweep3.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/sweep4.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/sweep5.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/sweep6.ogg": "sounds/geyser/entity/player/attack/", + "minecraft/sounds/entity/player/attack/sweep7.ogg": "sounds/geyser/entity/player/attack/" + } +} \ No newline at end of file diff --git a/src/main/resources/required_files.txt b/src/main/resources/required_files.txt deleted file mode 100644 index f5a8252..0000000 --- a/src/main/resources/required_files.txt +++ /dev/null @@ -1,10 +0,0 @@ -assets/minecraft/textures/entity/projectiles/spectral_arrow.png textures/geyser/entity/arrow/ -assets/minecraft/textures/entity/rabbit/caerbannog.png textures/geyser/entity/rabbit/ -assets/minecraft/textures/particle/damage.png textures/geyser/particle/ -assets/minecraft/textures/particle/flash.png textures/geyser/particle/ -assets/minecraft/textures/particle/nautilus.png textures/geyser/particle/ -assets/minecraft/textures/entity/illager/illusioner.png textures/geyser/entity/illager/ -assets/minecraft/textures/gui/sprites/hud/crosshair_attack_indicator_progress.png textures/geyser/ui/ -assets/minecraft/textures/gui/sprites/hud/crosshair_attack_indicator_background.png textures/geyser/ui/ -assets/minecraft/textures/gui/sprites/hud/hotbar_attack_indicator_progress.png textures/geyser/ui/ -assets/minecraft/textures/gui/sprites/hud/hotbar_attack_indicator_background.png textures/geyser/ui/ \ No newline at end of file