Skip to content

Commit

Permalink
port work
Browse files Browse the repository at this point in the history
  • Loading branch information
ix0rai committed May 8, 2024
1 parent b751fec commit d73dfc3
Show file tree
Hide file tree
Showing 15 changed files with 385 additions and 287 deletions.
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ org.gradle.jvmargs=-Xmx1G
# minecraft, mappings and loader dependencies
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.20.6
quilt_mappings=3
loader_version=0.15.7
quilt_mappings=6
loader_version=0.15.11

# mod properties
mod_version=1.2.0+mc1.20.6
Expand All @@ -15,4 +15,4 @@ archives_base_name=rainglow
# other dependencies
java_version=21
mod_menu_version=9.0.0
fabric_api_version=0.97.8+1.20.6
fabric_api_version=0.98.0+1.20.6
6 changes: 5 additions & 1 deletion src/main/java/io/ix0rai/rainglow/Rainglow.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.ix0rai.rainglow.config.RainglowConfig;
import io.ix0rai.rainglow.data.*;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.entity.data.DataTracker;
Expand Down Expand Up @@ -42,10 +43,13 @@ public class Rainglow implements ModInitializer {
public void onInitialize() {
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener((RainglowResourceReloader) () -> id("server_mode_data"));

PayloadTypeRegistry.playS2C().register(RainglowNetworking.ConfigSyncPayload.PACKET_ID, RainglowNetworking.ConfigSyncPayload.PACKET_CODEC);
PayloadTypeRegistry.playS2C().register(RainglowNetworking.ModeSyncPayload.PACKET_ID, RainglowNetworking.ModeSyncPayload.PACKET_CODEC);

ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
if (CONFIG.isServerSyncEnabled()) {
// send modes to client
RainglowNetworking.sendModeData(handler.player);
RainglowNetworking.syncModes(handler.player);

// send config to client
RainglowNetworking.syncConfig(handler.player);
Expand Down
79 changes: 39 additions & 40 deletions src/main/java/io/ix0rai/rainglow/client/RainglowClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,69 @@
import io.ix0rai.rainglow.Rainglow;
import io.ix0rai.rainglow.data.RainglowMode;
import io.ix0rai.rainglow.data.RainglowResourceReloader;
import io.ix0rai.rainglow.data.RainglowColour;
import io.ix0rai.rainglow.data.RainglowNetworking;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.client.MinecraftClient;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Environment(EnvType.CLIENT)
public class RainglowClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
ClientPlayNetworking.registerGlobalReceiver(RainglowNetworking.CONFIG_SYNC_ID, (client, handler, buf, responseSender) -> {
String mode = buf.readString();

List<String> colourIds = buf.readList(PacketByteBuf::readString);
List<RainglowColour> colours = colourIds.stream().map(RainglowColour::get).toList();

client.execute(() -> {
// custom must be set before mode so that if the server sends a custom mode it is set correctly
// otherwise the client's custom would be used
Rainglow.CONFIG.setCustom(colours);
Rainglow.CONFIG.setMode(RainglowMode.byId(mode));
ClientPlayNetworking.registerGlobalReceiver(RainglowNetworking.ConfigSyncPayload.PACKET_ID, (payload, context) -> {
try (MinecraftClient client = context.client()) {
client.execute(() -> {
// custom must be set before mode so that if the server sends a custom mode it is set correctly
// otherwise the client's custom would be used
Rainglow.CONFIG.setCustom(payload.customMode());
Rainglow.CONFIG.setMode(RainglowMode.byId(payload.currentMode()));

for (var entry : payload.enabledMobs().entrySet()) {
Rainglow.CONFIG.setEntityEnabled(entry.getKey(), entry.getValue());
}

// lock the config from reloading on resource reload
Rainglow.CONFIG.setEditLocked(true);
// lock the config from reloading on resource reload
Rainglow.CONFIG.setEditLocked(true);

// log
Rainglow.LOGGER.info("received config from server: set mode to " + mode + " and custom colours to " + colourIds);
});
// log
Rainglow.LOGGER.info("received config from server: set mode to " + payload.currentMode() + " and custom colours to " + payload.customMode());
});
}
});

ClientPlayNetworking.registerGlobalReceiver(RainglowNetworking.MODE_SYNC_ID, (client, handler, buf, responseSender) -> {
Collection<RainglowMode> modes = RainglowNetworking.readModeData(buf);

client.execute(() -> {
List<String> newModeIds = new ArrayList<>();

// add modes that do not exist on the client to the map
for (RainglowMode mode : modes) {
if (!mode.existsLocally()) {
newModeIds.add(mode.getId());
RainglowMode.addMode(mode);
ClientPlayNetworking.registerGlobalReceiver(RainglowNetworking.ModeSyncPayload.PACKET_ID, (payload, context) -> {
try (MinecraftClient client = context.client()) {
client.execute(() -> {
List<String> newModeIds = new ArrayList<>();

// add modes that do not exist on the client to the map
for (RainglowMode mode : payload.modes()) {
if (!mode.existsLocally()) {
newModeIds.add(mode.getId());
RainglowMode.addMode(mode);
}
}
}

// now that we have modes, we can load the config
if (Rainglow.CONFIG.isUninitialised()) {
Rainglow.CONFIG.reloadFromFile();
}
// now that we have modes, we can load the config
if (Rainglow.CONFIG.isUninitialised()) {
Rainglow.CONFIG.reloadFromFile();
}

// log
if (!newModeIds.isEmpty()) {
Rainglow.LOGGER.info("received new modes from server: " + newModeIds);
}
});
// log
if (!newModeIds.isEmpty()) {
Rainglow.LOGGER.info("received new modes from server: " + newModeIds);
}
});
}
});

ClientPlayConnectionEvents.DISCONNECT.register((handler, client) ->
Expand Down
158 changes: 82 additions & 76 deletions src/main/java/io/ix0rai/rainglow/config/CustomModeScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,86 +5,92 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.SimpleOptionsScreen;
import net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.Option;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class CustomModeScreen extends SimpleOptionsScreen {
private final SpruceOption clearOption;
private final SpruceOption saveOption;
private final SpruceBooleanOption[] colourToggles = new SpruceBooleanOption[RainglowColour.values().length];
private final boolean[] toggleStates = new boolean[RainglowColour.values().length];

public CustomModeScreen(@Nullable Screen parent) {
super(parent, MinecraftClient.getInstance().options, Rainglow.translatableText("config.title"),

);

// todo subclass option to allow saving via a save button
// ephemeral value, not saved until a specific method is called (will happen on save pressed)

// create toggles for each colour
for (int i = 0; i < RainglowColour.values().length; i ++) {
final RainglowColour colour = RainglowColour.values()[i];
final int index = i;

toggleStates[index] = Rainglow.CONFIG.getCustom().contains(colour);

colourToggles[index] = new SpruceBooleanOption(Rainglow.translatableTextKey("colour." + colour.getId()),
() -> toggleStates[index],
enable -> toggleStates[index] = enable,
null,
true
);
}

// toggles all colours to false
this.clearOption = SpruceSimpleActionOption.of(Rainglow.translatableTextKey("config.clear"),
btn -> {
for (int i = 0; i < RainglowColour.values().length; i ++) {
toggleStates[i] = false;
}

MinecraftClient client = MinecraftClient.getInstance();
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
});

// writes all the toggled colours to the config and reloads custom mode
this.saveOption = SpruceSimpleActionOption.of(Rainglow.translatableTextKey("config.save"),
buttonWidget -> {
List<RainglowColour> newCustom = new ArrayList<>();

for (int i = 0; i < RainglowColour.values().length; i ++) {
if (toggleStates[i]) {
newCustom.add(RainglowColour.values()[i]);
}
}

Rainglow.CONFIG.setCustom(newCustom);
Rainglow.CONFIG.saveCustom();
this.closeScreen();
}
);
}

@Override
protected void init() {
super.init();

// create a list of toggles for each colour
SpruceOptionListWidget options = new SpruceOptionListWidget(Position.of(0, 22), this.width, this.height - (35 + 22));
for (int i = 0; i < RainglowColour.values().length; i += 2) {
SpruceOption secondToggle = null;
if (i + 1 < RainglowColour.values().length) {
secondToggle = colourToggles[i + 1];
}
options.addOptionEntry(colourToggles[i], secondToggle);
}
this.addDrawableSelectableElement(options);

// save and clear buttons
this.addDrawableSelectableElement(this.clearOption.createWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150));
this.addDrawableSelectableElement(this.saveOption.createWidget(Position.of(this, this.width / 2 - 155 + 160, this.height - 29), 150));
}
public CustomModeScreen(Screen parent, GameOptions gameOptions, Text title, Option<?>[] options) {
super(parent, gameOptions, title, options);
}
// private final SpruceOption clearOption;
// private final SpruceOption saveOption;
// private final SpruceBooleanOption[] colourToggles = new SpruceBooleanOption[RainglowColour.values().length];
// private final boolean[] toggleStates = new boolean[RainglowColour.values().length];
//
// public CustomModeScreen(@Nullable Screen parent) {
// super(parent, MinecraftClient.getInstance().options, Rainglow.translatableText("config.title"),
//
// );
//
// // todo subclass option to allow saving via a save button
// // ephemeral value, not saved until a specific method is called (will happen on save pressed)
//
// // create toggles for each colour
// for (int i = 0; i < RainglowColour.values().length; i ++) {
// final RainglowColour colour = RainglowColour.values()[i];
// final int index = i;
//
// toggleStates[index] = Rainglow.CONFIG.getCustom().contains(colour);
//
// colourToggles[index] = new SpruceBooleanOption(Rainglow.translatableTextKey("colour." + colour.getId()),
// () -> toggleStates[index],
// enable -> toggleStates[index] = enable,
// null,
// true
// );
// }
//
// // toggles all colours to false
// this.clearOption = SpruceSimpleActionOption.of(Rainglow.translatableTextKey("config.clear"),
// btn -> {
// for (int i = 0; i < RainglowColour.values().length; i ++) {
// toggleStates[i] = false;
// }
//
// MinecraftClient client = MinecraftClient.getInstance();
// this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
// });
//
// // writes all the toggled colours to the config and reloads custom mode
// this.saveOption = SpruceSimpleActionOption.of(Rainglow.translatableTextKey("config.save"),
// buttonWidget -> {
// List<RainglowColour> newCustom = new ArrayList<>();
//
// for (int i = 0; i < RainglowColour.values().length; i ++) {
// if (toggleStates[i]) {
// newCustom.add(RainglowColour.values()[i]);
// }
// }
//
// Rainglow.CONFIG.setCustom(newCustom);
// Rainglow.CONFIG.saveCustom();
// this.closeScreen();
// }
// );
// }
//
// @Override
// protected void init() {
// super.init();
//
// // create a list of toggles for each colour
// SpruceOptionListWidget options = new SpruceOptionListWidget(Position.of(0, 22), this.width, this.height - (35 + 22));
// for (int i = 0; i < RainglowColour.values().length; i += 2) {
// SpruceOption secondToggle = null;
// if (i + 1 < RainglowColour.values().length) {
// secondToggle = colourToggles[i + 1];
// }
// options.addOptionEntry(colourToggles[i], secondToggle);
// }
// this.addDrawableSelectableElement(options);
//
// // save and clear buttons
// this.addDrawableSelectableElement(this.clearOption.createWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150));
// this.addDrawableSelectableElement(this.saveOption.createWidget(Position.of(this, this.width / 2 - 155 + 160, this.height - 29), 150));
// }
}
45 changes: 44 additions & 1 deletion src/main/java/io/ix0rai/rainglow/config/DeferredSaveOption.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,50 @@
package io.ix0rai.rainglow.config;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.Option;
import net.minecraft.text.Text;

import java.util.Objects;
import java.util.function.Consumer;

public class DeferredSaveOption<T> extends Option<T> {
private final T deferredValue;
private T deferredValue;

public DeferredSaveOption(String key, TooltipSupplier<T> tooltipSupplier, OptionTextGetter<T> textGetter, Option.ValueSet<T> values, T defaultValue, Consumer<T> updateCallback) {
super(key, tooltipSupplier, textGetter, values, defaultValue, updateCallback);
this.deferredValue = this.value;
}

@Override
public void set(T value) {
T object = (T) this.getValues().validate(value).orElseGet(() -> {
System.out.println("Illegal option value " + value + " for " + this.text);
return this.defaultValue;
});
if (!MinecraftClient.getInstance().isRunning()) {
this.deferredValue = object;
} else {
if (!Objects.equals(this.value, object)) {
this.deferredValue = object;
this.updateCallback.accept(this.deferredValue);
}
}
}

public static DeferredSaveOption<Boolean> createBoolean(boolean defaultValue, String key) {
return new DeferredSaveOption<>(
"rainglow.config." + key,
Option.constantTooltip(Text.translatable("rainglow.config.tooltip." + key)),
(text, value) -> GameOptions.getGenericValueText(text, Text.translatable("ramel.config.value." + key, value)),
Option.BOOLEAN_VALUES,
defaultValue,
value -> {
}
);
}

public void save() {
this.value = this.deferredValue;
}
}
5 changes: 5 additions & 0 deletions src/main/java/io/ix0rai/rainglow/config/RainglowConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;

import javax.swing.text.html.parser.Entity;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
Expand Down Expand Up @@ -150,6 +151,10 @@ public void setEntityEnabled(RainglowEntity entity, boolean enabled) {
this.entityToggles.put(entity, enabled);
}

public Map<RainglowEntity, Boolean> getEntityToggles() {
return this.entityToggles;
}

public void save(boolean log) {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER || !this.isEditLocked(MinecraftClient.getInstance())) {
ConfigIo.writeString(MODE_KEY, this.mode.getId());
Expand Down
Loading

0 comments on commit d73dfc3

Please sign in to comment.