Finish implementation of explosion repair
This commit is contained in:
parent
1126306c2c
commit
aadb2a5bf5
7 changed files with 146 additions and 47 deletions
|
@ -40,7 +40,7 @@ public class PrefixColorCommand {
|
|||
return 1;
|
||||
}
|
||||
Profile p = Profile.get_profile_of(source.getPlayer().getStringUUID());
|
||||
p.name_color = colorcoded;
|
||||
p.prefix_color = colorcoded;
|
||||
p.commit();
|
||||
OTEMod.PROFILES.put(source.getPlayer().getStringUUID(), p);
|
||||
|
||||
|
|
|
@ -23,8 +23,10 @@ public class OTEServerConfig {
|
|||
public static final ForgeConfigSpec.ConfigValue<Integer> ITEM_DESPAWN_TIMER;
|
||||
public static final ForgeConfigSpec.ConfigValue<Integer> RTP_COOLDOWN;
|
||||
public static final ForgeConfigSpec.ConfigValue<Integer> HEALER_TIMER;
|
||||
public static final ForgeConfigSpec.ConfigValue<List<String>> EXCLUDE_DIMENSIONS;
|
||||
public static final ForgeConfigSpec.BooleanValue DEBUG_HEALER;
|
||||
public static final ForgeConfigSpec.ConfigValue<Integer> TIME_BETWEEN_BLOCKS;
|
||||
public static final ForgeConfigSpec.ConfigValue<Integer> MAX_TRIES_HEAL;
|
||||
|
||||
|
||||
static {
|
||||
List<ItemStack> defaults = new ArrayList<ItemStack>();
|
||||
|
@ -47,10 +49,11 @@ public class OTEServerConfig {
|
|||
|
||||
BUILDER.pop();
|
||||
BUILDER.push("ANTIGRIEF").comment("AntiGrief Explosion Healing Events");
|
||||
HEALER_TIMER = BUILDER.comment("Time between healing events (In Milliseconds)").define("timer", 5000); // Should this be lower?
|
||||
EXCLUDE_DIMENSIONS = BUILDER.comment("What dimensions to exclude? (Namespace:Dimension) in lowercase").define("exclude_dims", defaultExcludeDimensions);
|
||||
HEALER_TIMER = BUILDER.comment("Time between healing events (In Milliseconds)").define("timer", 1000); // Should this be lower?
|
||||
DEBUG_HEALER = BUILDER.comment("Whether or not to debug the healer engine. (Saves as SNBT instead of NBT)").define("debug", false);
|
||||
|
||||
TIME_BETWEEN_BLOCKS = BUILDER.comment("The amount of time between restoring blocks (Maximum). This is in ticks").define("time_between", 250);
|
||||
|
||||
MAX_TRIES_HEAL = BUILDER.comment("Maximum amount of retries to restore a block").define("max_tries", 6);
|
||||
|
||||
|
||||
BUILDER.pop();
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
package dev.zontreck.otemod.zschem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import dev.zontreck.libzontreck.vectors.WorldPosition;
|
||||
import dev.zontreck.otemod.configs.OTEServerConfig;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BlockContainerList {
|
||||
private static final BlockContainerList INSTANCE =new BlockContainerList();
|
||||
|
@ -48,11 +52,24 @@ public class BlockContainerList {
|
|||
{
|
||||
lock.lock();
|
||||
try{
|
||||
for (StoredBlock storedBlock : containers) {
|
||||
Iterator<StoredBlock> isb = containers.iterator();
|
||||
while(isb.hasNext())
|
||||
{
|
||||
StoredBlock storedBlock = isb.next();
|
||||
storedBlock.tick();
|
||||
if(storedBlock.isExpired()){
|
||||
HealRunner.scheduleHeal(storedBlock);
|
||||
containers.remove(storedBlock);
|
||||
WorldPosition wp = storedBlock.getWorldPosition();
|
||||
BlockState bs = wp.getActualDimension().getBlockState(wp.Position.asBlockPos());
|
||||
if(bs.is(storedBlock.getState().getBlock()) || storedBlock.getTries() >= OTEServerConfig.MAX_TRIES_HEAL.get())
|
||||
{
|
||||
|
||||
HealRunner.scheduleHeal(storedBlock);
|
||||
isb.remove();
|
||||
}else {
|
||||
HealRunner.scheduleHeal(storedBlock);
|
||||
storedBlock.setTick(OTEServerConfig.HEALER_TIMER.get());
|
||||
storedBlock.tickTries();
|
||||
}
|
||||
}
|
||||
}
|
||||
}finally{
|
||||
|
|
|
@ -62,23 +62,26 @@ public class BlockSaver {
|
|||
|
||||
|
||||
// Healer Queue's data source is a NBT File in the config folder
|
||||
public static final String HealerQueueFile = "OTEHealerLastQueue.nbt";
|
||||
public static final String HealerQueueDebugFile = "OTEHealerLastQueue.snbt";
|
||||
public static final String HealerQueueFile = ".nbt";
|
||||
public static final String HealerQueueDebugFile = ".dev.nbt";
|
||||
|
||||
public static Path getPath()
|
||||
{
|
||||
|
||||
Path configDir = FMLPaths.GAMEDIR.get().resolve(FMLConfig.defaultConfigPath());
|
||||
Path configFile = null;
|
||||
return configDir.resolve("ote_queue");
|
||||
}
|
||||
|
||||
public static String getExtension()
|
||||
{
|
||||
|
||||
if(OTEServerConfig.DEBUG_HEALER.get())
|
||||
{
|
||||
configFile = configDir.resolve(BlockSaver.HealerQueueDebugFile);
|
||||
return BlockSaver.HealerQueueDebugFile;
|
||||
|
||||
}else {
|
||||
configFile = configDir.resolve(BlockSaver.HealerQueueFile);
|
||||
return BlockSaver.HealerQueueFile;
|
||||
}
|
||||
|
||||
//OTEMod.LOGGER.info("OTE HEALER TEMPORARY FILE: "+configFile.toFile().getAbsolutePath());
|
||||
return configFile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import net.minecraft.world.entity.Entity;
|
|||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.level.ExplosionEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
public class EventHandler {
|
||||
|
@ -52,6 +53,18 @@ public class EventHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onShutdown(ServerStoppingEvent ev)
|
||||
{
|
||||
WorldProp.SaveAll();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onSaving(LevelEvent.Save ev)
|
||||
{
|
||||
WorldProp.SaveAll();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onLevelTick(TickEvent.LevelTickEvent ev)
|
||||
{
|
||||
|
|
|
@ -21,12 +21,17 @@ public class StoredBlock
|
|||
private BlockState state;
|
||||
private CompoundTag blockEntity;
|
||||
private int tick;
|
||||
private int tries;
|
||||
|
||||
|
||||
public void tick(){
|
||||
this.tick--;
|
||||
}
|
||||
|
||||
public void setTick(int tick){
|
||||
this.tick=tick;
|
||||
}
|
||||
|
||||
|
||||
public boolean isExpired() {
|
||||
return tick <= 0;
|
||||
|
@ -95,12 +100,20 @@ public class StoredBlock
|
|||
|
||||
tag.put("pos", position.serialize());
|
||||
tag.put("state", NbtUtils.writeBlockState(state));
|
||||
tag.putInt("tick", tick);
|
||||
tag.putInt("tries", tries);
|
||||
|
||||
if(blockEntity != null) tag.put("entity", blockEntity);
|
||||
|
||||
return tag;
|
||||
}
|
||||
public int getTries(){
|
||||
return tries;
|
||||
}
|
||||
|
||||
public void tickTries(){
|
||||
tries++;
|
||||
}
|
||||
|
||||
public void deserialize(final CompoundTag tag)
|
||||
{
|
||||
|
@ -115,6 +128,9 @@ public class StoredBlock
|
|||
|
||||
final CompoundTag tmp = tag.getCompound("entity");
|
||||
blockEntity = tmp.isEmpty() ? null : tmp;
|
||||
|
||||
tick = tag.getInt("tick");
|
||||
tries=tag.getInt("tries");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,26 @@
|
|||
package dev.zontreck.otemod.zschem;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import dev.zontreck.libzontreck.vectors.Vector3;
|
||||
import dev.zontreck.libzontreck.vectors.WorldPosition;
|
||||
import dev.zontreck.otemod.OTEMod;
|
||||
import dev.zontreck.otemod.configs.OTEServerConfig;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
@ -15,8 +30,9 @@ import net.minecraft.world.level.saveddata.SavedData;
|
|||
import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||
import net.minecraftforge.event.level.ExplosionEvent;
|
||||
|
||||
public class WorldProp extends SavedData implements Supplier<Object>
|
||||
public class WorldProp implements Supplier<Object>
|
||||
{
|
||||
public static Map<ServerLevel, WorldProp> props = new HashMap<ServerLevel,WorldProp>();
|
||||
private Level world;
|
||||
private BlockContainerList task;
|
||||
static final String KEY = OTEMod.MOD_ID + ":" + WorldProp.class.getSimpleName();
|
||||
|
@ -40,56 +56,92 @@ public class WorldProp extends SavedData implements Supplier<Object>
|
|||
BlockState bsExplode = w.getBlockState(p);
|
||||
if(!isValid(bsExplode))continue;
|
||||
|
||||
if(!bsExplode.isAir()){
|
||||
int ticks = OTEServerConfig.HEALER_TIMER.get() + w.random.nextInt();
|
||||
if(ticks > maxTicks){
|
||||
maxTicks = ticks;
|
||||
}
|
||||
|
||||
if(!bsExplode.isAir() ){
|
||||
int ticks = OTEServerConfig.HEALER_TIMER.get() + maxTicks + OTEServerConfig.TIME_BETWEEN_BLOCKS.get();
|
||||
if(ticks<0) ticks = maxTicks + OTEServerConfig.TIME_BETWEEN_BLOCKS.get();
|
||||
maxTicks += OTEServerConfig.TIME_BETWEEN_BLOCKS.get();
|
||||
|
||||
addHeal(p, bsExplode, world);
|
||||
}
|
||||
}
|
||||
maxTicks ++;
|
||||
for(BlockPos p : ev.getAffectedBlocks())
|
||||
{
|
||||
BlockState bsE = w.getBlockState(p);
|
||||
if(!isValid(bsE))continue;
|
||||
if(!bsE.isAir()){
|
||||
addHeal(p, bsE, world);
|
||||
|
||||
addHeal(p, bsExplode, world, ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addHeal(BlockPos p, BlockState s, Level w)
|
||||
private void addHeal(BlockPos p, BlockState s, Level w, int tick)
|
||||
{
|
||||
task.add(new StoredBlock(p, s, (ServerLevel)w));
|
||||
StoredBlock sb = new StoredBlock(p, s, (ServerLevel)w);
|
||||
sb.setTick(tick);
|
||||
task.add(sb);
|
||||
world.removeBlockEntity(p);
|
||||
world.setBlock(p, Blocks.AIR.defaultBlockState(), 7);
|
||||
}
|
||||
|
||||
private boolean isValid(BlockState bs)
|
||||
{
|
||||
if(bs.is(BlockTags.DOORS) || bs.is(BlockTags.BEDS) || bs.is(BlockTags.TALL_FLOWERS)){
|
||||
if(bs.is(BlockTags.DOORS) || bs.is(BlockTags.BEDS) || bs.is(BlockTags.TALL_FLOWERS) || bs.is(Blocks.TNT)){
|
||||
return false;
|
||||
} else return true;
|
||||
}
|
||||
|
||||
public CompoundTag save(CompoundTag tag){
|
||||
|
||||
return (CompoundTag) tag.put("task", task.save(tag));
|
||||
|
||||
public static void SaveAll()
|
||||
{
|
||||
Path destBase = BlockSaver.getPath();
|
||||
String ext = BlockSaver.getExtension();
|
||||
|
||||
for (Map.Entry<ServerLevel, WorldProp> entry : props.entrySet()) {
|
||||
// Perform saving
|
||||
String dimsafe = entry.getKey().dimension().location().getNamespace() +"-"+entry.getKey().dimension().location().getPath();
|
||||
String pathTemp = destBase.toString()+"_"+dimsafe+ext;
|
||||
|
||||
Path finalPath = Path.of(pathTemp);
|
||||
CompoundTag fnl = new CompoundTag();
|
||||
|
||||
fnl = entry.getValue().task.save(fnl);
|
||||
try {
|
||||
NbtIo.writeCompressed(fnl, finalPath.toFile());
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void load(CompoundTag tag)
|
||||
{
|
||||
CompoundTag ct = tag.getCompound("task");
|
||||
task = BlockContainerList.load(ct);
|
||||
task = BlockContainerList.load(tag);
|
||||
}
|
||||
|
||||
public static WorldProp acquire(ServerLevel w)
|
||||
{
|
||||
DimensionDataStorage dds = w.getDataStorage();
|
||||
if(props.containsKey(w))
|
||||
{
|
||||
return props.get(w);
|
||||
}
|
||||
Path destBase = BlockSaver.getPath();
|
||||
String ext = BlockSaver.getExtension();
|
||||
String dimsafe = w.dimension().location().getNamespace() +"-"+w.dimension().location().getPath();
|
||||
String pathTemp = destBase.toString()+"_"+dimsafe+ext;
|
||||
|
||||
Path finalPath = Path.of(pathTemp);
|
||||
WorldProp nProp = new WorldProp();
|
||||
nProp.world=w;
|
||||
|
||||
if(finalPath.toFile().exists())
|
||||
{
|
||||
|
||||
try {
|
||||
nProp.load(NbtIo.read(finalPath.toFile()));
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
props.put(w,nProp);
|
||||
return nProp;
|
||||
/*DimensionDataStorage dds = w.getDataStorage();
|
||||
WorldProp wp = dds.computeIfAbsent(p->{
|
||||
WorldProp swp = new WorldProp();
|
||||
swp.load(p);
|
||||
|
@ -99,15 +151,10 @@ public class WorldProp extends SavedData implements Supplier<Object>
|
|||
}, KEY);
|
||||
wp.world = w;
|
||||
return wp;
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDirty(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get()
|
||||
{
|
||||
|
|
Reference in a new issue