Fixed server crashes

This commit is contained in:
Sollace 2021-08-13 14:46:54 +02:00
parent c62e872a66
commit 5557e67a05
13 changed files with 152 additions and 60 deletions

View file

@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.entity.player.dummy.DummyPlayerEntity; import com.minelittlepony.unicopia.entity.player.dummy.DummyPlayerEntity;
import com.minelittlepony.unicopia.entity.player.dummy.DummyServerPlayerEntity; import com.minelittlepony.unicopia.entity.player.dummy.DummyServerPlayerEntity;
import com.minelittlepony.unicopia.network.handler.ClientNetworkHandler;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -12,12 +13,31 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
public class InteractionManager { public class InteractionManager {
public static final int SOUND_EARS_RINGING = 0;
public static final int SOUND_CHANGELING_BUZZ = 1;
public static final int SOUND_BEE = 2;
public static final int SOUND_MINECART = 3;
public static InteractionManager INSTANCE = new InteractionManager(); public static InteractionManager INSTANCE = new InteractionManager();
public static InteractionManager instance() { public static InteractionManager instance() {
return INSTANCE; return INSTANCE;
} }
/**
* Returns the client network handler, or throws if called on the server.
*/
public ClientNetworkHandler getClientNetworkHandler() {
throw new NullPointerException("Client network handler called by the server");
}
/**
* Plays a custom sound instance
*/
public void playLoopingSound(Entity source, int type) {
}
/** /**
* Returns true on the client if the passed in player entity is the client's player. * Returns true on the client if the passed in player entity is the client's player.
* Always returns false on the server. * Always returns false on the server.

View file

@ -4,16 +4,55 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.client.sound.LoopingSoundInstance;
import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.entity.player.dummy.DummyClientPlayerEntity; import com.minelittlepony.unicopia.entity.player.dummy.DummyClientPlayerEntity;
import com.minelittlepony.unicopia.network.handler.ClientNetworkHandler;
import com.minelittlepony.unicopia.network.handler.ClientNetworkHandlerImpl;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.sound.AggressiveBeeSoundInstance;
import net.minecraft.client.sound.MovingMinecartSoundInstance;
import net.minecraft.client.sound.PassiveBeeSoundInstance;
import net.minecraft.client.sound.SoundManager;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.passive.BeeEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
public class ClientInteractionManager extends InteractionManager { public class ClientInteractionManager extends InteractionManager {
private final ClientNetworkHandler handler = new ClientNetworkHandlerImpl();
private final MinecraftClient client = MinecraftClient.getInstance();
@Override
@Nullable
public ClientNetworkHandler getClientNetworkHandler() {
return handler;
}
@Override
public void playLoopingSound(Entity source, int type) {
SoundManager soundManager = client.getSoundManager();
if (type == SOUND_EARS_RINGING && source instanceof LivingEntity) {
soundManager.play(new LoopingSoundInstance<>((LivingEntity)source, e -> e.hasStatusEffect(SunBlindnessStatusEffect.INSTANCE), USounds.ENTITY_PLAYER_EARS_RINGING, 1F, 1F));
} else if (type == SOUND_BEE && source instanceof BeeEntity) {
soundManager.playNextTick(
((BeeEntity)source).hasAngerTime()
? new AggressiveBeeSoundInstance(((BeeEntity)source))
: new PassiveBeeSoundInstance(((BeeEntity)source))
);
} else if (type == SOUND_MINECART && source instanceof AbstractMinecartEntity) {
soundManager.play(new MovingMinecartSoundInstance((AbstractMinecartEntity)source));
}
}
@Override @Override
@NotNull @NotNull
public PlayerEntity createPlayer(Entity observer, GameProfile profile) { public PlayerEntity createPlayer(Entity observer, GameProfile profile) {
@ -25,13 +64,13 @@ public class ClientInteractionManager extends InteractionManager {
@Override @Override
public boolean isClientPlayer(@Nullable PlayerEntity player) { public boolean isClientPlayer(@Nullable PlayerEntity player) {
return (MinecraftClient.getInstance().player != null && player != null) return (client.player != null && player != null)
&& (MinecraftClient.getInstance().player == player && (client.player == player
|| Pony.equal(MinecraftClient.getInstance().player, player)); || Pony.equal(client.player, player));
} }
@Override @Override
public int getViewMode() { public int getViewMode() {
return MinecraftClient.getInstance().options.getPerspective().ordinal(); return client.options.getPerspective().ordinal();
} }
} }

View file

@ -1,11 +1,9 @@
package com.minelittlepony.unicopia.entity.behaviour; package com.minelittlepony.unicopia.entity.behaviour;
import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.sound.AggressiveBeeSoundInstance;
import net.minecraft.client.sound.PassiveBeeSoundInstance;
import net.minecraft.entity.passive.BeeEntity; import net.minecraft.entity.passive.BeeEntity;
public class BeeBehaviour extends EntityBehaviour<BeeEntity> { public class BeeBehaviour extends EntityBehaviour<BeeEntity> {
@ -13,16 +11,13 @@ public class BeeBehaviour extends EntityBehaviour<BeeEntity> {
public BeeEntity onCreate(BeeEntity entity, Disguise context, boolean replaceOld) { public BeeEntity onCreate(BeeEntity entity, Disguise context, boolean replaceOld) {
super.onCreate(entity, context, replaceOld); super.onCreate(entity, context, replaceOld);
if (replaceOld && entity.world.isClient) { if (replaceOld && entity.world.isClient) {
MinecraftClient.getInstance().getSoundManager().playNextTick( InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_BEE);
entity.hasAngerTime() ? new AggressiveBeeSoundInstance(entity) : new PassiveBeeSoundInstance(entity)
);
} }
return entity; return entity;
} }
@Override @Override
public void update(Caster<?> source, BeeEntity entity, DisguiseSpell spell) { public void update(Caster<?> source, BeeEntity entity, DisguiseSpell spell) {
if (source.getMaster().isSneaking()) { if (source.getMaster().isSneaking()) {
entity.setAngerTime(10); entity.setAngerTime(10);
} else { } else {

View file

@ -1,10 +1,9 @@
package com.minelittlepony.unicopia.entity.behaviour; package com.minelittlepony.unicopia.entity.behaviour;
import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.sound.MovingMinecartSoundInstance;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity; import net.minecraft.entity.vehicle.AbstractMinecartEntity;
@ -14,7 +13,7 @@ public class MinecartBehaviour extends EntityBehaviour<AbstractMinecartEntity> {
public AbstractMinecartEntity onCreate(AbstractMinecartEntity entity, Disguise context, boolean replaceOld) { public AbstractMinecartEntity onCreate(AbstractMinecartEntity entity, Disguise context, boolean replaceOld) {
super.onCreate(entity, context, replaceOld); super.onCreate(entity, context, replaceOld);
if (replaceOld && entity.world.isClient) { if (replaceOld && entity.world.isClient) {
MinecraftClient.getInstance().getSoundManager().play(new MovingMinecartSoundInstance(entity)); InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_MINECART);
} }
return entity; return entity;
} }

View file

@ -9,10 +9,8 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.client.UnicopiaClient; import com.minelittlepony.unicopia.client.UnicopiaClient;
import com.minelittlepony.unicopia.client.sound.LoopingSoundInstance;
import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.UTags;
import com.minelittlepony.unicopia.WorldTribeManager; import com.minelittlepony.unicopia.WorldTribeManager;
import com.minelittlepony.unicopia.ability.AbilityDispatcher; import com.minelittlepony.unicopia.ability.AbilityDispatcher;
@ -297,8 +295,8 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
entity.addStatusEffect(new StatusEffectInstance(SunBlindnessStatusEffect.INSTANCE, SunBlindnessStatusEffect.MAX_DURATION * 10, 1, true, false)); entity.addStatusEffect(new StatusEffectInstance(SunBlindnessStatusEffect.INSTANCE, SunBlindnessStatusEffect.MAX_DURATION * 10, 1, true, false));
UCriteria.LOOK_INTO_SUN.trigger(entity); UCriteria.LOOK_INTO_SUN.trigger(entity);
if (isClient()) { if (isClientPlayer()) {
MinecraftClient.getInstance().getSoundManager().play(new LoopingSoundInstance<>(entity, e -> e.hasStatusEffect(SunBlindnessStatusEffect.INSTANCE), USounds.ENTITY_PLAYER_EARS_RINGING, 1F, 1F)); InteractionManager.instance().playLoopingSound(entity, InteractionManager.SOUND_EARS_RINGING);
} }
} }
} else if (ticksInSun > 0) { } else if (ticksInSun > 0) {

View file

@ -23,8 +23,6 @@ public class GemFindingEnchantment extends SimpleEnchantment {
BlockPos origin = user.getOrigin(); BlockPos origin = user.getOrigin();
double volume = BlockPos.findClosest(origin, radius, radius, pos -> user.getWorld().getBlockState(pos).isIn(UTags.INTERESTING)) double volume = BlockPos.findClosest(origin, radius, radius, pos -> user.getWorld().getBlockState(pos).isIn(UTags.INTERESTING))
.map(p -> user.getOriginVector().squaredDistanceTo(p.getX(), p.getY(), p.getZ())) .map(p -> user.getOriginVector().squaredDistanceTo(p.getX(), p.getY(), p.getZ()))
.map(find -> (1 - (Math.sqrt(find) / radius))) .map(find -> (1 - (Math.sqrt(find) / radius)))

View file

@ -1,12 +1,11 @@
package com.minelittlepony.unicopia.network; package com.minelittlepony.unicopia.network;
import com.minelittlepony.unicopia.client.ClientBlockDestructionManager; import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.util.network.Packet; import com.minelittlepony.unicopia.util.network.Packet;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
/** /**
@ -28,6 +27,10 @@ public class MsgBlockDestruction implements Packet<PlayerEntity> {
this.destructions = destructions; this.destructions = destructions;
} }
public Long2ObjectMap<Integer> getDestructions() {
return destructions;
}
@Override @Override
public void toBuffer(PacketByteBuf buffer) { public void toBuffer(PacketByteBuf buffer) {
buffer.writeInt(destructions.size()); buffer.writeInt(destructions.size());
@ -39,11 +42,6 @@ public class MsgBlockDestruction implements Packet<PlayerEntity> {
@Override @Override
public void handle(PlayerEntity sender) { public void handle(PlayerEntity sender) {
ClientBlockDestructionManager destr = ((ClientBlockDestructionManager.Source)MinecraftClient.getInstance().worldRenderer).getDestructionManager(); InteractionManager.instance().getClientNetworkHandler().handleBlockDestruction(this);
destructions.forEach((i, d) -> {
destr.setBlockDestruction(i, d);
});
} }
} }

View file

@ -13,7 +13,6 @@ public class MsgOtherPlayerCapabilities extends MsgPlayerCapabilities {
MsgOtherPlayerCapabilities(PacketByteBuf buffer) { MsgOtherPlayerCapabilities(PacketByteBuf buffer) {
super(buffer); super(buffer);
} }
public MsgOtherPlayerCapabilities(boolean full, Pony player) { public MsgOtherPlayerCapabilities(boolean full, Pony player) {

View file

@ -1,13 +1,11 @@
package com.minelittlepony.unicopia.network; package com.minelittlepony.unicopia.network;
import java.util.Optional; import java.util.Optional;
import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.Owned;
import com.minelittlepony.unicopia.util.network.Packet; import com.minelittlepony.unicopia.util.network.Packet;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
@ -35,29 +33,6 @@ public class MsgSpawnProjectile extends EntitySpawnS2CPacket implements Packet<P
@Override @Override
public void handle(PlayerEntity sender) { public void handle(PlayerEntity sender) {
if (sender.world.isClient) { InteractionManager.instance().getClientNetworkHandler().handleSpawnProjectile(this);
handledByClient(sender);
}
}
@Environment(EnvType.CLIENT)
@SuppressWarnings("unchecked")
private void handledByClient(PlayerEntity sender) {
ClientWorld world = MinecraftClient.getInstance().world;
Entity entity = getEntityTypeId().create(world);
entity.updateTrackedPosition(getX(), getY(), getZ());
entity.refreshPositionAfterTeleport(getX(), getY(), getZ());
entity.setVelocity(getVelocityX(), getVelocityY(), getVelocityZ());
entity.setPitch(getPitch() * 360 / 256F);
entity.setYaw(getYaw() * 360 / 256F);
entity.setId(getId());
entity.setUuid(getUuid());
if (entity instanceof Owned) {
((Owned<Entity>) entity).setMaster(world.getEntityById(getEntityData()));
}
world.addEntity(getId(), entity);
} }
} }

View file

@ -4,11 +4,10 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.client.gui.TribeSelectionScreen;
import com.minelittlepony.unicopia.util.network.Packet; import com.minelittlepony.unicopia.util.network.Packet;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
@ -27,6 +26,10 @@ public class MsgTribeSelect implements Packet<PlayerEntity> {
} }
} }
public Set<Race> getRaces() {
return availableRaces;
}
@Override @Override
public void toBuffer(PacketByteBuf buffer) { public void toBuffer(PacketByteBuf buffer) {
buffer.writeInt(availableRaces.size()); buffer.writeInt(availableRaces.size());
@ -35,6 +38,6 @@ public class MsgTribeSelect implements Packet<PlayerEntity> {
@Override @Override
public void handle(PlayerEntity sender) { public void handle(PlayerEntity sender) {
MinecraftClient.getInstance().openScreen(new TribeSelectionScreen(availableRaces)); InteractionManager.instance().getClientNetworkHandler().handleTribeScreen(this);
} }
} }

View file

@ -0,0 +1,14 @@
package com.minelittlepony.unicopia.network.handler;
import com.minelittlepony.unicopia.network.MsgBlockDestruction;
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
import com.minelittlepony.unicopia.network.MsgTribeSelect;
public interface ClientNetworkHandler {
void handleTribeScreen(MsgTribeSelect packet);
void handleSpawnProjectile(MsgSpawnProjectile packet);
void handleBlockDestruction(MsgBlockDestruction packet);
}

View file

@ -0,0 +1,53 @@
package com.minelittlepony.unicopia.network.handler;
import com.minelittlepony.unicopia.Owned;
import com.minelittlepony.unicopia.client.ClientBlockDestructionManager;
import com.minelittlepony.unicopia.client.gui.TribeSelectionScreen;
import com.minelittlepony.unicopia.network.MsgBlockDestruction;
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
import com.minelittlepony.unicopia.network.MsgTribeSelect;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
public class ClientNetworkHandlerImpl implements ClientNetworkHandler {
private final MinecraftClient client = MinecraftClient.getInstance();
@Override
public void handleTribeScreen(MsgTribeSelect packet) {
client.openScreen(new TribeSelectionScreen(packet.getRaces()));
}
@SuppressWarnings("unchecked")
@Override
public void handleSpawnProjectile(MsgSpawnProjectile packet) {
ClientWorld world = client.world;
Entity entity = packet.getEntityTypeId().create(world);
entity.updateTrackedPosition(packet.getX(), packet.getY(), packet.getZ());
entity.refreshPositionAfterTeleport(packet.getX(), packet.getY(), packet.getZ());
entity.setVelocity(packet.getVelocityX(), packet.getVelocityY(), packet.getVelocityZ());
entity.setPitch(packet.getPitch() * 360 / 256F);
entity.setYaw(packet.getYaw() * 360 / 256F);
entity.setId(packet.getId());
entity.setUuid(packet.getUuid());
if (entity instanceof Owned) {
((Owned<Entity>) entity).setMaster(world.getEntityById(packet.getEntityData()));
}
world.addEntity(packet.getId(), entity);
}
@Override
public void handleBlockDestruction(MsgBlockDestruction packet) {
ClientBlockDestructionManager destr = ((ClientBlockDestructionManager.Source)client.worldRenderer).getDestructionManager();
packet.getDestructions().forEach((i, d) -> {
destr.setBlockDestruction(i, d);
});
}
}

View file

@ -18,6 +18,7 @@ import net.minecraft.text.TranslatableText;
public class MagicalDamageSource extends EntityDamageSource { public class MagicalDamageSource extends EntityDamageSource {
public static final DamageSource EXHAUSTION = new MagicalDamageSource("magical_exhaustion", null, true, true); public static final DamageSource EXHAUSTION = new MagicalDamageSource("magical_exhaustion", null, true, true);
public static final DamageSource ALICORN_AMULET = new MagicalDamageSource("alicorn_amulet", null, true, true);
public static final DamageSource FOOD_POISONING = mundane("food_poisoning"); public static final DamageSource FOOD_POISONING = mundane("food_poisoning");
public static final DamageSource TRIBE_SWAP = mundane("tribe_swap"); public static final DamageSource TRIBE_SWAP = mundane("tribe_swap");
public static final DamageSource ZAP_APPLE = create("zap"); public static final DamageSource ZAP_APPLE = create("zap");