package com.hypixel.hytale.builtin.portals.integrations;
import com.hypixel.hytale.builtin.instances.removal.InstanceDataResource;
import com.hypixel.hytale.builtin.instances.removal.RemovalCondition;
import com.hypixel.hytale.builtin.instances.removal.TimeoutCondition;
import com.hypixel.hytale.builtin.instances.removal.WorldEmptyCondition;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.modules.time.TimeResource;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.time.Duration;
import java.time.Instant;
import javax.annotation.Nonnull;
public class PortalRemovalCondition implements RemovalCondition {
public static final BuilderCodec<PortalRemovalCondition> CODEC;
private final WorldEmptyCondition worldEmptyCondition;
private TimeoutCondition timeLimitCondition;
public PortalRemovalCondition() {
this(60.0);
}
public PortalRemovalCondition(double timeLimitSeconds) {
this.worldEmptyCondition = new WorldEmptyCondition(90.0);
this.timeLimitCondition = new TimeoutCondition(timeLimitSeconds);
}
private double getTimeLimitSeconds() {
return this.timeLimitCondition.getTimeoutSeconds();
}
private void setTimeLimitSeconds(double timeLimitSeconds) {
this.timeLimitCondition = new TimeoutCondition(timeLimitSeconds);
}
public double getElapsedSeconds(World world) {
double timeLimitSeconds = this.timeLimitCondition.getTimeoutSeconds();
double remainingSeconds = this.getRemainingSeconds(world);
return Math.max(0.0, timeLimitSeconds - remainingSeconds);
}
public double getRemainingSeconds(World world) {
Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
Store<EntityStore> entityStore = world.getEntityStore().getStore();
InstanceDataResource instanceData = (InstanceDataResource)chunkStore.getResource(InstanceDataResource.getResourceType());
TimeResource timeResource = (TimeResource)entityStore.getResource(TimeResource.getResourceType());
Instant timeoutInstant = instanceData.getTimeoutTimer();
if (timeoutInstant == null) {
return this.timeLimitCondition.getTimeoutSeconds();
} else {
double remainingSeconds = (double)Duration.between(timeResource.getNow(), timeoutInstant).toNanos() / 1.0E9;
return Math.max(0.0, remainingSeconds);
}
}
public void setRemainingSeconds(World world, double seconds) {
seconds = Math.max(0.0, seconds);
Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
Store<EntityStore> entityStore = world.getEntityStore().getStore();
InstanceDataResource instanceData = (InstanceDataResource)chunkStore.getResource(InstanceDataResource.getResourceType());
TimeResource timeResource = (TimeResource)entityStore.getResource(TimeResource.getResourceType());
instanceData.setTimeoutTimer(timeResource.getNow().plusMillis((long)(seconds * 1000.0)));
}
public boolean shouldRemoveWorld(@Nonnull Store<ChunkStore> store) {
InstanceDataResource instanceData = (InstanceDataResource)store.getResource(InstanceDataResource.getResourceType());
if (instanceData.hadPlayer() && this.timeLimitCondition.shouldRemoveWorld(store)) {
return true;
} else {
return this.worldEmptyCondition.shouldRemoveWorld(store);
}
}
static {
CODEC = ((BuilderCodec.Builder)((BuilderCodec.Builder)BuilderCodec.builder(PortalRemovalCondition.class, PortalRemovalCondition::new).documentation("A condition for temporary portal worlds.")).append(new KeyedCodec("TimeoutSeconds", Codec.DOUBLE), (o, i) -> o.setTimeLimitSeconds(i), (o) -> o.getTimeLimitSeconds()).documentation("How long the portal world will stay open (in seconds) after being joined.").add()).build();
}
}