Merge branch 'master' into 1.16
# Conflicts: # src/main/java/carpet/CarpetSettings.java # src/main/java/carpet/script/CarpetScriptServer.java # src/main/java/carpet/script/bundled/Module.java
This commit is contained in:
commit
f29153c3d2
21 files changed
+601
-74
No files matched your search
@@ -57,7 +57,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
if (sm != null) sm.attachServer(server);
|
||||
e.onServerLoaded(server);
|
||||
});
|
||||
scriptServer = new CarpetScriptServer();
|
||||
scriptServer = new CarpetScriptServer(server);
|
||||
scriptServer.loadAllWorldScripts();
|
||||
MobAI.resetTrackers();
|
||||
LoggerRegistry.initLoggers();
|
||||
|
||||
@@ -498,8 +498,8 @@ public class CarpetSettings
|
||||
if (server.isDedicated())
|
||||
{
|
||||
int vd = (newValue >= 2)?newValue:((DedicatedServer) server).getProperties().viewDistance;
|
||||
if (vd != CarpetServer.minecraft_server.getPlayerManager().getViewDistance())
|
||||
CarpetServer.minecraft_server.getPlayerManager().setViewDistance(vd);
|
||||
if (vd != server.getPlayerManager().getViewDistance())
|
||||
server.getPlayerManager().setViewDistance(vd);
|
||||
return newValue;
|
||||
}
|
||||
else
|
||||
@@ -546,6 +546,7 @@ public class CarpetSettings
|
||||
//must been some startup thing
|
||||
return newValue;
|
||||
}
|
||||
if (CarpetServer.minecraft_server == null) return newValue;
|
||||
ServerWorld currentOverworld = CarpetServer.minecraft_server.getWorld(World.OVERWORLD); // OW
|
||||
if (currentOverworld != null)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ import net.minecraft.command.arguments.DimensionArgumentType;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
@@ -197,7 +198,7 @@ public class SpawnCommand
|
||||
TickSpeed.tickrate_advance(null, 0, null, null);
|
||||
// tick warp given player
|
||||
ServerCommandSource csource = null;
|
||||
PlayerEntity player = null;
|
||||
ServerPlayerEntity player = null;
|
||||
try
|
||||
{
|
||||
player = source.getPlayer();
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.BaseText;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
@@ -80,7 +81,7 @@ public class TickCommand
|
||||
|
||||
private static int setWarp(ServerCommandSource source, int advance, String tail_command)
|
||||
{
|
||||
PlayerEntity player = null;
|
||||
ServerPlayerEntity player = null;
|
||||
try
|
||||
{
|
||||
player = source.getPlayer();
|
||||
|
||||
@@ -7,8 +7,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import carpet.logging.logHelpers.ExplosionLogHelper;
|
||||
import carpet.mixins.ExplosionAccessor;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.mixins.ExplosionMixin;
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.Lists;
|
||||
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
|
||||
@@ -51,6 +53,7 @@ public class OptimizedExplosion
|
||||
private static List<Entity> entitylist;
|
||||
private static Vec3d vec3dmem;
|
||||
private static long tickmem;
|
||||
private static Vec3d vec3dZero = new Vec3d(0, 0, 0);
|
||||
// For disabling the explosion particles and sound
|
||||
public static int explosionSound = 0;
|
||||
|
||||
@@ -66,7 +69,7 @@ public class OptimizedExplosion
|
||||
private static ArrayList<Float> chances = new ArrayList<>();
|
||||
private static BlockPos blastChanceLocation;
|
||||
|
||||
public static void doExplosionA(Explosion e) {
|
||||
public static void doExplosionA(Explosion e, ExplosionLogHelper eLogger) {
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
|
||||
blastCalc(e);
|
||||
@@ -120,6 +123,9 @@ public class OptimizedExplosion
|
||||
entity.getX() == eAccess.getEntity().getX() &&
|
||||
entity.getY() == eAccess.getEntity().getY() &&
|
||||
entity.getZ() == eAccess.getEntity().getZ()) {
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, new Vec3d(0,-0.9923437498509884d, 0));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -158,6 +164,10 @@ public class OptimizedExplosion
|
||||
d11 = ProtectionEnchantment.transformExplosionKnockback((LivingEntity) entity, d10);
|
||||
}
|
||||
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, new Vec3d(d5 * d11, d7 * d11, d9 * d11));
|
||||
}
|
||||
|
||||
entity.setVelocity(entity.getVelocity().add(d5 * d11, d7 * d11, d9 * d11));
|
||||
|
||||
if (entity instanceof PlayerEntity) {
|
||||
|
||||
@@ -7,10 +7,10 @@ import java.util.function.BiConsumer;
|
||||
import carpet.CarpetServer;
|
||||
import carpet.network.ServerNetworkHandler;
|
||||
import carpet.utils.Messenger;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.BaseText;
|
||||
|
||||
public class TickSpeed
|
||||
@@ -21,7 +21,7 @@ public class TickSpeed
|
||||
public static long time_bias = 0;
|
||||
public static long time_warp_start_time = 0;
|
||||
public static long time_warp_scheduled_ticks = 0;
|
||||
public static PlayerEntity time_advancerer = null;
|
||||
public static ServerPlayerEntity time_advancerer = null;
|
||||
public static String tick_warp_callback = null;
|
||||
public static ServerCommandSource tick_warp_sender = null;
|
||||
public static int player_active_timeout = 0;
|
||||
@@ -68,13 +68,14 @@ public class TickSpeed
|
||||
player_active_timeout = PLAYER_GRACE+ticks;
|
||||
}
|
||||
|
||||
public static BaseText tickrate_advance(PlayerEntity player, int advance, String callback, ServerCommandSource source)
|
||||
public static BaseText tickrate_advance(ServerPlayerEntity player, int advance, String callback, ServerCommandSource source)
|
||||
{
|
||||
if (0 == advance)
|
||||
{
|
||||
tick_warp_callback = null;
|
||||
tick_warp_sender = null;
|
||||
if (source != tick_warp_sender) tick_warp_sender = null;
|
||||
finish_time_warp();
|
||||
tick_warp_sender = null;
|
||||
return Messenger.c("gi Warp interrupted");
|
||||
}
|
||||
if (time_bias > 0)
|
||||
|
||||
@@ -30,6 +30,7 @@ public class LoggerRegistry
|
||||
public static boolean __packets;
|
||||
public static boolean __weather;
|
||||
public static boolean __pathfinding;
|
||||
public static boolean __explosions;
|
||||
|
||||
public static void initLoggers()
|
||||
{
|
||||
@@ -52,6 +53,7 @@ public class LoggerRegistry
|
||||
registerLogger("packets", HUDLogger.stardardHUDLogger("packets", null, null));
|
||||
registerLogger("counter",HUDLogger.stardardHUDLogger("counter","white", Arrays.stream(DyeColor.values()).map(Object::toString).toArray(String[]::new)));
|
||||
registerLogger("mobcaps", HUDLogger.stardardHUDLogger("mobcaps", "dynamic",new String[]{"dynamic", "overworld", "nether","end"}));
|
||||
registerLogger("explosions", HUDLogger.stardardLogger("explosions", "brief",new String[]{"brief", "full"}));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
package carpet.logging.logHelpers;
|
||||
|
||||
import carpet.logging.LoggerRegistry;
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.text.BaseText;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ExplosionLogHelper
|
||||
{
|
||||
private final boolean createFire;
|
||||
private final Explosion.DestructionType blockDestructionType;
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final double z;
|
||||
public final Entity entity;
|
||||
private final float power;
|
||||
private boolean affectBlocks = false;
|
||||
private List<EntityChangedStatusWithCount> entityChangedStatusWithCount = Lists.newArrayList();
|
||||
|
||||
private static long lastGametime = 0;
|
||||
private static int explosionCountInCurretGT = 0;
|
||||
|
||||
public ExplosionLogHelper(Entity entity, double x, double y, double z, float power, boolean createFire, Explosion.DestructionType blockDestructionType) {
|
||||
this.entity = entity;
|
||||
this.power = power;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.createFire = createFire;
|
||||
this.blockDestructionType = blockDestructionType;
|
||||
}
|
||||
|
||||
public void setAffectBlocks(boolean b)
|
||||
{
|
||||
affectBlocks = b;
|
||||
}
|
||||
|
||||
public void onExplosionDone(long gametime)
|
||||
{
|
||||
BaseText timeDisplay;
|
||||
if (!(lastGametime == gametime)){
|
||||
explosionCountInCurretGT = 0;
|
||||
lastGametime = gametime;
|
||||
timeDisplay = Messenger.c("wb " + ">>>>>> CURRENT GAME TIME : ", "d " + gametime, "wb >>>>>>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
timeDisplay = Messenger.s("");
|
||||
}
|
||||
explosionCountInCurretGT++;
|
||||
LoggerRegistry.getLogger("explosions").log( (option) -> {
|
||||
switch (option)
|
||||
{
|
||||
case "brief":
|
||||
return new BaseText[]{Messenger.c(
|
||||
timeDisplay, "gb EXPLOSION", "d #" + explosionCountInCurretGT,"gb -> ",
|
||||
"w P: ", "d ",Messenger.dblt("l",x ,y ,z),
|
||||
"w affectBlocks: ", "m " + this.affectBlocks
|
||||
)};
|
||||
case "full":
|
||||
return new BaseText[]{Messenger.c(
|
||||
timeDisplay, "gb EXPLOSION", "d #" + explosionCountInCurretGT,"gb -> ",
|
||||
"w P: ", "d ",Messenger.dblt("l",x ,y ,z),
|
||||
"w createFire: ", "m " + this.createFire,
|
||||
"w power: ", "c " + this.power,
|
||||
"w destructionType: ", "c " + this.blockDestructionType.name(),
|
||||
"w affectBlocks: ", "m " + this.affectBlocks,
|
||||
"b \n", ListToText()
|
||||
)};
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public void onEntityImpacted(Entity entity, Vec3d deltaVelocity)
|
||||
{
|
||||
for (EntityChangedStatusWithCount e : entityChangedStatusWithCount)
|
||||
{
|
||||
if (e.checkIfEquals(entity, deltaVelocity))
|
||||
{
|
||||
e.count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
entityChangedStatusWithCount.add(new EntityChangedStatusWithCount(entity.getPos(), entity.getType(), deltaVelocity));
|
||||
}
|
||||
|
||||
public BaseText ListToText()
|
||||
{
|
||||
BaseText s = Messenger.s("Entities Impacted:\n");
|
||||
for (EntityChangedStatusWithCount entityChanges : entityChangedStatusWithCount)
|
||||
{
|
||||
s.append(entityChanges.asText());
|
||||
s.append("\n");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
public static class EntityChangedStatusWithCount
|
||||
{
|
||||
public final Vec3d entityPos;
|
||||
public final EntityType entityType;
|
||||
public final Vec3d deltaSpeed;
|
||||
public int count;
|
||||
public EntityChangedStatusWithCount(Vec3d entityPos, EntityType entityType, Vec3d deltaSpeed)
|
||||
{
|
||||
this.entityPos = entityPos;
|
||||
this.entityType = entityType;
|
||||
this.deltaSpeed = deltaSpeed;
|
||||
this.count = 1;
|
||||
}
|
||||
|
||||
public boolean equals(EntityChangedStatusWithCount e)
|
||||
{
|
||||
return (
|
||||
e.entityType == this.entityType &&
|
||||
e.deltaSpeed.equals(this.deltaSpeed) &&
|
||||
e.entityPos.equals(this.entityPos)
|
||||
);
|
||||
}
|
||||
|
||||
public boolean checkIfEquals(Entity e, Vec3d deltaSpeed)
|
||||
{
|
||||
return (
|
||||
e.getType() == this.entityType &&
|
||||
deltaSpeed.equals(this.deltaSpeed) &&
|
||||
e.getPos().equals(this.entityPos)
|
||||
);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return String.format("{EntityType: %s, EntityPos: %s ,DeltaSpeed: %s}", entityType.getName().asString(), entityPos.toString(), deltaSpeed.toString());
|
||||
}
|
||||
|
||||
public BaseText asText()
|
||||
{
|
||||
return Messenger.c(
|
||||
"m Entity(count="+ this.count +") of",
|
||||
"l " + Registry.ENTITY_TYPE.getId(entityType), "g {",
|
||||
"w P: ", "y ", Messenger.dblt("t", entityPos.x, entityPos.y, entityPos.z),
|
||||
"w dV: ", "gbi " + (deltaSpeed.equals(new Vec3d(0,-0.9923437498509884d, 0)) ? "<TNTs-AT-SAME-SPOT>":""),"y ", Messenger.dblt("d", deltaSpeed.x, deltaSpeed.y, deltaSpeed.z),
|
||||
"g }"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,13 @@ package carpet.mixins;
|
||||
|
||||
import carpet.helpers.OptimizedExplosion;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.logging.LoggerRegistry;
|
||||
import carpet.logging.logHelpers.ExplosionLogHelper;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@@ -24,13 +28,17 @@ public abstract class ExplosionMixin
|
||||
@Final
|
||||
private List<BlockPos> affectedBlocks;
|
||||
|
||||
@Shadow @Final private World world;
|
||||
|
||||
private ExplosionLogHelper eLogger;
|
||||
|
||||
@Inject(method = "collectBlocksAndDamageEntities", at = @At("HEAD"),
|
||||
cancellable = true)
|
||||
private void onExplosionA(CallbackInfo ci)
|
||||
{
|
||||
if (CarpetSettings.optimizedTNT)
|
||||
{
|
||||
OptimizedExplosion.doExplosionA((Explosion) (Object) this);
|
||||
OptimizedExplosion.doExplosionA((Explosion) (Object) this, eLogger);
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
@@ -39,6 +47,11 @@ public abstract class ExplosionMixin
|
||||
cancellable = true)
|
||||
private void onExplosionB(boolean spawnParticles, CallbackInfo ci)
|
||||
{
|
||||
if (eLogger != null)
|
||||
{
|
||||
eLogger.setAffectBlocks( ! affectedBlocks.isEmpty());
|
||||
eLogger.onExplosionDone(this.world.getTime());
|
||||
}
|
||||
if (CarpetSettings.explosionNoBlockDamage)
|
||||
{
|
||||
affectedBlocks.clear();
|
||||
@@ -58,4 +71,24 @@ public abstract class ExplosionMixin
|
||||
if (CarpetSettings.explosionNoBlockDamage) return Blocks.BEDROCK.getDefaultState();
|
||||
return world.getBlockState(pos);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/entity/Entity;DDDFZLnet/minecraft/world/explosion/Explosion$DestructionType;)V",
|
||||
at = @At(value = "RETURN"))
|
||||
private void onExplosionCreated(World world, Entity entity, double x, double y, double z, float power, boolean createFire, Explosion.DestructionType blockDestructionType, CallbackInfo ci)
|
||||
{
|
||||
if (LoggerRegistry.__explosions && ! world.isClient)
|
||||
{
|
||||
eLogger = new ExplosionLogHelper(entity, x, y, z, power, createFire, blockDestructionType);
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "collectBlocksAndDamageEntities",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setVelocity(Lnet/minecraft/util/math/Vec3d;)V"))
|
||||
private void setVelocityAndUpdateLogging(Entity entity, Vec3d velocity)
|
||||
{
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, velocity.subtract(entity.getVelocity()));
|
||||
}
|
||||
entity.setVelocity(velocity);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import carpet.fakes.PistonBlockEntityInterface;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.piston.PistonBehavior;
|
||||
import net.minecraft.block.piston.PistonHandler;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
@@ -62,6 +63,17 @@ public abstract class PistonBlock_movableTEMixin extends FacingBlock
|
||||
return !(CarpetSettings.movableBlockEntities && isPushableBlockEntity(block));
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "isMovable", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/BlockState;getPistonBehavior()Lnet/minecraft/block/piston/PistonBehavior;"
|
||||
))
|
||||
private static PistonBehavior moveGrindstones(BlockState blockState)
|
||||
{
|
||||
if (CarpetSettings.movableBlockEntities && blockState.getBlock() == Blocks.GRINDSTONE) return PistonBehavior.NORMAL;
|
||||
return blockState.getPistonBehavior();
|
||||
}
|
||||
|
||||
@Inject(method = "move", at = @At(value = "INVOKE", shift = At.Shift.BEFORE,
|
||||
target = "Ljava/util/List;size()I", ordinal = 4),locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void onMove(World world_1, BlockPos blockPos_1, Direction direction_1, boolean boolean_1,
|
||||
|
||||
@@ -23,7 +23,7 @@ public abstract class PlayerEntity_antiCheatDisabled
|
||||
@Inject(method = "checkFallFlying", at = @At("HEAD"), cancellable = true)
|
||||
private void allowDeploys(CallbackInfoReturnable<Boolean> cir)
|
||||
{
|
||||
if (CarpetSettings.antiCheatDisabled && CarpetServer.minecraft_server.isDedicated())
|
||||
if (CarpetSettings.antiCheatDisabled && CarpetServer.minecraft_server != null && CarpetServer.minecraft_server.isDedicated())
|
||||
{
|
||||
ItemStack itemStack_1 = getEquippedStack(EquipmentSlot.CHEST);
|
||||
if (itemStack_1.getItem() == Items.ELYTRA && ElytraItem.isUsable(itemStack_1)) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import carpet.script.value.Value;
|
||||
import carpet.utils.Messenger;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@@ -53,6 +54,7 @@ import java.util.stream.Collectors;
|
||||
public class CarpetEventServer
|
||||
{
|
||||
public final List<ScheduledCall> scheduledCalls = new LinkedList<>();
|
||||
public final MinecraftServer server;
|
||||
|
||||
public static class Callback
|
||||
{
|
||||
@@ -658,8 +660,9 @@ public class CarpetEventServer
|
||||
}
|
||||
|
||||
|
||||
public CarpetEventServer()
|
||||
public CarpetEventServer(MinecraftServer server)
|
||||
{
|
||||
this.server = server;
|
||||
for (Event e: Event.values())
|
||||
e.handler.callList.clear();
|
||||
}
|
||||
|
||||
@@ -2489,6 +2489,18 @@ public class CarpetExpression
|
||||
|
||||
}
|
||||
|
||||
public static String recognizeResource(Value value)
|
||||
{
|
||||
String origfile = value.getString();
|
||||
String file = origfile.toLowerCase(Locale.ROOT).replaceAll("[^A-Za-z0-9/]", "");
|
||||
file = Arrays.stream(file.split("/+")).filter(s -> !s.isEmpty()).collect(Collectors.joining("/"));
|
||||
if (file.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("Cannot use "+origfile+" as resource name - must have some letters and numbers");
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
private void API_AuxiliaryAspects()
|
||||
{
|
||||
this.expr.addLazyFunction("sound", -1, (c, t, lv) -> {
|
||||
@@ -2877,13 +2889,6 @@ public class CarpetExpression
|
||||
// implmenetation should dock the task on the main thread.
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("logger", 1, (c, t, lv) ->
|
||||
{
|
||||
Value res = lv.get(0).evalValue(c);
|
||||
CarpetSettings.LOG.error(res.getString());
|
||||
return (_c, _t) -> res; // pass through for variables
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("run", 1, (c, t, lv) -> {
|
||||
BlockPos target = ((CarpetContext)c).origin;
|
||||
Vec3d posf = new Vec3d((double)target.getX()+0.5D,(double)target.getY(),(double)target.getZ()+0.5D);
|
||||
@@ -3070,25 +3075,108 @@ public class CarpetExpression
|
||||
return (c_, t_) -> Value.TRUE;
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("logger", 1, (c, t, lv) ->
|
||||
{
|
||||
Value res = lv.get(0).evalValue(c);
|
||||
CarpetSettings.LOG.error(res.getString());
|
||||
return (_c, _t) -> res; // pass through for variables
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("read_file", 2, (c, t, lv) -> {
|
||||
String resource = recognizeResource(lv.get(0).evalValue(c));
|
||||
String origtype = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||
boolean shared = origtype.startsWith("shared_");
|
||||
String type = shared ? origtype.substring(7) : origtype; //len(shared_)
|
||||
if (!type.equals("raw") && !type.equals("text") && !type.equals("nbt"))
|
||||
throw new InternalExpressionException("Unsupported file type: "+origtype);
|
||||
Value retVal;
|
||||
if (type.equals("nbt"))
|
||||
{
|
||||
Tag state = ((CarpetScriptHost)((CarpetContext)c).host).readFileTag(resource, shared);
|
||||
if (state == null) return LazyValue.NULL;
|
||||
retVal = new NBTSerializableValue(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<String> content = ((CarpetScriptHost) ((CarpetContext) c).host).readTextResource(resource, shared);
|
||||
if (content == null) return LazyValue.NULL;
|
||||
retVal = ListValue.wrap(content.stream().map(StringValue::new).collect(Collectors.toList()));
|
||||
}
|
||||
return (cc, tt) -> retVal;
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("delete_file", 2, (c, t, lv) -> {
|
||||
String resource = recognizeResource(lv.get(0).evalValue(c));
|
||||
String origtype = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||
boolean shared = origtype.startsWith("shared_");
|
||||
String type = shared ? origtype.substring(7) : origtype; //len(shared_)
|
||||
if (!type.equals("raw") && !type.equals("text") && !type.equals("nbt"))
|
||||
throw new InternalExpressionException("Unsupported file type: "+origtype);
|
||||
boolean success = ((CarpetScriptHost)((CarpetContext)c).host).removeResourceFile(resource, shared, type);
|
||||
return success?LazyValue.TRUE:LazyValue.FALSE;
|
||||
});
|
||||
|
||||
this.expr.addLazyFunction("write_file", -1, (c, t, lv) -> {
|
||||
if (lv.size() < 3) throw new InternalExpressionException("'write_file' requires three or more arguments");
|
||||
String resource = recognizeResource(lv.get(0).evalValue(c));
|
||||
String origtype = lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT);
|
||||
boolean shared = origtype.startsWith("shared_");
|
||||
String type = shared ? origtype.substring(7) : origtype; //len(shared_)
|
||||
if (!type.equals("raw") && !type.equals("text") && !type.equals("nbt"))
|
||||
throw new InternalExpressionException("Unsupported file type: "+origtype);
|
||||
boolean success;
|
||||
if (type.equals("nbt"))
|
||||
{
|
||||
Value val = lv.get(2).evalValue(c);
|
||||
NBTSerializableValue tagValue = (val instanceof NBTSerializableValue)
|
||||
? (NBTSerializableValue) val
|
||||
: new NBTSerializableValue(val.getString());
|
||||
Tag tag = tagValue.getTag();
|
||||
success = ((CarpetScriptHost)((CarpetContext)c).host).writeTagFile(tag, resource, shared);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<String> data = new ArrayList<>();
|
||||
if (lv.size()==3)
|
||||
{
|
||||
Value val = lv.get(2).evalValue(c);
|
||||
if (val instanceof ListValue)
|
||||
{
|
||||
List<Value> lval = ((ListValue) val).getItems();
|
||||
lval.forEach(v -> data.add(v.getString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
data.add(val.getString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 2; i < lv.size(); i++)
|
||||
{
|
||||
data.add(lv.get(i).evalValue(c).getString());
|
||||
}
|
||||
}
|
||||
success = ((CarpetScriptHost) ((CarpetContext) c).host).appendLogFile(resource, shared, type, data);
|
||||
}
|
||||
return success?LazyValue.TRUE:LazyValue.FALSE;
|
||||
});
|
||||
|
||||
//write_file
|
||||
|
||||
this.expr.addLazyFunction("load_app_data", -1, (c, t, lv) ->
|
||||
{
|
||||
String file = null;
|
||||
boolean shared = false;
|
||||
if (lv.size()>0)
|
||||
{
|
||||
String origfile = lv.get(0).evalValue(c).getString();
|
||||
file = origfile.toLowerCase(Locale.ROOT).replaceAll("[^A-Za-z0-9/]", "");
|
||||
file = Arrays.stream(file.split("/+")).filter(s -> !s.isEmpty()).collect(Collectors.joining("/"));
|
||||
if (file.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("Cannot use "+origfile+" as resource name - must have at least some letters and numbers");
|
||||
}
|
||||
file = recognizeResource(lv.get(0).evalValue(c));
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
shared = lv.get(1).evalValue(c).getBoolean();
|
||||
}
|
||||
}
|
||||
Tag state = ((CarpetScriptHost)((CarpetContext)c).host).getGlobalState(file, shared);
|
||||
Tag state = ((CarpetScriptHost)((CarpetContext)c).host).readFileTag(file, shared);
|
||||
if (state == null)
|
||||
return (cc, tt) -> Value.NULL;
|
||||
Value retVal = new NBTSerializableValue(state);
|
||||
@@ -3104,13 +3192,7 @@ public class CarpetExpression
|
||||
boolean shared = false;
|
||||
if (lv.size()>1)
|
||||
{
|
||||
String origfile = lv.get(1).evalValue(c).getString();
|
||||
file = origfile.toLowerCase(Locale.ROOT).replaceAll("[^A-Za-z0-9/]", "");
|
||||
file = Arrays.stream(file.split("/+")).filter(s -> !s.isEmpty()).collect(Collectors.joining("/"));
|
||||
if (file.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("Cannot use "+origfile+" as resource name - must have some letters and numbers");
|
||||
}
|
||||
file = recognizeResource(lv.get(1).evalValue(c));
|
||||
if (lv.size() > 2)
|
||||
{
|
||||
shared = lv.get(2).evalValue(c).getBoolean();
|
||||
@@ -3120,7 +3202,7 @@ public class CarpetExpression
|
||||
? (NBTSerializableValue) val
|
||||
: new NBTSerializableValue(val.getString());
|
||||
Tag tag = tagValue.getTag();
|
||||
boolean success = ((CarpetScriptHost)((CarpetContext)c).host).setGlobalState(tag, file, shared);
|
||||
boolean success = ((CarpetScriptHost)((CarpetContext)c).host).writeTagFile(tag, file, shared);
|
||||
return success?LazyValue.TRUE:LazyValue.FALSE;
|
||||
});
|
||||
|
||||
|
||||
@@ -323,7 +323,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
{
|
||||
try
|
||||
{
|
||||
callUDF(BlockPos.ORIGIN, CarpetServer.minecraft_server.getCommandSource(), closing, Collections.emptyList());
|
||||
callUDF(BlockPos.ORIGIN, scriptServer.server.getCommandSource(), closing, Collections.emptyList());
|
||||
}
|
||||
catch (InvalidCallbackException ignored)
|
||||
{
|
||||
@@ -334,8 +334,8 @@ public class CarpetScriptHost extends ScriptHost
|
||||
FunctionValue userClosing = value.getFunction("__on_close");
|
||||
if (userClosing != null)
|
||||
{
|
||||
ServerPlayerEntity player = CarpetServer.minecraft_server.getPlayerManager().getPlayer(key);
|
||||
ServerCommandSource source = (player != null)?player.getCommandSource():CarpetServer.minecraft_server.getCommandSource();
|
||||
ServerPlayerEntity player = scriptServer.server.getPlayerManager().getPlayer(key);
|
||||
ServerCommandSource source = (player != null)?player.getCommandSource():scriptServer.server.getCommandSource();
|
||||
try
|
||||
{
|
||||
((CarpetScriptHost) value).callUDF(BlockPos.ORIGIN, source, userClosing, Collections.emptyList());
|
||||
@@ -347,7 +347,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
});
|
||||
|
||||
String markerName = CarpetExpression.MARKER_STRING+"_"+((getName()==null)?"":getName());
|
||||
for (ServerWorld world : CarpetServer.minecraft_server.getWorlds())
|
||||
for (ServerWorld world : scriptServer.server.getWorlds())
|
||||
{
|
||||
for (Entity e : world.getEntities(EntityType.ARMOR_STAND, (as) -> as.getScoreboardTags().contains(markerName)))
|
||||
{
|
||||
@@ -369,7 +369,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
return Module.getData(main, null, false);
|
||||
}
|
||||
|
||||
public Tag getGlobalState(String file, boolean isShared)
|
||||
public Tag readFileTag(String file, boolean isShared)
|
||||
{
|
||||
if (getName() == null && !isShared) return null;
|
||||
if (file != null)
|
||||
@@ -379,7 +379,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
return ((CarpetScriptHost)parent).globalState;
|
||||
}
|
||||
|
||||
public boolean setGlobalState(Tag tag, String file, boolean isShared)
|
||||
public boolean writeTagFile(Tag tag, String file, boolean isShared)
|
||||
{
|
||||
if (getName() == null && !isShared) return false; // if belongs to an app, cannot be default host.
|
||||
|
||||
@@ -398,6 +398,25 @@ public class CarpetScriptHost extends ScriptHost
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeResourceFile(String resource, boolean isShared, String type)
|
||||
{
|
||||
if (getName() == null && !isShared) return false; //
|
||||
return Module.dropExistingFile(main, resource, type.equals("nbt")?"nbt":"txt", isShared);
|
||||
}
|
||||
|
||||
public boolean appendLogFile(String resource, boolean isShared, String type, List<String> data)
|
||||
{
|
||||
if (getName() == null && !isShared) return false; // if belongs to an app, cannot be default host.
|
||||
return Module.appendToTextFile(main, resource, type, isShared, data);
|
||||
}
|
||||
|
||||
public List<String> readTextResource(String resource, boolean isShared)
|
||||
{
|
||||
if (getName() == null && !isShared) return null; //
|
||||
return Module.listFile(main, resource, "txt", isShared);
|
||||
}
|
||||
|
||||
|
||||
public void tick()
|
||||
{
|
||||
if (this.saveTimeout > 0)
|
||||
|
||||
@@ -36,6 +36,7 @@ import static net.minecraft.server.command.CommandManager.literal;
|
||||
public class CarpetScriptServer
|
||||
{
|
||||
//make static for now, but will change that later:
|
||||
public final MinecraftServer server;
|
||||
public CarpetScriptHost globalHost;
|
||||
public Map<String, CarpetScriptHost> modules;
|
||||
public long tickStart;
|
||||
@@ -51,19 +52,20 @@ public class CarpetScriptServer
|
||||
add(new BundledModule("math", true));
|
||||
}};
|
||||
|
||||
public CarpetScriptServer()
|
||||
public CarpetScriptServer(MinecraftServer server)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
this.server = server;
|
||||
ScriptHost.systemGlobals.clear();
|
||||
events = new CarpetEventServer();
|
||||
events = new CarpetEventServer(server);
|
||||
modules = new HashMap<>();
|
||||
tickStart = 0L;
|
||||
stopAll = false;
|
||||
holyMoly = CarpetServer.minecraft_server.getCommandManager().getDispatcher().getRoot().getChildren().stream().map(CommandNode::getName).collect(Collectors.toSet());
|
||||
holyMoly = server.getCommandManager().getDispatcher().getRoot().getChildren().stream().map(CommandNode::getName).collect(Collectors.toSet());
|
||||
globalHost = CarpetScriptHost.create(this, null, false, null);
|
||||
}
|
||||
|
||||
@@ -71,10 +73,10 @@ public class CarpetScriptServer
|
||||
{
|
||||
if (CarpetSettings.scriptsAutoload)
|
||||
{
|
||||
Messenger.m(CarpetServer.minecraft_server.getCommandSource(), "Auto-loading world scarpet apps");
|
||||
Messenger.m(server.getCommandSource(), "Auto-loading world scarpet apps");
|
||||
for (String moduleName: listAvailableModules(false))
|
||||
{
|
||||
addScriptHost(CarpetServer.minecraft_server.getCommandSource(), moduleName, true, true);
|
||||
addScriptHost(server.getCommandSource(), moduleName, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +85,8 @@ public class CarpetScriptServer
|
||||
public Module getModule(String name, boolean allowLibraries)
|
||||
{
|
||||
File folder = CarpetServer.minecraft_server.getSavePath(WorldSavePath.ROOT).resolve("scripts").toFile();
|
||||
File folder = server.getLevelStorage().resolveFile(
|
||||
server.getLevelName(), "scripts");
|
||||
File[] listOfFiles = folder.listFiles();
|
||||
if (listOfFiles != null)
|
||||
for (File script : listOfFiles)
|
||||
@@ -117,6 +121,8 @@ public class CarpetScriptServer
|
||||
}
|
||||
}
|
||||
File folder = CarpetServer.minecraft_server.getSavePath(WorldSavePath.ROOT).resolve("scripts").toFile();
|
||||
File folder = server.getLevelStorage().resolveFile(
|
||||
server.getLevelName(), "scripts");
|
||||
File[] listOfFiles = folder.listFiles();
|
||||
if (listOfFiles == null)
|
||||
return moduleNames;
|
||||
@@ -228,7 +234,7 @@ public class CarpetScriptServer
|
||||
})));
|
||||
}
|
||||
Messenger.m(source, "gi "+hostName+" app loaded with /"+hostName+" command");
|
||||
CarpetServer.minecraft_server.getCommandManager().getDispatcher().register(command);
|
||||
server.getCommandManager().getDispatcher().register(command);
|
||||
CarpetServer.settingsManager.notifyPlayersCommandsChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -173,9 +173,9 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
}
|
||||
else if (nextChar == 't')
|
||||
{
|
||||
throw new ExpressionException(context, this.expression, token,
|
||||
"Tab character is not supported");
|
||||
//token.append('\t');
|
||||
//throw new ExpressionException(context, this.expression, token,
|
||||
// "Tab character is not supported");
|
||||
token.append('\t');
|
||||
}
|
||||
else if (nextChar == 'r')
|
||||
{
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
package carpet.script.bundled;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import net.minecraft.nbt.PositionTracker;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.nbt.TagReaders;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class FileModule extends Module
|
||||
@@ -96,4 +103,44 @@ public class FileModule extends Module
|
||||
if (!file.exists()) file_2.renameTo(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean appendText(File filePath, boolean addNewLines, List<String> data)
|
||||
{
|
||||
try
|
||||
{
|
||||
OutputStream out = Files.newOutputStream(filePath.toPath(), StandardOpenOption.APPEND, StandardOpenOption.CREATE);
|
||||
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
|
||||
{
|
||||
for (String line: data)
|
||||
{
|
||||
writer.append(line);
|
||||
if (addNewLines) writer.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static List<String> listFileContent(File filePath)
|
||||
{
|
||||
try (BufferedReader reader = Files.newBufferedReader(filePath.toPath(), StandardCharsets.UTF_8)) {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (;;) {
|
||||
String line = reader.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
result.add(line.replaceAll("[\n\r]+",""));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,14 @@ import net.minecraft.util.WorldSavePath;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import static carpet.script.bundled.FileModule.read;
|
||||
import static carpet.script.bundled.FileModule.write;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Module
|
||||
{
|
||||
public abstract String getName();
|
||||
public abstract String getCode();
|
||||
public abstract boolean isLibrary();
|
||||
public final static Object writeIOSync = new Object();
|
||||
|
||||
private static String getDescriptor(Module module, String file, boolean isShared)
|
||||
{
|
||||
@@ -34,18 +33,52 @@ public abstract class Module
|
||||
|
||||
public static Tag getData(Module module, String file, boolean isShared)
|
||||
{
|
||||
File dataFile = resolveResource(module, file, "nbt", isShared);
|
||||
if (dataFile == null) return null;
|
||||
if (!isShared && (module == null || module.getName() == null)) return null;
|
||||
File dataFile = CarpetServer.minecraft_server.getSavePath(WorldSavePath.ROOT).resolve("scripts/"+getDescriptor(module, file, isShared)+".nbt").toFile();
|
||||
if (!Files.exists(dataFile.toPath()) || !(dataFile.isFile())) return null;
|
||||
return read(dataFile);
|
||||
synchronized (writeIOSync) { return FileModule.read(dataFile); }
|
||||
}
|
||||
|
||||
public static boolean saveData(Module module, String file, Tag globalState, boolean isShared)
|
||||
{
|
||||
File dataFile = resolveResource(module, file, "nbt", isShared);
|
||||
if (dataFile == null) return false;
|
||||
if (!isShared && (module == null || module.getName() == null)) return false;
|
||||
File dataFile =CarpetServer.minecraft_server.getSavePath(WorldSavePath.ROOT).resolve("scripts/"+getDescriptor(module, file, isShared)+".nbt").toFile();
|
||||
if (!Files.exists(dataFile.toPath().getParent()) && !dataFile.getParentFile().mkdirs()) return false;
|
||||
return write(globalState, dataFile);
|
||||
synchronized (writeIOSync) { return FileModule.write(globalState, dataFile); }
|
||||
}
|
||||
|
||||
public static boolean appendToTextFile(Module module, String resourceName, String type, boolean isShared, List<String> message)
|
||||
{
|
||||
File dataFile = resolveResource(module, resourceName, "txt", isShared);
|
||||
if (dataFile == null) return false;
|
||||
if (!Files.exists(dataFile.toPath().getParent()) && !dataFile.getParentFile().mkdirs()) return false;
|
||||
synchronized (writeIOSync) { return FileModule.appendText(dataFile, type.equals("text"), message); }
|
||||
}
|
||||
|
||||
public static boolean dropExistingFile(Module module, String resourceName, String ext, boolean isShared)
|
||||
{
|
||||
File dataFile = resolveResource(module, resourceName, ext, isShared);
|
||||
if (dataFile == null) return false;
|
||||
synchronized (writeIOSync) { return dataFile.delete(); }
|
||||
}
|
||||
|
||||
public static List<String> listFile(Module module, String resourceName, String ext, boolean isShared)
|
||||
{
|
||||
File dataFile = resolveResource(module, resourceName, ext, isShared);
|
||||
if (dataFile == null) return null;
|
||||
if (!dataFile.exists()) return null;
|
||||
synchronized (writeIOSync) { return FileModule.listFileContent(dataFile); }
|
||||
}
|
||||
|
||||
private static File resolveResource(Module module, String resourceName, String ext, boolean isShared)
|
||||
{
|
||||
if (!isShared && (module == null || module.getName() == null)) return null;
|
||||
return CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
||||
CarpetServer.minecraft_server.getLevelName(), "scripts/"+getDescriptor(module, resourceName, isShared)+"."+ext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -361,8 +361,7 @@ public class SettingsManager
|
||||
{
|
||||
if (dispatcher.getRoot().getChildren().stream().anyMatch(node -> node.getName().equalsIgnoreCase(identifier)))
|
||||
{
|
||||
Messenger.print_server_message(CarpetServer.minecraft_server,
|
||||
Messenger.c("rb Failed to add settings command for " + identifier + ". It is masking previous command."));
|
||||
CarpetSettings.LOG.error("Failed to add settings command for " + identifier + ". It is masking previous command.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user