下面列出了怎么用net.minecraft.util.IThreadListener的API类实例代码及写法,或者点击链接到github查看源代码。
@SubscribeEvent
@SideOnly(Side.CLIENT)
@SuppressWarnings("unchecked")
public void onClientPacket(FMLNetworkEvent.ClientCustomPacketEvent event) {
Packet packet = proxy2packet(event.getPacket());
if (clientExecutors.containsKey(packet.getClass())) {
PacketExecutor<Packet, NetHandlerPlayClient> executor = (PacketExecutor<Packet, NetHandlerPlayClient>) clientExecutors.get(packet.getClass());
NetHandlerPlayClient handler = (NetHandlerPlayClient) event.getHandler();
IThreadListener threadListener = FMLCommonHandler.instance().getWorldThread(handler);
if(threadListener.isCallingFromMinecraftThread()) {
executor.execute(packet, handler);
} else {
threadListener.addScheduledTask(() -> executor.execute(packet, handler));
}
}
}
@Override
public IMessage onMessage(MessagePlayerStoppedPiloting message, MessageContext ctx) {
IThreadListener mainThread = ctx.getServerHandler().server;
mainThread.addScheduledTask(() -> {
BlockPos pos = message.posToStopPiloting;
EntityPlayerMP player = ctx.getServerHandler().player;
TileEntity tileEntity = player.world.getTileEntity(pos);
if (tileEntity instanceof ITileEntityPilotable) {
((ITileEntityPilotable) tileEntity).playerWantsToStopPiloting(player);
}
}
);
return null;
}
@Override
public IMessage onMessage(final PilotControlsMessage message, final MessageContext ctx) {
IThreadListener mainThread = ctx.getServerHandler().server;
mainThread.addScheduledTask(new Runnable() {
@Override
public void run() {
World worldObj = ctx.getServerHandler().player.world;
if (ValkyrienSkiesMod.VS_PHYSICS_MANAGER.getManagerForWorld(worldObj) != null) {
// UUID shipId = message.shipFor;
BlockPos posFor = message.controlBlockPos;
TileEntity tile = worldObj.getTileEntity(posFor);
if (tile instanceof ITileEntityPilotable) {
((ITileEntityPilotable) tile)
.onPilotControlsMessage(message, ctx.getServerHandler().player);
}
}
}
});
return null;
}
@Override
public IMessage onMessage(final WrapperPositionMessage message, MessageContext ctx) {
if (Minecraft.getMinecraft().player == null) {
return null;
}
IThreadListener mainThread = Minecraft.getMinecraft();
mainThread.addScheduledTask(new Runnable() {
@Override
public void run() {
if (Minecraft.getMinecraft().world != null) {
Entity ent = Minecraft.getMinecraft().world
.getEntityByID(message.getEntityID());
if (ent instanceof PhysicsWrapperEntity) {
PhysicsWrapperEntity wrapper = (PhysicsWrapperEntity) ent;
wrapper.getPhysicsObject().getShipTransformationManager().serverBuffer
.pushMessage(message);
}
}
}
});
return null;
}
@Override
public IMessage onMessage(VSGuiButtonMessage message, MessageContext ctx) {
IThreadListener mainThread = ctx.getServerHandler().server;
mainThread.addScheduledTask(() -> {
World playerWorld = ctx.getServerHandler().player.world;
TileEntity tileEntity = playerWorld.getTileEntity(message.getTileEntityPos());
if (tileEntity == null) {
// Nothing there, ignore this message
return;
}
int buttonId = message.getButtonId();
// Tell the tile entity that this player tried pressing the given button.
if (tileEntity instanceof IVSTileGui) {
((IVSTileGui) tileEntity).onButtonPress(buttonId, ctx.getServerHandler().player);
}
});
return null;
}
@Override
public InventoryChangeMessage onMessage(final InventoryMessage message, MessageContext ctx)
{
final EntityPlayerMP player = ctx.getServerHandler().playerEntity;
IThreadListener mainThread = (WorldServer)ctx.getServerHandler().playerEntity.world;
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
ItemStack[] changes = null;
if (message.combine)
changes = combineSlots(player, message.invA, message.slotA, message.invB, message.slotB, message.containerPos);
else
changes = swapSlots(player, message.invA, message.slotA, message.invB, message.slotB, message.containerPos);
if (changes != null)
MalmoMod.network.sendTo(new InventoryChangeMessage(changes[0], changes[1]), player);
}
});
return null;
}
/** IMPORTANT: Call this from the onMessage method in the subclass. */
public IMessage processMessage(ObservationRequestMessage message, MessageContext ctx)
{
IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.world;
final EntityPlayerMP player = ctx.getServerHandler().playerEntity;
final ObservationRequestMessage mess = message;
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
JsonObject json = new JsonObject();
buildJson(json, player, mess);
// Send this message back again now we've filled in the json stats.
Map<String, String> returnData = new HashMap<String, String>();
returnData.put("json", json.toString());
mess.addReturnData(returnData);
MalmoMod.network.sendTo(new MalmoMod.MalmoMessage(MalmoMessageType.SERVER_OBSERVATIONSREADY, mess.id, returnData), player);
}
});
return null; // no response in this case
}
@Override
public IMessage onMessage(final PacketMythicSound message, final MessageContext ctx)
{
IThreadListener mainThread = Minecraft.getMinecraft();
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
EntityPlayer player = Minecraft.getMinecraft().player;
player.playSound(SoundEvents.ENTITY_ENDERDRAGON_DEATH, 1.0F, 1.0F);
}
});
return null;
}
@Override
public IMessage onMessage(final CAnvilStrikePacket message, MessageContext ctx) {
IThreadListener mainThread = net.minecraft.client.Minecraft.getMinecraft(); //(WorldServer) ctx.getServerHandler().playerentityIn.world; // or Minecraft.getMinecraft() on the client
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
TileEntity te = net.minecraft.client.Minecraft.getMinecraft().world.getTileEntity(message.pos);
if(te != null)
{
TileAnvil anvil = (TileAnvil)te;
anvil.setStrikePoint(message.strikeIndex, message.strikePoint);
}
}
});
return null; // no response in this case
}
@Override
public IMessage onMessage(final CFoodPacket message, MessageContext ctx) {
IThreadListener mainThread = net.minecraft.client.Minecraft.getMinecraft(); //(WorldServer) ctx.getServerHandler().playerentityIn.world; // or Minecraft.getMinecraft() on the client
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
IFoodStatsTFC stats = (IFoodStatsTFC)net.minecraft.client.Minecraft.getMinecraft().player.getFoodStats();
stats.getNutritionMap().put(EnumFoodGroup.Fruit, message.nutritionFruit);
stats.getNutritionMap().put(EnumFoodGroup.Vegetable, message.nutritionVeg);
stats.getNutritionMap().put(EnumFoodGroup.Grain, message.nutritionGrain);
stats.getNutritionMap().put(EnumFoodGroup.Protein, message.nutritionProtein);
stats.getNutritionMap().put(EnumFoodGroup.Dairy, message.nutritionDairy);
stats.setWaterLevel(message.waterLevel);
}
});
return null; // no response in this case
}
@Override
public IMessage onMessage(final CMapPacket message, MessageContext ctx) {
IThreadListener mainThread = net.minecraft.client.Minecraft.getMinecraft(); //(WorldServer) ctx.getServerHandler().playerentityIn.world; // or Minecraft.getMinecraft() on the client
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
if(WorldGen.getInstance().worldSeed == Long.MIN_VALUE)
{
WorldGen.getInstance().worldSeed = message.seed - Helper.combineCoords(message.islandX, message.islandZ);
ClientRenderHandler.IsGeneratingFirstIsland = true;
}
//WorldGen.getInstance().createIsland(message.islandX, message.islandZ, message.seed, true);
WorldGen.getInstance().forceBuildIsland(message.islandX, message.islandZ, message.seed);
}
});
return null; // no response in this case
}
@Override
public IMessage onMessage(final SMapRequestPacket message, final MessageContext ctx) {
IThreadListener mainThread = (WorldServer) ctx.getServerHandler().player.world; // or Minecraft.getMinecraft() on the client
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
int j;
IslandMap map = WorldGen.getInstance().getIslandMap(message.islandX, message.islandZ);
long seed = ctx.getServerHandler().player.world.getSeed()+Helper.combineCoords(message.islandX, message.islandZ);
TFC.network.sendTo(new CMapPacket(message.islandX, message.islandZ, seed), ctx.getServerHandler().player);
}
});
return null; // no response in this case
}
@Override
public IMessage onMessage(final SKnappingPacket message, final MessageContext ctx) {
IThreadListener mainThread = (WorldServer) ctx.getServerHandler().player.world; // or Minecraft.getMinecraft() on the client
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
PlayerInfo pi = PlayerManagerTFC.getInstance().getPlayerInfoFromUUID(ctx.getServerHandler().player.getUniqueID());
pi.knappingInterface[message.id] = true;
if(ctx.getServerHandler().player.openContainer != null && ctx.getServerHandler().player.openContainer instanceof ContainerSpecialCrafting)
{
if(pi.specialCraftingTypeAlternate == null)
((ContainerSpecialCrafting)ctx.getServerHandler().player.openContainer).craftMatrix.setInventorySlotContents(message.id, ItemStack.EMPTY);
else
((ContainerSpecialCrafting)ctx.getServerHandler().player.openContainer).craftMatrix.setInventorySlotContents(message.id, pi.specialCraftingTypeAlternate);
}
}
});
return null; // no response in this case
}
@Override
public IMessage onMessage(final SAnvilCraftingPacket message, final MessageContext ctx) {
final IThreadListener mainThread = (WorldServer) ctx.getServerHandler().player.world; // or Minecraft.getMinecraft() on the client
mainThread.addScheduledTask(new Runnable()
{
@Override
public void run()
{
TileEntity te = ((WorldServer)mainThread).getTileEntity(message.pos);
if(te != null && te instanceof TileAnvil)
{
((TileAnvil)te).setAnvilRecipeIndex(message.recipe);
if(message.startedCrafting)
{
((TileAnvil)te).startCrafting(message.smithID);
}
}
}
});
return null; // no response in this case
}
@SubscribeEvent
@SuppressWarnings("unchecked")
public void onServerPacket(FMLNetworkEvent.ServerCustomPacketEvent event) {
Packet packet = proxy2packet(event.getPacket());
if (serverExecutors.containsKey(packet.getClass())) {
PacketExecutor<Packet, NetHandlerPlayServer> executor = (PacketExecutor<Packet, NetHandlerPlayServer>) serverExecutors.get(packet.getClass());
NetHandlerPlayServer handler = (NetHandlerPlayServer) event.getHandler();
IThreadListener threadListener = FMLCommonHandler.instance().getWorldThread(handler);
if(threadListener.isCallingFromMinecraftThread()) {
executor.execute(packet, handler);
} else {
threadListener.addScheduledTask(() -> executor.execute(packet, handler));
}
}
}
@Override
@Nullable
public IMessage onMessage(final T message, final MessageContext context) {
final IThreadListener thread = FMLCommonHandler.instance().getWorldThread(context.netHandler);
if (thread.isCallingFromMinecraftThread()) {
onMessageSynchronized(message, context);
} else {
thread.addScheduledTask(() -> onMessageSynchronized(message, context));
}
return null;
}
@Override
public IMessage onMessage(final MessageProcessorUpdate message, MessageContext ctx) {
if (message.processorData == null || message.processorData == null) {
return null;
}
IThreadListener mainThread = Minecraft.getMinecraft();
mainThread.addScheduledTask(new Runnable() {
@Override
public void run() {
if (GuiMinecoprocessor.INSTANCE == null) {
return;
}
if (!GuiMinecoprocessor.INSTANCE.getPos().equals(message.pos)) {
Minecoprocessors.NETWORK.sendToServer(new MessageEnableGuiUpdates(message.pos, false));
return;
}
GuiMinecoprocessor.INSTANCE.updateData(message.processorData, message.name);
}
});
return null;
}
public static <T extends IMessage> boolean checkThreadAndEnqueue(final T message, final IMessageHandler<T, IMessage> handler, final MessageContext ctx, IThreadListener listener)
{
if (!listener.isCallingFromMinecraftThread())
{
listener.addScheduledTask(() -> handler.onMessage(message, ctx));
return true;
}
return false;
}
@Override
public IMessage onMessage(MessageStopPiloting message, MessageContext ctx) {
IThreadListener mainThread = Minecraft.getMinecraft();
mainThread.addScheduledTask(() -> {
IShipPilotClient pilot = (IShipPilotClient) Minecraft.getMinecraft().player;
BlockPos posToStopPiloting = message.posToStopPiloting;
if (pilot.getPosBeingControlled() != null && pilot.getPosBeingControlled()
.equals(posToStopPiloting)) {
pilot.stopPilotingEverything();
}
});
return null;
}
@Override
@SideOnly(Side.CLIENT)
public IMessage onMessage(MessageStartPiloting message, MessageContext ctx) {
IThreadListener mainThread = Minecraft.getMinecraft();
mainThread.addScheduledTask(() -> {
IShipPilotClient pilot = (IShipPilotClient) Minecraft.getMinecraft().player;
pilot.setPosBeingControlled(message.posToStartPiloting);
pilot.setControllerInputEnum(message.controlType);
if (message.setPhysicsWrapperEntityToPilot) {
Optional<PhysicsObject> physicsObject = ValkyrienUtils
.getPhysicsObject(Minecraft.getMinecraft().world, message.posToStartPiloting);
if (physicsObject.isPresent()) {
pilot.setPilotedShip(physicsObject.get()
.getWrapperEntity());
} else {
new IllegalStateException("Received incorrect piloting message!")
.printStackTrace();
}
} else {
pilot.setPilotedShip(null);
}
});
return null;
}
@Override
public IMessage onMessage(final SubspacedEntityRecordMessage message,
final MessageContext ctx) {
IThreadListener threadScheduler = null;
World world = null;
if (ctx.side.isClient()) {
// We are receiving this on the client
threadScheduler = getClientThreadListener();
world = getClientWorld();
} else {
// Otherwise we are receiving this on the server
threadScheduler = ctx.getServerHandler().server;
world = ctx.getServerHandler().player.world;
}
final World worldFinal = world;
threadScheduler.addScheduledTask(() -> {
Entity physicsEntity = worldFinal.getEntityByID(message.physicsObjectWrapperID);
Entity subspacedEntity = worldFinal.getEntityByID(message.entitySubspacedID);
if (physicsEntity != null && subspacedEntity != null) {
PhysicsWrapperEntity wrapperEntity = (PhysicsWrapperEntity) physicsEntity;
ISubspacedEntityRecord record = message.createRecordForThisMessage(
(ISubspacedEntity) subspacedEntity, wrapperEntity.getPhysicsObject()
.getSubspace());
IDraggable draggable = (IDraggable) subspacedEntity;
draggable.setForcedRelativeSubspace(wrapperEntity);
wrapperEntity.getPhysicsObject().getSubspace()
.forceSubspaceRecord(record.getParentEntity(), record);
// Now just synchronize the player to the data sent by the client.
} else {
System.err.println("An incorrect SubspacedEntityRecordMessage has been thrown out");
}
});
return null;
}
/**
* Generates the new chunks
*/
public TickSyncCompletableFuture<Void> assembleShipAsOrderedByPlayer(EntityPlayer player) {
if (world().isRemote) {
throw new IllegalStateException("This method cannot be invoked on client side!");
}
if (!(world() instanceof WorldServer)) {
throw new IllegalStateException("The world " + world() + " wasn't an instance of WorldServer");
}
BlockPos centerInWorld = new BlockPos(getWrapperEntity().posX,
getWrapperEntity().posY, getWrapperEntity().posZ);
// The thread the tick sync will execute on.
IThreadListener worldServerThread = (WorldServer) world();
return TickSyncCompletableFuture
.supplyAsync(() -> DetectorManager.getDetectorFor(getDetectorID(), centerInWorld, world(),
VSConfig.maxShipSize + 1, true))
.thenAcceptTickSync(detector -> {
if (detector.foundSet.size() > VSConfig.maxShipSize || detector.cleanHouse) {
System.err.println("Ship too big or bedrock detected!");
if (player != null) {
player.sendMessage(new TextComponentString(
"Ship construction canceled because its exceeding the ship size limit; "
+
"or because it's attached to bedrock. " +
"Raise it with /physsettings maxshipsize [number]"));
}
getWrapperEntity().setDead();
return;
}
assembleShip(player, detector, centerInWorld);
markFullyLoaded();
}, worldServerThread);
}
public <K> TickSyncCompletableFuture<K> thenApplyTickSync(
Function<? super T, ? extends K> action, IThreadListener gameThread) {
TickSyncCompletableFuture<K> toReturn = new TickSyncCompletableFuture<>();
base.thenAccept(result -> // Consumer<T> --> ListenableFuture<Void>
gameThread.addScheduledTask( // Callable<K> --> ListenableFuture<K>
// (callback) 3. Apply the function
() -> toReturn.complete(action.apply(result)) // Function<T, K> --> Callable<K>
));
return toReturn;
}
public static void executeSynchronized(ChannelHandlerContext ctx, Runnable runnable) {
final IThreadListener thread = FMLCommonHandler.instance().getWorldThread(ctx.channel().attr(NetworkRegistry.NET_HANDLER).get());
if (!thread.isCallingFromMinecraftThread()) {
thread.addScheduledTask(runnable);
} else {
runnable.run();
}
}
@SideOnly(Side.CLIENT)
private IThreadListener getClientThreadListener() {
return net.minecraft.client.Minecraft.getMinecraft();
}
public static <K> TickSyncCompletableFuture<Object> supplyTickSync(Supplier<K> supplier, IThreadListener gameThread) {
return toCompletableFuture(gameThread.addScheduledTask(supplier::get));
}
public static TickSyncCompletableFuture<Object> runTickSync(Runnable runnable, IThreadListener gameThread) {
return supplyTickSync(runnableToSupplier(runnable), gameThread);
}
public TickSyncCompletableFuture<Void> thenAcceptTickSync(Consumer<? super T> action, IThreadListener gameThread) {
return thenApplyTickSync(consumerToFunction(action), gameThread);
}
public TickSyncCompletableFuture<Void> thenRunTickSync(Runnable action, IThreadListener gameThread) {
return thenApplyTickSync(runnableToFunction(action), gameThread);
}
/** Returns the appropriate thread scheduler for this message context.
* On the server, returns the world the player is in (world's thread).
* On the client, returns the Minecraft instance (main game thread). */
public static IThreadListener getScheduler(MessageContext ctx)
{ return (ctx.side.isServer() ? (WorldServer)getWorld(ctx) : ClientUtils.getScheduler()); }