// priority 99 // related files: // instance/server_banlist_config.json // instance/kubejs/client_scripts/server_sync_banlist.js // instance/kubejs/server_scripts/Tweaks/remove_recipes_from_banlist.js // instance/kubejs/server_scripts/banlist_script.js let $HashSet = Java.loadClass("java.util.HashSet") let $ArrayList = Java.loadClass("java.util.ArrayList") let config let bannedBlockEntities if (!Platform.isClientEnvironment()) { let configPath = "server_banlist_config.json" let defaultConfig = { server: { banned_block_entities: Utils.newList(), banned_items: Utils.newList(), banned_entities: Utils.newList(), remove_recipes_by: Utils.newList() } } config = JsonIO.read(configPath) if (config == null) { JsonIO.write(configPath, defaultConfig) config = defaultConfig } /** @type {$ArrayList_} */ bannedBlockEntities = config?.server.banned_block_entities /** @type {$ArrayList_} */ let bannedItems = config?.server.banned_items /** @type {$ArrayList_} */ let bannedEntities = config?.server.banned_entities if (bannedEntities instanceof $ArrayList) { let $EntityJoinLevelEvent = Java.loadClass("net.neoforged.neoforge.event.entity.EntityJoinLevelEvent") NativeEvents.onEvent($EntityJoinLevelEvent, event => { if (bannedEntities.contains(event.entity.type)) { event.level.server.tell(Text.red("Removed banned entity: " + event.entity.type + " at " + event.entity.blockPosition().toShortString())) event.setCanceled(true) } }) } let bannedList = new $HashSet() bannedList.addAll(bannedBlockEntities) bannedList.addAll(bannedItems) if (!bannedList.isEmpty()) { bannedList.forEach(item => { ItemEvents.rightClicked(item, (event) => sendMessageAndCancel(event, "item")) }) BlockEvents.rightClicked((event) => { if (bannedList.contains(event.item.id)) sendMessageAndCancel(event, "item") }) PlayerEvents.loggedIn((event) => { let data = bannedList console.log("Banned items: " + data) console.log("Sending banned items to " + event.player.username) event.player.sendData("banned_items", { banned_items: data }) }) } let $ChunkEvent$Load = Java.loadClass("net.neoforged.neoforge.event.level.ChunkEvent$Load") let $LevelTickEvent$Pre = Java.loadClass("net.neoforged.neoforge.event.tick.LevelTickEvent$Pre") if (!bannedBlockEntities.isEmpty()) { NativeEvents.onEvent($ChunkEvent$Load, event => { if (event.level.clientSide) return removeBlockEntities(event) }) NativeEvents.onEvent($LevelTickEvent$Pre, event => { let blocksToRemove = levelAndPosToRemove.get(event.level) if (blocksToRemove == null) return let pos while ((pos = blocksToRemove.poll()) != null) { addSignToPos(event.level, pos) event.level.server.tell("Removing banned block entity at " + pos.toShortString()) } }) LevelEvents.unloaded(event => { levelAndPosToRemove.remove(event.level) }) } } function sendMessageAndCancel(/** @type {$ItemClickedKubeEvent_} */event, type) { switch (type) { case "item": event.player.setStatusMessage(Text.red("This server does not allow you to use this item!")) event.cancel() break default: break } } let $LevelChunk = Java.loadClass("net.minecraft.world.level.chunk.LevelChunk") let levelAndPosToRemove = Utils.newMap() let $ConcurrentLinkedQueue = Java.loadClass("java.util.concurrent.ConcurrentLinkedQueue") let removeBlockEntities = (/** @type {$ChunkEvent$Load_} */ event) => { if (event.isNewChunk()) return let blocksToRemove = Utils.newList() if (event.chunk instanceof $LevelChunk) { if (event.chunk.persistedStatus != "minecraft:full") return event.chunk.getBlockEntities().forEach((pos, be) => { /** @type {$ResourceLocation_} */ let beRL = be.getType().getKey(be.getType()) if (bannedBlockEntities.contains(beRL.toString())) { blocksToRemove.add(pos) } }) } if (!blocksToRemove.isEmpty()) { let original = levelAndPosToRemove.get(event.level) if (original == null) { let queue = new $ConcurrentLinkedQueue(blocksToRemove) levelAndPosToRemove.put(event.level, queue) } else { original.addAll(blocksToRemove) } } } let addSignToPos = (/** @type {$ServerLevel_} */level, /** @type {$BlockPos_} */pos) => { let beRL = level.getBlock(pos).entityId level.getBlock(pos).set("minecraft:oak_sign", {}, 18) /** @type {$SignBlockEntity_} */ let oakSignBlockEntity = level.getBlockEntity(pos) let namespace = `'${beRL.split(":")[0]}:'` let path = beRL.split(":")[1] let nbt = {is_waxed: 1, front_text: {has_glowing_text: 1, color: "black", messages: [namespace, path, '"is banned on this"', "server"]}} oakSignBlockEntity.loadWithComponents(nbt, level.registryAccess()) }