Skip to content

Port to 1.21.5 and rework no vote data. #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: 1.21
Choose a base branch
from
Open
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
21 changes: 21 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ repositories {
maven { url "https://maven.gegy.dev" }
maven { url "https://maven.quiltmc.org/repository/release" }
maven { url "https://repo.sleeping.town/" }
exclusiveContent {
forRepository { maven { url "https://api.modrinth.com/maven" } }
filter { includeGroup "maven.modrinth" }
}
}

dependencies {
Expand All @@ -28,9 +32,26 @@ dependencies {

modImplementation libs.spruceui
modRuntimeOnly libs.modmenu
modRuntimeOnly libs.sresld
include libs.spruceui
}

loom {
mods {
register(modId) {
sourceSet(sourceSets["main"])
sourceSet(sourceSets["test"])
}
}
}

sourceSets {
named("main") {
runtimeClasspath += sourceSets["test"].runtimeClasspath
runtimeClasspath += sourceSets["test"].output
}
}

processResources {
final Map<String, String> meta = [
version : version,
Expand Down
12 changes: 6 additions & 6 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ modId=ballotbox
modName=Ballotbox
modDescription=In-game category voting!
authors=ModFest
contributors=Prospector, Sisby folk, acikek, afamiliarquiet
contributors=Prospector, Sisby folk, acikek, afamiliarquiet, MerchantCalico, Sylv <[email protected]>
license=MIT
# Mod Version
baseVersion=0.6.4
baseVersion=0.6.5
# Branch Metadata
branch=1.21
tagBranch=1.21
compatibleVersions=1.21, 1.21.1
compatibleLoaders=fabric, quilt, neoforge
branch=1.21.5
tagBranch=1.21.5
compatibleVersions=1.21.5
compatibleLoaders=fabric, quilt
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
18 changes: 11 additions & 7 deletions libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
[versions]
loom = "1.7.+"
loom = "1.10.+"
minotaur = "2.+"

kaleidoConfig = "0.3.1+1.3.1"

mc = "1.21.1"
fl = "0.16.7"
yarn = "1.21.1+build.3"
fapi = "0.104.0+1.21.1"
mc = "1.21.5"
fl = "0.16.14"
yarn = "1.21.5+build.1"
fapi = "0.126.0+1.21.5"

spruceui = "5.1.0+1.21"
modmenu = "11.0.3"
spruceui = "7.0.2+1.21.5"
modmenu = "14.0.0-rc.2"

sresld = "1.0.0+1.21.1"

[plugins]
loom = { id = "fabric-loom", version.ref = "loom" }
Expand All @@ -26,3 +28,5 @@ fapi = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "

spruceui = { group = "dev.lambdaurora", name = "spruceui", version.ref = "spruceui" }
modmenu = { group = "com.terraformersmc", name = "modmenu", version.ref = "modmenu" }

sresld = { group = "maven.modrinth", name = "simple-resource-loader", version.ref = "sresld" }
7 changes: 3 additions & 4 deletions src/main/java/net/modfest/ballotbox/BallotBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public class BallotBox implements ModInitializer {
public static final String ID = "ballotbox";
public static final Logger LOGGER = LoggerFactory.getLogger(ID);
public static final BallotBoxConfig CONFIG = BallotBoxConfig.createToml(FabricLoader.getInstance().getConfigDir(), "", ID, BallotBoxConfig.class);
public static final String STATE_KEY = "ballotbox_ballots";
public static BallotState STATE = null;
public static Instant closingTime = null;

Expand Down Expand Up @@ -66,7 +65,7 @@ public void onInitialize() {
CommandRegistrationCallback.EVENT.register(BallotBoxCommands::register);
ServerWorldEvents.LOAD.register(((server, world) -> {
if (world.getRegistryKey() == World.OVERWORLD) {
STATE = world.getPersistentStateManager().getOrCreate(BallotState.getPersistentStateType(), STATE_KEY);
STATE = world.getPersistentStateManager().getOrCreate(BallotState.TYPE);
}
}));
ServerLifecycleEvents.SERVER_STARTED.register((server -> {
Expand All @@ -82,8 +81,8 @@ public void onInitialize() {
VotingSelections selections = STATE.selections().get(handler.getPlayer().getUuid());
int totalVotes = BallotBoxPlatformClient.categories.values().stream().mapToInt(VotingCategory::limit).sum();
int remainingVotes = totalVotes - (selections == null ? 0 : selections.votes().size());
sender.sendPacket(new S2CGameJoin(CONFIG.closingTime.value(), remainingVotes));
sender.sendPacket(new S2CGameJoin(CONFIG.closingTime.value(), !BallotBoxPlatformClient.categories.isEmpty() && !BallotBoxPlatformClient.options.isEmpty(), remainingVotes));
}));
LOGGER.info("[BallotBox] Initialized!");
}
}
}
4 changes: 4 additions & 0 deletions src/main/java/net/modfest/ballotbox/BallotBoxCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ private static int vote(ServerPlayerEntity player, Consumer<Text> feedback) {
feedback.accept(Text.literal("[BallotBox] ").formatted(Formatting.GREEN).append(Text.literal("Voting is unavailable! Voting closed %s.".formatted(BallotBox.relativeTime(BallotBox.closingTime))).formatted(Formatting.RED)));
return 0;
}
if (BallotBoxPlatformClient.categories.isEmpty() || BallotBoxPlatformClient.options.isEmpty()) {
feedback.accept(Text.literal("[BallotBox] ").formatted(Formatting.GREEN).append(Text.literal("Voting is unavailable! Nothing to vote for.").formatted(Formatting.RED)));
return 0;
}
ServerPlayNetworking.send(player, new OpenVoteScreen());
BallotBoxNetworking.sendVoteScreenData(player);
return 1;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/net/modfest/ballotbox/BallotBoxConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@

public class BallotBoxConfig extends ReflectiveConfig {
@Comment("Whether to add a voting button")
public final ButtonSettings voting_button = new ButtonSettings(List.of("menu.feedback", "menu.sendFeedback"), false, true);
public final ButtonSettings voting_button = new ButtonSettings(List.of("menu.playerReporting"), false, true);
@Comment("Whether to replace the bug report button with another link")
public final ButtonSettings custom_link_button = new ButtonSettings(List.of("menu.reportBugs"), false, true);
@Comment("The text to use to replace the bug report button")
public final TrackedValue<String> custom_link_text = value("ModFest Discord");
@Comment("The link to use to replace the bug report button")
public final TrackedValue<String> custom_link_url = value("https://discord.gg/gn543Ee");
@Comment("Whether to add a credits button")
public final ButtonSettings credits_button = new ButtonSettings(List.of("menu.online", "menu.playerReporting"), true, true);
public final ButtonSettings credits_button = new ButtonSettings(List.of("menu.online"), true, false);
@Comment("The text to use for replacement credits but tons button")
public final TrackedValue<String> credits_text = value("Modpack Credits");
@Comment("The number of top results to show when displaying voting results")
public final TrackedValue<Integer> awardLimit = value(8);
@Comment("The closing date, as an ISO local date time - or an empty string for none")
public final TrackedValue<String> closingTime = value("2024-12-16T12:00:00");
public final TrackedValue<String> closingTime = value("");
@Comment("Settings for the reminder on the pause screen")
public final ReminderSettings reminder_settings = new ReminderSettings();

Expand Down
22 changes: 20 additions & 2 deletions src/main/java/net/modfest/ballotbox/BallotBoxPlatformClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.google.gson.JsonArray;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.JsonOps;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.modfest.ballotbox.data.VotingCategory;
Expand All @@ -14,6 +15,7 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.Optional;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
Expand All @@ -29,9 +31,25 @@ public class BallotBoxPlatformClient {
public static void init(ResourceManager resourceManager) {
try {
categories.clear();
Optional<Resource> categoriesData = resourceManager.getResource(CATEGORIES_DATA);
if (categoriesData.isPresent()) {
GSON.fromJson(new BufferedReader(new InputStreamReader(resourceManager.getResourceOrThrow(CATEGORIES_DATA).getInputStream())), JsonArray.class).asList().stream().map(e -> VotingCategory.CODEC.decode(JsonOps.INSTANCE, e).mapOrElse(Pair::getFirst, a -> null)).filter(Objects::nonNull).forEach(category -> categories.put(category.id(), category));
}
options.clear();
GSON.fromJson(new BufferedReader(new InputStreamReader(resourceManager.getResourceOrThrow(CATEGORIES_DATA).getInputStream())), JsonArray.class).asList().stream().map(e -> VotingCategory.CODEC.decode(JsonOps.INSTANCE, e).mapOrElse(Pair::getFirst, a -> null)).filter(Objects::nonNull).forEach(category -> categories.put(category.id(), category));
GSON.fromJson(new BufferedReader(new InputStreamReader(resourceManager.getResourceOrThrow(OPTIONS_DATA).getInputStream())), JsonArray.class).asList().stream().map(e -> VotingOption.CODEC.decode(JsonOps.INSTANCE, e).mapOrElse(Pair::getFirst, a -> null)).filter(Objects::nonNull).forEach(option -> options.put(option.id(), option));
Optional<Resource> optionsData = resourceManager.getResource(OPTIONS_DATA);
if (optionsData.isPresent()) {
GSON.fromJson(
new BufferedReader(new InputStreamReader(resourceManager.getResourceOrThrow(
OPTIONS_DATA).getInputStream())),
JsonArray.class
).asList().stream().map(e -> VotingOption.CODEC.decode(
JsonOps.INSTANCE,
e
).mapOrElse(
Pair::getFirst,
a -> null
)).filter(Objects::nonNull).forEach(option -> options.put(option.id(), option));
}
} catch (Exception e) {
BallotBox.LOGGER.info("[BallotBox] Failed to load ballotbox data!", e);
}
Expand Down
24 changes: 7 additions & 17 deletions src/main/java/net/modfest/ballotbox/BallotState.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtOps;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Uuids;
import net.minecraft.world.PersistentState;
import net.minecraft.world.PersistentStateType;
import net.modfest.ballotbox.data.VotingSelections;

import java.util.Map;
Expand All @@ -17,27 +15,19 @@ public class BallotState extends PersistentState {
public static final Codec<BallotState> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.unboundedMap(Uuids.CODEC, VotingSelections.CODEC).xmap(s -> (Map<UUID, VotingSelections>) new ConcurrentHashMap<>(s), ConcurrentHashMap::new).fieldOf("selections").forGetter(BallotState::selections)
).apply(instance, BallotState::new));

public static PersistentState.Type<BallotState> getPersistentStateType() {
return new PersistentState.Type<>(() -> new BallotState(new ConcurrentHashMap<>()), BallotState::fromNbt, null);
}
public static final PersistentStateType<BallotState> TYPE = new PersistentStateType<>(
"ballotbox_ballots",
() -> new BallotState(new ConcurrentHashMap<>()),
BallotState.CODEC,
null
);

private final Map<UUID, VotingSelections> selections;

private BallotState(Map<UUID, VotingSelections> selections) {
this.selections = selections;
}

private static BallotState fromNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
return BallotState.CODEC.decode(NbtOps.INSTANCE, nbt.getCompound("data")).getOrThrow().getFirst();
}

@Override
public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
nbt.put("data", BallotState.CODEC.encodeStart(NbtOps.INSTANCE, this).getOrThrow());
return nbt;
}

public Map<UUID, VotingSelections> selections() {
return selections;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmLinkScreen;
import net.minecraft.client.gui.screen.CreditsScreen;
import net.minecraft.client.gui.screen.GameMenuScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.sound.MusicInstance;
import net.minecraft.sound.MusicType;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent;
Expand Down Expand Up @@ -38,7 +38,7 @@ public static List<Pair<BallotBoxConfig.ButtonSettings, Function<Screen, ButtonW
list.add(new Pair<>(BallotBox.CONFIG.credits_button, (screen) -> ButtonWidget.builder(Text.of(BallotBox.CONFIG.credits_text.value()), b -> {
MinecraftClient.getInstance().setScreen(new CreditsScreen(false, () -> MinecraftClient.getInstance().setScreen(screen)));
MinecraftClient.getInstance().getMusicTracker().stop();
MinecraftClient.getInstance().getMusicTracker().play(MusicType.CREDITS);
MinecraftClient.getInstance().getMusicTracker().play(new MusicInstance(MusicType.CREDITS));
})));

return list;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
public class BallotBoxClient implements ClientModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger("%s-client".formatted(BallotBox.ID));
public static Instant closingTime = null;
public static boolean hasVotingOptions = true;
public static int remainingVotes = 0;

public static boolean isEnabled(MinecraftClient client) {
Expand All @@ -33,6 +34,7 @@ public void onInitializeClient() {
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> {
remainingVotes = 0;
closingTime = null;
hasVotingOptions = true;
});
BallotBoxClientNetworking.init();
BallotBoxKeybinds.init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static void init() {

private static void handleGameJoin(S2CGameJoin packet, ClientPlayNetworking.Context context) {
BallotBoxClient.closingTime = BallotBox.parseClosingTime(packet.closingTime());
BallotBoxClient.hasVotingOptions = packet.hasVotingOptions();
BallotBoxClient.remainingVotes = packet.remainingVotes();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ private static void tick(MinecraftClient client) {
while (OPEN_VOTING_SCREEN.wasPressed() && BallotBoxClient.isEnabled(client)) {
if (!BallotBoxClient.isOpen()) {
client.inGameHud.setOverlayMessage(Text.literal("[BallotBox] ").formatted(Formatting.GREEN).append(Text.literal("Voting is unavailable! Voting closed %s.".formatted(BallotBox.relativeTime(BallotBoxClient.closingTime))).formatted(Formatting.RED)), false);
} else if (client.currentScreen == null) {
} else if (!BallotBoxClient.hasVotingOptions) {
client.inGameHud.setOverlayMessage(Text.literal("[BallotBox] ").formatted(Formatting.GREEN).append(Text.literal("Voting is unavailable! Nothing to vote for.").formatted(Formatting.RED)), false);
} else if (client.currentScreen == null) {
client.setScreen(new VotingScreen());
ClientPlayNetworking.send(new OpenVoteScreen());
}
Expand Down
20 changes: 8 additions & 12 deletions src/main/java/net/modfest/ballotbox/client/VotingScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.lambdaurora.spruceui.Position;
import dev.lambdaurora.spruceui.background.EmptyBackground;
import dev.lambdaurora.spruceui.screen.SpruceScreen;
Expand All @@ -16,6 +15,7 @@
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.texture.Sprite;
import net.minecraft.text.Text;
Expand Down Expand Up @@ -50,6 +50,8 @@ public class VotingScreen extends SpruceScreen {
);

public static final Identifier LOCKUP_TEXTURE = Identifier.of(BallotBox.ID, "emblem");
public static final int LOCKUP_TEXTURE_WIDTH = 1101;
public static final int LOCKUP_TEXTURE_HEIGHT = 256;

protected final Multimap<String, String> previousSelections = HashMultimap.create();
protected final Multimap<String, String> selections = HashMultimap.create();
Expand Down Expand Up @@ -112,12 +114,10 @@ public void renderBackground(DrawContext context, int mouseX, int mouseY, float

public void renderLockup(DrawContext context) {
if (lockupSprite == null) return;
RenderSystem.enableBlend();
int texHeight = lockupSprite.getContents().getHeight();
int texWidth = lockupSprite.getContents().getWidth();
int drawHeight = sidePanelWidth * texHeight / texWidth;
context.drawGuiTexture(LOCKUP_TEXTURE, 0, (sidePanelVerticalPadding - drawHeight) / 2, sidePanelWidth, drawHeight);
RenderSystem.disableBlend();
context.drawTexture(RenderLayer::getGuiTextured, LOCKUP_TEXTURE, 0, (sidePanelVerticalPadding - drawHeight) / 2, sidePanelWidth, drawHeight, 0, 0, LOCKUP_TEXTURE_WIDTH, LOCKUP_TEXTURE_HEIGHT, LOCKUP_TEXTURE_WIDTH, LOCKUP_TEXTURE_HEIGHT);
}

@Override
Expand Down Expand Up @@ -184,6 +184,7 @@ public VotingOptionButtonWidget(Position position, int width, int height, Voting
this.parent = parent;
selected = selections.containsEntry(category.id(), option.id());
this.prohibited = prohibited;
this.active = prohibited;
if (!modIconCache.containsKey(option.id())) {
modIconCache.put(option.id(), Identifier.of(BallotBox.ID, option.id() + "_icon"));
Optional<ModContainer> mod = FabricLoader.getInstance().getModContainer(option.mod_id().isPresent() ? option.mod_id().get() : option.id())
Expand All @@ -198,14 +199,9 @@ public VotingOptionButtonWidget(Position position, int width, int height, Voting
setTooltip(url == null ? Text.literal(option.description()).formatted(Formatting.GRAY) : Text.literal(option.description()).formatted(Formatting.GRAY).append(Text.literal("\n")).append(Text.literal("Right-Click").formatted(Formatting.GOLD)).append(Text.literal(" to open the mod page.").formatted(Formatting.WHITE)));
}

@Override
public boolean isActive() {
return !prohibited && super.isActive();
}

@Override
public Optional<Text> getTooltip() {
return isActive() ? super.getTooltip() : prohibited ? Optional.of(Text.literal("Prohibited by another category!").formatted(Formatting.GRAY)) : Optional.of(Text.literal("You've reached the category vote limit!").formatted(Formatting.GRAY));
return active ? super.getTooltip() : prohibited ? Optional.of(Text.literal("Prohibited by another category!").formatted(Formatting.GRAY)) : Optional.of(Text.literal("You've reached the category vote limit!").formatted(Formatting.GRAY));
}

@Override
Expand All @@ -232,7 +228,7 @@ protected void renderButton(DrawContext context, int mouseX, int mouseY, float d
int bottom = getY() + getHeight();
int textY = (getY() * 2 + getHeight() - 9) / 2 + 1;
if (texture != null) {
context.drawTexture(texture, left, getY() + 2, 16, 16, 0, 0, 16, 16, 16, 16);
context.drawTexture(RenderLayer::getGuiTextured, texture, left, getY() + 2, 16, 16, 16, 16, 16, 16, 16, 16);
}
if (textWidth <= getWidth()) {
context.drawCenteredTextWithShadow(client.textRenderer, getMessage(), left + getWidth() / 2, textY, 0xFFFFFFFF);
Expand All @@ -252,7 +248,7 @@ protected void renderButton(DrawContext context, int mouseX, int mouseY, float d
protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
super.renderWidget(context, mouseX, mouseY, delta);
if (selected) {
context.drawTexture(CHECKMARK_TEXTURE, getX() + getWidth() - 11, getY() + getHeight() - 9, 0, 0, 7, 6, 7, 6);
context.drawTexture(RenderLayer::getGuiTextured, CHECKMARK_TEXTURE, getX() + getWidth() - 11, getY() + getHeight() - 9, 0, 0, 7, 6, 7, 6);
}
}

Expand Down
Loading