Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,32 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
- uses: actions/checkout@v5
- name: Set up JDK 25
uses: actions/setup-java@v5
with:
distribution: 'corretto'
java-version: '21'
java-version: '25'
- name: Cache Gradle dependencies
uses: actions/cache@v5
with:
path: ~/.gradle/caches
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-${{ runner.os }}-
- name: Cache Gradle wrapper
uses: actions/cache@v5
with:
path: ~/.gradle/wrapper
key: gradle-wrapper-${{ runner.os }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
gradle-wrapper-${{ runner.os }}-
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build --full-stacktrace
- name: Upload Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: Artifacts
path: build/libs/*-release.jar
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ run/
# LabyGradle | Addon Plugin
build-data.txt
.assetsroot
resources_index.json
access_widener_index.json

# Don't ignore libraries
!libs/*.jar
7 changes: 6 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
val versions = providers.gradleProperty("net.labymod.minecraft-versions").get().split(";")

group = "org.example"
version = providers.environmentVariable("VERSION").getOrElse("1.0.2")
version = providers.environmentVariable("VERSION").getOrElse("1.1.0")

labyMod {
defaultPackageName = "com.rappytv.betterfriends"
Expand Down Expand Up @@ -39,4 +39,9 @@ subprojects {

group = rootProject.group
version = rootProject.version

extensions.findByType(JavaPluginExtension::class.java)?.apply {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,21 @@
import com.rappytv.betterfriends.interactions.FriendNoteEditorBullet;
import com.rappytv.betterfriends.interactions.FriendTogglePinBullet;
import com.rappytv.betterfriends.listeners.ChatReceiveListener;
import com.rappytv.betterfriends.listeners.FriendAddListener;
import com.rappytv.betterfriends.listeners.FriendRemoveListener;
import com.rappytv.betterfriends.listeners.FriendRequestReceiveListener;
import com.rappytv.betterfriends.listeners.FriendRequestRemoveListener;
import com.rappytv.betterfriends.listeners.FriendServerStateListener;
import com.rappytv.betterfriends.listeners.FriendStatusUpdateListener;
import com.rappytv.betterfriends.listeners.ConfigVersionListener;
import com.rappytv.betterfriends.listeners.FriendListener;
import com.rappytv.betterfriends.listeners.FriendRequestListener;
import com.rappytv.betterfriends.listeners.LabyChatReceiveListener;
import com.rappytv.betterfriends.listeners.TemporaryPinListener;
import com.rappytv.betterfriends.ui.badge.FriendPinBadge;
import com.rappytv.betterfriends.ui.hud.FriendCountHudWidget;
import com.rappytv.betterfriends.ui.hud.IncomingFriendRequestCountHudWidget;
import com.rappytv.betterfriends.ui.hud.OnlineFriendCountHudWidget;
import com.rappytv.betterfriends.ui.hud.UnreadChatCountWidget;
import com.rappytv.betterfriends.ui.tags.FriendNoteNameTag;
import com.rappytv.betterfriends.ui.tags.FriendPinIconTag;
import com.rappytv.betterfriends.utils.GroupHelper;
import net.labymod.api.Laby;
import net.labymod.api.addon.LabyAddon;
import net.labymod.api.client.component.Component;
import net.labymod.api.client.component.TextComponent;
import net.labymod.api.client.component.format.NamedTextColor;
import net.labymod.api.client.component.format.TextColor;
import net.labymod.api.client.component.format.TextDecoration;
import net.labymod.api.client.component.serializer.legacy.LegacyComponentSerializer;
import net.labymod.api.client.entity.player.tag.PositionType;
import net.labymod.api.client.gui.hud.binding.category.HudWidgetCategory;
import net.labymod.api.models.addon.annotation.AddonMain;
Expand All @@ -38,34 +30,35 @@
@AddonMain
public class BetterFriendsAddon extends LabyAddon<BetterFriendsConfig> {

private static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.legacyAmpersand();
private static BetterFriendsAddon instance;
private static BetterFriendsAddon INSTANCE;

@Override
protected void preConfigurationLoad() {
this.registerListener(new ConfigVersionListener());
Laby.references().revisionRegistry().register(new SimpleRevision(
"betterfriends",
new SemanticVersion(1, 0, 1),
"2025-12-10"
));
Laby.references().revisionRegistry().register(new SimpleRevision(
"betterfriends",
new SemanticVersion(1, 1, 0),
"2026-04-30"
));
}

@Override
protected void enable() {
instance = this;
INSTANCE = this;
this.registerSettingCategory();
GroupHelper.registerGroupIds();

this.registerCommand(new BetterFriendsCommand());

this.registerListener(new ChatReceiveListener(this));
this.registerListener(new FriendAddListener(this));
this.registerListener(new FriendRemoveListener(this));
this.registerListener(new FriendRequestReceiveListener(this));
this.registerListener(new FriendRequestRemoveListener(this));
this.registerListener(new FriendServerStateListener(this));
this.registerListener(new FriendStatusUpdateListener(this));
this.registerListener(new FriendListener(this));
this.registerListener(new FriendRequestListener(this));
this.registerListener(new LabyChatReceiveListener(this));
this.registerListener(new TemporaryPinListener(this));

this.labyAPI().interactionMenuRegistry().register(new FriendNoteEditorBullet(this));
this.labyAPI().interactionMenuRegistry().register(new FriendTogglePinBullet(this));
Expand Down Expand Up @@ -105,21 +98,10 @@ protected Class<? extends BetterFriendsConfig> configurationClass() {
}

public static ReferenceStorage references() {
return instance.referenceStorageAccessor();
}

public static TextComponent getPrefix() {
return Component.empty()
.append(Component.text(
"BF",
TextColor.color(instance.configuration().prefixColor().get().get())
).decorate(TextDecoration.BOLD))
.append(Component.space())
.append(Component.text("»", NamedTextColor.DARK_GRAY))
.append(Component.space());
return INSTANCE.referenceStorageAccessor();
}

public LegacyComponentSerializer getSerializer() {
return SERIALIZER;
public static Component getPrefix() {
return INSTANCE.configuration().prefixCustomizationConfig().buildPrefix();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@

import com.rappytv.betterfriends.config.subconfig.FriendNoteTagConfig;
import com.rappytv.betterfriends.config.subconfig.PinIconConfig;
import com.rappytv.betterfriends.ui.activities.config.FriendlistActivity;
import com.rappytv.betterfriends.ui.widgets.FriendlistFriendWidget;
import com.rappytv.betterfriends.config.subconfig.PrefixCustomizationConfig;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import net.labymod.api.addon.AddonConfig;
import net.labymod.api.client.gui.screen.activity.Activity;
import net.labymod.api.client.gui.screen.widget.widgets.activity.settings.ActivitySettingWidget.ActivitySetting;
import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting;
import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget.TextFieldSetting;
import net.labymod.api.client.gui.screen.widget.widgets.input.color.ColorPickerWidget.ColorPickerSetting;
import net.labymod.api.client.gui.screen.widget.widgets.input.dropdown.DropdownWidget.DropdownSetting;
import net.labymod.api.configuration.loader.annotation.Exclude;
import net.labymod.api.configuration.loader.annotation.IntroducedIn;
import net.labymod.api.configuration.loader.annotation.SpriteSlot;
import net.labymod.api.configuration.loader.annotation.SpriteTexture;
import net.labymod.api.configuration.loader.property.ConfigProperty;
import net.labymod.api.configuration.settings.annotation.SettingRequires;
import net.labymod.api.configuration.settings.annotation.SettingSection;
import net.labymod.api.util.Color;
import net.labymod.api.util.MethodOrder;

@SpriteTexture("settings.png")
public class BetterFriendsConfig extends AddonConfig {
Expand All @@ -28,22 +26,22 @@ public class BetterFriendsConfig extends AddonConfig {
@SwitchSetting
private final ConfigProperty<Boolean> enabled = new ConfigProperty<>(true);

@IntroducedIn(namespace = "betterfriends", value = "1.1.0")
@SpriteSlot(x = 1)
@ColorPickerSetting
private final ConfigProperty<Color> prefixColor = new ConfigProperty<>(Color.ofRGB(255, 102, 0));

@MethodOrder(after = "prefixColor")
@ActivitySetting
public Activity advancedFriendlist() {
return new FriendlistActivity<>(FriendlistFriendWidget::new);
}
private final PrefixCustomizationConfig prefixCustomizationConfig = new PrefixCustomizationConfig();

@IntroducedIn(namespace = "betterfriends", value = "1.1.0")
@SpriteSlot(size = 8, x = 4)
private final PinIconConfig pinIconConfig = new PinIconConfig();
@SwitchSetting
private final ConfigProperty<Boolean> temporaryPinsEnabled = new ConfigProperty<>(false);

@SettingSection(value = "indicators", center = true)
@SpriteSlot(x = 3)
private final FriendNoteTagConfig friendNoteTagConfig = new FriendNoteTagConfig();

@SpriteSlot(size = 8, x = 4)
private final PinIconConfig pinIconConfig = new PinIconConfig();

@SpriteSlot(x = 4)
@TextFieldSetting
private final ConfigProperty<String> friendPrefix = new ConfigProperty<>("&aⒻ");
Expand Down Expand Up @@ -93,6 +91,7 @@ public Activity advancedFriendlist() {
// @SpriteSlot(x = 5, y = 1)
// @SwitchSetting
// private final ConfigProperty<Boolean> noteEditorBullet = new ConfigProperty<>(true);

@SpriteSlot(size = 8, x = 4)
@SwitchSetting
private final ConfigProperty<Boolean> togglePinBullet = new ConfigProperty<>(true);
Expand All @@ -102,22 +101,30 @@ public Activity advancedFriendlist() {
@SwitchSetting
private final ConfigProperty<Boolean> restartWhenMuted = new ConfigProperty<>(true);

@Exclude
private final List<UUID> temporaryPins = new ArrayList<>();

@Override
public ConfigProperty<Boolean> enabled() {
return this.enabled;
}

public ConfigProperty<Color> prefixColor() {
return this.prefixColor;
public PrefixCustomizationConfig prefixCustomizationConfig() {
return this.prefixCustomizationConfig;
}

public PinIconConfig pinIconConfig() {
return this.pinIconConfig;
public ConfigProperty<Boolean> temporaryPinsEnabled() {
return this.temporaryPinsEnabled;
}

public FriendNoteTagConfig friendNoteTagConfig() {
return this.friendNoteTagConfig;
}

public PinIconConfig pinIconConfig() {
return this.pinIconConfig;
}

public ConfigProperty<String> friendPrefix() {
return this.friendPrefix;
}
Expand Down Expand Up @@ -161,6 +168,7 @@ public ConfigProperty<Boolean> showInteractionButtons() {
// public ConfigProperty<Boolean> noteEditorBullet() {
// return this.noteEditorBullet;
// }

public ConfigProperty<Boolean> togglePinBullet() {
return this.togglePinBullet;
}
Expand All @@ -169,7 +177,16 @@ public ConfigProperty<Boolean> restartWhenMuted() {
return this.restartWhenMuted;
}

public List<UUID> temporaryPins() {
return this.temporaryPins;
}

public enum FriendRequestReaction {
NONE, ACCEPT, DECLINE
}

@Override
public int getConfigVersion() {
return 2;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.rappytv.betterfriends.config.subconfig;

import com.rappytv.betterfriends.ui.widget.config.PrefixPreviewWidget.PrefixPreviewSetting;
import net.labymod.api.client.component.Component;
import net.labymod.api.client.component.format.NamedTextColor;
import net.labymod.api.client.component.format.TextColor;
import net.labymod.api.client.component.format.TextDecoration;
import net.labymod.api.client.component.serializer.legacy.LegacyComponentSerializer;
import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting;
import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget.TextFieldSetting;
import net.labymod.api.client.gui.screen.widget.widgets.input.color.ColorPickerWidget.ColorPickerSetting;
import net.labymod.api.configuration.loader.Config;
import net.labymod.api.configuration.loader.annotation.IntroducedIn;
import net.labymod.api.configuration.loader.property.ConfigProperty;
import net.labymod.api.configuration.settings.annotation.CustomTranslation;
import net.labymod.api.configuration.settings.annotation.SettingRequires;
import net.labymod.api.configuration.settings.annotation.SettingSection;
import net.labymod.api.util.Color;

public class PrefixCustomizationConfig extends Config {

@IntroducedIn(namespace = "betterfriends", value = "1.1.0")
@PrefixPreviewSetting
private final ConfigProperty<Boolean> preview = new ConfigProperty<>(false);

@IntroducedIn(namespace = "betterfriends", value = "1.1.0")
@SwitchSetting
private final ConfigProperty<Boolean> enableManualPrefix = new ConfigProperty<>(false);

@SettingSection(value = "options", center = true)
@IntroducedIn(namespace = "betterfriends", value = "1.1.0")
@CustomTranslation("betterfriends.settings.prefixCustomizationConfig.prefix")
@TextFieldSetting
private final ConfigProperty<String> manualPrefix = new ConfigProperty<>("&6&lBF&8 » ")
.visibilitySupplier(this.enableManualPrefix::get);

@IntroducedIn(namespace = "betterfriends", value = "1.1.0")
@TextFieldSetting
private final ConfigProperty<String> prefix = new ConfigProperty<>("BF")
.visibilitySupplier(() -> !this.enableManualPrefix.get());

@IntroducedIn(namespace = "betterfriends", value = "1.1.0")
@SettingRequires(value = "prefix", required = "", invert = true)
@ColorPickerSetting
private final ConfigProperty<Color> prefixColor = new ConfigProperty<>(Color.ofRGB(255, 102, 0))
.visibilitySupplier(() -> !this.enableManualPrefix.get());

public ConfigProperty<Boolean> enableManualPrefix() {
return this.enableManualPrefix;
}

public ConfigProperty<String> manualPrefix() {
return this.manualPrefix;
}

public ConfigProperty<String> prefix() {
return this.prefix;
}

public ConfigProperty<Color> prefixColor() {
return this.prefixColor;
}

public Component buildPrefix() {
if (this.enableManualPrefix.get()) {
return LegacyComponentSerializer.legacyAmpersand()
.deserialize(this.manualPrefix.get());
}
Component component = Component.empty();

String prefix = this.prefix.get();
if (!prefix.isEmpty()) {
component
.append(
Component.text(
prefix,
TextColor.color(this.prefixColor.get().get())
).decorate(TextDecoration.BOLD)
)
.append(Component.space())
.append(Component.text("»", NamedTextColor.DARK_GRAY))
.append(Component.space());
}
return component;
}
}
Loading