mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-16 17:44:23 +01:00
Fixed pony skin data not being reliably sent to servers
# Conflicts: # src/main/java/com/minelittlepony/api/pony/network/fabric/Channel.java # src/main/java/com/minelittlepony/client/compat/hdskins/DummyPony.java # src/main/java/com/minelittlepony/client/mixin/MixinClientPlayerEntity.java # src/main/java/com/minelittlepony/client/render/EquineRenderManager.java
This commit is contained in:
parent
24e220bb29
commit
971f3623cf
7 changed files with 61 additions and 44 deletions
|
@ -0,0 +1,5 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
public interface PreviewModel {
|
||||
|
||||
}
|
|
@ -8,10 +8,13 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
|||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.network.MsgPonyData;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
|
||||
|
@ -19,13 +22,13 @@ import com.minelittlepony.client.MineLittlePony;
|
|||
public class Channel {
|
||||
private static final Identifier CLIENT_PONY_DATA = new Identifier("minelittlepony", "pony_data");
|
||||
private static final Identifier REQUEST_PONY_DATA = new Identifier("minelittlepony", "request_pony_data");
|
||||
private static final Logger LOGGER = LogManager.getLogger("MineLittlePony:Networking");
|
||||
|
||||
private static boolean registered;
|
||||
|
||||
public static void bootstrap() {
|
||||
ClientLoginConnectionEvents.INIT.register((handler, client) -> {
|
||||
registered = false;
|
||||
MineLittlePony.logger.info("Resetting registered flag");
|
||||
});
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
MineLittlePony.logger.info("Sending consent packet to " + handler.getPlayer().getName().getString());
|
||||
|
@ -34,12 +37,14 @@ public class Channel {
|
|||
});
|
||||
|
||||
ClientPlayNetworking.registerGlobalReceiver(REQUEST_PONY_DATA, (client, handler, ignored, sender) -> {
|
||||
registered = true;
|
||||
if (client.player != null) {
|
||||
IPony pony = IPony.getManager().getPony(client.player);
|
||||
registered = true;
|
||||
MineLittlePony.logger.info("Server has just consented");
|
||||
LOGGER.info("Server has just consented");
|
||||
|
||||
sender.sendPacket(CLIENT_PONY_DATA, new MsgPonyData(pony.metadata(), pony.defaulted()).toBuffer(PacketByteBufs.create()));
|
||||
} else {
|
||||
LOGGER.info("Server has just consented but the client player was not set");
|
||||
}
|
||||
});
|
||||
ServerPlayNetworking.registerGlobalReceiver(CLIENT_PONY_DATA, (server, player, ignore, buffer, ignore2) -> {
|
||||
|
@ -50,20 +55,19 @@ public class Channel {
|
|||
});
|
||||
}
|
||||
|
||||
public static void broadcastPonyData(MsgPonyData packet) {
|
||||
public static boolean broadcastPonyData(IPonyData packet, boolean noSkin) {
|
||||
if (FabricLoader.getInstance().getEnvironmentType() != EnvType.CLIENT) {
|
||||
throw new RuntimeException("Client packet send called by the server");
|
||||
}
|
||||
|
||||
if (!registered) {
|
||||
if (MinecraftClient.getInstance().isInSingleplayer() || MinecraftClient.getInstance().isIntegratedServerRunning()) {
|
||||
MineLittlePony.logger.info("Sending pony skin data over as we are either in single-player or lan");
|
||||
} else {
|
||||
MineLittlePony.logger.info("Skipping network packet as the server has not consented");
|
||||
return;
|
||||
}
|
||||
LOGGER.info("Skipping network packet as the server has not consented");
|
||||
return false;
|
||||
} else {
|
||||
LOGGER.info("Sending pony data to server for player");
|
||||
}
|
||||
|
||||
ClientPlayNetworking.send(CLIENT_PONY_DATA, packet.toBuffer(PacketByteBufs.create()));
|
||||
ClientPlayNetworking.send(CLIENT_PONY_DATA, new MsgPonyData(packet, noSkin).toBuffer(PacketByteBufs.create()));
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
public interface IPreviewModel {
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.client.hdskins;
|
|||
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
|
||||
import com.minelittlepony.api.model.PreviewModel;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyManager;
|
||||
import com.minelittlepony.client.IPreviewModel;
|
||||
|
@ -15,18 +16,13 @@ import java.util.UUID;
|
|||
/**
|
||||
* Dummy model used for the skin uploading screen.
|
||||
*/
|
||||
class DummyPony extends DummyPlayer implements IPreviewModel, IPonyManager.ForcedPony, EquineRenderManager.RegistrationHandler {
|
||||
class DummyPony extends DummyPlayer implements PreviewModel, IPonyManager.ForcedPony {
|
||||
|
||||
public DummyPony(ClientWorld world, PlayerSkins<?> textures) {
|
||||
super(world, textures);
|
||||
setUuid(UUID.randomUUID()); // uuid must be random so animations aren't linked between the two previews
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUpdateRegistration(IPony pony) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSubmergedInWater() {
|
||||
return getTextures().getPosture().getActiveSkinType() == MineLPHDSkins.seaponySkinType || super.isSubmergedInWater();
|
||||
|
|
|
@ -10,7 +10,6 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
@ -21,8 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implements EquineRenderManager.RegistrationHandler {
|
||||
public MixinClientPlayerEntity() { super(null, null); }
|
||||
|
||||
@Nullable
|
||||
private IPony pony;
|
||||
private final EquineRenderManager.SyncedPony syncedPony = new EquineRenderManager.SyncedPony();
|
||||
|
||||
@Inject(method = "startRiding(Lnet/minecraft/entity/Entity;Z)Z", at = @At("RETURN"))
|
||||
private void onStartRiding(Entity entity, boolean bl, CallbackInfoReturnable<Boolean> info) {
|
||||
|
@ -35,12 +33,8 @@ abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implem
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUpdateRegistration(IPony pony) {
|
||||
if (this.pony != pony && (this.pony == null || this.pony.metadata().compareTo(pony.metadata()) != 0)) {
|
||||
this.pony = Pony.snapshot(pony);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
public EquineRenderManager.SyncedPony getSyncedPony() {
|
||||
return syncedPony;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.minelittlepony.client.mixin;
|
||||
|
||||
import com.minelittlepony.api.model.PreviewModel;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.client.IPreviewModel;
|
||||
|
||||
|
@ -18,7 +19,7 @@ abstract class MixinEntityRenderDispatcher {
|
|||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/network/AbstractClientPlayerEntity;getModel()Ljava/lang/String;"))
|
||||
private String getPlayerModel(AbstractClientPlayerEntity player, Entity entity) {
|
||||
if (player instanceof IPreviewModel) {
|
||||
if (player instanceof PreviewModel) {
|
||||
return player.getModel();
|
||||
}
|
||||
return IPony.getManager()
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.RenderPass;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.network.MsgPonyData;
|
||||
import com.minelittlepony.api.pony.network.fabric.Channel;
|
||||
import com.minelittlepony.api.pony.network.fabric.PonyDataCallback;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
|
@ -26,6 +24,8 @@ import net.minecraft.entity.LivingEntity;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> {
|
||||
|
||||
private ModelWrapper<T, M> playerModel;
|
||||
|
@ -127,16 +127,31 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
pony = renderer.getEntityPony(entity);
|
||||
playerModel.applyMetadata(pony.metadata());
|
||||
|
||||
if (pony.hasMetadata() && entity instanceof RegistrationHandler && ((RegistrationHandler)entity).shouldUpdateRegistration(pony)) {
|
||||
entity.calculateDimensions();
|
||||
if (entity instanceof PlayerEntity player && entity instanceof RegistrationHandler handler) {
|
||||
SyncedPony synced = handler.getSyncedPony();
|
||||
boolean changed = pony.compareTo(synced.lastRenderedPony) != 0;
|
||||
|
||||
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
||||
if (clientPlayer != null) {
|
||||
if (Objects.equals(entity, clientPlayer) || Objects.equals(((PlayerEntity)entity).getGameProfile(), clientPlayer.getGameProfile())) {
|
||||
Channel.broadcastPonyData(new MsgPonyData(pony.metadata(), pony.defaulted()));
|
||||
if (changed) {
|
||||
synced.lastRenderedPony = pony;
|
||||
player.calculateDimensions();
|
||||
}
|
||||
|
||||
if (!(player instanceof PreviewModel)) {
|
||||
@Nullable
|
||||
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
||||
|
||||
if (pony.compareTo(synced.lastTransmittedPony) != 0) {
|
||||
if (clientPlayer != null && (Objects.equals(player, clientPlayer) || Objects.equals(player.getGameProfile(), clientPlayer.getGameProfile()))) {
|
||||
if (Channel.broadcastPonyData(pony.metadata(), pony.defaulted())) {
|
||||
synced.lastTransmittedPony = pony;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable(player, pony.metadata(), pony.defaulted(), EnvType.CLIENT);
|
||||
}
|
||||
}
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable((PlayerEntity)entity, pony.metadata(), pony.defaulted(), EnvType.CLIENT);
|
||||
}
|
||||
|
||||
getModel().updateLivingState(entity, pony, mode);
|
||||
|
@ -184,6 +199,13 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
}
|
||||
|
||||
public interface RegistrationHandler {
|
||||
boolean shouldUpdateRegistration(IPony pony);
|
||||
SyncedPony getSyncedPony();
|
||||
}
|
||||
|
||||
public static class SyncedPony {
|
||||
@Nullable
|
||||
private IPony lastRenderedPony;
|
||||
@Nullable
|
||||
private IPony lastTransmittedPony;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue