Properly fix concurrency problems with doing world stuff on the network thread

This commit is contained in:
Sollace 2020-05-29 18:10:45 +02:00
parent 5c01f45bdb
commit 6c73ccb028
2 changed files with 12 additions and 11 deletions

View file

@ -6,7 +6,6 @@ import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.minelittlepony.unicopia.AwaitTickQueue;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.TreeTraverser; import com.minelittlepony.unicopia.TreeTraverser;
import com.minelittlepony.unicopia.TreeType; import com.minelittlepony.unicopia.TreeType;
@ -102,7 +101,6 @@ public class EarthPonyStompAbility implements Ability<Multi> {
@Override @Override
public void apply(Pony iplayer, Multi data) { public void apply(Pony iplayer, Multi data) {
PlayerEntity player = iplayer.getOwner(); PlayerEntity player = iplayer.getOwner();
if (data.hitType == 0) { if (data.hitType == 0) {
@ -163,7 +161,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
if (harmed || player.world.random.nextInt(5) == 0) { if (harmed || player.world.random.nextInt(5) == 0) {
if (!harmed || player.world.random.nextInt(30) == 0) { if (!harmed || player.world.random.nextInt(30) == 0) {
AwaitTickQueue.enqueueTask(w -> TreeTraverser.removeTree(w, data.pos())); TreeTraverser.removeTree(player.world, data.pos());
} }
iplayer.subtractEnergyCost(3); iplayer.subtractEnergyCost(3);
@ -230,11 +228,9 @@ public class EarthPonyStompAbility implements Ability<Multi> {
dropApplesPart(capturedDrops, new ArrayList<BlockPos>(), w, log, pos, 0); dropApplesPart(capturedDrops, new ArrayList<BlockPos>(), w, log, pos, 0);
AwaitTickQueue.enqueueTask(wo -> { capturedDrops.forEach(item -> {
capturedDrops.forEach(item -> { item.setToDefaultPickupDelay();
item.setToDefaultPickupDelay(); w.spawnEntity(item);
wo.spawnEntity(item);
});
}); });
return capturedDrops.size() / 3; return capturedDrops.size() / 3;

View file

@ -25,7 +25,7 @@ public interface Channel {
static void bootstrap() { } static void bootstrap() { }
static <T extends Packet> SPacketType<T> clientToServer(Identifier id, Function<PacketByteBuf, T> factory) { static <T extends Packet> SPacketType<T> clientToServer(Identifier id, Function<PacketByteBuf, T> factory) {
ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handle(context)); ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handleOnMain(context));
return () -> id; return () -> id;
} }
@ -33,8 +33,9 @@ public interface Channel {
Identifier id = new Identifier(redirect.getId().getNamespace(), "broadcast_" + redirect.getId().getPath()); Identifier id = new Identifier(redirect.getId().getNamespace(), "broadcast_" + redirect.getId().getPath());
ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> { ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> {
PlayerEntity sender = context.getPlayer(); PlayerEntity sender = context.getPlayer();
T p = factory.apply(buffer); T p = factory.apply(buffer);
p.handle(context); p.handleOnMain(context);
sender.world.getPlayers().forEach(player -> { sender.world.getPlayers().forEach(player -> {
if (player != null) { if (player != null) {
redirect.send(player, p); redirect.send(player, p);
@ -45,7 +46,7 @@ public interface Channel {
} }
static <T extends Packet> CPacketType<T> serverToClient(Identifier id, Function<PacketByteBuf, T> factory) { static <T extends Packet> CPacketType<T> serverToClient(Identifier id, Function<PacketByteBuf, T> factory) {
ClientSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handle(context)); ClientSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handleOnMain(context));
return () -> id; return () -> id;
} }
@ -78,6 +79,10 @@ public interface Channel {
void toBuffer(PacketByteBuf buffer); void toBuffer(PacketByteBuf buffer);
default void handleOnMain(PacketContext context) {
context.getTaskQueue().execute(() -> handle(context));
}
default PacketByteBuf toBuffer() { default PacketByteBuf toBuffer() {
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
toBuffer(buf); toBuffer(buf);