fix(ambiance): stabiliser la lecture du disque blanc #87
@@ -24,8 +24,10 @@ Ambiance conserve ses données v2 ; son protocole passe de 5 à 6.
|
||||
|
||||
## Dépendances clientes embarquées
|
||||
|
||||
Le décodage repose sur Lavaplayer `2.2.7` (Apache-2.0) et youtube-source `1.18.2` (MIT), ainsi que
|
||||
leurs dépendances transitives placées en JAR imbriqués par Loom. Leurs avis de licence restent dans
|
||||
les archives d’origine. L’accès YouTube est effectué uniquement par le client et peut cesser de
|
||||
fonctionner si YouTube modifie ses mécanismes de lecture ; aucune clé ou URL arbitraire n’est
|
||||
acceptée par le serveur.
|
||||
Le décodage repose sur Lavaplayer `2.2.7` (Apache-2.0) et sur le commit youtube-source
|
||||
`f45bbb7aebfcbc1c553769e04af6cd43afa8b7c3` (MIT), épinglé pour intégrer les correctifs de lecture
|
||||
YouTube publiés après `1.18.2`. Le profil iOS corrigé est utilisé sans compte, OAuth, jeton privé ou
|
||||
service de chiffrement tiers. Les dépendances sont placées en JAR imbriqués par Loom et leurs avis
|
||||
de licence restent dans les archives d’origine. L’accès YouTube est effectué uniquement par le
|
||||
client et peut cesser de fonctionner si YouTube modifie ses mécanismes de lecture ; aucune clé ou
|
||||
URL arbitraire n’est acceptée par le serveur.
|
||||
|
||||
+32
-6
@@ -1,5 +1,7 @@
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
def youtubeSourceVersion = "f45bbb7aebfcbc1c553769e04af6cd43afa8b7c3-SNAPSHOT"
|
||||
|
||||
configurations {
|
||||
whiteDiscLibraries
|
||||
implementation.extendsFrom whiteDiscLibraries
|
||||
@@ -13,14 +15,14 @@ dependencies {
|
||||
exclude group: "org.slf4j", module: "slf4j-api"
|
||||
exclude group: "org.jetbrains", module: "annotations"
|
||||
}
|
||||
whiteDiscLibraries("dev.lavalink.youtube:v2:1.18.2") {
|
||||
whiteDiscLibraries("dev.lavalink.youtube:v2:${youtubeSourceVersion}") {
|
||||
exclude group: "org.slf4j", module: "slf4j-api"
|
||||
exclude group: "org.jetbrains", module: "annotations"
|
||||
}
|
||||
[
|
||||
"dev.arbjerg:lavaplayer-natives:2.2.7",
|
||||
"dev.arbjerg:lava-common:2.2.7",
|
||||
"dev.lavalink.youtube:common:1.18.2",
|
||||
"dev.lavalink.youtube:common:${youtubeSourceVersion}",
|
||||
"org.mozilla:rhino-engine:1.7.15",
|
||||
"org.mozilla:rhino:1.7.15",
|
||||
"commons-io:commons-io:2.13.0",
|
||||
@@ -64,15 +66,24 @@ tasks.register("whiteDiscUrlSmoke", JavaExec) {
|
||||
mainClass = "fr.koka99cab.sanctuary26.ambiance.white_disc.WhiteDiscUrlSmoke"
|
||||
}
|
||||
|
||||
tasks.register("whiteDiscPlaybackSmoke", JavaExec) {
|
||||
group = "verification"
|
||||
description = "Manually checks live YouTube loading and PCM decoding for the white disc."
|
||||
dependsOn tasks.named("testClasses")
|
||||
classpath = sourceSets.test.runtimeClasspath
|
||||
mainClass = "fr.koka99cab.sanctuary26.ambiance.client.audio.WhiteDiscPlaybackSmoke"
|
||||
}
|
||||
|
||||
tasks.named("test") {
|
||||
failOnNoDiscoveredTests = false
|
||||
}
|
||||
|
||||
tasks.register("verifyAmbiance") {
|
||||
group = "verification"
|
||||
description = "Checks Ambiance alpha.17, including deferred white-disc playback startup."
|
||||
description = "Checks Ambiance alpha.18, including resilient white-disc YouTube playback."
|
||||
inputs.files(fileTree("src/main/java"))
|
||||
inputs.files(fileTree("src/main/resources"))
|
||||
inputs.file(file("src/test/java/fr/koka99cab/sanctuary26/ambiance/client/audio/WhiteDiscPlaybackSmoke.java"))
|
||||
inputs.file(rootProject.file("pack/migrations/26.2.0-alpha.125-realtime-calendar-to-alpha.126.json"))
|
||||
inputs.file(rootProject.file("pack/migrations/26.2.0-alpha.127-daily-ambiance-sodium-iris-to-alpha.128.json"))
|
||||
inputs.file(rootProject.file("pack/migrations/26.2.0-alpha.128-ambiance-visuals-canon-iris-to-alpha.129.json"))
|
||||
@@ -122,8 +133,12 @@ tasks.register("verifyAmbiance") {
|
||||
file("src/main/resources/data/ambiance/jukebox_song/white_disc.json"))
|
||||
def levelEventMixin = file(
|
||||
"src/main/java/fr/koka99cab/sanctuary26/ambiance/mixin/client/LevelEventHandlerMixin.java").text
|
||||
def whiteDiscAudioPlayer = file(
|
||||
"src/main/java/fr/koka99cab/sanctuary26/ambiance/client/audio/WhiteDiscAudioPlayer.java").text
|
||||
def whiteDiscPlaybackSmoke = file(
|
||||
"src/test/java/fr/koka99cab/sanctuary26/ambiance/client/audio/WhiteDiscPlaybackSmoke.java").text
|
||||
|
||||
if (project.version.toString() != "0.0.0-alpha.17"
|
||||
if (project.version.toString() != "0.0.0-alpha.18"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.125"
|
||||
|| migration.target?.pack_version != "26.2.0-alpha.126"
|
||||
|| migration.target?.modules?.ambiance != "0.0.0-alpha.1"
|
||||
@@ -327,6 +342,15 @@ tasks.register("verifyAmbiance") {
|
||||
|| !javaText.contains('client.level.dimension().equals(playback.dimension())')
|
||||
|| !javaText.contains('MAXIMUM_TRACK_MILLIS = 30L * 60L * 1_000L')
|
||||
|| !javaText.contains('new Pcm16AudioDataFormat(1, LavaplayerAudioStream.SAMPLE_RATE')
|
||||
|| !javaText.contains('new YoutubeAudioSourceManager(false, new Ios())')
|
||||
|| !javaText.contains('player.addListener(new AudioEventAdapter()')
|
||||
|| !javaText.contains('failPlayback(client, key, failedPlayer)')
|
||||
|| !javaText.contains('initialWaitAttempted')
|
||||
|| !javaText.contains('frame = player.provide()')
|
||||
|| !whiteDiscAudioPlayer.contains('handle.execute(channel -> channel.stop())')
|
||||
|| whiteDiscAudioPlayer.contains('.release()')
|
||||
|| !whiteDiscPlaybackSmoke.contains('https://www.youtube.com/watch?v=Ue5ZBe-GzSM')
|
||||
|| !whiteDiscPlaybackSmoke.contains('Decoded audible PCM data')
|
||||
|| !javaText.contains('SoundSource.RECORDS')
|
||||
|| !javaText.contains('channel.linearAttenuation(ATTENUATION_DISTANCE)')
|
||||
|| !javaText.contains('LONG_HOSTS = Set.of(')
|
||||
@@ -348,8 +372,10 @@ tasks.register("verifyAmbiance") {
|
||||
}
|
||||
}
|
||||
|| !file("build.gradle").text.contains('dev.arbjerg:lavaplayer:2.2.7')
|
||||
|| !file("build.gradle").text.contains('dev.lavalink.youtube:v2:1.18.2')) {
|
||||
throw new GradleException("Ambiance alpha.17 white-disc playback contract is incomplete")
|
||||
|| !file("build.gradle").text.contains(
|
||||
'def youtubeSourceVersion = "f45bbb7aebfcbc1c553769e04af6cd43afa8b7c3-SNAPSHOT"')
|
||||
|| !file("build.gradle").text.contains('dev.lavalink.youtube:v2:${youtubeSourceVersion}')) {
|
||||
throw new GradleException("Ambiance alpha.18 white-disc playback contract is incomplete")
|
||||
}
|
||||
|
||||
[
|
||||
|
||||
+14
-6
@@ -12,13 +12,12 @@ import net.minecraft.client.sounds.AudioStream;
|
||||
/** Adapts bounded mono PCM frames from Lavaplayer to Minecraft's streaming OpenAL channel. */
|
||||
final class LavaplayerAudioStream implements AudioStream {
|
||||
static final int SAMPLE_RATE = 48_000;
|
||||
private static final int FRAME_SAMPLES = 960;
|
||||
private static final int BYTES_PER_SAMPLE = 2;
|
||||
private static final AudioFormat FORMAT =
|
||||
new AudioFormat(SAMPLE_RATE, 16, 1, true, false);
|
||||
private final AudioPlayer player;
|
||||
private byte[] pending = new byte[0];
|
||||
private int pendingOffset;
|
||||
private boolean initialWaitAttempted;
|
||||
private volatile boolean closed;
|
||||
private volatile boolean ended;
|
||||
|
||||
@@ -45,9 +44,8 @@ final class LavaplayerAudioStream implements AudioStream {
|
||||
AudioFrame frame = nextFrame();
|
||||
if (frame == null) {
|
||||
if (ended) break;
|
||||
int silence = Math.min(output.remaining(), FRAME_SAMPLES * BYTES_PER_SAMPLE);
|
||||
for (int index = 0; index < silence; index++) output.put((byte) 0);
|
||||
continue;
|
||||
while (output.hasRemaining()) output.put((byte) 0);
|
||||
break;
|
||||
}
|
||||
if (frame.isTerminator()) {
|
||||
ended = true;
|
||||
@@ -63,7 +61,13 @@ final class LavaplayerAudioStream implements AudioStream {
|
||||
|
||||
private AudioFrame nextFrame() throws IOException {
|
||||
try {
|
||||
AudioFrame frame = player.provide(2, TimeUnit.SECONDS);
|
||||
AudioFrame frame;
|
||||
if (!initialWaitAttempted) {
|
||||
initialWaitAttempted = true;
|
||||
frame = player.provide(2, TimeUnit.SECONDS);
|
||||
} else {
|
||||
frame = player.provide();
|
||||
}
|
||||
if (frame == null && player.getPlayingTrack() == null) ended = true;
|
||||
return frame;
|
||||
} catch (TimeoutException ignored) {
|
||||
@@ -78,6 +82,10 @@ final class LavaplayerAudioStream implements AudioStream {
|
||||
return ended;
|
||||
}
|
||||
|
||||
boolean uses(AudioPlayer expectedPlayer) {
|
||||
return player == expectedPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (closed) return;
|
||||
|
||||
+45
-11
@@ -5,10 +5,12 @@ import com.sedmelluq.discord.lavaplayer.format.Pcm16AudioDataFormat;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import dev.lavalink.youtube.YoutubeAudioSourceManager;
|
||||
import dev.lavalink.youtube.clients.Ios;
|
||||
import fr.koka99cab.sanctuary26.ambiance.AmbianceMod;
|
||||
import fr.koka99cab.sanctuary26.ambiance.mixin.client.SoundEngineAccessor;
|
||||
import fr.koka99cab.sanctuary26.ambiance.mixin.client.SoundManagerAccessor;
|
||||
@@ -114,24 +116,49 @@ public final class WhiteDiscAudioPlayer {
|
||||
ChannelAccess channels = ((SoundEngineAccessor) ((SoundManagerAccessor) client.getSoundManager())
|
||||
.ambiance$getSoundEngine()).ambiance$getChannelAccess();
|
||||
channels.createHandle(Library.Pool.STREAMING).thenAccept(handle -> client.execute(() -> {
|
||||
if (handle == null || REQUESTS.getOrDefault(key, -1L) != request) {
|
||||
if (handle != null) handle.release();
|
||||
if (handle == null || REQUESTS.getOrDefault(key, -1L) != request
|
||||
|| !validTarget(client, pos)) {
|
||||
if (handle != null) handle.execute(channel -> channel.stop());
|
||||
if (REQUESTS.getOrDefault(key, -1L) == request) REQUESTS.remove(key);
|
||||
return;
|
||||
}
|
||||
AudioPlayer player = MANAGER.createPlayer();
|
||||
player.playTrack(track);
|
||||
LavaplayerAudioStream stream = new LavaplayerAudioStream(player);
|
||||
Playback playback = new Playback(pos.immutable(), client.level.dimension(), handle, stream);
|
||||
PLAYBACKS.put(key, playback);
|
||||
REQUESTS.remove(key);
|
||||
player.addListener(new AudioEventAdapter() {
|
||||
@Override
|
||||
public void onTrackException(AudioPlayer failedPlayer, AudioTrack failedTrack,
|
||||
FriendlyException exception) {
|
||||
AmbianceMod.LOGGER.warn("White-disc playback failed for YouTube video {}: {}",
|
||||
failedTrack.getIdentifier(), exception.getMessage());
|
||||
client.execute(() -> failPlayback(client, key, failedPlayer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackStuck(AudioPlayer stuckPlayer, AudioTrack stuckTrack,
|
||||
long thresholdMs) {
|
||||
AmbianceMod.LOGGER.warn("White-disc playback stalled for YouTube video {} after {} ms",
|
||||
stuckTrack.getIdentifier(), thresholdMs);
|
||||
client.execute(() -> failPlayback(client, key, stuckPlayer));
|
||||
}
|
||||
});
|
||||
player.playTrack(track);
|
||||
float volume = client.options.getFinalSoundSourceVolume(SoundSource.RECORDS);
|
||||
handle.execute(channel -> {
|
||||
channel.setSelfPosition(Vec3.atCenterOf(pos));
|
||||
channel.setRelative(false);
|
||||
channel.linearAttenuation(ATTENUATION_DISTANCE);
|
||||
channel.setVolume(volume);
|
||||
channel.attachBufferStream(stream);
|
||||
channel.play();
|
||||
try {
|
||||
channel.setSelfPosition(Vec3.atCenterOf(pos));
|
||||
channel.setRelative(false);
|
||||
channel.linearAttenuation(ATTENUATION_DISTANCE);
|
||||
channel.setVolume(volume);
|
||||
channel.attachBufferStream(stream);
|
||||
channel.play();
|
||||
} catch (RuntimeException | LinkageError exception) {
|
||||
AmbianceMod.LOGGER.error("Unable to attach white-disc audio to Minecraft's sound engine",
|
||||
exception);
|
||||
client.execute(() -> failPlayback(client, key, player));
|
||||
}
|
||||
});
|
||||
if (client.player != null) client.player.sendOverlayMessage(
|
||||
Component.translatable("message.ambiance.white_disc.playing", track.getInfo().title));
|
||||
@@ -145,6 +172,14 @@ public final class WhiteDiscAudioPlayer {
|
||||
Component.translatable("message.ambiance.white_disc.failed"));
|
||||
}
|
||||
|
||||
private static void failPlayback(Minecraft client, long key, AudioPlayer player) {
|
||||
Playback playback = PLAYBACKS.get(key);
|
||||
if (playback == null || !playback.stream().uses(player)) return;
|
||||
stop(key);
|
||||
if (client.player != null) client.player.sendOverlayMessage(
|
||||
Component.translatable("message.ambiance.white_disc.failed"));
|
||||
}
|
||||
|
||||
public static void stop(BlockPos pos) {
|
||||
stop(pos.asLong());
|
||||
}
|
||||
@@ -156,7 +191,6 @@ public final class WhiteDiscAudioPlayer {
|
||||
if (playback == null) return;
|
||||
playback.stream().close();
|
||||
playback.handle().execute(channel -> channel.stop());
|
||||
playback.handle().release();
|
||||
}
|
||||
|
||||
public static void tick(Minecraft client) {
|
||||
@@ -200,7 +234,7 @@ public final class WhiteDiscAudioPlayer {
|
||||
new Pcm16AudioDataFormat(1, LavaplayerAudioStream.SAMPLE_RATE, 960, false));
|
||||
manager.setFrameBufferDuration(5_000);
|
||||
manager.setItemLoaderThreadPoolSize(2);
|
||||
manager.registerSourceManager(new YoutubeAudioSourceManager(false));
|
||||
manager.registerSourceManager(new YoutubeAudioSourceManager(false, new Ios()));
|
||||
return manager;
|
||||
}
|
||||
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package fr.koka99cab.sanctuary26.ambiance.client.audio;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.format.Pcm16AudioDataFormat;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import dev.lavalink.youtube.YoutubeAudioSourceManager;
|
||||
import dev.lavalink.youtube.clients.Ios;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/** Manual network smoke test for the exact YouTube playback path used by white discs. */
|
||||
public final class WhiteDiscPlaybackSmoke {
|
||||
private static final String VIDEO_URL = "https://www.youtube.com/watch?v=Ue5ZBe-GzSM";
|
||||
|
||||
private WhiteDiscPlaybackSmoke() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
DefaultAudioPlayerManager manager = new DefaultAudioPlayerManager();
|
||||
manager.getConfiguration().setOutputFormat(
|
||||
new Pcm16AudioDataFormat(1, LavaplayerAudioStream.SAMPLE_RATE, 960, false));
|
||||
manager.registerSourceManager(new YoutubeAudioSourceManager(false, new Ios()));
|
||||
try {
|
||||
AudioTrack track = load(manager).get(30, TimeUnit.SECONDS);
|
||||
AudioPlayer player = manager.createPlayer();
|
||||
player.playTrack(track);
|
||||
LavaplayerAudioStream stream = new LavaplayerAudioStream(player);
|
||||
int decodedBytes = 0;
|
||||
for (int index = 0; index < 4; index++) {
|
||||
ByteBuffer pcm = stream.read(LavaplayerAudioStream.SAMPLE_RATE * 2);
|
||||
if (pcm == null) break;
|
||||
while (pcm.hasRemaining()) {
|
||||
if (pcm.get() != 0) decodedBytes++;
|
||||
}
|
||||
}
|
||||
if (decodedBytes == 0) {
|
||||
throw new IllegalStateException("YouTube playback produced no audible PCM data");
|
||||
}
|
||||
System.out.println("Decoded audible PCM data from "
|
||||
+ track.getInfo().title);
|
||||
stream.close();
|
||||
} finally {
|
||||
manager.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private static CompletableFuture<AudioTrack> load(DefaultAudioPlayerManager manager) {
|
||||
CompletableFuture<AudioTrack> result = new CompletableFuture<>();
|
||||
manager.loadItem(VIDEO_URL, new AudioLoadResultHandler() {
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack track) {
|
||||
result.complete(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist playlist) {
|
||||
AudioTrack selected = playlist.getSelectedTrack();
|
||||
if (selected == null && !playlist.getTracks().isEmpty()) {
|
||||
selected = playlist.getTracks().getFirst();
|
||||
}
|
||||
if (selected == null) result.completeExceptionally(
|
||||
new IllegalStateException("YouTube playlist contained no track"));
|
||||
else result.complete(selected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
result.completeExceptionally(new IllegalStateException("YouTube returned no match"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException exception) {
|
||||
result.completeExceptionally(exception);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -36,8 +36,8 @@ allprojects {
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven {
|
||||
name = "Lavalink"
|
||||
url = "https://maven.lavalink.dev/releases"
|
||||
name = "LavalinkSnapshots"
|
||||
url = "https://maven.lavalink.dev/snapshots"
|
||||
}
|
||||
}
|
||||
filter { includeGroup "dev.lavalink.youtube" }
|
||||
@@ -4548,7 +4548,7 @@ tasks.register("verifyWeatherTntAmbianceRelease") {
|
||||
def ouchManifest = new JsonSlurper().parse(file("ouch/src/main/resources/fabric.mod.json"))
|
||||
def rootBuild = file("build.gradle").text
|
||||
if (rootProject.pack_version != "26.2.0-alpha.214"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.17"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.18"
|
||||
|| rootProject.ouch_version != "0.0.0-alpha.10"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.199"
|
||||
|| migration.source?.modules != [ambiance: "0.0.0-alpha.11", ouch: "0.0.0-alpha.8"]
|
||||
@@ -5319,7 +5319,7 @@ tasks.register("verifyCanapliaFoundation") {
|
||||
"ambiance/src/main/java/fr/koka99cab/sanctuary26/ambiance/api/visual/AmbianceVisualEffectApi.java").text
|
||||
if (rootProject.pack_version != "26.2.0-alpha.214"
|
||||
|| rootProject.itsalive_version != "0.0.0-alpha.36"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.17"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.18"
|
||||
|| migration.issue != 35
|
||||
|| migration.source?.fabric_id != "canaplia"
|
||||
|| migration.source?.version != "2.0.0"
|
||||
@@ -5570,7 +5570,7 @@ tasks.register("verifyCanapliaAlpha209Release") {
|
||||
itsalive: "0.0.0-alpha.33",
|
||||
onlyfun: "0.0.0-alpha.20"]
|
||||
if (rootProject.pack_version != "26.2.0-alpha.214"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.17"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.18"
|
||||
|| rootProject.itsalive_version != "0.0.0-alpha.36"
|
||||
|| rootProject.onlyfun_version != "0.0.0-alpha.24"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.207"
|
||||
@@ -5785,7 +5785,7 @@ tasks.register("verifyAlpha211Release") {
|
||||
def currentModules = expectedTarget + [
|
||||
sanctuary: "0.0.0-alpha.120",
|
||||
ambiance: "0.0.0-alpha.17"]
|
||||
def workspaceModules = currentModules + [ambiance: "0.0.0-alpha.17"]
|
||||
def workspaceModules = currentModules + [ambiance: "0.0.0-alpha.18"]
|
||||
def expectedDataVersions = [ambiance: 2, itsalive: 3, onlyfun: 2, ouch: 1, sanctuary: 11]
|
||||
def expectedProtocols = [ambiance: 6, itsalive: 4, onlyfun: 3, ouch: 1, sanctuary: 22]
|
||||
def manifests = expectedTarget.collectEntries { id, version ->
|
||||
@@ -5948,7 +5948,7 @@ tasks.register("verifyAlpha213Release") {
|
||||
it.path == "mods/jei-26.2-fabric-30.28.0.193.jar"
|
||||
}
|
||||
if (rootProject.pack_version != "26.2.0-alpha.214"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.17"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.18"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.212"
|
||||
|| migration.source?.modules != [ambiance: "0.0.0-alpha.15"]
|
||||
|| migration.target?.pack_version != "26.2.0-alpha.213"
|
||||
@@ -6016,7 +6016,7 @@ tasks.register("verifyAlpha214Release") {
|
||||
def urlSmoke = file(
|
||||
"ambiance/src/test/java/fr/koka99cab/sanctuary26/ambiance/white_disc/WhiteDiscUrlSmoke.java").text
|
||||
if (rootProject.pack_version != "26.2.0-alpha.214"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.17"
|
||||
|| rootProject.ambiance_version != "0.0.0-alpha.18"
|
||||
|| migration.source?.pack_version != "26.2.0-alpha.213"
|
||||
|| migration.source?.modules != [ambiance: "0.0.0-alpha.16"]
|
||||
|| migration.target?.pack_version != "26.2.0-alpha.214"
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ fabric_api_version=0.158.0+26.2
|
||||
# Standby modules stay at zero until their migration really begins.
|
||||
mod_version=0.0.0-alpha.0
|
||||
module_lifecycle=standby
|
||||
ambiance_version=0.0.0-alpha.17
|
||||
ambiance_version=0.0.0-alpha.18
|
||||
ambiance_lifecycle=active
|
||||
redstoner_version=0.0.0-alpha.10
|
||||
redstoner_lifecycle=active
|
||||
|
||||
Reference in New Issue
Block a user