Skip to content

Commit

Permalink
Merge pull request #17 from KabanFriends/dev/song-refactor
Browse files Browse the repository at this point in the history
Massive restructuring
  • Loading branch information
KabanFriends authored Jun 29, 2024
2 parents e670bbf + a31ac58 commit 6087900
Show file tree
Hide file tree
Showing 70 changed files with 1,700 additions and 1,472 deletions.
5 changes: 3 additions & 2 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ dependencies {
// Do NOT use other classes from fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"

modImplementation "dev.isxander:yet-another-config-lib:${rootProject.yacl_version}-fabric"
modCompileOnly "dev.isxander:yet-another-config-lib:${rootProject.yacl_version}-fabric"

implementation "com.github.umjammer:jlayer:${rootProject.jlayer_version}"
compileOnly "com.github.umjammer:jlayer:${rootProject.jlayer_version}"
compileOnly "org.java-websocket:Java-WebSocket:${rootProject.java_websocket_version}"
}

loom {
Expand Down
114 changes: 84 additions & 30 deletions common/src/main/java/io/github/kabanfriends/craftgr/CraftGR.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package io.github.kabanfriends.craftgr;

import io.github.kabanfriends.craftgr.config.GRConfig;
import io.github.kabanfriends.craftgr.handler.OverlayHandler;
import io.github.kabanfriends.craftgr.handler.SongHandler;
import io.github.kabanfriends.craftgr.audio.RadioStream;
import io.github.kabanfriends.craftgr.config.ModConfig;
import io.github.kabanfriends.craftgr.event.ClientEvents;
import io.github.kabanfriends.craftgr.keybind.Keybinds;
import io.github.kabanfriends.craftgr.platform.Platform;
import io.github.kabanfriends.craftgr.render.overlay.impl.SongInfoOverlay;
import io.github.kabanfriends.craftgr.overlay.SongInfoOverlay;
import io.github.kabanfriends.craftgr.song.FallbackSongProvider;
import io.github.kabanfriends.craftgr.song.SongProvider;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
Expand All @@ -20,51 +23,102 @@

public class CraftGR {

public static Logger LOGGER = LogManager.getLogger();

public static final String MOD_ID = "craftgr";
public static final String MOD_NAME = "CraftGR";

public static final Minecraft MC = Minecraft.getInstance();
public static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
public static final Component AUDIO_MUTED_ICON = Component.literal("M").withStyle(Style.EMPTY.withFont(ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "icons")));
public static final Component RECONNECT_ICON = Component.literal("R").withStyle(Style.EMPTY.withFont(ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "icons")));

private static CraftGR instance;

private final Minecraft minecraft;
private final Platform platform;
private final Logger logger;
private final ModConfig config;
private final ExecutorService executor;
private final CloseableHttpClient httpClient;
private final ClientEvents events;
private final Keybinds keybinds;
private final SongInfoOverlay songInfoOverlay;
private final RadioStream radioStream;

private SongProvider songProvider = new FallbackSongProvider();

public CraftGR(Platform platform) {
instance = this;

this.minecraft = Minecraft.getInstance();
this.platform = platform;
this.logger = LogManager.getLogger();
this.config = new ModConfig(this);
this.executor = Executors.newCachedThreadPool();
this.httpClient = HttpClients.createDefault();
this.events = new ClientEvents(this);
this.keybinds = new Keybinds(this);
this.songInfoOverlay = new SongInfoOverlay(this);
this.radioStream = new RadioStream(this);
}

public static final Component AUDIO_MUTED_ICON;
public static final Component RECONNECT_ICON;
public Platform getPlatform() {
return platform;
}

static {
ResourceLocation iconFont = ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "icons");
AUDIO_MUTED_ICON = Component.literal("M").withStyle(Style.EMPTY.withFont(iconFont));
RECONNECT_ICON = Component.literal("R").withStyle(Style.EMPTY.withFont(iconFont));
public CloseableHttpClient getHttpClient() {
return httpClient;
}

public static boolean renderSongOverlay;
public ExecutorService getThreadExecutor() {
return executor;
}

private static Platform platform;
private static CloseableHttpClient httpClient;
public SongInfoOverlay getSongInfoOverlay() {
return songInfoOverlay;
}

public static void init(Platform platform) {
CraftGR.platform = platform;
public Minecraft getMinecraft() {
return minecraft;
}

GRConfig.init();
public ModConfig getConfig() {
return config;
}

CraftGR.httpClient = HttpClients.createSystem();
public Keybinds getKeybinds() {
return keybinds;
}

public static void lateInit() {
OverlayHandler.addOverlay(new SongInfoOverlay(MC.getTextureManager()));
SongHandler.getInstance().initialize();
public SongProvider getSongProvider() {
return songProvider;
}

public static Platform getPlatform() {
return platform;
public RadioStream getRadioStream() {
return radioStream;
}

public static CloseableHttpClient getHttpClient() {
return httpClient;
public void setSongProvider(SongProvider newProvider) {
if (newProvider == null) {
return;
}

if (songProvider != null) {
songProvider.stop();
}

songProvider = newProvider;
songProvider.start();

CraftGR.getInstance().getSongInfoOverlay().onSongChanged();
}

public ClientEvents clientEvents() {
return events;
}

public static void log(Level level, String message) {
LOGGER.log(level, "[" + MOD_NAME + "] " + message);
public void log(Level level, String message) {
logger.log(level, String.format("[%s] %s", MOD_NAME, message));
}

public static CraftGR getInstance() {
return instance;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package io.github.kabanfriends.craftgr.audio;

import io.github.kabanfriends.craftgr.CraftGR;
import io.github.kabanfriends.craftgr.config.GRConfig;
import io.github.kabanfriends.craftgr.util.ProcessResult;
import io.github.kabanfriends.craftgr.config.ModConfig;
import javazoom.jl.decoder.*;
import net.minecraft.sounds.SoundSource;
import org.apache.logging.log4j.Level;
Expand All @@ -17,29 +16,25 @@
// Code based on: https://github.com/PC-Logix/OpenFM/blob/1.12.2/src/main/java/pcl/OpenFM/player/MP3Player.java
public class AudioPlayer {

private final Bitstream bitstream;
private final CraftGR craftGR;
private final Decoder decoder;

private Bitstream bitstream;
private IntBuffer buffer;
private IntBuffer source;
private float baseVolume = 1.0F;
private boolean playing = false;

public AudioPlayer(InputStream stream) {
this.bitstream = new Bitstream(stream);
public AudioPlayer(CraftGR craftGR) {
this.craftGR = craftGR;
this.decoder = new Decoder();
}

protected int alError() {
int error = AL10.alGetError();
if (error != AL10.AL_NO_ERROR) {
CraftGR.log(Level.ERROR, String.format("AL10 Error: %d: %s", error, AL10.alGetString(error)));
return error;
}
return 0;
public void setStream(InputStream stream) {
this.bitstream = new Bitstream(stream);
}

public ProcessResult play() {
public void play() throws AudioPlayerException {
try {
this.source = BufferUtils.createIntBuffer(1);
AL10.alGenSources(this.source);
Expand All @@ -48,47 +43,71 @@ public ProcessResult play() {
AL10.alSourcei(this.source.get(0), AL10.AL_LOOPING, AL10.AL_FALSE);
AL10.alSourcef(this.source.get(0), AL10.AL_PITCH, 1.0f);

AL10.alSourcef(this.source.get(0), AL10.AL_GAIN, this.baseVolume * (GRConfig.<Integer>getValue("volume") / 100f) * CraftGR.MC.options.getSoundSourceVolume(SoundSource.MASTER));
alError();

this.playing = true;
ProcessResult result = ProcessResult.SUCCESS;

while (this.playing && result == ProcessResult.SUCCESS) {
AL10.alSourcef(this.source.get(0), AL10.AL_GAIN, this.baseVolume * (GRConfig.<Integer>getValue("volume") / 100f) * CraftGR.MC.options.getSoundSourceVolume(SoundSource.MASTER));
result = decodeFrame();
}
do {
applyVolume();
} while (this.playing && decodeFrame());

close();
return result;
} catch (Exception e) {
if (this.playing) {
e.printStackTrace();
return ProcessResult.ERROR;
throw new AudioPlayerException(e);
}
return ProcessResult.STOP;
}
}

public void close() {
public void stop() {
this.playing = false;
if (this.source != null) {
AL10.alSourcef(this.source.get(0), AL10.AL_GAIN, 0.0f);
AL10.alSourceStop(this.source.get());
alError();
}
}

public void close() throws BitstreamException {
if (this.source != null) {
int state = AL10.alGetSourcei(this.source.get(0), AL10.AL_SOURCE_STATE);
if (state != AL10.AL_PLAYING && state != AL10.AL_PAUSED) {
AL10.alSourcei(this.source.get(0), AL10.AL_BUFFER, 0);
}
AL10.alDeleteSources(this.source);
this.source = null;
alError();
}
if (this.buffer != null) {
AL10.alDeleteBuffers(this.buffer);
this.buffer = null;
alError();
}
if (this.bitstream != null) {
this.bitstream.close();
}
}

protected ProcessResult decodeFrame() {
public void setBaseVolume(float f) {
this.baseVolume = f;
if (this.playing && this.source != null) {
applyVolume();
}
}

public float getBaseVolume() {
return this.baseVolume;
}

public boolean isPlaying() {
return this.playing;
}

private boolean decodeFrame() throws AudioPlayerException {
try {
Header h = this.bitstream.readFrame();

if (h == null) {
close();
return ProcessResult.STOP;
return false;
}

SampleBuffer output = (SampleBuffer) this.decoder.decodeFrame(h, this.bitstream);
Expand All @@ -108,25 +127,26 @@ protected ProcessResult decodeFrame() {
ShortBuffer data = (ShortBuffer) ((Buffer) shortBuffer).flip();
AL10.alBufferData(this.buffer.get(0), (output.getChannelCount() > 1) ? AL10.AL_FORMAT_STEREO16 : AL10.AL_FORMAT_MONO16, data, output.getSampleFrequency());
AL10.alSourceQueueBuffers(this.source.get(0), buffer);
alError();

int state = AL10.alGetSourcei(this.source.get(0), AL10.AL_SOURCE_STATE);
if (this.playing && state != AL10.AL_PLAYING) {
AL10.alSourcePlay(this.source.get(0));
}
alError();

this.bitstream.closeFrame();

return ProcessResult.SUCCESS;
return true;
} catch (Exception e) {
if (this.playing) {
e.printStackTrace();
return ProcessResult.ERROR;
throw new AudioPlayerException(e);
}
return ProcessResult.STOP;
return false;
}
}

protected boolean skipFrame() throws JavaLayerException {
private boolean skipFrame() throws JavaLayerException {
Header h = this.bitstream.readFrame();
if (h == null) {
return false;
Expand All @@ -135,28 +155,18 @@ protected boolean skipFrame() throws JavaLayerException {
return true;
}

public void stop() {
this.playing = false;
if (this.source != null) {
AL10.alSourcef(this.source.get(0), AL10.AL_GAIN, 0.0f);
AL10.alSourceStop(this.source.get());
}
}

public void setBaseVolume(float f) {
this.baseVolume = f;
if (this.playing && this.source != null) {
float volume = f * (GRConfig.<Integer>getValue("volume") / 100f) * CraftGR.MC.options.getSoundSourceVolume(SoundSource.MASTER);
AL10.alSourcef(this.source.get(0), AL10.AL_GAIN, volume);
private int alError() {
int error = AL10.alGetError();
if (error != AL10.AL_NO_ERROR) {
craftGR.log(Level.WARN, String.format("AL10 Error: %d: %s", error, AL10.alGetString(error)));
Thread.dumpStack();
return error;
}
return 0;
}

public float getBaseVolume() {
return this.baseVolume;
}

public boolean isPlaying() {
return this.playing;
private void applyVolume() {
AL10.alSourcef(this.source.get(0), AL10.AL_GAIN, this.baseVolume * (ModConfig.<Integer>get("volume") / 100f) * craftGR.getMinecraft().options.getSoundSourceVolume(SoundSource.MASTER));
alError();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.github.kabanfriends.craftgr.audio;

public class AudioPlayerException extends Exception {

public AudioPlayerException(String message) {
super(message);
}

public AudioPlayerException(String message, Throwable cause) {
super(message, cause);
}

public AudioPlayerException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.github.kabanfriends.craftgr.audio;

public class ConnectionException extends Exception {

public ConnectionException(String message) {
super(message);
}

public ConnectionException(String message, Throwable cause) {
super(message, cause);
}

public ConnectionException(Throwable cause) {
super(cause);
}
}
Loading

0 comments on commit 6087900

Please sign in to comment.