Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package draaft.command;

import net.minecraft.entity.Entity;

public interface CommandFunctionManagerInterface {
void draaft$entitySpawn(Entity entity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package draaft.mixin.server.function;

import draaft.command.CommandFunctionManagerInterface;
import net.minecraft.entity.Entity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.function.CommandFunction;
import net.minecraft.server.function.CommandFunctionManager;
import net.minecraft.server.function.FunctionLoader;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.List;

@Mixin(CommandFunctionManager.class)
public abstract class CommandFunctionManagerMixin implements CommandFunctionManagerInterface {
@Shadow @Final private MinecraftServer server;

@Shadow public abstract int execute(CommandFunction function, ServerCommandSource source);

@Unique
private static final Identifier ENTITY_SPAWN = new Identifier("draaft", "entity_spawn");

@Unique
private List<CommandFunction> entitySpawnFunctions = List.of();

@Inject(method = "method_29773", remap = false, at = @At("TAIL"))
private void afterLoad(FunctionLoader functionLoader, CallbackInfo ci) {
entitySpawnFunctions = functionLoader.getTags().getOrCreate(ENTITY_SPAWN).values();
}

@Override
public void draaft$entitySpawn(Entity entity) {
this.server.getProfiler().push(ENTITY_SPAWN::toString);

for (var cmd : entitySpawnFunctions) {
this.execute(cmd, entity.getCommandSource().withLevel(2).withSilent());
}

this.server.getProfiler().pop();
}
}
17 changes: 17 additions & 0 deletions src/main/java/draaft/mixin/server/world/ServerWorldMixin.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package draaft.mixin.server.world;

import draaft.command.CommandFunctionManagerInterface;
import draaft.persistent.WorldManifest;
import draaft.world.ServerWorldInterface;
import net.minecraft.entity.Entity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.profiler.Profiler;
Expand All @@ -17,7 +19,10 @@
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Random;
import java.util.function.Supplier;
Expand Down Expand Up @@ -142,6 +147,18 @@ private int injectedRain(int rainTime) {
return rainTime;
}

@Inject(method = "addEntity", at = @At("TAIL"))
void afterSpawnEntity(Entity entity, CallbackInfoReturnable<Boolean> cir) {
// note: this injection point can cause some spurious draaft:entity_spawn triggers, but that's fine (?)
if (cir.getReturnValue()) {
var server = entity.getServer();

assert server != null;

((CommandFunctionManagerInterface) server.getCommandFunctionManager()).draaft$entitySpawn(entity);
}
}

@Override
public WorldManifest draaft$getWorldManifest() {
return this.worldManifest;
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/draaft.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"screen.slot.TradeOutputSlotMixin",
"server.MinecraftServerAccessor",
"server.PlayerManagerMixin",
"server.function.CommandFunctionManagerMixin",
"server.world.ServerWorldMixin",
"structure.IglooGeneratorMixin",
"structure.StructurePieceMixin",
Expand Down