From 5708f9c80ffe80d461383a287ddfaac8781c1419 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 23 Apr 2020 23:44:31 +0200 Subject: [PATCH] Implement networking, reimplement pega-reach --- .../minelittlepony/jumpingcastle/api/Bus.java | 23 ----- .../jumpingcastle/api/Channel.java | 60 ------------- .../jumpingcastle/api/JumpingCastle.java | 28 ------ .../jumpingcastle/api/Message.java | 45 ---------- .../jumpingcastle/api/Server.java | 7 -- .../jumpingcastle/api/Target.java | 43 --------- .../api/payload/BinaryPayload.java | 63 ------------- .../api/payload/ByteBufBinaryPayload.java | 89 ------------------- .../api/payload/JsonSerializer.java | 19 ---- .../api/payload/Serializable.java | 19 ---- .../minelittlepony/unicopia/CustomDrops.java | 2 +- .../com/minelittlepony/unicopia/TreeType.java | 2 +- .../com/minelittlepony/unicopia/Unicopia.java | 21 +---- .../ability/UnicornCastingAbility.java | 2 +- .../unicopia/client/UnicopiaClient.java | 5 +- .../unicopia/client/gui/HudHooks.java | 2 +- .../container/SpellBookContainer.java | 5 +- .../container/SpellbookResultSlot.java | 5 +- .../unicopia/ducks/Climbable.java | 2 +- .../enchanting/recipe/SpecialRecipe.java | 53 +++++++---- .../enchanting/recipe/SpellIngredient.java | 4 +- .../enchanting/recipe/SpellRecipe.java | 6 +- .../unicopia/enchanting/recipe/URecipes.java | 30 +++++++ .../unicopia/entity/RainbowEntity.java | 44 +++------ .../entity/player/AbilityDelegate.java | 24 ++--- .../entity/player/GravityDelegate.java | 15 +++- .../entity/player/PlayerAttributes.java | 22 +++-- .../unicopia/entity/player/PlayerImpl.java | 15 ++-- .../unicopia/entity/player/Pony.java | 6 ++ .../unicopia/magic/spell/ShieldSpell.java | 2 +- .../unicopia/mixin/MixinPlayerEntity.java | 14 ++- .../unicopia/network/Channel.java | 86 ++++++++++++++++++ .../unicopia/network/MsgPlayerAbility.java | 43 +++++---- .../network/MsgPlayerCapabilities.java | 81 +++++++---------- .../network/MsgRequestCapabilities.java | 36 ++++---- .../unicopia/network/MsgSpawnRainbow.java | 52 +++++++++++ 36 files changed, 367 insertions(+), 608 deletions(-) delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/Bus.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/Channel.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/JumpingCastle.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/Message.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/Server.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/Target.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/payload/BinaryPayload.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/payload/ByteBufBinaryPayload.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/payload/JsonSerializer.java delete mode 100644 src/main/java/com/minelittlepony/jumpingcastle/api/payload/Serializable.java create mode 100644 src/main/java/com/minelittlepony/unicopia/enchanting/recipe/URecipes.java create mode 100644 src/main/java/com/minelittlepony/unicopia/network/Channel.java create mode 100644 src/main/java/com/minelittlepony/unicopia/network/MsgSpawnRainbow.java diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/Bus.java b/src/main/java/com/minelittlepony/jumpingcastle/api/Bus.java deleted file mode 100644 index d7016e91..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/Bus.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.minelittlepony.jumpingcastle.api; - -import java.util.UUID; - -import javax.annotation.Nullable; - -import com.minelittlepony.jumpingcastle.api.payload.BinaryPayload; - -/** - * Implementor for a Jumping Castle API bus. - */ -public interface Bus { - void sendToServer(String channel, long id, Message message, Target target); - - void sendToClient(String channel, long id, Message message, UUID playerId); - - void sendToClient(UUID playerId, BinaryPayload forwarded); - - @Nullable - Object getMinecraftServer(); - - Server getServer(); -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/Channel.java b/src/main/java/com/minelittlepony/jumpingcastle/api/Channel.java deleted file mode 100644 index e8bb5c55..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/Channel.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.minelittlepony.jumpingcastle.api; - -import java.util.UUID; - -/** - * A channel for sending and recieving messages. - */ -public interface Channel { - /** - * Registers a handler for a specific message type transmitted over this channel. - * - * @param messageType The message type being recieved. - * @param handler A handler instance to handle the message. - */ - Channel listenFor(Class messageType, Message.Handler handler); - - /** - * Registers a handler for a specific message type transmitted over this channel. - * - * @param messageType The message type being recieved. - */ - > Channel listenFor(Class messageType); - - /** - * Gets the minecraft server - */ - T getServer(); - - /** - * Sends a message over this channel. By default targets all other clients listening on this channel. - * - * @param message The message to send. - */ - default Channel send(Message message) { - return send(message, Target.CLIENTS); - } - - /** - * Sends a message over this channel. - * - * @param message The message to send. - * @param target Recipients that must handle this message (clients, server, or both) - */ - Channel send(Message message, Target target); - - /** - * Sends a message back. Use this if you're a server. - * - * @param message The message to send. - * @param recipient Recipient that must handle this message - */ - Channel respond(Message message, UUID recipient); - - /** - * Sends a message back to all clients. Use this if you're a server. - * - * @param message The message to send. - */ - Channel broadcast(Message message); -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/JumpingCastle.java b/src/main/java/com/minelittlepony/jumpingcastle/api/JumpingCastle.java deleted file mode 100644 index 75dd86cc..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/JumpingCastle.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.minelittlepony.jumpingcastle.api; - -/** - * Jumping Castle main interface. - *

- *{@code - * JumpingCastle.listen("My Channel").consume(MyMessage.class, (msg, channel) -> { - * ... - * }); - * - */ -public interface JumpingCastle { - /** - * Gets or creates a new channel indexed by the given identifier. - * - * @param channelName The channel name - * - * @return An instance of IChannel. - */ - static Channel subscribeTo(String channelName, Client clientHandler) { - return null;// TODO: JumpingFabric - } - - @FunctionalInterface - public interface Client { - void connectionEstablished(); - } -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/Message.java b/src/main/java/com/minelittlepony/jumpingcastle/api/Message.java deleted file mode 100644 index 56620adf..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/Message.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.minelittlepony.jumpingcastle.api; - -import com.minelittlepony.jumpingcastle.api.payload.Serializable; - -/** - * A message for communicating over a channel. - * Fields marked with @Expose are automatically serialized to the output packet stream - * and will be made available on the far end of the pipe. - * - * Override the read and write methods to customise this behaviour. - * - */ -public interface Message extends Serializable { - - /** - * Gets a unique identifier to represent a packet over channel communications. - */ - static long identifier(Class cls) { - return cls.getCanonicalName().hashCode(); - } - - /** - * Gets a unique identifier to represent this packet over channel communications. - */ - default long identifier() { - return identifier(getClass()); - } - - /** - * Handler interface for incoming messages. - * - * @param The type of message to handle. - */ - @FunctionalInterface - public interface Handler { - /** - * Called when a new message is received. - * - * @param message The message received. - * - * @param channel The channel used to deliver the message. - */ - void onPayload(T message, Channel channel); - } -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/Server.java b/src/main/java/com/minelittlepony/jumpingcastle/api/Server.java deleted file mode 100644 index 4238ff06..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/Server.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.minelittlepony.jumpingcastle.api; - -import java.util.UUID; - -public interface Server { - void stopTrackingPlayer(UUID playerId); -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/Target.java b/src/main/java/com/minelittlepony/jumpingcastle/api/Target.java deleted file mode 100644 index b29aa5c5..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/Target.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.minelittlepony.jumpingcastle.api; - -/** - * Targeting method to control who receives a message when sent. - * Senders choose whether a message is received on other clients, just the server, or both. - */ -public enum Target { - /** - * Message is ignored by the server and forwarded to connected clients. - */ - CLIENTS(true, false), - /** - * Only the server should process this message. Clients ignore it. - */ - SERVER(false, true), - /** - * The server should process this message and forward it to all available clients. - */ - SERVER_AND_CLIENTS(true, true); - - private final boolean clients; - - private final boolean servers; - - Target(boolean clients, boolean servers) { - this.clients = clients; - this.servers = servers; - } - - /** - * True if messages with this targeting must be processed by the client. - */ - public boolean isClients() { - return clients; - } - - /** - * True if messages with this targeting must be processed by the server. - */ - public boolean isServers() { - return servers; - } -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/BinaryPayload.java b/src/main/java/com/minelittlepony/jumpingcastle/api/payload/BinaryPayload.java deleted file mode 100644 index 10c6a559..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/BinaryPayload.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.minelittlepony.jumpingcastle.api.payload; - -import javax.annotation.Nullable; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -public interface BinaryPayload { - - @Nullable - static BinaryPayload of(Object buffer) { - if (buffer instanceof ByteBuf) { - return ByteBufBinaryPayload.of((ByteBuf)buffer); - } - return null; - } - - static BinaryPayload create() { - return of(Unpooled.buffer()); - } - - T buff(); - - byte[] bytes(); - - byte[] readToEnd(); - - long readLong(); - - BinaryPayload writeLong(long l); - - int readInt(); - - BinaryPayload writeInt(int b); - - byte readByte(); - - BinaryPayload writeByte(byte b); - - String readString(); - - BinaryPayload writeString(String s); - - byte[] readBytes(int len); - - BinaryPayload writeBytes(byte[] bytes); - - BinaryPayload reverse(); - - @SuppressWarnings("unchecked") - default > T readBinary(Class type) { - try { - return (T)type.newInstance().read(this); - } catch (InstantiationException | IllegalAccessException e) { - return null; - } - } - - default > BinaryPayload writeBinary(T message) { - message.write(this); - return this; - } -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/ByteBufBinaryPayload.java b/src/main/java/com/minelittlepony/jumpingcastle/api/payload/ByteBufBinaryPayload.java deleted file mode 100644 index 4d8fff26..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/ByteBufBinaryPayload.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.minelittlepony.jumpingcastle.api.payload; - -import java.nio.charset.StandardCharsets; - -import io.netty.buffer.ByteBuf; - -interface ByteBufBinaryPayload extends BinaryPayload { - - static BinaryPayload of(ByteBuf buff) { - return (ByteBufBinaryPayload)(() -> buff); - } - - @SuppressWarnings("unchecked") - ByteBuf buff(); - - @Override - default String readString() { - return buff().readCharSequence(readInt(), StandardCharsets.UTF_8).toString(); - } - - @Override - default int readInt() { - return buff().readInt(); - } - - @Override - default BinaryPayload writeInt(int b) { - buff().writeInt(b); - return this; - } - - @Override - default byte readByte() { - return buff().readByte(); - } - - @Override - default BinaryPayload writeByte(byte b) { - buff().writeByte(b); - return this; - } - - default byte[] bytes() { - return buff().array(); - } - - default byte[] readToEnd() { - byte[] bytes = new byte[buff().writerIndex() - buff().readerIndex()]; - buff().readBytes(bytes); - return bytes; - } - - @Override - default long readLong() { - return buff().readLong(); - } - - @Override - default BinaryPayload writeLong(long l) { - buff().writeLong(l); - return this; - } - - @Override - default BinaryPayload reverse() { - buff().readerIndex(0); - return this; - } - - @Override - default byte[] readBytes(int len) { - byte[] data = new byte[len]; - buff().readBytes(data); - return data; - } - - @Override - default BinaryPayload writeBytes(byte[] bytes) { - buff().writeBytes(bytes); - return this; - } - - @Override - default BinaryPayload writeString(String s) { - buff().writeInt(s.getBytes(StandardCharsets.UTF_8).length); - buff().writeCharSequence(s, StandardCharsets.UTF_8); - return this; - } -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/JsonSerializer.java b/src/main/java/com/minelittlepony/jumpingcastle/api/payload/JsonSerializer.java deleted file mode 100644 index 3117c129..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/JsonSerializer.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.minelittlepony.jumpingcastle.api.payload; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -public class JsonSerializer { - private static final Gson READER_GSON = new GsonBuilder() - .excludeFieldsWithoutExposeAnnotation() - .create(); - - public static T read(BinaryPayload payload, Class type) { - return (T)READER_GSON.fromJson(payload.readString(), type); - } - - public static void write(BinaryPayload payload, T object) { - payload.writeString(READER_GSON.toJson(object)); - } - -} diff --git a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/Serializable.java b/src/main/java/com/minelittlepony/jumpingcastle/api/payload/Serializable.java deleted file mode 100644 index bd2727b7..00000000 --- a/src/main/java/com/minelittlepony/jumpingcastle/api/payload/Serializable.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.minelittlepony.jumpingcastle.api.payload; - -public interface Serializable> { - /** - * Reads the contents of this message from a networking payload. - */ - @SuppressWarnings("unchecked") - default T read(BinaryPayload payload) { - return (T)JsonSerializer.read(payload, getClass()); - } - - /** - * Writes the contents of this message to a networking payload. - */ - default void write(BinaryPayload payload) { - JsonSerializer.write(payload, this); - } - -} diff --git a/src/main/java/com/minelittlepony/unicopia/CustomDrops.java b/src/main/java/com/minelittlepony/unicopia/CustomDrops.java index 364ff544..03808abe 100644 --- a/src/main/java/com/minelittlepony/unicopia/CustomDrops.java +++ b/src/main/java/com/minelittlepony/unicopia/CustomDrops.java @@ -16,7 +16,7 @@ import net.minecraft.world.World; @Deprecated public class CustomDrops { - // TODO: loot table + // XXX: loot table public void addAuxiliaryDrops(World world, BlockState state, BlockPos pos, List drops, int fortune) { Block block = state.getBlock(); diff --git a/src/main/java/com/minelittlepony/unicopia/TreeType.java b/src/main/java/com/minelittlepony/unicopia/TreeType.java index 5ddf4500..b1c40052 100644 --- a/src/main/java/com/minelittlepony/unicopia/TreeType.java +++ b/src/main/java/com/minelittlepony/unicopia/TreeType.java @@ -18,7 +18,7 @@ import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; public final class TreeType { - // TODO: move to datapack + // XXX: move to datapack private static final Set REGISTRY = new HashSet<>(); public static final TreeType NONE = new TreeType("none", new Weighted>()); diff --git a/src/main/java/com/minelittlepony/unicopia/Unicopia.java b/src/main/java/com/minelittlepony/unicopia/Unicopia.java index b173615e..37338bf8 100644 --- a/src/main/java/com/minelittlepony/unicopia/Unicopia.java +++ b/src/main/java/com/minelittlepony/unicopia/Unicopia.java @@ -8,8 +8,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.minelittlepony.common.util.GamePaths; -import com.minelittlepony.jumpingcastle.api.Channel; -import com.minelittlepony.jumpingcastle.api.JumpingCastle; import com.minelittlepony.unicopia.ability.Abilities; import com.minelittlepony.unicopia.advancement.BOHDeathCriterion; import com.minelittlepony.unicopia.block.UBlocks; @@ -17,39 +15,28 @@ import com.minelittlepony.unicopia.command.Commands; import com.minelittlepony.unicopia.container.UContainers; import com.minelittlepony.unicopia.enchanting.Pages; import com.minelittlepony.unicopia.enchanting.recipe.AffineIngredients; +import com.minelittlepony.unicopia.enchanting.recipe.URecipes; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.mixin.CriterionsRegistry; -import com.minelittlepony.unicopia.network.MsgPlayerAbility; -import com.minelittlepony.unicopia.network.MsgPlayerCapabilities; -import com.minelittlepony.unicopia.network.MsgRequestCapabilities; +import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.structure.UStructures; public class Unicopia implements ModInitializer { public static final String MODID = "unicopia"; - public static final Logger LOGGER = LogManager.getLogger(); - private static Channel channel; - - public static Channel getConnection() { - return channel; - } - @Override public void onInitialize() { Config.init(GamePaths.getConfigDirectory()); - channel = JumpingCastle.subscribeTo(MODID, () -> {}) - .listenFor(MsgRequestCapabilities.class) - .listenFor(MsgPlayerCapabilities.class) - .listenFor(MsgPlayerAbility.class); - + Channel.bootstrap(); UTags.bootstrap(); Commands.bootstrap(); UBlocks.bootstrap(); UItems.bootstrap(); UContainers.bootstrap(); UStructures.bootstrap(); + URecipes.bootstrap(); Abilities.getInstance().init(); CriterionsRegistry.register(BOHDeathCriterion.INSTANCE); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index b0610b65..f2675071 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -50,7 +50,7 @@ public class UnicornCastingAbility implements Ability { @Override public void apply(Pony player, Hit data) { - // TODO: A way for the player to select which effect they want + // XXX: A way for the player to select which effect they want if (player.getEffect() instanceof ShieldSpell) { player.setEffect(null); } else { diff --git a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java index 3cd5f528..9bfd0aba 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java +++ b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java @@ -6,11 +6,9 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.minelittlepony.common.event.ClientReadyCallback; -import com.minelittlepony.jumpingcastle.api.Target; import com.minelittlepony.unicopia.Config; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.ability.Abilities; import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.container.SpellbookResultSlot; @@ -19,6 +17,7 @@ import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.mixin.client.DefaultTexturesRegistry; +import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.MsgRequestCapabilities; import com.minelittlepony.unicopia.util.dummy.DummyClientPlayerEntity; import com.mojang.authlib.GameProfile; @@ -84,7 +83,7 @@ public class UnicopiaClient extends InteractionManager implements ClientModIniti if (newRace != clientPlayerRace) { clientPlayerRace = newRace; - Unicopia.getConnection().send(new MsgRequestCapabilities(player, clientPlayerRace), Target.SERVER); + Channel.REQUEST_CAPABILITIES.send(new MsgRequestCapabilities(player, clientPlayerRace)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/HudHooks.java b/src/main/java/com/minelittlepony/unicopia/client/gui/HudHooks.java index 2e1457a9..e144c9e6 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/HudHooks.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/HudHooks.java @@ -5,7 +5,7 @@ import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.client.MinecraftClient; @Deprecated -// TODO: forge events +// XXX: hud render events class HudHooks { public static void beforePreRenderHud() { MinecraftClient client = MinecraftClient.getInstance(); diff --git a/src/main/java/com/minelittlepony/unicopia/container/SpellBookContainer.java b/src/main/java/com/minelittlepony/unicopia/container/SpellBookContainer.java index bcf114c5..1d851113 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/SpellBookContainer.java +++ b/src/main/java/com/minelittlepony/unicopia/container/SpellBookContainer.java @@ -5,6 +5,7 @@ import javax.annotation.Nonnull; import com.minelittlepony.unicopia.AwaitTickQueue; import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.enchanting.IPageUnlockListener; +import com.minelittlepony.unicopia.enchanting.recipe.URecipes; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.magic.spell.SpellRegistry; @@ -16,7 +17,6 @@ import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.particle.ParticleTypes; import net.minecraft.recipe.Recipe; -import net.minecraft.recipe.RecipeType; import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; import net.minecraft.util.PacketByteBuf; @@ -73,8 +73,7 @@ public class SpellBookContainer extends Container { ItemStack current = craftResult.getInvStack(0); if (!current.isEmpty()) { - // TODO: URecipeType.SPELL_BOOK - ItemStack crafted = player.world.getRecipeManager().getFirstMatch(RecipeType.CRAFTING, craftMatrix, worldObj) + ItemStack crafted = player.world.getRecipeManager().getFirstMatch(URecipes.SPELL_BOOK, craftMatrix, worldObj) .map(Recipe::getOutput) .orElse(ItemStack.EMPTY); diff --git a/src/main/java/com/minelittlepony/unicopia/container/SpellbookResultSlot.java b/src/main/java/com/minelittlepony/unicopia/container/SpellbookResultSlot.java index e0eb538a..cfce1cca 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/SpellbookResultSlot.java +++ b/src/main/java/com/minelittlepony/unicopia/container/SpellbookResultSlot.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.container; import com.minelittlepony.unicopia.enchanting.IPageUnlockListener; import com.minelittlepony.unicopia.enchanting.SpellCraftingEvent; +import com.minelittlepony.unicopia.enchanting.recipe.URecipes; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.MagicGemItem; import com.minelittlepony.unicopia.magic.spell.SpellRegistry; @@ -12,7 +13,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.item.MusicDiscItem; -import net.minecraft.recipe.RecipeType; import net.minecraft.util.DefaultedList; import net.minecraft.util.Identifier; @@ -49,8 +49,7 @@ public class SpellbookResultSlot extends SpellBookContainer.SpellbookSlot { ItemStack current = craftMatrix.getCraftResultMatrix().getInvStack(0); craftMatrix.getCraftResultMatrix().setInvStack(0, stack); - // TODO: URecipeType.SPELL_BOOK - DefaultedList remaining = player.world.getRecipeManager().getRemainingStacks(RecipeType.CRAFTING, craftMatrix, player.world); + DefaultedList remaining = player.world.getRecipeManager().getRemainingStacks(URecipes.SPELL_BOOK, craftMatrix, player.world); craftMatrix.getCraftResultMatrix().setInvStack(0, current); diff --git a/src/main/java/com/minelittlepony/unicopia/ducks/Climbable.java b/src/main/java/com/minelittlepony/unicopia/ducks/Climbable.java index 5e12e5b6..54e1c63b 100644 --- a/src/main/java/com/minelittlepony/unicopia/ducks/Climbable.java +++ b/src/main/java/com/minelittlepony/unicopia/ducks/Climbable.java @@ -1,7 +1,7 @@ package com.minelittlepony.unicopia.ducks; @Deprecated -// TODO: 1.16 Use the vanilla BlockTag once mojang adds it +// XXX: 1.16 Use the vanilla BlockTag once mojang adds it public interface Climbable { } diff --git a/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpecialRecipe.java b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpecialRecipe.java index 73ead1bd..9b71a1f4 100644 --- a/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpecialRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpecialRecipe.java @@ -2,29 +2,18 @@ package com.minelittlepony.unicopia.enchanting.recipe; import com.google.gson.JsonObject; -import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; -import net.minecraft.recipe.Recipe; import net.minecraft.recipe.RecipeSerializer; import net.minecraft.recipe.RecipeType; import net.minecraft.util.DefaultedList; import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; public class SpecialRecipe extends AbstractSpecialRecipe { - private final SpellIngredient output; - public static Recipe deserialize(JsonObject json) { - return new SpecialRecipe(null, - SpellIngredient.single(json.get("input").getAsJsonObject()), - SpellIngredient.single(json.get("output").getAsJsonObject()), - SpellIngredient.multiple(json) - ); - } - public SpecialRecipe(Identifier id, SpellIngredient input, SpellIngredient output, DefaultedList ingredients) { super(id, input, ingredients); - this.output = output; } @@ -35,13 +24,45 @@ public class SpecialRecipe extends AbstractSpecialRecipe { @Override public RecipeSerializer getSerializer() { - // TODO Auto-generated method stub - return null; + return URecipes.SPECIAL_SERIALIZER; } @Override public RecipeType getType() { - // TODO Auto-generated method stub - return null; + return URecipes.SPELL_BOOK; } + + public static class Serializer implements RecipeSerializer { + @Override + public SpecialRecipe read(Identifier id, JsonObject json) { + return new SpecialRecipe(id, + SpellIngredient.single(json.get("input").getAsJsonObject()), + SpellIngredient.single(json.get("output").getAsJsonObject()), + SpellIngredient.multiple(json) + ); + } + + @Override + public SpecialRecipe read(Identifier id, PacketByteBuf buf) { + SpellIngredient input = SpellIngredient.SERIALIZER.read(buf); + SpellIngredient output = SpellIngredient.SERIALIZER.read(buf); + int length = buf.readInt(); + DefaultedList ingredients = DefaultedList.copyOf(SpellIngredient.EMPTY); + while (ingredients.size() < length) { + ingredients.add(SpellIngredient.SERIALIZER.read(buf)); + } + + return new SpecialRecipe(id, input, output, ingredients); + } + + @Override + public void write(PacketByteBuf buf, SpecialRecipe recipe) { + recipe.getSpellItem().write(buf); + recipe.output.write(buf); + DefaultedList ingredients = recipe.getSpellIngredients(); + buf.writeInt(ingredients.size()); + ingredients.forEach(i -> i.write(buf)); + } + } + } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellIngredient.java b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellIngredient.java index 8c27423c..da478379 100644 --- a/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellIngredient.java +++ b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellIngredient.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.enchanting.recipe; import java.util.HashMap; import java.util.Map; +import java.util.stream.Collectors; import java.util.stream.Stream; import com.google.gson.JsonElement; @@ -20,6 +21,7 @@ public interface SpellIngredient { map.put("single", SingleSpellIngredient.SERIALIZER); map.put("affine", AffineIngredient.SERIALIZER); }); + Map, String> IDS = SERIALIZERS.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); Serializer SERIALIZER = new Serializer() { @Override @@ -40,7 +42,7 @@ public interface SpellIngredient { @Override public void write(PacketByteBuf buff, SpellIngredient recipe) { - buff.writeByte(recipe instanceof SingleSpellIngredient ? 0 : 1); + buff.writeString(IDS.get(recipe.getSerializer())); recipe.write(buff); } }; diff --git a/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellRecipe.java b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellRecipe.java index fddfc970..3e200d6e 100644 --- a/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/SpellRecipe.java @@ -45,16 +45,15 @@ public class SpellRecipe extends AbstractSpecialRecipe { @Override public RecipeSerializer getSerializer() { - return null; + return URecipes.SPELL_SERIALIZER; } @Override public RecipeType getType() { - return null; + return URecipes.SPELL_BOOK; } public static class Serializer implements RecipeSerializer { - @Override public SpellRecipe read(Identifier id, JsonObject json) { JsonObject resultJson = json.get("result").getAsJsonObject(); @@ -93,4 +92,5 @@ public class SpellRecipe extends AbstractSpecialRecipe { ingredients.forEach(i -> i.write(buff)); } } + } diff --git a/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/URecipes.java b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/URecipes.java new file mode 100644 index 00000000..aaf4f593 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/enchanting/recipe/URecipes.java @@ -0,0 +1,30 @@ +package com.minelittlepony.unicopia.enchanting.recipe; + +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.RecipeType; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +public interface URecipes { + + RecipeType SPELL_BOOK = register("spell_book"); + + RecipeSerializer SPECIAL_SERIALIZER = register("special_spell", new SpecialRecipe.Serializer()); + RecipeSerializer SPELL_SERIALIZER = register("spell", new SpellRecipe.Serializer()); + + static > RecipeType register(final String id) { + return Registry.register(Registry.RECIPE_TYPE, new Identifier("unicopia", id), new RecipeType() { + @Override + public String toString() { + return id; + } + }); + } + + static , T extends Recipe> S register(String id, S serializer) { + return Registry.register(Registry.RECIPE_SERIALIZER, new Identifier("unicopia", id), serializer); + } + + static void bootstrap() {} +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/RainbowEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/RainbowEntity.java index 61761e17..d81e2187 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/RainbowEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/RainbowEntity.java @@ -1,18 +1,17 @@ package com.minelittlepony.unicopia.entity; import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.network.Channel; +import com.minelittlepony.unicopia.network.MsgSpawnRainbow; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.packet.EntitySpawnGlobalS2CPacket; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityType; -import net.minecraft.entity.LightningEntity; import net.minecraft.entity.SpawnType; import net.minecraft.entity.mob.MobEntity; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.NetworkThreadUtils; import net.minecraft.network.Packet; -import net.minecraft.network.listener.ClientPlayPacketListener; import net.minecraft.sound.SoundCategory; import net.minecraft.util.math.Box; import net.minecraft.util.math.MathHelper; @@ -26,7 +25,7 @@ public class RainbowEntity extends Entity implements InAnimate { private int ticksAlive; - private double radius; + private final double radius; public static final int RAINBOW_MAX_SIZE = 180; public static final int RAINBOW_MIN_SIZE = 50; @@ -49,8 +48,7 @@ public class RainbowEntity extends Entity implements InAnimate { ignoreCameraFrustum = true; - //width = (float)radius; - //height = width; + calculateDimensions(); } @Override @@ -69,6 +67,11 @@ public class RainbowEntity extends Entity implements InAnimate { )); } + @Override + public EntityDimensions getDimensions(EntityPose pose) { + return EntityDimensions.changing((float)getRadius(), (float)getRadius()); + } + @Override public SoundCategory getSoundCategory() { return SoundCategory.WEATHER; @@ -119,7 +122,7 @@ public class RainbowEntity extends Entity implements InAnimate { @Override public Packet createSpawnPacket() { - return new SpawnPacket(this); + return Channel.SPAWN_RAINBOW.toPacket(new MsgSpawnRainbow(this)); } public static class Spawner extends MobEntity { @@ -159,27 +162,4 @@ public class RainbowEntity extends Entity implements InAnimate { world.spawnEntity(rainbow); } } - - static class SpawnPacket extends EntitySpawnGlobalS2CPacket { - public SpawnPacket(RainbowEntity entity) { - super(entity); - } - - @Override - public void apply(ClientPlayPacketListener listener) { - // TODO: Packet needs to be registered, and handling separated - MinecraftClient client = MinecraftClient.getInstance(); - - NetworkThreadUtils.forceMainThread(this, listener, client); - double x = getX(); - double y = getY(); - double z = getZ(); - LightningEntity entity = new LightningEntity(client.world, x, y, z, false); - entity.updateTrackedPosition(x, y, z); - entity.yaw = 0; - entity.pitch = 0; - entity.setEntityId(getId()); - client.world.addLightning(entity); - } - } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/AbilityDelegate.java b/src/main/java/com/minelittlepony/unicopia/entity/player/AbilityDelegate.java index fbb323f2..a7a266b6 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/AbilityDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/AbilityDelegate.java @@ -1,15 +1,13 @@ package com.minelittlepony.unicopia.entity.player; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import com.minelittlepony.jumpingcastle.api.Target; -import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.ability.AbilityReceiver; import com.minelittlepony.unicopia.ability.Ability; import com.minelittlepony.unicopia.ability.Abilities; import com.minelittlepony.unicopia.entity.Updatable; import com.minelittlepony.unicopia.network.MsgPlayerAbility; +import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.util.NbtSerialisable; import net.minecraft.nbt.CompoundTag; @@ -112,7 +110,11 @@ class AbilityDelegate implements AbilityReceiver, Updatable, NbtSerialisable { cooldown = ability.getCooldownTime(player); if (player.isClientPlayer()) { - if (!activateAbility(ability)) { + Ability.IData data = ability.tryActivate(player); + + if (data != null) { + Channel.PLAYER_ABILITY.send(new MsgPlayerAbility(ability, data)); + } else { cooldown = 0; } } @@ -150,18 +152,4 @@ class AbilityDelegate implements AbilityReceiver, Updatable, NbtSerialisable { .ifPresent(p -> activeAbility = p); } } - - /** - * Attempts to activate the current stored ability. - * Returns true if the ability suceeded, otherwise false. - */ - protected boolean activateAbility(@Nonnull Ability ability) { - Ability.IData data = ability.tryActivate(player); - - if (data != null) { - Unicopia.getConnection().send(new MsgPlayerAbility(player.getOwner(), ability, data), Target.SERVER); - } - - return data != null; - } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/GravityDelegate.java b/src/main/java/com/minelittlepony/unicopia/entity/player/GravityDelegate.java index 4e368355..44cf6cc3 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/GravityDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/GravityDelegate.java @@ -15,6 +15,7 @@ import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.MutableVector; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundTag; import net.minecraft.sound.SoundCategory; @@ -41,6 +42,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl private float gravity = 0; + private float eyeHeight; + public GravityDelegate(Pony player) { this.player = player; } @@ -65,6 +68,10 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl return Math.sqrt(getHorizontalMotion(player.getOwner())) > 0.4F; } + public float getEyeHeight() { + return eyeHeight; + } + @Override public float getTargetEyeHeight(Pony player) { if (player.hasEffect()) { @@ -81,7 +88,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl return 0.5F; } - return player.getOwner().getStandingEyeHeight(); + EntityPose pose = player.getOwner().getPose(); + return player.getOwner().getActiveEyeHeight(pose, player.getOwner().getDimensions(pose)); } @Override @@ -163,7 +171,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl } float bodyHeight = getTargetBodyHeight(player); - float eyeHeight = getTargetEyeHeight(player); + eyeHeight = 0; + eyeHeight = getTargetEyeHeight(player); if (gravity < 0) { eyeHeight = bodyHeight - eyeHeight; @@ -176,8 +185,6 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl ((MixinEntity)entity).setSize(entity.getWidth(), bodyHeight); - // TODO: Change eye height - //entity.eyeHeight = eyeHeight; if (gravity < 0) { if (entity.isSneaking()) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerAttributes.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerAttributes.java index 4262d1d3..d925a9ca 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerAttributes.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerAttributes.java @@ -6,6 +6,7 @@ import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.container.HeavyInventory; import com.minelittlepony.unicopia.mixin.Walker; +import net.minecraft.entity.attribute.ClampedEntityAttribute; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.attribute.EntityAttributeModifier; @@ -13,14 +14,16 @@ import net.minecraft.entity.attribute.EntityAttributeModifier.Operation; import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.player.PlayerEntity; -public class PlayerAttributes { +class PlayerAttributes { + + static final EntityAttribute EXTENDED_REACH_DISTANCE = new ClampedEntityAttribute(null, "player.reachDistance", 0, 0, 10); private static final EntityAttributeModifier EARTH_PONY_STRENGTH = new EntityAttributeModifier(UUID.fromString("777a5505-521e-480b-b9d5-6ea54f259564"), "Earth Pony Strength", 0.6, Operation.MULTIPLY_TOTAL); private static final EntityAttributeModifier PEGASUS_SPEED = new EntityAttributeModifier(UUID.fromString("9e2699fc-3b8d-4f71-9d2d-fb92ee19b4f7"), "Pegasus Speed", 0.2, Operation.MULTIPLY_TOTAL); - //private static final EntityAttributeModifier PEGASUS_REACH = - // new EntityAttributeModifier(UUID.fromString("707b50a8-03e8-40f4-8553-ecf67025fd6d"), "Pegasus Reach", 1.5, Operation.ADDITION); + private static final EntityAttributeModifier PEGASUS_REACH = + new EntityAttributeModifier(UUID.fromString("707b50a8-03e8-40f4-8553-ecf67025fd6d"), "Pegasus Reach", 1.5, Operation.ADDITION); private double loadStrength = 0; @@ -29,14 +32,15 @@ public class PlayerAttributes { ((Walker)entity.abilities).setWalkSpeed(0.1F - (float)(loadStrength / 100000)); - applyAttribute(entity, EntityAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth()); - applyAttribute(entity, EntityAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth()); - applyAttribute(entity, EntityAttributes.MOVEMENT_SPEED, PEGASUS_SPEED, race.canFly()); - applyAttribute(entity, EntityAttributes.ATTACK_SPEED, PEGASUS_SPEED, race.canFly()); - // applyAttribute(entity, PlayerEntity.REACH_DISTANCE, PEGASUS_REACH, race.canFly()); + toggleAttribute(entity, EntityAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth()); + toggleAttribute(entity, EntityAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth()); + toggleAttribute(entity, EntityAttributes.MOVEMENT_SPEED, PEGASUS_SPEED, race.canFly()); + toggleAttribute(entity, EntityAttributes.ATTACK_SPEED, PEGASUS_SPEED, race.canFly()); + toggleAttribute(entity, EXTENDED_REACH_DISTANCE, PEGASUS_REACH, race.canFly()); } - private void applyAttribute(PlayerEntity entity, EntityAttribute attribute, EntityAttributeModifier modifier, boolean enable) { + private void toggleAttribute(PlayerEntity entity, EntityAttribute attribute, EntityAttributeModifier modifier, boolean enable) { + EntityAttributeInstance instance = entity.getAttributeInstance(attribute); if (enable) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerImpl.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerImpl.java index 81cfd703..f0f96235 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerImpl.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerImpl.java @@ -4,7 +4,6 @@ import javax.annotation.Nullable; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.UTags; -import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.ability.AbilityReceiver; import com.minelittlepony.unicopia.enchanting.PageOwner; import com.minelittlepony.unicopia.entity.FlightControl; @@ -16,6 +15,7 @@ import com.minelittlepony.unicopia.magic.HeldMagicEffect; import com.minelittlepony.unicopia.magic.MagicEffect; import com.minelittlepony.unicopia.magic.MagicalItem; import com.minelittlepony.unicopia.magic.spell.SpellRegistry; +import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.EffectSync; import com.minelittlepony.unicopia.network.MsgPlayerCapabilities; import com.minelittlepony.unicopia.util.BasicEasingInterpolator; @@ -85,6 +85,8 @@ public class PlayerImpl implements Pony { player.getDataTracker().startTracking(ENERGY, 0F); player.getDataTracker().startTracking(EFFECT, new CompoundTag()); player.getDataTracker().startTracking(HELD_EFFECT, new CompoundTag()); + + player.getAttributes().register(PlayerAttributes.EXTENDED_REACH_DISTANCE); } @Override @@ -169,11 +171,7 @@ public class PlayerImpl implements Pony { dirty = false; if (!getWorld().isClient()) { - if (full) { - Unicopia.getConnection().broadcast(new MsgPlayerCapabilities(this)); - } else { - Unicopia.getConnection().broadcast(new MsgPlayerCapabilities(getSpecies(), getOwner())); - } + Channel.BROADCAST_CAPABILITIES.send(new MsgPlayerCapabilities(full, this)); } } @@ -199,6 +197,11 @@ public class PlayerImpl implements Pony { return gravity; } + @Override + public float getExtendedReach() { + return (float)entity.getAttributeInstance(PlayerAttributes.EXTENDED_REACH_DISTANCE).getValue(); + } + @Override public FlightControl getFlight() { return gravity; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index bf5a6c49..64329bb2 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -70,6 +70,12 @@ public interface Pony extends Caster, RaceContainer, */ void setExertion(float exertion); + /** + * + * @return + */ + float getExtendedReach(); + /** * Adds player tiredness. */ diff --git a/src/main/java/com/minelittlepony/unicopia/magic/spell/ShieldSpell.java b/src/main/java/com/minelittlepony/unicopia/magic/spell/ShieldSpell.java index acca6a03..3b483755 100644 --- a/src/main/java/com/minelittlepony/unicopia/magic/spell/ShieldSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/magic/spell/ShieldSpell.java @@ -55,7 +55,7 @@ public class ShieldSpell extends AbstractSpell.RangedAreaSpell implements Attach particlEffect .ifMissing(source, () -> { source.addParticle(UParticles.SPHERE, source.getOriginVector(), Vec3d.ZERO); - return null; // TODO: Attachables + return null; // XXX: Attachables }) // 1, getTint(), 10 .ifPresent(p -> p.setAttribute(0, radius)); } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java index c6970eaa..3cf25789 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java @@ -13,6 +13,8 @@ import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.PlayerImpl; import com.mojang.datafixers.util.Either; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; @@ -58,7 +60,17 @@ public abstract class MixinPlayerEntity extends LivingEntity implements PonyCont @Inject(method = "setGameMode(Lnet/minecraft/world/GameMode;)V", at = @At("RETURN")) - public void setGameMode(GameMode mode, CallbackInfo info) { + private void onSetGameMode(GameMode mode, CallbackInfo info) { get().setSpecies(get().getSpecies()); } + + @Inject(method = "getActiveEyeHeight(Lnet/minecraft/entity/EntityPose;Lnet/minecraft/entity/EntityDimensions;)F", + at = @At("RETURN"), + cancellable = true) + private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable info) { + float h = get().getGravity().getEyeHeight(); + if (h != 0) { + info.setReturnValue(h); + } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/network/Channel.java b/src/main/java/com/minelittlepony/unicopia/network/Channel.java new file mode 100644 index 00000000..23d1871c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/network/Channel.java @@ -0,0 +1,86 @@ +package com.minelittlepony.unicopia.network; + +import java.util.function.Function; + +import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; +import net.fabricmc.fabric.api.network.PacketContext; +import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Identifier; +import net.minecraft.util.PacketByteBuf; + +public interface Channel { + + SPacketType PLAYER_ABILITY = clientToServer(new Identifier("unicopia", "player_ability"), MsgPlayerAbility::new); + + SPacketType REQUEST_CAPABILITIES = clientToServer(new Identifier("unicopia", "request_capabilities"), MsgRequestCapabilities::new); + CPacketType PLAYER_CAPABILITIES = serverToClient(new Identifier("unicopia", "player_capabilities"), MsgPlayerCapabilities::new); + + SPacketType BROADCAST_CAPABILITIES = broadcast(PLAYER_CAPABILITIES, MsgPlayerCapabilities::new); + + CPacketType SPAWN_RAINBOW = serverToClient(new Identifier("unicopia", "rainbow_entity"), MsgSpawnRainbow::new); + + static void bootstrap() { } + + static SPacketType clientToServer(Identifier id, Function factory) { + ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handle(context)); + return () -> id; + } + + static SPacketType broadcast(CPacketType redirect, Function factory) { + Identifier id = new Identifier(redirect.getId().getNamespace(), "broadcast_" + redirect.getId().getPath()); + ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> { + PlayerEntity sender = context.getPlayer(); + T p = factory.apply(buffer); + p.handle(context); + sender.world.getPlayers().forEach(player -> { + if (player != null && player != sender) { + redirect.send(player, p); + } + }); + }); + return () -> id; + } + + static CPacketType serverToClient(Identifier id, Function factory) { + ClientSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handle(context)); + return () -> id; + } + + interface CPacketType { + Identifier getId(); + + default void send(PlayerEntity recipient, T packet) { + ServerSidePacketRegistry.INSTANCE.sendToPlayer(recipient, getId(), packet.toBuffer()); + } + + default net.minecraft.network.Packet toPacket(T packet) { + return ServerSidePacketRegistry.INSTANCE.toPacket(getId(), packet.toBuffer()); + } + } + + interface SPacketType { + Identifier getId(); + + default void send(T packet) { + ClientSidePacketRegistry.INSTANCE.sendToServer(getId(), packet.toBuffer()); + } + + default net.minecraft.network.Packet toPacket(T packet) { + return ClientSidePacketRegistry.INSTANCE.toPacket(getId(), packet.toBuffer()); + } + } + + interface Packet { + void handle(PacketContext context); + + void toBuffer(PacketByteBuf buffer); + + default PacketByteBuf toBuffer() { + PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); + toBuffer(buf); + return buf; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java b/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java index 0a81947b..6b7d58fd 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerAbility.java @@ -1,43 +1,36 @@ package com.minelittlepony.unicopia.network; -import java.util.UUID; - import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.annotations.Expose; -import com.minelittlepony.jumpingcastle.api.Channel; -import com.minelittlepony.jumpingcastle.api.Message; import com.minelittlepony.unicopia.ability.Ability; import com.minelittlepony.unicopia.ability.Abilities; import com.minelittlepony.unicopia.entity.player.Pony; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; +import net.fabricmc.fabric.api.network.PacketContext; +import net.minecraft.util.PacketByteBuf; -public class MsgPlayerAbility implements Message, Message.Handler { +public class MsgPlayerAbility implements Channel.Packet { private static final Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create(); - @Expose - private UUID senderId; + private final String powerIdentifier; - @Expose - private String powerIdentifier; + private final String abilityJson; - @Expose - private String abilityJson; - - public MsgPlayerAbility(PlayerEntity player, Ability power, Ability.IData data) { - senderId = player.getUuid(); + public MsgPlayerAbility(Ability power, Ability.IData data) { powerIdentifier = power.getKeyName(); abilityJson = gson.toJson(data, power.getPackageType()); } - private void apply(Ability power, Channel channel) { - MinecraftServer server = channel.getServer(); - Pony player = Pony.of(server.getPlayerManager().getPlayer(senderId)); + public MsgPlayerAbility(PacketByteBuf buffer) { + powerIdentifier = buffer.readString(); + abilityJson = buffer.readString(); + } + + private void apply(Ability power, PacketContext context) { + Pony player = Pony.of(context.getPlayer()); if (player == null) { return; } @@ -48,7 +41,13 @@ public class MsgPlayerAbility implements Message, Message.Handler apply(power, channel)); + public void toBuffer(PacketByteBuf buffer) { + buffer.writeString(powerIdentifier); + buffer.writeString(abilityJson); + } + + @Override + public void handle(PacketContext context) { + Abilities.getInstance().getPowerFromName(powerIdentifier).ifPresent(power -> apply(power, context)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerCapabilities.java b/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerCapabilities.java index 15f0f48f..4c72f516 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerCapabilities.java +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgPlayerCapabilities.java @@ -1,77 +1,60 @@ package com.minelittlepony.unicopia.network; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; import java.io.IOException; -import java.util.UUID; - -import com.google.gson.annotations.Expose; -import com.minelittlepony.jumpingcastle.api.Channel; -import com.minelittlepony.jumpingcastle.api.Message; +import java.io.InputStream; +import java.io.OutputStream; import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.entity.player.Pony; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.ByteBufOutputStream; +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; +import net.minecraft.util.PacketByteBuf; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtIo; -public class MsgPlayerCapabilities implements Message, Message.Handler { - @Expose - Race newRace; +public class MsgPlayerCapabilities implements Channel.Packet { - @Expose - UUID senderId; + private final Race newRace; - @Expose - byte[] compoundTag; + private final CompoundTag compoundTag; + + public MsgPlayerCapabilities(PacketByteBuf buffer) { + newRace = Race.values()[buffer.readInt()]; + try (InputStream in = new ByteBufInputStream(buffer)) { + compoundTag = NbtIo.readCompressed(in); + } catch (IOException e) { + throw new RuntimeException(e); + } + } public MsgPlayerCapabilities(Race race, PlayerEntity player) { newRace = race; - senderId = player.getUuid(); - compoundTag = new byte[0]; + compoundTag = new CompoundTag(); } - public MsgPlayerCapabilities(Pony player) { + public MsgPlayerCapabilities(boolean full, Pony player) { newRace = player.getSpecies(); - senderId = player.getOwner().getUuid(); + compoundTag = full ? player.toNBT() : new CompoundTag(); + } - try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) { - CompoundTag nbt = player.toNBT(); - - NbtIo.write(nbt, new DataOutputStream(bytes)); - - compoundTag = bytes.toByteArray(); + @Override + public void toBuffer(PacketByteBuf buffer) { + buffer.writeInt(newRace.ordinal()); + try (OutputStream out = new ByteBufOutputStream(buffer)) { + NbtIo.writeCompressed(compoundTag, out); } catch (IOException e) { } } @Override - public void onPayload(MsgPlayerCapabilities message, Channel channel) { - - MinecraftServer server = channel.getServer(); - - PlayerEntity self = server.getPlayerManager().getPlayer(senderId); - - if (self == null) { - Unicopia.LOGGER.warn("[Unicopia] [CLIENT] [MsgPlayerCapabilities] Player with id %s was not found!\n", senderId.toString()); + public void handle(PacketContext context) { + Pony player = Pony.of(context.getPlayer()); + if (compoundTag.isEmpty()) { + player.setSpecies(newRace); } else { - Pony player = Pony.of(self); - - if (compoundTag.length > 0) { - try (ByteArrayInputStream input = new ByteArrayInputStream(compoundTag)) { - CompoundTag nbt = NbtIo.read(new DataInputStream(input)); - - player.fromNBT(nbt); - } catch (IOException e) { - - } - } else { - player.setSpecies(newRace); - } + player.fromNBT(compoundTag); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgRequestCapabilities.java b/src/main/java/com/minelittlepony/unicopia/network/MsgRequestCapabilities.java index b4d01a81..41efa53b 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/MsgRequestCapabilities.java +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgRequestCapabilities.java @@ -1,40 +1,38 @@ package com.minelittlepony.unicopia.network; -import java.util.UUID; - -import com.google.gson.annotations.Expose; -import com.minelittlepony.jumpingcastle.api.Channel; -import com.minelittlepony.jumpingcastle.api.Message; import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.entity.player.Pony; +import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.server.MinecraftServer; +import net.minecraft.util.PacketByteBuf; -public class MsgRequestCapabilities implements Message, Message.Handler { - @Expose - public UUID senderId; +public class MsgRequestCapabilities implements Channel.Packet { - @Expose - public Race race; + private final Race race; + + public MsgRequestCapabilities(PacketByteBuf buffer) { + race = Race.values()[buffer.readInt()]; + } public MsgRequestCapabilities(PlayerEntity player, Race preferredRace) { - senderId = player.getGameProfile().getId(); race = preferredRace; } @Override - public void onPayload(MsgRequestCapabilities message, Channel channel) { - MinecraftServer server = channel.getServer(); + public void toBuffer(PacketByteBuf buffer) { + buffer.writeInt(race.ordinal()); + } - Unicopia.LOGGER.warn("[Unicopia] [SERVER] [MsgRequestCapabilities] Sending capabilities to player %s\n", senderId.toString()); - Pony player = Pony.of(server.getPlayerManager().getPlayer(senderId)); + @Override + public void handle(PacketContext context) { + Pony player = Pony.of(context.getPlayer()); if (player.getSpecies().isDefault()) { - player.setSpecies(message.race); + player.setSpecies(race); } - channel.respond(new MsgPlayerCapabilities(player), senderId); + Channel.PLAYER_CAPABILITIES.send(context.getPlayer(), new MsgPlayerCapabilities(true, player)); } + } diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgSpawnRainbow.java b/src/main/java/com/minelittlepony/unicopia/network/MsgSpawnRainbow.java new file mode 100644 index 00000000..3843e8a5 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgSpawnRainbow.java @@ -0,0 +1,52 @@ +package com.minelittlepony.unicopia.network; + +import com.minelittlepony.unicopia.entity.RainbowEntity; +import com.minelittlepony.unicopia.entity.UEntities; +import net.fabricmc.fabric.api.network.PacketContext; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.Entity; +import net.minecraft.util.PacketByteBuf; + +public class MsgSpawnRainbow implements Channel.Packet { + + private final int id; + + private final double x; + private final double y; + private final double z; + + public MsgSpawnRainbow(Entity entity) { + id = entity.getEntityId(); + x = entity.getX(); + y = entity.getY(); + z = entity.getZ(); + } + + public MsgSpawnRainbow(PacketByteBuf buffer) { + id = buffer.readVarInt(); + x = buffer.readDouble(); + y = buffer.readDouble(); + z = buffer.readDouble(); + } + + @Override + public void toBuffer(PacketByteBuf buffer) { + buffer.writeVarInt(id); + buffer.writeDouble(x); + buffer.writeDouble(y); + buffer.writeDouble(z); + } + + @Override + public void handle(PacketContext context) { + MinecraftClient client = MinecraftClient.getInstance(); + + RainbowEntity entity = UEntities.RAINBOW.create(client.world); + entity.setPos(x, y, z); + entity.updateTrackedPosition(x, y, z); + entity.yaw = 0; + entity.pitch = 0; + entity.setEntityId(id); + client.world.addEntity(id, entity); + } +}