-
Posts
6 -
Joined
-
Last visited
Everything posted by Synthesyzer
-
Hey, i have figured it out. Here is an example class i made public class SomeService { private final PlayerManager playerManager; public SomeService(PlayerManager playerManager) { this.playerManager = playerManager; } public void kickPlayer(UUID playerId) { CompletableFuture.supplyAsync(() -> { try { Thread.sleep(10_000); } catch (InterruptedException e) { throw new RuntimeException(e); } return new Random().nextBoolean(); }).thenAcceptAsync((kick) -> { // player might have left the server in the meantime, so playermanager allows us to get the player safely ServerPlayerEntity player = playerManager.getPlayer(playerId); if (player == null) { return; } if (kick) { player.networkHandler.disconnect(Text.of("Unlucky!")); } else { player.sendMessage(Text.of("lucky!")); } }, playerManager.getServer()); } } It's fabric and server side, but i think it will work very similarly in forge.
-
Hello, I'm trying to spawn some particles and play some sound ones a block has been broken (particles and sounds must be observable for all players) I have it setup that when a breakevent is emitted and some criteria has been met, I send out a packet to the client of all players: @SubscribeEvent public static void onBreakPowerCrystal(BlockEvent.BreakEvent event) { var world = event.getWorld(); var block = event.getWorld().getBlockState(event.getPos()).getBlock(); if (world.isClientSide())) { // calling anything here seems to not work. looks like this event happens on the server side only return; } if (!block.equals(ModBlocks.POWER_CRYSTAL_BLOCK.get()) { return; } event.setCanceled(true); Player player = event.getPlayer(); KingdomManager manager = KingdomManager.get(player.level); getKingdom(player).ifPresentOrElse( kingdomOfPlayer -> { manager.getKingdom(event.getPos()).ifPresentOrElse( kingdomOfBlock -> { if (!kingdomOfBlock.equals(kingdomOfPlayer)) { manager.decrementLives(kingdomOfBlock, 1); sendPacketToAllPlayers(player.getLevel(), new SPacketCrystalBreak( kingdomOfBlock.getName(), event.getPos(), kingdomOfBlock.getLives() )); if (kingdomOfBlock.isDead()) { event.setCanceled(false); } } else { // not important logic } }, () -> event.setCanceled(false) ); }, () -> Messenger.sendClientError(player, "You are not in a kingdom")); } private static void sendPacketToAllPlayers(Level level, Object packet) { level.players().forEach(player -> { if (player instanceof ServerPlayer serverPlayer) { PacketHandler.sendToPlayer(packet, serverPlayer); } }); } Now this packet gets handled with the following code public boolean handle(Supplier<NetworkEvent.Context> supplier) { NetworkEvent.Context context = supplier.get(); context.enqueueWork(() -> { DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> () -> { Player player = Minecraft.getInstance().player; float randomSoundPitch = ((float) Math.random() / 10f) + 0.9f; // Adding this line crashes multiplayer servers on startup player.playSound(SoundEvents.ANVIL_PLACE, 1f, randomSoundPitch); return 0; }); }); return true; } This will work fine on singleplayer. However, when trying to boot up a multiplayer server, it will refuse to start, giving the following error: Caused by 0: java.lang.BootstrapMethodError: java.lang.RuntimeException: Attempted to load class net/minecraft/client/player/LocalPlayer for invalid dist DEDICATED_SERVER at org.daan.kingdomclash.common.network.PacketHandler.register(PacketHandler.java:37) ~[%2380!/:?] {re:classloading} at org.daan.kingdomclash.common.KingdomClash.setup(KingdomClash.java:62) ~[%2380!/:?] {re:classloading} at net.minecraftforge.eventbus.EventBus.doCastFilter(EventBus.java:247) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.eventbus.EventBus.lambda$addListener$11(EventBus.java:239) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:302) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:283) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.fml.javafmlmod.FMLModContainer.acceptEvent(FMLModContainer.java:106) ~[javafmllanguage-1.18.2-40.1.0.jar%2377!/:?] {} at net.minecraftforge.fml.ModContainer.lambda$buildTransitionHandler$4(ModContainer.java:107) ~[fmlcore-1.18.2-40.1.0.jar%2379!/:?] {} at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) ~[?:?] {} at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796) ~[?:?] {} at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[?:?] {} at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) ~[?:?] {} at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) ~[?:?] {} at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) ~[?:?] {} at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) ~[?:?] {} Mod File: main Failure message: Kingdom Clash (kingdomclash) encountered an error during the common_setup event phase java.lang.BootstrapMethodError: java.lang.RuntimeException: Attempted to load class net/minecraft/client/player/LocalPlayer for invalid dist DEDICATED_SERVER Mod Version: 0.0NONE Mod Issue URL: NOT PROVIDED Exception message: java.lang.RuntimeException: Attempted to load class net/minecraft/client/player/LocalPlayer for invalid dist DEDICATED_SERVER Stacktrace: at net.minecraftforge.fml.loading.RuntimeDistCleaner.processClassWithFlags(RuntimeDistCleaner.java:57) ~[fmlloader-1.18.2-40.1.0.jar:1.0] {} at cpw.mods.modlauncher.LaunchPluginHandler.offerClassNodeToPlugins(LaunchPluginHandler.java:88) ~[modlauncher-9.1.3.jar:?] {} at cpw.mods.modlauncher.ClassTransformer.transform(ClassTransformer.java:120) ~[modlauncher-9.1.3.jar:?] {} at cpw.mods.modlauncher.TransformingClassLoader.maybeTransformClassBytes(TransformingClassLoader.java:50) ~[modlauncher-9.1.3.jar:?] {} at cpw.mods.cl.ModuleClassLoader.readerToClass(ModuleClassLoader.java:110) ~[securejarhandler-1.0.3.jar:?] {} at cpw.mods.cl.ModuleClassLoader.lambda$findClass$16(ModuleClassLoader.java:216) ~[securejarhandler-1.0.3.jar:?] {} at cpw.mods.cl.ModuleClassLoader.loadFromModule(ModuleClassLoader.java:226) ~[securejarhandler-1.0.3.jar:?] {} at cpw.mods.cl.ModuleClassLoader.findClass(ModuleClassLoader.java:216) ~[securejarhandler-1.0.3.jar:?] {} at cpw.mods.cl.ModuleClassLoader.loadClass(ModuleClassLoader.java:132) ~[securejarhandler-1.0.3.jar:?] {} at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?] {} at org.daan.kingdomclash.common.network.PacketHandler.register(PacketHandler.java:37) ~[%2380!/:?] {re:classloading} at org.daan.kingdomclash.common.KingdomClash.setup(KingdomClash.java:62) ~[%2380!/:?] {re:classloading} at net.minecraftforge.eventbus.EventBus.doCastFilter(EventBus.java:247) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.eventbus.EventBus.lambda$addListener$11(EventBus.java:239) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:302) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:283) ~[eventbus-5.0.7.jar%239!/:?] {} at net.minecraftforge.fml.javafmlmod.FMLModContainer.acceptEvent(FMLModContainer.java:106) ~[javafmllanguage-1.18.2-40.1.0.jar%2377!/:?] {} at net.minecraftforge.fml.ModContainer.lambda$buildTransitionHandler$4(ModContainer.java:107) ~[fmlcore-1.18.2-40.1.0.jar%2379!/:?] {} at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) ~[?:?] {} at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796) ~[?:?] {} at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[?:?] {} at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) ~[?:?] {} at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) ~[?:?] {} at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) ~[?:?] {} at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) ~[?:?] {} Swapping player to equal context.getSender() will make the server boot again, but won't make it so that the player hears the sound, because from my understanding, it will then not be called on the client side. How do i access the player from the client side in a packet without upsetting the multiplayer server?
-
displayName of player Model not changing
Synthesyzer replied to Synthesyzer's topic in Modder Support
Thank you, works like a charm! Sidenote, the event in the recommended forge version of 1.18.2 is called `RenderNameplateEvent`. -
Hello, I've stumbled into an issue when trying to change the player's displayName. Most of it has been successfull, but I am still running into the following issue, described best by this image The nameTag of the player's model is not showing the changed displayName. This is what i currently have in terms of code: @SubscribeEvent public static void renderName(PlayerEvent.NameFormat event) { if (!event.getPlayer().level.isClientSide()) { KingdomManager manager = KingdomManager.get(event.getPlayer().level); manager.getKingdom(event.getPlayer().getGameProfile()).ifPresent( kingdom -> event.setDisplayname(formatPlayerName( event.getPlayer().getGameProfile().getName(), kingdom.getName() ) ) ); } } @SubscribeEvent public static void renderTabName(PlayerEvent.TabListNameFormat event) { if (!event.getPlayer().level.isClientSide()) { KingdomManager manager = KingdomManager.get(event.getPlayer().level); manager.getKingdom(event.getPlayer().getGameProfile()).ifPresent( kingdom -> event.setDisplayName(formatPlayerName( event.getPlayer().getGameProfile().getName(), kingdom.getName() ) ) ); } } private static MutableComponent formatPlayerName(String playerName, String kingdom) { var kingdomColor = ChatFormatting.GREEN; return new TextComponent("[").withStyle(ChatFormatting.WHITE) .append(new TextComponent(kingdom).withStyle(kingdomColor)) .append(new TextComponent("] ").withStyle(ChatFormatting.WHITE)) .append(new TextComponent(playerName).withStyle(ChatFormatting.WHITE)); } I'm also calling these methods: // called every world tick public void tick(Level level) { counter++; if (counter > 40) { counter = 0; level.players().forEach(player -> { if (player instanceof ServerPlayer serverPlayer) { serverPlayer.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.UPDATE_DISPLAY_NAME)); serverPlayer.refreshDisplayName(); serverPlayer.refreshTabListName(); } }); } } Any lead into the right direction would be much aprreciated!