diff --git a/Canopy [BP]/scripts/lib/canopy/Canopy.js b/Canopy [BP]/scripts/lib/canopy/Canopy.js index 4aa1d2d..f24d4ae 100644 --- a/Canopy [BP]/scripts/lib/canopy/Canopy.js +++ b/Canopy [BP]/scripts/lib/canopy/Canopy.js @@ -8,5 +8,11 @@ import { RuleHelpEntry, CommandHelpEntry, InfoDisplayRuleHelpEntry } from './hel import { RuleHelpPage, CommandHelpPage, InfoDisplayRuleHelpPage } from './help/HelpPage'; import HelpBook from './help/HelpBook'; +function getLoadedExtensions() { + const ruleExtensions = Rule.getExtensionNames(); + const commandExtensions = Command.getExtensionNames(); + return [...new Set([...ruleExtensions, ...commandExtensions])]; +} + export { Command, Rule, InfoDisplayRule, RuleHelpEntry, CommandHelpEntry, InfoDisplayRuleHelpEntry, - RuleHelpPage, CommandHelpPage, InfoDisplayRuleHelpPage, HelpBook }; \ No newline at end of file + RuleHelpPage, CommandHelpPage, InfoDisplayRuleHelpPage, HelpBook, getLoadedExtensions }; \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/Command.js b/Canopy [BP]/scripts/lib/canopy/Command.js index 3c47cad..dcd3e05 100644 --- a/Canopy [BP]/scripts/lib/canopy/Command.js +++ b/Canopy [BP]/scripts/lib/canopy/Command.js @@ -106,17 +106,17 @@ class Command { result.sort((a, b) => a.getName().localeCompare(b.getName())); return result; } - - static getExtensionNames() { - return Object.values(commands).map(cmd => cmd.getExtensionName()).filter(name => name); - } - + static getCommandsByExtension(extensionName) { let result = Object.values(commands).filter(cmd => cmd.getExtensionName() === extensionName); result.sort((a, b) => a.getName().localeCompare(b.getName())); return result; } + static getExtensionNames() { + return Object.values(commands).map(cmd => cmd.getExtensionName()).filter(name => name); + } + static checkArg(value, type) { let data; if (type == 'array' && Array.isArray(value)) data = value; diff --git a/Canopy [BP]/scripts/lib/canopy/registry/CommandRegistry.js b/Canopy [BP]/scripts/lib/canopy/registry/CommandRegistry.js index 23a8abb..927b019 100644 --- a/Canopy [BP]/scripts/lib/canopy/registry/CommandRegistry.js +++ b/Canopy [BP]/scripts/lib/canopy/registry/CommandRegistry.js @@ -13,5 +13,5 @@ system.afterEvents.scriptEventReceive.subscribe((event) => { } if (!cmdData) return; new Command(cmdData); - console.warn(`[Canopy] Registered command: ${cmdData.extensionName}:${cmdData.name}`); + // console.warn(`[Canopy] Registered command: ${cmdData.extensionName}:${cmdData.name}`); }, { namespaces: ['canopyExtension']}); \ No newline at end of file diff --git a/Canopy [BP]/scripts/lib/canopy/registry/RuleRegistry.js b/Canopy [BP]/scripts/lib/canopy/registry/RuleRegistry.js index 174ca40..76aed18 100644 --- a/Canopy [BP]/scripts/lib/canopy/registry/RuleRegistry.js +++ b/Canopy [BP]/scripts/lib/canopy/registry/RuleRegistry.js @@ -13,5 +13,5 @@ system.afterEvents.scriptEventReceive.subscribe((event) => { } if (!ruleData) return; new Rule(ruleData); - console.warn(`[Canopy] Registered rule: ${ruleData.extensionName}:${ruleData.identifier}`); + // console.warn(`[Canopy] Registered rule: ${ruleData.extensionName}:${ruleData.identifier}`); }, { namespaces: ['canopyExtension']}); \ No newline at end of file diff --git a/Canopy [BP]/scripts/main.js b/Canopy [BP]/scripts/main.js index ea213bf..1391e98 100644 --- a/Canopy [BP]/scripts/main.js +++ b/Canopy [BP]/scripts/main.js @@ -57,7 +57,7 @@ import ProbeManager from 'src/classes/ProbeManager'; import { Command } from 'lib/canopy/Canopy'; const players = world.getAllPlayers(); -if (players[0] !== undefined && players[0].isValid()) { +if (players[0]?.isValid()) { Utils.broadcastActionBar('§aBehavior packs have been reloaded.'); ProbeManager.startCleanupCycle(); Command.broadcastPrefix(); diff --git a/Canopy [BP]/scripts/src/classes/ProbeManager.js b/Canopy [BP]/scripts/src/classes/ProbeManager.js index bc5c769..a3753e2 100644 --- a/Canopy [BP]/scripts/src/classes/ProbeManager.js +++ b/Canopy [BP]/scripts/src/classes/ProbeManager.js @@ -189,14 +189,14 @@ class ProbeManager { world.beforeEvents.playerLeave.subscribe((event) => { const player = event.player; system.run(() => { - if (player.getDynamicProperty('light') || player.getDynamicProperty('biome')) + if (player?.getDynamicProperty('light') || player?.getDynamicProperty('biome')) this.removeProbe(player); }); }); world.afterEvents.playerDimensionChange.subscribe((event) => { const player = event.player; - if (player.getDynamicProperty('light') || player.getDynamicProperty('biome')) + if (player?.getDynamicProperty('light') || player?.getDynamicProperty('biome')) this.removeProbe(player); }); diff --git a/Canopy [BP]/scripts/src/commands/camera.js b/Canopy [BP]/scripts/src/commands/camera.js index 719793f..6a2542f 100644 --- a/Canopy [BP]/scripts/src/commands/camera.js +++ b/Canopy [BP]/scripts/src/commands/camera.js @@ -72,7 +72,7 @@ class BeforeSpectatorPlayer { world.beforeEvents.playerGameModeChange.subscribe((event) => { const player = event.player; - if (player.getDynamicProperty('isSpectating') && event.fromGameMode === 'spectator' && event.toGameMode !== 'spectator') { + if (player?.getDynamicProperty('isSpectating') && event.fromGameMode === 'spectator' && event.toGameMode !== 'spectator') { system.run(() => { player.setGameMode(event.fromGameMode); player.onScreenDisplay.setActionBar('§cYou cannot change your gamemode while spectating.'); @@ -81,7 +81,7 @@ world.beforeEvents.playerGameModeChange.subscribe((event) => { }); world.beforeEvents.playerLeave.subscribe((event) => { - event.player.setDynamicProperty('isViewingCamera', false); + event.player?.setDynamicProperty('isViewingCamera', false); }); world.afterEvents.playerDimensionChange.subscribe((event) => { diff --git a/Canopy [BP]/scripts/src/commands/counter.js b/Canopy [BP]/scripts/src/commands/counter.js index 50b2ad3..c03d787 100644 --- a/Canopy [BP]/scripts/src/commands/counter.js +++ b/Canopy [BP]/scripts/src/commands/counter.js @@ -295,7 +295,7 @@ function realtimeQueryAll(sender) { function query(sender, color) { const channel = channelMap.getChannel(color); - sender.sendMessage(channelMap.getQueryOutput(channel)); + sender?.sendMessage(channelMap.getQueryOutput(channel)); } function queryAll(sender) { @@ -306,7 +306,7 @@ function queryAll(sender) { }); if (output === '') output = '§7There are no hopper counters in use.'; - sender.sendMessage(output); + sender?.sendMessage(output); } function setMode(sender, color, mode) { diff --git a/Canopy [BP]/scripts/src/commands/log.js b/Canopy [BP]/scripts/src/commands/log.js index 52f910c..5c6dea6 100644 --- a/Canopy [BP]/scripts/src/commands/log.js +++ b/Canopy [BP]/scripts/src/commands/log.js @@ -158,7 +158,7 @@ world.afterEvents.entitySpawn.subscribe((event) => { world.beforeEvents.entityRemove.subscribe((event) => { const removedEntity = event.removedEntity; - if (removedEntity.typeId === 'minecraft:tnt') { + if (removedEntity?.typeId === 'minecraft:tnt') { loggingPlayers.forEach(loggingPlayer => { if (loggingPlayer.types.includes('tnt')) { printTntLog(loggingPlayer.player, removedEntity); diff --git a/Canopy [BP]/scripts/src/commands/resetall.js b/Canopy [BP]/scripts/src/commands/resetall.js index a9f9134..ffc561e 100644 --- a/Canopy [BP]/scripts/src/commands/resetall.js +++ b/Canopy [BP]/scripts/src/commands/resetall.js @@ -13,7 +13,7 @@ function resetallCommand(sender) { world.clearDynamicProperties(); const players = world.getAllPlayers(); players.forEach(player => { - player.clearDynamicProperties(); + player?.clearDynamicProperties(); }); world.sendMessage('§cPlayer and world dynamic properties have been reset.'); } \ No newline at end of file diff --git a/Canopy [BP]/scripts/src/entities.js b/Canopy [BP]/scripts/src/entities.js index 7c293f0..143ea57 100644 --- a/Canopy [BP]/scripts/src/entities.js +++ b/Canopy [BP]/scripts/src/entities.js @@ -28,6 +28,7 @@ const Entities = { let count = 0; for (const entity of entities) { + if (!entity) continue; try{ const toEntity = Utils.normalizeVector(subtractVectors(entity.location, player.location)); const dotProduct = Utils.dotProduct(viewDirection, toEntity); diff --git a/Canopy [BP]/scripts/src/rules/InfoDisplay.js b/Canopy [BP]/scripts/src/rules/InfoDisplay.js index c59f8e9..17f4330 100644 --- a/Canopy [BP]/scripts/src/rules/InfoDisplay.js +++ b/Canopy [BP]/scripts/src/rules/InfoDisplay.js @@ -90,8 +90,9 @@ new InfoDisplayRule({ }); system.runInterval(() => { - const Players = world.getAllPlayers(); - for (const player of Players) { + const players = world.getAllPlayers(); + for (const player of players) { + if (!player) continue; if (InfoDisplayRule.getValue(player, 'showDisplay')) InfoDisplay(player); } }); diff --git a/Canopy [BP]/scripts/src/rules/hotbarSwitching.js b/Canopy [BP]/scripts/src/rules/hotbarSwitching.js index 0dfca16..804f567 100644 --- a/Canopy [BP]/scripts/src/rules/hotbarSwitching.js +++ b/Canopy [BP]/scripts/src/rules/hotbarSwitching.js @@ -24,6 +24,7 @@ system.runInterval(async () => { if (!await Rule.getValue('hotbarSwitching')) return; const players = world.getAllPlayers(); for (const player of players) { + if (!player) continue; if (!await hasAppropriateGameMode(player)) continue; if (hotbarManagers[player.id] === undefined) hotbarManagers[player.id] = new HotbarManager(player); diff --git a/Canopy [BP]/scripts/src/rules/renewableElytra.js b/Canopy [BP]/scripts/src/rules/renewableElytra.js index f37f593..b6f396e 100644 --- a/Canopy [BP]/scripts/src/rules/renewableElytra.js +++ b/Canopy [BP]/scripts/src/rules/renewableElytra.js @@ -7,8 +7,8 @@ new Rule({ description: 'Phantoms have a 1%% chance to drop an elytra when killed by a shulker bullet.', }); -world.afterEvents.entityDie.subscribe(async (event) => { - if (!await Rule.getValue('renewableElytra')) return; +world.afterEvents.entityDie.subscribe((event) => { + if (!Rule.getValue('renewableElytra')) return; const entity = event.deadEntity; if (entity?.typeId === 'minecraft:phantom' && event.damageSource.damagingProjectile?.typeId === 'minecraft:shulker_bullet') { if (Math.random() > 0.01) return; diff --git a/Canopy [BP]/scripts/src/rules/renewableSponge.js b/Canopy [BP]/scripts/src/rules/renewableSponge.js index e436de5..889c976 100644 --- a/Canopy [BP]/scripts/src/rules/renewableSponge.js +++ b/Canopy [BP]/scripts/src/rules/renewableSponge.js @@ -8,7 +8,7 @@ new Rule({ }); world.afterEvents.entityHurt.subscribe(async (event) => { - if (event.hurtEntity.typeId !== 'minecraft:guardian' || !await Rule.getValue('renewableSponge') || event.damageSource.cause !== 'lightning') + if (event.hurtEntity?.typeId !== 'minecraft:guardian' || !await Rule.getValue('renewableSponge') || event.damageSource.cause !== 'lightning') return; const guardian = event.hurtEntity; diff --git a/Canopy [BP]/scripts/src/validWorld.js b/Canopy [BP]/scripts/src/validWorld.js index a6ac8e6..00ecbf0 100644 --- a/Canopy [BP]/scripts/src/validWorld.js +++ b/Canopy [BP]/scripts/src/validWorld.js @@ -1,6 +1,7 @@ import { world, system } from '@minecraft/server'; import Data from 'stickycore/data'; import ProbeManager from 'src/classes/ProbeManager'; +import { getLoadedExtensions } from 'lib/canopy/Canopy'; let hasShownWelcome = false; @@ -8,7 +9,7 @@ world.afterEvents.playerJoin.subscribe((event) => { let runner = system.runInterval(() => { const players = world.getPlayers({ name: event.playerName }); players.forEach(player => { - if (!hasShownWelcome && player.isValid()) { + if (!hasShownWelcome && player?.isValid()) { system.clearRun(runner); hasShownWelcome = true; onValidWorld(player); @@ -33,4 +34,8 @@ function displayWelcome(player) { output += `§a+ ----- +\n`; output += `§7This server is running §l§aCanopy§r§7. Type ./help to get started.§r\n`; player.sendMessage(output); + const extensions = getLoadedExtensions(); + if (extensions.length > 0) { + player.sendMessage(`§7Loaded extensions: §a${extensions.join('§7, §a')}`); + } } diff --git a/Canopy [BP]/scripts/stickycore/data.js b/Canopy [BP]/scripts/stickycore/data.js index 461fb0a..e628008 100644 --- a/Canopy [BP]/scripts/stickycore/data.js +++ b/Canopy [BP]/scripts/stickycore/data.js @@ -117,6 +117,7 @@ class Data { if (!blockRayResult && !entityRayResult) return ''; target = Utils.getClosestTarget(sender, blockRayResult, entityRayResult); + if (!target) return ''; try { inventory = target.getComponent('inventory'); } catch(error) { diff --git a/Canopy [BP]/scripts/stickycore/utils.js b/Canopy [BP]/scripts/stickycore/utils.js index 2876a68..9ab11e7 100644 --- a/Canopy [BP]/scripts/stickycore/utils.js +++ b/Canopy [BP]/scripts/stickycore/utils.js @@ -210,7 +210,7 @@ class Utils { let players; if (sender) players = world.getPlayers({ excludeNames: [sender.name] }); else players = world.getAllPlayers(); - players.forEach(player => player.onScreenDisplay.setActionBar(message)); + players.forEach(player => player?.onScreenDisplay.setActionBar(message)); } static locationInArea(area, position) {