Merge branch 'master' into future

This commit is contained in:
gnembon committed 2021-10-20 23:24:52 -03:00
commit 31a6bd21df
14 files changed
+223 -18

No files matched your search

+6
View File
@@ -961,6 +961,12 @@ public class CarpetSettings
)
public static String updateSuppressionBlock = "false";
@Rule(
desc = "Fixes update suppression causing server crashes.",
category = {BUGFIX}
)
public static boolean updateSuppressionCrashFix = false;
public static int getInteger(String s) {
try {
return Integer.parseInt(s);
@@ -18,6 +18,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static net.minecraft.command.CommandSource.suggestMatching;
@@ -201,8 +202,13 @@ public class LogCommand
Messenger.m(source, "r Unknown logger: ","rb "+logname);
return 0;
}
if (!LoggerRegistry.getLogger(logname).isOptionValid(option))
{
Messenger.m(source, "r Invalid option: ", "rb "+option);
return 0;
}
LoggerRegistry.subscribePlayer(player_name, logname, option);
if (option!=null)
if (option != null)
{
Messenger.m(source, "gi Subscribed to " + logname + "(" + option + ")");
}
@@ -210,6 +216,6 @@ public class LogCommand
{
Messenger.m(source, "gi Subscribed to " + logname);
}
return 1;
return 1;
}
}
@@ -14,5 +14,5 @@ public interface ThreadedAnvilChunkStorageInterface
void releaseRelightTicket(ChunkPos pos);
Iterable<ChunkHolder> getChunks();
Iterable<ChunkHolder> getChunksCM();
}
@@ -0,0 +1,12 @@
package carpet.helpers;
import net.minecraft.util.math.BlockPos;
public class ThrowableSuppression extends RuntimeException{
public final BlockPos pos;
public ThrowableSuppression(String message, BlockPos pos) {
super(message);
this.pos = pos;
}
}
+13 -3
View File
@@ -8,11 +8,16 @@ import java.lang.reflect.Field;
public class HUDLogger extends Logger
{
static Logger stardardHUDLogger(String logName, String def, String [] options)
{
return stardardHUDLogger(logName, def, options, false);
}
static Logger stardardHUDLogger(String logName, String def, String [] options, boolean strictOptions)
{
// should convert to factory method if more than 2 classes are here
try
{
return new HUDLogger(LoggerRegistry.class.getField("__"+logName), logName, def, options);
return new HUDLogger(LoggerRegistry.class.getField("__"+logName), logName, def, options, strictOptions);
}
catch (NoSuchFieldException e)
{
@@ -20,9 +25,14 @@ public class HUDLogger extends Logger
}
}
public HUDLogger(Field field, String logName, String def, String[] options)
public HUDLogger(Field field, String logName, String def, String[] options, boolean strictOptions)
{
super(field, logName, def, options);
super(field, logName, def, options, strictOptions);
}
@Deprecated
public HUDLogger(Field field, String logName, String def, String[] options) {
super(field, logName, def, options, false);
}
@Override
+23 -2
View File
@@ -32,11 +32,18 @@ public class Logger
private Field acceleratorField;
private boolean strictOptions;
static Logger stardardLogger(String logName, String def, String [] options)
{
return stardardLogger(logName, def, options, false);
}
static Logger stardardLogger(String logName, String def, String [] options, boolean strictOptions)
{
try
{
return new Logger(LoggerRegistry.class.getField("__"+logName), logName, def, options);
return new Logger(LoggerRegistry.class.getField("__"+logName), logName, def, options, strictOptions);
}
catch (NoSuchFieldException e)
{
@@ -44,7 +51,12 @@ public class Logger
}
}
public Logger(Field acceleratorField, String logName, String def, String [] options)
@Deprecated
public Logger(Field acceleratorField, String logName, String def, String [] options) {
this(acceleratorField, logName, def, options, false);
}
public Logger(Field acceleratorField, String logName, String def, String [] options, boolean strictOptions)
{
subscribedOnlinePlayers = new HashMap<>();
subscribedOfflinePlayers = new HashMap<>();
@@ -52,6 +64,7 @@ public class Logger
this.logName = logName;
this.default_option = def;
this.options = options;
this.strictOptions = strictOptions;
if (acceleratorField == null)
CarpetSettings.LOG.error("[CM] Logger "+getLogName()+" is missing a specified accelerator");
}
@@ -232,4 +245,12 @@ public class Logger
if (options != null && Arrays.asList(options).contains(arg)) return arg;
return null;
}
public boolean isOptionValid(String option) {
if (strictOptions)
{
return Arrays.asList(this.options).contains(option);
}
return true;
}
}
@@ -28,6 +28,7 @@ public class LoggerRegistry
public static boolean __packets;
public static boolean __pathfinding;
public static boolean __explosions;
public static boolean __updateSuppressedCrashes;
public static void initLoggers()
{
@@ -38,7 +39,7 @@ public class LoggerRegistry
public static void registerLoggers()
{
registerLogger("tnt", Logger.stardardLogger( "tnt", "brief", new String[]{"brief", "full"}));
registerLogger("tnt", Logger.stardardLogger( "tnt", "brief", new String[]{"brief", "full"}, true));
registerLogger("projectiles", Logger.stardardLogger("projectiles", "brief", new String[]{"brief", "full"}));
registerLogger("fallingBlocks",Logger.stardardLogger("fallingBlocks", "brief", new String[]{"brief", "full"}));
registerLogger("pathfinding", Logger.stardardLogger("pathfinding", "20", new String[]{"2", "5", "10"}));
@@ -46,7 +47,8 @@ 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"}));
registerLogger("explosions", Logger.stardardLogger("explosions", "brief",new String[]{"brief", "full"}, true));
registerLogger("updateSuppressedCrashes", Logger.stardardLogger("updateSuppressedCrashes", null,null));
}
@@ -172,7 +174,4 @@ public class LoggerRegistry
log.onPlayerDisconnect(player);
}
}
}
@@ -28,6 +28,7 @@ public class ExplosionLogHelper
private static long lastGametime = 0;
private static int explosionCountInCurretGT = 0;
private static boolean newTick;
public ExplosionLogHelper(Entity entity, double x, double y, double z, float power, boolean createFire, Explosion.DestructionType blockDestructionType) {
this.entity = entity;
@@ -44,14 +45,16 @@ public class ExplosionLogHelper
public void onExplosionDone(long gametime)
{
List<BaseText> messages = new ArrayList<>();
newTick = false;
if (!(lastGametime == gametime)){
explosionCountInCurretGT = 0;
lastGametime = gametime;
messages.add(c("wb tick : ", "d " + gametime));
newTick = true;
}
explosionCountInCurretGT++;
LoggerRegistry.getLogger("explosions").log( (option) -> {
List<BaseText> messages = new ArrayList<>();
if(newTick) messages.add(c("wb tick : ", "d " + gametime));
if ("brief".equals(option))
{
messages.add( c("d #" + explosionCountInCurretGT,"gb ->",
@@ -0,0 +1,57 @@
package carpet.mixins;
import carpet.CarpetSettings;
import carpet.helpers.ThrowableSuppression;
import carpet.logging.LoggerRegistry;
import carpet.utils.Messenger;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.BaseText;
import net.minecraft.util.crash.CrashException;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.function.BooleanSupplier;
@Mixin(MinecraftServer.class)
public class MinecraftServer_updateSuppressionCrashFixMixin {
@Redirect(
method = "tickWorlds",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/server/world/ServerWorld;tick(Ljava/util/function/BooleanSupplier;)V"
),
require = 0
)
private void fixUpdateSuppressionCrashTick(ServerWorld serverWorld, BooleanSupplier shouldKeepTicking){
if (!CarpetSettings.updateSuppressionCrashFix) {
serverWorld.tick(shouldKeepTicking);
return;
}
try {
serverWorld.tick(shouldKeepTicking);
} catch (CrashException e) {
if (!(e.getCause() instanceof ThrowableSuppression throwableSuppression)) throw e;
logUpdateSuppression(throwableSuppression.pos);
} catch (ThrowableSuppression e) {
logUpdateSuppression(e.pos);
}
}
private void logUpdateSuppression(BlockPos pos) {
if(LoggerRegistry.__updateSuppressedCrashes) {
LoggerRegistry.getLogger("updateSuppressedCrashes").log(() -> {
return new BaseText[]{Messenger.c(
"w Server crash prevented in: ",
"m world tick ",
"w - at: ",
"g [ " + pos.toShortString() + " ]"
)};
});
}
}
}
@@ -62,7 +62,7 @@ public abstract class ServerChunkManager_tickMixin
// simplified chunk tick iteration assuming world is frozen otherwise as suggested by Hadron67
// to be kept in sync with the original injection source
if (!debug){
List<ChunkHolder> holders = Lists.newArrayList(((ThreadedAnvilChunkStorageInterface)threadedAnvilChunkStorage).getChunks());
List<ChunkHolder> holders = Lists.newArrayList(((ThreadedAnvilChunkStorageInterface)threadedAnvilChunkStorage).getChunksCM());
Collections.shuffle(holders);
for (ChunkHolder holder: holders){
Optional<WorldChunk> optional = holder.getTickingFuture().getNow(ChunkHolder.UNLOADED_WORLD_CHUNK).left();
@@ -0,0 +1,55 @@
package carpet.mixins;
import carpet.CarpetSettings;
import carpet.helpers.ThrowableSuppression;
import carpet.logging.LoggerRegistry;
import carpet.utils.Messenger;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.BaseText;
import net.minecraft.util.crash.CrashException;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerPlayerEntity.class)
public class ServerPlayerEntity_updateSuppressionCrashFixMixin {
@Redirect(
method = "playerTick()V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/player/PlayerEntity;tick()V"
),
require = 0
)
private void fixUpdateSuppressionCrashPlayerTick(PlayerEntity playerEntity){
if (!CarpetSettings.updateSuppressionCrashFix) {
playerEntity.tick();
return;
}
try {
playerEntity.tick();
} catch (CrashException e) {
if (!(e.getCause() instanceof ThrowableSuppression throwableSuppression)) throw e;
logUpdateSuppressionPlayer(throwableSuppression.pos);
} catch (ThrowableSuppression e) {
logUpdateSuppressionPlayer(e.pos);
}
}
private void logUpdateSuppressionPlayer(BlockPos pos) {
if(LoggerRegistry.__updateSuppressedCrashes) {
LoggerRegistry.getLogger("updateSuppressedCrashes").log(() -> {
return new BaseText[]{Messenger.c(
"w Server crash prevented in: ",
"m player tick ",
"w - at: ",
"g [ " + pos.toShortString() + " ]"
)};
});
}
}
}
@@ -484,7 +484,7 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
}
@Override
public Iterable<ChunkHolder> getChunks() {
public Iterable<ChunkHolder> getChunksCM() {
return entryIterator();
}
}
@@ -0,0 +1,32 @@
package carpet.mixins;
import carpet.CarpetSettings;
import carpet.helpers.ThrowableSuppression;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(World.class)
public class World_updateSuppressionCrashFixMixin {
@Inject(
method = "updateNeighbor",
at = @At(
value="INVOKE",
target = "Lnet/minecraft/util/crash/CrashReport;create(Ljava/lang/Throwable;Ljava/lang/String;)Lnet/minecraft/util/crash/CrashReport;"
),
locals = LocalCapture.CAPTURE_FAILHARD,
require = 0
)
public void checkUpdateSuppression(BlockPos sourcePos, Block sourceBlock, BlockPos neighborPos, CallbackInfo ci, BlockState state,Throwable throwable){
if(CarpetSettings.updateSuppressionCrashFix && (throwable instanceof ThrowableSuppression || throwable instanceof StackOverflowError)){
throw new ThrowableSuppression("Update suppression",neighborPos);
}
}
}