Skip to content

Commit

Permalink
fix missing song parts when starting a song with offset
Browse files Browse the repository at this point in the history
  • Loading branch information
LCLPYT committed Mar 17, 2024
1 parent a3298f7 commit 7c28c4e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
12 changes: 12 additions & 0 deletions src/client/java/work/lclpnet/notica/impl/PendingSong.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@ public class PendingSong implements Song {
private final Instruments instruments;
private final boolean stereo;
private final byte signature;
private int startTick;

public PendingSong(SongHeader header) {
this(header, 0);
}

public PendingSong(SongHeader header, int startTick) {
this.durationTicks = header.durationTicks();
this.ticksPerSecond = header.ticksPerSecond();
this.loopConfig = header.loopConfig();
this.instruments = header.instruments();
this.stereo = header.stereo();
this.signature = header.signature();
this.startTick = startTick;

var layerInfo = header.layerInfo();
var layers = new HashMap<Integer, MutableLayer>(layerInfo.size());
Expand Down Expand Up @@ -86,6 +92,8 @@ public byte signature() {
* @param slice The song slice.
*/
public void accept(SongSlice slice) {
startTick = Math.max(0, Math.min(slice.tickStart(), startTick));

for (NoteEvent noteEvent : slice) {
MutableLayer layer = layers.get(noteEvent.layer());

Expand All @@ -94,4 +102,8 @@ public void accept(SongSlice slice) {
layer.accept(noteEvent);
}
}

public int getStartTick() {
return startTick;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,29 +59,53 @@ private CompletableFuture<PacketByteBuf> onQueryVersion(MinecraftClient client,
private void onPlaySong(PlaySongS2CPacket packet, ClientPlayerEntity player, PacketSender sender) {
Identifier songId = packet.getSongId();
byte[] checksum = packet.getChecksum();
int startTick = packet.getStartTick();

PendingSong song = songRepository.get(checksum);

if (song == null) {
logger.debug("Song {} ({}) is not cached, requesting it", songId, ByteHelper.toHexString(checksum, 32));
acceptUnknownSong(packet, songId, checksum, startTick);
} else if (startTick < song.getStartTick()) {
// the cached song is missing parts before its old start
acceptUnknownRegion(packet, song, songId);
}

// song is not cached, create a new instance
song = new PendingSong(packet.getHeader());
controller.playSong(songId, packet.getVolume(), startTick);
}

SongSlice slice = packet.getSlice();
private void acceptUnknownSong(PlaySongS2CPacket packet, Identifier songId, byte[] checksum, int startTick) {
logger.debug("Song {} ({}) is not cached, requesting it...", songId, ByteHelper.toHexString(checksum, 32));

logger.debug("Got initial slice {} for song {}", slice, songId);
// song is not cached, create a new instance
PendingSong song = new PendingSong(packet.getHeader(), startTick);

song.accept(slice);
SongSlice slice = packet.getSlice();

if (!packet.isLast()) {
requestNext(songId, slice);
}
logger.debug("Got initial slice {} for song {}", slice, songId);

songRepository.add(songId, checksum, song);
song.accept(slice);

if (song.loopConfig().enabled() && startTick > 0) {
// songs with looping enabled that start with an offset need to be fetched completely
request(songId, 0, 0);
} else if (!packet.isLast()) {
// request next song part
requestNext(songId, slice);
}

controller.playSong(songId, packet.getVolume(), packet.getStartTick());
songRepository.add(songId, checksum, song);
}

private void acceptUnknownRegion(PlaySongS2CPacket packet, PendingSong song, Identifier songId) {
SongSlice slice = packet.getSlice();

song.accept(slice);

if (packet.isLast()) return;

logger.debug("Cached song is missing parts, requesting the song from the beginning...");

request(songId, 0, 0);
}

private void onStopSong(StopSongBidiPacket packet, ClientPlayerEntity player, PacketSender sender) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
Expand All @@ -20,7 +21,7 @@ public class PlayerConfigContainer {

private final Path directory;
private final Logger logger;
private final Map<UUID, PlayerConfigEntry> entries = new HashMap<>();
private final Map<UUID, PlayerConfigEntry> entries = Collections.synchronizedMap(new HashMap<>());

public PlayerConfigContainer(Path directory, Logger logger) {
this.directory = directory;
Expand Down

0 comments on commit 7c28c4e

Please sign in to comment.