Fixed race allow list not functioning correctly, fix the world's default race setting, and change the default race to auto-assign when it's set

This commit is contained in:
Sollace 2022-10-17 17:28:13 +02:00
parent 5e3711c042
commit f2bb7adc74
9 changed files with 79 additions and 60 deletions

View file

@ -1,17 +1,13 @@
package com.minelittlepony.unicopia; package com.minelittlepony.unicopia;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import com.google.gson.GsonBuilder;
import com.minelittlepony.common.util.GamePaths; import com.minelittlepony.common.util.GamePaths;
import com.minelittlepony.common.util.settings.*; import com.minelittlepony.common.util.settings.*;
public class Config extends com.minelittlepony.common.util.settings.Config { public class Config extends com.minelittlepony.common.util.settings.Config {
private static final Adapter ADAPTER = new HeirarchicalJsonConfigAdapter(new GsonBuilder() public final Setting<Set<String>> speciesWhiteList = value("server", "speciesWhiteList", (Set<String>)new HashSet<String>())
.registerTypeAdapter(Race.class, RegistryTypeAdapter.of(Race.REGISTRY))
);
public final Setting<Set<Race>> speciesWhiteList = value("server", "speciesWhiteList", Set.<Race>of())
.addComment("A whitelist of races permitted on the server") .addComment("A whitelist of races permitted on the server")
.addComment("Races added to this list can be used by anyone,") .addComment("Races added to this list can be used by anyone,")
.addComment("whilst any ones left off are not permitted") .addComment("whilst any ones left off are not permitted")
@ -35,6 +31,6 @@ public class Config extends com.minelittlepony.common.util.settings.Config {
.addComment("Turn this ON if you're using another mod that does something similar of if you encounter copatibility issues with other mods."); .addComment("Turn this ON if you're using another mod that does something similar of if you encounter copatibility issues with other mods.");
public Config() { public Config() {
super(ADAPTER, GamePaths.getConfigDirectory().resolve("unicopia.json")); super(HEIRARCHICAL_JSON_ADAPTER, GamePaths.getConfigDirectory().resolve("unicopia.json"));
} }
} }

View file

@ -1,8 +1,10 @@
package com.minelittlepony.unicopia; package com.minelittlepony.unicopia;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.include.com.google.common.base.Objects;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Affine;
@ -102,6 +104,11 @@ public final class Race implements Affine {
return canFly() && this != CHANGELING && this != BAT; return canFly() && this != CHANGELING && this != BAT;
} }
public Identifier getId() {
Identifier id = REGISTRY.getId(this);
return id;
}
public Text getDisplayName() { public Text getDisplayName() {
return Text.translatable(getTranslationKey()); return Text.translatable(getTranslationKey());
} }
@ -111,12 +118,12 @@ public final class Race implements Affine {
} }
public String getTranslationKey() { public String getTranslationKey() {
Identifier id = REGISTRY.getId(this); Identifier id = getId();
return String.format("%s.race.%s", id.getNamespace(), id.getPath().toLowerCase()); return String.format("%s.race.%s", id.getNamespace(), id.getPath().toLowerCase());
} }
public Identifier getIcon() { public Identifier getIcon() {
Identifier id = REGISTRY.getId(this); Identifier id = getId();
return new Identifier(id.getNamespace(), "textures/gui/race/" + id.getPath() + ".png"); return new Identifier(id.getNamespace(), "textures/gui/race/" + id.getPath() + ".png");
} }
@ -125,11 +132,11 @@ public final class Race implements Affine {
return false; return false;
} }
Set<Race> whitelist = Unicopia.getConfig().speciesWhiteList.get(); Set<String> whitelist = Unicopia.getConfig().speciesWhiteList.get();
return isDefault() return isDefault()
|| whitelist.isEmpty() || whitelist.isEmpty()
|| whitelist.contains(this); || whitelist.contains(getId().toString());
} }
public Race validate(PlayerEntity sender) { public Race validate(PlayerEntity sender) {
@ -144,8 +151,23 @@ public final class Race implements Affine {
return this; return this;
} }
@Override
public int hashCode() {
return getId().hashCode();
}
@Override
public boolean equals(Object o) {
return o instanceof Race race && Objects.equal(race.getId(), getId());
}
@Override
public String toString() {
return "Race{ " + getId().toString() + " }";
}
public boolean equals(String s) { public boolean equals(String s) {
return REGISTRY.getId(this).toString().equalsIgnoreCase(s) return getId().toString().equalsIgnoreCase(s)
|| getTranslationKey().equalsIgnoreCase(s); || getTranslationKey().equalsIgnoreCase(s);
} }
@ -171,6 +193,10 @@ public final class Race implements Affine {
Identifier id = context.getArgument(name, RegistryKey.class).getValue(); Identifier id = context.getArgument(name, RegistryKey.class).getValue();
return REGISTRY.getOrEmpty(id).orElseThrow(() -> UNKNOWN_RACE_EXCEPTION.create(id)); return REGISTRY.getOrEmpty(id).orElseThrow(() -> UNKNOWN_RACE_EXCEPTION.create(id));
} }
public static Set<Race> allPermitted(PlayerEntity player) {
return REGISTRY.stream().filter(r -> r.isPermitted(player)).collect(Collectors.toSet());
}
} }

View file

@ -22,7 +22,9 @@ public class WorldTribeManager extends PersistentState {
} }
public Race setDefaultRace(Race race) { public Race setDefaultRace(Race race) {
return defaultRace = race; defaultRace = race;
markDirty();
return defaultRace;
} }
@Override @Override

View file

@ -84,13 +84,13 @@ public class LanSettingsScreen extends GameGui {
}) })
.getStyle().setText("unicopia.options.cheats"); .getStyle().setText("unicopia.options.cheats");
Set<Race> whitelist = config.speciesWhiteList.get(); Set<String> whitelist = config.speciesWhiteList.get();
boolean whitelistEnabled = (forceShowWhitelist || !whitelist.isEmpty()) && !forceHideWhitelist; boolean whitelistEnabled = (forceShowWhitelist || !whitelist.isEmpty()) && !forceHideWhitelist;
if (whitelist.isEmpty() && forceShowWhitelist) { if (whitelist.isEmpty() && forceShowWhitelist) {
for (Race r : Race.REGISTRY) { for (Race r : Race.REGISTRY) {
if (!r.isDefault()) { if (!r.isDefault()) {
whitelist.add(r); whitelist.add(r.getId().toString());
} }
} }
} }
@ -116,12 +116,12 @@ public class LanSettingsScreen extends GameGui {
if (!race.isDefault()) { if (!race.isDefault()) {
Bounds bound = WHITELIST_GRID_PACKER.next(); Bounds bound = WHITELIST_GRID_PACKER.next();
Button button = content.addButton(new Toggle(LEFT + bound.left + 10, row + bound.top, whitelist.contains(race))) Button button = content.addButton(new Toggle(LEFT + bound.left + 10, row + bound.top, whitelist.contains(race.getId().toString())))
.onChange(v -> { .onChange(v -> {
if (v) { if (v) {
whitelist.add(race); whitelist.add(race.getId().toString());
} else { } else {
whitelist.remove(race); whitelist.remove(race.getId().toString());
} }
return v; return v;
}) })

View file

@ -7,7 +7,6 @@ import com.minelittlepony.common.client.gui.GameGui;
import com.minelittlepony.common.client.gui.element.Label; import com.minelittlepony.common.client.gui.element.Label;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.client.UnicopiaClient;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgRequestSpeciesChange; import com.minelittlepony.unicopia.network.MsgRequestSpeciesChange;
@ -46,33 +45,34 @@ public class TribeSelectionScreen extends GameGui implements HidesHud {
block = addDrawable(new TextBlock(left, top += 7, pageWidth)); block = addDrawable(new TextBlock(left, top += 7, pageWidth));
block.getStyle().setText(Text.translatable("gui.unicopia.tribe_selection.welcome.choice")); block.getStyle().setText(Text.translatable("gui.unicopia.tribe_selection.welcome.choice"));
top += block.getBounds().height; top += block.getBounds().height;
Race preference = UnicopiaClient.getPreferredRace();
top += 30; top += 30;
final int itemWidth = 70; final int itemWidth = 70 + 10;
List<Race> options = Race.REGISTRY.stream().filter(race -> !race.isDefault() && !race.isOp()).toList(); List<Race> options = Race.REGISTRY.stream().filter(race -> !race.isDefault() && !race.isOp()).toList();
int totalWidth = options.size() * (itemWidth + 10) - 10; int columns = Math.min(width / itemWidth, options.size());
int x = (width - totalWidth) / 2; int x = (width - (columns * itemWidth)) / 2;
int y = top;
int column = 0;
int row = 0;
for (Race race : options) { for (Race race : options) {
addOption(race, x, top); addOption(race, x + (column * itemWidth), y + (row * itemWidth));
x += itemWidth + 10; column++;
if (column >= columns) {
column = 0;
row++;
}
} }
top = height - 20; top = height - 20;
if (!preference.isDefault()) {
addDrawable(new Label(width / 2, top).setCentered()).getStyle().setText(Text.translatable("gui.unicopia.tribe_selection.preference", preference.getDisplayName().copy().formatted(Formatting.YELLOW)));
}
} }
private void addOption(Race race, int x, int top) { private void addOption(Race race, int x, int y) {
addDrawableChild(new TribeButton(x, top, width, race)).onClick(b -> { addDrawableChild(new TribeButton(x, y, width, race)).onClick(b -> {
finished = true; finished = true;
client.setScreen(new TribeConfirmationScreen(result -> { client.setScreen(new TribeConfirmationScreen(result -> {
finished = false; finished = false;

View file

@ -2,8 +2,7 @@ package com.minelittlepony.unicopia.command;
import java.util.function.Function; import java.util.function.Function;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.Unicopia;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
@ -24,7 +23,7 @@ class RacelistCommand {
builder.then(CommandManager.literal("allow") builder.then(CommandManager.literal("allow")
.then(CommandManager.argument("race", raceArgument) .then(CommandManager.argument("race", raceArgument)
.executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), Race.fromArgument(context, "race"), "allowed", race -> { .executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), Race.fromArgument(context, "race"), "allowed", race -> {
boolean result = Unicopia.getConfig().speciesWhiteList.get().add(race); boolean result = Unicopia.getConfig().speciesWhiteList.get().add(race.getId().toString());
Unicopia.getConfig().save(); Unicopia.getConfig().save();
@ -34,7 +33,7 @@ class RacelistCommand {
builder.then(CommandManager.literal("disallow") builder.then(CommandManager.literal("disallow")
.then(CommandManager.argument("race", raceArgument) .then(CommandManager.argument("race", raceArgument)
.executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), Race.fromArgument(context, "race"), "disallowed", race -> { .executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), Race.fromArgument(context, "race"), "disallowed", race -> {
boolean result = Unicopia.getConfig().speciesWhiteList.get().remove(race); boolean result = Unicopia.getConfig().speciesWhiteList.get().remove(race.getId().toString());
Unicopia.getConfig().save(); Unicopia.getConfig().save();

View file

@ -9,7 +9,6 @@ import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.client.UnicopiaClient;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.*; import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.ability.AbilityDispatcher; import com.minelittlepony.unicopia.ability.AbilityDispatcher;
@ -30,7 +29,6 @@ import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities; import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities;
import com.minelittlepony.unicopia.network.MsgPlayerAnimationChange; import com.minelittlepony.unicopia.network.MsgPlayerAnimationChange;
import com.minelittlepony.unicopia.network.MsgRequestSpeciesChange;
import com.minelittlepony.unicopia.network.datasync.Transmittable; import com.minelittlepony.unicopia.network.datasync.Transmittable;
import com.minelittlepony.unicopia.util.*; import com.minelittlepony.unicopia.util.*;
import com.minelittlepony.unicopia.network.datasync.EffectSync.UpdateCallback; import com.minelittlepony.unicopia.network.datasync.EffectSync.UpdateCallback;
@ -94,7 +92,6 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
private final Interpolator interpolator = new LinearInterpolator(); private final Interpolator interpolator = new LinearInterpolator();
private boolean dirty; private boolean dirty;
private boolean speciesSet;
private boolean speciesPersisted; private boolean speciesPersisted;
private Optional<BlockPos> hangingPosition = Optional.empty(); private Optional<BlockPos> hangingPosition = Optional.empty();
@ -168,6 +165,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
@Override @Override
public Race getSpecies() { public Race getSpecies() {
if (UItems.ALICORN_AMULET.isApplicable(entity)) {
return Race.ALICORN;
}
return getSpellSlot() return getSpellSlot()
.get(SpellPredicate.IS_MIMIC, true) .get(SpellPredicate.IS_MIMIC, true)
.map(AbstractDisguiseSpell::getDisguise) .map(AbstractDisguiseSpell::getDisguise)
@ -184,7 +185,6 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
@Override @Override
public void setSpecies(Race race) { public void setSpecies(Race race) {
race = race.validate(entity); race = race.validate(entity);
speciesSet = true;
ticksInSun = 0; ticksInSun = 0;
entity.getDataTracker().set(RACE, Race.REGISTRY.getId(race).toString()); entity.getDataTracker().set(RACE, Race.REGISTRY.getId(race).toString());
@ -297,19 +297,6 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
@Override @Override
public boolean beforeUpdate() { public boolean beforeUpdate() {
if (isClientPlayer() && !speciesSet) {
Race race = UnicopiaClient.getPreferredRace();
if (race != clientPreferredRace) {
clientPreferredRace = race;
if (race != getActualSpecies()) {
Channel.CLIENT_REQUEST_SPECIES_CHANGE.send(new MsgRequestSpeciesChange(race));
}
}
}
if (isClient()) { if (isClient()) {
if (entity.hasVehicle() && entity.isSneaking()) { if (entity.hasVehicle() && entity.isSneaking()) {
@ -596,7 +583,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
@Override @Override
public void copyFrom(Pony oldPlayer) { public void copyFrom(Pony oldPlayer) {
speciesPersisted = oldPlayer.speciesPersisted; speciesPersisted = true;
if (!oldPlayer.getEntity().isRemoved()) { if (!oldPlayer.getEntity().isRemoved()) {
oldPlayer.getSpellSlot().stream(true).forEach(getSpellSlot()::put); oldPlayer.getSpellSlot().stream(true).forEach(getSpellSlot()::put);
} else { } else {

View file

@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.network;
import com.minelittlepony.unicopia.util.network.S2CBroadcastPacketType; import com.minelittlepony.unicopia.util.network.S2CBroadcastPacketType;
import com.minelittlepony.unicopia.util.network.S2CPacketType; import com.minelittlepony.unicopia.util.network.S2CPacketType;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.*;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.util.network.C2SPacketType; import com.minelittlepony.unicopia.util.network.C2SPacketType;
import com.minelittlepony.unicopia.util.network.SimpleNetworking; import com.minelittlepony.unicopia.util.network.SimpleNetworking;
@ -38,9 +38,19 @@ public interface Channel {
static void bootstrap() { static void bootstrap() {
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
if (!Pony.of(handler.player).isSpeciesPersisted()) { Pony pony = Pony.of(handler.player);
if (!pony.isSpeciesPersisted()) {
Race race = WorldTribeManager.forWorld(handler.player.getWorld()).getDefaultRace();
if (!race.isPermitted(handler.player)) {
race = Race.HUMAN;
}
if (race.isUsable()) {
pony.setSpecies(race);
Unicopia.LOGGER.info("Setting {}'s race to {} due to host setting", handler.player.getDisplayName().getString(), Race.REGISTRY.getId(race).toString());
} else {
sender.sendPacket(SERVER_SELECT_TRIBE.getId(), new MsgTribeSelect(handler.player).toBuffer()); sender.sendPacket(SERVER_SELECT_TRIBE.getId(), new MsgTribeSelect(handler.player).toBuffer());
} }
}
sender.sendPacket(SERVER_RESOURCES_SEND.getId(), new MsgServerResources().toBuffer()); sender.sendPacket(SERVER_RESOURCES_SEND.getId(), new MsgServerResources().toBuffer());
}); });
} }

View file

@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.network;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
@ -15,7 +14,7 @@ public class MsgTribeSelect implements Packet<PlayerEntity> {
private final Set<Race> availableRaces; private final Set<Race> availableRaces;
public MsgTribeSelect(PlayerEntity player) { public MsgTribeSelect(PlayerEntity player) {
availableRaces = Race.REGISTRY.stream().filter(r -> r.isPermitted(player)).collect(Collectors.toSet()); availableRaces = Race.allPermitted(player);
} }
public MsgTribeSelect(PacketByteBuf buffer) { public MsgTribeSelect(PacketByteBuf buffer) {