2026.02.06-0baf7c5aa

This commit is contained in:
Intege-rs
2026-02-06 23:08:15 -05:00
parent 72c1df79ca
commit 8988b1dc65
666 changed files with 10538 additions and 4740 deletions

View File

@@ -7,6 +7,7 @@ import com.hypixel.hytale.logger.sentry.SkipSentryException;
import com.hypixel.hytale.server.core.HytaleServer; import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.HytaleServerConfig; import com.hypixel.hytale.server.core.HytaleServerConfig;
import com.hypixel.hytale.server.core.Options; import com.hypixel.hytale.server.core.Options;
import com.hypixel.hytale.server.core.console.ConsoleModule;
import io.sentry.Sentry; import io.sentry.Sentry;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.logging.Level; import java.util.logging.Level;
@@ -16,6 +17,7 @@ public class LateMain {
try { try {
if (!Options.parse(args)) { if (!Options.parse(args)) {
HytaleLogger.init(); HytaleLogger.init();
ConsoleModule.initializeTerminal();
HytaleFileHandler.INSTANCE.enable(); HytaleFileHandler.INSTANCE.enable();
HytaleLogger.replaceStd(); HytaleLogger.replaceStd();
HytaleLoggerBackend.LOG_LEVEL_LOADER = name -> { HytaleLoggerBackend.LOG_LEVEL_LOADER = name -> {

View File

@@ -10,13 +10,17 @@ import com.hypixel.hytale.builtin.adventure.camera.asset.viewbobbing.ViewBobbing
import com.hypixel.hytale.builtin.adventure.camera.command.CameraEffectCommand; import com.hypixel.hytale.builtin.adventure.camera.command.CameraEffectCommand;
import com.hypixel.hytale.builtin.adventure.camera.interaction.CameraShakeInteraction; import com.hypixel.hytale.builtin.adventure.camera.interaction.CameraShakeInteraction;
import com.hypixel.hytale.builtin.adventure.camera.system.CameraEffectSystem; import com.hypixel.hytale.builtin.adventure.camera.system.CameraEffectSystem;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.protocol.MovementType; import com.hypixel.hytale.protocol.MovementType;
import com.hypixel.hytale.server.core.asset.HytaleAssetStore; import com.hypixel.hytale.server.core.asset.HytaleAssetStore;
import com.hypixel.hytale.server.core.asset.type.camera.CameraEffect; import com.hypixel.hytale.server.core.asset.type.camera.CameraEffect;
import com.hypixel.hytale.server.core.modules.entitystats.EntityStatMap;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.plugin.registry.AssetRegistry; import com.hypixel.hytale.server.core.plugin.registry.AssetRegistry;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class CameraPlugin extends JavaPlugin { public class CameraPlugin extends JavaPlugin {
@@ -55,6 +59,8 @@ public class CameraPlugin extends JavaPlugin {
.build() .build()
); );
this.getCommandRegistry().registerCommand(new CameraEffectCommand()); this.getCommandRegistry().registerCommand(new CameraEffectCommand());
this.getEntityStoreRegistry().registerSystem(new CameraEffectSystem()); ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
ComponentType<EntityStore, EntityStatMap> entityStatMapComponentType = EntityStatMap.getComponentType();
this.getEntityStoreRegistry().registerSystem(new CameraEffectSystem(playerRefComponentType, entityStatMapComponentType));
} }
} }

View File

@@ -23,10 +23,19 @@ import javax.annotation.Nullable;
public class CameraEffectSystem extends DamageEventSystem { public class CameraEffectSystem extends DamageEventSystem {
@Nonnull @Nonnull
private static final ComponentType<EntityStore, PlayerRef> PLAYER_REF_COMPONENT_TYPE = PlayerRef.getComponentType(); private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
private static final ComponentType<EntityStore, EntityStatMap> ENTITY_STAT_MAP_COMPONENT_TYPE = EntityStatMap.getComponentType();
@Nonnull @Nonnull
private static final Query<EntityStore> QUERY = Query.and(PLAYER_REF_COMPONENT_TYPE, ENTITY_STAT_MAP_COMPONENT_TYPE); private final ComponentType<EntityStore, EntityStatMap> entityStatMapComponentType;
@Nonnull
private final Query<EntityStore> query;
public CameraEffectSystem(
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType, @Nonnull ComponentType<EntityStore, EntityStatMap> entityStatMapComponentType
) {
this.playerRefComponentType = playerRefComponentType;
this.entityStatMapComponentType = entityStatMapComponentType;
this.query = Query.and(playerRefComponentType, entityStatMapComponentType);
}
@Nullable @Nullable
@Override @Override
@@ -37,7 +46,7 @@ public class CameraEffectSystem extends DamageEventSystem {
@Nonnull @Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return QUERY; return this.query;
} }
public void handle( public void handle(
@@ -47,7 +56,7 @@ public class CameraEffectSystem extends DamageEventSystem {
@Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull CommandBuffer<EntityStore> commandBuffer,
@Nonnull Damage damage @Nonnull Damage damage
) { ) {
EntityStatMap entityStatMapComponent = archetypeChunk.getComponent(index, ENTITY_STAT_MAP_COMPONENT_TYPE); EntityStatMap entityStatMapComponent = archetypeChunk.getComponent(index, this.entityStatMapComponentType);
assert entityStatMapComponent != null; assert entityStatMapComponent != null;
@@ -55,7 +64,7 @@ public class CameraEffectSystem extends DamageEventSystem {
if (healthStat != null) { if (healthStat != null) {
float health = healthStat.getMax() - healthStat.getMin(); float health = healthStat.getMax() - healthStat.getMin();
if (!(health <= 0.0F)) { if (!(health <= 0.0F)) {
PlayerRef playerRefComponent = archetypeChunk.getComponent(index, PLAYER_REF_COMPONENT_TYPE); PlayerRef playerRefComponent = archetypeChunk.getComponent(index, this.playerRefComponentType);
assert playerRefComponent != null; assert playerRefComponent != null;

View File

@@ -32,11 +32,15 @@ import com.hypixel.hytale.server.core.asset.type.blocktype.config.farming.Farmin
import com.hypixel.hytale.server.core.asset.type.blocktype.config.farming.GrowthModifierAsset; import com.hypixel.hytale.server.core.asset.type.blocktype.config.farming.GrowthModifierAsset;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemDropList; import com.hypixel.hytale.server.core.asset.type.item.config.ItemDropList;
import com.hypixel.hytale.server.core.asset.type.weather.config.Weather; import com.hypixel.hytale.server.core.asset.type.weather.config.Weather;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.modules.block.BlockModule;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.plugin.registry.AssetRegistry; import com.hypixel.hytale.server.core.plugin.registry.AssetRegistry;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk; import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk;
import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection;
import com.hypixel.hytale.server.core.universe.world.events.ChunkPreLoadProcessEvent; import com.hypixel.hytale.server.core.universe.world.events.ChunkPreLoadProcessEvent;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
@@ -105,13 +109,25 @@ public class FarmingPlugin extends JavaPlugin {
this.farmingBlockStateComponentType = chunkStoreRegistry.registerComponent(FarmingBlockState.class, "Farming", FarmingBlockState.CODEC); this.farmingBlockStateComponentType = chunkStoreRegistry.registerComponent(FarmingBlockState.class, "Farming", FarmingBlockState.CODEC);
this.coopBlockStateComponentType = chunkStoreRegistry.registerComponent(CoopBlock.class, "Coop", CoopBlock.CODEC); this.coopBlockStateComponentType = chunkStoreRegistry.registerComponent(CoopBlock.class, "Coop", CoopBlock.CODEC);
this.coopResidentComponentType = entityStoreRegistry.registerComponent(CoopResidentComponent.class, "CoopResident", CoopResidentComponent.CODEC); this.coopResidentComponentType = entityStoreRegistry.registerComponent(CoopResidentComponent.class, "CoopResident", CoopResidentComponent.CODEC);
chunkStoreRegistry.registerSystem(new FarmingSystems.OnSoilAdded()); ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType = BlockModule.BlockStateInfo.getComponentType();
chunkStoreRegistry.registerSystem(new FarmingSystems.OnFarmBlockAdded()); ComponentType<ChunkStore, BlockSection> blockSectionComponentType = BlockSection.getComponentType();
chunkStoreRegistry.registerSystem(new FarmingSystems.Ticking()); ComponentType<ChunkStore, ChunkSection> chunkSectionComponentType = ChunkSection.getComponentType();
ComponentType<EntityStore, UUIDComponent> uuidComponentType = UUIDComponent.getComponentType();
chunkStoreRegistry.registerSystem(new FarmingSystems.OnSoilAdded(blockStateInfoComponentType, this.tiledSoilBlockComponentType));
chunkStoreRegistry.registerSystem(new FarmingSystems.OnFarmBlockAdded(blockStateInfoComponentType, this.farmingBlockComponentType));
chunkStoreRegistry.registerSystem(
new FarmingSystems.Ticking(
blockSectionComponentType,
chunkSectionComponentType,
this.farmingBlockComponentType,
this.tiledSoilBlockComponentType,
this.coopBlockStateComponentType
)
);
chunkStoreRegistry.registerSystem(new FarmingSystems.MigrateFarming()); chunkStoreRegistry.registerSystem(new FarmingSystems.MigrateFarming());
chunkStoreRegistry.registerSystem(new FarmingSystems.OnCoopAdded()); chunkStoreRegistry.registerSystem(new FarmingSystems.OnCoopAdded(blockStateInfoComponentType, this.coopBlockStateComponentType));
entityStoreRegistry.registerSystem(new FarmingSystems.CoopResidentEntitySystem()); entityStoreRegistry.registerSystem(new FarmingSystems.CoopResidentEntitySystem(this.coopResidentComponentType, uuidComponentType));
entityStoreRegistry.registerSystem(new FarmingSystems.CoopResidentTicking()); entityStoreRegistry.registerSystem(new FarmingSystems.CoopResidentTicking(this.coopResidentComponentType));
this.getEventRegistry().registerGlobal(EventPriority.LAST, ChunkPreLoadProcessEvent.class, FarmingPlugin::preventSpreadOnNew); this.getEventRegistry().registerGlobal(EventPriority.LAST, ChunkPreLoadProcessEvent.class, FarmingPlugin::preventSpreadOnNew);
} }

View File

@@ -99,11 +99,23 @@ public class FarmingSystems {
} }
public static class CoopResidentEntitySystem extends RefSystem<EntityStore> { public static class CoopResidentEntitySystem extends RefSystem<EntityStore> {
private static final ComponentType<EntityStore, CoopResidentComponent> COMPONENT_TYPE_COOP_RESIDENT = CoopResidentComponent.getComponentType(); @Nonnull
private final ComponentType<EntityStore, CoopResidentComponent> coopResidentComponentType;
@Nonnull
private final ComponentType<EntityStore, UUIDComponent> uuidComponentType;
public CoopResidentEntitySystem(
@Nonnull ComponentType<EntityStore, CoopResidentComponent> coopResidentComponentType,
@Nonnull ComponentType<EntityStore, UUIDComponent> uuidComponentType
) {
this.coopResidentComponentType = coopResidentComponentType;
this.uuidComponentType = uuidComponentType;
}
@Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return COMPONENT_TYPE_COOP_RESIDENT; return this.coopResidentComponentType;
} }
@Override @Override
@@ -117,10 +129,10 @@ public class FarmingSystems {
@Nonnull Ref<EntityStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull Ref<EntityStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
if (reason != RemoveReason.UNLOAD) { if (reason != RemoveReason.UNLOAD) {
UUIDComponent uuidComponent = commandBuffer.getComponent(ref, UUIDComponent.getComponentType()); UUIDComponent uuidComponent = commandBuffer.getComponent(ref, this.uuidComponentType);
if (uuidComponent != null) { if (uuidComponent != null) {
UUID uuid = uuidComponent.getUuid(); UUID uuid = uuidComponent.getUuid();
CoopResidentComponent coopResidentComponent = commandBuffer.getComponent(ref, COMPONENT_TYPE_COOP_RESIDENT); CoopResidentComponent coopResidentComponent = commandBuffer.getComponent(ref, this.coopResidentComponentType);
if (coopResidentComponent != null) { if (coopResidentComponent != null) {
Vector3i coopPosition = coopResidentComponent.getCoopLocation(); Vector3i coopPosition = coopResidentComponent.getCoopLocation();
World world = commandBuffer.getExternalData().getWorld(); World world = commandBuffer.getExternalData().getWorld();
@@ -159,11 +171,17 @@ public class FarmingSystems {
} }
public static class CoopResidentTicking extends EntityTickingSystem<EntityStore> { public static class CoopResidentTicking extends EntityTickingSystem<EntityStore> {
private static final ComponentType<EntityStore, CoopResidentComponent> COMPONENT_TYPE_COOP_RESIDENT = CoopResidentComponent.getComponentType(); @Nonnull
private final ComponentType<EntityStore, CoopResidentComponent> coopResidentComponentType;
public CoopResidentTicking(@Nonnull ComponentType<EntityStore, CoopResidentComponent> coopResidentComponentType) {
this.coopResidentComponentType = coopResidentComponentType;
}
@Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return COMPONENT_TYPE_COOP_RESIDENT; return this.coopResidentComponentType;
} }
@Override @Override
@@ -174,14 +192,15 @@ public class FarmingSystems {
@Nonnull Store<EntityStore> store, @Nonnull Store<EntityStore> store,
@Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
CoopResidentComponent coopResidentComponent = archetypeChunk.getComponent(index, CoopResidentComponent.getComponentType()); CoopResidentComponent coopResidentComponent = archetypeChunk.getComponent(index, this.coopResidentComponentType);
if (coopResidentComponent != null) {
assert coopResidentComponent != null;
if (coopResidentComponent.getMarkedForDespawn()) { if (coopResidentComponent.getMarkedForDespawn()) {
commandBuffer.removeEntity(archetypeChunk.getReferenceTo(index), RemoveReason.REMOVE); commandBuffer.removeEntity(archetypeChunk.getReferenceTo(index), RemoveReason.REMOVE);
} }
} }
} }
}
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static class MigrateFarming extends BlockModule.MigrationSystem { public static class MigrateFarming extends BlockModule.MigrationSystem {
@@ -209,17 +228,30 @@ public class FarmingSystems {
public static class OnCoopAdded extends RefSystem<ChunkStore> { public static class OnCoopAdded extends RefSystem<ChunkStore> {
@Nonnull @Nonnull
private static final Query<ChunkStore> QUERY = Query.and(BlockModule.BlockStateInfo.getComponentType(), CoopBlock.getComponentType()); private final ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType;
@Nonnull
private final ComponentType<ChunkStore, CoopBlock> coopBlockComponentType;
@Nonnull
private final Query<ChunkStore> query;
public OnCoopAdded(
@Nonnull ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType,
@Nonnull ComponentType<ChunkStore, CoopBlock> coopBlockComponentType
) {
this.blockStateInfoComponentType = blockStateInfoComponentType;
this.coopBlockComponentType = coopBlockComponentType;
this.query = Query.and(blockStateInfoComponentType, coopBlockComponentType);
}
@Override @Override
public void onEntityAdded( public void onEntityAdded(
@Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
CoopBlock coopBlockComponent = commandBuffer.getComponent(ref, CoopBlock.getComponentType()); CoopBlock coopBlockComponent = commandBuffer.getComponent(ref, this.coopBlockComponentType);
assert coopBlockComponent != null; assert coopBlockComponent != null;
BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, this.blockStateInfoComponentType);
assert blockStateInfoComponent != null; assert blockStateInfoComponent != null;
@@ -244,11 +276,11 @@ public class FarmingSystems {
@Nonnull Ref<ChunkStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull Ref<ChunkStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
if (reason != RemoveReason.UNLOAD) { if (reason != RemoveReason.UNLOAD) {
CoopBlock coopBlockComponent = commandBuffer.getComponent(ref, CoopBlock.getComponentType()); CoopBlock coopBlockComponent = commandBuffer.getComponent(ref, this.coopBlockComponentType);
assert coopBlockComponent != null; assert coopBlockComponent != null;
BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, this.blockStateInfoComponentType);
assert blockStateInfoComponent != null; assert blockStateInfoComponent != null;
@@ -286,26 +318,39 @@ public class FarmingSystems {
} }
} }
@Nullable @Nonnull
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return QUERY; return this.query;
} }
} }
public static class OnFarmBlockAdded extends RefSystem<ChunkStore> { public static class OnFarmBlockAdded extends RefSystem<ChunkStore> {
@Nonnull @Nonnull
private static final Query<ChunkStore> QUERY = Query.and(BlockModule.BlockStateInfo.getComponentType(), FarmingBlock.getComponentType()); private final ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType;
@Nonnull
private final ComponentType<ChunkStore, FarmingBlock> farmingBlockComponentType;
@Nonnull
private final Query<ChunkStore> query;
public OnFarmBlockAdded(
@Nonnull ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType,
@Nonnull ComponentType<ChunkStore, FarmingBlock> farmingBlockComponentType
) {
this.blockStateInfoComponentType = blockStateInfoComponentType;
this.farmingBlockComponentType = farmingBlockComponentType;
this.query = Query.and(blockStateInfoComponentType, farmingBlockComponentType);
}
@Override @Override
public void onEntityAdded( public void onEntityAdded(
@Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
FarmingBlock farmingBlockComponent = commandBuffer.getComponent(ref, FarmingBlock.getComponentType()); FarmingBlock farmingBlockComponent = commandBuffer.getComponent(ref, this.farmingBlockComponentType);
assert farmingBlockComponent != null; assert farmingBlockComponent != null;
BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, this.blockStateInfoComponentType);
assert blockStateInfoComponent != null; assert blockStateInfoComponent != null;
@@ -421,26 +466,39 @@ public class FarmingSystems {
) { ) {
} }
@Nullable @Nonnull
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return QUERY; return this.query;
} }
} }
public static class OnSoilAdded extends RefSystem<ChunkStore> { public static class OnSoilAdded extends RefSystem<ChunkStore> {
@Nonnull @Nonnull
private static final Query<ChunkStore> QUERY = Query.and(BlockModule.BlockStateInfo.getComponentType(), TilledSoilBlock.getComponentType()); private final ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType;
@Nonnull
private final ComponentType<ChunkStore, TilledSoilBlock> tilledSoilBlockComponentType;
@Nonnull
private final Query<ChunkStore> query;
public OnSoilAdded(
@Nonnull ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType,
@Nonnull ComponentType<ChunkStore, TilledSoilBlock> tilledSoilBlockComponentType
) {
this.blockStateInfoComponentType = blockStateInfoComponentType;
this.tilledSoilBlockComponentType = tilledSoilBlockComponentType;
this.query = Query.and(blockStateInfoComponentType, tilledSoilBlockComponentType);
}
@Override @Override
public void onEntityAdded( public void onEntityAdded(
@Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
TilledSoilBlock soilComponent = commandBuffer.getComponent(ref, TilledSoilBlock.getComponentType()); TilledSoilBlock soilComponent = commandBuffer.getComponent(ref, this.tilledSoilBlockComponentType);
assert soilComponent != null; assert soilComponent != null;
BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, this.blockStateInfoComponentType);
assert blockStateInfoComponent != null; assert blockStateInfoComponent != null;
@@ -478,16 +536,41 @@ public class FarmingSystems {
) { ) {
} }
@Nullable @Nonnull
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return QUERY; return this.query;
} }
} }
public static class Ticking extends EntityTickingSystem<ChunkStore> { public static class Ticking extends EntityTickingSystem<ChunkStore> {
@Nonnull @Nonnull
private static final Query<ChunkStore> QUERY = Query.and(BlockSection.getComponentType(), ChunkSection.getComponentType()); private final ComponentType<ChunkStore, BlockSection> blockSectionComponentType;
@Nonnull
private final ComponentType<ChunkStore, ChunkSection> chunkSectionComponentType;
@Nonnull
private final ComponentType<ChunkStore, FarmingBlock> farmingBlockComponentType;
@Nonnull
private final ComponentType<ChunkStore, TilledSoilBlock> tilledSoilBlockComponentType;
@Nonnull
private final ComponentType<ChunkStore, CoopBlock> coopBlockComponentType;
@Nonnull
private final Query<ChunkStore> query;
public Ticking(
@Nonnull ComponentType<ChunkStore, BlockSection> blockSectionComponentType,
@Nonnull ComponentType<ChunkStore, ChunkSection> chunkSectionComponentType,
@Nonnull ComponentType<ChunkStore, FarmingBlock> farmingBlockComponentType,
@Nonnull ComponentType<ChunkStore, TilledSoilBlock> tilledSoilBlockComponentType,
@Nonnull ComponentType<ChunkStore, CoopBlock> coopBlockComponentType
) {
this.blockSectionComponentType = blockSectionComponentType;
this.chunkSectionComponentType = chunkSectionComponentType;
this.farmingBlockComponentType = farmingBlockComponentType;
this.tilledSoilBlockComponentType = tilledSoilBlockComponentType;
this.coopBlockComponentType = coopBlockComponentType;
this.query = Query.and(blockSectionComponentType, chunkSectionComponentType);
}
@Override @Override
public void tick( public void tick(
@@ -497,12 +580,12 @@ public class FarmingSystems {
@Nonnull Store<ChunkStore> store, @Nonnull Store<ChunkStore> store,
@Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
BlockSection blockSectionComponent = archetypeChunk.getComponent(index, BlockSection.getComponentType()); BlockSection blockSectionComponent = archetypeChunk.getComponent(index, this.blockSectionComponentType);
assert blockSectionComponent != null; assert blockSectionComponent != null;
if (blockSectionComponent.getTickingBlocksCountCopy() != 0) { if (blockSectionComponent.getTickingBlocksCountCopy() != 0) {
ChunkSection chunkSectionComponent = archetypeChunk.getComponent(index, ChunkSection.getComponentType()); ChunkSection chunkSectionComponent = archetypeChunk.getComponent(index, this.chunkSectionComponentType);
assert chunkSectionComponent != null; assert chunkSectionComponent != null;
@@ -526,21 +609,21 @@ public class FarmingSystems {
if (blockRef == null) { if (blockRef == null) {
return BlockTickStrategy.IGNORED; return BlockTickStrategy.IGNORED;
} else { } else {
FarmingBlock farmingBlockComponent = commandBuffer1.getComponent(blockRef, FarmingBlock.getComponentType()); FarmingBlock farmingBlockComp = commandBuffer1.getComponent(blockRef, this.farmingBlockComponentType);
if (farmingBlockComponent != null) { if (farmingBlockComp != null) {
FarmingUtil.tickFarming( FarmingUtil.tickFarming(
commandBuffer1, blockChunk, blockSectionComponent, ref, blockRef, farmingBlockComponent, localX, localY, localZ, false commandBuffer1, blockChunk, blockSectionComponent, ref, blockRef, farmingBlockComp, localX, localY, localZ, false
); );
return BlockTickStrategy.SLEEP; return BlockTickStrategy.SLEEP;
} else { } else {
TilledSoilBlock tilledSoilBlockComponent = commandBuffer1.getComponent(blockRef, TilledSoilBlock.getComponentType()); TilledSoilBlock tilledSoilBlockComp = commandBuffer1.getComponent(blockRef, this.tilledSoilBlockComponentType);
if (tilledSoilBlockComponent != null) { if (tilledSoilBlockComp != null) {
tickSoil(commandBuffer1, blockRef, tilledSoilBlockComponent); tickSoil(commandBuffer1, blockRef, tilledSoilBlockComp);
return BlockTickStrategy.SLEEP; return BlockTickStrategy.SLEEP;
} else { } else {
CoopBlock coopBlockComponent = commandBuffer1.getComponent(blockRef, CoopBlock.getComponentType()); CoopBlock coopBlockComp = commandBuffer1.getComponent(blockRef, this.coopBlockComponentType);
if (coopBlockComponent != null) { if (coopBlockComp != null) {
tickCoop(commandBuffer1, blockRef, coopBlockComponent); tickCoop(commandBuffer1, blockRef, coopBlockComp);
return BlockTickStrategy.SLEEP; return BlockTickStrategy.SLEEP;
} else { } else {
return BlockTickStrategy.IGNORED; return BlockTickStrategy.IGNORED;
@@ -711,10 +794,10 @@ public class FarmingSystems {
} }
} }
@Nullable @Nonnull
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return QUERY; return this.query;
} }
} }
} }

View File

@@ -1,6 +1,5 @@
package com.hypixel.hytale.builtin.adventure.farming.config.stages; package com.hypixel.hytale.builtin.adventure.farming.config.stages;
import com.hypixel.hytale.assetstore.AssetPack;
import com.hypixel.hytale.assetstore.AssetRegistry; import com.hypixel.hytale.assetstore.AssetRegistry;
import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap; import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
import com.hypixel.hytale.builtin.adventure.farming.states.FarmingBlock; import com.hypixel.hytale.builtin.adventure.farming.states.FarmingBlock;
@@ -20,7 +19,6 @@ import com.hypixel.hytale.math.util.HashUtil;
import com.hypixel.hytale.math.util.MathUtil; import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.math.vector.Vector3i; import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.BlockMaterial; import com.hypixel.hytale.protocol.BlockMaterial;
import com.hypixel.hytale.server.core.asset.AssetModule;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation; import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple; import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
@@ -38,7 +36,6 @@ import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection; import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.util.PrefabUtil; import com.hypixel.hytale.server.core.util.PrefabUtil;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -456,16 +453,14 @@ public class PrefabFarmingStageData extends FarmingStageData {
@Nonnull @Nonnull
public Path getResolvedPath() { public Path getResolvedPath() {
for (AssetPack pack : AssetModule.get().getAssetPacks()) { Path assetPath = PrefabStore.get().findAssetPrefabPath(this.path);
Path assetPath = pack.getRoot().resolve("Server").resolve("Prefabs").resolve(this.path); if (assetPath == null) {
if (Files.exists(assetPath)) { throw new IllegalStateException("Invalid prefab path: " + this.path);
} else {
return assetPath; return assetPath;
} }
} }
return PrefabStore.get().getAssetPrefabsPath().resolve(this.path);
}
@Nonnull @Nonnull
@Override @Override
public String toString() { public String toString() {

View File

@@ -40,6 +40,7 @@ import com.hypixel.hytale.server.core.asset.type.gameplay.GameplayConfig;
import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.windows.Window; import com.hypixel.hytale.server.core.entity.entities.player.windows.Window;
import com.hypixel.hytale.server.core.io.PacketHandler; import com.hypixel.hytale.server.core.io.PacketHandler;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSystems; import com.hypixel.hytale.server.core.modules.entity.player.PlayerSystems;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.server.OpenCustomUIInteraction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.server.OpenCustomUIInteraction;
@@ -100,9 +101,16 @@ public class MemoriesPlugin extends JavaPlugin {
OpenCustomUIInteraction.registerCustomPageSupplier(this, MemoriesUnlockedPage.class, "MemoriesUnlocked", new MemoriesUnlockedPageSuplier()); OpenCustomUIInteraction.registerCustomPageSupplier(this, MemoriesUnlockedPage.class, "MemoriesUnlocked", new MemoriesUnlockedPageSuplier());
Window.CLIENT_REQUESTABLE_WINDOW_TYPES.put(WindowType.Memories, MemoriesWindow::new); Window.CLIENT_REQUESTABLE_WINDOW_TYPES.put(WindowType.Memories, MemoriesWindow::new);
this.playerMemoriesComponentType = entityStoreRegistry.registerComponent(PlayerMemories.class, "PlayerMemories", PlayerMemories.CODEC); this.playerMemoriesComponentType = entityStoreRegistry.registerComponent(PlayerMemories.class, "PlayerMemories", PlayerMemories.CODEC);
ComponentType<EntityStore, Player> playerComponentType = Player.getComponentType();
ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
ComponentType<EntityStore, TransformComponent> transformComponentType = TransformComponent.getComponentType();
NPCMemoryProvider npcMemoryProvider = new NPCMemoryProvider(); NPCMemoryProvider npcMemoryProvider = new NPCMemoryProvider();
this.registerMemoryProvider(npcMemoryProvider); this.registerMemoryProvider(npcMemoryProvider);
entityStoreRegistry.registerSystem(new NPCMemory.GatherMemoriesSystem(npcMemoryProvider.getCollectionRadius())); entityStoreRegistry.registerSystem(
new NPCMemory.GatherMemoriesSystem(
transformComponentType, playerComponentType, playerRefComponentType, this.playerMemoriesComponentType, npcMemoryProvider.getCollectionRadius()
)
);
for (MemoryProvider<?> provider : this.providers) { for (MemoryProvider<?> provider : this.providers) {
BuilderCodec<? extends Memory> codec = (BuilderCodec<? extends Memory>)provider.getCodec(); BuilderCodec<? extends Memory> codec = (BuilderCodec<? extends Memory>)provider.getCodec();
@@ -110,11 +118,11 @@ public class MemoriesPlugin extends JavaPlugin {
} }
this.getEventRegistry().register(AllNPCsLoadedEvent.class, event -> this.onAssetsLoad()); this.getEventRegistry().register(AllNPCsLoadedEvent.class, event -> this.onAssetsLoad());
entityStoreRegistry.registerSystem(new MemoriesPlugin.PlayerAddedSystem()); entityStoreRegistry.registerSystem(new MemoriesPlugin.PlayerAddedSystem(playerComponentType, playerRefComponentType, this.playerMemoriesComponentType));
this.getCodecRegistry(Interaction.CODEC).register("SetMemoriesCapacity", SetMemoriesCapacityInteraction.class, SetMemoriesCapacityInteraction.CODEC); this.getCodecRegistry(Interaction.CODEC).register("SetMemoriesCapacity", SetMemoriesCapacityInteraction.class, SetMemoriesCapacityInteraction.CODEC);
this.getCodecRegistry(GameplayConfig.PLUGIN_CODEC).register(MemoriesGameplayConfig.class, "Memories", MemoriesGameplayConfig.CODEC); this.getCodecRegistry(GameplayConfig.PLUGIN_CODEC).register(MemoriesGameplayConfig.class, "Memories", MemoriesGameplayConfig.CODEC);
this.getCodecRegistry(Interaction.CODEC).register("MemoriesCondition", MemoriesConditionInteraction.class, MemoriesConditionInteraction.CODEC); this.getCodecRegistry(Interaction.CODEC).register("MemoriesCondition", MemoriesConditionInteraction.class, MemoriesConditionInteraction.CODEC);
entityStoreRegistry.registerSystem(new TempleRespawnPlayersSystem()); entityStoreRegistry.registerSystem(new TempleRespawnPlayersSystem(playerRefComponentType, transformComponentType));
this.getCodecRegistry(GameplayConfig.PLUGIN_CODEC).register(ForgottenTempleConfig.class, "ForgottenTemple", ForgottenTempleConfig.CODEC); this.getCodecRegistry(GameplayConfig.PLUGIN_CODEC).register(ForgottenTempleConfig.class, "ForgottenTemple", ForgottenTempleConfig.CODEC);
} }
@@ -328,7 +336,24 @@ public class MemoriesPlugin extends JavaPlugin {
@Nonnull @Nonnull
private final Set<Dependency<EntityStore>> dependencies = Set.of(new SystemDependency<>(Order.AFTER, PlayerSystems.PlayerSpawnedSystem.class)); private final Set<Dependency<EntityStore>> dependencies = Set.of(new SystemDependency<>(Order.AFTER, PlayerSystems.PlayerSpawnedSystem.class));
@Nonnull @Nonnull
private final Query<EntityStore> query = Query.and(Player.getComponentType(), PlayerRef.getComponentType()); private final ComponentType<EntityStore, Player> playerComponentType;
@Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final ComponentType<EntityStore, PlayerMemories> playerMemoriesComponentType;
@Nonnull
private final Query<EntityStore> query;
public PlayerAddedSystem(
@Nonnull ComponentType<EntityStore, Player> playerComponentType,
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType,
@Nonnull ComponentType<EntityStore, PlayerMemories> playerMemoriesComponentType
) {
this.playerComponentType = playerComponentType;
this.playerRefComponentType = playerRefComponentType;
this.playerMemoriesComponentType = playerMemoriesComponentType;
this.query = Query.and(playerComponentType, playerRefComponentType);
}
@Nonnull @Nonnull
@Override @Override
@@ -346,15 +371,15 @@ public class MemoriesPlugin extends JavaPlugin {
public void onEntityAdded( public void onEntityAdded(
@Nonnull Ref<EntityStore> ref, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull Ref<EntityStore> ref, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
Player playerComponent = store.getComponent(ref, Player.getComponentType()); Player playerComponent = store.getComponent(ref, this.playerComponentType);
assert playerComponent != null; assert playerComponent != null;
PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType()); PlayerRef playerRefComponent = store.getComponent(ref, this.playerRefComponentType);
assert playerRefComponent != null; assert playerRefComponent != null;
PlayerMemories playerMemoriesComponent = store.getComponent(ref, PlayerMemories.getComponentType()); PlayerMemories playerMemoriesComponent = store.getComponent(ref, this.playerMemoriesComponentType);
boolean isFeatureUnlockedByPlayer = playerMemoriesComponent != null; boolean isFeatureUnlockedByPlayer = playerMemoriesComponent != null;
PacketHandler playerConnection = playerRefComponent.getPacketHandler(); PacketHandler playerConnection = playerRefComponent.getPacketHandler();
playerConnection.writeNoCache(new UpdateMemoriesFeatureStatus(isFeatureUnlockedByPlayer)); playerConnection.writeNoCache(new UpdateMemoriesFeatureStatus(isFeatureUnlockedByPlayer));

View File

@@ -13,6 +13,7 @@ import com.hypixel.hytale.codec.validation.Validators;
import com.hypixel.hytale.component.AddReason; import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.ArchetypeChunk; import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Holder; import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
@@ -203,12 +204,29 @@ public class NPCMemory extends Memory {
public static class GatherMemoriesSystem extends EntityTickingSystem<EntityStore> { public static class GatherMemoriesSystem extends EntityTickingSystem<EntityStore> {
@Nonnull @Nonnull
public static final Query<EntityStore> QUERY = Query.and( private final ComponentType<EntityStore, TransformComponent> transformComponentType;
TransformComponent.getComponentType(), Player.getComponentType(), PlayerRef.getComponentType(), PlayerMemories.getComponentType() @Nonnull
); private final ComponentType<EntityStore, Player> playerComponentType;
@Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final ComponentType<EntityStore, PlayerMemories> playerMemoriesComponentType;
@Nonnull
private final Query<EntityStore> query;
private final double radius; private final double radius;
public GatherMemoriesSystem(double radius) { public GatherMemoriesSystem(
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType,
@Nonnull ComponentType<EntityStore, Player> playerComponentType,
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType,
@Nonnull ComponentType<EntityStore, PlayerMemories> playerMemoriesComponentType,
double radius
) {
this.transformComponentType = transformComponentType;
this.playerComponentType = playerComponentType;
this.playerRefComponentType = playerRefComponentType;
this.playerMemoriesComponentType = playerMemoriesComponentType;
this.query = Query.and(transformComponentType, playerComponentType, playerRefComponentType, playerMemoriesComponentType);
this.radius = radius; this.radius = radius;
} }
@@ -220,12 +238,12 @@ public class NPCMemory extends Memory {
@Nonnull Store<EntityStore> store, @Nonnull Store<EntityStore> store,
@Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
Player playerComponent = archetypeChunk.getComponent(index, Player.getComponentType()); Player playerComponent = archetypeChunk.getComponent(index, this.playerComponentType);
assert playerComponent != null; assert playerComponent != null;
if (playerComponent.getGameMode() == GameMode.Adventure) { if (playerComponent.getGameMode() == GameMode.Adventure) {
TransformComponent transformComponent = archetypeChunk.getComponent(index, TransformComponent.getComponentType()); TransformComponent transformComponent = archetypeChunk.getComponent(index, this.transformComponentType);
assert transformComponent != null; assert transformComponent != null;
@@ -234,13 +252,13 @@ public class NPCMemory extends Memory {
ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList(); ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
npcSpatialResource.getSpatialStructure().collect(position, this.radius, results); npcSpatialResource.getSpatialStructure().collect(position, this.radius, results);
if (!results.isEmpty()) { if (!results.isEmpty()) {
PlayerRef playerRefComponent = archetypeChunk.getComponent(index, PlayerRef.getComponentType()); PlayerRef playerRefComponent = archetypeChunk.getComponent(index, this.playerRefComponentType);
assert playerRefComponent != null; assert playerRefComponent != null;
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index); Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
MemoriesPlugin memoriesPlugin = MemoriesPlugin.get(); MemoriesPlugin memoriesPlugin = MemoriesPlugin.get();
PlayerMemories playerMemoriesComponent = archetypeChunk.getComponent(index, PlayerMemories.getComponentType()); PlayerMemories playerMemoriesComponent = archetypeChunk.getComponent(index, this.playerMemoriesComponentType);
assert playerMemoriesComponent != null; assert playerMemoriesComponent != null;
@@ -351,7 +369,7 @@ public class NPCMemory extends Memory {
@Nonnull @Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return QUERY; return this.query;
} }
} }
} }

View File

@@ -2,6 +2,7 @@ package com.hypixel.hytale.builtin.adventure.memories.temple;
import com.hypixel.hytale.component.ArchetypeChunk; import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
@@ -18,14 +19,22 @@ import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.spawn.ISpawnProvider; import com.hypixel.hytale.server.core.universe.world.spawn.ISpawnProvider;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class TempleRespawnPlayersSystem extends DelayedEntitySystem<EntityStore> { public class TempleRespawnPlayersSystem extends DelayedEntitySystem<EntityStore> {
@Nonnull @Nonnull
public static final Query<EntityStore> QUERY = Query.and(PlayerRef.getComponentType(), TransformComponent.getComponentType()); private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull
private final Query<EntityStore> query;
public TempleRespawnPlayersSystem() { public TempleRespawnPlayersSystem(
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType, @Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType
) {
super(1.0F); super(1.0F);
this.playerRefComponentType = playerRefComponentType;
this.transformComponentType = transformComponentType;
this.query = Query.and(playerRefComponentType, transformComponentType);
} }
@Override @Override
@@ -40,7 +49,7 @@ public class TempleRespawnPlayersSystem extends DelayedEntitySystem<EntityStore>
GameplayConfig gameplayConfig = world.getGameplayConfig(); GameplayConfig gameplayConfig = world.getGameplayConfig();
ForgottenTempleConfig config = gameplayConfig.getPluginConfig().get(ForgottenTempleConfig.class); ForgottenTempleConfig config = gameplayConfig.getPluginConfig().get(ForgottenTempleConfig.class);
if (config != null) { if (config != null) {
TransformComponent transformComponent = archetypeChunk.getComponent(index, TransformComponent.getComponentType()); TransformComponent transformComponent = archetypeChunk.getComponent(index, this.transformComponentType);
assert transformComponent != null; assert transformComponent != null;
@@ -51,15 +60,18 @@ public class TempleRespawnPlayersSystem extends DelayedEntitySystem<EntityStore>
Transform spawnTransform = spawnProvider.getSpawnPoint(ref, commandBuffer); Transform spawnTransform = spawnProvider.getSpawnPoint(ref, commandBuffer);
Teleport teleportComponent = Teleport.createForPlayer(null, spawnTransform); Teleport teleportComponent = Teleport.createForPlayer(null, spawnTransform);
commandBuffer.addComponent(ref, Teleport.getComponentType(), teleportComponent); commandBuffer.addComponent(ref, Teleport.getComponentType(), teleportComponent);
PlayerRef playerRef = archetypeChunk.getComponent(index, PlayerRef.getComponentType()); PlayerRef playerRefComponent = archetypeChunk.getComponent(index, this.playerRefComponentType);
SoundUtil.playSoundEvent2dToPlayer(playerRef, config.getRespawnSoundIndex(), SoundCategory.SFX);
assert playerRefComponent != null;
SoundUtil.playSoundEvent2dToPlayer(playerRefComponent, config.getRespawnSoundIndex(), SoundCategory.SFX);
} }
} }
} }
@Nullable @Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return QUERY; return this.query;
} }
} }

View File

@@ -24,6 +24,7 @@ import com.hypixel.hytale.builtin.adventure.objectives.task.ObjectiveTask;
import com.hypixel.hytale.builtin.adventure.objectives.task.UseEntityObjectiveTask; import com.hypixel.hytale.builtin.adventure.objectives.task.UseEntityObjectiveTask;
import com.hypixel.hytale.builtin.tagset.config.NPCGroup; import com.hypixel.hytale.builtin.tagset.config.NPCGroup;
import com.hypixel.hytale.component.ComponentRegistryProxy; import com.hypixel.hytale.component.ComponentRegistryProxy;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ResourceType; import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
@@ -34,8 +35,10 @@ import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.NPCPlugin; import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.server.spawning.assets.spawnmarker.config.SpawnMarker; import com.hypixel.hytale.server.spawning.assets.spawnmarker.config.SpawnMarker;
import com.hypixel.hytale.server.spawning.assets.spawns.config.BeaconNPCSpawn; import com.hypixel.hytale.server.spawning.assets.spawns.config.BeaconNPCSpawn;
import com.hypixel.hytale.server.spawning.beacons.LegacySpawnBeaconEntity;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@@ -91,9 +94,11 @@ public class NPCObjectivesPlugin extends JavaPlugin {
KillNPCObjectiveTask.CODEC, KillNPCObjectiveTask.CODEC,
KillNPCObjectiveTask::new KillNPCObjectiveTask::new
); );
entityStoreRegistry.registerSystem(new SpawnBeaconCheckRemovalSystem());
this.killTrackerResourceType = entityStoreRegistry.registerResource(KillTrackerResource.class, KillTrackerResource::new); this.killTrackerResourceType = entityStoreRegistry.registerResource(KillTrackerResource.class, KillTrackerResource::new);
entityStoreRegistry.registerSystem(new KillTrackerSystem()); ComponentType<EntityStore, LegacySpawnBeaconEntity> legacySpawnBeaconEntityComponentType = LegacySpawnBeaconEntity.getComponentType();
ComponentType<EntityStore, NPCEntity> npcEntityComponentType = NPCEntity.getComponentType();
entityStoreRegistry.registerSystem(new SpawnBeaconCheckRemovalSystem(legacySpawnBeaconEntityComponentType));
entityStoreRegistry.registerSystem(new KillTrackerSystem(npcEntityComponentType, this.killTrackerResourceType));
NPCPlugin.get() NPCPlugin.get()
.registerCoreComponentType("CompleteTask", BuilderActionCompleteTask::new) .registerCoreComponentType("CompleteTask", BuilderActionCompleteTask::new)
.registerCoreComponentType("StartObjective", BuilderActionStartObjective::new) .registerCoreComponentType("StartObjective", BuilderActionStartObjective::new)

View File

@@ -3,7 +3,9 @@ package com.hypixel.hytale.builtin.adventure.npcobjectives.systems;
import com.hypixel.hytale.builtin.adventure.npcobjectives.resources.KillTrackerResource; import com.hypixel.hytale.builtin.adventure.npcobjectives.resources.KillTrackerResource;
import com.hypixel.hytale.builtin.adventure.npcobjectives.transaction.KillTaskTransaction; import com.hypixel.hytale.builtin.adventure.npcobjectives.transaction.KillTaskTransaction;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.server.core.modules.entity.damage.Damage; import com.hypixel.hytale.server.core.modules.entity.damage.Damage;
@@ -13,23 +15,34 @@ import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.entities.NPCEntity; import com.hypixel.hytale.server.npc.entities.NPCEntity;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class KillTrackerSystem extends DeathSystems.OnDeathSystem { public class KillTrackerSystem extends DeathSystems.OnDeathSystem {
@Nullable @Nonnull
private final ComponentType<EntityStore, NPCEntity> npcEntityComponentType;
@Nonnull
private final ResourceType<EntityStore, KillTrackerResource> killTrackerResourceType;
public KillTrackerSystem(
@Nonnull ComponentType<EntityStore, NPCEntity> npcEntityComponentType, @Nonnull ResourceType<EntityStore, KillTrackerResource> killTrackerResourceType
) {
this.npcEntityComponentType = npcEntityComponentType;
this.killTrackerResourceType = killTrackerResourceType;
}
@Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return NPCEntity.getComponentType(); return this.npcEntityComponentType;
} }
public void onComponentAdded( public void onComponentAdded(
@Nonnull Ref<EntityStore> ref, @Nonnull DeathComponent component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull Ref<EntityStore> ref, @Nonnull DeathComponent component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
NPCEntity npcEntityComponent = store.getComponent(ref, NPCEntity.getComponentType()); NPCEntity npcEntityComponent = store.getComponent(ref, this.npcEntityComponentType);
assert npcEntityComponent != null; assert npcEntityComponent != null;
KillTrackerResource killTrackerResource = store.getResource(KillTrackerResource.getResourceType()); KillTrackerResource killTrackerResource = store.getResource(this.killTrackerResourceType);
List<KillTaskTransaction> killTasks = killTrackerResource.getKillTasks(); List<KillTaskTransaction> killTasks = killTrackerResource.getKillTasks();
Damage deathInfo = component.getDeathInfo(); Damage deathInfo = component.getDeathInfo();
if (deathInfo != null) { if (deathInfo != null) {

View File

@@ -2,6 +2,7 @@ package com.hypixel.hytale.builtin.adventure.npcobjectives.systems;
import com.hypixel.hytale.builtin.adventure.objectives.ObjectivePlugin; import com.hypixel.hytale.builtin.adventure.objectives.ObjectivePlugin;
import com.hypixel.hytale.component.AddReason; import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Holder; import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.RemoveReason; import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
@@ -11,18 +12,24 @@ import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.spawning.beacons.LegacySpawnBeaconEntity; import com.hypixel.hytale.server.spawning.beacons.LegacySpawnBeaconEntity;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class SpawnBeaconCheckRemovalSystem extends HolderSystem<EntityStore> { public class SpawnBeaconCheckRemovalSystem extends HolderSystem<EntityStore> {
@Nullable @Nonnull
private final ComponentType<EntityStore, LegacySpawnBeaconEntity> legacySpawnBeaconEntityComponentType;
public SpawnBeaconCheckRemovalSystem(@Nonnull ComponentType<EntityStore, LegacySpawnBeaconEntity> legacySpawnBeaconEntityComponentType) {
this.legacySpawnBeaconEntityComponentType = legacySpawnBeaconEntityComponentType;
}
@Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return LegacySpawnBeaconEntity.getComponentType(); return this.legacySpawnBeaconEntityComponentType;
} }
@Override @Override
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) { public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
LegacySpawnBeaconEntity spawnBeaconComponent = holder.getComponent(LegacySpawnBeaconEntity.getComponentType()); LegacySpawnBeaconEntity spawnBeaconComponent = holder.getComponent(this.legacySpawnBeaconEntityComponentType);
assert spawnBeaconComponent != null; assert spawnBeaconComponent != null;

View File

@@ -19,12 +19,14 @@ import javax.annotation.Nonnull;
public class NPCReputationHolderSystem extends HolderSystem<EntityStore> { public class NPCReputationHolderSystem extends HolderSystem<EntityStore> {
@Nonnull @Nonnull
private final ComponentType<EntityStore, ReputationGroupComponent> reputationGroupComponentType; private final ComponentType<EntityStore, ReputationGroupComponent> reputationGroupComponentType;
@Nonnull
private final ComponentType<EntityStore, NPCEntity> npcEntityComponentType; private final ComponentType<EntityStore, NPCEntity> npcEntityComponentType;
@Nonnull @Nonnull
private final Query<EntityStore> query; private final Query<EntityStore> query;
public NPCReputationHolderSystem( public NPCReputationHolderSystem(
@Nonnull ComponentType<EntityStore, ReputationGroupComponent> reputationGroupComponentType, ComponentType<EntityStore, NPCEntity> npcEntityComponentType @Nonnull ComponentType<EntityStore, ReputationGroupComponent> reputationGroupComponentType,
@Nonnull ComponentType<EntityStore, NPCEntity> npcEntityComponentType
) { ) {
this.reputationGroupComponentType = reputationGroupComponentType; this.reputationGroupComponentType = reputationGroupComponentType;
this.npcEntityComponentType = npcEntityComponentType; this.npcEntityComponentType = npcEntityComponentType;

View File

@@ -2,9 +2,13 @@ package com.hypixel.hytale.builtin.adventure.npcreputation;
import com.hypixel.hytale.builtin.adventure.reputation.ReputationGroupComponent; import com.hypixel.hytale.builtin.adventure.reputation.ReputationGroupComponent;
import com.hypixel.hytale.component.ComponentRegistryProxy; import com.hypixel.hytale.component.ComponentRegistryProxy;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.blackboard.Blackboard;
import com.hypixel.hytale.server.npc.entities.NPCEntity; import com.hypixel.hytale.server.npc.entities.NPCEntity;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -16,7 +20,11 @@ public class NPCReputationPlugin extends JavaPlugin {
@Override @Override
protected void setup() { protected void setup() {
ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry(); ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry();
entityStoreRegistry.registerSystem(new ReputationAttitudeSystem()); ResourceType<EntityStore, Blackboard> blackboardResourceType = Blackboard.getResourceType();
entityStoreRegistry.registerSystem(new NPCReputationHolderSystem(ReputationGroupComponent.getComponentType(), NPCEntity.getComponentType())); ComponentType<EntityStore, Player> playerComponentType = Player.getComponentType();
ComponentType<EntityStore, ReputationGroupComponent> reputationGroupComponentType = ReputationGroupComponent.getComponentType();
ComponentType<EntityStore, NPCEntity> npcEntityComponentType = NPCEntity.getComponentType();
entityStoreRegistry.registerSystem(new ReputationAttitudeSystem(blackboardResourceType, playerComponentType));
entityStoreRegistry.registerSystem(new NPCReputationHolderSystem(reputationGroupComponentType, npcEntityComponentType));
} }
} }

View File

@@ -1,6 +1,7 @@
package com.hypixel.hytale.builtin.adventure.npcreputation; package com.hypixel.hytale.builtin.adventure.npcreputation;
import com.hypixel.hytale.builtin.adventure.reputation.ReputationPlugin; import com.hypixel.hytale.builtin.adventure.reputation.ReputationPlugin;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.ResourceType; import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.system.StoreSystem; import com.hypixel.hytale.component.system.StoreSystem;
@@ -12,14 +13,23 @@ import javax.annotation.Nonnull;
public class ReputationAttitudeSystem extends StoreSystem<EntityStore> { public class ReputationAttitudeSystem extends StoreSystem<EntityStore> {
@Nonnull @Nonnull
private final ResourceType<EntityStore, Blackboard> resourceType = Blackboard.getResourceType(); private final ResourceType<EntityStore, Blackboard> blackboardResourceType;
@Nonnull
private final ComponentType<EntityStore, Player> playerComponentType;
public ReputationAttitudeSystem(
@Nonnull ResourceType<EntityStore, Blackboard> blackboardResourceType, @Nonnull ComponentType<EntityStore, Player> playerComponentType
) {
this.blackboardResourceType = blackboardResourceType;
this.playerComponentType = playerComponentType;
}
@Override @Override
public void onSystemAddedToStore(@Nonnull Store<EntityStore> store) { public void onSystemAddedToStore(@Nonnull Store<EntityStore> store) {
Blackboard blackboardResource = store.getResource(this.resourceType); Blackboard blackboardResource = store.getResource(this.blackboardResourceType);
AttitudeView attitudeView = blackboardResource.getView(AttitudeView.class, 0L); AttitudeView attitudeView = blackboardResource.getView(AttitudeView.class, 0L);
attitudeView.registerProvider(100, (ref, role, targetRef, accessor) -> { attitudeView.registerProvider(100, (ref, role, targetRef, accessor) -> {
Player playerComponent = store.getComponent(targetRef, Player.getComponentType()); Player playerComponent = store.getComponent(targetRef, this.playerComponentType);
return playerComponent == null ? null : ReputationPlugin.get().getAttitude(store, targetRef, ref); return playerComponent == null ? null : ReputationPlugin.get().getAttitude(store, targetRef, ref);
}); });
} }

View File

@@ -45,10 +45,12 @@ import com.hypixel.hytale.builtin.adventure.objectives.task.ReachLocationTask;
import com.hypixel.hytale.builtin.adventure.objectives.task.TreasureMapObjectiveTask; import com.hypixel.hytale.builtin.adventure.objectives.task.TreasureMapObjectiveTask;
import com.hypixel.hytale.builtin.adventure.objectives.task.UseBlockObjectiveTask; import com.hypixel.hytale.builtin.adventure.objectives.task.UseBlockObjectiveTask;
import com.hypixel.hytale.builtin.adventure.objectives.task.UseEntityObjectiveTask; import com.hypixel.hytale.builtin.adventure.objectives.task.UseEntityObjectiveTask;
import com.hypixel.hytale.builtin.weather.components.WeatherTracker;
import com.hypixel.hytale.codec.Codec; import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec; import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec; import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.common.util.ArrayUtil; import com.hypixel.hytale.common.util.ArrayUtil;
import com.hypixel.hytale.component.ComponentRegistryProxy;
import com.hypixel.hytale.component.ComponentType; import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ResourceType; import com.hypixel.hytale.component.ResourceType;
@@ -56,6 +58,7 @@ import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.AndQuery; import com.hypixel.hytale.component.query.AndQuery;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.spatial.SpatialResource; import com.hypixel.hytale.component.spatial.SpatialResource;
import com.hypixel.hytale.event.EventRegistry;
import com.hypixel.hytale.function.function.TriFunction; import com.hypixel.hytale.function.function.TriFunction;
import com.hypixel.hytale.math.vector.Vector3f; import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.protocol.packets.assets.TrackOrUpdateObjective; import com.hypixel.hytale.protocol.packets.assets.TrackOrUpdateObjective;
@@ -71,7 +74,6 @@ import com.hypixel.hytale.server.core.asset.type.item.config.ItemDropList;
import com.hypixel.hytale.server.core.asset.type.model.config.Model; import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset; import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.core.asset.type.weather.config.Weather; import com.hypixel.hytale.server.core.asset.type.weather.config.Weather;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.entity.UUIDComponent; import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerConfigData; import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerConfigData;
@@ -83,9 +85,11 @@ import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent; import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel; import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.prefab.PrefabCopyableComponent;
import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.Universe; import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.datastore.DataStoreProvider; import com.hypixel.hytale.server.core.universe.datastore.DataStoreProvider;
@@ -123,6 +127,7 @@ public class ObjectivePlugin extends JavaPlugin {
private ComponentType<EntityStore, ObjectiveHistoryComponent> objectiveHistoryComponentType; private ComponentType<EntityStore, ObjectiveHistoryComponent> objectiveHistoryComponentType;
private ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponentType; private ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponentType;
private ComponentType<EntityStore, ObjectiveLocationMarker> objectiveLocationMarkerComponentType; private ComponentType<EntityStore, ObjectiveLocationMarker> objectiveLocationMarkerComponentType;
@Nullable
private ObjectiveDataStore objectiveDataStore; private ObjectiveDataStore objectiveDataStore;
public static ObjectivePlugin get() { public static ObjectivePlugin get() {
@@ -141,6 +146,7 @@ public class ObjectivePlugin extends JavaPlugin {
return this.objectiveLocationMarkerModel; return this.objectiveLocationMarkerModel;
} }
@Nullable
public ObjectiveDataStore getObjectiveDataStore() { public ObjectiveDataStore getObjectiveDataStore() {
return this.objectiveDataStore; return this.objectiveDataStore;
} }
@@ -148,6 +154,8 @@ public class ObjectivePlugin extends JavaPlugin {
@Override @Override
protected void setup() { protected void setup() {
instance = this; instance = this;
EventRegistry eventRegistry = this.getEventRegistry();
ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry();
AssetRegistry.register( AssetRegistry.register(
((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder( ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(
ObjectiveAsset.class, new DefaultAssetMap() ObjectiveAsset.class, new DefaultAssetMap()
@@ -189,10 +197,10 @@ public class ObjectivePlugin extends JavaPlugin {
.build() .build()
); );
this.objectiveDataStore = new ObjectiveDataStore(this.config.get().getDataStoreProvider().create(Objective.CODEC)); this.objectiveDataStore = new ObjectiveDataStore(this.config.get().getDataStoreProvider().create(Objective.CODEC));
this.reachLocationMarkerComponentType = this.getEntityStoreRegistry() this.reachLocationMarkerComponentType = entityStoreRegistry.registerComponent(ReachLocationMarker.class, "ReachLocationMarker", ReachLocationMarker.CODEC);
.registerComponent(ReachLocationMarker.class, "ReachLocationMarker", ReachLocationMarker.CODEC); this.objectiveLocationMarkerComponentType = entityStoreRegistry.registerComponent(
this.objectiveLocationMarkerComponentType = this.getEntityStoreRegistry() ObjectiveLocationMarker.class, "ObjectiveLocation", ObjectiveLocationMarker.CODEC
.registerComponent(ObjectiveLocationMarker.class, "ObjectiveLocation", ObjectiveLocationMarker.CODEC); );
this.registerTask( this.registerTask(
"Craft", CraftObjectiveTaskAsset.class, CraftObjectiveTaskAsset.CODEC, CraftObjectiveTask.class, CraftObjectiveTask.CODEC, CraftObjectiveTask::new "Craft", CraftObjectiveTaskAsset.class, CraftObjectiveTaskAsset.CODEC, CraftObjectiveTask.class, CraftObjectiveTask.CODEC, CraftObjectiveTask::new
); );
@@ -235,45 +243,63 @@ public class ObjectivePlugin extends JavaPlugin {
this.registerCompletion( this.registerCompletion(
"ClearObjectiveItems", ClearObjectiveItemsCompletionAsset.class, ClearObjectiveItemsCompletionAsset.CODEC, ClearObjectiveItemsCompletion::new "ClearObjectiveItems", ClearObjectiveItemsCompletionAsset.class, ClearObjectiveItemsCompletionAsset.CODEC, ClearObjectiveItemsCompletion::new
); );
this.getEventRegistry().register(LoadedAssetsEvent.class, ObjectiveLineAsset.class, this::onObjectiveLineAssetLoaded); eventRegistry.register(LoadedAssetsEvent.class, ObjectiveLineAsset.class, this::onObjectiveLineAssetLoaded);
this.getEventRegistry().register(LoadedAssetsEvent.class, ObjectiveAsset.class, this::onObjectiveAssetLoaded); eventRegistry.register(LoadedAssetsEvent.class, ObjectiveAsset.class, this::onObjectiveAssetLoaded);
this.getEventRegistry().register(PlayerDisconnectEvent.class, this::onPlayerDisconnect); eventRegistry.register(PlayerDisconnectEvent.class, this::onPlayerDisconnect);
this.getEventRegistry().register(LoadedAssetsEvent.class, ObjectiveLocationMarkerAsset.class, ObjectivePlugin::onObjectiveLocationMarkerChange); eventRegistry.register(LoadedAssetsEvent.class, ObjectiveLocationMarkerAsset.class, ObjectivePlugin::onObjectiveLocationMarkerChange);
this.getEventRegistry().register(LoadedAssetsEvent.class, ModelAsset.class, this::onModelAssetChange); eventRegistry.register(LoadedAssetsEvent.class, ModelAsset.class, this::onModelAssetChange);
this.getEventRegistry().registerGlobal(LivingEntityInventoryChangeEvent.class, this::onLivingEntityInventoryChange); eventRegistry.registerGlobal(LivingEntityInventoryChangeEvent.class, this::onLivingEntityInventoryChange);
this.getEventRegistry().registerGlobal(AddWorldEvent.class, this::onWorldAdded); eventRegistry.registerGlobal(AddWorldEvent.class, this::onWorldAdded);
this.getCommandRegistry().registerCommand(new ObjectiveCommand()); this.getCommandRegistry().registerCommand(new ObjectiveCommand());
EntityModule entityModule = EntityModule.get(); EntityModule entityModule = EntityModule.get();
ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType(); ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent = entityModule.getPlayerSpatialResourceType(); ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent = entityModule.getPlayerSpatialResourceType();
this.getEntityStoreRegistry().registerSystem(new ReachLocationMarkerSystems.EntityAdded(this.reachLocationMarkerComponentType)); ComponentType<EntityStore, NetworkId> networkIdComponentType = NetworkId.getComponentType();
this.getEntityStoreRegistry().registerSystem(new ReachLocationMarkerSystems.EnsureNetworkSendable()); ComponentType<EntityStore, TransformComponent> transformComponentType = TransformComponent.getComponentType();
this.getEntityStoreRegistry().registerSystem(new ReachLocationMarkerSystems.Ticking(this.reachLocationMarkerComponentType, playerSpatialComponent)); ComponentType<EntityStore, UUIDComponent> uuidComponentType = UUIDComponent.getComponentType();
this.getEntityStoreRegistry().registerSystem(new ObjectiveLocationMarkerSystems.EnsureNetworkSendableSystem()); ComponentType<EntityStore, WeatherTracker> weatherTrackerComponentType = WeatherTracker.getComponentType();
this.getEntityStoreRegistry().registerSystem(new ObjectiveLocationMarkerSystems.InitSystem(this.objectiveLocationMarkerComponentType)); ComponentType<EntityStore, ModelComponent> modelComponentType = ModelComponent.getComponentType();
this.getEntityStoreRegistry() ComponentType<EntityStore, PrefabCopyableComponent> prefabCopyableComponentType = PrefabCopyableComponent.getComponentType();
.registerSystem( entityStoreRegistry.registerSystem(new ReachLocationMarkerSystems.EntityAdded(this.reachLocationMarkerComponentType, transformComponentType));
new ObjectiveLocationMarkerSystems.TickingSystem(this.objectiveLocationMarkerComponentType, playerRefComponentType, playerSpatialComponent) entityStoreRegistry.registerSystem(new ReachLocationMarkerSystems.EnsureNetworkSendable(this.reachLocationMarkerComponentType, networkIdComponentType));
entityStoreRegistry.registerSystem(
new ReachLocationMarkerSystems.Ticking(this.reachLocationMarkerComponentType, playerSpatialComponent, transformComponentType, uuidComponentType)
);
entityStoreRegistry.registerSystem(
new ObjectiveLocationMarkerSystems.EnsureNetworkSendableSystem(this.objectiveLocationMarkerComponentType, networkIdComponentType)
);
entityStoreRegistry.registerSystem(
new ObjectiveLocationMarkerSystems.InitSystem(
this.objectiveLocationMarkerComponentType, modelComponentType, transformComponentType, prefabCopyableComponentType
)
);
entityStoreRegistry.registerSystem(
new ObjectiveLocationMarkerSystems.TickingSystem(
this.objectiveLocationMarkerComponentType,
playerRefComponentType,
playerSpatialComponent,
transformComponentType,
weatherTrackerComponentType,
uuidComponentType
)
); );
CommonObjectiveHistoryData.CODEC.register("Objective", ObjectiveHistoryData.class, ObjectiveHistoryData.CODEC); CommonObjectiveHistoryData.CODEC.register("Objective", ObjectiveHistoryData.class, ObjectiveHistoryData.CODEC);
CommonObjectiveHistoryData.CODEC.register("ObjectiveLine", ObjectiveLineHistoryData.class, ObjectiveLineHistoryData.CODEC); CommonObjectiveHistoryData.CODEC.register("ObjectiveLine", ObjectiveLineHistoryData.class, ObjectiveLineHistoryData.CODEC);
ObjectiveRewardHistoryData.CODEC.register("Item", ItemObjectiveRewardHistoryData.class, ItemObjectiveRewardHistoryData.CODEC); ObjectiveRewardHistoryData.CODEC.register("Item", ItemObjectiveRewardHistoryData.class, ItemObjectiveRewardHistoryData.CODEC);
this.objectiveHistoryComponentType = this.getEntityStoreRegistry() this.objectiveHistoryComponentType = entityStoreRegistry.registerComponent(
.registerComponent(ObjectiveHistoryComponent.class, "ObjectiveHistory", ObjectiveHistoryComponent.CODEC); ObjectiveHistoryComponent.class, "ObjectiveHistory", ObjectiveHistoryComponent.CODEC
this.getEntityStoreRegistry().registerSystem(new ObjectivePlayerSetupSystem(this.objectiveHistoryComponentType, Player.getComponentType())); );
this.getEntityStoreRegistry().registerSystem(new ObjectiveItemEntityRemovalSystem()); entityStoreRegistry.registerSystem(new ObjectivePlayerSetupSystem(this.objectiveHistoryComponentType, Player.getComponentType()));
entityStoreRegistry.registerSystem(new ObjectiveItemEntityRemovalSystem());
this.getCodecRegistry(Interaction.CODEC).register("StartObjective", StartObjectiveInteraction.class, StartObjectiveInteraction.CODEC); this.getCodecRegistry(Interaction.CODEC).register("StartObjective", StartObjectiveInteraction.class, StartObjectiveInteraction.CODEC);
this.getCodecRegistry(Interaction.CODEC).register("CanBreakRespawnPoint", CanBreakRespawnPointInteraction.class, CanBreakRespawnPointInteraction.CODEC); this.getCodecRegistry(Interaction.CODEC).register("CanBreakRespawnPoint", CanBreakRespawnPointInteraction.class, CanBreakRespawnPointInteraction.CODEC);
BlockStateModule.get().registerBlockState(TreasureChestState.class, "TreasureChest", TreasureChestState.CODEC); BlockStateModule.get().registerBlockState(TreasureChestState.class, "TreasureChest", TreasureChestState.CODEC);
this.getCodecRegistry(GameplayConfig.PLUGIN_CODEC).register(ObjectiveGameplayConfig.class, "Objective", ObjectiveGameplayConfig.CODEC); this.getCodecRegistry(GameplayConfig.PLUGIN_CODEC).register(ObjectiveGameplayConfig.class, "Objective", ObjectiveGameplayConfig.CODEC);
this.getEntityStoreRegistry() entityStoreRegistry.registerSystem(
.registerSystem(
new EntityModule.TangibleMigrationSystem(Query.or(ObjectiveLocationMarker.getComponentType(), ReachLocationMarker.getComponentType())), true new EntityModule.TangibleMigrationSystem(Query.or(ObjectiveLocationMarker.getComponentType(), ReachLocationMarker.getComponentType())), true
); );
this.getEntityStoreRegistry() entityStoreRegistry.registerSystem(
.registerSystem( new EntityModule.HiddenFromPlayerMigrationSystem(Query.or(ObjectiveLocationMarker.getComponentType(), ReachLocationMarker.getComponentType())), true
new EntityModule.HiddenFromPlayerMigrationSystem(Query.or(ObjectiveLocationMarker.getComponentType(), ReachLocationMarker.getComponentType())),
true
); );
} }
@@ -284,14 +310,18 @@ public class ObjectivePlugin extends JavaPlugin {
throw new IllegalStateException(String.format("Default objective location marker model '%s' not found", "Objective_Location_Marker")); throw new IllegalStateException(String.format("Default objective location marker model '%s' not found", "Objective_Location_Marker"));
} else { } else {
this.objectiveLocationMarkerModel = Model.createUnitScaleModel(modelAsset); this.objectiveLocationMarkerModel = Model.createUnitScaleModel(modelAsset);
if (this.objectiveDataStore != null) {
HytaleServer.SCHEDULED_EXECUTOR.scheduleWithFixedDelay(() -> this.objectiveDataStore.saveToDiskAllObjectives(), 5L, 5L, TimeUnit.MINUTES); HytaleServer.SCHEDULED_EXECUTOR.scheduleWithFixedDelay(() -> this.objectiveDataStore.saveToDiskAllObjectives(), 5L, 5L, TimeUnit.MINUTES);
} }
} }
}
@Override @Override
protected void shutdown() { protected void shutdown() {
if (this.objectiveDataStore != null) {
this.objectiveDataStore.saveToDiskAllObjectives(); this.objectiveDataStore.saveToDiskAllObjectives();
} }
}
public ComponentType<EntityStore, ReachLocationMarker> getReachLocationMarkerComponentType() { public ComponentType<EntityStore, ReachLocationMarker> getReachLocationMarkerComponentType() {
return this.reachLocationMarkerComponentType; return this.reachLocationMarkerComponentType;
@@ -309,11 +339,13 @@ public class ObjectivePlugin extends JavaPlugin {
Codec<U> implementationCodec, Codec<U> implementationCodec,
TriFunction<T, Integer, Integer, U> generator TriFunction<T, Integer, Integer, U> generator
) { ) {
if (this.objectiveDataStore != null) {
ObjectiveTaskAsset.CODEC.register(id, assetClass, assetCodec); ObjectiveTaskAsset.CODEC.register(id, assetClass, assetCodec);
ObjectiveTask.CODEC.register(id, implementationClass, implementationCodec); ObjectiveTask.CODEC.register(id, implementationClass, implementationCodec);
this.taskGenerators.put(assetClass, generator); this.taskGenerators.put(assetClass, generator);
this.objectiveDataStore.registerTaskRef(implementationClass); this.objectiveDataStore.registerTaskRef(implementationClass);
} }
}
public <T extends ObjectiveCompletionAsset, U extends ObjectiveCompletion> void registerCompletion( public <T extends ObjectiveCompletionAsset, U extends ObjectiveCompletion> void registerCompletion(
String id, Class<T> assetClass, Codec<T> codec, Function<T, U> generator String id, Class<T> assetClass, Codec<T> codec, Function<T, U> generator
@@ -346,6 +378,9 @@ public class ObjectivePlugin extends JavaPlugin {
@Nullable UUID markerUUID, @Nullable UUID markerUUID,
@Nonnull Store<EntityStore> store @Nonnull Store<EntityStore> store
) { ) {
if (this.objectiveDataStore == null) {
return null;
} else {
ObjectiveAsset asset = ObjectiveAsset.getAssetMap().getAsset(objectiveId); ObjectiveAsset asset = ObjectiveAsset.getAssetMap().getAsset(objectiveId);
if (asset == null) { if (asset == null) {
this.getLogger().at(Level.WARNING).log("Failed to find objective asset '%s'", objectiveId); this.getLogger().at(Level.WARNING).log("Failed to find objective asset '%s'", objectiveId);
@@ -375,11 +410,14 @@ public class ObjectivePlugin extends JavaPlugin {
} else { } else {
TrackOrUpdateObjective trackObjectivePacket = new TrackOrUpdateObjective(objective.toPacket()); TrackOrUpdateObjective trackObjectivePacket = new TrackOrUpdateObjective(objective.toPacket());
String objectiveAssetId = asset.getId(); String objectiveAssetId = asset.getId();
objective.forEachParticipant(participantReference -> { objective.forEachParticipant(
participantReference -> {
Player playerComponent = store.getComponent(participantReference, Player.getComponentType()); Player playerComponent = store.getComponent(participantReference, Player.getComponentType());
if (playerComponent != null) { if (playerComponent != null) {
if (!this.canPlayerDoObjective(playerComponent, objectiveAssetId)) { if (!this.canPlayerDoObjective(playerComponent, objectiveAssetId)) {
playerComponent.sendMessage(Message.translation("server.modules.objective.playerAlreadyDoingObjective").param("title", assetTitleMessage)); playerComponent.sendMessage(
Message.translation("server.modules.objective.playerAlreadyDoingObjective").param("title", assetTitleMessage)
);
} else { } else {
PlayerRef playerRefComponent = store.getComponent(participantReference, PlayerRef.getComponentType()); PlayerRef playerRefComponent = store.getComponent(participantReference, PlayerRef.getComponentType());
@@ -398,14 +436,19 @@ public class ObjectivePlugin extends JavaPlugin {
playerRefComponent.getPacketHandler().writeNoCache(trackObjectivePacket); playerRefComponent.getPacketHandler().writeNoCache(trackObjectivePacket);
} }
} }
}); }
);
objective.markDirty(); objective.markDirty();
return objective; return objective;
} }
} }
} }
}
public boolean canPlayerDoObjective(@Nonnull Player player, @Nonnull String objectiveAssetId) { public boolean canPlayerDoObjective(@Nonnull Player player, @Nonnull String objectiveAssetId) {
if (this.objectiveDataStore == null) {
return false;
} else {
Set<UUID> activeObjectiveUUIDs = player.getPlayerConfigData().getActiveObjectiveUUIDs(); Set<UUID> activeObjectiveUUIDs = player.getPlayerConfigData().getActiveObjectiveUUIDs();
if (activeObjectiveUUIDs == null) { if (activeObjectiveUUIDs == null) {
return true; return true;
@@ -420,6 +463,7 @@ public class ObjectivePlugin extends JavaPlugin {
return true; return true;
} }
} }
}
@Nullable @Nullable
public Objective startObjectiveLine( public Objective startObjectiveLine(
@@ -472,6 +516,9 @@ public class ObjectivePlugin extends JavaPlugin {
} }
public boolean canPlayerDoObjectiveLine(@Nonnull Player player, @Nonnull String objectiveLineId) { public boolean canPlayerDoObjectiveLine(@Nonnull Player player, @Nonnull String objectiveLineId) {
if (this.objectiveDataStore == null) {
return false;
} else {
Set<UUID> activeObjectiveUUIDs = player.getPlayerConfigData().getActiveObjectiveUUIDs(); Set<UUID> activeObjectiveUUIDs = player.getPlayerConfigData().getActiveObjectiveUUIDs();
if (activeObjectiveUUIDs == null) { if (activeObjectiveUUIDs == null) {
return true; return true;
@@ -489,8 +536,10 @@ public class ObjectivePlugin extends JavaPlugin {
return true; return true;
} }
} }
}
public void objectiveCompleted(@Nonnull Objective objective, @Nonnull Store<EntityStore> store) { public void objectiveCompleted(@Nonnull Objective objective, @Nonnull Store<EntityStore> store) {
if (this.objectiveDataStore != null) {
for (UUID playerUUID : objective.getPlayerUUIDs()) { for (UUID playerUUID : objective.getPlayerUUIDs()) {
this.untrackObjectiveForPlayer(objective, playerUUID); this.untrackObjectiveForPlayer(objective, playerUUID);
} }
@@ -528,6 +577,7 @@ public class ObjectivePlugin extends JavaPlugin {
} }
} }
} }
}
public void storeObjectiveHistoryData(@Nonnull Objective objective) { public void storeObjectiveHistoryData(@Nonnull Objective objective) {
String objectiveId = objective.getObjectiveId(); String objectiveId = objective.getObjectiveId();
@@ -590,6 +640,7 @@ public class ObjectivePlugin extends JavaPlugin {
} }
public void cancelObjective(@Nonnull UUID objectiveUUID, @Nonnull Store<EntityStore> store) { public void cancelObjective(@Nonnull UUID objectiveUUID, @Nonnull Store<EntityStore> store) {
if (this.objectiveDataStore != null) {
Objective objective = this.objectiveDataStore.loadObjective(objectiveUUID, store); Objective objective = this.objectiveDataStore.loadObjective(objectiveUUID, store);
if (objective != null) { if (objective != null) {
objective.cancel(); objective.cancel();
@@ -602,8 +653,10 @@ public class ObjectivePlugin extends JavaPlugin {
this.objectiveDataStore.removeFromDisk(objectiveUUID.toString()); this.objectiveDataStore.removeFromDisk(objectiveUUID.toString());
} }
} }
}
public void untrackObjectiveForPlayer(@Nonnull Objective objective, @Nonnull UUID playerUUID) { public void untrackObjectiveForPlayer(@Nonnull Objective objective, @Nonnull UUID playerUUID) {
if (this.objectiveDataStore != null) {
UUID objectiveUUID = objective.getObjectiveUUID(); UUID objectiveUUID = objective.getObjectiveUUID();
ObjectiveTask[] currentTasks = objective.getCurrentTasks(); ObjectiveTask[] currentTasks = objective.getCurrentTasks();
@@ -622,8 +675,10 @@ public class ObjectivePlugin extends JavaPlugin {
playerRef.getPacketHandler().writeNoCache(new UntrackObjective(objectiveUUID)); playerRef.getPacketHandler().writeNoCache(new UntrackObjective(objectiveUUID));
} }
} }
}
public void addPlayerToExistingObjective(@Nonnull Store<EntityStore> store, @Nonnull UUID playerUUID, @Nonnull UUID objectiveUUID) { public void addPlayerToExistingObjective(@Nonnull Store<EntityStore> store, @Nonnull UUID playerUUID, @Nonnull UUID objectiveUUID) {
if (this.objectiveDataStore != null) {
Objective objective = this.objectiveDataStore.loadObjective(objectiveUUID, store); Objective objective = this.objectiveDataStore.loadObjective(objectiveUUID, store);
if (objective != null) { if (objective != null) {
objective.addActivePlayerUUID(playerUUID); objective.addActivePlayerUUID(playerUUID);
@@ -652,8 +707,10 @@ public class ObjectivePlugin extends JavaPlugin {
} }
} }
} }
}
public void removePlayerFromExistingObjective(@Nonnull Store<EntityStore> store, @Nonnull UUID playerUUID, @Nonnull UUID objectiveUUID) { public void removePlayerFromExistingObjective(@Nonnull Store<EntityStore> store, @Nonnull UUID playerUUID, @Nonnull UUID objectiveUUID) {
if (this.objectiveDataStore != null) {
Objective objective = this.objectiveDataStore.loadObjective(objectiveUUID, store); Objective objective = this.objectiveDataStore.loadObjective(objectiveUUID, store);
if (objective != null) { if (objective != null) {
objective.removeActivePlayerUUID(playerUUID); objective.removeActivePlayerUUID(playerUUID);
@@ -665,8 +722,10 @@ public class ObjectivePlugin extends JavaPlugin {
this.untrackObjectiveForPlayer(objective, playerUUID); this.untrackObjectiveForPlayer(objective, playerUUID);
} }
} }
}
private void onPlayerDisconnect(@Nonnull PlayerDisconnectEvent event) { private void onPlayerDisconnect(@Nonnull PlayerDisconnectEvent event) {
if (this.objectiveDataStore != null) {
PlayerRef playerRef = event.getPlayerRef(); PlayerRef playerRef = event.getPlayerRef();
Ref<EntityStore> ref = playerRef.getReference(); Ref<EntityStore> ref = playerRef.getReference();
if (ref != null) { if (ref != null) {
@@ -685,7 +744,9 @@ public class ObjectivePlugin extends JavaPlugin {
} else { } else {
this.getLogger() this.getLogger()
.at(Level.INFO) .at(Level.INFO)
.log("Processing " + activeObjectiveUUIDs.size() + " active objectives for '" + playerRef.getUsername() + "' (" + playerUUID + ")"); .log(
"Processing " + activeObjectiveUUIDs.size() + " active objectives for '" + playerRef.getUsername() + "' (" + playerUUID + ")"
);
for (UUID objectiveUUID : activeObjectiveUUIDs) { for (UUID objectiveUUID : activeObjectiveUUIDs) {
Objective objective = this.objectiveDataStore.getObjective(objectiveUUID); Objective objective = this.objectiveDataStore.getObjective(objectiveUUID);
@@ -704,6 +765,7 @@ public class ObjectivePlugin extends JavaPlugin {
); );
} }
} }
}
private void onObjectiveLineAssetLoaded(@Nonnull LoadedAssetsEvent<String, ObjectiveLineAsset, DefaultAssetMap<String, ObjectiveLineAsset>> event) { private void onObjectiveLineAssetLoaded(@Nonnull LoadedAssetsEvent<String, ObjectiveLineAsset, DefaultAssetMap<String, ObjectiveLineAsset>> event) {
if (this.objectiveDataStore != null) { if (this.objectiveDataStore != null) {
@@ -731,7 +793,11 @@ public class ObjectivePlugin extends JavaPlugin {
} }
private void onObjectiveAssetLoaded(@Nonnull LoadedAssetsEvent<String, ObjectiveAsset, DefaultAssetMap<String, ObjectiveAsset>> event) { private void onObjectiveAssetLoaded(@Nonnull LoadedAssetsEvent<String, ObjectiveAsset, DefaultAssetMap<String, ObjectiveAsset>> event) {
this.objectiveDataStore.getObjectiveCollection().forEach(objective -> objective.reloadObjectiveAsset(event.getLoadedAssets())); if (this.objectiveDataStore != null) {
for (Objective objective : this.objectiveDataStore.getObjectiveCollection()) {
objective.reloadObjectiveAsset(event.getLoadedAssets());
}
}
} }
private static void onObjectiveLocationMarkerChange( private static void onObjectiveLocationMarkerChange(
@@ -818,12 +884,12 @@ public class ObjectivePlugin extends JavaPlugin {
} }
private void onLivingEntityInventoryChange(@Nonnull LivingEntityInventoryChangeEvent event) { private void onLivingEntityInventoryChange(@Nonnull LivingEntityInventoryChangeEvent event) {
LivingEntity entity = event.getEntity(); if (this.objectiveDataStore != null) {
if (entity instanceof Player player) { if (event.getEntity() instanceof Player player) {
Set<UUID> activeObjectiveUUIDs = player.getPlayerConfigData().getActiveObjectiveUUIDs(); Set<UUID> activeObjectiveUUIDs = player.getPlayerConfigData().getActiveObjectiveUUIDs();
if (!activeObjectiveUUIDs.isEmpty()) { if (!activeObjectiveUUIDs.isEmpty()) {
Set<UUID> inventoryItemObjectiveUUIDs = null; Set<UUID> inventoryItemObjectiveUUIDs = null;
CombinedItemContainer inventory = entity.getInventory().getCombinedHotbarFirst(); CombinedItemContainer inventory = player.getInventory().getCombinedHotbarFirst();
for (short i = 0; i < inventory.getCapacity(); i++) { for (short i = 0; i < inventory.getCapacity(); i++) {
ItemStack itemStack = inventory.getItemStack(i); ItemStack itemStack = inventory.getItemStack(i);
@@ -839,15 +905,17 @@ public class ObjectivePlugin extends JavaPlugin {
} }
} }
Ref<EntityStore> reference = player.getReference();
if (reference != null && reference.isValid()) {
Store<EntityStore> store = reference.getStore();
World world = store.getExternalData().getWorld();
for (UUID activeObjectiveUUID : activeObjectiveUUIDs) { for (UUID activeObjectiveUUID : activeObjectiveUUIDs) {
if (inventoryItemObjectiveUUIDs == null || !inventoryItemObjectiveUUIDs.contains(activeObjectiveUUID)) { if (inventoryItemObjectiveUUIDs == null || !inventoryItemObjectiveUUIDs.contains(activeObjectiveUUID)) {
Objective objective = this.objectiveDataStore.getObjective(activeObjectiveUUID); Objective objective = this.objectiveDataStore.getObjective(activeObjectiveUUID);
if (objective != null) { if (objective != null) {
ObjectiveAsset objectiveAsset = objective.getObjectiveAsset(); ObjectiveAsset objectiveAsset = objective.getObjectiveAsset();
if (objectiveAsset != null && objectiveAsset.isRemoveOnItemDrop()) { if (objectiveAsset != null && objectiveAsset.isRemoveOnItemDrop()) {
Ref<EntityStore> reference = entity.getReference();
Store<EntityStore> store = reference.getStore();
World world = store.getExternalData().getWorld();
world.execute(() -> { world.execute(() -> {
UUIDComponent uuidComponent = store.getComponent(reference, UUIDComponent.getComponentType()); UUIDComponent uuidComponent = store.getComponent(reference, UUIDComponent.getComponentType());
@@ -862,6 +930,8 @@ public class ObjectivePlugin extends JavaPlugin {
} }
} }
} }
}
}
private void onWorldAdded(@Nonnull AddWorldEvent event) { private void onWorldAdded(@Nonnull AddWorldEvent event) {
event.getWorld().getWorldMapManager().addMarkerProvider("objectives", ObjectiveMarkerProvider.INSTANCE); event.getWorld().getWorldMapManager().addMarkerProvider("objectives", ObjectiveMarkerProvider.INSTANCE);
@@ -870,7 +940,7 @@ public class ObjectivePlugin extends JavaPlugin {
@Nonnull @Nonnull
public String getObjectiveDataDump() { public String getObjectiveDataDump() {
StringBuilder sb = new StringBuilder("Objective Data\n"); StringBuilder sb = new StringBuilder("Objective Data\n");
if (this.objectiveDataStore != null) {
for (Objective objective : this.objectiveDataStore.getObjectiveCollection()) { for (Objective objective : this.objectiveDataStore.getObjectiveCollection()) {
sb.append("Objective ID: ") sb.append("Objective ID: ")
.append(objective.getObjectiveId()) .append(objective.getObjectiveId())
@@ -885,6 +955,9 @@ public class ObjectivePlugin extends JavaPlugin {
.append(Arrays.toString(objective.getActivePlayerUUIDs().toArray())) .append(Arrays.toString(objective.getActivePlayerUUIDs().toArray()))
.append("\n\n"); .append("\n\n");
} }
} else {
sb.append("Objective data store is not initialized.\n");
}
return sb.toString(); return sb.toString();
} }

View File

@@ -76,7 +76,7 @@ public class ObjectiveCompleteCommand extends AbstractCommandCollection {
String objectiveId = this.objectiveArg.get(context); String objectiveId = this.objectiveArg.get(context);
Objective objective = ObjectiveCompleteCommand.getObjectiveFromId(ref, objectiveId, store); Objective objective = ObjectiveCompleteCommand.getObjectiveFromId(ref, objectiveId, store);
if (objective == null) { if (objective == null) {
context.sendMessage(ObjectiveCompleteCommand.MESSAGE_COMMANDS_OBJECTIVE_OBJECTIVE_NOT_FOUND); context.sendMessage(ObjectiveCompleteCommand.MESSAGE_COMMANDS_OBJECTIVE_OBJECTIVE_NOT_FOUND.param("id", objectiveId));
} else { } else {
ObjectiveTask[] tasks = objective.getCurrentTasks(); ObjectiveTask[] tasks = objective.getCurrentTasks();
if (tasks == null) { if (tasks == null) {
@@ -114,7 +114,7 @@ public class ObjectiveCompleteCommand extends AbstractCommandCollection {
int taskIndex = this.taskIndexArg.get(context); int taskIndex = this.taskIndexArg.get(context);
Objective objective = ObjectiveCompleteCommand.getObjectiveFromId(ref, objectiveId, store); Objective objective = ObjectiveCompleteCommand.getObjectiveFromId(ref, objectiveId, store);
if (objective == null) { if (objective == null) {
context.sendMessage(ObjectiveCompleteCommand.MESSAGE_COMMANDS_OBJECTIVE_OBJECTIVE_NOT_FOUND); context.sendMessage(ObjectiveCompleteCommand.MESSAGE_COMMANDS_OBJECTIVE_OBJECTIVE_NOT_FOUND.param("id", objectiveId));
} else { } else {
ObjectiveTask[] tasks = objective.getCurrentTasks(); ObjectiveTask[] tasks = objective.getCurrentTasks();
if (taskIndex >= tasks.length) { if (taskIndex >= tasks.length) {
@@ -146,7 +146,7 @@ public class ObjectiveCompleteCommand extends AbstractCommandCollection {
String objectiveId = this.objectiveArg.get(context); String objectiveId = this.objectiveArg.get(context);
Objective objective = ObjectiveCompleteCommand.getObjectiveFromId(ref, objectiveId, store); Objective objective = ObjectiveCompleteCommand.getObjectiveFromId(ref, objectiveId, store);
if (objective == null) { if (objective == null) {
context.sendMessage(ObjectiveCompleteCommand.MESSAGE_COMMANDS_OBJECTIVE_OBJECTIVE_NOT_FOUND); context.sendMessage(ObjectiveCompleteCommand.MESSAGE_COMMANDS_OBJECTIVE_OBJECTIVE_NOT_FOUND.param("id", objectiveId));
} else { } else {
ObjectiveTask[] tasks = objective.getCurrentTasks(); ObjectiveTask[] tasks = objective.getCurrentTasks();
if (tasks != null && tasks.length != 0) { if (tasks != null && tasks.length != 0) {

View File

@@ -57,11 +57,21 @@ import javax.annotation.Nullable;
public class ObjectiveLocationMarkerSystems { public class ObjectiveLocationMarkerSystems {
public static class EnsureNetworkSendableSystem extends HolderSystem<EntityStore> { public static class EnsureNetworkSendableSystem extends HolderSystem<EntityStore> {
@Nonnull @Nonnull
private final Query<EntityStore> query = Query.and(ObjectiveLocationMarker.getComponentType(), Query.not(NetworkId.getComponentType())); private final ComponentType<EntityStore, NetworkId> networkIdComponentType;
@Nonnull
private final Query<EntityStore> query;
public EnsureNetworkSendableSystem(
@Nonnull ComponentType<EntityStore, ObjectiveLocationMarker> objectiveLocationMarkerComponentType,
@Nonnull ComponentType<EntityStore, NetworkId> networkIdComponentType
) {
this.networkIdComponentType = networkIdComponentType;
this.query = Query.and(objectiveLocationMarkerComponentType, Query.not(networkIdComponentType));
}
@Override @Override
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) { public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
holder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId())); holder.addComponent(this.networkIdComponentType, new NetworkId(store.getExternalData().takeNextNetworkId()));
} }
@Override @Override
@@ -83,13 +93,21 @@ public class ObjectiveLocationMarkerSystems {
@Nonnull @Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType; private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull @Nonnull
private final ComponentType<EntityStore, PrefabCopyableComponent> prefabCopyableComponentType;
@Nonnull
private final Query<EntityStore> query; private final Query<EntityStore> query;
public InitSystem(@Nonnull ComponentType<EntityStore, ObjectiveLocationMarker> objectiveLocationMarkerComponent) { public InitSystem(
@Nonnull ComponentType<EntityStore, ObjectiveLocationMarker> objectiveLocationMarkerComponent,
@Nonnull ComponentType<EntityStore, ModelComponent> modelComponentType,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType,
@Nonnull ComponentType<EntityStore, PrefabCopyableComponent> prefabCopyableComponentType
) {
this.objectiveLocationMarkerComponent = objectiveLocationMarkerComponent; this.objectiveLocationMarkerComponent = objectiveLocationMarkerComponent;
this.modelComponentType = ModelComponent.getComponentType(); this.modelComponentType = modelComponentType;
this.transformComponentType = TransformComponent.getComponentType(); this.transformComponentType = transformComponentType;
this.query = Query.and(objectiveLocationMarkerComponent, this.modelComponentType, this.transformComponentType); this.prefabCopyableComponentType = prefabCopyableComponentType;
this.query = Query.and(objectiveLocationMarkerComponent, modelComponentType, transformComponentType);
} }
@Nonnull @Nonnull
@@ -171,7 +189,7 @@ public class ObjectiveLocationMarkerSystems {
) )
) )
); );
commandBuffer.ensureComponent(ref, PrefabCopyableComponent.getComponentType()); commandBuffer.ensureComponent(ref, this.prefabCopyableComponentType);
} }
} }
@@ -201,11 +219,11 @@ public class ObjectiveLocationMarkerSystems {
@Nonnull @Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType; private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull @Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType = TransformComponent.getComponentType(); private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull @Nonnull
private final ComponentType<EntityStore, WeatherTracker> weatherTrackerComponentType = WeatherTracker.getComponentType(); private final ComponentType<EntityStore, WeatherTracker> weatherTrackerComponentType;
@Nonnull @Nonnull
private final ComponentType<EntityStore, UUIDComponent> uuidComponentType = UUIDComponent.getComponentType(); private final ComponentType<EntityStore, UUIDComponent> uuidComponentType;
@Nonnull @Nonnull
private final ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent; private final ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent;
@Nonnull @Nonnull
@@ -216,12 +234,18 @@ public class ObjectiveLocationMarkerSystems {
public TickingSystem( public TickingSystem(
@Nonnull ComponentType<EntityStore, ObjectiveLocationMarker> objectiveLocationMarkerComponentType, @Nonnull ComponentType<EntityStore, ObjectiveLocationMarker> objectiveLocationMarkerComponentType,
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType, @Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType,
@Nonnull ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent @Nonnull ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType,
@Nonnull ComponentType<EntityStore, WeatherTracker> weatherTrackerComponentType,
@Nonnull ComponentType<EntityStore, UUIDComponent> uuidComponentType
) { ) {
this.objectiveLocationMarkerComponentType = objectiveLocationMarkerComponentType; this.objectiveLocationMarkerComponentType = objectiveLocationMarkerComponentType;
this.playerRefComponentType = playerRefComponentType; this.playerRefComponentType = playerRefComponentType;
this.transformComponentType = transformComponentType;
this.weatherTrackerComponentType = weatherTrackerComponentType;
this.uuidComponentType = uuidComponentType;
this.playerSpatialComponent = playerSpatialComponent; this.playerSpatialComponent = playerSpatialComponent;
this.query = Archetype.of(objectiveLocationMarkerComponentType, this.transformComponentType, this.uuidComponentType); this.query = Archetype.of(objectiveLocationMarkerComponentType, transformComponentType, uuidComponentType);
this.dependencies = Set.of(new SystemDependency<>(Order.AFTER, PlayerSpatialSystem.class, OrderPriority.CLOSEST)); this.dependencies = Set.of(new SystemDependency<>(Order.AFTER, PlayerSpatialSystem.class, OrderPriority.CLOSEST));
} }
@@ -278,20 +302,20 @@ public class ObjectiveLocationMarkerSystems {
this.setupMarker(store, objectiveLocationMarkerComponent, entityReference, position, uuid, commandBuffer); this.setupMarker(store, objectiveLocationMarkerComponent, entityReference, position, uuid, commandBuffer);
} else if (!activeObjective.isCompleted()) { } else if (!activeObjective.isCompleted()) {
SpatialResource<Ref<EntityStore>, EntityStore> spatialResource = store.getResource(this.playerSpatialComponent); SpatialResource<Ref<EntityStore>, EntityStore> spatialResource = store.getResource(this.playerSpatialComponent);
ObjectList<Ref<EntityStore>> playerReferences = SpatialResource.getThreadLocalReferenceList(); ObjectList<Ref<EntityStore>> playerRefs = SpatialResource.getThreadLocalReferenceList();
objectiveLocationMarkerComponent.area.getPlayersInExitArea(spatialResource, playerReferences, position); objectiveLocationMarkerComponent.area.getPlayersInExitArea(spatialResource, playerRefs, position);
HashSet<UUID> playersInExitArea = new HashSet<>(playerReferences.size()); HashSet<UUID> playersInExitArea = new HashSet<>(playerRefs.size());
PlayerRef[] playersInEntryArea = new PlayerRef[playerReferences.size()]; PlayerRef[] playersInEntryArea = new PlayerRef[playerRefs.size()];
int playersInEntryAreaSize = 0; int playersInEntryAreaSize = 0;
for (Ref<EntityStore> playerReference : playerReferences) { for (Ref<EntityStore> playerRef : playerRefs) {
PlayerRef playerRefComponent = commandBuffer.getComponent(playerReference, this.playerRefComponentType); PlayerRef playerRefComponent = commandBuffer.getComponent(playerRef, this.playerRefComponentType);
if (playerRefComponent != null) { if (playerRefComponent != null) {
UUIDComponent playerUuidComponent = commandBuffer.getComponent(playerReference, this.uuidComponentType); UUIDComponent playerUuidComponent = commandBuffer.getComponent(playerRef, this.uuidComponentType);
if (playerUuidComponent != null) { if (playerUuidComponent != null) {
TransformComponent playerTransformComponent = commandBuffer.getComponent(playerReference, this.transformComponentType); TransformComponent playerTransformComponent = commandBuffer.getComponent(playerRef, this.transformComponentType);
if (playerTransformComponent != null) { if (playerTransformComponent != null) {
WeatherTracker playerWeatherTrackerComponent = commandBuffer.getComponent(playerReference, this.weatherTrackerComponentType); WeatherTracker playerWeatherTrackerComponent = commandBuffer.getComponent(playerRef, this.weatherTrackerComponentType);
if (playerWeatherTrackerComponent != null if (playerWeatherTrackerComponent != null
&& isPlayerInSpecificEnvironment( && isPlayerInSpecificEnvironment(
objectiveLocationMarkerComponent, playerWeatherTrackerComponent, playerTransformComponent, commandBuffer objectiveLocationMarkerComponent, playerWeatherTrackerComponent, playerTransformComponent, commandBuffer
@@ -437,13 +461,13 @@ public class ObjectiveLocationMarkerSystems {
private static boolean isPlayerInSpecificEnvironment( private static boolean isPlayerInSpecificEnvironment(
@Nonnull ObjectiveLocationMarker entity, @Nonnull ObjectiveLocationMarker entity,
@Nonnull WeatherTracker weatherTracker, @Nonnull WeatherTracker weatherTracker,
@Nonnull TransformComponent transform, @Nonnull TransformComponent transformComponent,
@Nonnull ComponentAccessor<EntityStore> componentAccessor @Nonnull ComponentAccessor<EntityStore> componentAccessor
) { ) {
if (entity.environmentIndexes == null) { if (entity.environmentIndexes == null) {
return true; return true;
} else { } else {
weatherTracker.updateEnvironment(transform, componentAccessor); weatherTracker.updateEnvironment(transformComponent, componentAccessor);
int environmentIndex = weatherTracker.getEnvironmentId(); int environmentIndex = weatherTracker.getEnvironmentId();
return Arrays.binarySearch(entity.environmentIndexes, environmentIndex) >= 0; return Arrays.binarySearch(entity.environmentIndexes, environmentIndex) >= 0;
} }
@@ -453,8 +477,8 @@ public class ObjectiveLocationMarkerSystems {
ObjectiveDataStore objectiveDataStore = ObjectivePlugin.get().getObjectiveDataStore(); ObjectiveDataStore objectiveDataStore = ObjectivePlugin.get().getObjectiveDataStore();
for (ObjectiveTask task : entity.getActiveObjective().getCurrentTasks()) { for (ObjectiveTask task : entity.getActiveObjective().getCurrentTasks()) {
if (task instanceof UseEntityObjectiveTask) { if (task instanceof UseEntityObjectiveTask useEntityObjectiveTask) {
String taskId = ((UseEntityObjectiveTask)task).getAsset().getTaskId(); String taskId = useEntityObjectiveTask.getAsset().getTaskId();
objectiveDataStore.removeEntityTaskForPlayer(entity.activeObjectiveUUID, taskId, playerUUID); objectiveDataStore.removeEntityTaskForPlayer(entity.activeObjectiveUUID, taskId, playerUUID);
} }
} }

View File

@@ -45,11 +45,22 @@ public class ReachLocationMarkerSystems {
public static class EnsureNetworkSendable extends HolderSystem<EntityStore> { public static class EnsureNetworkSendable extends HolderSystem<EntityStore> {
@Nonnull @Nonnull
private final Query<EntityStore> query = Query.and(ReachLocationMarker.getComponentType(), Query.not(NetworkId.getComponentType())); private final ComponentType<EntityStore, NetworkId> networkIdComponentType;
@Nonnull
private final Query<EntityStore> query;
public EnsureNetworkSendable(
@Nonnull ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponentType,
@Nonnull ComponentType<EntityStore, NetworkId> networkIdComponentType
) {
this.networkIdComponentType = networkIdComponentType;
this.query = Query.and(reachLocationMarkerComponentType, Query.not(networkIdComponentType));
}
@Override @Override
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) { public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
holder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId())); int nextNetworkId = store.getExternalData().takeNextNetworkId();
holder.addComponent(this.networkIdComponentType, new NetworkId(nextNetworkId));
} }
@Override @Override
@@ -64,16 +75,20 @@ public class ReachLocationMarkerSystems {
} }
public static class EntityAdded extends RefSystem<EntityStore> { public static class EntityAdded extends RefSystem<EntityStore> {
@Nonnull
private final ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent; private final ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent;
@Nonnull @Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType; private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull @Nonnull
private final Query<EntityStore> query; private final Query<EntityStore> query;
public EntityAdded(ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent) { public EntityAdded(
@Nonnull ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType
) {
this.reachLocationMarkerComponent = reachLocationMarkerComponent; this.reachLocationMarkerComponent = reachLocationMarkerComponent;
this.transformComponentType = TransformComponent.getComponentType(); this.transformComponentType = transformComponentType;
this.query = Query.and(reachLocationMarkerComponent, this.transformComponentType); this.query = Query.and(reachLocationMarkerComponent, transformComponentType);
} }
@Nonnull @Nonnull
@@ -113,25 +128,30 @@ public class ReachLocationMarkerSystems {
} }
public static class Ticking extends EntityTickingSystem<EntityStore> { public static class Ticking extends EntityTickingSystem<EntityStore> {
@Nonnull
private final ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent; private final ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent;
@Nonnull @Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType; private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull
private final ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent; private final ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent;
@Nonnull @Nonnull
private final ComponentType<EntityStore, UUIDComponent> uuidComponentType = UUIDComponent.getComponentType(); private final ComponentType<EntityStore, UUIDComponent> uuidComponentType;
@Nonnull @Nonnull
private final Query<EntityStore> query; private final Query<EntityStore> query;
@Nonnull @Nonnull
private final Set<Dependency<EntityStore>> dependencies; private final Set<Dependency<EntityStore>> dependencies;
public Ticking( public Ticking(
ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent, @Nonnull ComponentType<EntityStore, ReachLocationMarker> reachLocationMarkerComponent,
ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent @Nonnull ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> playerSpatialComponent,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType,
@Nonnull ComponentType<EntityStore, UUIDComponent> uuidComponentType
) { ) {
this.reachLocationMarkerComponent = reachLocationMarkerComponent; this.reachLocationMarkerComponent = reachLocationMarkerComponent;
this.transformComponentType = TransformComponent.getComponentType(); this.transformComponentType = transformComponentType;
this.uuidComponentType = uuidComponentType;
this.playerSpatialComponent = playerSpatialComponent; this.playerSpatialComponent = playerSpatialComponent;
this.query = Query.and(reachLocationMarkerComponent, this.transformComponentType); this.query = Query.and(reachLocationMarkerComponent, transformComponentType);
this.dependencies = Set.of(new SystemDependency<>(Order.AFTER, PlayerSpatialSystem.class, OrderPriority.CLOSEST)); this.dependencies = Set.of(new SystemDependency<>(Order.AFTER, PlayerSpatialSystem.class, OrderPriority.CLOSEST));
} }

View File

@@ -8,7 +8,9 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class StashGameplayConfig { public class StashGameplayConfig {
@Nonnull
public static final String ID = "Stash"; public static final String ID = "Stash";
@Nonnull
public static final BuilderCodec<StashGameplayConfig> CODEC = BuilderCodec.builder(StashGameplayConfig.class, StashGameplayConfig::new) public static final BuilderCodec<StashGameplayConfig> CODEC = BuilderCodec.builder(StashGameplayConfig.class, StashGameplayConfig::new)
.appendInherited( .appendInherited(
new KeyedCodec<>("ClearContainerDropList", Codec.BOOLEAN), new KeyedCodec<>("ClearContainerDropList", Codec.BOOLEAN),

View File

@@ -38,6 +38,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class StashPlugin extends JavaPlugin { public class StashPlugin extends JavaPlugin {
@Nonnull
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass(); private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
public StashPlugin(@Nonnull JavaPluginInit init) { public StashPlugin(@Nonnull JavaPluginInit init) {
@@ -95,18 +96,19 @@ public class StashPlugin extends JavaPlugin {
} }
private static class StashSystem extends RefSystem<ChunkStore> { private static class StashSystem extends RefSystem<ChunkStore> {
private final ComponentType<ChunkStore, ItemContainerState> componentType; @Nonnull
private final ComponentType<ChunkStore, ItemContainerState> itemContainerStateComponentType;
@Nonnull @Nonnull
private final Set<Dependency<ChunkStore>> dependencies; private final Set<Dependency<ChunkStore>> dependencies;
public StashSystem(ComponentType<ChunkStore, ItemContainerState> componentType) { public StashSystem(@Nonnull ComponentType<ChunkStore, ItemContainerState> itemContainerStateComponentType) {
this.componentType = componentType; this.itemContainerStateComponentType = itemContainerStateComponentType;
this.dependencies = Set.of(new SystemDependency<>(Order.AFTER, BlockStateModule.LegacyBlockStateRefSystem.class)); this.dependencies = Set.of(new SystemDependency<>(Order.AFTER, BlockStateModule.LegacyBlockStateRefSystem.class));
} }
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return this.componentType; return this.itemContainerStateComponentType;
} }
@Override @Override
@@ -115,9 +117,13 @@ public class StashPlugin extends JavaPlugin {
) { ) {
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
if (world.getWorldConfig().getGameMode() != GameMode.Creative) { if (world.getWorldConfig().getGameMode() != GameMode.Creative) {
ItemContainerState itemContainerStateComponent = store.getComponent(ref, this.itemContainerStateComponentType);
assert itemContainerStateComponent != null;
StashGameplayConfig stashGameplayConfig = StashGameplayConfig.getOrDefault(world.getGameplayConfig()); StashGameplayConfig stashGameplayConfig = StashGameplayConfig.getOrDefault(world.getGameplayConfig());
boolean clearContainerDropList = stashGameplayConfig.isClearContainerDropList(); boolean clearContainerDropList = stashGameplayConfig.isClearContainerDropList();
StashPlugin.stash(store.getComponent(ref, this.componentType), clearContainerDropList); StashPlugin.stash(itemContainerStateComponent, clearContainerDropList);
} }
} }

View File

@@ -9,6 +9,7 @@ import com.hypixel.hytale.builtin.adventure.teleporter.system.CreateWarpWhenTele
import com.hypixel.hytale.builtin.teleport.TeleportPlugin; import com.hypixel.hytale.builtin.teleport.TeleportPlugin;
import com.hypixel.hytale.component.AddReason; import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentRegistryProxy;
import com.hypixel.hytale.component.ComponentType; import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.RemoveReason; import com.hypixel.hytale.component.RemoveReason;
@@ -16,10 +17,17 @@ import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.RefChangeSystem; import com.hypixel.hytale.component.system.RefChangeSystem;
import com.hypixel.hytale.component.system.RefSystem; import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.server.core.modules.block.BlockModule;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.teleport.PendingTeleport;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.server.core.modules.entity.teleport.TeleportRecord;
import com.hypixel.hytale.server.core.modules.interaction.components.PlacedByInteractionComponent;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.server.OpenCustomUIInteraction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.server.OpenCustomUIInteraction;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -41,12 +49,29 @@ public class TeleporterPlugin extends JavaPlugin {
@Override @Override
protected void setup() { protected void setup() {
this.teleporterComponentType = this.getChunkStoreRegistry().registerComponent(Teleporter.class, "Teleporter", Teleporter.CODEC); ComponentRegistryProxy<ChunkStore> chunkStoreRegistry = this.getChunkStoreRegistry();
this.getChunkStoreRegistry().registerSystem(new TeleporterPlugin.TeleporterOwnedWarpRefChangeSystem()); ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry();
this.getChunkStoreRegistry().registerSystem(new TeleporterPlugin.TeleporterOwnedWarpRefSystem()); this.teleporterComponentType = chunkStoreRegistry.registerComponent(Teleporter.class, "Teleporter", Teleporter.CODEC);
this.getChunkStoreRegistry().registerSystem(new CreateWarpWhenTeleporterPlacedSystem()); ComponentType<ChunkStore, PlacedByInteractionComponent> placedByInteractionComponentType = PlacedByInteractionComponent.getComponentType();
this.usedTeleporterComponentType = this.getEntityStoreRegistry().registerComponent(UsedTeleporter.class, UsedTeleporter::new); ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType = BlockModule.BlockStateInfo.getComponentType();
this.getEntityStoreRegistry().registerSystem(new ClearUsedTeleporterSystem()); ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
ComponentType<EntityStore, TransformComponent> transformComponentType = TransformComponent.getComponentType();
ComponentType<EntityStore, TeleportRecord> teleportRecordComponentType = TeleportRecord.getComponentType();
ComponentType<EntityStore, Teleport> teleportComponentType = Teleport.getComponentType();
ComponentType<EntityStore, PendingTeleport> pendingTeleportComponentType = PendingTeleport.getComponentType();
chunkStoreRegistry.registerSystem(new TeleporterPlugin.TeleporterOwnedWarpRefChangeSystem(this.teleporterComponentType));
chunkStoreRegistry.registerSystem(new TeleporterPlugin.TeleporterOwnedWarpRefSystem(this.teleporterComponentType));
chunkStoreRegistry.registerSystem(
new CreateWarpWhenTeleporterPlacedSystem(
placedByInteractionComponentType, this.teleporterComponentType, blockStateInfoComponentType, playerRefComponentType
)
);
this.usedTeleporterComponentType = entityStoreRegistry.registerComponent(UsedTeleporter.class, UsedTeleporter::new);
entityStoreRegistry.registerSystem(
new ClearUsedTeleporterSystem(
this.usedTeleporterComponentType, transformComponentType, teleportRecordComponentType, teleportComponentType, pendingTeleportComponentType
)
);
this.getCodecRegistry(Interaction.CODEC).register("Teleporter", TeleporterInteraction.class, TeleporterInteraction.CODEC); this.getCodecRegistry(Interaction.CODEC).register("Teleporter", TeleporterInteraction.class, TeleporterInteraction.CODEC);
this.getCodecRegistry(OpenCustomUIInteraction.PAGE_CODEC) this.getCodecRegistry(OpenCustomUIInteraction.PAGE_CODEC)
.register("Teleporter", TeleporterSettingsPageSupplier.class, TeleporterSettingsPageSupplier.CODEC); .register("Teleporter", TeleporterSettingsPageSupplier.class, TeleporterSettingsPageSupplier.CODEC);
@@ -61,10 +86,17 @@ public class TeleporterPlugin extends JavaPlugin {
} }
private static class TeleporterOwnedWarpRefChangeSystem extends RefChangeSystem<ChunkStore, Teleporter> { private static class TeleporterOwnedWarpRefChangeSystem extends RefChangeSystem<ChunkStore, Teleporter> {
@Nonnull
private final ComponentType<ChunkStore, Teleporter> teleporterComponentType;
public TeleporterOwnedWarpRefChangeSystem(@Nonnull ComponentType<ChunkStore, Teleporter> teleporterComponentType) {
this.teleporterComponentType = teleporterComponentType;
}
@Nonnull @Nonnull
@Override @Override
public ComponentType<ChunkStore, Teleporter> componentType() { public ComponentType<ChunkStore, Teleporter> componentType() {
return Teleporter.getComponentType(); return this.teleporterComponentType;
} }
public void onComponentAdded( public void onComponentAdded(
@@ -79,6 +111,7 @@ public class TeleporterPlugin extends JavaPlugin {
@Nonnull Store<ChunkStore> store, @Nonnull Store<ChunkStore> store,
@Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
if (oldComponent != null) {
String ownedWarp = oldComponent.getOwnedWarp(); String ownedWarp = oldComponent.getOwnedWarp();
if (ownedWarp != null && !ownedWarp.isEmpty() && !ownedWarp.equals(newComponent.getOwnedWarp())) { if (ownedWarp != null && !ownedWarp.isEmpty() && !ownedWarp.equals(newComponent.getOwnedWarp())) {
TeleportPlugin.get().getWarps().remove(ownedWarp.toLowerCase()); TeleportPlugin.get().getWarps().remove(ownedWarp.toLowerCase());
@@ -86,6 +119,7 @@ public class TeleporterPlugin extends JavaPlugin {
oldComponent.setOwnedWarp(null); oldComponent.setOwnedWarp(null);
} }
} }
}
public void onComponentRemoved( public void onComponentRemoved(
@Nonnull Ref<ChunkStore> ref, @Nonnull Teleporter component, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull Ref<ChunkStore> ref, @Nonnull Teleporter component, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer
@@ -106,7 +140,12 @@ public class TeleporterPlugin extends JavaPlugin {
} }
private static class TeleporterOwnedWarpRefSystem extends RefSystem<ChunkStore> { private static class TeleporterOwnedWarpRefSystem extends RefSystem<ChunkStore> {
public static final ComponentType<ChunkStore, Teleporter> COMPONENT_TYPE = Teleporter.getComponentType(); @Nonnull
private final ComponentType<ChunkStore, Teleporter> teleporterComponentType;
public TeleporterOwnedWarpRefSystem(@Nonnull ComponentType<ChunkStore, Teleporter> teleporterComponentType) {
this.teleporterComponentType = teleporterComponentType;
}
@Override @Override
public void onEntityAdded( public void onEntityAdded(
@@ -114,10 +153,14 @@ public class TeleporterPlugin extends JavaPlugin {
) { ) {
switch (reason) { switch (reason) {
case LOAD: case LOAD:
Teleporter component = commandBuffer.getComponent(ref, COMPONENT_TYPE); Teleporter teleporterComponent = commandBuffer.getComponent(ref, this.teleporterComponentType);
String ownedWarp = component.getOwnedWarp(); if (teleporterComponent == null) {
return;
} else {
String ownedWarp = teleporterComponent.getOwnedWarp();
if (ownedWarp != null && !ownedWarp.isEmpty() && !TeleportPlugin.get().getWarps().containsKey(ownedWarp.toLowerCase())) { if (ownedWarp != null && !ownedWarp.isEmpty() && !TeleportPlugin.get().getWarps().containsKey(ownedWarp.toLowerCase())) {
} }
}
case SPAWN: case SPAWN:
} }
} }
@@ -127,19 +170,24 @@ public class TeleporterPlugin extends JavaPlugin {
@Nonnull Ref<ChunkStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull Ref<ChunkStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
if (reason == RemoveReason.REMOVE) { if (reason == RemoveReason.REMOVE) {
Teleporter component = commandBuffer.getComponent(ref, COMPONENT_TYPE); Teleporter teleporterComponent = commandBuffer.getComponent(ref, this.teleporterComponentType);
String ownedWarp = component.getOwnedWarp(); if (teleporterComponent == null) {
return;
}
String ownedWarp = teleporterComponent.getOwnedWarp();
if (ownedWarp != null && !ownedWarp.isEmpty()) { if (ownedWarp != null && !ownedWarp.isEmpty()) {
TeleportPlugin.get().getWarps().remove(ownedWarp.toLowerCase()); TeleportPlugin.get().getWarps().remove(ownedWarp.toLowerCase());
TeleportPlugin.get().saveWarps(); TeleportPlugin.get().saveWarps();
component.setOwnedWarp(null); teleporterComponent.setOwnedWarp(null);
} }
} }
} }
@Nonnull
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return COMPONENT_TYPE; return this.teleporterComponentType;
} }
} }
} }

View File

@@ -22,6 +22,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class Teleporter implements Component<ChunkStore> { public class Teleporter implements Component<ChunkStore> {
@Nonnull
public static final BuilderCodec<Teleporter> CODEC = BuilderCodec.builder(Teleporter.class, Teleporter::new) public static final BuilderCodec<Teleporter> CODEC = BuilderCodec.builder(Teleporter.class, Teleporter::new)
.append(new KeyedCodec<>("World", Codec.UUID_BINARY), (teleporter, uuid) -> teleporter.worldUuid = uuid, teleporter -> teleporter.worldUuid) .append(new KeyedCodec<>("World", Codec.UUID_BINARY), (teleporter, uuid) -> teleporter.worldUuid = uuid, teleporter -> teleporter.worldUuid)
.add() .add()
@@ -51,6 +52,7 @@ public class Teleporter implements Component<ChunkStore> {
@Nullable @Nullable
private String warp; private String warp;
@Deprecated @Deprecated
@Nullable
private String ownedWarp; private String ownedWarp;
private boolean isCustomName; private boolean isCustomName;
private String warpNameWordListKey; private String warpNameWordListKey;
@@ -94,11 +96,12 @@ public class Teleporter implements Component<ChunkStore> {
this.warp = warp != null && !warp.isEmpty() ? warp : null; this.warp = warp != null && !warp.isEmpty() ? warp : null;
} }
@Nullable
public String getOwnedWarp() { public String getOwnedWarp() {
return this.ownedWarp; return this.ownedWarp;
} }
public void setOwnedWarp(String ownedWarp) { public void setOwnedWarp(@Nullable String ownedWarp) {
this.ownedWarp = ownedWarp; this.ownedWarp = ownedWarp;
} }

View File

@@ -12,6 +12,7 @@ import com.hypixel.hytale.component.spatial.SpatialResource;
import com.hypixel.hytale.math.util.ChunkUtil; import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3i; import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.InteractionState;
import com.hypixel.hytale.protocol.InteractionType; import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.protocol.WaitForDataFrom; import com.hypixel.hytale.protocol.WaitForDataFrom;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
@@ -23,7 +24,6 @@ import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.teleport.PendingTeleport; import com.hypixel.hytale.server.core.modules.entity.teleport.PendingTeleport;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport; import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.server.core.modules.entity.teleport.TeleportRecord;
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler; import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.client.SimpleBlockInteraction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.client.SimpleBlockInteraction;
import com.hypixel.hytale.server.core.universe.world.ParticleUtil; import com.hypixel.hytale.server.core.universe.world.ParticleUtil;
@@ -33,7 +33,6 @@ import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.objects.ObjectList; import it.unimi.dsi.fastutil.objects.ObjectList;
import java.time.Duration;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -69,7 +68,6 @@ public class TeleporterInteraction extends SimpleBlockInteraction {
.documentation("Upon reaching the warp destination, how far away one has to move along the Y axis in order to use another Teleporter.") .documentation("Upon reaching the warp destination, how far away one has to move along the Y axis in order to use another Teleporter.")
.add() .add()
.build(); .build();
private static final Duration TELEPORTER_GLOBAL_COOLDOWN = Duration.ofMillis(100L);
@Nullable @Nullable
private String particle; private String particle;
private double clearoutXZ = 1.3; private double clearoutXZ = 1.3;
@@ -90,30 +88,56 @@ public class TeleporterInteraction extends SimpleBlockInteraction {
@Nullable ItemStack itemInHand, @Nullable ItemStack itemInHand,
@Nonnull Vector3i targetBlock, @Nonnull Vector3i targetBlock,
@Nonnull CooldownHandler cooldownHandler @Nonnull CooldownHandler cooldownHandler
) {
boolean result = this.interact(world, commandBuffer, context, targetBlock);
if (!result) {
context.getState().state = InteractionState.Failed;
}
}
private boolean interact(
@Nonnull World world, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull InteractionContext context, @Nonnull Vector3i targetBlock
) { ) {
ChunkStore chunkStore = world.getChunkStore(); ChunkStore chunkStore = world.getChunkStore();
long chunkIndex = ChunkUtil.indexChunkFromBlock(targetBlock.getX(), targetBlock.getZ()); long chunkIndex = ChunkUtil.indexChunkFromBlock(targetBlock.getX(), targetBlock.getZ());
BlockComponentChunk blockComponentChunk = chunkStore.getChunkComponent(chunkIndex, BlockComponentChunk.getComponentType()); BlockComponentChunk blockComponentChunk = chunkStore.getChunkComponent(chunkIndex, BlockComponentChunk.getComponentType());
if (blockComponentChunk != null) { if (blockComponentChunk == null) {
return false;
} else {
int blockIndex = ChunkUtil.indexBlockInColumn(targetBlock.x, targetBlock.y, targetBlock.z); int blockIndex = ChunkUtil.indexBlockInColumn(targetBlock.x, targetBlock.y, targetBlock.z);
Ref<ChunkStore> blockRef = blockComponentChunk.getEntityReference(blockIndex); Ref<ChunkStore> blockRef = blockComponentChunk.getEntityReference(blockIndex);
if (blockRef != null && blockRef.isValid()) { if (blockRef != null && blockRef.isValid()) {
BlockModule.BlockStateInfo blockStateInfoComponent = blockRef.getStore().getComponent(blockRef, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfoComponent = blockRef.getStore().getComponent(blockRef, BlockModule.BlockStateInfo.getComponentType());
if (blockStateInfoComponent != null) { if (blockStateInfoComponent == null) {
return false;
} else {
Ref<ChunkStore> chunkRef = blockStateInfoComponent.getChunkRef(); Ref<ChunkStore> chunkRef = blockStateInfoComponent.getChunkRef();
if (chunkRef.isValid()) { if (!chunkRef.isValid()) {
return false;
} else {
Teleporter teleporter = chunkStore.getStore().getComponent(blockRef, Teleporter.getComponentType()); Teleporter teleporter = chunkStore.getStore().getComponent(blockRef, Teleporter.getComponentType());
if (teleporter != null) { if (teleporter == null) {
return false;
} else {
Ref<EntityStore> ref = context.getEntity(); Ref<EntityStore> ref = context.getEntity();
Player playerComponent = commandBuffer.getComponent(ref, Player.getComponentType()); Player playerComponent = commandBuffer.getComponent(ref, Player.getComponentType());
if (playerComponent == null || !playerComponent.isWaitingForClientReady()) { if (playerComponent != null && playerComponent.isWaitingForClientReady()) {
return false;
} else {
Archetype<EntityStore> archetype = commandBuffer.getArchetype(ref); Archetype<EntityStore> archetype = commandBuffer.getArchetype(ref);
if (!archetype.contains(Teleport.getComponentType()) && !archetype.contains(PendingTeleport.getComponentType())) { if (archetype.contains(Teleport.getComponentType()) || archetype.contains(PendingTeleport.getComponentType())) {
if (!archetype.contains(UsedTeleporter.getComponentType())) { return false;
} else if (archetype.contains(UsedTeleporter.getComponentType())) {
return false;
} else {
WorldChunk worldChunkComponent = chunkRef.getStore().getComponent(chunkRef, WorldChunk.getComponentType()); WorldChunk worldChunkComponent = chunkRef.getStore().getComponent(chunkRef, WorldChunk.getComponentType());
if (worldChunkComponent != null) { if (worldChunkComponent == null) {
return false;
} else {
BlockType blockType = worldChunkComponent.getBlockType(targetBlock.x, targetBlock.y, targetBlock.z); BlockType blockType = worldChunkComponent.getBlockType(targetBlock.x, targetBlock.y, targetBlock.z);
if (blockType != null) { if (blockType == null) {
return false;
} else {
if (!teleporter.isValid()) { if (!teleporter.isValid()) {
String currentState = blockType.getStateForBlock(blockType); String currentState = blockType.getStateForBlock(blockType);
if (!"default".equals(currentState)) { if (!"default".equals(currentState)) {
@@ -127,13 +151,15 @@ public class TeleporterInteraction extends SimpleBlockInteraction {
} }
TransformComponent transformComponent = commandBuffer.getComponent(ref, TransformComponent.getComponentType()); TransformComponent transformComponent = commandBuffer.getComponent(ref, TransformComponent.getComponentType());
if (transformComponent != null) { if (transformComponent == null) {
return false;
} else {
Teleport teleportComponent = teleporter.toTeleport( Teleport teleportComponent = teleporter.toTeleport(
transformComponent.getPosition(), transformComponent.getRotation(), targetBlock transformComponent.getPosition(), transformComponent.getRotation(), targetBlock
); );
if (teleportComponent != null) { if (teleportComponent == null) {
TeleportRecord recorder = commandBuffer.getComponent(ref, TeleportRecord.getComponentType()); return false;
if (recorder == null || recorder.hasElapsedSinceLastTeleport(TELEPORTER_GLOBAL_COOLDOWN)) { } else {
commandBuffer.addComponent(ref, Teleport.getComponentType(), teleportComponent); commandBuffer.addComponent(ref, Teleport.getComponentType(), teleportComponent);
commandBuffer.addComponent( commandBuffer.addComponent(
ref, ref,
@@ -149,6 +175,8 @@ public class TeleporterInteraction extends SimpleBlockInteraction {
playerSpatialResource.getSpatialStructure().collect(particlePosition, 75.0, results); playerSpatialResource.getSpatialStructure().collect(particlePosition, 75.0, results);
ParticleUtil.spawnParticleEffect(this.particle, particlePosition, results, commandBuffer); ParticleUtil.spawnParticleEffect(this.particle, particlePosition, results, commandBuffer);
} }
return true;
} }
} }
} }
@@ -158,8 +186,8 @@ public class TeleporterInteraction extends SimpleBlockInteraction {
} }
} }
} }
} } else {
} return false;
} }
} }
} }

View File

@@ -13,7 +13,6 @@ import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.math.util.ChunkUtil; import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.vector.Transform; import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime; import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType; import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.protocol.packets.interface_.Page; import com.hypixel.hytale.protocol.packets.interface_.Page;
@@ -38,6 +37,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSettingsPage.PageEventData> { public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSettingsPage.PageEventData> {
@Nonnull @Nonnull
@@ -103,16 +103,7 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
commandBuilder.set("#WorldDropdown.Entries", worlds); commandBuilder.set("#WorldDropdown.Entries", worlds);
UUID worldUuid = teleporter.getWorldUuid(); UUID worldUuid = teleporter.getWorldUuid();
commandBuilder.set("#WorldDropdown.Value", worldUuid != null ? worldUuid.toString() : ""); commandBuilder.set("#WorldDropdown.Value", worldUuid != null ? worldUuid.toString() : "");
ObjectArrayList<DropdownEntryInfo> warps = new ObjectArrayList<>(); commandBuilder.set("#WarpDropdown.Entries", getWarpsSortedById(teleporter.getOwnedWarp(), null));
warps.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.teleporter.noWarp"), ""));
for (Warp warp : TeleportPlugin.get().getWarps().values()) {
if (!warp.getId().equalsIgnoreCase(teleporter.getOwnedWarp())) {
warps.add(new DropdownEntryInfo(LocalizableString.fromString(warp.getId()), warp.getId().toLowerCase()));
}
}
commandBuilder.set("#WarpDropdown.Entries", warps);
commandBuilder.set("#WarpDropdown.Value", teleporter.getWarp() != null ? teleporter.getWarp() : ""); commandBuilder.set("#WarpDropdown.Value", teleporter.getWarp() != null ? teleporter.getWarp() : "");
commandBuilder.set("#NewWarp.Value", teleporter.getOwnedWarp() != null ? teleporter.getOwnedWarp() : ""); commandBuilder.set("#NewWarp.Value", teleporter.getOwnedWarp() != null ? teleporter.getOwnedWarp() : "");
eventBuilder.addEventBinding( eventBuilder.addEventBinding(
@@ -138,16 +129,7 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
); );
break; break;
case WARP: case WARP:
List<DropdownEntryInfo> warps = new ObjectArrayList<>(); commandBuilder.set("#WarpDropdown.Entries", getWarpsSortedById(teleporter.getOwnedWarp(), store.getExternalData().getWorld().getName()));
warps.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.teleporter.noWarp"), ""));
for (Warp warpx : TeleportPlugin.get().getWarps().values()) {
if (warpx.getWorld().equals(store.getExternalData().getWorld().getName()) && !warpx.getId().equalsIgnoreCase(teleporter.getOwnedWarp())) {
warps.add(new DropdownEntryInfo(LocalizableString.fromString(warpx.getId()), warpx.getId().toLowerCase()));
}
}
commandBuilder.set("#WarpDropdown.Entries", warps);
commandBuilder.set("#WarpDropdown.Value", teleporter.getWarp() != null ? teleporter.getWarp() : ""); commandBuilder.set("#WarpDropdown.Value", teleporter.getWarp() != null ? teleporter.getWarp() : "");
Message placeholder; Message placeholder;
if (teleporter.hasOwnedWarp() && !teleporter.isCustomName()) { if (teleporter.hasOwnedWarp() && !teleporter.isCustomName()) {
@@ -169,11 +151,24 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
} }
} }
static List<DropdownEntryInfo> getWarpsSortedById(@NullableDecl String ownedWarpId, @NullableDecl String worldNameToFilter) {
List<DropdownEntryInfo> warps = new ObjectArrayList<>();
warps.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.teleporter.noWarp"), ""));
ObjectArrayList<Warp> sortedWarps = new ObjectArrayList<>(TeleportPlugin.get().getWarps().values());
sortedWarps.sort((a, b) -> a.getId().compareToIgnoreCase(b.getId()));
for (Warp warp : sortedWarps) {
if ((worldNameToFilter == null || warp.getWorld().equals(worldNameToFilter)) && !warp.getId().equalsIgnoreCase(ownedWarpId)) {
warps.add(new DropdownEntryInfo(LocalizableString.fromString(warp.getId()), warp.getId().toLowerCase()));
}
}
return warps;
}
public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull TeleporterSettingsPage.PageEventData data) { public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull TeleporterSettingsPage.PageEventData data) {
Player playerComponent = store.getComponent(ref, Player.getComponentType()); Player playerComponent = store.getComponent(ref, Player.getComponentType());
if (playerComponent != null) {
assert playerComponent != null;
String language = this.playerRef.getLanguage(); String language = this.playerRef.getLanguage();
BlockModule.BlockStateInfo blockStateInfo = this.blockRef.getStore().getComponent(this.blockRef, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfo = this.blockRef.getStore().getComponent(this.blockRef, BlockModule.BlockStateInfo.getComponentType());
if (blockStateInfo == null) { if (blockStateInfo == null) {
@@ -191,14 +186,22 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
int targetX = ChunkUtil.xFromBlockInColumn(index); int targetX = ChunkUtil.xFromBlockInColumn(index);
int targetY = ChunkUtil.yFromBlockInColumn(index); int targetY = ChunkUtil.yFromBlockInColumn(index);
int targetZ = ChunkUtil.zFromBlockInColumn(index); int targetZ = ChunkUtil.zFromBlockInColumn(index);
new Vector3i(targetX, targetY, targetZ); Teleporter teleporterComponent = this.blockRef.getStore().getComponent(this.blockRef, Teleporter.getComponentType());
Teleporter teleporter = this.blockRef.getStore().getComponent(this.blockRef, Teleporter.getComponentType()); if (teleporterComponent == null) {
String oldOwnedWarp = teleporter.getOwnedWarp(); playerComponent.getPageManager().setPage(ref, store, Page.None);
} else {
String oldOwnedWarp = teleporterComponent.getOwnedWarp();
boolean customName = true; boolean customName = true;
if (data.ownedWarp == null || data.ownedWarp.isEmpty()) { if (data.warpName == null || data.warpName.isEmpty()) {
data.ownedWarp = CannedWarpNames.generateCannedWarpName(this.blockRef, language); if (oldOwnedWarp == null) {
data.warpName = CannedWarpNames.generateCannedWarpName(this.blockRef, language);
customName = false; customName = false;
if (data.ownedWarp == null) { } else {
data.warpName = oldOwnedWarp;
customName = teleporterComponent.isCustomName();
}
if (data.warpName == null) {
UICommandBuilder commandBuilder = new UICommandBuilder(); UICommandBuilder commandBuilder = new UICommandBuilder();
commandBuilder.set("#NewWarp.PlaceholderText", Message.translation("server.customUI.teleporter.warpNameRightHereHint")); commandBuilder.set("#NewWarp.PlaceholderText", Message.translation("server.customUI.teleporter.warpNameRightHereHint"));
commandBuilder.set("#ErrorLabel.Text", Message.translation("server.customUI.teleporter.errorMissingWarpName")); commandBuilder.set("#ErrorLabel.Text", Message.translation("server.customUI.teleporter.errorMissingWarpName"));
@@ -208,8 +211,8 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
} }
} }
if (!data.ownedWarp.equalsIgnoreCase(oldOwnedWarp)) { if (!data.warpName.equalsIgnoreCase(oldOwnedWarp)) {
boolean alreadyExists = TeleportPlugin.get().getWarps().containsKey(data.ownedWarp.toLowerCase()); boolean alreadyExists = TeleportPlugin.get().getWarps().containsKey(data.warpName.toLowerCase());
if (alreadyExists) { if (alreadyExists) {
UICommandBuilder commandBuilder = new UICommandBuilder(); UICommandBuilder commandBuilder = new UICommandBuilder();
commandBuilder.set("#ErrorLabel.Text", Message.translation("server.customUI.teleporter.errorWarpAlreadyExists")); commandBuilder.set("#ErrorLabel.Text", Message.translation("server.customUI.teleporter.errorWarpAlreadyExists"));
@@ -224,12 +227,12 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
} }
playerComponent.getPageManager().setPage(ref, store, Page.None); playerComponent.getPageManager().setPage(ref, store, Page.None);
CreateWarpWhenTeleporterPlacedSystem.createWarp(worldChunkComponent, blockStateInfo, data.ownedWarp); CreateWarpWhenTeleporterPlacedSystem.createWarp(worldChunkComponent, blockStateInfo, data.warpName);
teleporter.setOwnedWarp(data.ownedWarp); teleporterComponent.setOwnedWarp(data.warpName);
teleporter.setIsCustomName(customName); teleporterComponent.setIsCustomName(customName);
switch (this.mode) { switch (this.mode) {
case FULL: case FULL:
teleporter.setWorldUuid(data.world != null && !data.world.isEmpty() ? UUID.fromString(data.world) : null); teleporterComponent.setWorldUuid(data.world != null && !data.world.isEmpty() ? UUID.fromString(data.world) : null);
Transform transform = new Transform(); Transform transform = new Transform();
transform.getPosition().setX(data.x); transform.getPosition().setX(data.x);
transform.getPosition().setY(data.y); transform.getPosition().setY(data.y);
@@ -237,8 +240,8 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
transform.getRotation().setYaw(data.yaw); transform.getRotation().setYaw(data.yaw);
transform.getRotation().setPitch(data.pitch); transform.getRotation().setPitch(data.pitch);
transform.getRotation().setRoll(data.roll); transform.getRotation().setRoll(data.roll);
teleporter.setTransform(transform); teleporterComponent.setTransform(transform);
teleporter.setRelativeMask( teleporterComponent.setRelativeMask(
(byte)( (byte)(
(data.xIsRelative ? 1 : 0) (data.xIsRelative ? 1 : 0)
| (data.yIsRelative ? 2 : 0) | (data.yIsRelative ? 2 : 0)
@@ -249,22 +252,27 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
| (data.isBlockRelative ? 64 : 0) | (data.isBlockRelative ? 64 : 0)
) )
); );
teleporter.setWarp(data.warp != null && !data.warp.isEmpty() ? data.warp : null); teleporterComponent.setWarp(data.warp != null && !data.warp.isEmpty() ? data.warp : null);
break; break;
case WARP: case WARP:
teleporter.setWorldUuid(null); teleporterComponent.setWorldUuid(null);
teleporter.setTransform(null); teleporterComponent.setTransform(null);
teleporter.setWarp(data.warp != null && !data.warp.isEmpty() ? data.warp : null); teleporterComponent.setWarp(data.warp != null && !data.warp.isEmpty() ? data.warp : null);
} }
String newState = "default"; String newState = "default";
if (teleporter.isValid()) { if (teleporterComponent.isValid()) {
newState = this.activeState != null ? this.activeState : "default"; newState = this.activeState != null ? this.activeState : "default";
} }
boolean isDifferentState = false;
BlockType blockType = worldChunkComponent.getBlockType(targetX, targetY, targetZ); BlockType blockType = worldChunkComponent.getBlockType(targetX, targetY, targetZ);
if (blockType != null) {
String currentState = blockType.getStateForBlock(blockType); String currentState = blockType.getStateForBlock(blockType);
if (currentState == null || !currentState.equals(newState)) { isDifferentState = !newState.equals(currentState);
}
if (isDifferentState) {
BlockType variantBlockType = blockType.getBlockForState(newState); BlockType variantBlockType = blockType.getBlockForState(newState);
if (variantBlockType != null) { if (variantBlockType != null) {
worldChunkComponent.setBlockInteractionState(targetX, targetY, targetZ, variantBlockType, newState, true); worldChunkComponent.setBlockInteractionState(targetX, targetY, targetZ, variantBlockType, newState, true);
@@ -275,31 +283,51 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
} }
} }
} }
}
}
public static enum Mode { public static enum Mode {
FULL, FULL,
WARP; WARP;
@Nonnull
public static final Codec<TeleporterSettingsPage.Mode> CODEC = new EnumCodec<>(TeleporterSettingsPage.Mode.class); public static final Codec<TeleporterSettingsPage.Mode> CODEC = new EnumCodec<>(TeleporterSettingsPage.Mode.class);
} }
public static class PageEventData { public static class PageEventData {
@Nonnull
public static final String KEY_BLOCK_RELATIVE = "@BlockRelative"; public static final String KEY_BLOCK_RELATIVE = "@BlockRelative";
@Nonnull
public static final String KEY_X = "@X"; public static final String KEY_X = "@X";
@Nonnull
public static final String KEY_Y = "@Y"; public static final String KEY_Y = "@Y";
@Nonnull
public static final String KEY_Z = "@Z"; public static final String KEY_Z = "@Z";
@Nonnull
public static final String KEY_X_IS_RELATIVE = "@XIsRelative"; public static final String KEY_X_IS_RELATIVE = "@XIsRelative";
@Nonnull
public static final String KEY_Y_IS_RELATIVE = "@YIsRelative"; public static final String KEY_Y_IS_RELATIVE = "@YIsRelative";
@Nonnull
public static final String KEY_Z_IS_RELATIVE = "@ZIsRelative"; public static final String KEY_Z_IS_RELATIVE = "@ZIsRelative";
@Nonnull
public static final String KEY_YAW = "@Yaw"; public static final String KEY_YAW = "@Yaw";
@Nonnull
public static final String KEY_PITCH = "@Pitch"; public static final String KEY_PITCH = "@Pitch";
@Nonnull
public static final String KEY_ROLL = "@Roll"; public static final String KEY_ROLL = "@Roll";
@Nonnull
public static final String KEY_YAW_IS_RELATIVE = "@YawIsRelative"; public static final String KEY_YAW_IS_RELATIVE = "@YawIsRelative";
@Nonnull
public static final String KEY_PITCH_IS_RELATIVE = "@PitchIsRelative"; public static final String KEY_PITCH_IS_RELATIVE = "@PitchIsRelative";
@Nonnull
public static final String KEY_ROLL_IS_RELATIVE = "@RollIsRelative"; public static final String KEY_ROLL_IS_RELATIVE = "@RollIsRelative";
@Nonnull
public static final String KEY_WORLD = "@World"; public static final String KEY_WORLD = "@World";
@Nonnull
public static final String KEY_WARP = "@Warp"; public static final String KEY_WARP = "@Warp";
@Nonnull
public static final String KEY_NEW_WARP = "@NewWarp"; public static final String KEY_NEW_WARP = "@NewWarp";
@Nonnull
public static final BuilderCodec<TeleporterSettingsPage.PageEventData> CODEC = BuilderCodec.builder( public static final BuilderCodec<TeleporterSettingsPage.PageEventData> CODEC = BuilderCodec.builder(
TeleporterSettingsPage.PageEventData.class, TeleporterSettingsPage.PageEventData::new TeleporterSettingsPage.PageEventData.class, TeleporterSettingsPage.PageEventData::new
) )
@@ -355,7 +383,7 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
.add() .add()
.append(new KeyedCodec<>("@Warp", Codec.STRING), (pageEventData, o) -> pageEventData.warp = o, pageEventData -> pageEventData.warp) .append(new KeyedCodec<>("@Warp", Codec.STRING), (pageEventData, o) -> pageEventData.warp = o, pageEventData -> pageEventData.warp)
.add() .add()
.append(new KeyedCodec<>("@NewWarp", Codec.STRING), (pageEventData, o) -> pageEventData.ownedWarp = o, pageEventData -> pageEventData.ownedWarp) .append(new KeyedCodec<>("@NewWarp", Codec.STRING), (pageEventData, o) -> pageEventData.warpName = o, pageEventData -> pageEventData.warpName)
.add() .add()
.build(); .build();
public boolean isBlockRelative; public boolean isBlockRelative;
@@ -374,6 +402,6 @@ public class TeleporterSettingsPage extends InteractiveCustomUIPage<TeleporterSe
public String world; public String world;
public String warp; public String warp;
@Nullable @Nullable
public String ownedWarp; public String warpName;
} }
} }

View File

@@ -24,6 +24,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class TeleporterSettingsPageSupplier implements OpenCustomUIInteraction.CustomPageSupplier { public class TeleporterSettingsPageSupplier implements OpenCustomUIInteraction.CustomPageSupplier {
@Nonnull
public static final BuilderCodec<TeleporterSettingsPageSupplier> CODEC = BuilderCodec.builder( public static final BuilderCodec<TeleporterSettingsPageSupplier> CODEC = BuilderCodec.builder(
TeleporterSettingsPageSupplier.class, TeleporterSettingsPageSupplier::new TeleporterSettingsPageSupplier.class, TeleporterSettingsPageSupplier::new
) )

View File

@@ -1,46 +1,99 @@
package com.hypixel.hytale.builtin.adventure.teleporter.system; package com.hypixel.hytale.builtin.adventure.teleporter.system;
import com.hypixel.hytale.builtin.adventure.teleporter.interaction.server.UsedTeleporter; import com.hypixel.hytale.builtin.adventure.teleporter.interaction.server.UsedTeleporter;
import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.ArchetypeChunk; import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.dependency.Dependency;
import com.hypixel.hytale.component.dependency.Order;
import com.hypixel.hytale.component.dependency.SystemDependency;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.tick.EntityTickingSystem; import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
import com.hypixel.hytale.math.vector.Vector2d; import com.hypixel.hytale.math.vector.Vector2d;
import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.teleport.PendingTeleport;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.server.core.modules.entity.teleport.TeleportRecord;
import com.hypixel.hytale.server.core.modules.entity.teleport.TeleportSystems;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.time.Duration;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nullable; import javax.annotation.Nonnull;
import org.checkerframework.checker.nullness.compatqual.NonNullDecl;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
public class ClearUsedTeleporterSystem extends EntityTickingSystem<EntityStore> { public class ClearUsedTeleporterSystem extends EntityTickingSystem<EntityStore> {
@Nonnull
public static final Duration TELEPORTER_GLOBAL_COOLDOWN = Duration.ofMillis(100L);
@Nonnull
private static final Set<Dependency<EntityStore>> DEPENDENCIES = Set.of(new SystemDependency<>(Order.AFTER, TeleportSystems.PlayerMoveSystem.class));
@Nonnull
private final ComponentType<EntityStore, UsedTeleporter> usedTeleporterComponentType;
@Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull
private final ComponentType<EntityStore, TeleportRecord> teleportRecordComponentType;
@Nonnull
private final ComponentType<EntityStore, Teleport> teleportComponentType;
@Nonnull
private final ComponentType<EntityStore, PendingTeleport> pendingTeleportComponentType;
public ClearUsedTeleporterSystem(
@Nonnull ComponentType<EntityStore, UsedTeleporter> usedTeleporterComponentType,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType,
@Nonnull ComponentType<EntityStore, TeleportRecord> teleportRecordComponentType,
@Nonnull ComponentType<EntityStore, Teleport> teleportComponentType,
@Nonnull ComponentType<EntityStore, PendingTeleport> pendingTeleportComponentType
) {
this.usedTeleporterComponentType = usedTeleporterComponentType;
this.transformComponentType = transformComponentType;
this.teleportRecordComponentType = teleportRecordComponentType;
this.teleportComponentType = teleportComponentType;
this.pendingTeleportComponentType = pendingTeleportComponentType;
}
@Nonnull
@Override
public Set<Dependency<EntityStore>> getDependencies() {
return DEPENDENCIES;
}
@Override @Override
public void tick( public void tick(
float dt, float dt,
int index, int index,
@NonNullDecl ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk,
@NonNullDecl Store<EntityStore> store, @Nonnull Store<EntityStore> store,
@NonNullDecl CommandBuffer<EntityStore> commandBuffer @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
UsedTeleporter usedTeleporter = archetypeChunk.getComponent(index, UsedTeleporter.getComponentType()); if (this.shouldClear(world, index, archetypeChunk)) {
TransformComponent transformComponent = archetypeChunk.getComponent(index, TransformComponent.getComponentType());
if (shouldClear(world, usedTeleporter, transformComponent)) {
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index); Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
commandBuffer.removeComponent(ref, UsedTeleporter.getComponentType()); commandBuffer.removeComponent(ref, this.usedTeleporterComponentType);
} }
} }
private static boolean shouldClear(World entityWorld, UsedTeleporter usedTeleporter, @Nullable TransformComponent transformComponent) { private boolean shouldClear(@Nonnull World world, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk) {
UsedTeleporter usedTeleporter = archetypeChunk.getComponent(index, this.usedTeleporterComponentType);
assert usedTeleporter != null;
TransformComponent transformComponent = archetypeChunk.getComponent(index, this.transformComponentType);
TeleportRecord teleportRecord = archetypeChunk.getComponent(index, this.teleportRecordComponentType);
if (transformComponent == null) { if (transformComponent == null) {
return true; return true;
} else {
Archetype<EntityStore> archetype = archetypeChunk.getArchetype();
if (!archetype.contains(this.teleportComponentType) && !archetype.contains(this.pendingTeleportComponentType)) {
if (teleportRecord != null && !teleportRecord.hasElapsedSinceLastTeleport(System.nanoTime(), TELEPORTER_GLOBAL_COOLDOWN)) {
return false;
} else { } else {
UUID destinationWorldUuid = usedTeleporter.getDestinationWorldUuid(); UUID destinationWorldUuid = usedTeleporter.getDestinationWorldUuid();
if (destinationWorldUuid != null && !entityWorld.getWorldConfig().getUuid().equals(destinationWorldUuid)) { if (destinationWorldUuid != null && !world.getWorldConfig().getUuid().equals(destinationWorldUuid)) {
return true; return true;
} else { } else {
Vector3d entityPosition = transformComponent.getPosition(); Vector3d entityPosition = transformComponent.getPosition();
@@ -50,11 +103,15 @@ public class ClearUsedTeleporterSystem extends EntityTickingSystem<EntityStore>
return deltaY > usedTeleporter.getClearOutY() || distanceXZsq > usedTeleporter.getClearOutXZ(); return deltaY > usedTeleporter.getClearOutY() || distanceXZsq > usedTeleporter.getClearOutXZ();
} }
} }
} else {
return false;
}
}
} }
@NullableDecl @Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return UsedTeleporter.getComponentType(); return this.usedTeleporterComponentType;
} }
} }

View File

@@ -31,6 +31,30 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class CreateWarpWhenTeleporterPlacedSystem extends RefChangeSystem<ChunkStore, PlacedByInteractionComponent> { public class CreateWarpWhenTeleporterPlacedSystem extends RefChangeSystem<ChunkStore, PlacedByInteractionComponent> {
@Nonnull
private final ComponentType<ChunkStore, PlacedByInteractionComponent> placedByInteractionComponentType;
@Nonnull
private final ComponentType<ChunkStore, Teleporter> teleporterComponentType;
@Nonnull
private final ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType;
@Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final Query<ChunkStore> query;
public CreateWarpWhenTeleporterPlacedSystem(
@Nonnull ComponentType<ChunkStore, PlacedByInteractionComponent> placedByInteractionComponentType,
@Nonnull ComponentType<ChunkStore, Teleporter> teleporterComponentType,
@Nonnull ComponentType<ChunkStore, BlockModule.BlockStateInfo> blockStateInfoComponentType,
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType
) {
this.placedByInteractionComponentType = placedByInteractionComponentType;
this.teleporterComponentType = teleporterComponentType;
this.blockStateInfoComponentType = blockStateInfoComponentType;
this.playerRefComponentType = playerRefComponentType;
this.query = Query.and(placedByInteractionComponentType, teleporterComponentType, blockStateInfoComponentType);
}
public void onComponentAdded( public void onComponentAdded(
@Nonnull Ref<ChunkStore> ref, @Nonnull Ref<ChunkStore> ref,
@Nonnull PlacedByInteractionComponent placedBy, @Nonnull PlacedByInteractionComponent placedBy,
@@ -42,21 +66,21 @@ public class CreateWarpWhenTeleporterPlacedSystem extends RefChangeSystem<ChunkS
UUID whoPlacedUuid = placedBy.getWhoPlacedUuid(); UUID whoPlacedUuid = placedBy.getWhoPlacedUuid();
Ref<EntityStore> whoPlacedRef = entityStore.getRefFromUUID(whoPlacedUuid); Ref<EntityStore> whoPlacedRef = entityStore.getRefFromUUID(whoPlacedUuid);
if (whoPlacedRef != null && whoPlacedRef.isValid()) { if (whoPlacedRef != null && whoPlacedRef.isValid()) {
PlayerRef playerRefComponent = entityStore.getStore().getComponent(whoPlacedRef, PlayerRef.getComponentType()); PlayerRef playerRefComponent = entityStore.getStore().getComponent(whoPlacedRef, this.playerRefComponentType);
String language = playerRefComponent == null ? null : playerRefComponent.getLanguage(); String language = playerRefComponent == null ? null : playerRefComponent.getLanguage();
if (language != null) { if (language != null) {
BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, this.blockStateInfoComponentType);
assert blockStateInfoComponent != null; assert blockStateInfoComponent != null;
Ref<ChunkStore> chunkRef = blockStateInfoComponent.getChunkRef(); Ref<ChunkStore> chunkRef = blockStateInfoComponent.getChunkRef();
if (chunkRef != null && chunkRef.isValid()) { if (chunkRef.isValid()) {
WorldChunk worldChunk = chunkStore.getComponent(chunkRef, WorldChunk.getComponentType()); WorldChunk worldChunk = chunkStore.getComponent(chunkRef, WorldChunk.getComponentType());
if (worldChunk != null) { if (worldChunk != null) {
String cannedName = CannedWarpNames.generateCannedWarpName(ref, language); String cannedName = CannedWarpNames.generateCannedWarpName(ref, language);
if (cannedName != null) { if (cannedName != null) {
createWarp(worldChunk, blockStateInfoComponent, cannedName); createWarp(worldChunk, blockStateInfoComponent, cannedName);
Teleporter teleporterComponent = commandBuffer.getComponent(ref, Teleporter.getComponentType()); Teleporter teleporterComponent = commandBuffer.getComponent(ref, this.teleporterComponentType);
assert teleporterComponent != null; assert teleporterComponent != null;
@@ -76,9 +100,7 @@ public class CreateWarpWhenTeleporterPlacedSystem extends RefChangeSystem<ChunkS
int y = ChunkUtil.yFromBlockInColumn(index); int y = ChunkUtil.yFromBlockInColumn(index);
int z = chunkBlockZ + ChunkUtil.zFromBlockInColumn(index); int z = chunkBlockZ + ChunkUtil.zFromBlockInColumn(index);
BlockChunk blockChunkComponent = worldChunk.getBlockChunk(); BlockChunk blockChunkComponent = worldChunk.getBlockChunk();
if (blockChunkComponent != null) {
assert blockChunkComponent != null;
BlockSection section = blockChunkComponent.getSectionAtBlockY(y); BlockSection section = blockChunkComponent.getSectionAtBlockY(y);
int rotationIndex = section.getRotationIndex(x, y, z); int rotationIndex = section.getRotationIndex(x, y, z);
RotationTuple rotationTuple = RotationTuple.get(rotationIndex); RotationTuple rotationTuple = RotationTuple.get(rotationIndex);
@@ -92,6 +114,7 @@ public class CreateWarpWhenTeleporterPlacedSystem extends RefChangeSystem<ChunkS
teleportPlugin.getWarps().put(warpId, warp); teleportPlugin.getWarps().put(warpId, warp);
teleportPlugin.saveWarps(); teleportPlugin.saveWarps();
} }
}
public void onComponentSet( public void onComponentSet(
@Nonnull Ref<ChunkStore> ref, @Nonnull Ref<ChunkStore> ref,
@@ -113,12 +136,12 @@ public class CreateWarpWhenTeleporterPlacedSystem extends RefChangeSystem<ChunkS
@Nonnull @Nonnull
@Override @Override
public ComponentType<ChunkStore, PlacedByInteractionComponent> componentType() { public ComponentType<ChunkStore, PlacedByInteractionComponent> componentType() {
return PlacedByInteractionComponent.getComponentType(); return this.placedByInteractionComponentType;
} }
@Nullable @Nonnull
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return Query.and(PlacedByInteractionComponent.getComponentType(), Teleporter.getComponentType(), BlockModule.BlockStateInfo.getComponentType()); return this.query;
} }
} }

View File

@@ -21,23 +21,23 @@ public final class CannedWarpNames {
} }
@Nullable @Nullable
public static String generateCannedWarpName(Ref<ChunkStore> blockRef, String language) { public static String generateCannedWarpName(@Nonnull Ref<ChunkStore> blockRef, @Nonnull String language) {
String translationKey = generateCannedWarpNameKey(blockRef, language); String translationKey = generateCannedWarpNameKey(blockRef, language);
return translationKey == null ? null : I18nModule.get().getMessage(language, translationKey); return translationKey == null ? null : I18nModule.get().getMessage(language, translationKey);
} }
@Nullable @Nullable
public static String generateCannedWarpNameKey(Ref<ChunkStore> blockRef, String language) { public static String generateCannedWarpNameKey(@Nonnull Ref<ChunkStore> blockRef, @Nonnull String language) {
Store<ChunkStore> store = blockRef.getStore(); Store<ChunkStore> store = blockRef.getStore();
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
BlockModule.BlockStateInfo blockStateInfo = store.getComponent(blockRef, BlockModule.BlockStateInfo.getComponentType()); BlockModule.BlockStateInfo blockStateInfo = store.getComponent(blockRef, BlockModule.BlockStateInfo.getComponentType());
Random random = blockStateInfo == null ? new Random() : new Random(blockStateInfo.getIndex()); Random random = blockStateInfo == null ? new Random() : new Random(blockStateInfo.getIndex());
Teleporter teleporter = store.getComponent(blockRef, Teleporter.getComponentType()); Teleporter teleporterComponent = store.getComponent(blockRef, Teleporter.getComponentType());
String wordListKey = teleporter == null ? null : teleporter.getWarpNameWordListKey(); String wordListKey = teleporterComponent == null ? null : teleporterComponent.getWarpNameWordListKey();
Set<String> existingNames = getWarpNamesInWorld(world); Set<String> existingNames = getWarpNamesInWorld(world);
if (teleporter != null) { if (teleporterComponent != null) {
String ownName = teleporter.getOwnedWarp(); String ownName = teleporterComponent.getOwnedWarp();
if (ownName != null && !teleporter.isCustomName()) { if (ownName != null && !teleporterComponent.isCustomName()) {
existingNames.remove(ownName); existingNames.remove(ownName);
} }
} }
@@ -46,7 +46,7 @@ public final class CannedWarpNames {
} }
@Nonnull @Nonnull
private static Set<String> getWarpNamesInWorld(World world) { private static Set<String> getWarpNamesInWorld(@Nonnull World world) {
Set<String> existingNames = new HashSet<>(); Set<String> existingNames = new HashSet<>();
for (Warp warp : TeleportPlugin.get().getWarps().values()) { for (Warp warp : TeleportPlugin.get().getWarps().values()) {

View File

@@ -21,6 +21,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class NeighbourBlockTagsLocationCondition extends WorldLocationCondition { public class NeighbourBlockTagsLocationCondition extends WorldLocationCondition {
@Nonnull
public static final BuilderCodec<NeighbourBlockTagsLocationCondition> CODEC = BuilderCodec.builder( public static final BuilderCodec<NeighbourBlockTagsLocationCondition> CODEC = BuilderCodec.builder(
NeighbourBlockTagsLocationCondition.class, NeighbourBlockTagsLocationCondition::new, WorldLocationCondition.BASE_CODEC NeighbourBlockTagsLocationCondition.class, NeighbourBlockTagsLocationCondition::new, WorldLocationCondition.BASE_CODEC
) )
@@ -53,11 +54,12 @@ public class NeighbourBlockTagsLocationCondition extends WorldLocationCondition
protected IntRange support = new IntRange(1, 4); protected IntRange support = new IntRange(1, 4);
@Override @Override
public boolean test(World world, int worldX, int worldY, int worldZ) { public boolean test(@Nonnull World world, int worldX, int worldY, int worldZ) {
if (worldY <= 0) { if (worldY <= 0) {
return false; return false;
} else { } else {
WorldChunk worldChunk = world.getNonTickingChunk(ChunkUtil.indexChunkFromBlock(worldX, worldZ)); long chunkIndex = ChunkUtil.indexChunkFromBlock(worldX, worldZ);
WorldChunk worldChunk = world.getNonTickingChunk(chunkIndex);
if (worldChunk == null) { if (worldChunk == null) {
return false; return false;
} else if (this.neighbourDirection == NeighbourBlockTagsLocationCondition.NeighbourDirection.SIDEWAYS) { } else if (this.neighbourDirection == NeighbourBlockTagsLocationCondition.NeighbourDirection.SIDEWAYS) {
@@ -95,17 +97,26 @@ public class NeighbourBlockTagsLocationCondition extends WorldLocationCondition
} }
} }
private boolean checkBlockHasTag(int x, int y, int z, @Nonnull BlockAccessor worldChunk) { private boolean checkBlockHasTag(int x, int y, int z, @Nullable BlockAccessor worldChunk) {
if (worldChunk == null) {
return false;
} else {
int blockIndex = worldChunk.getBlock(x, y, z); int blockIndex = worldChunk.getBlock(x, y, z);
TagPattern tagPattern = TagPattern.getAssetMap().getAsset(this.tagPatternId); TagPattern tagPattern = TagPattern.getAssetMap().getAsset(this.tagPatternId);
if (tagPattern != null) { if (tagPattern != null) {
AssetExtraInfo.Data data = BlockType.getAssetMap().getAsset(blockIndex).getData(); BlockType blockType = BlockType.getAssetMap().getAsset(blockIndex);
if (blockType == null) {
return false;
} else {
AssetExtraInfo.Data data = blockType.getData();
return data == null ? false : tagPattern.test(data.getTags()); return data == null ? false : tagPattern.test(data.getTags());
}
} else { } else {
HytaleLogger.getLogger().at(Level.WARNING).log("No TagPattern asset found for id: " + this.tagPatternId); HytaleLogger.getLogger().at(Level.WARNING).log("No TagPattern asset found for id: " + this.tagPatternId);
return false; return false;
} }
} }
}
@Override @Override
public boolean equals(@Nullable Object o) { public boolean equals(@Nullable Object o) {
@@ -145,7 +156,7 @@ public class NeighbourBlockTagsLocationCondition extends WorldLocationCondition
+ super.toString(); + super.toString();
} }
private static enum NeighbourDirection { protected static enum NeighbourDirection {
ABOVE, ABOVE,
BELOW, BELOW,
SIDEWAYS; SIDEWAYS;

View File

@@ -10,23 +10,33 @@ import com.hypixel.hytale.builtin.ambience.systems.ForcedMusicSystems;
import com.hypixel.hytale.codec.Codec; import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec; import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec; import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.ComponentRegistryProxy;
import com.hypixel.hytale.component.ComponentType; import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.ResourceType; import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.server.core.asset.type.model.config.Model; import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset; import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.entity.component.AudioComponent;
import com.hypixel.hytale.server.core.modules.entity.component.Intangible;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.tracker.NetworkId;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.prefab.PrefabCopyableComponent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.core.util.Config; import com.hypixel.hytale.server.core.util.Config;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class AmbiencePlugin extends JavaPlugin { public class AmbiencePlugin extends JavaPlugin {
@Nonnull
private static final String DEFAULT_AMBIENT_EMITTER_MODEL = "NPC_Spawn_Marker"; private static final String DEFAULT_AMBIENT_EMITTER_MODEL = "NPC_Spawn_Marker";
private static AmbiencePlugin instance; private static AmbiencePlugin instance;
private ComponentType<EntityStore, AmbienceTracker> ambienceTrackerComponentType; private ComponentType<EntityStore, AmbienceTracker> ambienceTrackerComponentType;
private ComponentType<EntityStore, AmbientEmitterComponent> ambientEmitterComponentType; private ComponentType<EntityStore, AmbientEmitterComponent> ambientEmitterComponentType;
private ResourceType<EntityStore, AmbienceResource> ambienceResourceType; private ResourceType<EntityStore, AmbienceResource> ambienceResourceType;
@Nonnull
private final Config<AmbiencePlugin.AmbiencePluginConfig> config = this.withConfig("AmbiencePlugin", AmbiencePlugin.AmbiencePluginConfig.CODEC); private final Config<AmbiencePlugin.AmbiencePluginConfig> config = this.withConfig("AmbiencePlugin", AmbiencePlugin.AmbiencePluginConfig.CODEC);
private Model ambientEmitterModel; private Model ambientEmitterModel;
@@ -41,15 +51,32 @@ public class AmbiencePlugin extends JavaPlugin {
@Override @Override
protected void setup() { protected void setup() {
this.ambienceTrackerComponentType = this.getEntityStoreRegistry().registerComponent(AmbienceTracker.class, AmbienceTracker::new); ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry();
this.ambientEmitterComponentType = this.getEntityStoreRegistry() this.ambienceTrackerComponentType = entityStoreRegistry.registerComponent(AmbienceTracker.class, AmbienceTracker::new);
.registerComponent(AmbientEmitterComponent.class, "AmbientEmitter", AmbientEmitterComponent.CODEC); this.ambientEmitterComponentType = entityStoreRegistry.registerComponent(AmbientEmitterComponent.class, "AmbientEmitter", AmbientEmitterComponent.CODEC);
this.ambienceResourceType = this.getEntityStoreRegistry().registerResource(AmbienceResource.class, AmbienceResource::new); this.ambienceResourceType = entityStoreRegistry.registerResource(AmbienceResource.class, AmbienceResource::new);
this.getEntityStoreRegistry().registerSystem(new AmbientEmitterSystems.EntityAdded()); ComponentType<EntityStore, TransformComponent> transformComponentType = TransformComponent.getComponentType();
this.getEntityStoreRegistry().registerSystem(new AmbientEmitterSystems.EntityRefAdded()); ComponentType<EntityStore, NetworkId> networkIdComponentType = NetworkId.getComponentType();
this.getEntityStoreRegistry().registerSystem(new AmbientEmitterSystems.Ticking()); ComponentType<EntityStore, Intangible> intangibleComponentType = Intangible.getComponentType();
this.getEntityStoreRegistry().registerSystem(new ForcedMusicSystems.Tick()); ComponentType<EntityStore, PrefabCopyableComponent> prefabCopyableComponentType = PrefabCopyableComponent.getComponentType();
this.getEntityStoreRegistry().registerSystem(new ForcedMusicSystems.PlayerAdded()); ComponentType<EntityStore, AudioComponent> audioComponentType = AudioComponent.getComponentType();
ComponentType<EntityStore, Player> playerComponentType = Player.getComponentType();
ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
entityStoreRegistry.registerSystem(
new AmbientEmitterSystems.EntityAdded(
this.ambientEmitterComponentType, transformComponentType, networkIdComponentType, intangibleComponentType, prefabCopyableComponentType
)
);
entityStoreRegistry.registerSystem(
new AmbientEmitterSystems.EntityRefAdded(
this.ambientEmitterComponentType, transformComponentType, audioComponentType, networkIdComponentType, intangibleComponentType
)
);
entityStoreRegistry.registerSystem(new AmbientEmitterSystems.Ticking(this.ambientEmitterComponentType, transformComponentType));
entityStoreRegistry.registerSystem(
new ForcedMusicSystems.Tick(playerComponentType, playerRefComponentType, this.ambienceTrackerComponentType, this.ambienceResourceType)
);
entityStoreRegistry.registerSystem(new ForcedMusicSystems.PlayerAdded(playerRefComponentType, this.ambienceTrackerComponentType));
this.getCommandRegistry().registerCommand(new AmbienceCommands()); this.getCommandRegistry().registerCommand(new AmbienceCommands());
} }
@@ -87,6 +114,7 @@ public class AmbiencePlugin extends JavaPlugin {
} }
public static class AmbiencePluginConfig { public static class AmbiencePluginConfig {
@Nonnull
public static final BuilderCodec<AmbiencePlugin.AmbiencePluginConfig> CODEC = BuilderCodec.builder( public static final BuilderCodec<AmbiencePlugin.AmbiencePluginConfig> CODEC = BuilderCodec.builder(
AmbiencePlugin.AmbiencePluginConfig.class, AmbiencePlugin.AmbiencePluginConfig::new AmbiencePlugin.AmbiencePluginConfig.class, AmbiencePlugin.AmbiencePluginConfig::new
) )

View File

@@ -10,14 +10,17 @@ import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class AmbienceClearCommand extends AbstractWorldCommand { public class AmbienceClearCommand extends AbstractWorldCommand {
@Nonnull
private static final Message MESSAGE_SERVER_COMMANDS_AMBIENCE_CLEAR_SUCCESS = Message.translation("server.commands.ambience.clear.success");
public AmbienceClearCommand() { public AmbienceClearCommand() {
super("clear", "server.commands.ambience.clear.desc"); super("clear", "server.commands.ambience.clear.desc");
} }
@Override @Override
protected void execute(@Nonnull CommandContext context, @Nonnull World world, @Nonnull Store<EntityStore> store) { protected void execute(@Nonnull CommandContext context, @Nonnull World world, @Nonnull Store<EntityStore> store) {
AmbienceResource resource = store.getResource(AmbienceResource.getResourceType()); AmbienceResource ambienceResource = store.getResource(AmbienceResource.getResourceType());
resource.setForcedMusicAmbience(null); ambienceResource.setForcedMusicAmbience(null);
context.sendMessage(Message.translation("server.commands.ambience.clear.success")); context.sendMessage(MESSAGE_SERVER_COMMANDS_AMBIENCE_CLEAR_SUCCESS);
} }
} }

View File

@@ -32,6 +32,8 @@ public class AmbienceEmitterAddCommand extends AbstractPlayerCommand {
"server.commands.ambience.emitter.add.arg.soundEvent.name", SoundEvent.class, "server.commands.ambience.emitter.add.arg.soundEvent.usage" "server.commands.ambience.emitter.add.arg.soundEvent.name", SoundEvent.class, "server.commands.ambience.emitter.add.arg.soundEvent.usage"
); );
@Nonnull @Nonnull
private static final Message MESSAGE_SERVER_COMMANDS_ERRORS_PLAYER_ONLY = Message.translation("server.commands.errors.playerOnly");
@Nonnull
private final RequiredArg<SoundEvent> soundEventArg = this.withRequiredArg( private final RequiredArg<SoundEvent> soundEventArg = this.withRequiredArg(
"soundEvent", "server.commands.ambience.emitter.add.arg.soundEvent.desc", SOUND_EVENT_ASSET_TYPE "soundEvent", "server.commands.ambience.emitter.add.arg.soundEvent.desc", SOUND_EVENT_ASSET_TYPE
); );
@@ -45,12 +47,10 @@ public class AmbienceEmitterAddCommand extends AbstractPlayerCommand {
@Nonnull CommandContext context, @Nonnull Store<EntityStore> store, @Nonnull Ref<EntityStore> ref, @Nonnull PlayerRef playerRef, @Nonnull World world @Nonnull CommandContext context, @Nonnull Store<EntityStore> store, @Nonnull Ref<EntityStore> ref, @Nonnull PlayerRef playerRef, @Nonnull World world
) { ) {
if (!context.isPlayer()) { if (!context.isPlayer()) {
throw new GeneralCommandException(Message.translation("server.commands.errors.playerOnly")); throw new GeneralCommandException(MESSAGE_SERVER_COMMANDS_ERRORS_PLAYER_ONLY);
} else { } else {
TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType()); TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType());
if (transformComponent != null) {
assert transformComponent != null;
Holder<EntityStore> holder = EntityStore.REGISTRY.newHolder(); Holder<EntityStore> holder = EntityStore.REGISTRY.newHolder();
SoundEvent soundEvent = this.soundEventArg.get(context); SoundEvent soundEvent = this.soundEventArg.get(context);
boolean looping = false; boolean looping = false;
@@ -85,4 +85,5 @@ public class AmbienceEmitterAddCommand extends AbstractPlayerCommand {
} }
} }
} }
}
} }

View File

@@ -13,6 +13,7 @@ import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class AmbienceSetMusicCommand extends AbstractWorldCommand { public class AmbienceSetMusicCommand extends AbstractWorldCommand {
@Nonnull
private final RequiredArg<AmbienceFX> ambienceFxIdArg = this.withRequiredArg( private final RequiredArg<AmbienceFX> ambienceFxIdArg = this.withRequiredArg(
"ambienceFxId", "server.commands.ambience.setmusic.arg.ambiencefxid.desc", ArgTypes.AMBIENCE_FX_ASSET "ambienceFxId", "server.commands.ambience.setmusic.arg.ambiencefxid.desc", ArgTypes.AMBIENCE_FX_ASSET
); );
@@ -24,8 +25,8 @@ public class AmbienceSetMusicCommand extends AbstractWorldCommand {
@Override @Override
protected void execute(@Nonnull CommandContext context, @Nonnull World world, @Nonnull Store<EntityStore> store) { protected void execute(@Nonnull CommandContext context, @Nonnull World world, @Nonnull Store<EntityStore> store) {
AmbienceFX ambienceFX = this.ambienceFxIdArg.get(context); AmbienceFX ambienceFX = this.ambienceFxIdArg.get(context);
AmbienceResource resource = store.getResource(AmbienceResource.getResourceType()); AmbienceResource ambienceResource = store.getResource(AmbienceResource.getResourceType());
resource.setForcedMusicAmbience(ambienceFX.getId()); ambienceResource.setForcedMusicAmbience(ambienceFX.getId());
context.sendMessage(Message.translation("server.commands.ambience.setmusic.success").param("ambience", ambienceFX.getId())); context.sendMessage(Message.translation("server.commands.ambience.setmusic.success").param("ambience", ambienceFX.getId()));
} }
} }

View File

@@ -5,9 +5,11 @@ import com.hypixel.hytale.component.Component;
import com.hypixel.hytale.component.ComponentType; import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.protocol.packets.world.UpdateEnvironmentMusic; import com.hypixel.hytale.protocol.packets.world.UpdateEnvironmentMusic;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class AmbienceTracker implements Component<EntityStore> { public class AmbienceTracker implements Component<EntityStore> {
@Nonnull
private final UpdateEnvironmentMusic musicPacket = new UpdateEnvironmentMusic(0); private final UpdateEnvironmentMusic musicPacket = new UpdateEnvironmentMusic(0);
private int forcedMusicIndex; private int forcedMusicIndex;
@@ -23,6 +25,7 @@ public class AmbienceTracker implements Component<EntityStore> {
return this.forcedMusicIndex; return this.forcedMusicIndex;
} }
@Nonnull
public UpdateEnvironmentMusic getMusicPacket() { public UpdateEnvironmentMusic getMusicPacket() {
return this.musicPacket; return this.musicPacket;
} }

View File

@@ -8,9 +8,11 @@ import com.hypixel.hytale.component.Component;
import com.hypixel.hytale.component.ComponentType; import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class AmbientEmitterComponent implements Component<EntityStore> { public class AmbientEmitterComponent implements Component<EntityStore> {
@Nonnull
public static final BuilderCodec<AmbientEmitterComponent> CODEC = BuilderCodec.builder(AmbientEmitterComponent.class, AmbientEmitterComponent::new) public static final BuilderCodec<AmbientEmitterComponent> CODEC = BuilderCodec.builder(AmbientEmitterComponent.class, AmbientEmitterComponent::new)
.append(new KeyedCodec<>("SoundEventId", Codec.STRING), (emitter, s) -> emitter.soundEventId = s, emitter -> emitter.soundEventId) .append(new KeyedCodec<>("SoundEventId", Codec.STRING), (emitter, s) -> emitter.soundEventId = s, emitter -> emitter.soundEventId)
.add() .add()

View File

@@ -29,18 +29,37 @@ import javax.annotation.Nonnull;
public class AmbientEmitterSystems { public class AmbientEmitterSystems {
public static class EntityAdded extends HolderSystem<EntityStore> { public static class EntityAdded extends HolderSystem<EntityStore> {
@Nonnull @Nonnull
private final Query<EntityStore> query = Query.and(AmbientEmitterComponent.getComponentType(), TransformComponent.getComponentType()); private final ComponentType<EntityStore, NetworkId> networkIdComponentType;
@Nonnull
private final ComponentType<EntityStore, Intangible> intangibleComponentType;
@Nonnull
private final ComponentType<EntityStore, PrefabCopyableComponent> prefabCopyableComponentType;
@Nonnull
private final Query<EntityStore> query;
public EntityAdded(
@Nonnull ComponentType<EntityStore, AmbientEmitterComponent> ambientEmitterComponentType,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType,
@Nonnull ComponentType<EntityStore, NetworkId> networkIdComponentType,
@Nonnull ComponentType<EntityStore, Intangible> intangibleComponentType,
@Nonnull ComponentType<EntityStore, PrefabCopyableComponent> prefabCopyableComponentType
) {
this.networkIdComponentType = networkIdComponentType;
this.intangibleComponentType = intangibleComponentType;
this.prefabCopyableComponentType = prefabCopyableComponentType;
this.query = Query.and(ambientEmitterComponentType, transformComponentType);
}
@Override @Override
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) { public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
Archetype<EntityStore> archetype = holder.getArchetype(); Archetype<EntityStore> archetype = holder.getArchetype();
ComponentType<EntityStore, NetworkId> networkIdComponentType = NetworkId.getComponentType(); if (!archetype.contains(this.networkIdComponentType)) {
if (!archetype.contains(networkIdComponentType)) { int nextNetworkId = store.getExternalData().takeNextNetworkId();
holder.addComponent(networkIdComponentType, new NetworkId(store.getExternalData().takeNextNetworkId())); holder.addComponent(this.networkIdComponentType, new NetworkId(nextNetworkId));
} }
holder.ensureComponent(Intangible.getComponentType()); holder.ensureComponent(this.intangibleComponentType);
holder.ensureComponent(PrefabCopyableComponent.getComponentType()); holder.ensureComponent(this.prefabCopyableComponentType);
} }
@Override @Override
@@ -56,29 +75,56 @@ public class AmbientEmitterSystems {
public static class EntityRefAdded extends RefSystem<EntityStore> { public static class EntityRefAdded extends RefSystem<EntityStore> {
@Nonnull @Nonnull
private final Query<EntityStore> query = Query.and(AmbientEmitterComponent.getComponentType(), TransformComponent.getComponentType()); private final ComponentType<EntityStore, AmbientEmitterComponent> ambientEmitterComponentType;
@Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull
private final ComponentType<EntityStore, AudioComponent> audioComponentType;
@Nonnull
private final ComponentType<EntityStore, NetworkId> networkIdComponentType;
@Nonnull
private final ComponentType<EntityStore, Intangible> intangibleComponentType;
@Nonnull
private final Query<EntityStore> query;
public EntityRefAdded(
@Nonnull ComponentType<EntityStore, AmbientEmitterComponent> ambientEmitterComponentType,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType,
@Nonnull ComponentType<EntityStore, AudioComponent> audioComponentType,
@Nonnull ComponentType<EntityStore, NetworkId> networkIdComponentType,
@Nonnull ComponentType<EntityStore, Intangible> intangibleComponentType
) {
this.ambientEmitterComponentType = ambientEmitterComponentType;
this.transformComponentType = transformComponentType;
this.audioComponentType = audioComponentType;
this.networkIdComponentType = networkIdComponentType;
this.intangibleComponentType = intangibleComponentType;
this.query = Query.and(ambientEmitterComponentType, transformComponentType);
}
@Override @Override
public void onEntityAdded( public void onEntityAdded(
@Nonnull Ref<EntityStore> ref, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull Ref<EntityStore> ref, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
AmbientEmitterComponent emitterComponent = store.getComponent(ref, AmbientEmitterComponent.getComponentType()); AmbientEmitterComponent emitterComponent = store.getComponent(ref, this.ambientEmitterComponentType);
assert emitterComponent != null; assert emitterComponent != null;
TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType()); TransformComponent transformComponent = store.getComponent(ref, this.transformComponentType);
assert transformComponent != null; assert transformComponent != null;
Holder<EntityStore> emitterHolder = EntityStore.REGISTRY.newHolder(); Holder<EntityStore> emitterHolder = EntityStore.REGISTRY.newHolder();
emitterHolder.addComponent(TransformComponent.getComponentType(), transformComponent.clone()); emitterHolder.addComponent(this.transformComponentType, transformComponent.clone());
AudioComponent audioComponent = new AudioComponent(); AudioComponent audioComponent = new AudioComponent();
audioComponent.addSound(SoundEvent.getAssetMap().getIndex(emitterComponent.getSoundEventId())); audioComponent.addSound(SoundEvent.getAssetMap().getIndex(emitterComponent.getSoundEventId()));
emitterHolder.addComponent(AudioComponent.getComponentType(), audioComponent); emitterHolder.addComponent(this.audioComponentType, audioComponent);
emitterHolder.addComponent(NetworkId.getComponentType(), new NetworkId(store.getExternalData().takeNextNetworkId())); int nextNetworkId = store.getExternalData().takeNextNetworkId();
emitterHolder.ensureComponent(Intangible.getComponentType()); emitterHolder.addComponent(this.networkIdComponentType, new NetworkId(nextNetworkId));
emitterHolder.ensureComponent(this.intangibleComponentType);
emitterHolder.addComponent(EntityStore.REGISTRY.getNonSerializedComponentType(), NonSerialized.get()); emitterHolder.addComponent(EntityStore.REGISTRY.getNonSerializedComponentType(), NonSerialized.get());
emitterComponent.setSpawnedEmitter(commandBuffer.addEntity(emitterHolder, AddReason.SPAWN)); Ref<EntityStore> emitterRef = commandBuffer.addEntity(emitterHolder, AddReason.SPAWN);
emitterComponent.setSpawnedEmitter(emitterRef);
} }
@Override @Override
@@ -86,7 +132,7 @@ public class AmbientEmitterSystems {
@Nonnull Ref<EntityStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull Ref<EntityStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
if (reason == RemoveReason.REMOVE) { if (reason == RemoveReason.REMOVE) {
AmbientEmitterComponent emitterComponent = store.getComponent(ref, AmbientEmitterComponent.getComponentType()); AmbientEmitterComponent emitterComponent = store.getComponent(ref, this.ambientEmitterComponentType);
assert emitterComponent != null; assert emitterComponent != null;
@@ -106,7 +152,20 @@ public class AmbientEmitterSystems {
public static class Ticking extends EntityTickingSystem<EntityStore> { public static class Ticking extends EntityTickingSystem<EntityStore> {
@Nonnull @Nonnull
private final Query<EntityStore> query = Query.and(AmbientEmitterComponent.getComponentType(), TransformComponent.getComponentType()); private final ComponentType<EntityStore, AmbientEmitterComponent> ambientEmitterComponentType;
@Nonnull
private final ComponentType<EntityStore, TransformComponent> transformComponentType;
@Nonnull
private final Query<EntityStore> query;
public Ticking(
@Nonnull ComponentType<EntityStore, AmbientEmitterComponent> ambientEmitterComponentType,
@Nonnull ComponentType<EntityStore, TransformComponent> transformComponentType
) {
this.ambientEmitterComponentType = ambientEmitterComponentType;
this.transformComponentType = transformComponentType;
this.query = Query.and(ambientEmitterComponentType, transformComponentType);
}
@Override @Override
public void tick( public void tick(
@@ -116,17 +175,17 @@ public class AmbientEmitterSystems {
@Nonnull Store<EntityStore> store, @Nonnull Store<EntityStore> store,
@Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
AmbientEmitterComponent emitterComponent = archetypeChunk.getComponent(index, AmbientEmitterComponent.getComponentType()); AmbientEmitterComponent emitterComponent = archetypeChunk.getComponent(index, this.ambientEmitterComponentType);
assert emitterComponent != null; assert emitterComponent != null;
TransformComponent transformComponent = archetypeChunk.getComponent(index, TransformComponent.getComponentType()); TransformComponent transformComponent = archetypeChunk.getComponent(index, this.transformComponentType);
assert transformComponent != null; assert transformComponent != null;
Ref<EntityStore> spawnedEmitterRef = emitterComponent.getSpawnedEmitter(); Ref<EntityStore> spawnedEmitterRef = emitterComponent.getSpawnedEmitter();
if (spawnedEmitterRef != null && spawnedEmitterRef.isValid()) { if (spawnedEmitterRef != null && spawnedEmitterRef.isValid()) {
TransformComponent ownedEmitterTransform = commandBuffer.getComponent(spawnedEmitterRef, TransformComponent.getComponentType()); TransformComponent ownedEmitterTransform = commandBuffer.getComponent(spawnedEmitterRef, this.transformComponentType);
if (ownedEmitterTransform != null) { if (ownedEmitterTransform != null) {
if (transformComponent.getPosition().distanceSquaredTo(ownedEmitterTransform.getPosition()) > 1.0) { if (transformComponent.getPosition().distanceSquaredTo(ownedEmitterTransform.getPosition()) > 1.0) {
ownedEmitterTransform.setPosition(transformComponent.getPosition()); ownedEmitterTransform.setPosition(transformComponent.getPosition());

View File

@@ -6,8 +6,10 @@ import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.Archetype; import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.ArchetypeChunk; import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Holder; import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.RemoveReason; import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.HolderSystem; import com.hypixel.hytale.component.system.HolderSystem;
@@ -17,26 +19,37 @@ import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ForcedMusicSystems { public class ForcedMusicSystems {
private static final Query<EntityStore> TICK_QUERY = Archetype.of(
Player.getComponentType(), PlayerRef.getComponentType(), AmbienceTracker.getComponentType()
);
public static class PlayerAdded extends HolderSystem<EntityStore> { public static class PlayerAdded extends HolderSystem<EntityStore> {
@Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final ComponentType<EntityStore, AmbienceTracker> ambienceTrackerComponentType;
@Nonnull
private final Query<EntityStore> query;
public PlayerAdded(
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType,
@Nonnull ComponentType<EntityStore, AmbienceTracker> ambienceTrackerComponentType
) {
this.playerRefComponentType = playerRefComponentType;
this.ambienceTrackerComponentType = ambienceTrackerComponentType;
this.query = Query.and(playerRefComponentType, ambienceTrackerComponentType);
}
@Override @Override
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) { public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
holder.ensureComponent(AmbienceTracker.getComponentType()); holder.ensureComponent(this.ambienceTrackerComponentType);
} }
@Override @Override
public void onEntityRemoved(@Nonnull Holder<EntityStore> holder, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store) { public void onEntityRemoved(@Nonnull Holder<EntityStore> holder, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store) {
AmbienceTracker ambienceTrackerComponent = holder.getComponent(AmbienceTracker.getComponentType()); AmbienceTracker ambienceTrackerComponent = holder.getComponent(this.ambienceTrackerComponentType);
assert ambienceTrackerComponent != null; assert ambienceTrackerComponent != null;
PlayerRef playerRefComponent = holder.getComponent(PlayerRef.getComponentType()); PlayerRef playerRefComponent = holder.getComponent(this.playerRefComponentType);
assert playerRefComponent != null; assert playerRefComponent != null;
@@ -45,14 +58,35 @@ public class ForcedMusicSystems {
playerRefComponent.getPacketHandler().write(pooledPacket); playerRefComponent.getPacketHandler().write(pooledPacket);
} }
@Nullable @Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return Query.and(PlayerRef.getComponentType(), AmbienceTracker.getComponentType()); return this.query;
} }
} }
public static class Tick extends EntityTickingSystem<EntityStore> { public static class Tick extends EntityTickingSystem<EntityStore> {
@Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final ComponentType<EntityStore, AmbienceTracker> ambienceTrackerComponentType;
@Nonnull
private final ResourceType<EntityStore, AmbienceResource> ambienceResourceType;
@Nonnull
private final Query<EntityStore> query;
public Tick(
@Nonnull ComponentType<EntityStore, Player> playerComponentType,
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType,
@Nonnull ComponentType<EntityStore, AmbienceTracker> ambienceTrackerComponentType,
@Nonnull ResourceType<EntityStore, AmbienceResource> ambienceResourceType
) {
this.playerRefComponentType = playerRefComponentType;
this.ambienceTrackerComponentType = ambienceTrackerComponentType;
this.ambienceResourceType = ambienceResourceType;
this.query = Archetype.of(playerComponentType, playerRefComponentType, ambienceTrackerComponentType);
}
@Override @Override
public void tick( public void tick(
float dt, float dt,
@@ -61,23 +95,29 @@ public class ForcedMusicSystems {
@Nonnull Store<EntityStore> store, @Nonnull Store<EntityStore> store,
@Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
AmbienceResource ambienceResource = store.getResource(AmbienceResource.getResourceType()); AmbienceResource ambienceResource = store.getResource(this.ambienceResourceType);
AmbienceTracker tracker = archetypeChunk.getComponent(index, AmbienceTracker.getComponentType()); AmbienceTracker ambienceTrackerComponent = archetypeChunk.getComponent(index, this.ambienceTrackerComponentType);
PlayerRef playerRef = archetypeChunk.getComponent(index, PlayerRef.getComponentType());
int have = tracker.getForcedMusicIndex(); assert ambienceTrackerComponent != null;
PlayerRef playerRefComponent = archetypeChunk.getComponent(index, this.playerRefComponentType);
assert playerRefComponent != null;
int have = ambienceTrackerComponent.getForcedMusicIndex();
int desired = ambienceResource.getForcedMusicIndex(); int desired = ambienceResource.getForcedMusicIndex();
if (have != desired) { if (have != desired) {
tracker.setForcedMusicIndex(desired); ambienceTrackerComponent.setForcedMusicIndex(desired);
UpdateEnvironmentMusic pooledPacket = tracker.getMusicPacket(); UpdateEnvironmentMusic pooledPacket = ambienceTrackerComponent.getMusicPacket();
pooledPacket.environmentIndex = desired; pooledPacket.environmentIndex = desired;
playerRef.getPacketHandler().write(pooledPacket); playerRefComponent.getPacketHandler().write(pooledPacket);
} }
} }
@Nullable @Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return ForcedMusicSystems.TICK_QUERY; return this.query;
} }
} }
} }

View File

@@ -65,22 +65,28 @@ public class AssetEditorGamePacketHandler implements SubPacketHandler {
if (ref != null && ref.isValid()) { if (ref != null && ref.isValid()) {
Store<EntityStore> store = ref.getStore(); Store<EntityStore> store = ref.getStore();
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
CompletableFuture.runAsync(() -> { world.execute(
() -> {
Player playerComponent = store.getComponent(ref, Player.getComponentType()); Player playerComponent = store.getComponent(ref, Player.getComponentType());
if (!this.lacksPermission(playerComponent, true)) { if (!this.lacksPermission(playerComponent, true)) {
; CompletableFuture.runAsync(
}
}, world)
.thenRunAsync(
() -> { () -> {
LOGGER.at(Level.INFO).log("%s updating json asset at %s", this.packetHandler.getPlayerRef().getUsername(), packet.path); LOGGER.at(Level.INFO).log("%s updating json asset at %s", this.packetHandler.getPlayerRef().getUsername(), packet.path);
EditorClient mockClient = new EditorClient(playerRef); EditorClient mockClient = new EditorClient(playerRef);
AssetEditorPlugin.get() AssetEditorPlugin.get()
.handleJsonAssetUpdate( .handleJsonAssetUpdate(
mockClient, packet.path != null ? new AssetPath(packet.path) : null, packet.assetType, packet.assetIndex, packet.commands, packet.token mockClient,
packet.path != null ? new AssetPath(packet.path) : null,
packet.assetType,
packet.assetIndex,
packet.commands,
packet.token
); );
} }
); );
}
}
);
} else { } else {
throw new RuntimeException("Unable to process AssetEditorUpdateJsonAsset packet. Player ref is invalid!"); throw new RuntimeException("Unable to process AssetEditorUpdateJsonAsset packet. Player ref is invalid!");
} }
@@ -89,7 +95,7 @@ public class AssetEditorGamePacketHandler implements SubPacketHandler {
private boolean lacksPermission(@Nonnull Player player, boolean shouldShowDenialMessage) { private boolean lacksPermission(@Nonnull Player player, boolean shouldShowDenialMessage) {
if (!player.hasPermission("hytale.editor.asset")) { if (!player.hasPermission("hytale.editor.asset")) {
if (shouldShowDenialMessage) { if (shouldShowDenialMessage) {
player.sendMessage(Messages.USAGE_DENIED_MESSAGE); player.sendMessage(Messages.USAGE_DENIED);
} }
return true; return true;

View File

@@ -409,7 +409,7 @@ public class AssetEditorPacketHandler extends GenericPacketHandler {
private boolean lacksPermission(int token) { private boolean lacksPermission(int token) {
if (!this.editorClient.hasPermission("hytale.editor.asset")) { if (!this.editorClient.hasPermission("hytale.editor.asset")) {
this.editorClient.sendFailureReply(token, Messages.USAGE_DENIED_MESSAGE); this.editorClient.sendFailureReply(token, Messages.USAGE_DENIED);
return true; return true;
} else { } else {
return false; return false;
@@ -422,7 +422,7 @@ public class AssetEditorPacketHandler extends GenericPacketHandler {
private boolean lacksPermission(String permissionId) { private boolean lacksPermission(String permissionId) {
if (!this.editorClient.hasPermission(permissionId)) { if (!this.editorClient.hasPermission(permissionId)) {
this.editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.USAGE_DENIED_MESSAGE); this.editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.USAGE_DENIED);
return true; return true;
} else { } else {
return false; return false;
@@ -431,7 +431,7 @@ public class AssetEditorPacketHandler extends GenericPacketHandler {
private boolean lacksPermission(int token, String permissionId) { private boolean lacksPermission(int token, String permissionId) {
if (!this.editorClient.hasPermission(permissionId)) { if (!this.editorClient.hasPermission(permissionId)) {
this.editorClient.sendFailureReply(token, Messages.USAGE_DENIED_MESSAGE); this.editorClient.sendFailureReply(token, Messages.USAGE_DENIED);
return true; return true;
} else { } else {
return false; return false;

View File

@@ -36,6 +36,7 @@ import com.hypixel.hytale.common.util.FormatUtil;
import com.hypixel.hytale.common.util.PathUtil; import com.hypixel.hytale.common.util.PathUtil;
import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.event.EventRegistry;
import com.hypixel.hytale.event.IEventDispatcher; import com.hypixel.hytale.event.IEventDispatcher;
import com.hypixel.hytale.protocol.Packet; import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.protocol.packets.asseteditor.AssetEditorAsset; import com.hypixel.hytale.protocol.packets.asseteditor.AssetEditorAsset;
@@ -69,6 +70,7 @@ import com.hypixel.hytale.protocol.packets.asseteditor.SchemaFile;
import com.hypixel.hytale.protocol.packets.asseteditor.TimestampedAssetReference; import com.hypixel.hytale.protocol.packets.asseteditor.TimestampedAssetReference;
import com.hypixel.hytale.protocol.packets.assets.UpdateTranslations; import com.hypixel.hytale.protocol.packets.assets.UpdateTranslations;
import com.hypixel.hytale.server.core.HytaleServer; import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.HytaleServerConfig;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.Options; import com.hypixel.hytale.server.core.Options;
import com.hypixel.hytale.server.core.asset.AssetModule; import com.hypixel.hytale.server.core.asset.AssetModule;
@@ -96,7 +98,6 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@@ -118,22 +119,32 @@ import org.bson.BsonValue;
public class AssetEditorPlugin extends JavaPlugin { public class AssetEditorPlugin extends JavaPlugin {
private static AssetEditorPlugin instance; private static AssetEditorPlugin instance;
@Nonnull
private final StampedLock globalEditLock = new StampedLock(); private final StampedLock globalEditLock = new StampedLock();
@Nonnull
private final Map<UUID, Set<EditorClient>> uuidToEditorClients = new ConcurrentHashMap<>(); private final Map<UUID, Set<EditorClient>> uuidToEditorClients = new ConcurrentHashMap<>();
@Nonnull
private final Map<EditorClient, AssetPath> clientOpenAssetPathMapping = new ConcurrentHashMap<>(); private final Map<EditorClient, AssetPath> clientOpenAssetPathMapping = new ConcurrentHashMap<>();
@Nonnull
private final Set<EditorClient> clientsSubscribedToModifiedAssetsChanges = ConcurrentHashMap.newKeySet(); private final Set<EditorClient> clientsSubscribedToModifiedAssetsChanges = ConcurrentHashMap.newKeySet();
@Nonnull @Nonnull
private Map<String, Schema> schemas = new Object2ObjectOpenHashMap<>(); private Map<String, Schema> schemas = new Object2ObjectOpenHashMap<>();
private AssetEditorSetupSchemas setupSchemasPacket; private AssetEditorSetupSchemas setupSchemasPacket;
@Nonnull
private final StampedLock initLock = new StampedLock(); private final StampedLock initLock = new StampedLock();
@Nonnull
private final Set<EditorClient> initQueue = new HashSet<>(); private final Set<EditorClient> initQueue = new HashSet<>();
@Nonnull @Nonnull
private AssetEditorPlugin.InitState initState = AssetEditorPlugin.InitState.NOT_INITIALIZED; private AssetEditorPlugin.InitState initState = AssetEditorPlugin.InitState.NOT_INITIALIZED;
@Nullable @Nullable
private ScheduledFuture<?> scheduledReinitFuture; private ScheduledFuture<?> scheduledReinitFuture;
@Nonnull
private final Map<String, DataSource> assetPackDataSources = new ConcurrentHashMap<>(); private final Map<String, DataSource> assetPackDataSources = new ConcurrentHashMap<>();
@Nonnull
private final AssetTypeRegistry assetTypeRegistry = new AssetTypeRegistry(); private final AssetTypeRegistry assetTypeRegistry = new AssetTypeRegistry();
@Nonnull
private final UndoRedoManager undoRedoManager = new UndoRedoManager(); private final UndoRedoManager undoRedoManager = new UndoRedoManager();
@Nullable
private ScheduledFuture<?> pingClientsTask; private ScheduledFuture<?> pingClientsTask;
public static AssetEditorPlugin get() { public static AssetEditorPlugin get() {
@@ -145,7 +156,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
@Nullable @Nullable
DataSource registerDataSourceForPack(AssetPack assetPack) { DataSource registerDataSourceForPack(@Nonnull AssetPack assetPack) {
PluginManifest manifest = assetPack.getManifest(); PluginManifest manifest = assetPack.getManifest();
if (manifest == null) { if (manifest == null) {
this.getLogger().at(Level.SEVERE).log("Could not load asset pack manifest for " + assetPack.getName()); this.getLogger().at(Level.SEVERE).log("Could not load asset pack manifest for " + assetPack.getName());
@@ -160,6 +171,7 @@ public class AssetEditorPlugin extends JavaPlugin {
@Override @Override
protected void setup() { protected void setup() {
instance = this; instance = this;
EventRegistry eventRegistry = this.getEventRegistry();
for (AssetPack assetPack : AssetModule.get().getAssetPacks()) { for (AssetPack assetPack : AssetModule.get().getAssetPacks()) {
this.registerDataSourceForPack(assetPack); this.registerDataSourceForPack(assetPack);
@@ -180,13 +192,13 @@ public class AssetEditorPlugin extends JavaPlugin {
this.assetTypeRegistry.registerAssetType(new CommonAssetTypeHandler("Sound", null, ".ogg", AssetEditorEditorType.None)); this.assetTypeRegistry.registerAssetType(new CommonAssetTypeHandler("Sound", null, ".ogg", AssetEditorEditorType.None));
this.assetTypeRegistry.registerAssetType(new CommonAssetTypeHandler("UI", null, ".ui", AssetEditorEditorType.Text)); this.assetTypeRegistry.registerAssetType(new CommonAssetTypeHandler("UI", null, ".ui", AssetEditorEditorType.Text));
this.assetTypeRegistry.registerAssetType(new CommonAssetTypeHandler("Language", null, ".lang", AssetEditorEditorType.Text)); this.assetTypeRegistry.registerAssetType(new CommonAssetTypeHandler("Language", null, ".lang", AssetEditorEditorType.Text));
this.getEventRegistry().register(RegisterAssetStoreEvent.class, this::onRegisterAssetStore); eventRegistry.register(RegisterAssetStoreEvent.class, this::onRegisterAssetStore);
this.getEventRegistry().register(RemoveAssetStoreEvent.class, this::onUnregisterAssetStore); eventRegistry.register(RemoveAssetStoreEvent.class, this::onUnregisterAssetStore);
this.getEventRegistry().register(AssetPackRegisterEvent.class, this::onRegisterAssetPack); eventRegistry.register(AssetPackRegisterEvent.class, this::onRegisterAssetPack);
this.getEventRegistry().register(AssetPackUnregisterEvent.class, this::onUnregisterAssetPack); eventRegistry.register(AssetPackUnregisterEvent.class, this::onUnregisterAssetPack);
this.getEventRegistry().register(AssetStoreMonitorEvent.class, this::onAssetMonitor); eventRegistry.register(AssetStoreMonitorEvent.class, this::onAssetMonitor);
this.getEventRegistry().register(CommonAssetMonitorEvent.class, this::onAssetMonitor); eventRegistry.register(CommonAssetMonitorEvent.class, this::onAssetMonitor);
this.getEventRegistry().register(MessagesUpdated.class, this::onI18nMessagesUpdated); eventRegistry.register(MessagesUpdated.class, this::onI18nMessagesUpdated);
AssetSpecificFunctionality.setup(); AssetSpecificFunctionality.setup();
} }
@@ -210,38 +222,49 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
} }
if (this.pingClientsTask != null) {
this.pingClientsTask.cancel(false); this.pingClientsTask.cancel(false);
} else {
this.getLogger().at(Level.WARNING).log("Failed to cancel ping clients task as it was null");
}
for (DataSource dataSource : this.assetPackDataSources.values()) { for (DataSource dataSource : this.assetPackDataSources.values()) {
dataSource.shutdown(); dataSource.shutdown();
} }
} }
public DataSource getDataSourceForPath(AssetPath path) { @Nullable
public DataSource getDataSourceForPath(@Nonnull AssetPath path) {
return this.getDataSourceForPack(path.packId()); return this.getDataSourceForPack(path.packId());
} }
public DataSource getDataSourceForPack(String assetPack) { @Nullable
public DataSource getDataSourceForPack(@Nonnull String assetPack) {
return this.assetPackDataSources.get(assetPack); return this.assetPackDataSources.get(assetPack);
} }
@Nonnull
public Collection<DataSource> getDataSources() { public Collection<DataSource> getDataSources() {
return this.assetPackDataSources.values(); return this.assetPackDataSources.values();
} }
@Nonnull
public AssetTypeRegistry getAssetTypeRegistry() { public AssetTypeRegistry getAssetTypeRegistry() {
return this.assetTypeRegistry; return this.assetTypeRegistry;
} }
public Schema getSchema(String id) { @Nullable
public Schema getSchema(@Nonnull String id) {
return this.schemas.get(id); return this.schemas.get(id);
} }
@Nonnull
public Map<EditorClient, AssetPath> getClientOpenAssetPathMapping() { public Map<EditorClient, AssetPath> getClientOpenAssetPathMapping() {
return this.clientOpenAssetPathMapping; return this.clientOpenAssetPathMapping;
} }
public Set<EditorClient> getEditorClients(UUID uuid) { @Nullable
public Set<EditorClient> getEditorClients(@Nonnull UUID uuid) {
return this.uuidToEditorClients.get(uuid); return this.uuidToEditorClients.get(uuid);
} }
@@ -259,7 +282,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
@Nonnull @Nonnull
private List<EditorClient> getClientsWithOpenAssetPath(AssetPath path) { private List<EditorClient> getClientsWithOpenAssetPath(@Nonnull AssetPath path) {
if (this.clientOpenAssetPathMapping.isEmpty()) { if (this.clientOpenAssetPathMapping.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} else { } else {
@@ -275,11 +298,12 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
} }
public AssetPath getOpenAssetPath(EditorClient editorClient) { @Nullable
public AssetPath getOpenAssetPath(@Nonnull EditorClient editorClient) {
return this.clientOpenAssetPathMapping.get(editorClient); return this.clientOpenAssetPathMapping.get(editorClient);
} }
private void onRegisterAssetPack(AssetPackRegisterEvent event) { private void onRegisterAssetPack(@Nonnull AssetPackRegisterEvent event) {
if (!this.assetPackDataSources.containsKey(event.getAssetPack().getName())) { if (!this.assetPackDataSources.containsKey(event.getAssetPack().getName())) {
DataSource dataSource = this.registerDataSourceForPack(event.getAssetPack()); DataSource dataSource = this.registerDataSourceForPack(event.getAssetPack());
if (dataSource != null) { if (dataSource != null) {
@@ -307,7 +331,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
} }
private void onUnregisterAssetPack(AssetPackUnregisterEvent event) { private void onUnregisterAssetPack(@Nonnull AssetPackUnregisterEvent event) {
if (this.assetPackDataSources.containsKey(event.getAssetPack().getName())) { if (this.assetPackDataSources.containsKey(event.getAssetPack().getName())) {
DataSource dataSource = this.assetPackDataSources.remove(event.getAssetPack().getName()); DataSource dataSource = this.assetPackDataSources.remove(event.getAssetPack().getName());
dataSource.shutdown(); dataSource.shutdown();
@@ -633,7 +657,7 @@ public class AssetEditorPlugin extends JavaPlugin {
this.getLogger().at(Level.INFO).log("Done Initializing %s", editorClient.getUsername()); this.getLogger().at(Level.INFO).log("Done Initializing %s", editorClient.getUsername());
} }
public void handleEditorClientDisconnected(@Nonnull EditorClient editorClient, PacketHandler.DisconnectReason disconnectReason) { public void handleEditorClientDisconnected(@Nonnull EditorClient editorClient, @Nonnull PacketHandler.DisconnectReason disconnectReason) {
IEventDispatcher<AssetEditorClientDisconnectEvent, AssetEditorClientDisconnectEvent> dispatch = HytaleServer.get() IEventDispatcher<AssetEditorClientDisconnectEvent, AssetEditorClientDisconnectEvent> dispatch = HytaleServer.get()
.getEventBus() .getEventBus()
.dispatchFor(AssetEditorClientDisconnectEvent.class); .dispatchFor(AssetEditorClientDisconnectEvent.class);
@@ -655,11 +679,11 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleDeleteAssetPack(@Nonnull EditorClient editorClient, @Nonnull String packId) { public void handleDeleteAssetPack(@Nonnull EditorClient editorClient, @Nonnull String packId) {
if (packId.equalsIgnoreCase("Hytale:Hytale")) { if (packId.equalsIgnoreCase("Hytale:Hytale")) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSET_PACK);
} else { } else {
DataSource dataSource = this.getDataSourceForPack(packId); DataSource dataSource = this.getDataSourceForPack(packId);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSET_PACK);
} else { } else {
AssetModule.get().unregisterPack(packId); AssetModule.get().unregisterPack(packId);
@@ -692,9 +716,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
if (!isInModsDirectory) { if (!isInModsDirectory) {
editorClient.sendPopupNotification( editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.PACK_OUTSIDE_DIRECTORY);
AssetEditorPopupNotificationType.Error, Message.translation("server.assetEditor.messages.packOutsideDirectory")
);
} else { } else {
try { try {
FileUtil.deleteDirectory(targetPath); FileUtil.deleteDirectory(targetPath);
@@ -708,17 +730,17 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleUpdateAssetPack(@Nonnull EditorClient editorClient, @Nonnull String packId, @Nonnull AssetPackManifest packetManifest) { public void handleUpdateAssetPack(@Nonnull EditorClient editorClient, @Nonnull String packId, @Nonnull AssetPackManifest packetManifest) {
if (packId.equals("Hytale:Hytale")) { if (packId.equals("Hytale:Hytale")) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSET_PACK);
} else { } else {
DataSource dataSource = this.getDataSourceForPack(packId); DataSource dataSource = this.getDataSourceForPack(packId);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSET_PACK);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.ASSETS_READ_ONLY);
} else { } else {
PluginManifest manifest = dataSource.getManifest(); PluginManifest manifest = dataSource.getManifest();
if (manifest == null) { if (manifest == null) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Message.translation("server.assetEditor.messages.manifestNotFound")); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.MANIFEST_NOT_FOUND);
} else { } else {
boolean didIdentifierChange = false; boolean didIdentifierChange = false;
if (packetManifest.name != null && !packetManifest.name.isEmpty() && !manifest.getName().equals(packetManifest.name)) { if (packetManifest.name != null && !packetManifest.name.isEmpty() && !manifest.getName().equals(packetManifest.name)) {
@@ -742,11 +764,9 @@ public class AssetEditorPlugin extends JavaPlugin {
if (packetManifest.version != null && !packetManifest.version.isEmpty()) { if (packetManifest.version != null && !packetManifest.version.isEmpty()) {
try { try {
manifest.setVersion(Semver.fromString(packetManifest.version)); manifest.setVersion(Semver.fromString(packetManifest.version));
} catch (IllegalArgumentException var14) { } catch (IllegalArgumentException var15) {
this.getLogger().at(Level.WARNING).withCause(var14).log("Invalid version format: %s", packetManifest.version); this.getLogger().at(Level.WARNING).withCause(var15).log("Invalid version format: %s", packetManifest.version);
editorClient.sendPopupNotification( editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.INVALID_VERSION_FORMAT);
AssetEditorPopupNotificationType.Error, Message.translation("server.assetEditor.messages.invalidVersionFormat")
);
return; return;
} }
} }
@@ -765,23 +785,35 @@ public class AssetEditorPlugin extends JavaPlugin {
manifest.setAuthors(authors); manifest.setAuthors(authors);
} }
if (packetManifest.serverVersion != null) {
manifest.setServerVersion(packetManifest.serverVersion);
}
Path manifestPath = dataSource.getRootPath().resolve("manifest.json"); Path manifestPath = dataSource.getRootPath().resolve("manifest.json");
try { try {
BsonUtil.writeSync(manifestPath, PluginManifest.CODEC, manifest, this.getLogger()); BsonUtil.writeSync(manifestPath, PluginManifest.CODEC, manifest, this.getLogger());
this.getLogger().at(Level.INFO).log("Saved manifest for pack %s", packId); this.getLogger().at(Level.INFO).log("Saved manifest for pack %s", packId);
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Success, Message.translation("server.assetEditor.messages.manifestSaved")); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Success, Messages.MANIFEST_SAVED);
} catch (IOException var13) { } catch (IOException var14) {
this.getLogger().at(Level.SEVERE).withCause(var13).log("Failed to save manifest for pack %s", packId); this.getLogger().at(Level.SEVERE).withCause(var14).log("Failed to save manifest for pack %s", packId);
editorClient.sendPopupNotification( editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.MANIFEST_SAVE_FAILED);
AssetEditorPopupNotificationType.Error, Message.translation("server.assetEditor.messages.manifestSaveFailed")
);
} }
this.broadcastPackAddedOrUpdated(packId, manifest); this.broadcastPackAddedOrUpdated(packId, manifest);
if (didIdentifierChange) { if (didIdentifierChange) {
String newPackId = new PluginIdentifier(manifest).toString(); PluginIdentifier newPackIdentifier = new PluginIdentifier(manifest);
String newPackId = newPackIdentifier.toString();
Path packPath = dataSource.getRootPath(); Path packPath = dataSource.getRootPath();
HytaleServerConfig serverConfig = HytaleServer.get().getConfig();
HytaleServerConfig.ModConfig.setBoot(serverConfig, newPackIdentifier, true);
Map<PluginIdentifier, HytaleServerConfig.ModConfig> modConfig = serverConfig.getModConfig();
modConfig.remove(PluginIdentifier.fromString(packId));
serverConfig.markChanged();
if (serverConfig.consumeHasChanged()) {
HytaleServerConfig.save(serverConfig).join();
}
AssetModule assetModule = AssetModule.get(); AssetModule assetModule = AssetModule.get();
assetModule.unregisterPack(packId); assetModule.unregisterPack(packId);
assetModule.registerPack(newPackId, packPath, manifest); assetModule.registerPack(newPackId, packPath, manifest);
@@ -793,7 +825,7 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleCreateAssetPack(@Nonnull EditorClient editorClient, @Nonnull AssetPackManifest packetManifest, int requestToken) { public void handleCreateAssetPack(@Nonnull EditorClient editorClient, @Nonnull AssetPackManifest packetManifest, int requestToken) {
if (packetManifest.name == null || packetManifest.name.isEmpty()) { if (packetManifest.name == null || packetManifest.name.isEmpty()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.packNameRequired")); editorClient.sendFailureReply(requestToken, Messages.PACK_NAME_REQUIRED);
} else if (packetManifest.group != null && !packetManifest.group.isEmpty()) { } else if (packetManifest.group != null && !packetManifest.group.isEmpty()) {
PluginManifest manifest = new PluginManifest(); PluginManifest manifest = new PluginManifest();
manifest.setName(packetManifest.name); manifest.setName(packetManifest.name);
@@ -809,9 +841,9 @@ public class AssetEditorPlugin extends JavaPlugin {
if (packetManifest.version != null && !packetManifest.version.isEmpty()) { if (packetManifest.version != null && !packetManifest.version.isEmpty()) {
try { try {
manifest.setVersion(Semver.fromString(packetManifest.version)); manifest.setVersion(Semver.fromString(packetManifest.version));
} catch (IllegalArgumentException var12) { } catch (IllegalArgumentException var13) {
this.getLogger().at(Level.WARNING).withCause(var12).log("Invalid version format: %s", packetManifest.version); this.getLogger().at(Level.WARNING).withCause(var13).log("Invalid version format: %s", packetManifest.version);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.invalidVersionFormat")); editorClient.sendFailureReply(requestToken, Messages.INVALID_VERSION_FORMAT);
return; return;
} }
} }
@@ -830,9 +862,10 @@ public class AssetEditorPlugin extends JavaPlugin {
manifest.setAuthors(authors); manifest.setAuthors(authors);
} }
manifest.setServerVersion(packetManifest.serverVersion);
String packId = new PluginIdentifier(manifest).toString(); String packId = new PluginIdentifier(manifest).toString();
if (this.assetPackDataSources.containsKey(packId)) { if (this.assetPackDataSources.containsKey(packId)) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.packAlreadyExists")); editorClient.sendFailureReply(requestToken, Messages.PACK_ALREADY_EXISTS);
} else { } else {
Path modsPath = PluginManager.MODS_PATH; Path modsPath = PluginManager.MODS_PATH;
String dirName = AssetPathUtil.removeInvalidFileNameChars( String dirName = AssetPathUtil.removeInvalidFileNameChars(
@@ -840,33 +873,41 @@ public class AssetEditorPlugin extends JavaPlugin {
); );
Path normalized = Path.of(dirName).normalize(); Path normalized = Path.of(dirName).normalize();
if (AssetPathUtil.isInvalidFileName(normalized)) { if (AssetPathUtil.isInvalidFileName(normalized)) {
editorClient.sendFailureReply(requestToken, Messages.INVALID_FILENAME_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.INVALID_FILE_NAME);
} else { } else {
Path packPath = modsPath.resolve(normalized).normalize(); Path packPath = modsPath.resolve(normalized).normalize();
if (!packPath.startsWith(modsPath)) { if (!packPath.startsWith(modsPath)) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.packOutsideDirectory")); editorClient.sendFailureReply(requestToken, Messages.PACK_OUTSIDE_DIRECTORY);
} else if (Files.exists(packPath)) { } else if (Files.exists(packPath)) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.packAlreadyExistsAtPath")); editorClient.sendFailureReply(requestToken, Messages.PACK_ALREADY_EXISTS_AT_PATH);
} else { } else {
try { try {
Files.createDirectories(packPath); Files.createDirectories(packPath);
Path manifestPath = packPath.resolve("manifest.json"); Path manifestPath = packPath.resolve("manifest.json");
BsonUtil.writeSync(manifestPath, PluginManifest.CODEC, manifest, this.getLogger()); BsonUtil.writeSync(manifestPath, PluginManifest.CODEC, manifest, this.getLogger());
HytaleServerConfig serverConfig = HytaleServer.get().getConfig();
HytaleServerConfig.ModConfig.setBoot(serverConfig, new PluginIdentifier(manifest), true);
serverConfig.markChanged();
if (serverConfig.consumeHasChanged()) {
HytaleServerConfig.save(serverConfig).join();
}
AssetModule.get().registerPack(packId, packPath, manifest); AssetModule.get().registerPack(packId, packPath, manifest);
editorClient.sendSuccessReply(requestToken, Message.translation("server.assetEditor.messages.packCreated")); editorClient.sendSuccessReply(requestToken, Messages.PACK_CREATED);
this.getLogger().at(Level.INFO).log("Created new pack: %s at %s", packId, packPath); this.getLogger().at(Level.INFO).log("Created new pack: %s at %s", packId, packPath);
} catch (IOException var11) { } catch (IOException var12) {
this.getLogger().at(Level.SEVERE).withCause(var11).log("Failed to create pack %s", packId); this.getLogger().at(Level.SEVERE).withCause(var12).log("Failed to create pack %s", packId);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.packCreationFailed")); editorClient.sendFailureReply(requestToken, Messages.PACK_CREATION_FAILED);
} }
} }
} }
} }
} else { } else {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.packGroupRequired")); editorClient.sendFailureReply(requestToken, Messages.PACK_GROUP_REQUIRED);
} }
} }
@Nonnull
private static AssetPackManifest toManifestPacket(@Nonnull PluginManifest manifest) { private static AssetPackManifest toManifestPacket(@Nonnull PluginManifest manifest) {
AssetPackManifest packet = new AssetPackManifest(); AssetPackManifest packet = new AssetPackManifest();
packet.name = manifest.getName(); packet.name = manifest.getName();
@@ -874,6 +915,7 @@ public class AssetEditorPlugin extends JavaPlugin {
packet.group = manifest.getGroup(); packet.group = manifest.getGroup();
packet.version = manifest.getVersion() != null ? manifest.getVersion().toString() : ""; packet.version = manifest.getVersion() != null ? manifest.getVersion().toString() : "";
packet.website = manifest.getWebsite() != null ? manifest.getWebsite() : ""; packet.website = manifest.getWebsite() != null ? manifest.getWebsite() : "";
packet.serverVersion = manifest.getServerVersion() != null ? manifest.getServerVersion() : "";
List<com.hypixel.hytale.protocol.packets.asseteditor.AuthorInfo> authors = new ObjectArrayList<>(); List<com.hypixel.hytale.protocol.packets.asseteditor.AuthorInfo> authors = new ObjectArrayList<>();
for (AuthorInfo a : manifest.getAuthors()) { for (AuthorInfo a : manifest.getAuthors()) {
@@ -887,7 +929,7 @@ public class AssetEditorPlugin extends JavaPlugin {
return packet; return packet;
} }
private void broadcastPackAddedOrUpdated(String packId, PluginManifest manifest) { private void broadcastPackAddedOrUpdated(@Nonnull String packId, @Nonnull PluginManifest manifest) {
AssetPackManifest manifestPacket = toManifestPacket(manifest); AssetPackManifest manifestPacket = toManifestPacket(manifest);
for (Set<EditorClient> clients : this.uuidToEditorClients.values()) { for (Set<EditorClient> clients : this.uuidToEditorClients.values()) {
@@ -993,11 +1035,11 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleAssetUpdate(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, @Nonnull byte[] data, int requestToken) { public void handleAssetUpdate(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, @Nonnull byte[] data, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken); AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken);
if (assetTypeHandler != null) { if (assetTypeHandler != null) {
@@ -1007,13 +1049,13 @@ public class AssetEditorPlugin extends JavaPlugin {
try { try {
if (!dataSource.doesAssetExist(assetPath.path())) { if (!dataSource.doesAssetExist(assetPath.path())) {
this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath); this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.update.doesntExist")); editorClient.sendFailureReply(requestToken, Messages.UPDATE_DOESNT_EXIST);
return; return;
} }
if (!assetTypeHandler.isValidData(data)) { if (!assetTypeHandler.isValidData(data)) {
this.getLogger().at(Level.WARNING).log("Failed to validate data for %s", assetPath); this.getLogger().at(Level.WARNING).log("Failed to validate data for %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createAsset.failed")); editorClient.sendFailureReply(requestToken, Messages.CREATE_ASSET_FAILED);
return; return;
} }
@@ -1026,7 +1068,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.WARNING).log("Failed to update asset %s in data source!", assetPath); this.getLogger().at(Level.WARNING).log("Failed to update asset %s in data source!", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.update.failed")); editorClient.sendFailureReply(requestToken, Messages.UPDATE_FAILED);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1048,26 +1090,26 @@ public class AssetEditorPlugin extends JavaPlugin {
int requestToken int requestToken
) { ) {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.getAssetTypeHandler(assetType); AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.getAssetTypeHandler(assetType);
if (!(assetTypeHandler instanceof JsonTypeHandler)) { if (!(assetTypeHandler instanceof JsonTypeHandler jsonTypeHandler)) {
this.getLogger().at(Level.WARNING).log("Invalid asset type %s", assetType); this.getLogger().at(Level.WARNING).log("Invalid asset type %s", assetType);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.unknownAssetType").param("assetType", assetType)); editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.unknownAssetType").param("assetType", assetType));
} else { } else {
DataSource dataSource; DataSource dataSource;
if (assetIndex > -1 && assetTypeHandler instanceof AssetStoreTypeHandler) { if (assetIndex > -1 && assetTypeHandler instanceof AssetStoreTypeHandler assetStoreTypeHandler) {
AssetStore assetStore = ((AssetStoreTypeHandler)assetTypeHandler).getAssetStore(); AssetStore assetStore = assetStoreTypeHandler.getAssetStore();
AssetMap assetMap = assetStore.getAssetMap(); AssetMap assetMap = assetStore.getAssetMap();
String keyString = AssetStoreUtil.getIdFromIndex(assetStore, assetIndex); String keyString = AssetStoreUtil.getIdFromIndex(assetStore, assetIndex);
Object key = assetStore.decodeStringKey(keyString); Object key = assetStore.decodeStringKey(keyString);
Path storedPath = assetMap.getPath(key); Path storedPath = assetMap.getPath(key);
String storedAssetPack = assetMap.getAssetPack(key); String storedAssetPack = assetMap.getAssetPack(key);
if (storedPath == null || storedAssetPack == null) { if (storedPath == null || storedAssetPack == null) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.unknownAssetIndex")); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_INDEX);
return; return;
} }
dataSource = this.getDataSourceForPack(storedAssetPack); dataSource = this.getDataSourceForPack(storedAssetPack);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
return; return;
} }
@@ -1075,18 +1117,18 @@ public class AssetEditorPlugin extends JavaPlugin {
} else { } else {
dataSource = this.getDataSourceForPath(assetPath); dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
return; return;
} }
} }
if (dataSource.isImmutable()) { if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else if (!assetPath.path().startsWith(assetTypeHandler.getRootPath())) { } else if (!assetPath.path().startsWith(assetTypeHandler.getRootPath())) {
this.getLogger().at(Level.WARNING).log("%s is not within valid asset directory", assetPath); this.getLogger().at(Level.WARNING).log("%s is not within valid asset directory", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.directoryOutsideRoot")); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ROOT);
} else { } else {
String fileExtension = PathUtil.getFileExtension(assetPath.path()); String fileExtension = PathUtil.getFileExtension(assetPath.path());
if (!fileExtension.equalsIgnoreCase(assetTypeHandler.getConfig().fileExtension)) { if (!fileExtension.equalsIgnoreCase(assetTypeHandler.getConfig().fileExtension)) {
@@ -1107,7 +1149,7 @@ public class AssetEditorPlugin extends JavaPlugin {
byte[] bytes = dataSource.getAssetBytes(assetPath.path()); byte[] bytes = dataSource.getAssetBytes(assetPath.path());
if (bytes == null) { if (bytes == null) {
this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath); this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.update.doesntExist")); editorClient.sendFailureReply(requestToken, Messages.UPDATE_DOESNT_EXIST);
return; return;
} }
@@ -1118,9 +1160,9 @@ public class AssetEditorPlugin extends JavaPlugin {
asset = this.applyCommandsToAsset(bytes, assetPath, commands, rebuildCacheBuilder); asset = this.applyCommandsToAsset(bytes, assetPath, commands, rebuildCacheBuilder);
String json = BsonUtil.toJson(asset) + "\n"; String json = BsonUtil.toJson(asset) + "\n";
bytes = json.getBytes(StandardCharsets.UTF_8); bytes = json.getBytes(StandardCharsets.UTF_8);
} catch (Exception var23) { } catch (Exception var24) {
this.getLogger().at(Level.WARNING).withCause(var23).log("Failed to apply commands to %s", assetPath); this.getLogger().at(Level.WARNING).withCause(var24).log("Failed to apply commands to %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.update.failed")); editorClient.sendFailureReply(requestToken, Messages.UPDATE_FAILED);
return; return;
} }
@@ -1135,8 +1177,7 @@ public class AssetEditorPlugin extends JavaPlugin {
this.updateJsonAssetForConnectedClients(assetPath, commands, editorClient); this.updateJsonAssetForConnectedClients(assetPath, commands, editorClient);
editorClient.sendSuccessReply(requestToken); editorClient.sendSuccessReply(requestToken);
this.sendModifiedAssetsUpdateToConnectedUsers(); this.sendModifiedAssetsUpdateToConnectedUsers();
((JsonTypeHandler)assetTypeHandler) jsonTypeHandler.loadAssetFromDocument(
.loadAssetFromDocument(
assetPath, assetPath,
dataSource.getFullPathToAssetData(assetPath.path()), dataSource.getFullPathToAssetData(assetPath.path()),
asset.clone(), asset.clone(),
@@ -1146,7 +1187,7 @@ public class AssetEditorPlugin extends JavaPlugin {
return; return;
} }
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.update.failed")); editorClient.sendFailureReply(requestToken, Messages.UPDATE_FAILED);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1158,17 +1199,17 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleUndo(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) { public void handleUndo(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken); AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken);
if (assetTypeHandler != null) { if (assetTypeHandler != null) {
if (!(assetTypeHandler instanceof JsonTypeHandler)) { if (!(assetTypeHandler instanceof JsonTypeHandler)) {
this.getLogger().at(Level.WARNING).log("Undo can only be applied to an instance of JsonTypeHandler"); this.getLogger().at(Level.WARNING).log("Undo can only be applied to an instance of JsonTypeHandler");
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.invalidAssetType")); editorClient.sendFailureReply(requestToken, Messages.INVALID_ASSET_TYPE);
} else { } else {
long stamp = this.globalEditLock.writeLock(); long stamp = this.globalEditLock.writeLock();
@@ -1176,7 +1217,7 @@ public class AssetEditorPlugin extends JavaPlugin {
AssetUndoRedoInfo undoRedo = this.undoRedoManager.getUndoRedoStack(assetPath); AssetUndoRedoInfo undoRedo = this.undoRedoManager.getUndoRedoStack(assetPath);
if (undoRedo == null || undoRedo.undoStack.isEmpty()) { if (undoRedo == null || undoRedo.undoStack.isEmpty()) {
this.getLogger().at(Level.INFO).log("Nothing to undo"); this.getLogger().at(Level.INFO).log("Nothing to undo");
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.undo.empty")); editorClient.sendFailureReply(requestToken, Messages.UNDO_EMPTY);
return; return;
} }
@@ -1195,7 +1236,7 @@ public class AssetEditorPlugin extends JavaPlugin {
byte[] bytes = dataSource.getAssetBytes(assetPath.path()); byte[] bytes = dataSource.getAssetBytes(assetPath.path());
if (bytes == null) { if (bytes == null) {
this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath); this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.update.doesntExist")); editorClient.sendFailureReply(requestToken, Messages.UPDATE_DOESNT_EXIST);
return; return;
} }
@@ -1208,7 +1249,7 @@ public class AssetEditorPlugin extends JavaPlugin {
bytes = json.getBytes(StandardCharsets.UTF_8); bytes = json.getBytes(StandardCharsets.UTF_8);
} catch (Exception var18) { } catch (Exception var18) {
this.getLogger().at(Level.WARNING).withCause(var18).log("Failed to undo for %s", assetPath); this.getLogger().at(Level.WARNING).withCause(var18).log("Failed to undo for %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.undo.failed")); editorClient.sendFailureReply(requestToken, Messages.UNDO_FAILED);
return; return;
} }
@@ -1229,7 +1270,7 @@ public class AssetEditorPlugin extends JavaPlugin {
return; return;
} }
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.undo.failed")); editorClient.sendFailureReply(requestToken, Messages.UNDO_FAILED);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1241,17 +1282,17 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleRedo(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) { public void handleRedo(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken); AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken);
if (assetTypeHandler != null) { if (assetTypeHandler != null) {
if (!(assetTypeHandler instanceof JsonTypeHandler)) { if (!(assetTypeHandler instanceof JsonTypeHandler)) {
this.getLogger().at(Level.WARNING).log("Redo can only be applied to an instance of JsonTypeHandler"); this.getLogger().at(Level.WARNING).log("Redo can only be applied to an instance of JsonTypeHandler");
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.invalidAssetType")); editorClient.sendFailureReply(requestToken, Messages.INVALID_ASSET_TYPE);
} else { } else {
long stamp = this.globalEditLock.writeLock(); long stamp = this.globalEditLock.writeLock();
@@ -1259,14 +1300,14 @@ public class AssetEditorPlugin extends JavaPlugin {
AssetUndoRedoInfo undoRedo = this.undoRedoManager.getUndoRedoStack(assetPath); AssetUndoRedoInfo undoRedo = this.undoRedoManager.getUndoRedoStack(assetPath);
if (undoRedo == null || undoRedo.redoStack.isEmpty()) { if (undoRedo == null || undoRedo.redoStack.isEmpty()) {
this.getLogger().at(Level.WARNING).log("Nothing to redo"); this.getLogger().at(Level.WARNING).log("Nothing to redo");
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.redo.empty")); editorClient.sendFailureReply(requestToken, Messages.REDO_EMPTY);
return; return;
} }
byte[] bytes = dataSource.getAssetBytes(assetPath.path()); byte[] bytes = dataSource.getAssetBytes(assetPath.path());
if (bytes == null) { if (bytes == null) {
this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath); this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.update.doesntExist")); editorClient.sendFailureReply(requestToken, Messages.UPDATE_DOESNT_EXIST);
return; return;
} }
@@ -1280,7 +1321,7 @@ public class AssetEditorPlugin extends JavaPlugin {
bytes = json.getBytes(StandardCharsets.UTF_8); bytes = json.getBytes(StandardCharsets.UTF_8);
} catch (Exception var17) { } catch (Exception var17) {
this.getLogger().at(Level.WARNING).withCause(var17).log("Failed to redo for %s", assetPath); this.getLogger().at(Level.WARNING).withCause(var17).log("Failed to redo for %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.redo.failed")); editorClient.sendFailureReply(requestToken, Messages.REDO_FAILED);
return; return;
} }
@@ -1301,7 +1342,7 @@ public class AssetEditorPlugin extends JavaPlugin {
return; return;
} }
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.redo.failed")); editorClient.sendFailureReply(requestToken, Messages.REDO_FAILED);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1313,16 +1354,16 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleFetchAsset(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) { public void handleFetchAsset(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else if (this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken) != null) { } else if (this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken) != null) {
long stamp = this.globalEditLock.readLock(); long stamp = this.globalEditLock.readLock();
try { try {
if (!dataSource.doesAssetExist(assetPath.path())) { if (!dataSource.doesAssetExist(assetPath.path())) {
this.getLogger().at(Level.WARNING).log("%s is not a regular file", assetPath); this.getLogger().at(Level.WARNING).log("%s is not a regular file", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.fetchAsset.doesntExist")); editorClient.sendFailureReply(requestToken, Messages.FETCH_ASSET_DOESNT_EXIST);
return; return;
} }
@@ -1334,7 +1375,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.INFO).log("Failed to get '%s'", assetPath); this.getLogger().at(Level.INFO).log("Failed to get '%s'", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.fetchAsset.failed")); editorClient.sendFailureReply(requestToken, Messages.FETCH_ASSET_FAILED);
} finally { } finally {
this.globalEditLock.unlockRead(stamp); this.globalEditLock.unlockRead(stamp);
} }
@@ -1344,9 +1385,9 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleFetchJsonAssetWithParents(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, boolean isFromOpenedTab, int requestToken) { public void handleFetchJsonAssetWithParents(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, boolean isFromOpenedTab, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else if (this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken) != null) { } else if (this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken) != null) {
long stamp = this.globalEditLock.readLock(); long stamp = this.globalEditLock.readLock();
@@ -1362,7 +1403,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.INFO).log("Failed to get '%s'", assetPath); this.getLogger().at(Level.INFO).log("Failed to get '%s'", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.fetchAsset.failed")); editorClient.sendFailureReply(requestToken, Messages.FETCH_ASSET_FAILED);
} finally { } finally {
this.globalEditLock.unlockRead(stamp); this.globalEditLock.unlockRead(stamp);
} }
@@ -1372,21 +1413,17 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleRequestChildIds(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath) { public void handleRequestChildIds(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.UNKNOWN_ASSET_PACK);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else if (!(this.assetTypeRegistry.getAssetTypeHandlerForPath(assetPath.path()) instanceof AssetStoreTypeHandler assetStoreTypeHandler)) {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.getAssetTypeHandlerForPath(assetPath.path());
if (!(assetTypeHandler instanceof AssetStoreTypeHandler)) {
this.getLogger().at(Level.WARNING).log("Invalid asset type for %s", assetPath); this.getLogger().at(Level.WARNING).log("Invalid asset type for %s", assetPath);
editorClient.sendPopupNotification( editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, Messages.REQUEST_CHILD_IDS_ASSET_TYPE_MISSING);
AssetEditorPopupNotificationType.Error, Message.translation("server.assetEditor.messages.requestChildIds.assetTypeMissing")
);
} else { } else {
AssetStore assetStore = ((AssetStoreTypeHandler)assetTypeHandler).getAssetStore(); AssetStore assetStore = assetStoreTypeHandler.getAssetStore();
Object key = assetStore.decodeFilePathKey(assetPath.path()); Object key = assetStore.decodeFilePathKey(assetPath.path());
Set children = assetStore.getAssetMap().getChildren(key); Set children = assetStore.getAssetMap().getChildren(key);
HashSet<String> childrenIds = new HashSet<>(); HashSet childrenIds = new HashSet();
if (children != null) { if (children != null) {
for (Object child : children) { for (Object child : children) {
if (assetStore.getAssetMap().getPath(child) != null) { if (assetStore.getAssetMap().getPath(child) != null) {
@@ -1399,16 +1436,15 @@ public class AssetEditorPlugin extends JavaPlugin {
editorClient.getPacketHandler().write(new AssetEditorRequestChildrenListReply(assetPath.toPacket(), childrenIds.toArray(String[]::new))); editorClient.getPacketHandler().write(new AssetEditorRequestChildrenListReply(assetPath.toPacket(), childrenIds.toArray(String[]::new)));
} }
} }
}
public void handleDeleteAsset(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) { public void handleDeleteAsset(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken); AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken);
if (assetTypeHandler != null) { if (assetTypeHandler != null) {
@@ -1418,7 +1454,7 @@ public class AssetEditorPlugin extends JavaPlugin {
try { try {
if (!dataSource.doesAssetExist(assetPath.path())) { if (!dataSource.doesAssetExist(assetPath.path())) {
this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath); this.getLogger().at(Level.WARNING).log("%s does not exist", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.deleteAsset.alreadyDeleted")); editorClient.sendFailureReply(requestToken, Messages.DELETE_ASSET_ALREADY_DELETED);
return; return;
} }
@@ -1434,7 +1470,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.WARNING).log("Failed to delete %s from data source", assetPath); this.getLogger().at(Level.WARNING).log("Failed to delete %s from data source", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.failedToDeleteAsset")); editorClient.sendFailureReply(requestToken, Messages.FAILED_TO_DELETE_ASSET);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1447,24 +1483,24 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
} }
public void handleSubscribeToModifiedAssetsChanges(EditorClient editorClient) { public void handleSubscribeToModifiedAssetsChanges(@Nonnull EditorClient editorClient) {
this.clientsSubscribedToModifiedAssetsChanges.add(editorClient); this.clientsSubscribedToModifiedAssetsChanges.add(editorClient);
} }
public void handleUnsubscribeFromModifiedAssetsChanges(EditorClient editorClient) { public void handleUnsubscribeFromModifiedAssetsChanges(@Nonnull EditorClient editorClient) {
this.clientsSubscribedToModifiedAssetsChanges.remove(editorClient); this.clientsSubscribedToModifiedAssetsChanges.remove(editorClient);
} }
public void handleRenameAsset(@Nonnull EditorClient editorClient, @Nonnull AssetPath oldAssetPath, @Nonnull AssetPath newAssetPath, int requestToken) { public void handleRenameAsset(@Nonnull EditorClient editorClient, @Nonnull AssetPath oldAssetPath, @Nonnull AssetPath newAssetPath, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(oldAssetPath); DataSource dataSource = this.getDataSourceForPath(oldAssetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, oldAssetPath)) { } else if (!this.isValidPath(dataSource, oldAssetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else if (!this.isValidPath(dataSource, newAssetPath)) { } else if (!this.isValidPath(dataSource, newAssetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(oldAssetPath.path(), editorClient, requestToken); AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(oldAssetPath.path(), editorClient, requestToken);
if (assetTypeHandler != null) { if (assetTypeHandler != null) {
@@ -1479,21 +1515,21 @@ public class AssetEditorPlugin extends JavaPlugin {
); );
} else if (!newAssetPath.path().startsWith(assetTypeHandler.getRootPath())) { } else if (!newAssetPath.path().startsWith(assetTypeHandler.getRootPath())) {
this.getLogger().at(Level.WARNING).log("%s is not within valid asset directory", newAssetPath); this.getLogger().at(Level.WARNING).log("%s is not within valid asset directory", newAssetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.directoryOutsideRoot")); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ROOT);
} else { } else {
long stamp = this.globalEditLock.writeLock(); long stamp = this.globalEditLock.writeLock();
try { try {
if (dataSource.doesAssetExist(newAssetPath.path())) { if (dataSource.doesAssetExist(newAssetPath.path())) {
this.getLogger().at(Level.WARNING).log("%s already exists", newAssetPath); this.getLogger().at(Level.WARNING).log("%s already exists", newAssetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.renameAsset.alreadyExists")); editorClient.sendFailureReply(requestToken, Messages.RENAME_ASSET_ALREADY_EXISTS);
return; return;
} }
byte[] oldAsset = dataSource.getAssetBytes(oldAssetPath.path()); byte[] oldAsset = dataSource.getAssetBytes(oldAssetPath.path());
if (oldAsset == null) { if (oldAsset == null) {
this.getLogger().at(Level.WARNING).log("%s is not a regular file", oldAssetPath); this.getLogger().at(Level.WARNING).log("%s is not a regular file", oldAssetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.renameAsset.doesntExist")); editorClient.sendFailureReply(requestToken, Messages.RENAME_ASSET_DOESNT_EXIST);
return; return;
} }
@@ -1517,7 +1553,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.WARNING).log("Failed to move file %s to %s", oldAssetPath, newAssetPath); this.getLogger().at(Level.WARNING).log("Failed to move file %s to %s", oldAssetPath, newAssetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.renameAsset.failed")); editorClient.sendFailureReply(requestToken, Messages.RENAME_ASSET_FAILED);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1529,24 +1565,24 @@ public class AssetEditorPlugin extends JavaPlugin {
public void handleDeleteDirectory(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) { public void handleDeleteDirectory(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource.isImmutable()) { if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.directoryOutsideRoot")); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ROOT);
} else if (!this.getAssetTypeRegistry().isPathInAssetTypeFolder(assetPath.path())) { } else if (!this.getAssetTypeRegistry().isPathInAssetTypeFolder(assetPath.path())) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else {
long stamp = this.globalEditLock.writeLock(); long stamp = this.globalEditLock.writeLock();
try { try {
if (!dataSource.doesDirectoryExist(assetPath.path())) { if (!dataSource.doesDirectoryExist(assetPath.path())) {
this.getLogger().at(Level.WARNING).log("Directory doesn't exist %s", assetPath); this.getLogger().at(Level.WARNING).log("Directory doesn't exist %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createDirectory.alreadyExists")); editorClient.sendFailureReply(requestToken, Messages.CREATE_DIRECTORY_ALREADY_EXISTS);
return; return;
} }
if (!dataSource.getAssetTree().isDirectoryEmpty(assetPath.path())) { if (!dataSource.getAssetTree().isDirectoryEmpty(assetPath.path())) {
this.getLogger().at(Level.WARNING).log("%s must be empty", assetPath); this.getLogger().at(Level.WARNING).log("%s must be empty", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.deleteDirectory.notEmpty")); editorClient.sendFailureReply(requestToken, Messages.DELETE_DIRECTORY_NOT_EMPTY);
return; return;
} }
@@ -1560,7 +1596,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.WARNING).log("Directory %s could not be deleted!", assetPath); this.getLogger().at(Level.WARNING).log("Directory %s could not be deleted!", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.deleteDirectory.failed")); editorClient.sendFailureReply(requestToken, Messages.DELETE_DIRECTORY_FAILED);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1568,31 +1604,31 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
public void handleRenameDirectory(@Nonnull EditorClient editorClient, AssetPath path, AssetPath newPath, int requestToken) { public void handleRenameDirectory(@Nonnull EditorClient editorClient, AssetPath path, AssetPath newPath, int requestToken) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.renameDirectory.unsupported")); editorClient.sendFailureReply(requestToken, Messages.RENAME_DIRECTORY_UNSUPPORTED);
} }
public void handleCreateDirectory(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) { public void handleCreateDirectory(@Nonnull EditorClient editorClient, @Nonnull AssetPath assetPath, int requestToken) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createDirectory.noDataSource")); editorClient.sendFailureReply(requestToken, Messages.CREATE_DIRECTORY_NO_DATA_SOURCE);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createDirectory.noPath")); editorClient.sendFailureReply(requestToken, Messages.CREATE_DIRECTORY_NO_PATH);
} else { } else {
long stamp = this.globalEditLock.writeLock(); long stamp = this.globalEditLock.writeLock();
try { try {
if (dataSource.doesDirectoryExist(assetPath.path())) { if (dataSource.doesDirectoryExist(assetPath.path())) {
this.getLogger().at(Level.WARNING).log("Directory already exists at %s", assetPath); this.getLogger().at(Level.WARNING).log("Directory already exists at %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createDirectory.alreadyExists")); editorClient.sendFailureReply(requestToken, Messages.CREATE_DIRECTORY_ALREADY_EXISTS);
return; return;
} }
Path parentDirectoryPath = assetPath.path().getParent(); Path parentDirectoryPath = assetPath.path().getParent();
if (!dataSource.doesDirectoryExist(parentDirectoryPath)) { if (!dataSource.doesDirectoryExist(parentDirectoryPath)) {
this.getLogger().at(Level.WARNING).log("Parent directory is missing for %s", assetPath); this.getLogger().at(Level.WARNING).log("Parent directory is missing for %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.parentDirectoryMissing")); editorClient.sendFailureReply(requestToken, Messages.PARENT_DIRECTORY_MISSING);
return; return;
} }
@@ -1609,7 +1645,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.WARNING).log("Failed to create directory %s", assetPath); this.getLogger().at(Level.WARNING).log("Failed to create directory %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.failedToCreateDirectory")); editorClient.sendFailureReply(requestToken, Messages.FAILED_TO_CREATE_DIRECTORY);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1626,11 +1662,11 @@ public class AssetEditorPlugin extends JavaPlugin {
) { ) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
if (dataSource == null) { if (dataSource == null) {
editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSETPACK_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.UNKNOWN_ASSET_PACK);
} else if (dataSource.isImmutable()) { } else if (dataSource.isImmutable()) {
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.assetsReadOnly")); editorClient.sendFailureReply(requestToken, Messages.ASSETS_READ_ONLY);
} else if (!this.isValidPath(dataSource, assetPath)) { } else if (!this.isValidPath(dataSource, assetPath)) {
editorClient.sendFailureReply(requestToken, Messages.OUTSIDE_ASSET_ROOT_MESSAGE); editorClient.sendFailureReply(requestToken, Messages.DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT);
} else { } else {
AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken); AssetTypeHandler assetTypeHandler = this.assetTypeRegistry.tryGetAssetTypeHandler(assetPath.path(), editorClient, requestToken);
if (assetTypeHandler != null) { if (assetTypeHandler != null) {
@@ -1639,13 +1675,13 @@ public class AssetEditorPlugin extends JavaPlugin {
try { try {
if (dataSource.doesAssetExist(assetPath.path())) { if (dataSource.doesAssetExist(assetPath.path())) {
this.getLogger().at(Level.WARNING).log("%s already exists", assetPath); this.getLogger().at(Level.WARNING).log("%s already exists", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createAsset.idAlreadyExists")); editorClient.sendFailureReply(requestToken, Messages.CREATE_ASSET_ID_ALREADY_EXISTS);
return; return;
} }
if (!assetTypeHandler.isValidData(data)) { if (!assetTypeHandler.isValidData(data)) {
this.getLogger().at(Level.WARNING).log("Failed to validate data for %s", assetPath); this.getLogger().at(Level.WARNING).log("Failed to validate data for %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createAsset.failed")); editorClient.sendFailureReply(requestToken, Messages.CREATE_ASSET_FAILED);
return; return;
} }
@@ -1681,7 +1717,7 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
this.getLogger().at(Level.WARNING).log("Failed to create asset %s", assetPath); this.getLogger().at(Level.WARNING).log("Failed to create asset %s", assetPath);
editorClient.sendFailureReply(requestToken, Message.translation("server.assetEditor.messages.createAsset.failed")); editorClient.sendFailureReply(requestToken, Messages.CREATE_ASSET_FAILED);
} finally { } finally {
this.globalEditLock.unlockWrite(stamp); this.globalEditLock.unlockWrite(stamp);
} }
@@ -1778,13 +1814,13 @@ public class AssetEditorPlugin extends JavaPlugin {
this.updateAssetForConnectedClients(assetPath, null); this.updateAssetForConnectedClients(assetPath, null);
} }
private void updateAssetForConnectedClients(@Nonnull AssetPath assetPath, EditorClient ignoreEditorClient) { private void updateAssetForConnectedClients(@Nonnull AssetPath assetPath, @Nullable EditorClient ignoreEditorClient) {
DataSource dataSource = this.getDataSourceForPath(assetPath); DataSource dataSource = this.getDataSourceForPath(assetPath);
byte[] bytes = dataSource.getAssetBytes(assetPath.path()); byte[] bytes = dataSource.getAssetBytes(assetPath.path());
this.updateAssetForConnectedClients(assetPath, bytes, ignoreEditorClient); this.updateAssetForConnectedClients(assetPath, bytes, ignoreEditorClient);
} }
private void updateAssetForConnectedClients(@Nonnull AssetPath assetPath, byte[] bytes, EditorClient ignoreEditorClient) { private void updateAssetForConnectedClients(@Nonnull AssetPath assetPath, byte[] bytes, @Nullable EditorClient ignoreEditorClient) {
AssetEditorAssetUpdated updatePacket = new AssetEditorAssetUpdated(assetPath.toPacket(), bytes); AssetEditorAssetUpdated updatePacket = new AssetEditorAssetUpdated(assetPath.toPacket(), bytes);
for (Entry<EditorClient, AssetPath> entry : this.clientOpenAssetPathMapping.entrySet()) { for (Entry<EditorClient, AssetPath> entry : this.clientOpenAssetPathMapping.entrySet()) {
@@ -1794,11 +1830,13 @@ public class AssetEditorPlugin extends JavaPlugin {
} }
} }
private void updateJsonAssetForConnectedClients(@Nonnull AssetPath assetPath, JsonUpdateCommand[] commands) { private void updateJsonAssetForConnectedClients(@Nonnull AssetPath assetPath, @Nonnull JsonUpdateCommand[] commands) {
this.updateJsonAssetForConnectedClients(assetPath, commands, null); this.updateJsonAssetForConnectedClients(assetPath, commands, null);
} }
private void updateJsonAssetForConnectedClients(@Nonnull AssetPath assetPath, JsonUpdateCommand[] commands, EditorClient ignoreEditorClient) { private void updateJsonAssetForConnectedClients(
@Nonnull AssetPath assetPath, @Nonnull JsonUpdateCommand[] commands, @Nullable EditorClient ignoreEditorClient
) {
AssetEditorJsonAssetUpdated updatePacket = new AssetEditorJsonAssetUpdated(assetPath.toPacket(), commands); AssetEditorJsonAssetUpdated updatePacket = new AssetEditorJsonAssetUpdated(assetPath.toPacket(), commands);
for (Entry<EditorClient, AssetPath> connectedPlayer : this.clientOpenAssetPathMapping.entrySet()) { for (Entry<EditorClient, AssetPath> connectedPlayer : this.clientOpenAssetPathMapping.entrySet()) {
@@ -1810,7 +1848,7 @@ public class AssetEditorPlugin extends JavaPlugin {
@Nonnull @Nonnull
private AssetEditorLastModifiedAssets buildAssetEditorLastModifiedAssetsPacket() { private AssetEditorLastModifiedAssets buildAssetEditorLastModifiedAssetsPacket() {
ArrayList<AssetInfo> allAssets = new ArrayList<>(); List<AssetInfo> allAssets = new ObjectArrayList<>();
for (Entry<String, DataSource> dataSource : this.assetPackDataSources.entrySet()) { for (Entry<String, DataSource> dataSource : this.assetPackDataSources.entrySet()) {
if (dataSource.getValue() instanceof StandardDataSource standardDataSource) { if (dataSource.getValue() instanceof StandardDataSource standardDataSource) {

View File

@@ -1,10 +1,93 @@
package com.hypixel.hytale.builtin.asseteditor; package com.hypixel.hytale.builtin.asseteditor;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import javax.annotation.Nonnull;
public class Messages { public class Messages {
public static final Message USAGE_DENIED_MESSAGE = Message.translation("server.assetEditor.messages.usageDenied"); @Nonnull
public static final Message INVALID_FILENAME_MESSAGE = Message.translation("server.assetEditor.messages.invalidFileName"); public static final Message USAGE_DENIED = Message.translation("server.assetEditor.messages.usageDenied");
public static final Message OUTSIDE_ASSET_ROOT_MESSAGE = Message.translation("server.assetEditor.messages.directoryOutsideAssetTypeRoot"); @Nonnull
public static final Message UNKNOWN_ASSETPACK_MESSAGE = Message.translation("server.assetEditor.messages.unknownAssetPack"); public static final Message INVALID_FILE_NAME = Message.translation("server.assetEditor.messages.invalidFileName");
@Nonnull
public static final Message DIRECTORY_OUTSIDE_ASSET_TYPE_ROOT = Message.translation("server.assetEditor.messages.directoryOutsideAssetTypeRoot");
@Nonnull
public static final Message UNKNOWN_ASSET_PACK = Message.translation("server.assetEditor.messages.unknownAssetPack");
@Nonnull
public static final Message ASSETS_READ_ONLY = Message.translation("server.assetEditor.messages.assetsReadOnly");
@Nonnull
public static final Message UPDATE_DOESNT_EXIST = Message.translation("server.assetEditor.messages.update.doesntExist");
@Nonnull
public static final Message CREATE_ASSET_FAILED = Message.translation("server.assetEditor.messages.createAsset.failed");
@Nonnull
public static final Message UPDATE_FAILED = Message.translation("server.assetEditor.messages.update.failed");
@Nonnull
public static final Message PACK_OUTSIDE_DIRECTORY = Message.translation("server.assetEditor.messages.packOutsideDirectory");
@Nonnull
public static final Message PACK_ALREADY_EXISTS_AT_PATH = Message.translation("server.assetEditor.messages.packAlreadyExistsAtPath");
@Nonnull
public static final Message PACK_CREATED = Message.translation("server.assetEditor.messages.packCreated");
@Nonnull
public static final Message PACK_CREATION_FAILED = Message.translation("server.assetEditor.messages.packCreationFailed");
@Nonnull
public static final Message UNKNOWN_ASSET_INDEX = Message.translation("server.assetEditor.messages.unknownAssetIndex");
@Nonnull
public static final Message DIRECTORY_OUTSIDE_ROOT = Message.translation("server.assetEditor.messages.directoryOutsideRoot");
@Nonnull
public static final Message INVALID_ASSET_TYPE = Message.translation("server.assetEditor.messages.invalidAssetType");
@Nonnull
public static final Message UNDO_EMPTY = Message.translation("server.assetEditor.messages.undo.empty");
@Nonnull
public static final Message UNDO_FAILED = Message.translation("server.assetEditor.messages.undo.failed");
@Nonnull
public static final Message REDO_EMPTY = Message.translation("server.assetEditor.messages.redo.empty");
@Nonnull
public static final Message REDO_FAILED = Message.translation("server.assetEditor.messages.redo.failed");
@Nonnull
public static final Message FETCH_ASSET_DOESNT_EXIST = Message.translation("server.assetEditor.messages.fetchAsset.doesntExist");
@Nonnull
public static final Message FETCH_ASSET_FAILED = Message.translation("server.assetEditor.messages.fetchAsset.failed");
@Nonnull
public static final Message REQUEST_CHILD_IDS_ASSET_TYPE_MISSING = Message.translation("server.assetEditor.messages.requestChildIds.assetTypeMissing");
@Nonnull
public static final Message DELETE_ASSET_ALREADY_DELETED = Message.translation("server.assetEditor.messages.deleteAsset.alreadyDeleted");
@Nonnull
public static final Message FAILED_TO_DELETE_ASSET = Message.translation("server.assetEditor.messages.failedToDeleteAsset");
@Nonnull
public static final Message RENAME_ASSET_ALREADY_EXISTS = Message.translation("server.assetEditor.messages.renameAsset.alreadyExists");
@Nonnull
public static final Message RENAME_ASSET_DOESNT_EXIST = Message.translation("server.assetEditor.messages.renameAsset.doesntExist");
@Nonnull
public static final Message RENAME_ASSET_FAILED = Message.translation("server.assetEditor.messages.renameAsset.failed");
@Nonnull
public static final Message CREATE_DIRECTORY_ALREADY_EXISTS = Message.translation("server.assetEditor.messages.createDirectory.alreadyExists");
@Nonnull
public static final Message DELETE_DIRECTORY_NOT_EMPTY = Message.translation("server.assetEditor.messages.deleteDirectory.notEmpty");
@Nonnull
public static final Message DELETE_DIRECTORY_FAILED = Message.translation("server.assetEditor.messages.deleteDirectory.failed");
@Nonnull
public static final Message RENAME_DIRECTORY_UNSUPPORTED = Message.translation("server.assetEditor.messages.renameDirectory.unsupported");
@Nonnull
public static final Message CREATE_DIRECTORY_NO_DATA_SOURCE = Message.translation("server.assetEditor.messages.createDirectory.noDataSource");
@Nonnull
public static final Message CREATE_DIRECTORY_NO_PATH = Message.translation("server.assetEditor.messages.createDirectory.noPath");
@Nonnull
public static final Message PARENT_DIRECTORY_MISSING = Message.translation("server.assetEditor.messages.parentDirectoryMissing");
@Nonnull
public static final Message FAILED_TO_CREATE_DIRECTORY = Message.translation("server.assetEditor.messages.failedToCreateDirectory");
@Nonnull
public static final Message CREATE_ASSET_ID_ALREADY_EXISTS = Message.translation("server.assetEditor.messages.createAsset.idAlreadyExists");
@Nonnull
public static final Message MANIFEST_NOT_FOUND = Message.translation("server.assetEditor.messages.manifestNotFound");
@Nonnull
public static final Message INVALID_VERSION_FORMAT = Message.translation("server.assetEditor.messages.invalidVersionFormat");
@Nonnull
public static final Message MANIFEST_SAVED = Message.translation("server.assetEditor.messages.manifestSaved");
@Nonnull
public static final Message MANIFEST_SAVE_FAILED = Message.translation("server.assetEditor.messages.manifestSaveFailed");
@Nonnull
public static final Message PACK_NAME_REQUIRED = Message.translation("server.assetEditor.messages.packNameRequired");
@Nonnull
public static final Message PACK_GROUP_REQUIRED = Message.translation("server.assetEditor.messages.packGroupRequired");
@Nonnull
public static final Message PACK_ALREADY_EXISTS = Message.translation("server.assetEditor.messages.packAlreadyExists");
} }

View File

@@ -21,11 +21,12 @@ import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class CommonAssetTypeHandler extends AssetTypeHandler { public class CommonAssetTypeHandler extends AssetTypeHandler {
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass(); private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
public CommonAssetTypeHandler(String id, String icon, String fileExtension, AssetEditorEditorType editorType) { public CommonAssetTypeHandler(String id, @Nullable String icon, String fileExtension, AssetEditorEditorType editorType) {
super(new AssetEditorAssetType(id, icon, true, "Common", fileExtension, editorType)); super(new AssetEditorAssetType(id, icon, true, "Common", fileExtension, editorType));
} }

View File

@@ -7,6 +7,7 @@ import com.hypixel.hytale.builtin.asseteditor.data.AssetState;
import com.hypixel.hytale.builtin.asseteditor.data.ModifiedAsset; import com.hypixel.hytale.builtin.asseteditor.data.ModifiedAsset;
import com.hypixel.hytale.codec.ExtraInfo; import com.hypixel.hytale.codec.ExtraInfo;
import com.hypixel.hytale.common.plugin.PluginManifest; import com.hypixel.hytale.common.plugin.PluginManifest;
import com.hypixel.hytale.common.util.PathUtil;
import com.hypixel.hytale.logger.HytaleLogger; import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.HytaleServer; import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.Options; import com.hypixel.hytale.server.core.Options;
@@ -134,7 +135,12 @@ public class StandardDataSource implements DataSource {
} }
public Path resolveAbsolutePath(Path path) { public Path resolveAbsolutePath(Path path) {
return this.rootPath.resolve(path.toString()).toAbsolutePath(); Path resolved = this.rootPath.resolve(path.toString()).toAbsolutePath();
if (!PathUtil.isChildOf(this.rootPath, resolved)) {
throw new IllegalArgumentException("Invalid path: " + path);
} else {
return resolved;
}
} }
@Override @Override

View File

@@ -6,15 +6,20 @@ import com.hypixel.hytale.builtin.beds.sleep.components.SleepTracker;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence; import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence;
import com.hypixel.hytale.builtin.beds.sleep.systems.player.EnterBedSystem; import com.hypixel.hytale.builtin.beds.sleep.systems.player.EnterBedSystem;
import com.hypixel.hytale.builtin.beds.sleep.systems.player.RegisterTrackerSystem; import com.hypixel.hytale.builtin.beds.sleep.systems.player.RegisterTrackerSystem;
import com.hypixel.hytale.builtin.beds.sleep.systems.player.SleepNotificationSystem;
import com.hypixel.hytale.builtin.beds.sleep.systems.player.UpdateSleepPacketSystem; import com.hypixel.hytale.builtin.beds.sleep.systems.player.UpdateSleepPacketSystem;
import com.hypixel.hytale.builtin.beds.sleep.systems.player.WakeUpOnDismountSystem; import com.hypixel.hytale.builtin.beds.sleep.systems.player.WakeUpOnDismountSystem;
import com.hypixel.hytale.builtin.beds.sleep.systems.world.StartSlumberSystem; import com.hypixel.hytale.builtin.beds.sleep.systems.world.StartSlumberSystem;
import com.hypixel.hytale.builtin.beds.sleep.systems.world.UpdateWorldSlumberSystem; import com.hypixel.hytale.builtin.beds.sleep.systems.world.UpdateWorldSlumberSystem;
import com.hypixel.hytale.builtin.mounts.MountedComponent;
import com.hypixel.hytale.component.ComponentRegistryProxy;
import com.hypixel.hytale.component.ComponentType; import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.ResourceType; import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPlugin;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -35,15 +40,26 @@ public class BedsPlugin extends JavaPlugin {
@Override @Override
protected void setup() { protected void setup() {
instance = this; instance = this;
this.playerSomnolenceComponentType = this.getEntityStoreRegistry().registerComponent(PlayerSomnolence.class, PlayerSomnolence::new); ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry();
this.sleepTrackerComponentType = this.getEntityStoreRegistry().registerComponent(SleepTracker.class, SleepTracker::new); this.playerSomnolenceComponentType = entityStoreRegistry.registerComponent(PlayerSomnolence.class, PlayerSomnolence::new);
this.worldSomnolenceResourceType = this.getEntityStoreRegistry().registerResource(WorldSomnolence.class, WorldSomnolence::new); this.sleepTrackerComponentType = entityStoreRegistry.registerComponent(SleepTracker.class, SleepTracker::new);
this.getEntityStoreRegistry().registerSystem(new StartSlumberSystem()); this.worldSomnolenceResourceType = entityStoreRegistry.registerResource(WorldSomnolence.class, WorldSomnolence::new);
this.getEntityStoreRegistry().registerSystem(new UpdateSleepPacketSystem()); ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
this.getEntityStoreRegistry().registerSystem(new WakeUpOnDismountSystem()); ComponentType<EntityStore, MountedComponent> mountedComponentType = MountedComponent.getComponentType();
this.getEntityStoreRegistry().registerSystem(new RegisterTrackerSystem()); ResourceType<EntityStore, WorldTimeResource> worldTimeResourceType = WorldTimeResource.getResourceType();
this.getEntityStoreRegistry().registerSystem(new UpdateWorldSlumberSystem()); entityStoreRegistry.registerSystem(new RegisterTrackerSystem(playerRefComponentType, this.sleepTrackerComponentType));
this.getEntityStoreRegistry().registerSystem(new EnterBedSystem()); entityStoreRegistry.registerSystem(new WakeUpOnDismountSystem(mountedComponentType, this.playerSomnolenceComponentType));
entityStoreRegistry.registerSystem(new EnterBedSystem(mountedComponentType, playerRefComponentType));
entityStoreRegistry.registerSystem(
new UpdateSleepPacketSystem(
playerRefComponentType, this.playerSomnolenceComponentType, this.sleepTrackerComponentType, this.worldSomnolenceResourceType, worldTimeResourceType
)
);
entityStoreRegistry.registerSystem(new StartSlumberSystem(this.playerSomnolenceComponentType, this.worldSomnolenceResourceType, worldTimeResourceType));
entityStoreRegistry.registerSystem(
new UpdateWorldSlumberSystem(this.playerSomnolenceComponentType, this.worldSomnolenceResourceType, worldTimeResourceType)
);
entityStoreRegistry.registerSystem(new SleepNotificationSystem());
Interaction.CODEC.register("Bed", BedInteraction.class, BedInteraction.CODEC); Interaction.CODEC.register("Bed", BedInteraction.class, BedInteraction.CODEC);
} }

View File

@@ -5,6 +5,7 @@ import com.hypixel.hytale.builtin.beds.respawn.SelectOverrideRespawnPointPage;
import com.hypixel.hytale.builtin.beds.respawn.SetNameRespawnPointPage; import com.hypixel.hytale.builtin.beds.respawn.SetNameRespawnPointPage;
import com.hypixel.hytale.builtin.beds.sleep.components.PlayerSleep; import com.hypixel.hytale.builtin.beds.sleep.components.PlayerSleep;
import com.hypixel.hytale.builtin.beds.sleep.components.PlayerSomnolence; import com.hypixel.hytale.builtin.beds.sleep.components.PlayerSomnolence;
import com.hypixel.hytale.builtin.beds.sleep.systems.player.SleepNotificationSystem;
import com.hypixel.hytale.builtin.mounts.BlockMountAPI; import com.hypixel.hytale.builtin.mounts.BlockMountAPI;
import com.hypixel.hytale.codec.builder.BuilderCodec; import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.AddReason; import com.hypixel.hytale.component.AddReason;
@@ -58,30 +59,25 @@ public class BedInteraction extends SimpleBlockInteraction {
@Nonnull CooldownHandler cooldownHandler @Nonnull CooldownHandler cooldownHandler
) { ) {
Ref<EntityStore> ref = context.getEntity(); Ref<EntityStore> ref = context.getEntity();
Player player = commandBuffer.getComponent(ref, Player.getComponentType()); Player playerComponent = commandBuffer.getComponent(ref, Player.getComponentType());
if (player != null) { if (playerComponent != null) {
Store<EntityStore> store = commandBuffer.getStore(); Store<EntityStore> store = commandBuffer.getStore();
PlayerRef playerRefComponent = commandBuffer.getComponent(ref, PlayerRef.getComponentType()); PlayerRef playerRefComponent = commandBuffer.getComponent(ref, PlayerRef.getComponentType());
if (playerRefComponent != null) {
assert playerRefComponent != null;
UUIDComponent playerUuidComponent = commandBuffer.getComponent(ref, UUIDComponent.getComponentType()); UUIDComponent playerUuidComponent = commandBuffer.getComponent(ref, UUIDComponent.getComponentType());
if (playerUuidComponent != null) {
assert playerUuidComponent != null;
UUID playerUuid = playerUuidComponent.getUuid(); UUID playerUuid = playerUuidComponent.getUuid();
Ref<ChunkStore> chunkReference = world.getChunkStore().getChunkReference(ChunkUtil.indexChunkFromBlock(pos.x, pos.z)); long chunkIndex = ChunkUtil.indexChunkFromBlock(pos.x, pos.z);
if (chunkReference != null) { Ref<ChunkStore> chunkRef = world.getChunkStore().getChunkReference(chunkIndex);
Store<ChunkStore> chunkStore = chunkReference.getStore(); if (chunkRef != null && chunkRef.isValid()) {
BlockComponentChunk blockComponentChunk = chunkStore.getComponent(chunkReference, BlockComponentChunk.getComponentType()); Store<ChunkStore> chunkStore = chunkRef.getStore();
BlockComponentChunk blockComponentChunk = chunkStore.getComponent(chunkRef, BlockComponentChunk.getComponentType());
assert blockComponentChunk != null; if (blockComponentChunk != null) {
int blockIndex = ChunkUtil.indexBlockInColumn(pos.x, pos.y, pos.z); int blockIndex = ChunkUtil.indexBlockInColumn(pos.x, pos.y, pos.z);
Ref<ChunkStore> blockRef = blockComponentChunk.getEntityReference(blockIndex); Ref<ChunkStore> blockRef = blockComponentChunk.getEntityReference(blockIndex);
if (blockRef == null || !blockRef.isValid()) { if (blockRef == null || !blockRef.isValid()) {
Holder<ChunkStore> holder = ChunkStore.REGISTRY.newHolder(); Holder<ChunkStore> holder = ChunkStore.REGISTRY.newHolder();
holder.putComponent(BlockModule.BlockStateInfo.getComponentType(), new BlockModule.BlockStateInfo(blockIndex, chunkReference)); holder.putComponent(BlockModule.BlockStateInfo.getComponentType(), new BlockModule.BlockStateInfo(blockIndex, chunkRef));
holder.ensureComponent(RespawnBlock.getComponentType()); holder.ensureComponent(RespawnBlock.getComponentType());
blockRef = chunkStore.addEntity(holder, AddReason.SPAWN); blockRef = chunkStore.addEntity(holder, AddReason.SPAWN);
} }
@@ -90,21 +86,24 @@ public class BedInteraction extends SimpleBlockInteraction {
RespawnBlock respawnBlockComponent = chunkStore.getComponent(blockRef, RespawnBlock.getComponentType()); RespawnBlock respawnBlockComponent = chunkStore.getComponent(blockRef, RespawnBlock.getComponentType());
if (respawnBlockComponent != null) { if (respawnBlockComponent != null) {
UUID ownerUUID = respawnBlockComponent.getOwnerUUID(); UUID ownerUUID = respawnBlockComponent.getOwnerUUID();
PageManager pageManager = player.getPageManager(); PageManager pageManager = playerComponent.getPageManager();
boolean isOwner = playerUuid.equals(ownerUUID); boolean isOwner = playerUuid.equals(ownerUUID);
if (isOwner) { if (isOwner) {
BlockPosition targetBlockPosition = context.getMetaStore().getMetaObject(TARGET_BLOCK_RAW); BlockPosition targetBlockPosition = context.getMetaStore().getMetaObject(TARGET_BLOCK_RAW);
Vector3f whereWasHit = new Vector3f(targetBlockPosition.x + 0.5F, targetBlockPosition.y + 0.5F, targetBlockPosition.z + 0.5F); Vector3f whereWasHit = new Vector3f(targetBlockPosition.x + 0.5F, targetBlockPosition.y + 0.5F, targetBlockPosition.z + 0.5F);
BlockMountAPI.BlockMountResult result = BlockMountAPI.mountOnBlock(ref, commandBuffer, pos, whereWasHit); BlockMountAPI.BlockMountResult result = BlockMountAPI.mountOnBlock(ref, commandBuffer, pos, whereWasHit);
if (result instanceof BlockMountAPI.DidNotMount) { if (result instanceof BlockMountAPI.DidNotMount) {
player.sendMessage(Message.translation("server.interactions.didNotMount").param("state", result.toString())); playerComponent.sendMessage(Message.translation("server.interactions.didNotMount").param("state", result.toString()));
} else if (result instanceof BlockMountAPI.Mounted) { } else if (result instanceof BlockMountAPI.Mounted) {
commandBuffer.putComponent(ref, PlayerSomnolence.getComponentType(), PlayerSleep.NoddingOff.createComponent()); commandBuffer.putComponent(ref, PlayerSomnolence.getComponentType(), PlayerSleep.NoddingOff.createComponent());
commandBuffer.run(s -> SleepNotificationSystem.maybeDoNotification(s, false));
} }
} else if (ownerUUID != null) { } else if (ownerUUID != null) {
player.sendMessage(MESSAGE_SERVER_CUSTOM_UI_RESPAWN_POINT_CLAIMED); playerComponent.sendMessage(MESSAGE_SERVER_CUSTOM_UI_RESPAWN_POINT_CLAIMED);
} else { } else {
PlayerRespawnPointData[] respawnPoints = player.getPlayerConfigData().getPerWorldData(world.getName()).getRespawnPoints(); PlayerRespawnPointData[] respawnPoints = playerComponent.getPlayerConfigData()
.getPerWorldData(world.getName())
.getRespawnPoints();
RespawnConfig respawnConfig = world.getGameplayConfig().getRespawnConfig(); RespawnConfig respawnConfig = world.getGameplayConfig().getRespawnConfig();
int radiusLimitRespawnPoint = respawnConfig.getRadiusLimitRespawnPoint(); int radiusLimitRespawnPoint = respawnConfig.getRadiusLimitRespawnPoint();
PlayerRespawnPointData[] nearbyRespawnPoints = getNearbySavedRespawnPoints(pos, respawnPoints, radiusLimitRespawnPoint); PlayerRespawnPointData[] nearbyRespawnPoints = getNearbySavedRespawnPoints(pos, respawnPoints, radiusLimitRespawnPoint);
@@ -129,6 +128,9 @@ public class BedInteraction extends SimpleBlockInteraction {
} }
} }
} }
}
}
}
@Override @Override
protected void simulateInteractWithBlock( protected void simulateInteractWithBlock(

View File

@@ -50,13 +50,9 @@ public class OverrideNearbyRespawnPointPage extends RespawnPointPage {
) { ) {
commandBuilder.append("Pages/OverrideNearbyRespawnPointPage.ui"); commandBuilder.append("Pages/OverrideNearbyRespawnPointPage.ui");
HeadRotation headRotationComponent = store.getComponent(ref, HeadRotation.getComponentType()); HeadRotation headRotationComponent = store.getComponent(ref, HeadRotation.getComponentType());
if (headRotationComponent != null) {
assert headRotationComponent != null;
PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType()); PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
if (playerRefComponent != null) {
assert playerRefComponent != null;
double direction = Math.toDegrees(headRotationComponent.getRotation().getYaw()); double direction = Math.toDegrees(headRotationComponent.getRotation().getYaw());
commandBuilder.set( commandBuilder.set(
"#DescriptionLabel.Text", "#DescriptionLabel.Text",
@@ -72,16 +68,21 @@ public class OverrideNearbyRespawnPointPage extends RespawnPointPage {
commandBuilder.set(selector + ".Disabled", true); commandBuilder.set(selector + ".Disabled", true);
commandBuilder.set(selector + " #Name.Text", nearbyRespawnPoint.getName()); commandBuilder.set(selector + " #Name.Text", nearbyRespawnPoint.getName());
Vector3i nearbyRespawnPointPosition = nearbyRespawnPoint.getBlockPosition(); Vector3i nearbyRespawnPointPosition = nearbyRespawnPoint.getBlockPosition();
int distance = (int)this.respawnPointPosition.distanceTo(nearbyRespawnPointPosition.x, this.respawnPointPosition.y, nearbyRespawnPointPosition.z); int distance = (int)this.respawnPointPosition
.distanceTo(nearbyRespawnPointPosition.x, this.respawnPointPosition.y, nearbyRespawnPointPosition.z);
commandBuilder.set(selector + " #Distance.Text", Message.translation("server.customUI.respawnPointDistance").param("distance", distance)); commandBuilder.set(selector + " #Distance.Text", Message.translation("server.customUI.respawnPointDistance").param("distance", distance));
double angle = Math.atan2(nearbyRespawnPointPosition.z - this.respawnPointPosition.z, nearbyRespawnPointPosition.x - this.respawnPointPosition.x); double angle = Math.atan2(nearbyRespawnPointPosition.z - this.respawnPointPosition.z, nearbyRespawnPointPosition.x - this.respawnPointPosition.x);
commandBuilder.set(selector + " #Icon.Angle", Math.toDegrees(angle) + direction + 90.0); commandBuilder.set(selector + " #Icon.Angle", Math.toDegrees(angle) + direction + 90.0);
} }
commandBuilder.set("#NameInput.Value", Message.translation("server.customUI.defaultRespawnPointName").param("name", playerRefComponent.getUsername())); commandBuilder.set(
"#NameInput.Value", Message.translation("server.customUI.defaultRespawnPointName").param("name", playerRefComponent.getUsername())
);
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ConfirmButton", EventData.of("@RespawnPointName", "#NameInput.Value")); eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ConfirmButton", EventData.of("@RespawnPointName", "#NameInput.Value"));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#CancelButton", EventData.of("Action", "Cancel")); eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#CancelButton", EventData.of("Action", "Cancel"));
} }
}
}
public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull RespawnPointPage.RespawnPointEventData data) { public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull RespawnPointPage.RespawnPointEventData data) {
String respawnPointName = data.getRespawnPointName(); String respawnPointName = data.getRespawnPointName();

View File

@@ -65,9 +65,7 @@ public abstract class RespawnPointPage extends InteractiveCustomUIPage<RespawnPo
respawnBlock.setOwnerUUID(this.playerRef.getUuid()); respawnBlock.setOwnerUUID(this.playerRef.getUuid());
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
Player playerComponent = store.getComponent(ref, Player.getComponentType()); Player playerComponent = store.getComponent(ref, Player.getComponentType());
if (playerComponent != null) {
assert playerComponent != null;
long chunkIndex = ChunkUtil.indexChunkFromBlock(blockPosition.x, blockPosition.z); long chunkIndex = ChunkUtil.indexChunkFromBlock(blockPosition.x, blockPosition.z);
WorldChunk chunk = world.getChunkIfInMemory(chunkIndex); WorldChunk chunk = world.getChunkIfInMemory(chunkIndex);
if (chunk != null) { if (chunk != null) {
@@ -112,6 +110,7 @@ public abstract class RespawnPointPage extends InteractiveCustomUIPage<RespawnPo
} }
} }
} }
}
@Nonnull @Nonnull
private static PlayerRespawnPointData[] handleRespawnPointsToRemove( private static PlayerRespawnPointData[] handleRespawnPointsToRemove(

View File

@@ -56,13 +56,9 @@ public class SelectOverrideRespawnPointPage extends RespawnPointPage {
commandBuilder.append("Pages/SelectOverrideRespawnPointPage.ui"); commandBuilder.append("Pages/SelectOverrideRespawnPointPage.ui");
commandBuilder.clear("#RespawnPointList"); commandBuilder.clear("#RespawnPointList");
PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType()); PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
if (playerRefComponent != null) {
assert playerRefComponent != null;
HeadRotation rotationComponent = store.getComponent(ref, HeadRotation.getComponentType()); HeadRotation rotationComponent = store.getComponent(ref, HeadRotation.getComponentType());
if (rotationComponent != null) {
assert rotationComponent != null;
float lookYaw = rotationComponent.getRotation().getYaw(); float lookYaw = rotationComponent.getRotation().getYaw();
double direction = Math.toDegrees(lookYaw); double direction = Math.toDegrees(lookYaw);
@@ -79,10 +75,14 @@ public class SelectOverrideRespawnPointPage extends RespawnPointPage {
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, selector, EventData.of("Index", Integer.toString(i)), false); eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, selector, EventData.of("Index", Integer.toString(i)), false);
} }
commandBuilder.set("#NameInput.Value", Message.translation("server.customUI.defaultRespawnPointName").param("name", playerRefComponent.getUsername())); commandBuilder.set(
"#NameInput.Value", Message.translation("server.customUI.defaultRespawnPointName").param("name", playerRefComponent.getUsername())
);
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ConfirmButton", EventData.of("@RespawnPointName", "#NameInput.Value")); eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ConfirmButton", EventData.of("@RespawnPointName", "#NameInput.Value"));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#CancelButton", EventData.of("Action", "Cancel")); eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#CancelButton", EventData.of("Action", "Cancel"));
} }
}
}
public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull RespawnPointPage.RespawnPointEventData data) { public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull RespawnPointPage.RespawnPointEventData data) {
if (data.getIndex() != -1) { if (data.getIndex() != -1) {

View File

@@ -38,13 +38,9 @@ public class SetNameRespawnPointPage extends RespawnPointPage {
) { ) {
commandBuilder.append("Pages/NameRespawnPointPage.ui"); commandBuilder.append("Pages/NameRespawnPointPage.ui");
Player playerComponent = store.getComponent(ref, Player.getComponentType()); Player playerComponent = store.getComponent(ref, Player.getComponentType());
if (playerComponent != null) {
assert playerComponent != null;
PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType()); PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
if (playerRefComponent != null) {
assert playerRefComponent != null;
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
PlayerRespawnPointData[] respawnPoints = playerComponent.getPlayerConfigData().getPerWorldData(world.getName()).getRespawnPoints(); PlayerRespawnPointData[] respawnPoints = playerComponent.getPlayerConfigData().getPerWorldData(world.getName()).getRespawnPoints();
String respawnPointName = null; String respawnPointName = null;
@@ -58,7 +54,9 @@ public class SetNameRespawnPointPage extends RespawnPointPage {
} }
if (respawnPointName == null) { if (respawnPointName == null) {
commandBuilder.set("#NameInput.Value", Message.translation("server.customUI.defaultRespawnPointName").param("name", playerRefComponent.getUsername())); commandBuilder.set(
"#NameInput.Value", Message.translation("server.customUI.defaultRespawnPointName").param("name", playerRefComponent.getUsername())
);
} else { } else {
commandBuilder.set("#NameInput.Value", respawnPointName); commandBuilder.set("#NameInput.Value", respawnPointName);
} }
@@ -66,6 +64,8 @@ public class SetNameRespawnPointPage extends RespawnPointPage {
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#SetButton", EventData.of("@RespawnPointName", "#NameInput.Value")); eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#SetButton", EventData.of("@RespawnPointName", "#NameInput.Value"));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#CancelButton", EventData.of("Action", "Cancel")); eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#CancelButton", EventData.of("Action", "Cancel"));
} }
}
}
public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull RespawnPointPage.RespawnPointEventData data) { public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull RespawnPointPage.RespawnPointEventData data) {
String respawnPointName = data.getRespawnPointName(); String respawnPointName = data.getRespawnPointName();

View File

@@ -1,21 +1,33 @@
package com.hypixel.hytale.builtin.beds.sleep.components; package com.hypixel.hytale.builtin.beds.sleep.components;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource; import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public sealed interface PlayerSleep permits PlayerSleep.FullyAwake, PlayerSleep.MorningWakeUp, PlayerSleep.NoddingOff, PlayerSleep.Slumber { public sealed interface PlayerSleep permits PlayerSleep.FullyAwake, PlayerSleep.MorningWakeUp, PlayerSleep.NoddingOff, PlayerSleep.Slumber {
public static enum FullyAwake implements PlayerSleep { public static enum FullyAwake implements PlayerSleep {
INSTANCE; INSTANCE;
} }
public record MorningWakeUp(Instant gameTimeStart) implements PlayerSleep { public record MorningWakeUp(@Nullable Instant gameTimeStart) implements PlayerSleep {
private static final Duration WAKE_UP_AUTOSLEEP_DELAY = Duration.ofHours(1L);
@Nonnull @Nonnull
public static PlayerSomnolence createComponent(@Nonnull WorldTimeResource worldTimeResource) { public static PlayerSomnolence createComponent(@Nullable Instant gameTimeStart) {
Instant now = worldTimeResource.getGameTime(); PlayerSleep.MorningWakeUp state = new PlayerSleep.MorningWakeUp(gameTimeStart);
PlayerSleep.MorningWakeUp state = new PlayerSleep.MorningWakeUp(now);
return new PlayerSomnolence(state); return new PlayerSomnolence(state);
} }
public boolean isReadyToSleepAgain(Instant worldTime) {
if (this.gameTimeStart == null) {
return true;
} else {
Instant readyTime = worldTime.plus(WAKE_UP_AUTOSLEEP_DELAY);
return worldTime.isAfter(readyTime);
}
}
} }
public record NoddingOff(Instant realTimeStart) implements PlayerSleep { public record NoddingOff(Instant realTimeStart) implements PlayerSleep {

View File

@@ -10,6 +10,7 @@ import javax.annotation.Nullable;
public class WorldSomnolence implements Resource<EntityStore> { public class WorldSomnolence implements Resource<EntityStore> {
@Nonnull @Nonnull
private WorldSleep state = WorldSleep.Awake.INSTANCE; private WorldSleep state = WorldSleep.Awake.INSTANCE;
private long lastSleepNotification;
public static ResourceType<EntityStore, WorldSomnolence> getResourceType() { public static ResourceType<EntityStore, WorldSomnolence> getResourceType() {
return BedsPlugin.getInstance().getWorldSomnolenceResourceType(); return BedsPlugin.getInstance().getWorldSomnolenceResourceType();
@@ -24,6 +25,21 @@ public class WorldSomnolence implements Resource<EntityStore> {
this.state = state; this.state = state;
} }
public boolean useSleepNotificationCooldown(long now, long cooldownMs) {
long elapsedMs = now - this.lastSleepNotification;
boolean ready = elapsedMs >= cooldownMs;
if (ready) {
this.lastSleepNotification = now;
return true;
} else {
return false;
}
}
public void resetNotificationCooldown() {
this.lastSleepNotification = 0L;
}
@Nullable @Nullable
@Override @Override
public Resource<EntityStore> clone() { public Resource<EntityStore> clone() {

View File

@@ -9,9 +9,11 @@ import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.RefChangeSystem; import com.hypixel.hytale.component.system.RefChangeSystem;
import com.hypixel.hytale.protocol.BlockMountType; import com.hypixel.hytale.protocol.BlockMountType;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.type.gameplay.SleepConfig; import com.hypixel.hytale.server.core.asset.type.gameplay.sleep.SleepConfig;
import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.time.Duration; import java.time.Duration;
@@ -28,23 +30,36 @@ public class EnterBedSystem extends RefChangeSystem<EntityStore, MountedComponen
@Nonnull @Nonnull
private static final Message MESSAGE_SERVER_INTERACTIONS_SLEEP_DISABLED = Message.translation("server.interactions.sleep.disabled"); private static final Message MESSAGE_SERVER_INTERACTIONS_SLEEP_DISABLED = Message.translation("server.interactions.sleep.disabled");
@Nonnull @Nonnull
private static final Query<EntityStore> QUERY = Query.and(MountedComponent.getComponentType(), PlayerRef.getComponentType()); private final ComponentType<EntityStore, MountedComponent> mountedComponentType;
@Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final Query<EntityStore> query;
public EnterBedSystem(
@Nonnull ComponentType<EntityStore, MountedComponent> mountedComponentType, @Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType
) {
this.mountedComponentType = mountedComponentType;
this.playerRefComponentType = playerRefComponentType;
this.query = Query.and(mountedComponentType, playerRefComponentType);
}
@Nonnull @Nonnull
@Override @Override
public ComponentType<EntityStore, MountedComponent> componentType() { public ComponentType<EntityStore, MountedComponent> componentType() {
return MountedComponent.getComponentType(); return this.mountedComponentType;
} }
@Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return QUERY; return this.query;
} }
public void onComponentAdded( public void onComponentAdded(
@Nonnull Ref<EntityStore> ref, @Nonnull MountedComponent component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull Ref<EntityStore> ref, @Nonnull MountedComponent component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
check(ref, component, store); check(ref, component, store, this.playerRefComponentType);
} }
public void onComponentSet( public void onComponentSet(
@@ -54,7 +69,7 @@ public class EnterBedSystem extends RefChangeSystem<EntityStore, MountedComponen
@Nonnull Store<EntityStore> store, @Nonnull Store<EntityStore> store,
@Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
check(ref, newComponent, store); check(ref, newComponent, store, this.playerRefComponentType);
} }
public void onComponentRemoved( public void onComponentRemoved(
@@ -62,30 +77,38 @@ public class EnterBedSystem extends RefChangeSystem<EntityStore, MountedComponen
) { ) {
} }
public static void check(@Nonnull Ref<EntityStore> ref, @Nonnull MountedComponent component, @Nonnull Store<EntityStore> store) { private static void check(
@Nonnull Ref<EntityStore> ref,
@Nonnull MountedComponent component,
@Nonnull Store<EntityStore> store,
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType
) {
if (component.getBlockMountType() == BlockMountType.Bed) { if (component.getBlockMountType() == BlockMountType.Bed) {
onEnterBed(ref, store); onEnterBed(ref, store, playerRefComponentType);
} }
} }
public static void onEnterBed(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) { private static void onEnterBed(
@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType
) {
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
CanSleepInWorld.Result canSleepResult = CanSleepInWorld.check(world); CanSleepInWorld.Result canSleepResult = CanSleepInWorld.check(world);
if (canSleepResult.isNegative()) { if (canSleepResult.isNegative()) {
PlayerRef playerRef = store.getComponent(ref, PlayerRef.getComponentType()); PlayerRef playerRefComponent = store.getComponent(ref, playerRefComponentType);
assert playerRef != null; assert playerRefComponent != null;
if (canSleepResult instanceof CanSleepInWorld.NotDuringSleepHoursRange(LocalDateTime msg, SleepConfig var13)) { if (canSleepResult instanceof CanSleepInWorld.NotDuringSleepHoursRange(LocalDateTime msg, SleepConfig var14)) {
LocalTime startTime = var13.getSleepStartTime(); LocalTime startTime = var14.getSleepStartTime();
Duration untilSleep = var13.computeDurationUntilSleep(msg); Duration untilSleep = var14.computeDurationUntilSleep(msg);
Message msgx = Message.translation("server.interactions.sleep.sleepAtTheseHours") Message msgx = Message.translation("server.interactions.sleep.sleepAtTheseHours")
.param("timeValue", startTime.toString()) .param("timeValue", startTime.toString())
.param("until", formatDuration(untilSleep)); .param("until", formatDuration(untilSleep));
playerRef.sendMessage(msgx.color("#F2D729")); playerRefComponent.sendMessage(msgx.color("#F2D729"));
SoundUtil.playSoundEvent2dToPlayer(playerRefComponent, var14.getSounds().getFailIndex(), SoundCategory.UI);
} else { } else {
Message msg = getMessage(canSleepResult); Message msg = getMessage(canSleepResult);
playerRef.sendMessage(msg); playerRefComponent.sendMessage(msg);
} }
} }
} }

View File

@@ -2,6 +2,7 @@ package com.hypixel.hytale.builtin.beds.sleep.systems.player;
import com.hypixel.hytale.builtin.beds.sleep.components.SleepTracker; import com.hypixel.hytale.builtin.beds.sleep.components.SleepTracker;
import com.hypixel.hytale.component.AddReason; import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Holder; import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.RemoveReason; import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
@@ -10,21 +11,32 @@ import com.hypixel.hytale.component.system.HolderSystem;
import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class RegisterTrackerSystem extends HolderSystem<EntityStore> { public class RegisterTrackerSystem extends HolderSystem<EntityStore> {
@Nonnull
private final ComponentType<EntityStore, SleepTracker> sleepTrackerComponentType;
@Nonnull
private final Query<EntityStore> query;
public RegisterTrackerSystem(
@Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType, @Nonnull ComponentType<EntityStore, SleepTracker> sleepTrackerComponentType
) {
this.sleepTrackerComponentType = sleepTrackerComponentType;
this.query = playerRefComponentType;
}
@Override @Override
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) { public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
holder.ensureComponent(SleepTracker.getComponentType()); holder.ensureComponent(this.sleepTrackerComponentType);
} }
@Override @Override
public void onEntityRemoved(@Nonnull Holder<EntityStore> holder, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store) { public void onEntityRemoved(@Nonnull Holder<EntityStore> holder, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store) {
} }
@Nullable @Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return PlayerRef.getComponentType(); return this.query;
} }
} }

View File

@@ -0,0 +1,174 @@
package com.hypixel.hytale.builtin.beds.sleep.systems.player;
import com.hypixel.hytale.builtin.beds.sleep.components.PlayerSomnolence;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSleep;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSlumber;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence;
import com.hypixel.hytale.builtin.beds.sleep.systems.world.CanSleepInWorld;
import com.hypixel.hytale.builtin.beds.sleep.systems.world.StartSlumberSystem;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.system.DelayedSystem;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.type.gameplay.sleep.SleepSoundsConfig;
import com.hypixel.hytale.server.core.modules.entity.component.DisplayNameComponent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
import org.checkerframework.checker.nullness.compatqual.NonNullDecl;
public class SleepNotificationSystem extends DelayedSystem<EntityStore> {
public static final int SMALL_SERVER_PLAYER_COUNT = 4;
public static final double BIG_SERVER_SLEEPERS_RATIO = 0.5;
public static final String COLOR = "#5AB5B5";
public SleepNotificationSystem() {
super(1.0F);
}
@Override
public void delayedTick(float dt, int systemIndex, @NonNullDecl Store<EntityStore> store) {
World world = store.getExternalData().getWorld();
SleepSoundsConfig sleepSounds = world.getGameplayConfig().getWorldConfig().getSleepConfig().getSounds();
if (sleepSounds.isNotificationLoopEnabled()) {
maybeDoNotification(store, true);
}
}
public static void maybeDoNotification(Store<EntityStore> store, boolean fromAutoLoop) {
World world = store.getExternalData().getWorld();
SleepSoundsConfig sleepSounds = world.getGameplayConfig().getWorldConfig().getSleepConfig().getSounds();
SleepNotificationSystem.NotificationState state = getNotificationState(world);
if (state != SleepNotificationSystem.NotReady.INSTANCE) {
long now = System.currentTimeMillis();
WorldSomnolence worldSomnolence = store.getResource(WorldSomnolence.getResourceType());
if (worldSomnolence.useSleepNotificationCooldown(now, sleepSounds.getNotificationLoopCooldownMs())) {
int soundIndex = fromAutoLoop ? sleepSounds.getNotificationLoopIndex() : sleepSounds.getNotificationIndex();
Collection<PlayerRef> playerRefs = world.getPlayerRefs();
for (PlayerRef playerRef : playerRefs) {
Ref<EntityStore> ref = playerRef.getReference();
if (ref != null && !StartSlumberSystem.canNotifyOthersAboutTryingToSleep(store, ref)) {
SoundUtil.playSoundEvent2dToPlayer(playerRef, soundIndex, SoundCategory.UI);
if (state instanceof SleepNotificationSystem.SmallServer) {
if (state.readyToSleep() == 1) {
Message sleeperName = playerRefs.stream()
.map(PlayerRef::getReference)
.filter(r -> StartSlumberSystem.canNotifyOthersAboutTryingToSleep(store, (Ref<EntityStore>)r))
.map(SleepNotificationSystem::getSleeperName)
.findFirst()
.orElseGet(() -> Message.raw("???"));
String msgKey = fromAutoLoop ? "server.interactions.sleep.notificationSingle" : "server.interactions.sleep.notificationSingleEnter";
playerRef.sendMessage(Message.translation(msgKey).color("#5AB5B5").param("player", sleeperName));
} else {
playerRef.sendMessage(
Message.translation("server.interactions.sleep.notificationSmall").color("#5AB5B5").param("sleepers", state.readyToSleep())
);
}
} else if (state instanceof SleepNotificationSystem.BigServer) {
playerRef.sendMessage(
Message.translation("server.interactions.sleep.notificationBig")
.color("#5AB5B5")
.param("sleepers", state.readyToSleep())
.param("total", state.playerCount())
);
}
}
}
}
}
}
private static SleepNotificationSystem.NotificationState getNotificationState(World world) {
if (CanSleepInWorld.check(world).isNegative()) {
return SleepNotificationSystem.NotReady.INSTANCE;
} else {
Store<EntityStore> store = world.getEntityStore().getStore();
WorldSleep worldSleep = store.getResource(WorldSomnolence.getResourceType()).getState();
if (worldSleep instanceof WorldSlumber) {
return SleepNotificationSystem.NotReady.INSTANCE;
} else {
List<Ref<EntityStore>> refs = world.getPlayerRefs().stream().map(PlayerRef::getReference).filter(Objects::nonNull).toList();
int playerCount = refs.size();
int readyToSleep = countReadyToSleep(refs, store);
if (playerCount <= 4) {
boolean ready = readyToSleep > 0;
return (SleepNotificationSystem.NotificationState)(ready
? new SleepNotificationSystem.SmallServer(readyToSleep, playerCount)
: SleepNotificationSystem.NotReady.INSTANCE);
} else {
double sleepersRatio = (double)readyToSleep / playerCount;
boolean ready = sleepersRatio >= 0.5;
return (SleepNotificationSystem.NotificationState)(ready
? new SleepNotificationSystem.BigServer(sleepersRatio, readyToSleep, playerCount)
: SleepNotificationSystem.NotReady.INSTANCE);
}
}
}
}
private static int countReadyToSleep(Collection<Ref<EntityStore>> playerRefs, ComponentAccessor<EntityStore> store) {
int count = 0;
for (Ref<EntityStore> ref : playerRefs) {
PlayerSomnolence somnolence = store.getComponent(ref, PlayerSomnolence.getComponentType());
if (somnolence != null) {
boolean readyToSleep = StartSlumberSystem.canNotifyOthersAboutTryingToSleep(store, ref);
if (readyToSleep) {
count++;
}
}
}
return count;
}
public static Message getSleeperName(@Nullable Ref<EntityStore> ref) {
if (ref != null && ref.isValid()) {
Store<EntityStore> store = ref.getStore();
DisplayNameComponent displayNameComponent = store.getComponent(ref, DisplayNameComponent.getComponentType());
Message lastSleeperDisplay = displayNameComponent == null ? null : displayNameComponent.getDisplayName();
if (lastSleeperDisplay != null) {
return lastSleeperDisplay;
} else {
PlayerRef sleeperPlayerRef = store.getComponent(ref, PlayerRef.getComponentType());
return Message.raw(sleeperPlayerRef == null ? "???" : sleeperPlayerRef.getUsername());
}
} else {
return Message.raw("???");
}
}
private record BigServer(double ratio, int readyToSleep, int playerCount) implements SleepNotificationSystem.NotificationState {
}
private static enum NotReady implements SleepNotificationSystem.NotificationState {
INSTANCE;
@Override
public int readyToSleep() {
return 0;
}
@Override
public int playerCount() {
return 0;
}
}
private sealed interface NotificationState permits SleepNotificationSystem.NotReady, SleepNotificationSystem.SmallServer, SleepNotificationSystem.BigServer {
int readyToSleep();
int playerCount();
}
private record SmallServer(int readyToSleep, int playerCount) implements SleepNotificationSystem.NotificationState {
}
}

View File

@@ -10,13 +10,16 @@ import com.hypixel.hytale.builtin.beds.sleep.systems.world.CanSleepInWorld;
import com.hypixel.hytale.builtin.beds.sleep.systems.world.StartSlumberSystem; import com.hypixel.hytale.builtin.beds.sleep.systems.world.StartSlumberSystem;
import com.hypixel.hytale.component.ArchetypeChunk; import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.tick.DelayedEntitySystem; import com.hypixel.hytale.component.system.tick.DelayedEntitySystem;
import com.hypixel.hytale.protocol.packets.world.SleepClock; import com.hypixel.hytale.protocol.packets.world.SleepClock;
import com.hypixel.hytale.protocol.packets.world.SleepMultiplayer; import com.hypixel.hytale.protocol.packets.world.SleepMultiplayer;
import com.hypixel.hytale.protocol.packets.world.UpdateSleepState; import com.hypixel.hytale.protocol.packets.world.UpdateSleepState;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
@@ -30,23 +33,47 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class UpdateSleepPacketSystem extends DelayedEntitySystem<EntityStore> { public class UpdateSleepPacketSystem extends DelayedEntitySystem<EntityStore> {
private static final int MAX_SAMPLE_COUNT = 5;
private static final float SYSTEM_INTERVAL_S = 0.25F;
@Nonnull @Nonnull
public static final Query<EntityStore> QUERY = Query.and(PlayerRef.getComponentType(), PlayerSomnolence.getComponentType(), SleepTracker.getComponentType()); private static final Duration SPAN_BEFORE_BLACK_SCREEN = Duration.ofMillis(1200L);
public static final Duration SPAN_BEFORE_BLACK_SCREEN = Duration.ofMillis(1200L);
public static final int MAX_SAMPLE_COUNT = 5;
@Nonnull @Nonnull
private static final UUID[] EMPTY_UUIDS = new UUID[0]; private static final UUID[] EMPTY_UUIDS = new UUID[0];
@Nonnull @Nonnull
private static final UpdateSleepState PACKET_NO_SLEEP_UI = new UpdateSleepState(false, false, null, null); private static final UpdateSleepState PACKET_NO_SLEEP_UI = new UpdateSleepState(false, false, null, null);
private static final float SYSTEM_INTERVAL_S = 0.25F; @Nonnull
private final ComponentType<EntityStore, PlayerRef> playerRefComponentType;
@Nonnull
private final ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType;
@Nonnull
private final ComponentType<EntityStore, SleepTracker> sleepTrackerComponentType;
@Nonnull
private final ResourceType<EntityStore, WorldSomnolence> worldSomnolenceResourceType;
@Nonnull
private final ResourceType<EntityStore, WorldTimeResource> worldTimeResourceType;
@Nonnull
private final Query<EntityStore> query;
@Override public UpdateSleepPacketSystem(
public Query<EntityStore> getQuery() { @Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType,
return QUERY; @Nonnull ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType,
@Nonnull ComponentType<EntityStore, SleepTracker> sleepTrackerComponentType,
@Nonnull ResourceType<EntityStore, WorldSomnolence> worldSomnolenceResourceType,
@Nonnull ResourceType<EntityStore, WorldTimeResource> worldTimeResourceType
) {
super(0.25F);
this.playerRefComponentType = playerRefComponentType;
this.playerSomnolenceComponentType = playerSomnolenceComponentType;
this.sleepTrackerComponentType = sleepTrackerComponentType;
this.worldSomnolenceResourceType = worldSomnolenceResourceType;
this.worldTimeResourceType = worldTimeResourceType;
this.query = Query.and(playerRefComponentType, playerSomnolenceComponentType, sleepTrackerComponentType);
} }
public UpdateSleepPacketSystem() { @Nonnull
super(0.25F); @Override
public Query<EntityStore> getQuery() {
return this.query;
} }
@Override @Override
@@ -58,13 +85,13 @@ public class UpdateSleepPacketSystem extends DelayedEntitySystem<EntityStore> {
@Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
UpdateSleepState packet = this.createSleepPacket(store, index, archetypeChunk); UpdateSleepState packet = this.createSleepPacket(store, index, archetypeChunk);
SleepTracker sleepTrackerComponent = archetypeChunk.getComponent(index, SleepTracker.getComponentType()); SleepTracker sleepTrackerComponent = archetypeChunk.getComponent(index, this.sleepTrackerComponentType);
assert sleepTrackerComponent != null; assert sleepTrackerComponent != null;
packet = sleepTrackerComponent.generatePacketToSend(packet); packet = sleepTrackerComponent.generatePacketToSend(packet);
if (packet != null) { if (packet != null) {
PlayerRef playerRefComponent = archetypeChunk.getComponent(index, PlayerRef.getComponentType()); PlayerRef playerRefComponent = archetypeChunk.getComponent(index, this.playerRefComponentType);
assert playerRefComponent != null; assert playerRefComponent != null;
@@ -75,9 +102,9 @@ public class UpdateSleepPacketSystem extends DelayedEntitySystem<EntityStore> {
@Nonnull @Nonnull
private UpdateSleepState createSleepPacket(@Nonnull Store<EntityStore> store, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk) { private UpdateSleepState createSleepPacket(@Nonnull Store<EntityStore> store, int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk) {
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
WorldSomnolence worldSomnolence = store.getResource(WorldSomnolence.getResourceType()); WorldSomnolence worldSomnolenceResource = store.getResource(this.worldSomnolenceResourceType);
WorldSleep worldSleepState = worldSomnolence.getState(); WorldSleep worldSleepState = worldSomnolenceResource.getState();
PlayerSomnolence playerSomnolenceComponent = archetypeChunk.getComponent(index, PlayerSomnolence.getComponentType()); PlayerSomnolence playerSomnolenceComponent = archetypeChunk.getComponent(index, this.playerSomnolenceComponentType);
assert playerSomnolenceComponent != null; assert playerSomnolenceComponent != null;
@@ -118,6 +145,7 @@ public class UpdateSleepPacketSystem extends DelayedEntitySystem<EntityStore> {
for (PlayerRef playerRef : playerRefs) { for (PlayerRef playerRef : playerRefs) {
Ref<EntityStore> ref = playerRef.getReference(); Ref<EntityStore> ref = playerRef.getReference();
if (ref != null && ref.isValid()) {
boolean readyToSleep = StartSlumberSystem.isReadyToSleep(store, ref); boolean readyToSleep = StartSlumberSystem.isReadyToSleep(store, ref);
if (readyToSleep) { if (readyToSleep) {
sleepersCount++; sleepersCount++;
@@ -126,6 +154,7 @@ public class UpdateSleepPacketSystem extends DelayedEntitySystem<EntityStore> {
awakeSampleList.add(playerRef.getUuid()); awakeSampleList.add(playerRef.getUuid());
} }
} }
}
UUID[] awakeSample = awakeSampleList.size() > 5 ? EMPTY_UUIDS : awakeSampleList.toArray(UUID[]::new); UUID[] awakeSample = awakeSampleList.size() > 5 ? EMPTY_UUIDS : awakeSampleList.toArray(UUID[]::new);
return new SleepMultiplayer(sleepersCount, awakeCount, awakeSample); return new SleepMultiplayer(sleepersCount, awakeCount, awakeSample);

View File

@@ -15,14 +15,28 @@ import javax.annotation.Nullable;
public class WakeUpOnDismountSystem extends RefChangeSystem<EntityStore, MountedComponent> { public class WakeUpOnDismountSystem extends RefChangeSystem<EntityStore, MountedComponent> {
@Nonnull @Nonnull
@Override private final ComponentType<EntityStore, MountedComponent> mountedComponentType;
public ComponentType<EntityStore, MountedComponent> componentType() { @Nonnull
return MountedComponent.getComponentType(); private final ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType;
public WakeUpOnDismountSystem(
@Nonnull ComponentType<EntityStore, MountedComponent> mountedComponentType,
@Nonnull ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType
) {
this.mountedComponentType = mountedComponentType;
this.playerSomnolenceComponentType = playerSomnolenceComponentType;
} }
@Nonnull
@Override
public ComponentType<EntityStore, MountedComponent> componentType() {
return this.mountedComponentType;
}
@Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return MountedComponent.getComponentType(); return this.mountedComponentType;
} }
public void onComponentAdded( public void onComponentAdded(
@@ -43,7 +57,7 @@ public class WakeUpOnDismountSystem extends RefChangeSystem<EntityStore, Mounted
@Nonnull Ref<EntityStore> ref, @Nonnull MountedComponent component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer @Nonnull Ref<EntityStore> ref, @Nonnull MountedComponent component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer
) { ) {
if (component.getBlockMountType() == BlockMountType.Bed) { if (component.getBlockMountType() == BlockMountType.Bed) {
commandBuffer.putComponent(ref, PlayerSomnolence.getComponentType(), PlayerSomnolence.AWAKE); commandBuffer.putComponent(ref, this.playerSomnolenceComponentType, PlayerSomnolence.AWAKE);
} }
} }
} }

View File

@@ -1,7 +1,7 @@
package com.hypixel.hytale.builtin.beds.sleep.systems.world; package com.hypixel.hytale.builtin.beds.sleep.systems.world;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.asset.type.gameplay.SleepConfig; import com.hypixel.hytale.server.core.asset.type.gameplay.sleep.SleepConfig;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource; import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;

View File

@@ -6,11 +6,16 @@ import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSleep;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSlumber; import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSlumber;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence; import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence;
import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.system.DelayedSystem; import com.hypixel.hytale.component.system.DelayedSystem;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.server.core.asset.type.gameplay.sleep.SleepConfig;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource; import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.time.Duration; import java.time.Duration;
@@ -20,6 +25,7 @@ import java.time.ZoneOffset;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class StartSlumberSystem extends DelayedSystem<EntityStore> { public class StartSlumberSystem extends DelayedSystem<EntityStore> {
@Nonnull @Nonnull
@@ -27,9 +33,22 @@ public class StartSlumberSystem extends DelayedSystem<EntityStore> {
@Nonnull @Nonnull
private static final Duration WAKE_UP_AUTOSLEEP_DELAY = Duration.ofHours(1L); private static final Duration WAKE_UP_AUTOSLEEP_DELAY = Duration.ofHours(1L);
private static final float SYSTEM_INTERVAL_S = 0.3F; private static final float SYSTEM_INTERVAL_S = 0.3F;
@Nonnull
private final ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType;
@Nonnull
private final ResourceType<EntityStore, WorldSomnolence> worldSomnolenceResourceType;
@Nonnull
private final ResourceType<EntityStore, WorldTimeResource> worldTimeResourceType;
public StartSlumberSystem() { public StartSlumberSystem(
@Nonnull ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType,
@Nonnull ResourceType<EntityStore, WorldSomnolence> worldSomnolenceResourceType,
@Nonnull ResourceType<EntityStore, WorldTimeResource> worldTimeResourceType
) {
super(0.3F); super(0.3F);
this.playerSomnolenceComponentType = playerSomnolenceComponentType;
this.worldSomnolenceResourceType = worldSomnolenceResourceType;
this.worldTimeResourceType = worldTimeResourceType;
} }
@Override @Override
@@ -42,20 +61,26 @@ public class StartSlumberSystem extends DelayedSystem<EntityStore> {
Collection<PlayerRef> playerRefs = world.getPlayerRefs(); Collection<PlayerRef> playerRefs = world.getPlayerRefs();
if (!playerRefs.isEmpty()) { if (!playerRefs.isEmpty()) {
if (!CanSleepInWorld.check(world).isNegative()) { if (!CanSleepInWorld.check(world).isNegative()) {
float wakeUpHour = world.getGameplayConfig().getWorldConfig().getSleepConfig().getWakeUpHour(); SleepConfig sleepConfig = world.getGameplayConfig().getWorldConfig().getSleepConfig();
WorldSomnolence worldSomnolenceResource = store.getResource(WorldSomnolence.getResourceType()); float wakeUpHour = sleepConfig.getWakeUpHour();
WorldSomnolence worldSomnolenceResource = store.getResource(this.worldSomnolenceResourceType);
WorldSleep worldState = worldSomnolenceResource.getState(); WorldSleep worldState = worldSomnolenceResource.getState();
if (worldState == WorldSleep.Awake.INSTANCE) { if (worldState == WorldSleep.Awake.INSTANCE) {
if (isEveryoneReadyToSleep(store)) { if (this.isEveryoneReadyToSleep(store)) {
WorldTimeResource timeResource = store.getResource(WorldTimeResource.getResourceType()); WorldTimeResource timeResource = store.getResource(this.worldTimeResourceType);
Instant now = timeResource.getGameTime(); Instant now = timeResource.getGameTime();
Instant target = this.computeWakeupInstant(now, wakeUpHour); Instant target = this.computeWakeupInstant(now, wakeUpHour);
float irlSeconds = computeIrlSeconds(now, target); float irlSeconds = computeIrlSeconds(now, target);
worldSomnolenceResource.setState(new WorldSlumber(now, target, irlSeconds)); worldSomnolenceResource.setState(new WorldSlumber(now, target, irlSeconds));
store.forEachEntityParallel(PlayerSomnolence.getComponentType(), (index, archetypeChunk, commandBuffer) -> { store.forEachEntityParallel(this.playerSomnolenceComponentType, (index, archetypeChunk, commandBuffer) -> {
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index); Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
commandBuffer.putComponent(ref, PlayerSomnolence.getComponentType(), PlayerSleep.Slumber.createComponent(timeResource)); commandBuffer.putComponent(ref, this.playerSomnolenceComponentType, PlayerSleep.Slumber.createComponent(timeResource));
PlayerRef playerRef = archetypeChunk.getComponent(index, PlayerRef.getComponentType());
if (playerRef != null) {
SoundUtil.playSoundEvent2dToPlayer(playerRef, sleepConfig.getSounds().getSuccessIndex(), SoundCategory.UI);
}
}); });
worldSomnolenceResource.resetNotificationCooldown();
} }
} }
} }
@@ -81,7 +106,7 @@ public class StartSlumberSystem extends DelayedSystem<EntityStore> {
return (float)Math.ceil(seconds); return (float)Math.ceil(seconds);
} }
private static boolean isEveryoneReadyToSleep(@Nonnull ComponentAccessor<EntityStore> store) { private boolean isEveryoneReadyToSleep(@Nonnull ComponentAccessor<EntityStore> store) {
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
Collection<PlayerRef> playerRefs = world.getPlayerRefs(); Collection<PlayerRef> playerRefs = world.getPlayerRefs();
if (playerRefs.isEmpty()) { if (playerRefs.isEmpty()) {
@@ -98,31 +123,54 @@ public class StartSlumberSystem extends DelayedSystem<EntityStore> {
} }
} }
public static boolean isReadyToSleep(@Nonnull ComponentAccessor<EntityStore> store, @Nonnull Ref<EntityStore> ref) { public static boolean isReadyToSleep(@Nonnull ComponentAccessor<EntityStore> store, @Nullable Ref<EntityStore> ref) {
if (!ref.isValid()) { if (ref != null && ref.isValid()) {
return true; PlayerSomnolence somnolenceComponent = store.getComponent(ref, PlayerSomnolence.getComponentType());
} else { if (somnolenceComponent == null) {
PlayerSomnolence somnolence = store.getComponent(ref, PlayerSomnolence.getComponentType());
if (somnolence == null) {
return false; return false;
} else { } else {
PlayerSleep sleepState = somnolence.getSleepState(); PlayerSleep sleepState = somnolenceComponent.getSleepState();
return switch (sleepState) { return switch (sleepState) {
case PlayerSleep.FullyAwake ignored -> false; case PlayerSleep.FullyAwake fullAwake -> false;
case PlayerSleep.MorningWakeUp morningWakeUp -> { case PlayerSleep.MorningWakeUp morningWakeUp -> {
WorldTimeResource worldTimeResource = store.getResource(WorldTimeResource.getResourceType()); WorldTimeResource worldTimeResource = store.getResource(WorldTimeResource.getResourceType());
Instant readyTime = morningWakeUp.gameTimeStart().plus(WAKE_UP_AUTOSLEEP_DELAY); yield morningWakeUp.isReadyToSleepAgain(worldTimeResource.getGameTime());
yield worldTimeResource.getGameTime().isAfter(readyTime);
} }
case PlayerSleep.NoddingOff noddingOff -> { case PlayerSleep.NoddingOff noddingOff -> {
Instant sleepStart = noddingOff.realTimeStart().plus(NODDING_OFF_DURATION); Instant sleepStart = noddingOff.realTimeStart().plus(NODDING_OFF_DURATION);
yield Instant.now().isAfter(sleepStart); yield Instant.now().isAfter(sleepStart);
} }
case PlayerSleep.Slumber ignoredx -> true; case PlayerSleep.Slumber ignored -> true;
default -> throw new MatchException(null, null); default -> throw new MatchException(null, null);
}; };
} }
} else {
return true;
}
}
public static boolean canNotifyOthersAboutTryingToSleep(@Nonnull ComponentAccessor<EntityStore> store, @Nullable Ref<EntityStore> ref) {
if (ref != null && ref.isValid()) {
PlayerSomnolence somnolenceComponent = store.getComponent(ref, PlayerSomnolence.getComponentType());
if (somnolenceComponent == null) {
return false;
} else {
PlayerSleep sleepState = somnolenceComponent.getSleepState();
return switch (sleepState) {
case PlayerSleep.FullyAwake fullAwake -> false;
case PlayerSleep.MorningWakeUp morningWakeUp -> {
WorldTimeResource worldTimeResource = store.getResource(WorldTimeResource.getResourceType());
yield morningWakeUp.isReadyToSleepAgain(worldTimeResource.getGameTime());
}
case PlayerSleep.NoddingOff noddingOff -> true;
case PlayerSleep.Slumber ignored -> true;
default -> throw new MatchException(null, null);
};
}
} else {
return true;
} }
} }
} }

View File

@@ -6,7 +6,9 @@ import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSleep;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSlumber; import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSlumber;
import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence; import com.hypixel.hytale.builtin.beds.sleep.resources.WorldSomnolence;
import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.system.tick.TickingSystem; import com.hypixel.hytale.component.system.tick.TickingSystem;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource; import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
@@ -19,26 +21,47 @@ import java.util.Collection;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class UpdateWorldSlumberSystem extends TickingSystem<EntityStore> { public class UpdateWorldSlumberSystem extends TickingSystem<EntityStore> {
@Nonnull
private final ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType;
@Nonnull
private final ResourceType<EntityStore, WorldSomnolence> worldSomnolenceResourceType;
@Nonnull
private final ResourceType<EntityStore, WorldTimeResource> worldTimeResourceType;
public UpdateWorldSlumberSystem(
@Nonnull ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType,
@Nonnull ResourceType<EntityStore, WorldSomnolence> worldSomnolenceResourceType,
@Nonnull ResourceType<EntityStore, WorldTimeResource> worldTimeResourceType
) {
this.playerSomnolenceComponentType = playerSomnolenceComponentType;
this.worldSomnolenceResourceType = worldSomnolenceResourceType;
this.worldTimeResourceType = worldTimeResourceType;
}
@Override @Override
public void tick(float dt, int systemIndex, @Nonnull Store<EntityStore> store) { public void tick(float dt, int systemIndex, @Nonnull Store<EntityStore> store) {
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
WorldSomnolence worldSomnolence = store.getResource(WorldSomnolence.getResourceType()); WorldSomnolence worldSomnolenceResource = store.getResource(this.worldSomnolenceResourceType);
if (worldSomnolence.getState() instanceof WorldSlumber slumber) { if (worldSomnolenceResource.getState() instanceof WorldSlumber slumber) {
slumber.incrementProgressSeconds(dt); slumber.incrementProgressSeconds(dt);
boolean sleepingIsOver = slumber.getProgressSeconds() >= slumber.getIrlDurationSeconds() || isSomeoneAwake(store); boolean itsMorningTimeToWAKEUP = slumber.getProgressSeconds() >= slumber.getIrlDurationSeconds();
boolean someoneIsAwake = isSomeoneAwake(store, this.playerSomnolenceComponentType);
boolean sleepingIsOver = itsMorningTimeToWAKEUP || someoneIsAwake;
if (sleepingIsOver) { if (sleepingIsOver) {
worldSomnolence.setState(WorldSleep.Awake.INSTANCE); worldSomnolenceResource.setState(WorldSleep.Awake.INSTANCE);
WorldTimeResource timeResource = store.getResource(WorldTimeResource.getResourceType()); WorldTimeResource timeResource = store.getResource(this.worldTimeResourceType);
Instant now = timeResource.getGameTime();
Instant wakeUpTime = computeWakeupTime(slumber); Instant wakeUpTime = computeWakeupTime(slumber);
timeResource.setGameTime(wakeUpTime, world, store); timeResource.setGameTime(wakeUpTime, world, store);
store.forEachEntityParallel(PlayerSomnolence.getComponentType(), (index, archetypeChunk, commandBuffer) -> { store.forEachEntityParallel(this.playerSomnolenceComponentType, (index, archetypeChunk, commandBuffer) -> {
PlayerSomnolence somnolenceComponent = archetypeChunk.getComponent(index, PlayerSomnolence.getComponentType()); PlayerSomnolence somnolenceComponent = archetypeChunk.getComponent(index, this.playerSomnolenceComponentType);
assert somnolenceComponent != null; assert somnolenceComponent != null;
if (somnolenceComponent.getSleepState() instanceof PlayerSleep.Slumber) { if (somnolenceComponent.getSleepState() instanceof PlayerSleep.Slumber) {
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index); Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
commandBuffer.putComponent(ref, PlayerSomnolence.getComponentType(), PlayerSleep.MorningWakeUp.createComponent(timeResource)); PlayerSomnolence sleepComponent = PlayerSleep.MorningWakeUp.createComponent(itsMorningTimeToWAKEUP ? now : null);
commandBuffer.putComponent(ref, this.playerSomnolenceComponentType, sleepComponent);
} }
}); });
} }
@@ -53,7 +76,9 @@ public class UpdateWorldSlumberSystem extends TickingSystem<EntityStore> {
return slumber.getStartInstant().plusNanos(progressNanos); return slumber.getStartInstant().plusNanos(progressNanos);
} }
private static boolean isSomeoneAwake(@Nonnull ComponentAccessor<EntityStore> store) { private static boolean isSomeoneAwake(
@Nonnull ComponentAccessor<EntityStore> store, @Nonnull ComponentType<EntityStore, PlayerSomnolence> playerSomnolenceComponentType
) {
World world = store.getExternalData().getWorld(); World world = store.getExternalData().getWorld();
Collection<PlayerRef> playerRefs = world.getPlayerRefs(); Collection<PlayerRef> playerRefs = world.getPlayerRefs();
if (playerRefs.isEmpty()) { if (playerRefs.isEmpty()) {
@@ -62,7 +87,7 @@ public class UpdateWorldSlumberSystem extends TickingSystem<EntityStore> {
for (PlayerRef playerRef : playerRefs) { for (PlayerRef playerRef : playerRefs) {
Ref<EntityStore> ref = playerRef.getReference(); Ref<EntityStore> ref = playerRef.getReference();
if (ref != null && ref.isValid()) { if (ref != null && ref.isValid()) {
PlayerSomnolence somnolenceComponent = store.getComponent(ref, PlayerSomnolence.getComponentType()); PlayerSomnolence somnolenceComponent = store.getComponent(ref, playerSomnolenceComponentType);
if (somnolenceComponent == null) { if (somnolenceComponent == null) {
return true; return true;
} }

View File

@@ -5,6 +5,7 @@ import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.DisableProcessingAssert; import com.hypixel.hytale.component.DisableProcessingAssert;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.dependency.Dependency; import com.hypixel.hytale.component.dependency.Dependency;
import com.hypixel.hytale.component.dependency.Order; import com.hypixel.hytale.component.dependency.Order;
@@ -30,10 +31,12 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class BlockPhysicsSystems { public class BlockPhysicsSystems {
@Nonnull
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass(); private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
public static final int MAX_SUPPORT_RADIUS = 14; public static final int MAX_SUPPORT_RADIUS = 14;
public static class CachedAccessor extends AbstractCachedAccessor { public static class CachedAccessor extends AbstractCachedAccessor {
@Nonnull
private static final ThreadLocal<BlockPhysicsSystems.CachedAccessor> THREAD_LOCAL = ThreadLocal.withInitial(BlockPhysicsSystems.CachedAccessor::new); private static final ThreadLocal<BlockPhysicsSystems.CachedAccessor> THREAD_LOCAL = ThreadLocal.withInitial(BlockPhysicsSystems.CachedAccessor::new);
private static final int PHYSICS_COMPONENT = 0; private static final int PHYSICS_COMPONENT = 0;
private static final int FLUID_COMPONENT = 1; private static final int FLUID_COMPONENT = 1;
@@ -125,9 +128,11 @@ public class BlockPhysicsSystems {
} }
public static class Ticking extends EntityTickingSystem<ChunkStore> implements DisableProcessingAssert { public static class Ticking extends EntityTickingSystem<ChunkStore> implements DisableProcessingAssert {
@Nonnull
private static final Query<ChunkStore> QUERY = Query.and( private static final Query<ChunkStore> QUERY = Query.and(
ChunkSection.getComponentType(), BlockSection.getComponentType(), BlockPhysics.getComponentType(), FluidSection.getComponentType() ChunkSection.getComponentType(), BlockSection.getComponentType(), BlockPhysics.getComponentType(), FluidSection.getComponentType()
); );
@Nonnull
private static final Set<Dependency<ChunkStore>> DEPENDENCIES = Set.of( private static final Set<Dependency<ChunkStore>> DEPENDENCIES = Set.of(
new SystemDependency<>(Order.AFTER, ChunkBlockTickSystem.PreTick.class), new SystemDependency<>(Order.BEFORE, ChunkBlockTickSystem.Ticking.class) new SystemDependency<>(Order.AFTER, ChunkBlockTickSystem.PreTick.class), new SystemDependency<>(Order.BEFORE, ChunkBlockTickSystem.Ticking.class)
); );
@@ -157,28 +162,40 @@ public class BlockPhysicsSystems {
assert section != null; assert section != null;
try { try {
BlockSection blockSection = archetypeChunk.getComponent(index, BlockSection.getComponentType()); BlockSection blockSectionComponent = archetypeChunk.getComponent(index, BlockSection.getComponentType());
if (blockSectionComponent == null) {
assert blockSection != null;
if (blockSection.getTickingBlocksCountCopy() <= 0) {
return; return;
} }
BlockPhysics blockPhysics = archetypeChunk.getComponent(index, BlockPhysics.getComponentType()); if (blockSectionComponent.getTickingBlocksCountCopy() <= 0) {
return;
}
assert blockPhysics != null; BlockPhysics blockPhysicsComponent = archetypeChunk.getComponent(index, BlockPhysics.getComponentType());
if (blockPhysicsComponent == null) {
return;
}
FluidSection fluidSection = archetypeChunk.getComponent(index, FluidSection.getComponentType()); FluidSection fluidSectionComponent = archetypeChunk.getComponent(index, FluidSection.getComponentType());
if (fluidSectionComponent == null) {
return;
}
assert fluidSection != null; Ref<ChunkStore> columnRef = section.getChunkColumnReference();
if (columnRef == null || !columnRef.isValid()) {
return;
}
WorldChunk worldChunkComponent = commandBuffer.getComponent(columnRef, WorldChunk.getComponentType());
if (worldChunkComponent == null) {
return;
}
WorldChunk worldChunk = commandBuffer.getComponent(section.getChunkColumnReference(), WorldChunk.getComponentType());
BlockPhysicsSystems.CachedAccessor accessor = BlockPhysicsSystems.CachedAccessor.of( BlockPhysicsSystems.CachedAccessor accessor = BlockPhysicsSystems.CachedAccessor.of(
commandBuffer, blockSection, blockPhysics, fluidSection, section.getX(), section.getY(), section.getZ(), 14 commandBuffer, blockSectionComponent, blockPhysicsComponent, fluidSectionComponent, section.getX(), section.getY(), section.getZ(), 14
); );
blockSection.forEachTicking( blockSectionComponent.forEachTicking(
worldChunk, worldChunkComponent,
accessor, accessor,
section.getY(), section.getY(),
(wc, accessor1, localX, localY, localZ, blockId) -> { (wc, accessor1, localX, localY, localZ, blockId) -> {
@@ -218,8 +235,8 @@ public class BlockPhysicsSystems {
} }
} }
); );
} catch (Exception var12) { } catch (Exception var13) {
BlockPhysicsSystems.LOGGER.at(Level.SEVERE).withCause(var12).log("Failed to tick chunk: %s", section); BlockPhysicsSystems.LOGGER.at(Level.SEVERE).withCause(var13).log("Failed to tick chunk: %s", section);
} }
} }
} }

View File

@@ -34,7 +34,7 @@ public class BlockPhysicsUtil {
@Nonnull @Nonnull
public static BlockPhysicsUtil.Result applyBlockPhysics( public static BlockPhysicsUtil.Result applyBlockPhysics(
@Nullable ComponentAccessor<EntityStore> commandBuffer, @Nonnull ComponentAccessor<EntityStore> componentAccessor,
@Nonnull Ref<ChunkStore> chunkReference, @Nonnull Ref<ChunkStore> chunkReference,
@Nonnull BlockPhysicsSystems.CachedAccessor chunkAccessor, @Nonnull BlockPhysicsSystems.CachedAccessor chunkAccessor,
BlockSection blockSection, BlockSection blockSection,
@@ -55,9 +55,7 @@ public class BlockPhysicsUtil {
supportDistance = testBlockPhysics(chunkAccessor, blockSection, blockPhysics, fluidSection, blockX, blockY, blockZ, blockType, rotation, filler); supportDistance = testBlockPhysics(chunkAccessor, blockSection, blockPhysics, fluidSection, blockX, blockY, blockZ, blockType, rotation, filler);
} else { } else {
BlockBoundingBoxes boundingBoxes = BlockBoundingBoxes.getAssetMap().getAsset(blockType.getHitboxTypeIndex()); BlockBoundingBoxes boundingBoxes = BlockBoundingBoxes.getAssetMap().getAsset(blockType.getHitboxTypeIndex());
if (!boundingBoxes.protrudesUnitBox()) { if (boundingBoxes != null && boundingBoxes.protrudesUnitBox()) {
supportDistance = testBlockPhysics(chunkAccessor, blockSection, blockPhysics, fluidSection, blockX, blockY, blockZ, blockType, rotation, filler);
} else {
BlockBoundingBoxes.RotatedVariantBoxes rotatedBox = boundingBoxes.get(rotation); BlockBoundingBoxes.RotatedVariantBoxes rotatedBox = boundingBoxes.get(rotation);
Box boundingBox = rotatedBox.getBoundingBox(); Box boundingBox = rotatedBox.getBoundingBox();
int minX = (int)boundingBox.min.x; int minX = (int)boundingBox.min.x;
@@ -94,7 +92,7 @@ public class BlockPhysicsUtil {
int blockHeight = Math.max(maxY - minY, 1); int blockHeight = Math.max(maxY - minY, 1);
int blockDepth = Math.max(maxZ - minZ, 1); int blockDepth = Math.max(maxZ - minZ, 1);
label138: label136:
for (int x = 0; x < blockWidth; x++) { for (int x = 0; x < blockWidth; x++) {
for (int y = 0; y < blockHeight; y++) { for (int y = 0; y < blockHeight; y++) {
for (int z = 0; z < blockDepth; z++) { for (int z = 0; z < blockDepth; z++) {
@@ -140,7 +138,7 @@ public class BlockPhysicsUtil {
case Any: case Any:
if (fillerSupportDistance == -2) { if (fillerSupportDistance == -2) {
supportDistance = -2; supportDistance = -2;
break label138; break label136;
} }
if (fillerSupportDistance == 0) { if (fillerSupportDistance == 0) {
@@ -152,7 +150,7 @@ public class BlockPhysicsUtil {
case All: case All:
if (fillerSupportDistance == 0) { if (fillerSupportDistance == 0) {
supportDistance = 0; supportDistance = 0;
break label138; break label136;
} }
if (fillerSupportDistance == -2) { if (fillerSupportDistance == -2) {
@@ -165,21 +163,23 @@ public class BlockPhysicsUtil {
} }
} }
} }
} else {
supportDistance = testBlockPhysics(chunkAccessor, blockSection, blockPhysics, fluidSection, blockX, blockY, blockZ, blockType, rotation, filler);
} }
} }
if (supportDistance == 0) { if (supportDistance == 0) {
World world = commandBuffer.getExternalData().getWorld(); World world = componentAccessor.getExternalData().getWorld();
Store<ChunkStore> chunkStore = world.getChunkStore().getStore(); Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
switch (blockType.getSupportDropType()) { switch (blockType.getSupportDropType()) {
case BREAK: case BREAK:
BlockHarvestUtils.naturallyRemoveBlockByPhysics( BlockHarvestUtils.naturallyRemoveBlockByPhysics(
new Vector3i(blockX, blockY, blockZ), blockType, filler, 256, chunkReference, commandBuffer, chunkStore new Vector3i(blockX, blockY, blockZ), blockType, filler, 256, chunkReference, componentAccessor, chunkStore
); );
break; break;
case DESTROY: case DESTROY:
BlockHarvestUtils.naturallyRemoveBlockByPhysics( BlockHarvestUtils.naturallyRemoveBlockByPhysics(
new Vector3i(blockX, blockY, blockZ), blockType, filler, 2304, chunkReference, commandBuffer, chunkStore new Vector3i(blockX, blockY, blockZ), blockType, filler, 2304, chunkReference, componentAccessor, chunkStore
); );
} }
@@ -289,7 +289,6 @@ public class BlockPhysicsUtil {
if (requiredBlockFaceSupport.isAppliedToFiller(blockFillerOffset)) { if (requiredBlockFaceSupport.isAppliedToFiller(blockFillerOffset)) {
boolean doesSatisfyRequirements = doesSatisfyRequirements( boolean doesSatisfyRequirements = doesSatisfyRequirements(
blockType, blockType,
fluid,
blockFillerOffset, blockFillerOffset,
neighbourFillerOffset, neighbourFillerOffset,
blockFace, blockFace,
@@ -361,7 +360,6 @@ public class BlockPhysicsUtil {
public static boolean doesSatisfyRequirements( public static boolean doesSatisfyRequirements(
@Nonnull BlockType blockType, @Nonnull BlockType blockType,
Fluid fluid,
Vector3i blockFillerOffset, Vector3i blockFillerOffset,
Vector3i neighbourFillerOffset, Vector3i neighbourFillerOffset,
BlockFace blockFace, BlockFace blockFace,

View File

@@ -31,16 +31,17 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class PrefabBufferValidator { public class PrefabBufferValidator {
@Nonnull
private static final FillerBlockUtil.FillerFetcher<IPrefabBuffer, Void> FILLER_FETCHER = new FillerBlockUtil.FillerFetcher<IPrefabBuffer, Void>() { private static final FillerBlockUtil.FillerFetcher<IPrefabBuffer, Void> FILLER_FETCHER = new FillerBlockUtil.FillerFetcher<IPrefabBuffer, Void>() {
public int getBlock(IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) { public int getBlock(@Nonnull IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) {
return iPrefabBuffer.getBlockId(x, y, z); return iPrefabBuffer.getBlockId(x, y, z);
} }
public int getFiller(IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) { public int getFiller(@Nonnull IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) {
return iPrefabBuffer.getFiller(x, y, z); return iPrefabBuffer.getFiller(x, y, z);
} }
public int getRotationIndex(IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) { public int getRotationIndex(@Nonnull IPrefabBuffer iPrefabBuffer, Void unused, int x, int y, int z) {
return iPrefabBuffer.getRotationIndex(x, y, z); return iPrefabBuffer.getRotationIndex(x, y, z);
} }
}; };

View File

@@ -35,6 +35,7 @@ public class BlockSpawnerEntry implements IWeightedElement {
) )
.add() .add()
.build(); .build();
@Nonnull
public static final BlockSpawnerEntry[] EMPTY_ARRAY = new BlockSpawnerEntry[0]; public static final BlockSpawnerEntry[] EMPTY_ARRAY = new BlockSpawnerEntry[0];
private String blockName; private String blockName;
private Holder<ChunkStore> blockComponents; private Holder<ChunkStore> blockComponents;
@@ -63,6 +64,7 @@ public class BlockSpawnerEntry implements IWeightedElement {
RANDOM, RANDOM,
INHERIT; INHERIT;
@Nonnull
public static final Codec<BlockSpawnerEntry.RotationMode> CODEC = new EnumCodec<>(BlockSpawnerEntry.RotationMode.class); public static final Codec<BlockSpawnerEntry.RotationMode> CODEC = new EnumCodec<>(BlockSpawnerEntry.RotationMode.class);
} }
} }

View File

@@ -38,6 +38,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class BlockSpawnerPlugin extends JavaPlugin { public class BlockSpawnerPlugin extends JavaPlugin {
@Nonnull
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass(); private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
private ComponentType<ChunkStore, BlockSpawner> blockSpawnerComponentType; private ComponentType<ChunkStore, BlockSpawner> blockSpawnerComponentType;
private static BlockSpawnerPlugin INSTANCE; private static BlockSpawnerPlugin INSTANCE;
@@ -70,14 +71,14 @@ public class BlockSpawnerPlugin extends JavaPlugin {
this.getEventRegistry().registerGlobal(PrefabBufferValidator.ValidateBlockEvent.class, BlockSpawnerPlugin::validatePrefabBlock); this.getEventRegistry().registerGlobal(PrefabBufferValidator.ValidateBlockEvent.class, BlockSpawnerPlugin::validatePrefabBlock);
} }
private static void validatePrefabBlock(PrefabBufferValidator.ValidateBlockEvent validateBlockEvent) { private static void validatePrefabBlock(@Nonnull PrefabBufferValidator.ValidateBlockEvent validateBlockEvent) {
Holder<ChunkStore> holder = validateBlockEvent.holder(); Holder<ChunkStore> holder = validateBlockEvent.holder();
if (holder != null) { if (holder != null) {
BlockSpawner spawner = holder.getComponent(BlockSpawner.getComponentType()); BlockSpawner blockSpawnerComponent = holder.getComponent(BlockSpawner.getComponentType());
if (spawner != null) { if (blockSpawnerComponent != null) {
BlockType blockType = BlockType.getAssetMap().getAsset(validateBlockEvent.blockId()); BlockType blockType = BlockType.getAssetMap().getAsset(validateBlockEvent.blockId());
if (blockType != null) { if (blockType != null) {
if (spawner.getBlockSpawnerId() == null) { if (blockSpawnerComponent.getBlockSpawnerId() == null) {
validateBlockEvent.reason() validateBlockEvent.reason()
.append("\t Block ") .append("\t Block ")
.append(blockType.getId()) .append(blockType.getId())
@@ -90,7 +91,7 @@ public class BlockSpawnerPlugin extends JavaPlugin {
.append(" has no defined block spawner id") .append(" has no defined block spawner id")
.append('\n'); .append('\n');
} else { } else {
BlockSpawnerTable blockSpawner = BlockSpawnerTable.getAssetMap().getAsset(spawner.getBlockSpawnerId()); BlockSpawnerTable blockSpawner = BlockSpawnerTable.getAssetMap().getAsset(blockSpawnerComponent.getBlockSpawnerId());
if (blockSpawner == null) { if (blockSpawner == null) {
validateBlockEvent.reason() validateBlockEvent.reason()
.append("\t Block ") .append("\t Block ")
@@ -102,7 +103,7 @@ public class BlockSpawnerPlugin extends JavaPlugin {
.append(", ") .append(", ")
.append(validateBlockEvent.z()) .append(validateBlockEvent.z())
.append(" has an invalid spawner id ") .append(" has an invalid spawner id ")
.append(spawner.getBlockSpawnerId()) .append(blockSpawnerComponent.getBlockSpawnerId())
.append('\n'); .append('\n');
} }
} }
@@ -116,8 +117,11 @@ public class BlockSpawnerPlugin extends JavaPlugin {
} }
private static class BlockSpawnerSystem extends RefSystem<ChunkStore> { private static class BlockSpawnerSystem extends RefSystem<ChunkStore> {
@Nonnull
private static final ComponentType<ChunkStore, BlockSpawner> COMPONENT_TYPE = BlockSpawner.getComponentType(); private static final ComponentType<ChunkStore, BlockSpawner> COMPONENT_TYPE = BlockSpawner.getComponentType();
@Nonnull
private static final ComponentType<ChunkStore, BlockModule.BlockStateInfo> BLOCK_INFO_COMPONENT_TYPE = BlockModule.BlockStateInfo.getComponentType(); private static final ComponentType<ChunkStore, BlockModule.BlockStateInfo> BLOCK_INFO_COMPONENT_TYPE = BlockModule.BlockStateInfo.getComponentType();
@Nonnull
private static final Query<ChunkStore> QUERY = Query.and(COMPONENT_TYPE, BLOCK_INFO_COMPONENT_TYPE); private static final Query<ChunkStore> QUERY = Query.and(COMPONENT_TYPE, BLOCK_INFO_COMPONENT_TYPE);
public BlockSpawnerSystem() { public BlockSpawnerSystem() {
@@ -134,26 +138,27 @@ public class BlockSpawnerPlugin extends JavaPlugin {
) { ) {
WorldConfig worldConfig = store.getExternalData().getWorld().getWorldConfig(); WorldConfig worldConfig = store.getExternalData().getWorld().getWorldConfig();
if (worldConfig.getGameMode() != GameMode.Creative) { if (worldConfig.getGameMode() != GameMode.Creative) {
BlockSpawner state = commandBuffer.getComponent(ref, COMPONENT_TYPE); BlockSpawner blockSpawnerComponent = commandBuffer.getComponent(ref, COMPONENT_TYPE);
assert state != null; assert blockSpawnerComponent != null;
BlockModule.BlockStateInfo info = commandBuffer.getComponent(ref, BLOCK_INFO_COMPONENT_TYPE); BlockModule.BlockStateInfo blockStateInfoComponent = commandBuffer.getComponent(ref, BLOCK_INFO_COMPONENT_TYPE);
assert info != null; assert blockStateInfoComponent != null;
String blockSpawnerId = state.getBlockSpawnerId(); String blockSpawnerId = blockSpawnerComponent.getBlockSpawnerId();
if (blockSpawnerId != null) { if (blockSpawnerId != null) {
BlockSpawnerTable table = BlockSpawnerTable.getAssetMap().getAsset(blockSpawnerId); BlockSpawnerTable table = BlockSpawnerTable.getAssetMap().getAsset(blockSpawnerId);
if (table == null) { if (table == null) {
BlockSpawnerPlugin.LOGGER.at(Level.WARNING).log("Failed to find BlockSpawner Asset by name: %s", blockSpawnerId); BlockSpawnerPlugin.LOGGER.at(Level.WARNING).log("Failed to find BlockSpawner Asset by name: %s", blockSpawnerId);
} else { } else {
Ref<ChunkStore> chunk = info.getChunkRef(); Ref<ChunkStore> chunkRef = blockStateInfoComponent.getChunkRef();
if (chunk != null) { if (chunkRef.isValid()) {
WorldChunk wc = commandBuffer.getComponent(chunk, WorldChunk.getComponentType()); WorldChunk worldChunkComponent = commandBuffer.getComponent(chunkRef, WorldChunk.getComponentType());
int x = ChunkUtil.worldCoordFromLocalCoord(wc.getX(), ChunkUtil.xFromBlockInColumn(info.getIndex())); if (worldChunkComponent != null) {
int y = ChunkUtil.yFromBlockInColumn(info.getIndex()); int x = ChunkUtil.worldCoordFromLocalCoord(worldChunkComponent.getX(), ChunkUtil.xFromBlockInColumn(blockStateInfoComponent.getIndex()));
int z = ChunkUtil.worldCoordFromLocalCoord(wc.getZ(), ChunkUtil.zFromBlockInColumn(info.getIndex())); int y = ChunkUtil.yFromBlockInColumn(blockStateInfoComponent.getIndex());
int z = ChunkUtil.worldCoordFromLocalCoord(worldChunkComponent.getZ(), ChunkUtil.zFromBlockInColumn(blockStateInfoComponent.getIndex()));
long seed = worldConfig.getSeed(); long seed = worldConfig.getSeed();
double randomRnd = HashUtil.random(x, y, z, seed + -1699164769L); double randomRnd = HashUtil.random(x, y, z, seed + -1699164769L);
BlockSpawnerEntry entry = table.getEntries().get(randomRnd); BlockSpawnerEntry entry = table.getEntries().get(randomRnd);
@@ -179,7 +184,7 @@ public class BlockSpawnerPlugin extends JavaPlugin {
if (variantRotation == VariantRotation.None) { if (variantRotation == VariantRotation.None) {
yield RotationTuple.NONE; yield RotationTuple.NONE;
} else { } else {
RotationTuple spawnerRotation = RotationTuple.get(wc.getRotationIndex(x, y, z)); RotationTuple spawnerRotation = RotationTuple.get(worldChunkComponent.getRotationIndex(x, y, z));
Rotation spawnerYaw = spawnerRotation.yaw(); Rotation spawnerYaw = spawnerRotation.yaw();
yield BlockRotationUtil.getRotated(RotationTuple.NONE, Axis.Y, spawnerYaw, variantRotation); yield BlockRotationUtil.getRotated(RotationTuple.NONE, Axis.Y, spawnerYaw, variantRotation);
} }
@@ -195,9 +200,9 @@ public class BlockSpawnerPlugin extends JavaPlugin {
int blockId = BlockType.getAssetMap().getIndex(blockKey); int blockId = BlockType.getAssetMap().getIndex(blockKey);
BlockType blockType = BlockType.getAssetMap().getAsset(blockId); BlockType blockType = BlockType.getAssetMap().getAsset(blockId);
wc.setBlock(x, y, z, blockId, blockType, rotation.index(), 0, flags); worldChunkComponent.setBlock(x, y, z, blockId, blockType, rotation.index(), 0, flags);
if (holder != null) { if (holder != null) {
wc.setState(x, y, z, holder.clone()); worldChunkComponent.setState(x, y, z, holder.clone());
} }
}); });
} }
@@ -206,6 +211,7 @@ public class BlockSpawnerPlugin extends JavaPlugin {
} }
} }
} }
}
@Override @Override
public void onEntityRemove( public void onEntityRemove(

View File

@@ -16,6 +16,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class BlockSpawnerTable implements JsonAssetWithMap<String, DefaultAssetMap<String, BlockSpawnerTable>> { public class BlockSpawnerTable implements JsonAssetWithMap<String, DefaultAssetMap<String, BlockSpawnerTable>> {
@Nonnull
public static final AssetBuilderCodec<String, BlockSpawnerTable> CODEC = AssetBuilderCodec.builder( public static final AssetBuilderCodec<String, BlockSpawnerTable> CODEC = AssetBuilderCodec.builder(
BlockSpawnerTable.class, BlockSpawnerTable.class,
BlockSpawnerTable::new, BlockSpawnerTable::new,

View File

@@ -25,6 +25,8 @@ public class BlockSpawnerGetCommand extends AbstractWorldCommand {
@Nonnull @Nonnull
private static final Message MESSAGE_COMMANDS_ERRORS_PROVIDE_POSITION = Message.translation("server.commands.errors.providePosition"); private static final Message MESSAGE_COMMANDS_ERRORS_PROVIDE_POSITION = Message.translation("server.commands.errors.providePosition");
@Nonnull @Nonnull
private static final Message MESSAGE_COMMANDS_ERRORS_PLAYER_NOT_IN_WORLD = Message.translation("server.commands.errors.playerNotInWorld");
@Nonnull
private static final Message MESSAGE_COMMANDS_BLOCK_SPAWNER_NO_BLOCK_SPAWNER_SET = Message.translation("server.commands.blockspawner.noBlockSpawnerSet"); private static final Message MESSAGE_COMMANDS_BLOCK_SPAWNER_NO_BLOCK_SPAWNER_SET = Message.translation("server.commands.blockspawner.noBlockSpawnerSet");
@Nonnull @Nonnull
private final OptionalArg<RelativeIntPosition> positionArg = this.withOptionalArg( private final OptionalArg<RelativeIntPosition> positionArg = this.withOptionalArg(
@@ -47,6 +49,10 @@ public class BlockSpawnerGetCommand extends AbstractWorldCommand {
} }
Ref<EntityStore> ref = context.senderAsPlayerRef(); Ref<EntityStore> ref = context.senderAsPlayerRef();
if (ref == null || !ref.isValid()) {
throw new GeneralCommandException(MESSAGE_COMMANDS_ERRORS_PLAYER_NOT_IN_WORLD);
}
Vector3i targetBlock = TargetUtil.getTargetBlock(ref, 10.0, store); Vector3i targetBlock = TargetUtil.getTargetBlock(ref, 10.0, store);
if (targetBlock == null) { if (targetBlock == null) {
throw new GeneralCommandException(MESSAGE_GENERAL_BLOCK_TARGET_NOT_IN_RANGE); throw new GeneralCommandException(MESSAGE_GENERAL_BLOCK_TARGET_NOT_IN_RANGE);
@@ -64,9 +70,7 @@ public class BlockSpawnerGetCommand extends AbstractWorldCommand {
assert worldChunkComponent != null; assert worldChunkComponent != null;
Ref<ChunkStore> blockRef = worldChunkComponent.getBlockComponentEntity(position.x, position.y, position.z); Ref<ChunkStore> blockRef = worldChunkComponent.getBlockComponentEntity(position.x, position.y, position.z);
if (blockRef == null) { if (blockRef != null && blockRef.isValid()) {
context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString()));
} else {
BlockSpawner spawnerState = chunkStore.getStore().getComponent(blockRef, BlockSpawner.getComponentType()); BlockSpawner spawnerState = chunkStore.getStore().getComponent(blockRef, BlockSpawner.getComponentType());
if (spawnerState == null) { if (spawnerState == null) {
context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString())); context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString()));
@@ -77,6 +81,8 @@ public class BlockSpawnerGetCommand extends AbstractWorldCommand {
context.sendMessage(Message.translation("server.commands.blockspawner.currentBlockSpawner").param("id", spawnerState.getBlockSpawnerId())); context.sendMessage(Message.translation("server.commands.blockspawner.currentBlockSpawner").param("id", spawnerState.getBlockSpawnerId()));
} }
} }
} else {
context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString()));
} }
} else { } else {
context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString())); context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString()));

View File

@@ -30,6 +30,8 @@ public class BlockSpawnerSetCommand extends AbstractWorldCommand {
@Nonnull @Nonnull
private static final Message MESSAGE_COMMANDS_ERRORS_PROVIDE_POSITION = Message.translation("server.commands.errors.providePosition"); private static final Message MESSAGE_COMMANDS_ERRORS_PROVIDE_POSITION = Message.translation("server.commands.errors.providePosition");
@Nonnull @Nonnull
private static final Message MESSAGE_COMMANDS_ERRORS_PLAYER_NOT_IN_WORLD = Message.translation("server.commands.errors.playerNotInWorld");
@Nonnull
private static final SingleArgumentType<BlockSpawnerTable> BLOCK_SPAWNER_ASSET_TYPE = new AssetArgumentType( private static final SingleArgumentType<BlockSpawnerTable> BLOCK_SPAWNER_ASSET_TYPE = new AssetArgumentType(
"server.commands.parsing.argtype.asset.blockspawnertable.name", BlockSpawnerTable.class, "server.commands.parsing.argtype.asset.blockspawnertable.usage" "server.commands.parsing.argtype.asset.blockspawnertable.name", BlockSpawnerTable.class, "server.commands.parsing.argtype.asset.blockspawnertable.usage"
); );
@@ -60,6 +62,10 @@ public class BlockSpawnerSetCommand extends AbstractWorldCommand {
} }
Ref<EntityStore> ref = context.senderAsPlayerRef(); Ref<EntityStore> ref = context.senderAsPlayerRef();
if (ref == null || !ref.isValid()) {
throw new GeneralCommandException(MESSAGE_COMMANDS_ERRORS_PLAYER_NOT_IN_WORLD);
}
Vector3i targetBlock = TargetUtil.getTargetBlock(ref, 10.0, store); Vector3i targetBlock = TargetUtil.getTargetBlock(ref, 10.0, store);
if (targetBlock == null) { if (targetBlock == null) {
throw new GeneralCommandException(MESSAGE_GENERAL_BLOCK_TARGET_NOT_IN_RANGE); throw new GeneralCommandException(MESSAGE_GENERAL_BLOCK_TARGET_NOT_IN_RANGE);
@@ -68,12 +74,14 @@ public class BlockSpawnerSetCommand extends AbstractWorldCommand {
position = targetBlock; position = targetBlock;
} }
WorldChunk chunk = world.getChunk(ChunkUtil.indexChunkFromBlock(position.x, position.z)); WorldChunk worldChunk = world.getChunk(ChunkUtil.indexChunkFromBlock(position.x, position.z));
Ref<ChunkStore> blockRef = chunk.getBlockComponentEntity(position.x, position.y, position.z); if (worldChunk == null) {
if (blockRef == null) {
context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString())); context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString()));
} else { } else {
BlockSpawner spawnerState = world.getChunkStore().getStore().getComponent(blockRef, BlockSpawner.getComponentType()); Ref<ChunkStore> blockRef = worldChunk.getBlockComponentEntity(position.x, position.y, position.z);
if (blockRef != null && blockRef.isValid()) {
Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
BlockSpawner spawnerState = chunkStore.getComponent(blockRef, BlockSpawner.getComponentType());
if (spawnerState == null) { if (spawnerState == null) {
context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString())); context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString()));
} else { } else {
@@ -92,9 +100,12 @@ public class BlockSpawnerSetCommand extends AbstractWorldCommand {
} }
spawnerState.setBlockSpawnerId(spawnerId); spawnerState.setBlockSpawnerId(spawnerId);
chunk.markNeedsSaving(); worldChunk.markNeedsSaving();
context.sendMessage(Message.translation("server.commands.blockspawner.blockSpawnerSet").param("id", spawnerId)); context.sendMessage(Message.translation("server.commands.blockspawner.blockSpawnerSet").param("id", spawnerId));
} }
} else {
context.sendMessage(Message.translation("server.general.containerNotFound").param("block", position.toString()));
}
} }
} }
} }

View File

@@ -11,6 +11,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class BlockSpawner implements Component<ChunkStore> { public class BlockSpawner implements Component<ChunkStore> {
@Nonnull
public static final BuilderCodec<BlockSpawner> CODEC = BuilderCodec.builder(BlockSpawner.class, BlockSpawner::new) public static final BuilderCodec<BlockSpawner> CODEC = BuilderCodec.builder(BlockSpawner.class, BlockSpawner::new)
.addField(new KeyedCodec<>("BlockSpawnerId", Codec.STRING), (state, s) -> state.blockSpawnerId = s, state -> state.blockSpawnerId) .addField(new KeyedCodec<>("BlockSpawnerId", Codec.STRING), (state, s) -> state.blockSpawnerId = s, state -> state.blockSpawnerId)
.build(); .build();

View File

@@ -55,19 +55,17 @@ public class BlockTickPlugin extends JavaPlugin implements IBlockTickProvider {
} }
} }
public int discoverTickingBlocks(@Nonnull Holder<ChunkStore> holder, @Nonnull WorldChunk chunk) { public int discoverTickingBlocks(@Nonnull Holder<ChunkStore> holder, @Nonnull WorldChunk worldChunk) {
if (!this.isEnabled()) { if (!this.isEnabled()) {
return 0; return 0;
} else { } else {
BlockChunk bc = chunk.getBlockChunk(); BlockChunk blockChunkComponent = worldChunk.getBlockChunk();
if (!bc.consumeNeedsPhysics()) { if (blockChunkComponent != null && blockChunkComponent.consumeNeedsPhysics()) {
ChunkColumn chunkColumnComponent = holder.getComponent(ChunkColumn.getComponentType());
if (chunkColumnComponent == null) {
return 0; return 0;
} else { } else {
ChunkColumn column = holder.getComponent(ChunkColumn.getComponentType()); Holder<ChunkStore>[] sections = chunkColumnComponent.getSectionHolders();
if (column == null) {
return 0;
} else {
Holder<ChunkStore>[] sections = column.getSectionHolders();
if (sections == null) { if (sections == null) {
return 0; return 0;
} else { } else {
@@ -76,14 +74,14 @@ public class BlockTickPlugin extends JavaPlugin implements IBlockTickProvider {
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
Holder<ChunkStore> sectionHolder = sections[i]; Holder<ChunkStore> sectionHolder = sections[i];
BlockSection section = sectionHolder.ensureAndGetComponent(BlockSection.getComponentType()); BlockSection blockSectionComponent = sectionHolder.ensureAndGetComponent(BlockSection.getComponentType());
if (!section.isSolidAir()) { if (!blockSectionComponent.isSolidAir()) {
for (int blockIdx = 0; blockIdx < 32768; blockIdx++) { for (int blockIdx = 0; blockIdx < 32768; blockIdx++) {
int blockId = section.get(blockIdx); int blockId = blockSectionComponent.get(blockIdx);
BlockType blockType = assetMap.getAsset(blockId); BlockType blockType = assetMap.getAsset(blockId);
if (blockType != null && blockType.getTickProcedure() != null) { if (blockType != null && blockType.getTickProcedure() != null) {
section.setTicking(blockIdx, true); blockSectionComponent.setTicking(blockIdx, true);
bc.markNeedsSaving(); blockChunkComponent.markNeedsSaving();
count++; count++;
} }
} }
@@ -93,6 +91,8 @@ public class BlockTickPlugin extends JavaPlugin implements IBlockTickProvider {
return count; return count;
} }
} }
} else {
return 0;
} }
} }
} }

View File

@@ -10,6 +10,7 @@ import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class BasicChanceBlockGrowthProcedure extends TickProcedure { public class BasicChanceBlockGrowthProcedure extends TickProcedure {
@Nonnull
public static final BuilderCodec<BasicChanceBlockGrowthProcedure> CODEC = BuilderCodec.builder( public static final BuilderCodec<BasicChanceBlockGrowthProcedure> CODEC = BuilderCodec.builder(
BasicChanceBlockGrowthProcedure.class, BasicChanceBlockGrowthProcedure::new, TickProcedure.BASE_CODEC BasicChanceBlockGrowthProcedure.class, BasicChanceBlockGrowthProcedure::new, TickProcedure.BASE_CODEC
) )

View File

@@ -14,6 +14,7 @@ import org.bson.BsonDocument;
import org.bson.BsonValue; import org.bson.BsonValue;
public class SplitChanceBlockGrowthProcedure extends BasicChanceBlockGrowthProcedure { public class SplitChanceBlockGrowthProcedure extends BasicChanceBlockGrowthProcedure {
@Nonnull
public static final BuilderCodec<SplitChanceBlockGrowthProcedure> CODEC = BuilderCodec.builder( public static final BuilderCodec<SplitChanceBlockGrowthProcedure> CODEC = BuilderCodec.builder(
SplitChanceBlockGrowthProcedure.class, SplitChanceBlockGrowthProcedure::new, TickProcedure.BASE_CODEC SplitChanceBlockGrowthProcedure.class, SplitChanceBlockGrowthProcedure::new, TickProcedure.BASE_CODEC
) )

View File

@@ -21,20 +21,23 @@ import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk; import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk; import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.time.Instant; import java.time.Instant;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class ChunkBlockTickSystem { public class ChunkBlockTickSystem {
@Nonnull
protected static final HytaleLogger LOGGER = BlockTickPlugin.get().getLogger(); protected static final HytaleLogger LOGGER = BlockTickPlugin.get().getLogger();
public static class PreTick extends EntityTickingSystem<ChunkStore> { public static class PreTick extends EntityTickingSystem<ChunkStore> {
private static final ComponentType<ChunkStore, BlockChunk> COMPONENT_TYPE = BlockChunk.getComponentType(); @Nonnull
private static final ComponentType<ChunkStore, BlockChunk> COMPONENT_TYPE_WORLD_CHUNK = BlockChunk.getComponentType();
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return COMPONENT_TYPE; return COMPONENT_TYPE_WORLD_CHUNK;
} }
@Override @Override
@@ -50,26 +53,30 @@ public class ChunkBlockTickSystem {
@Nonnull Store<ChunkStore> store, @Nonnull Store<ChunkStore> store,
@Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
Instant time = commandBuffer.getExternalData().getWorld().getEntityStore().getStore().getResource(WorldTimeResource.getResourceType()).getGameTime(); World world = commandBuffer.getExternalData().getWorld();
BlockChunk chunk = archetypeChunk.getComponent(index, COMPONENT_TYPE); Store<EntityStore> entityStore = world.getEntityStore().getStore();
Instant timeResource = entityStore.getResource(WorldTimeResource.getResourceType()).getGameTime();
BlockChunk blockChunkComponent = archetypeChunk.getComponent(index, COMPONENT_TYPE_WORLD_CHUNK);
assert chunk != null; assert blockChunkComponent != null;
try { try {
chunk.preTick(time); blockChunkComponent.preTick(timeResource);
} catch (Throwable var9) { } catch (Throwable var11) {
ChunkBlockTickSystem.LOGGER.at(Level.SEVERE).withCause(var9).log("Failed to pre-tick chunk: %s", chunk); ChunkBlockTickSystem.LOGGER.at(Level.SEVERE).withCause(var11).log("Failed to pre-tick chunk: %s", blockChunkComponent);
} }
} }
} }
public static class Ticking extends EntityTickingSystem<ChunkStore> { public static class Ticking extends EntityTickingSystem<ChunkStore> {
private static final ComponentType<ChunkStore, WorldChunk> COMPONENT_TYPE = WorldChunk.getComponentType(); @Nonnull
private static final ComponentType<ChunkStore, WorldChunk> COMPONENT_TYPE_WORLD_CHUNK = WorldChunk.getComponentType();
@Nonnull
private static final Set<Dependency<ChunkStore>> DEPENDENCIES = Set.of(new SystemDependency<>(Order.AFTER, ChunkBlockTickSystem.PreTick.class)); private static final Set<Dependency<ChunkStore>> DEPENDENCIES = Set.of(new SystemDependency<>(Order.AFTER, ChunkBlockTickSystem.PreTick.class));
@Override @Override
public Query<ChunkStore> getQuery() { public Query<ChunkStore> getQuery() {
return COMPONENT_TYPE; return COMPONENT_TYPE_WORLD_CHUNK;
} }
@Nonnull @Nonnull
@@ -87,17 +94,25 @@ public class ChunkBlockTickSystem {
@Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
Ref<ChunkStore> reference = archetypeChunk.getReferenceTo(index); Ref<ChunkStore> reference = archetypeChunk.getReferenceTo(index);
WorldChunk worldChunk = archetypeChunk.getComponent(index, COMPONENT_TYPE); WorldChunk worldChunkComponent = archetypeChunk.getComponent(index, COMPONENT_TYPE_WORLD_CHUNK);
assert worldChunkComponent != null;
try { try {
tick(reference, worldChunk); tick(reference, worldChunkComponent);
} catch (Throwable var9) { } catch (Throwable var9) {
ChunkBlockTickSystem.LOGGER.at(Level.SEVERE).withCause(var9).log("Failed to tick chunk: %s", worldChunk); ChunkBlockTickSystem.LOGGER.at(Level.SEVERE).withCause(var9).log("Failed to tick chunk: %s", worldChunkComponent);
} }
} }
protected static void tick(Ref<ChunkStore> ref, @Nonnull WorldChunk worldChunk) { protected static void tick(@Nonnull Ref<ChunkStore> ref, @Nonnull WorldChunk worldChunk) {
int ticked = worldChunk.getBlockChunk().forEachTicking(ref, worldChunk, (r, c, localX, localY, localZ, blockId) -> { BlockChunk blockChunkComponent = worldChunk.getBlockChunk();
if (blockChunkComponent == null) {
ChunkBlockTickSystem.LOGGER
.at(Level.WARNING)
.log("World chunk (%d, %d) has no BlockChunk component, skipping block ticking.", worldChunk.getX(), worldChunk.getZ());
} else {
int ticked = blockChunkComponent.forEachTicking(ref, worldChunk, (r, c, localX, localY, localZ, blockId) -> {
World world = c.getWorld(); World world = c.getWorld();
int blockX = c.getX() << 5 | localX; int blockX = c.getX() << 5 | localX;
int blockZ = c.getZ() << 5 | localZ; int blockZ = c.getZ() << 5 | localZ;
@@ -107,6 +122,7 @@ public class ChunkBlockTickSystem {
ChunkBlockTickSystem.LOGGER.at(Level.FINER).log("Ticked %d blocks in chunk (%d, %d)", ticked, worldChunk.getX(), worldChunk.getZ()); ChunkBlockTickSystem.LOGGER.at(Level.FINER).log("Ticked %d blocks in chunk (%d, %d)", ticked, worldChunk.getX(), worldChunk.getZ());
} }
} }
}
protected static BlockTickStrategy tickProcedure(@Nonnull World world, @Nonnull WorldChunk chunk, int blockX, int blockY, int blockZ, int blockId) { protected static BlockTickStrategy tickProcedure(@Nonnull World world, @Nonnull WorldChunk chunk, int blockX, int blockY, int blockZ, int blockId) {
if (world.getWorldConfig().isBlockTicking() && BlockTickManager.hasBlockTickProvider()) { if (world.getWorldConfig().isBlockTicking() && BlockTickManager.hasBlockTickProvider()) {

View File

@@ -15,6 +15,7 @@ import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class MergeWaitingBlocksSystem extends RefSystem<ChunkStore> { public class MergeWaitingBlocksSystem extends RefSystem<ChunkStore> {
@Nonnull
private static final ComponentType<ChunkStore, WorldChunk> COMPONENT_TYPE = WorldChunk.getComponentType(); private static final ComponentType<ChunkStore, WorldChunk> COMPONENT_TYPE = WorldChunk.getComponentType();
@Override @Override
@@ -27,9 +28,12 @@ public class MergeWaitingBlocksSystem extends RefSystem<ChunkStore> {
@Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer @Nonnull Ref<ChunkStore> ref, @Nonnull AddReason reason, @Nonnull Store<ChunkStore> store, @Nonnull CommandBuffer<ChunkStore> commandBuffer
) { ) {
ChunkStore chunkStore = store.getExternalData(); ChunkStore chunkStore = store.getExternalData();
WorldChunk chunk = store.getComponent(ref, COMPONENT_TYPE); WorldChunk worldChunkComponent = store.getComponent(ref, COMPONENT_TYPE);
int x = chunk.getX();
int z = chunk.getZ(); assert worldChunkComponent != null;
int x = worldChunkComponent.getX();
int z = worldChunkComponent.getZ();
mergeTickingBlocks(chunkStore, x - 1, z); mergeTickingBlocks(chunkStore, x - 1, z);
mergeTickingBlocks(chunkStore, x + 1, z); mergeTickingBlocks(chunkStore, x + 1, z);
mergeTickingBlocks(chunkStore, x, z - 1); mergeTickingBlocks(chunkStore, x, z - 1);
@@ -43,9 +47,10 @@ public class MergeWaitingBlocksSystem extends RefSystem<ChunkStore> {
} }
public static void mergeTickingBlocks(@Nonnull ChunkStore store, int x, int z) { public static void mergeTickingBlocks(@Nonnull ChunkStore store, int x, int z) {
BlockChunk blockChunk = store.getChunkComponent(ChunkUtil.indexChunk(x, z), BlockChunk.getComponentType()); long chunkIndex = ChunkUtil.indexChunk(x, z);
if (blockChunk != null) { BlockChunk blockChunkComponent = store.getChunkComponent(chunkIndex, BlockChunk.getComponentType());
blockChunk.mergeTickingBlocks(); if (blockChunkComponent != null) {
blockChunkComponent.mergeTickingBlocks();
} }
} }
} }

View File

@@ -21,6 +21,7 @@ import com.hypixel.hytale.builtin.buildertools.commands.FlipCommand;
import com.hypixel.hytale.builtin.buildertools.commands.GlobalMaskCommand; import com.hypixel.hytale.builtin.buildertools.commands.GlobalMaskCommand;
import com.hypixel.hytale.builtin.buildertools.commands.HollowCommand; import com.hypixel.hytale.builtin.buildertools.commands.HollowCommand;
import com.hypixel.hytale.builtin.buildertools.commands.HotbarSwitchCommand; import com.hypixel.hytale.builtin.buildertools.commands.HotbarSwitchCommand;
import com.hypixel.hytale.builtin.buildertools.commands.LayerCommand;
import com.hypixel.hytale.builtin.buildertools.commands.MoveCommand; import com.hypixel.hytale.builtin.buildertools.commands.MoveCommand;
import com.hypixel.hytale.builtin.buildertools.commands.PasteCommand; import com.hypixel.hytale.builtin.buildertools.commands.PasteCommand;
import com.hypixel.hytale.builtin.buildertools.commands.Pos1Command; import com.hypixel.hytale.builtin.buildertools.commands.Pos1Command;
@@ -245,6 +246,7 @@ import com.hypixel.hytale.server.core.util.TargetUtil;
import com.hypixel.hytale.server.core.util.TempAssetIdUtil; import com.hypixel.hytale.server.core.util.TempAssetIdUtil;
import com.hypixel.hytale.sneakythrow.consumer.ThrowableConsumer; import com.hypixel.hytale.sneakythrow.consumer.ThrowableConsumer;
import com.hypixel.hytale.sneakythrow.consumer.ThrowableTriConsumer; import com.hypixel.hytale.sneakythrow.consumer.ThrowableTriConsumer;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.Int2IntFunction; import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntMaps; import it.unimi.dsi.fastutil.ints.Int2IntMaps;
@@ -443,6 +445,7 @@ public class BuilderToolsPlugin extends JavaPlugin implements SelectionProvider,
commandRegistry.registerCommand(new SetToolHistorySizeCommand()); commandRegistry.registerCommand(new SetToolHistorySizeCommand());
commandRegistry.registerCommand(new ObjImportCommand()); commandRegistry.registerCommand(new ObjImportCommand());
commandRegistry.registerCommand(new ImageImportCommand()); commandRegistry.registerCommand(new ImageImportCommand());
commandRegistry.registerCommand(new LayerCommand());
OpenCustomUIInteraction.registerBlockCustomPage( OpenCustomUIInteraction.registerBlockCustomPage(
this, this,
PrefabSpawnerState.PrefabSpawnerSettingsPage.class, PrefabSpawnerState.PrefabSpawnerSettingsPage.class,
@@ -885,7 +888,8 @@ public class BuilderToolsPlugin extends JavaPlugin implements SelectionProvider,
EXTRUDE, EXTRUDE,
UPDATE_SELECTION, UPDATE_SELECTION,
WALLS, WALLS,
HOLLOW; HOLLOW,
LAYER;
} }
public static class ActionEntry { public static class ActionEntry {
@@ -2607,6 +2611,111 @@ public class BuilderToolsPlugin extends JavaPlugin implements SelectionProvider,
); );
} }
public void layer(
int x,
int y,
int z,
@Nonnull List<Pair<Integer, String>> layers,
int depth,
Vector3i direction,
WorldChunk chunk,
BlockSelection before,
BlockSelection after
) {
int xModifier = direction.x == 1 ? -1 : (direction.x == -1 ? 1 : 0);
int yModifier = direction.y == 1 ? -1 : (direction.y == -1 ? 1 : 0);
int zModifier = direction.z == 1 ? -1 : (direction.z == -1 ? 1 : 0);
for (int i = 0; i < depth; i++) {
if (chunk.getBlock(x + i * xModifier + xModifier, y + i * yModifier + yModifier, z + i * zModifier + zModifier) <= 0
&& this.attemptSetLayer(x, y, z, i, layers, chunk, before, after)) {
return;
}
}
}
public void layer(@Nonnull List<Pair<Integer, String>> layers, Vector3i direction, ComponentAccessor<EntityStore> componentAccessor) {
if (this.selection == null) {
this.sendFeedback(Message.translation("server.builderTools.noSelection"), componentAccessor);
} else if (!this.selection.hasSelectionBounds()) {
this.sendFeedback(Message.translation("server.builderTools.noSelectionBounds"), componentAccessor);
} else {
int maxDepth = 0;
for (Pair<Integer, String> layer : layers) {
maxDepth += layer.left();
}
long start = System.nanoTime();
Vector3i min = Vector3i.min(this.selection.getSelectionMin(), this.selection.getSelectionMax());
Vector3i max = Vector3i.max(this.selection.getSelectionMin(), this.selection.getSelectionMax());
int xMin = min.getX();
int xMax = max.getX();
int yMin = min.getY();
int yMax = max.getY();
int zMin = min.getZ();
int zMax = max.getZ();
BlockSelection before = new BlockSelection();
int width = xMax - xMin;
int depth = zMax - zMin;
int halfWidth = width / 2;
int halfDepth = depth / 2;
before.setPosition(xMin + halfWidth, yMin, zMin + halfDepth);
before.setSelectionArea(min, max);
this.pushHistory(BuilderToolsPlugin.Action.LAYER, new BlockSelectionSnapshot(before));
BlockSelection after = new BlockSelection(before);
World world = componentAccessor.getExternalData().getWorld();
LocalCachedChunkAccessor accessor = LocalCachedChunkAccessor.atWorldCoords(world, xMin + halfWidth, zMin + halfDepth, Math.max(width, depth));
for (int x = xMin; x <= xMax; x++) {
for (int z = zMin; z <= zMax; z++) {
WorldChunk chunk = accessor.getChunk(ChunkUtil.indexChunkFromBlock(x, z));
for (int y = yMax; y >= yMin; y--) {
int currentBlock = chunk.getBlock(x, y, z);
int currentFluid = chunk.getFluidId(x, y, z);
if (currentBlock > 0 && (this.globalMask == null || !this.globalMask.isExcluded(accessor, x, y, z, min, max, currentBlock, currentFluid))) {
this.layer(x, y, z, layers, maxDepth, direction, chunk, before, after);
}
}
}
}
after.placeNoReturn("Finished layer", this.player, BuilderToolsPlugin.FEEDBACK_CONSUMER, world, componentAccessor);
BuilderToolsPlugin.invalidateWorldMapForSelection(after, world);
long end = System.nanoTime();
long diff = end - start;
BuilderToolsPlugin.get().getLogger().at(Level.FINE).log("Took: %dns (%dms) to execute layer", diff, TimeUnit.NANOSECONDS.toMillis(diff));
this.sendUpdate();
this.sendArea();
}
}
private boolean attemptSetLayer(
int x, int y, int z, int depth, List<Pair<Integer, String>> layers, WorldChunk chunk, BlockSelection before, BlockSelection after
) {
int currentDepth = 0;
for (Pair<Integer, String> layer : layers) {
currentDepth += layer.left();
if (depth < currentDepth) {
int currentBlock = chunk.getBlock(x, y, z);
int currentBlockFiller = chunk.getFiller(x, y, z);
Holder<ChunkStore> holder = chunk.getBlockComponentHolder(x, y, z);
int rotation = chunk.getRotationIndex(x, y, z);
int supportValue = chunk.getSupportValue(x, y, z);
BlockPattern pattern = BlockPattern.parse(layer.right());
int materialId = pattern.nextBlock(this.random);
Holder<ChunkStore> newHolder = BuilderToolsPlugin.createBlockComponent(chunk, x, y, z, materialId, currentBlock, holder, true);
before.addBlockAtWorldPos(x, y, z, currentBlock, rotation, currentBlockFiller, supportValue, holder);
after.addBlockAtWorldPos(x, y, z, materialId, rotation, 0, 0, newHolder);
return true;
}
}
return false;
}
public int paste(@Nonnull Ref<EntityStore> ref, int x, int y, int z, @Nonnull ComponentAccessor<EntityStore> componentAccessor) { public int paste(@Nonnull Ref<EntityStore> ref, int x, int y, int z, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
return this.paste(ref, x, y, z, false, componentAccessor); return this.paste(ref, x, y, z, false, componentAccessor);
} }

View File

@@ -0,0 +1,78 @@
package com.hypixel.hytale.builtin.buildertools.commands;
import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
import com.hypixel.hytale.builtin.buildertools.PrototypePlayerBuilderToolSettings;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.arguments.system.RequiredArg;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.Pair;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
public class LayerCommand extends AbstractPlayerCommand {
private static Map<String, Vector3i> directions = Map.of(
"up", Vector3i.UP, "down", Vector3i.DOWN, "north", Vector3i.NORTH, "south", Vector3i.SOUTH, "east", Vector3i.EAST, "west", Vector3i.WEST
);
@Nonnull
private final RequiredArg<String> layerDirectionArg = this.withRequiredArg("direction", "server.commands.layer.direction.desc", ArgTypes.STRING);
@Nonnull
private final RequiredArg<List<Pair<Integer, String>>> layersArg = this.withListRequiredArg(
"layers", "server.commands.layer.layers.desc", ArgTypes.LAYER_ENTRY_TYPE
);
public LayerCommand() {
super("layer", "server.commands.layer.desc");
this.setPermissionGroup(GameMode.Creative);
this.requirePermission("hytale.editor.selection.clipboard");
}
@Override
protected void execute(
@Nonnull CommandContext context, @Nonnull Store<EntityStore> store, @Nonnull Ref<EntityStore> ref, @Nonnull PlayerRef playerRef, @Nonnull World world
) {
Player playerComponent = store.getComponent(ref, Player.getComponentType());
assert playerComponent != null;
if (PrototypePlayerBuilderToolSettings.isOkayToDoCommandsOnSelection(ref, playerComponent, store)) {
String direction = this.layerDirectionArg.get(context).toLowerCase();
List<Pair<Integer, String>> layers = this.layersArg.get(context);
if (layers != null && direction != null) {
boolean directionValid = directions.containsKey(direction);
if (directionValid) {
BuilderToolsPlugin.addToQueue(playerComponent, playerRef, (r, s, componentAccessor) -> {
HeadRotation headRotationComponent = componentAccessor.getComponent(ref, HeadRotation.getComponentType());
assert headRotationComponent != null;
Vector3i layerDirection = Vector3i.ZERO;
if (direction.equalsIgnoreCase("camera")) {
layerDirection = headRotationComponent.getAxisDirection();
} else {
layerDirection = directions.get(direction);
}
s.layer(layers, layerDirection, componentAccessor);
});
} else {
context.sendMessage(Message.translation("server.commands.layer.directionInvalid").param("direction", direction));
context.sendMessage(Message.translation("server.commands.help.useHelpToLearnMore").param("command", this.getFullyQualifiedName()));
}
} else {
context.sendMessage(Message.translation("server.commands.help.useHelpToLearnMore").param("command", this.getFullyQualifiedName()));
}
}
}
}

View File

@@ -14,6 +14,7 @@ import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType; import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.protocol.packets.interface_.Page; import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.AssetModule;
import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage; import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;
import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection; import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
@@ -259,7 +260,9 @@ public class ImageImportPage extends InteractiveCustomUIPage<ImageImportPage.Pag
this.setError("Please enter a path to an image file"); this.setError("Please enter a path to an image file");
} else { } else {
Path path = Paths.get(this.imagePath); Path path = Paths.get(this.imagePath);
if (!Files.exists(path)) { if (!AssetModule.get().isWithinPackSubDir(path, "Server/Imports/Images")) {
this.setError("File must be within an asset pack's imports directory");
} else if (!Files.exists(path)) {
this.setError("File not found: " + this.imagePath); this.setError("File not found: " + this.imagePath);
} else { } else {
this.isProcessing = true; this.isProcessing = true;

View File

@@ -9,15 +9,12 @@ import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.protocol.InteractionState; import com.hypixel.hytale.protocol.InteractionState;
import com.hypixel.hytale.protocol.InteractionType; import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.entity.InteractionContext; import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.inventory.ItemStack; import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction; import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent; import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler; import com.hypixel.hytale.server.core.modules.interaction.interaction.CooldownHandler;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.SimpleInstantInteraction; import com.hypixel.hytale.server.core.modules.interaction.interaction.config.SimpleInstantInteraction;
@@ -59,33 +56,33 @@ public class PickupItemInteraction extends SimpleInstantInteraction {
context.getState().state = InteractionState.Failed; context.getState().state = InteractionState.Failed;
} else { } else {
ItemStack itemStack = itemComponent.getItemStack(); ItemStack itemStack = itemComponent.getItemStack();
Item item = itemStack.getItem(); if (!ItemStack.isEmpty(itemStack)) {
Vector3d itemEntityPosition = transformComponent.getPosition(); Vector3d itemEntityPosition = transformComponent.getPosition();
PlayerSettings playerSettings = commandBuffer.getComponent(ref, PlayerSettings.getComponentType()); ItemStackTransaction transaction = playerComponent.giveItem(itemStack, ref, commandBuffer);
if (playerSettings == null) {
playerSettings = PlayerSettings.defaults();
}
ItemContainer itemContainer = playerComponent.getInventory().getContainerForItemPickup(item, playerSettings);
ItemStackTransaction transaction = itemContainer.addItemStack(itemStack);
ItemStack remainder = transaction.getRemainder(); ItemStack remainder = transaction.getRemainder();
if (ItemStack.isEmpty(remainder)) { if (ItemStack.isEmpty(remainder)) {
itemComponent.setRemovedByPlayerPickup(true); itemComponent.setRemovedByPlayerPickup(true);
commandBuffer.removeEntity(targetRef, RemoveReason.REMOVE); commandBuffer.removeEntity(targetRef, RemoveReason.REMOVE);
playerComponent.notifyPickupItem(ref, itemStack, itemEntityPosition, commandBuffer); playerComponent.notifyPickupItem(ref, itemStack, itemEntityPosition, commandBuffer);
Holder<EntityStore> pickupItemHolder = ItemComponent.generatePickedUpItem(targetRef, commandBuffer, ref, itemEntityPosition); Holder<EntityStore> pickupItemHolder = ItemComponent.generatePickedUpItem(targetRef, commandBuffer, ref, itemEntityPosition);
if (pickupItemHolder != null) {
commandBuffer.addEntity(pickupItemHolder, AddReason.SPAWN); commandBuffer.addEntity(pickupItemHolder, AddReason.SPAWN);
}
} else if (!remainder.equals(itemStack)) { } else if (!remainder.equals(itemStack)) {
int quantity = itemStack.getQuantity() - remainder.getQuantity(); int quantity = itemStack.getQuantity() - remainder.getQuantity();
itemComponent.setItemStack(remainder); itemComponent.setItemStack(remainder);
Holder<EntityStore> pickupItemHolder = ItemComponent.generatePickedUpItem(targetRef, commandBuffer, ref, itemEntityPosition); Holder<EntityStore> pickupItemHolder = ItemComponent.generatePickedUpItem(targetRef, commandBuffer, ref, itemEntityPosition);
if (pickupItemHolder != null) {
commandBuffer.addEntity(pickupItemHolder, AddReason.SPAWN); commandBuffer.addEntity(pickupItemHolder, AddReason.SPAWN);
}
if (quantity > 0) { if (quantity > 0) {
playerComponent.notifyPickupItem(ref, itemStack.withQuantity(quantity), itemEntityPosition, commandBuffer); playerComponent.notifyPickupItem(ref, itemStack.withQuantity(quantity), itemEntityPosition, commandBuffer);
} }
} }
} }
} }
}
} else { } else {
context.getState().state = InteractionState.Failed; context.getState().state = InteractionState.Failed;
} }

View File

@@ -6,6 +6,7 @@ import com.hypixel.hytale.builtin.buildertools.utils.PasteToolUtil;
import com.hypixel.hytale.codec.Codec; import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec; import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec; import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.common.util.PathUtil;
import com.hypixel.hytale.common.util.StringUtil; import com.hypixel.hytale.common.util.StringUtil;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
@@ -14,6 +15,7 @@ import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType; import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.protocol.packets.interface_.Page; import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.AssetModule;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage; import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;
@@ -401,12 +403,14 @@ public class ObjImportPage extends InteractiveCustomUIPage<ObjImportPage.PageDat
private void performImport(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) { private void performImport(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
if (this.objPath.isEmpty()) { if (this.objPath.isEmpty()) {
this.setError("Please enter a path to an OBJ file"); this.setError("Please enter a path to an OBJ file");
} else {
Path path = Paths.get(this.objPath);
if (!Files.exists(path)) {
this.setError("File not found: " + this.objPath);
} else if (!this.objPath.toLowerCase().endsWith(".obj")) { } else if (!this.objPath.toLowerCase().endsWith(".obj")) {
this.setError("File must be a .obj file"); this.setError("File must be a .obj file");
} else {
Path path = Paths.get(this.objPath);
if (!AssetModule.get().isWithinPackSubDir(path, "Server/Imports/Models")) {
this.setError("File must be within an asset pack's imports directory");
} else if (!Files.exists(path)) {
this.setError("File not found: " + this.objPath);
} else { } else {
List<ObjImportPage.WeightedBlock> blocks = this.parseBlockPattern(this.blockPattern); List<ObjImportPage.WeightedBlock> blocks = this.parseBlockPattern(this.blockPattern);
if (blocks == null) { if (blocks == null) {
@@ -577,8 +581,8 @@ public class ObjImportPage extends InteractiveCustomUIPage<ObjImportPage.PageDat
boolean autoDetectTextures boolean autoDetectTextures
) throws IOException { ) throws IOException {
if (mesh.mtlLib() != null) { if (mesh.mtlLib() != null) {
Path mtlPath = objPath.getParent().resolve(mesh.mtlLib()); Path mtlPath = PathUtil.resolvePathWithinDir(objPath.getParent(), mesh.mtlLib());
if (Files.exists(mtlPath)) { if (mtlPath != null && Files.exists(mtlPath)) {
Map<String, MtlParser.MtlMaterial> materials = MtlParser.parse(mtlPath); Map<String, MtlParser.MtlMaterial> materials = MtlParser.parse(mtlPath);
Path textureDir = mtlPath.getParent(); Path textureDir = mtlPath.getParent();
@@ -591,7 +595,11 @@ public class ObjImportPage extends InteractiveCustomUIPage<ObjImportPage.PageDat
} }
if (texturePath != null) { if (texturePath != null) {
Path resolvedPath = textureDir.resolve(texturePath); Path resolvedPath = PathUtil.resolvePathWithinDir(textureDir, texturePath);
if (resolvedPath == null) {
continue;
}
BufferedImage texture = TextureSampler.loadTexture(resolvedPath); BufferedImage texture = TextureSampler.loadTexture(resolvedPath);
if (texture != null) { if (texture != null) {
materialTextures.put(materialName, texture); materialTextures.put(materialName, texture);

View File

@@ -5,6 +5,7 @@ import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditorCreation
import com.hypixel.hytale.builtin.buildertools.prefabeditor.enums.PrefabRootDirectory; import com.hypixel.hytale.builtin.buildertools.prefabeditor.enums.PrefabRootDirectory;
import com.hypixel.hytale.builtin.buildertools.prefabeditor.enums.WorldGenType; import com.hypixel.hytale.builtin.buildertools.prefabeditor.enums.WorldGenType;
import com.hypixel.hytale.codec.validation.Validators; import com.hypixel.hytale.codec.validation.Validators;
import com.hypixel.hytale.common.util.PathUtil;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
@@ -72,11 +73,8 @@ public class PrefabEditCreateNewCommand extends AbstractAsyncPlayerCommand {
prefabName = prefabName + ".prefab.json"; prefabName = prefabName + ".prefab.json";
} }
Path prefabPath = prefabBaseDirectory.resolve(prefabName); Path prefabPath = PathUtil.resolvePathWithinDir(prefabBaseDirectory, prefabName);
if (prefabPath.toString().endsWith("/")) { if (prefabPath != null && !prefabPath.toString().endsWith("/")) {
context.sendMessage(MESSAGE_COMMANDS_EDIT_PREFAB_NEW_ERRORS_NOT_A_FILE);
return CompletableFuture.completedFuture(null);
} else {
PrefabEditorCreationSettings prefabEditorLoadCommandSettings = new PrefabEditorCreationSettings( PrefabEditorCreationSettings prefabEditorLoadCommandSettings = new PrefabEditorCreationSettings(
this.prefabPathArg.get(context), this.prefabPathArg.get(context),
List.of(prefabName), List.of(prefabName),
@@ -98,6 +96,9 @@ public class PrefabEditCreateNewCommand extends AbstractAsyncPlayerCommand {
return BuilderToolsPlugin.get() return BuilderToolsPlugin.get()
.getPrefabEditSessionManager() .getPrefabEditSessionManager()
.createEditSessionForNewPrefab(ref, playerComponent, prefabEditorLoadCommandSettings, store); .createEditSessionForNewPrefab(ref, playerComponent, prefabEditorLoadCommandSettings, store);
} else {
context.sendMessage(MESSAGE_COMMANDS_EDIT_PREFAB_NEW_ERRORS_NOT_A_FILE);
return CompletableFuture.completedFuture(null);
} }
} }
} }

View File

@@ -10,6 +10,7 @@ import com.hypixel.hytale.common.util.PathUtil;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.AssetModule;
import com.hypixel.hytale.server.core.command.system.CommandContext; import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg; import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractAsyncPlayerCommand; import com.hypixel.hytale.server.core.command.system.basecommands.AbstractAsyncPlayerCommand;
@@ -44,9 +45,14 @@ public class PrefabEditSaveCommand extends AbstractAsyncPlayerCommand {
private static boolean isPathInAllowedPrefabDirectory(@Nonnull Path path) { private static boolean isPathInAllowedPrefabDirectory(@Nonnull Path path) {
PrefabStore prefabStore = PrefabStore.get(); PrefabStore prefabStore = PrefabStore.get();
return PathUtil.isChildOf(prefabStore.getServerPrefabsPath(), path) if (PathUtil.isChildOf(prefabStore.getServerPrefabsPath(), path)) {
|| PathUtil.isChildOf(prefabStore.getAssetPrefabsPath(), path) return true;
|| PathUtil.isChildOf(prefabStore.getWorldGenPrefabsPath(), path); } else if (PathUtil.isChildOf(prefabStore.getWorldGenPrefabsPath(), path)) {
return true;
} else {
AssetModule assetModule = AssetModule.get();
return assetModule.isWithinPackSubDir(path, "Server/Prefabs") && !assetModule.isAssetPathImmutable(path);
}
} }
public PrefabEditSaveCommand() { public PrefabEditSaveCommand() {

View File

@@ -627,7 +627,7 @@ public class PrefabEditorLoadSettingsPage extends InteractiveCustomUIPage<Prefab
private void handleRegularNavigation(@Nonnull String fileName) { private void handleRegularNavigation(@Nonnull String fileName) {
Path file = this.browserRoot.resolve(this.browserCurrent).resolve(fileName); Path file = this.browserRoot.resolve(this.browserCurrent).resolve(fileName);
if (!file.normalize().startsWith(this.browserRoot.normalize())) { if (!PathUtil.isChildOf(this.browserRoot, file)) {
this.sendUpdate(); this.sendUpdate();
} else { } else {
if (Files.isDirectory(file)) { if (Files.isDirectory(file)) {

View File

@@ -1,5 +1,6 @@
package com.hypixel.hytale.builtin.buildertools.prefablist; package com.hypixel.hytale.builtin.buildertools.prefablist;
import com.hypixel.hytale.common.util.PathUtil;
import com.hypixel.hytale.common.util.StringCompareUtil; import com.hypixel.hytale.common.util.StringCompareUtil;
import com.hypixel.hytale.server.core.prefab.PrefabStore; import com.hypixel.hytale.server.core.prefab.PrefabStore;
import com.hypixel.hytale.server.core.ui.browser.FileListProvider; import com.hypixel.hytale.server.core.ui.browser.FileListProvider;
@@ -67,7 +68,10 @@ public class AssetPrefabFileProvider implements FileListProvider {
} else { } else {
Path targetPath = packPath.prefabsPath(); Path targetPath = packPath.prefabsPath();
if (!subPath.isEmpty()) { if (!subPath.isEmpty()) {
targetPath = targetPath.resolve(subPath); targetPath = PathUtil.resolvePathWithinDir(targetPath, subPath);
if (targetPath == null) {
return entries;
}
} }
if (!Files.isDirectory(targetPath)) { if (!Files.isDirectory(targetPath)) {
@@ -116,7 +120,10 @@ public class AssetPrefabFileProvider implements FileListProvider {
if (packPath != null) { if (packPath != null) {
Path searchRoot = packPath.prefabsPath(); Path searchRoot = packPath.prefabsPath();
if (!subPath.isEmpty()) { if (!subPath.isEmpty()) {
searchRoot = searchRoot.resolve(subPath); searchRoot = PathUtil.resolvePathWithinDir(searchRoot, subPath);
if (searchRoot == null) {
return List.of();
}
} }
this.searchInDirectory(searchRoot, packKey, subPath, lowerQuery, allResults); this.searchInDirectory(searchRoot, packKey, subPath, lowerQuery, allResults);
@@ -203,7 +210,7 @@ public class AssetPrefabFileProvider implements FileListProvider {
if (packPath == null) { if (packPath == null) {
return null; return null;
} else { } else {
return subPath.isEmpty() ? packPath.prefabsPath() : packPath.prefabsPath().resolve(subPath); return subPath.isEmpty() ? packPath.prefabsPath() : PathUtil.resolvePathWithinDir(packPath.prefabsPath(), subPath);
} }
} }
} }

View File

@@ -2,6 +2,7 @@ package com.hypixel.hytale.builtin.buildertools.prefablist;
import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin; import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
import com.hypixel.hytale.builtin.buildertools.utils.PasteToolUtil; import com.hypixel.hytale.builtin.buildertools.utils.PasteToolUtil;
import com.hypixel.hytale.common.util.PathUtil;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.protocol.GameMode; import com.hypixel.hytale.protocol.GameMode;
@@ -161,13 +162,8 @@ public class PrefabPage extends InteractiveCustomUIPage<FileBrowserEventData> {
this.buildFileList(commandBuilder, eventBuilder); this.buildFileList(commandBuilder, eventBuilder);
this.sendUpdate(commandBuilder, eventBuilder, false); this.sendUpdate(commandBuilder, eventBuilder, false);
} else { } else {
Path file; Path baseDir = isSearchResult ? this.browser.getRoot() : this.browser.getRoot().resolve(this.browser.getCurrentDir().toString());
if (isSearchResult) { Path file = PathUtil.resolvePathWithinDir(baseDir, selectedPath);
file = this.browser.resolveSecure(selectedPath);
} else {
file = this.browser.resolveFromCurrent(selectedPath);
}
if (file != null && !Files.isDirectory(file)) { if (file != null && !Files.isDirectory(file)) {
this.handlePrefabSelection(ref, store, file, selectedPath); this.handlePrefabSelection(ref, store, file, selectedPath);
} else { } else {

View File

@@ -1,5 +1,6 @@
package com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential; package com.hypixel.hytale.builtin.buildertools.scriptedbrushes.operations.sequential;
import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfig; import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfig;
import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigCommandExecutor; import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigCommandExecutor;
import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigEditStore; import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigEditStore;
@@ -9,13 +10,18 @@ import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.codec.codecs.array.ArrayCodec; import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.server.core.asset.type.buildertool.config.BuilderTool; import com.hypixel.hytale.server.core.asset.type.buildertool.config.BuilderTool;
import com.hypixel.hytale.server.core.codec.LayerEntryCodec; import com.hypixel.hytale.server.core.codec.LayerEntryCodec;
import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.inventory.ItemStack; import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern; import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.accessor.BlockAccessor;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -51,58 +57,50 @@ public class LayerOperation extends SequenceBrushOperation {
int z, int z,
ComponentAccessor<EntityStore> componentAccessor ComponentAccessor<EntityStore> componentAccessor
) { ) {
int maxDepth = 0; Player playerComponent = componentAccessor.getComponent(ref, Player.getComponentType());
for (LayerEntryCodec entry : this.layerArgs) { assert playerComponent != null;
maxDepth += entry.getDepth();
}
PlayerRef playerRefComponent = componentAccessor.getComponent(ref, PlayerRef.getComponentType());
assert playerRefComponent != null;
BuilderToolsPlugin.BuilderState builderState = BuilderToolsPlugin.getState(playerComponent, playerRefComponent);
if (edit.getBlock(x, y, z) <= 0) { if (edit.getBlock(x, y, z) <= 0) {
return true; return true;
} else { } else {
Map<String, Object> toolArgs = this.getToolArgs(ref, componentAccessor); Map<String, Object> toolArgs = this.getToolArgs(ref, componentAccessor);
List<Pair<Integer, String>> layers = new ArrayList<>();
int maxDepth = 0;
for (int depth = 0; depth < maxDepth; depth++) { for (LayerEntryCodec layer : this.layerArgs) {
if (edit.getBlock(x, y + depth + 1, z) <= 0) { if (!layer.isSkip()) {
int depthTestingAt = 0; maxDepth += layer.getDepth();
layers.add(Pair.of(layer.getDepth(), this.resolveBlockPattern(layer, toolArgs, brushConfig)));
for (LayerEntryCodec entry : this.layerArgs) {
depthTestingAt += entry.getDepth();
if (depth < depthTestingAt) {
if (entry.isSkip()) {
return true;
}
int blockId = this.resolveBlockId(entry, toolArgs, brushConfig);
if (blockId >= 0) {
edit.setBlock(x, y, z, blockId);
}
return true;
}
}
} }
} }
BlockAccessor chunk = edit.getAccessor().getChunk(ChunkUtil.indexChunkFromBlock(x, z));
builderState.layer(x, y, z, layers, maxDepth, Vector3i.DOWN, (WorldChunk)chunk, edit.getBefore(), edit.getAfter());
return true; return true;
} }
} }
private int resolveBlockId(LayerEntryCodec entry, @Nullable Map<String, Object> toolArgs, BrushConfig brushConfig) { private String resolveBlockPattern(LayerEntryCodec entry, @Nullable Map<String, Object> toolArgs, BrushConfig brushConfig) {
if (entry.isUseToolArg()) { if (entry.isUseToolArg()) {
if (toolArgs != null && toolArgs.containsKey(entry.getMaterial())) { if (toolArgs != null && toolArgs.containsKey(entry.getMaterial())) {
if (toolArgs.get(entry.getMaterial()) instanceof BlockPattern blockPattern) { if (toolArgs.get(entry.getMaterial()) instanceof BlockPattern blockPattern) {
return blockPattern.nextBlock(brushConfig.getRandom()); return blockPattern.toString();
} else { } else {
brushConfig.setErrorFlag("Layer: Tool arg '" + entry.getMaterial() + "' is not a Block type"); brushConfig.setErrorFlag("Layer: Tool arg '" + entry.getMaterial() + "' is not a Block type");
return -1; return "";
} }
} else { } else {
brushConfig.setErrorFlag("Layer: Tool arg '" + entry.getMaterial() + "' not found"); brushConfig.setErrorFlag("Layer: Tool arg '" + entry.getMaterial() + "' not found");
return -1; return "";
} }
} else { } else {
return BlockType.getAssetMap().getIndex(entry.getMaterial()); return entry.getMaterial();
} }
} }

View File

@@ -2,13 +2,18 @@ package com.hypixel.hytale.builtin.buildertools.tooloperations;
import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.vector.Vector3i; import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.packets.buildertools.BuilderToolOnUseInteraction; import com.hypixel.hytale.protocol.packets.buildertools.BuilderToolOnUseInteraction;
import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation; import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern; import com.hypixel.hytale.server.core.universe.world.accessor.BlockAccessor;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.Pair;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class LayersOperation extends ToolOperation { public class LayersOperation extends ToolOperation {
@@ -18,17 +23,16 @@ public class LayersOperation extends ToolOperation {
private final boolean enableLayerTwo; private final boolean enableLayerTwo;
private final int layerThreeLength; private final int layerThreeLength;
private final boolean enableLayerThree; private final boolean enableLayerThree;
private final BlockPattern layerOneBlockPattern; private final String layerOneBlockPattern;
private final BlockPattern layerTwoBlockPattern; private final String layerTwoBlockPattern;
private final BlockPattern layerThreeBlockPattern; private final String layerThreeBlockPattern;
private final int brushDensity; private final int brushDensity;
private final int maxDepthNecessary; private final int maxDepthNecessary;
private boolean failed; private boolean failed;
private final int layerTwoDepthEnd;
private final int layerThreeDepthEnd;
private final boolean skipLayerOne; private final boolean skipLayerOne;
private final boolean skipLayerTwo; private final boolean skipLayerTwo;
private final boolean skipLayerThree; private final boolean skipLayerThree;
private List<Pair<Integer, String>> layers;
public LayersOperation( public LayersOperation(
@Nonnull Ref<EntityStore> ref, @Nonnull Ref<EntityStore> ref,
@@ -72,17 +76,28 @@ public class LayersOperation extends ToolOperation {
this.layerOneLength = (Integer)this.args.tool().get("bLayerOneLength"); this.layerOneLength = (Integer)this.args.tool().get("bLayerOneLength");
this.layerTwoLength = (Integer)this.args.tool().get("eLayerTwoLength"); this.layerTwoLength = (Integer)this.args.tool().get("eLayerTwoLength");
this.layerThreeLength = (Integer)this.args.tool().get("hLayerThreeLength"); this.layerThreeLength = (Integer)this.args.tool().get("hLayerThreeLength");
this.layerOneBlockPattern = (BlockPattern)this.args.tool().get("cLayerOneMaterial"); this.layerOneBlockPattern = this.args.tool().get("cLayerOneMaterial").toString();
this.layerTwoBlockPattern = (BlockPattern)this.args.tool().get("fLayerTwoMaterial"); this.layerTwoBlockPattern = this.args.tool().get("fLayerTwoMaterial").toString();
this.layerThreeBlockPattern = (BlockPattern)this.args.tool().get("iLayerThreeMaterial"); this.layerThreeBlockPattern = this.args.tool().get("iLayerThreeMaterial").toString();
this.enableLayerTwo = (Boolean)this.args.tool().get("dEnableLayerTwo"); this.enableLayerTwo = (Boolean)this.args.tool().get("dEnableLayerTwo");
this.enableLayerThree = (Boolean)this.args.tool().get("gEnableLayerThree"); this.enableLayerThree = (Boolean)this.args.tool().get("gEnableLayerThree");
this.skipLayerOne = (Boolean)this.args.tool().getOrDefault("kSkipLayerOne", false); this.skipLayerOne = (Boolean)this.args.tool().getOrDefault("kSkipLayerOne", false);
this.skipLayerTwo = (Boolean)this.args.tool().getOrDefault("lSkipLayerTwo", false); this.skipLayerTwo = (Boolean)this.args.tool().getOrDefault("lSkipLayerTwo", false);
this.skipLayerThree = (Boolean)this.args.tool().getOrDefault("mSkipLayerThree", false); this.skipLayerThree = (Boolean)this.args.tool().getOrDefault("mSkipLayerThree", false);
this.layers = new ArrayList<>();
if (!this.skipLayerOne) {
this.layers.add(Pair.of(this.layerOneLength, this.layerOneBlockPattern));
}
if (!this.skipLayerTwo && this.enableLayerTwo) {
this.layers.add(Pair.of(this.layerTwoLength, this.layerTwoBlockPattern));
}
if (!this.skipLayerThree && this.enableLayerThree) {
this.layers.add(Pair.of(this.layerThreeLength, this.layerThreeBlockPattern));
}
this.maxDepthNecessary = this.layerOneLength + (this.enableLayerTwo ? this.layerTwoLength : 0) + (this.enableLayerThree ? this.layerThreeLength : 0); this.maxDepthNecessary = this.layerOneLength + (this.enableLayerTwo ? this.layerTwoLength : 0) + (this.enableLayerThree ? this.layerThreeLength : 0);
this.layerTwoDepthEnd = this.layerOneLength + this.layerTwoLength;
this.layerThreeDepthEnd = this.layerTwoDepthEnd + this.layerThreeLength;
if (this.enableLayerThree && !this.enableLayerTwo) { if (this.enableLayerThree && !this.enableLayerTwo) {
player.sendMessage(Message.translation("server.builderTools.layerOperation.layerTwoRequired")); player.sendMessage(Message.translation("server.builderTools.layerOperation.layerTwoRequired"));
this.failed = true; this.failed = true;
@@ -95,75 +110,13 @@ public class LayersOperation extends ToolOperation {
return false; return false;
} else if (this.random.nextInt(100) > this.brushDensity) { } else if (this.random.nextInt(100) > this.brushDensity) {
return true; return true;
} else { } else if (this.edit.getBlock(x, y, z) <= 0) {
int currentBlock = this.edit.getBlock(x, y, z);
if (currentBlock <= 0) {
return true; return true;
} else { } else {
if (this.depthDirection.x == 1) { BlockAccessor chunk = this.edit.getAccessor().getChunk(ChunkUtil.indexChunkFromBlock(x, z));
for (int i = 0; i < this.maxDepthNecessary; i++) { this.builderState
if (this.edit.getBlock(x - i - 1, y, z) <= 0 && this.attemptSetBlock(x, y, z, i)) { .layer(x, y, z, this.layers, this.maxDepthNecessary, this.depthDirection, (WorldChunk)chunk, this.edit.getBefore(), this.edit.getAfter());
return true; return true;
} }
} }
} else if (this.depthDirection.x == -1) {
for (int ix = 0; ix < this.maxDepthNecessary; ix++) {
if (this.edit.getBlock(x + ix + 1, y, z) <= 0 && this.attemptSetBlock(x, y, z, ix)) {
return true;
}
}
} else if (this.depthDirection.y == 1) {
for (int ixx = 0; ixx < this.maxDepthNecessary; ixx++) {
if (this.edit.getBlock(x, y - ixx - 1, z) <= 0 && this.attemptSetBlock(x, y, z, ixx)) {
return true;
}
}
} else if (this.depthDirection.y == -1) {
for (int ixxx = 0; ixxx < this.maxDepthNecessary; ixxx++) {
if (this.edit.getBlock(x, y + ixxx + 1, z) <= 0 && this.attemptSetBlock(x, y, z, ixxx)) {
return true;
}
}
} else if (this.depthDirection.z == 1) {
for (int ixxxx = 0; ixxxx < this.maxDepthNecessary; ixxxx++) {
if (this.edit.getBlock(x, y, z - ixxxx - 1) <= 0 && this.attemptSetBlock(x, y, z, ixxxx)) {
return true;
}
}
} else if (this.depthDirection.z == -1) {
for (int ixxxxx = 0; ixxxxx < this.maxDepthNecessary; ixxxxx++) {
if (this.edit.getBlock(x, y, z + ixxxxx + 1) <= 0 && this.attemptSetBlock(x, y, z, ixxxxx)) {
return true;
}
}
}
return true;
}
}
}
public boolean attemptSetBlock(int x, int y, int z, int depth) {
if (depth < this.layerOneLength) {
if (!this.skipLayerOne) {
this.edit.setBlock(x, y, z, this.layerOneBlockPattern.nextBlock(this.random));
}
return true;
} else if (this.enableLayerTwo && depth < this.layerTwoDepthEnd) {
if (!this.skipLayerTwo && !this.layerTwoBlockPattern.isEmpty()) {
this.edit.setBlock(x, y, z, this.layerTwoBlockPattern.nextBlock(this.random));
}
return true;
} else if (this.enableLayerThree && depth < this.layerThreeDepthEnd) {
if (!this.skipLayerThree && !this.layerThreeBlockPattern.isEmpty()) {
this.edit.setBlock(x, y, z, this.layerThreeBlockPattern.nextBlock(this.random));
}
return true;
} else {
return false;
}
}
} }

View File

@@ -8,6 +8,7 @@ import com.hypixel.hytale.server.core.command.system.basecommands.CommandBase;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class EchoCommand extends CommandBase { public class EchoCommand extends CommandBase {
@Nonnull
private final RequiredArg<String> messageArg = this.withRequiredArg("message", "server.commands.echos.message.desc", ArgTypes.STRING); private final RequiredArg<String> messageArg = this.withRequiredArg("message", "server.commands.echos.message.desc", ArgTypes.STRING);
public EchoCommand() { public EchoCommand() {

View File

@@ -24,9 +24,15 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class MacroCommandBase extends AbstractAsyncCommand { public class MacroCommandBase extends AbstractAsyncCommand {
@Nonnull
public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass(); public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
@Nonnull
private static final Pattern regexBracketPattern = Pattern.compile("\\{(.*?)}"); private static final Pattern regexBracketPattern = Pattern.compile("\\{(.*?)}");
@Nonnull
private static final Pattern PATTERN = Pattern.compile("\\\\\\{");
@Nonnull
private final Map<String, Argument<?, ?>> arguments = new Object2ObjectOpenHashMap<>(); private final Map<String, Argument<?, ?>> arguments = new Object2ObjectOpenHashMap<>();
@Nonnull
private final List<Pair<String, List<MacroCommandReplacement>>> commandReplacements = new ObjectArrayList<>(); private final List<Pair<String, List<MacroCommandReplacement>>> commandReplacements = new ObjectArrayList<>();
private final Map<String, String> defaultValueStrings = new Object2ObjectOpenHashMap<>(); private final Map<String, String> defaultValueStrings = new Object2ObjectOpenHashMap<>();
@@ -96,7 +102,7 @@ public class MacroCommandBase extends AbstractAsyncCommand {
} }
} }
command = command.replaceAll("\\\\\\{", "{"); command = PATTERN.matcher(command).replaceAll("{");
commands[i] = command; commands[i] = command;
this.commandReplacements.add(Pair.of(command, replacements)); this.commandReplacements.add(Pair.of(command, replacements));
} }

View File

@@ -12,6 +12,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class MacroCommandBuilder implements JsonAssetWithMap<String, DefaultAssetMap<String, MacroCommandBuilder>> { public class MacroCommandBuilder implements JsonAssetWithMap<String, DefaultAssetMap<String, MacroCommandBuilder>> {
@Nonnull
public static final AssetBuilderCodec<String, MacroCommandBuilder> CODEC = AssetBuilderCodec.builder( public static final AssetBuilderCodec<String, MacroCommandBuilder> CODEC = AssetBuilderCodec.builder(
MacroCommandBuilder.class, MacroCommandBuilder.class,
MacroCommandBuilder::new, MacroCommandBuilder::new,

View File

@@ -6,8 +6,10 @@ import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.codec.codecs.EnumCodec; import com.hypixel.hytale.codec.codecs.EnumCodec;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes; import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgumentType; import com.hypixel.hytale.server.core.command.system.arguments.types.ArgumentType;
import javax.annotation.Nonnull;
public class MacroCommandParameter { public class MacroCommandParameter {
@Nonnull
public static final BuilderCodec<MacroCommandParameter> CODEC = BuilderCodec.builder(MacroCommandParameter.class, MacroCommandParameter::new) public static final BuilderCodec<MacroCommandParameter> CODEC = BuilderCodec.builder(MacroCommandParameter.class, MacroCommandParameter::new)
.append(new KeyedCodec<>("Name", Codec.STRING, true), (macroParameter, name) -> macroParameter.name = name, macroParameter -> macroParameter.name) .append(new KeyedCodec<>("Name", Codec.STRING, true), (macroParameter, name) -> macroParameter.name = name, macroParameter -> macroParameter.name)
.add() .add()

View File

@@ -13,6 +13,7 @@ import javax.annotation.Nonnull;
public class MacroCommandPlugin extends JavaPlugin { public class MacroCommandPlugin extends JavaPlugin {
private static MacroCommandPlugin instance; private static MacroCommandPlugin instance;
@Nonnull
private final Map<String, CommandRegistration> macroCommandRegistrations = new Object2ObjectOpenHashMap<>(); private final Map<String, CommandRegistration> macroCommandRegistrations = new Object2ObjectOpenHashMap<>();
public static MacroCommandPlugin get() { public static MacroCommandPlugin get() {

View File

@@ -14,10 +14,13 @@ import javax.annotation.Nonnull;
public class WaitCommand extends AbstractAsyncCommand { public class WaitCommand extends AbstractAsyncCommand {
private static final long MILLISECONDS_TO_SECONDS_MULTIPLIER = 1000L; private static final long MILLISECONDS_TO_SECONDS_MULTIPLIER = 1000L;
@Nonnull
public static final Runnable EMPTY_RUNNABLE = () -> {}; public static final Runnable EMPTY_RUNNABLE = () -> {};
@Nonnull
private final RequiredArg<Float> timeArg = this.withRequiredArg("time", "server.commands.wait.arg.time", ArgTypes.FLOAT) private final RequiredArg<Float> timeArg = this.withRequiredArg("time", "server.commands.wait.arg.time", ArgTypes.FLOAT)
.addValidator(Validators.greaterThan(0.0F)) .addValidator(Validators.greaterThan(0.0F))
.addValidator(Validators.lessThan(1000.0F)); .addValidator(Validators.lessThan(1000.0F));
@Nonnull
private final FlagArg printArg = this.withFlagArg("print", "server.commands.wait.arg.print"); private final FlagArg printArg = this.withFlagArg("print", "server.commands.wait.arg.print");
public WaitCommand() { public WaitCommand() {

View File

@@ -19,16 +19,22 @@ import javax.annotation.Nullable;
public class BenchRecipeRegistry { public class BenchRecipeRegistry {
private final String benchId; private final String benchId;
@Nonnull
private final Map<String, Set<String>> categoryMap = new Object2ObjectOpenHashMap<>(); private final Map<String, Set<String>> categoryMap = new Object2ObjectOpenHashMap<>();
@Nonnull
private final Map<String, Set<String>> itemToIncomingRecipe = new Object2ObjectOpenHashMap<>(); private final Map<String, Set<String>> itemToIncomingRecipe = new Object2ObjectOpenHashMap<>();
@Nonnull
private final Set<String> uncategorizedRecipes = new ObjectOpenHashSet<>(); private final Set<String> uncategorizedRecipes = new ObjectOpenHashSet<>();
@Nonnull
private final Set<String> allMaterialIds = new ObjectOpenHashSet<>(); private final Set<String> allMaterialIds = new ObjectOpenHashSet<>();
@Nonnull
private final Set<String> allMaterialResourceType = new ObjectOpenHashSet<>(); private final Set<String> allMaterialResourceType = new ObjectOpenHashSet<>();
public BenchRecipeRegistry(String benchId) { public BenchRecipeRegistry(String benchId) {
this.benchId = benchId; this.benchId = benchId;
} }
@Nonnull
public Iterable<String> getIncomingRecipesForItem(@Nonnull String itemId) { public Iterable<String> getIncomingRecipesForItem(@Nonnull String itemId) {
Set<String> recipes = this.itemToIncomingRecipe.get(itemId); Set<String> recipes = this.itemToIncomingRecipe.get(itemId);
return recipes == null ? Collections.emptySet() : recipes; return recipes == null ? Collections.emptySet() : recipes;
@@ -88,7 +94,7 @@ public class BenchRecipeRegistry {
this.extractMaterialFromRecipes(this.uncategorizedRecipes); this.extractMaterialFromRecipes(this.uncategorizedRecipes);
} }
private void extractMaterialFromRecipes(Set<String> recipes) { private void extractMaterialFromRecipes(@Nonnull Set<String> recipes) {
for (String recipeId : recipes) { for (String recipeId : recipes) {
CraftingRecipe recipe = CraftingRecipe.getAssetMap().getAsset(recipeId); CraftingRecipe recipe = CraftingRecipe.getAssetMap().getAsset(recipeId);
if (recipe != null) { if (recipe != null) {
@@ -141,7 +147,7 @@ public class BenchRecipeRegistry {
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(@Nullable Object o) {
if (o != null && this.getClass() == o.getClass()) { if (o != null && this.getClass() == o.getClass()) {
BenchRecipeRegistry that = (BenchRecipeRegistry)o; BenchRecipeRegistry that = (BenchRecipeRegistry)o;
return Objects.equals(this.benchId, that.benchId) return Objects.equals(this.benchId, that.benchId)
@@ -159,6 +165,7 @@ public class BenchRecipeRegistry {
return Objects.hash(this.benchId, this.categoryMap, this.uncategorizedRecipes, this.allMaterialIds, this.allMaterialResourceType); return Objects.hash(this.benchId, this.categoryMap, this.uncategorizedRecipes, this.allMaterialIds, this.allMaterialResourceType);
} }
@Nonnull
@Override @Override
public String toString() { public String toString() {
return "BenchRecipeRegistry{benchId='" return "BenchRecipeRegistry{benchId='"

View File

@@ -25,6 +25,7 @@ import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.RefSystem; import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.event.EventRegistry;
import com.hypixel.hytale.protocol.BenchRequirement; import com.hypixel.hytale.protocol.BenchRequirement;
import com.hypixel.hytale.protocol.BenchType; import com.hypixel.hytale.protocol.BenchType;
import com.hypixel.hytale.protocol.ItemResourceType; import com.hypixel.hytale.protocol.ItemResourceType;
@@ -59,7 +60,9 @@ import javax.annotation.Nullable;
public class CraftingPlugin extends JavaPlugin { public class CraftingPlugin extends JavaPlugin {
private static CraftingPlugin instance; private static CraftingPlugin instance;
@Nonnull
private static final Map<String, BenchRecipeRegistry> registries = new Object2ObjectOpenHashMap<>(); private static final Map<String, BenchRecipeRegistry> registries = new Object2ObjectOpenHashMap<>();
@Nonnull
private static final Map<String, String[]> itemGeneratedRecipes = new Object2ObjectOpenHashMap<>(); private static final Map<String, String[]> itemGeneratedRecipes = new Object2ObjectOpenHashMap<>();
private ComponentType<EntityStore, CraftingManager> craftingManagerComponentType; private ComponentType<EntityStore, CraftingManager> craftingManagerComponentType;
@@ -69,17 +72,17 @@ public class CraftingPlugin extends JavaPlugin {
} }
@Nullable @Nullable
public static Set<String> getAvailableRecipesForCategory(String benchId, String benchCategoryId) { public static Set<String> getAvailableRecipesForCategory(@Nonnull String benchId, @Nonnull String benchCategoryId) {
BenchRecipeRegistry benchRecipeRegistry = registries.get(benchId); BenchRecipeRegistry benchRecipeRegistry = registries.get(benchId);
return benchRecipeRegistry == null ? null : benchRecipeRegistry.getRecipesForCategory(benchCategoryId); return benchRecipeRegistry == null ? null : benchRecipeRegistry.getRecipesForCategory(benchCategoryId);
} }
public static boolean isValidCraftingMaterialForBench(BenchState benchState, ItemStack itemStack) { public static boolean isValidCraftingMaterialForBench(@Nonnull BenchState benchState, @Nonnull ItemStack itemStack) {
BenchRecipeRegistry benchRecipeRegistry = registries.get(benchState.getBench().getId()); BenchRecipeRegistry benchRecipeRegistry = registries.get(benchState.getBench().getId());
return benchRecipeRegistry == null ? false : benchRecipeRegistry.isValidCraftingMaterial(itemStack); return benchRecipeRegistry == null ? false : benchRecipeRegistry.isValidCraftingMaterial(itemStack);
} }
public static boolean isValidUpgradeMaterialForBench(BenchState benchState, ItemStack itemStack) { public static boolean isValidUpgradeMaterialForBench(@Nonnull BenchState benchState, @Nonnull ItemStack itemStack) {
BenchUpgradeRequirement nextLevelUpgradeMaterials = benchState.getNextLevelUpgradeMaterials(); BenchUpgradeRequirement nextLevelUpgradeMaterials = benchState.getNextLevelUpgradeMaterials();
if (nextLevelUpgradeMaterials == null) { if (nextLevelUpgradeMaterials == null) {
return false; return false;
@@ -92,7 +95,7 @@ public class CraftingPlugin extends JavaPlugin {
ItemResourceType[] resourceTypeId = itemStack.getItem().getResourceTypes(); ItemResourceType[] resourceTypeId = itemStack.getItem().getResourceTypes();
if (resourceTypeId != null) { if (resourceTypeId != null) {
for (ItemResourceType resTypeId : resourceTypeId) { for (ItemResourceType resTypeId : resourceTypeId) {
if (resTypeId.id.equals(upgradeMaterial.getResourceTypeId())) { if (resTypeId.id != null && resTypeId.id.equals(upgradeMaterial.getResourceTypeId())) {
return true; return true;
} }
} }
@@ -118,10 +121,8 @@ public class CraftingPlugin extends JavaPlugin {
) )
); );
ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry(); ComponentRegistryProxy<EntityStore> entityStoreRegistry = this.getEntityStoreRegistry();
EventRegistry eventRegistry = this.getEventRegistry();
this.craftingManagerComponentType = entityStoreRegistry.registerComponent(CraftingManager.class, CraftingManager::new); this.craftingManagerComponentType = entityStoreRegistry.registerComponent(CraftingManager.class, CraftingManager::new);
entityStoreRegistry.registerSystem(new PlayerCraftingSystems.CraftingTickingSystem(this.craftingManagerComponentType));
entityStoreRegistry.registerSystem(new PlayerCraftingSystems.CraftingHolderSystem(this.craftingManagerComponentType));
entityStoreRegistry.registerSystem(new PlayerCraftingSystems.CraftingRefSystem(this.craftingManagerComponentType));
this.getCodecRegistry(Interaction.CODEC) this.getCodecRegistry(Interaction.CODEC)
.register("OpenBenchPage", OpenBenchPageInteraction.class, OpenBenchPageInteraction.CODEC) .register("OpenBenchPage", OpenBenchPageInteraction.class, OpenBenchPageInteraction.CODEC)
.register("OpenProcessingBench", OpenProcessingBenchInteraction.class, OpenProcessingBenchInteraction.CODEC); .register("OpenProcessingBench", OpenProcessingBenchInteraction.class, OpenProcessingBenchInteraction.CODEC);
@@ -132,16 +133,21 @@ public class CraftingPlugin extends JavaPlugin {
blockStateRegistry.registerBlockState(ProcessingBenchState.class, "processingBench", ProcessingBenchState.CODEC); blockStateRegistry.registerBlockState(ProcessingBenchState.class, "processingBench", ProcessingBenchState.CODEC);
blockStateRegistry.registerBlockState(BenchState.class, "crafting", BenchState.CODEC); blockStateRegistry.registerBlockState(BenchState.class, "crafting", BenchState.CODEC);
Window.CLIENT_REQUESTABLE_WINDOW_TYPES.put(WindowType.PocketCrafting, FieldCraftingWindow::new); Window.CLIENT_REQUESTABLE_WINDOW_TYPES.put(WindowType.PocketCrafting, FieldCraftingWindow::new);
this.getEventRegistry().register(LoadedAssetsEvent.class, CraftingRecipe.class, CraftingPlugin::onRecipeLoad); eventRegistry.register(LoadedAssetsEvent.class, CraftingRecipe.class, CraftingPlugin::onRecipeLoad);
this.getEventRegistry().register(RemovedAssetsEvent.class, CraftingRecipe.class, CraftingPlugin::onRecipeRemove); eventRegistry.register(RemovedAssetsEvent.class, CraftingRecipe.class, CraftingPlugin::onRecipeRemove);
this.getEventRegistry().register(LoadedAssetsEvent.class, Item.class, CraftingPlugin::onItemAssetLoad); eventRegistry.register(LoadedAssetsEvent.class, Item.class, CraftingPlugin::onItemAssetLoad);
this.getEventRegistry().register(RemovedAssetsEvent.class, Item.class, CraftingPlugin::onItemAssetRemove); eventRegistry.register(RemovedAssetsEvent.class, Item.class, CraftingPlugin::onItemAssetRemove);
Interaction.CODEC.register("LearnRecipe", LearnRecipeInteraction.class, LearnRecipeInteraction.CODEC); Interaction.CODEC.register("LearnRecipe", LearnRecipeInteraction.class, LearnRecipeInteraction.CODEC);
CommandManager.get().registerSystemCommand(new RecipeCommand()); CommandManager.get().registerSystemCommand(new RecipeCommand());
entityStoreRegistry.registerSystem(new CraftingPlugin.PlayerAddedSystem()); ComponentType<EntityStore, Player> playerComponentType = Player.getComponentType();
ComponentType<EntityStore, PlayerRef> playerRefComponentType = PlayerRef.getComponentType();
entityStoreRegistry.registerSystem(new PlayerCraftingSystems.CraftingTickingSystem(this.craftingManagerComponentType));
entityStoreRegistry.registerSystem(new PlayerCraftingSystems.CraftingHolderSystem(playerComponentType, this.craftingManagerComponentType));
entityStoreRegistry.registerSystem(new PlayerCraftingSystems.CraftingRefSystem(playerComponentType, this.craftingManagerComponentType));
entityStoreRegistry.registerSystem(new CraftingPlugin.PlayerAddedSystem(playerComponentType, playerRefComponentType));
} }
private static void onItemAssetLoad(LoadedAssetsEvent<String, Item, DefaultAssetMap<String, Item>> event) { private static void onItemAssetLoad(@Nonnull LoadedAssetsEvent<String, Item, DefaultAssetMap<String, Item>> event) {
List<CraftingRecipe> recipesToLoad = new ObjectArrayList<>(); List<CraftingRecipe> recipesToLoad = new ObjectArrayList<>();
for (Item item : event.getLoadedAssets().values()) { for (Item item : event.getLoadedAssets().values()) {
@@ -174,7 +180,7 @@ public class CraftingPlugin extends JavaPlugin {
} }
} }
private static void onRecipeLoad(LoadedAssetsEvent<String, CraftingRecipe, DefaultAssetMap<String, CraftingRecipe>> event) { private static void onRecipeLoad(@Nonnull LoadedAssetsEvent<String, CraftingRecipe, DefaultAssetMap<String, CraftingRecipe>> event) {
for (CraftingRecipe recipe : event.getLoadedAssets().values()) { for (CraftingRecipe recipe : event.getLoadedAssets().values()) {
for (BenchRecipeRegistry registry : registries.values()) { for (BenchRecipeRegistry registry : registries.values()) {
registry.removeRecipe(recipe.getId()); registry.removeRecipe(recipe.getId());
@@ -191,7 +197,7 @@ public class CraftingPlugin extends JavaPlugin {
computeBenchRecipeRegistries(); computeBenchRecipeRegistries();
} }
private static void onRecipeRemove(RemovedAssetsEvent<String, CraftingRecipe, DefaultAssetMap<String, CraftingRecipe>> event) { private static void onRecipeRemove(@Nonnull RemovedAssetsEvent<String, CraftingRecipe, DefaultAssetMap<String, CraftingRecipe>> event) {
for (String removedRecipeId : event.getRemovedAssets()) { for (String removedRecipeId : event.getRemovedAssets()) {
for (BenchRecipeRegistry registry : registries.values()) { for (BenchRecipeRegistry registry : registries.values()) {
registry.removeRecipe(removedRecipeId); registry.removeRecipe(removedRecipeId);
@@ -322,11 +328,19 @@ public class CraftingPlugin extends JavaPlugin {
} }
public static class PlayerAddedSystem extends RefSystem<EntityStore> { public static class PlayerAddedSystem extends RefSystem<EntityStore> {
private static final Query<EntityStore> QUERY = Archetype.of(Player.getComponentType(), PlayerRef.getComponentType()); @Nonnull
private final Query<EntityStore> query;
public PlayerAddedSystem(
@Nonnull ComponentType<EntityStore, Player> playerComponentType, @Nonnull ComponentType<EntityStore, PlayerRef> playerRefComponentType
) {
this.query = Archetype.of(playerComponentType, playerRefComponentType);
}
@Nonnull
@Override @Override
public Query<EntityStore> getQuery() { public Query<EntityStore> getQuery() {
return QUERY; return this.query;
} }
@Override @Override

View File

@@ -49,6 +49,7 @@ import com.hypixel.hytale.server.core.inventory.container.filter.FilterType;
import com.hypixel.hytale.server.core.inventory.transaction.ListTransaction; import com.hypixel.hytale.server.core.inventory.transaction.ListTransaction;
import com.hypixel.hytale.server.core.inventory.transaction.MaterialSlotTransaction; import com.hypixel.hytale.server.core.inventory.transaction.MaterialSlotTransaction;
import com.hypixel.hytale.server.core.inventory.transaction.MaterialTransaction; import com.hypixel.hytale.server.core.inventory.transaction.MaterialTransaction;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.SoundUtil; import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
@@ -422,7 +423,18 @@ public class CraftingManager implements Component<EntityStore> {
} else { } else {
List<ItemStack> itemStacks = getOutputItemStacks(craftingRecipe, quantity); List<ItemStack> itemStacks = getOutputItemStacks(craftingRecipe, quantity);
Inventory inventory = playerComponent.getInventory(); Inventory inventory = playerComponent.getInventory();
SimpleItemContainer.addOrDropItemStacks(componentAccessor, ref, inventory.getCombinedArmorHotbarStorage(), itemStacks); PlayerSettings playerSettings = componentAccessor.getComponent(ref, PlayerSettings.getComponentType());
if (playerSettings == null) {
playerSettings = PlayerSettings.defaults();
}
for (ItemStack itemStack : itemStacks) {
if (!ItemStack.isEmpty(itemStack)) {
SimpleItemContainer.addOrDropItemStack(
componentAccessor, ref, inventory.getContainerForItemPickup(itemStack.getItem(), playerSettings), itemStack
);
}
}
} }
} }
@@ -872,6 +884,7 @@ public class CraftingManager implements Component<EntityStore> {
this.timeSeconds = timeSeconds; this.timeSeconds = timeSeconds;
} }
@Nonnull
@Override @Override
public String toString() { public String toString() {
return "BenchUpgradingJob{window=" + this.window + ", timeSeconds=" + this.timeSeconds + "}"; return "BenchUpgradingJob{window=" + this.window + ", timeSeconds=" + this.timeSeconds + "}";

View File

@@ -24,6 +24,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class LearnRecipeInteraction extends SimpleInstantInteraction { public class LearnRecipeInteraction extends SimpleInstantInteraction {
@Nonnull
public static final KeyedCodec<String> ITEM_ID = new KeyedCodec<>("ItemId", Codec.STRING); public static final KeyedCodec<String> ITEM_ID = new KeyedCodec<>("ItemId", Codec.STRING);
@Nonnull @Nonnull
public static final BuilderCodec<LearnRecipeInteraction> CODEC = BuilderCodec.builder( public static final BuilderCodec<LearnRecipeInteraction> CODEC = BuilderCodec.builder(
@@ -35,7 +36,6 @@ public class LearnRecipeInteraction extends SimpleInstantInteraction {
) )
.add() .add()
.build(); .build();
public static final Message MESSAGE_MODULES_LEARN_RECIPE_INVALID_ITEM = Message.translation("server.modules.learnrecipe.invalidItem");
@Nullable @Nullable
protected String itemId; protected String itemId;

View File

@@ -30,17 +30,23 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class OpenBenchPageInteraction extends SimpleBlockInteraction { public class OpenBenchPageInteraction extends SimpleBlockInteraction {
@Nonnull
public static final OpenBenchPageInteraction SIMPLE_CRAFTING = new OpenBenchPageInteraction( public static final OpenBenchPageInteraction SIMPLE_CRAFTING = new OpenBenchPageInteraction(
"*Simple_Crafting_Default", OpenBenchPageInteraction.PageType.SIMPLE_CRAFTING "*Simple_Crafting_Default", OpenBenchPageInteraction.PageType.SIMPLE_CRAFTING
); );
@Nonnull
public static final RootInteraction SIMPLE_CRAFTING_ROOT = new RootInteraction(SIMPLE_CRAFTING.getId(), SIMPLE_CRAFTING.getId()); public static final RootInteraction SIMPLE_CRAFTING_ROOT = new RootInteraction(SIMPLE_CRAFTING.getId(), SIMPLE_CRAFTING.getId());
@Nonnull
public static final OpenBenchPageInteraction DIAGRAM_CRAFTING = new OpenBenchPageInteraction( public static final OpenBenchPageInteraction DIAGRAM_CRAFTING = new OpenBenchPageInteraction(
"*Diagram_Crafting_Default", OpenBenchPageInteraction.PageType.DIAGRAM_CRAFTING "*Diagram_Crafting_Default", OpenBenchPageInteraction.PageType.DIAGRAM_CRAFTING
); );
@Nonnull
public static final RootInteraction DIAGRAM_CRAFTING_ROOT = new RootInteraction(DIAGRAM_CRAFTING.getId(), DIAGRAM_CRAFTING.getId()); public static final RootInteraction DIAGRAM_CRAFTING_ROOT = new RootInteraction(DIAGRAM_CRAFTING.getId(), DIAGRAM_CRAFTING.getId());
@Nonnull
public static final OpenBenchPageInteraction STRUCTURAL_CRAFTING = new OpenBenchPageInteraction( public static final OpenBenchPageInteraction STRUCTURAL_CRAFTING = new OpenBenchPageInteraction(
"*Structural_Crafting_Default", OpenBenchPageInteraction.PageType.STRUCTURAL_CRAFTING "*Structural_Crafting_Default", OpenBenchPageInteraction.PageType.STRUCTURAL_CRAFTING
); );
@Nonnull
public static final RootInteraction STRUCTURAL_CRAFTING_ROOT = new RootInteraction(STRUCTURAL_CRAFTING.getId(), STRUCTURAL_CRAFTING.getId()); public static final RootInteraction STRUCTURAL_CRAFTING_ROOT = new RootInteraction(STRUCTURAL_CRAFTING.getId(), STRUCTURAL_CRAFTING.getId());
@Nonnull @Nonnull
public static final BuilderCodec<OpenBenchPageInteraction> CODEC = BuilderCodec.builder( public static final BuilderCodec<OpenBenchPageInteraction> CODEC = BuilderCodec.builder(

View File

@@ -33,6 +33,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class OpenProcessingBenchInteraction extends SimpleBlockInteraction { public class OpenProcessingBenchInteraction extends SimpleBlockInteraction {
@Nonnull
public static final BuilderCodec<OpenProcessingBenchInteraction> CODEC = BuilderCodec.builder( public static final BuilderCodec<OpenProcessingBenchInteraction> CODEC = BuilderCodec.builder(
OpenProcessingBenchInteraction.class, OpenProcessingBenchInteraction::new, SimpleBlockInteraction.CODEC OpenProcessingBenchInteraction.class, OpenProcessingBenchInteraction::new, SimpleBlockInteraction.CODEC
) )
@@ -83,7 +84,7 @@ public class OpenProcessingBenchInteraction extends SimpleBlockInteraction {
if (currentBlockType != null) { if (currentBlockType != null) {
String interactionState = BlockAccessor.getCurrentInteractionState(currentBlockType); String interactionState = BlockAccessor.getCurrentInteractionState(currentBlockType);
if (windows.isEmpty() && !"Processing".equals(interactionState) && !"ProcessCompleted".equals(interactionState)) { if (windows.isEmpty() && !"Processing".equals(interactionState) && !"ProcessCompleted".equals(interactionState)) {
world.setBlockInteractionState(pos, currentBlockType, "default"); world.setBlockInteractionState(pos, benchState.getBaseBlockType(), benchState.getTierStateName());
} }
int soundEventIndexx = blockType.getBench().getLocalCloseSoundEventIndex(); int soundEventIndexx = blockType.getBench().getLocalCloseSoundEventIndex();

View File

@@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class BenchState extends BlockState implements DestroyableBlockState { public class BenchState extends BlockState implements DestroyableBlockState {
@Nonnull
public static BuilderCodec<BenchState> CODEC = BuilderCodec.builder(BenchState.class, BenchState::new, BlockState.BASE_CODEC) public static BuilderCodec<BenchState> CODEC = BuilderCodec.builder(BenchState.class, BenchState::new, BlockState.BASE_CODEC)
.appendInherited( .appendInherited(
new KeyedCodec<>("TierLevel", Codec.INTEGER), new KeyedCodec<>("TierLevel", Codec.INTEGER),
@@ -47,6 +48,7 @@ public class BenchState extends BlockState implements DestroyableBlockState {
private int tierLevel = 1; private int tierLevel = 1;
protected ItemStack[] upgradeItems = ItemStack.EMPTY_ARRAY; protected ItemStack[] upgradeItems = ItemStack.EMPTY_ARRAY;
protected Bench bench; protected Bench bench;
@Nonnull
protected final Map<UUID, BenchWindow> windows = new ConcurrentHashMap<>(); protected final Map<UUID, BenchWindow> windows = new ConcurrentHashMap<>();
public int getTierLevel() { public int getTierLevel() {
@@ -71,7 +73,7 @@ public class BenchState extends BlockState implements DestroyableBlockState {
} }
} }
public void addUpgradeItems(List<ItemStack> consumed) { public void addUpgradeItems(@Nonnull List<ItemStack> consumed) {
consumed.addAll(Arrays.asList(this.upgradeItems)); consumed.addAll(Arrays.asList(this.upgradeItems));
this.upgradeItems = consumed.toArray(ItemStack[]::new); this.upgradeItems = consumed.toArray(ItemStack[]::new);
this.markNeedsSave(); this.markNeedsSave();
@@ -111,6 +113,7 @@ public class BenchState extends BlockState implements DestroyableBlockState {
this.getChunk().setBlockInteractionState(this.getBlockPosition(), this.getBaseBlockType(), this.getTierStateName()); this.getChunk().setBlockInteractionState(this.getBlockPosition(), this.getBaseBlockType(), this.getTierStateName());
} }
@Nonnull
public BlockType getBaseBlockType() { public BlockType getBaseBlockType() {
BlockType currentBlockType = this.getBlockType(); BlockType currentBlockType = this.getBlockType();
String baseBlockKey = currentBlockType.getDefaultStateKey(); String baseBlockKey = currentBlockType.getDefaultStateKey();
@@ -122,6 +125,7 @@ public class BenchState extends BlockState implements DestroyableBlockState {
return baseBlockType; return baseBlockType;
} }
@Nonnull
public String getTierStateName() { public String getTierStateName() {
return this.tierLevel > 1 ? "Tier" + this.tierLevel : "default"; return this.tierLevel > 1 ? "Tier" + this.tierLevel : "default";
} }

View File

@@ -16,6 +16,7 @@ import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.event.EventPriority; import com.hypixel.hytale.event.EventPriority;
import com.hypixel.hytale.logger.HytaleLogger; import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.util.MathUtil; import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f; import com.hypixel.hytale.math.vector.Vector3f;
@@ -48,6 +49,7 @@ import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
import com.hypixel.hytale.server.core.universe.world.SoundUtil; import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.accessor.BlockAccessor; import com.hypixel.hytale.server.core.universe.world.accessor.BlockAccessor;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.chunk.state.TickableBlockState; import com.hypixel.hytale.server.core.universe.world.chunk.state.TickableBlockState;
import com.hypixel.hytale.server.core.universe.world.meta.BlockState; import com.hypixel.hytale.server.core.universe.world.meta.BlockState;
import com.hypixel.hytale.server.core.universe.world.meta.state.DestroyableBlockState; import com.hypixel.hytale.server.core.universe.world.meta.state.DestroyableBlockState;
@@ -70,8 +72,10 @@ import javax.annotation.Nullable;
import org.bson.BsonDocument; import org.bson.BsonDocument;
public class ProcessingBenchState extends BenchState implements TickableBlockState, ItemContainerBlockState, DestroyableBlockState, PlacedByBlockState { public class ProcessingBenchState extends BenchState implements TickableBlockState, ItemContainerBlockState, DestroyableBlockState, PlacedByBlockState {
@Nonnull
public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass(); public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
public static final boolean EXACT_RESOURCE_AMOUNTS = true; public static final boolean EXACT_RESOURCE_AMOUNTS = true;
@Nonnull
public static final Codec<ProcessingBenchState> CODEC = BuilderCodec.builder(ProcessingBenchState.class, ProcessingBenchState::new, BenchState.CODEC) public static final Codec<ProcessingBenchState> CODEC = BuilderCodec.builder(ProcessingBenchState.class, ProcessingBenchState::new, BenchState.CODEC)
.append(new KeyedCodec<>("InputContainer", ItemContainer.CODEC), (state, o) -> state.inputContainer = o, state -> state.inputContainer) .append(new KeyedCodec<>("InputContainer", ItemContainer.CODEC), (state, o) -> state.inputContainer = o, state -> state.inputContainer)
.add() .add()
@@ -93,7 +97,9 @@ public class ProcessingBenchState extends BenchState implements TickableBlockSta
private static final float EJECT_VELOCITY = 2.0F; private static final float EJECT_VELOCITY = 2.0F;
private static final float EJECT_SPREAD_VELOCITY = 1.0F; private static final float EJECT_SPREAD_VELOCITY = 1.0F;
private static final float EJECT_VERTICAL_VELOCITY = 3.25F; private static final float EJECT_VERTICAL_VELOCITY = 3.25F;
@Nonnull
public static final String PROCESSING = "Processing"; public static final String PROCESSING = "Processing";
@Nonnull
public static final String PROCESS_COMPLETED = "ProcessCompleted"; public static final String PROCESS_COMPLETED = "ProcessCompleted";
private ProcessingBench processingBench; private ProcessingBench processingBench;
private ItemContainer inputContainer; private ItemContainer inputContainer;
@@ -104,7 +110,9 @@ public class ProcessingBenchState extends BenchState implements TickableBlockSta
private float fuelTime; private float fuelTime;
private int lastConsumedFuelTotal; private int lastConsumedFuelTotal;
private int nextExtra = -1; private int nextExtra = -1;
@Nonnull
private final Set<Short> processingSlots = new HashSet<>(); private final Set<Short> processingSlots = new HashSet<>();
@Nonnull
private final Set<Short> processingFuelSlots = new HashSet<>(); private final Set<Short> processingFuelSlots = new HashSet<>();
@Nullable @Nullable
private String recipeId; private String recipeId;
@@ -766,7 +774,16 @@ public class ProcessingBenchState extends BenchState implements TickableBlockSta
private void playSound(@Nonnull World world, int soundEventIndex, @Nonnull ComponentAccessor<EntityStore> componentAccessor) { private void playSound(@Nonnull World world, int soundEventIndex, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
if (soundEventIndex != 0) { if (soundEventIndex != 0) {
Vector3i pos = this.getBlockPosition(); Vector3i pos = this.getBlockPosition();
SoundUtil.playSoundEvent3d(soundEventIndex, SoundCategory.SFX, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, componentAccessor); WorldChunk chunk = world.getChunk(ChunkUtil.indexChunkFromBlock(pos.x, pos.z));
int rotationIndex = chunk.getRotationIndex(pos.x, pos.y, pos.z);
Vector3d soundPos = new Vector3d();
BlockType blockType = this.getBlockType();
if (blockType != null) {
blockType.getBlockCenter(rotationIndex, soundPos);
}
soundPos.add(pos);
SoundUtil.playSoundEvent3d(soundEventIndex, SoundCategory.SFX, soundPos, componentAccessor);
} }
} }

Some files were not shown because too many files have changed in this diff Show More