GlobalWorldEventManager class
Пакет: com.hypixel.hytale.builtin.adventure.worldevents
Файл: com/hypixel/hytale/builtin/adventure/worldevents/GlobalWorldEventManager.java
Поля (39)
| Модификаторы | Тип | Имя |
|---|---|---|
|
public static final RecordCodec<GlobalWorldEventManager.Data> |
CODEC |
|
private static final UUID[] |
EMPTY_ID_ARRAY |
final |
GlobalWorldEventManager |
INSTANCE |
|
|
break |
|
|
break |
|
|
return |
|
|
return |
|
long |
var1 |
|
long |
var1 |
|
UUID[] |
var1 |
|
|
var1 |
|
Path |
var1 |
|
UUID[] |
var1 |
|
|
var1 |
|
Path |
var1 |
|
ScheduledFuture |
var1 |
|
long |
var1 |
|
GlobalWorldEventManager |
var1 |
|
GlobalWorldEventManager |
var1 |
|
GlobalWorldEventManager |
var1 |
|
GlobalWorldEventManager |
var1 |
|
long |
var2 |
|
long |
var2 |
|
long |
var2 |
|
long |
var2 |
|
GlobalWorldEventManager.Data |
var2 |
|
long |
var2 |
|
GlobalWorldEventManager.Data |
var2 |
|
long |
var2 |
|
long |
var2 |
|
long |
var3 |
|
long |
var3 |
|
BsonDocument |
var3 |
|
WorldEventsConfig |
var3 |
|
WorldEventsConfig |
var3 |
|
long |
var4 |
|
long |
var4 |
|
Store |
var8 |
|
Store |
var8 |
Методы (29)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
private |
record |
Datarecord Data(@Nonnull UUID[] events) |
public |
int |
activeCountint activeCount() |
public |
boolean |
addboolean add(@Nonnull UUID var1) |
public |
void |
clearvoid clear() |
public |
boolean |
containsboolean contains(@Nonnull UUID var1) |
|
|
for for(WorldEventRecord var8 : var2) |
|
|
for for(WorldEventRecord var7 : var3.globalEvents) |
|
|
for for(WorldEventRecord var7 : var3.globalEvents) |
abstract |
|
for for(int var3 = 0; var3 < this.tasks.size() |
|
|
if if(var2 == null) |
|
|
if if(var1 != null) |
|
|
if if(var1 != null) |
|
|
if if(var3 != null) |
|
|
if if(var3 != null) |
public |
CompletableFuture<GlobalWorldEventManager> |
loadAsyncCompletableFuture<GlobalWorldEventManager> loadAsync() |
public |
boolean |
removeboolean remove(@Nonnull UUID var1) |
private |
void |
runTasksvoid runTasks() |
public |
void |
saveAsyncvoid saveAsync() |
static |
void |
scheduleRestartEventInAllWorldsvoid scheduleRestartEventInAllWorlds(@Nonnull UUID var0) |
static |
void |
scheduleStartEventInAllWorldsvoid scheduleStartEventInAllWorlds(@Nonnull UUID var0) |
public |
void |
shutdownvoid shutdown() |
public |
void |
startvoid start(@Nonnull Store<EntityStore> var1, @Nonnull WorldEventRecord[] var2) |
static |
boolean |
startEventboolean startEvent(@Nonnull UUID var0) |
static |
void |
startEventInAllWorldsvoid startEventInAllWorlds(@Nonnull UUID var0) |
abstract |
|
startEventInAllWorlds startEventInAllWorlds(var0) |
public |
void |
startupvoid startup() |
static |
boolean |
stopEventboolean stopEvent(@Nonnull UUID var0) |
static |
void |
stopEventInAllWorldsvoid stopEventInAllWorlds(@Nonnull UUID var0) |
abstract |
|
stopEventInAllWorlds stopEventInAllWorlds(var0) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.adventure.worldevents;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.action.EventStartAction;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.action.EventStopAction;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.ExtraInfo;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.record.RecordCodec;
class="kw">import com.hypixel.hytale.codec.util.RawJsonReader;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.logger.sentry.SkipSentryException;
class="kw">import com.hypixel.hytale.server.core.HytaleServer;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.util.BsonUtil;
class="kw">import com.hypixel.hytale.sneakythrow.SneakyThrow;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectSet;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.util.Arrays;
class="kw">import java.util.Collections;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ScheduledFuture;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.concurrent.atomic.AtomicReference;
class="kw">import java.util.concurrent.locks.StampedLock;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.concurrent.ThreadSafe;
class="kw">import org.bson.BsonDocument;
@ThreadSafe
class="kw">public class="kw">final class GlobalWorldEventManager {
class="kw">public class="kw">static class="kw">final GlobalWorldEventManager INSTANCE = new GlobalWorldEventManager();
class="kw">public class="kw">static class="kw">final String FILENAME = "events.json";
class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
class="kw">private class="kw">static class="kw">final long TASK_DELAY_MS = 1000L;
class="kw">private class="kw">static class="kw">final long TASK_INTERVAL_MS = 500L;
class="kw">private class="kw">final StampedLock lock = new StampedLock();
class="kw">private class="kw">final ObjectSet<UUID> events = new ObjectOpenHashSet();
class="kw">private class="kw">final ObjectList<Runnable> tasks = new ObjectArrayList();
class="kw">private class="kw">final AtomicReference<ScheduledFuture<?>> taskRunner = new AtomicReference<>();
class="kw">public GlobalWorldEventManager() {
}
class="kw">public void clear() {
long var1 = this.lock.writeLock();
try {
this.events.clear();
this.tasks.clear();
} class="kw">finally {
this.lock.unlockWrite(var1);
}
}
class="kw">public boolean add(@Nonnull UUID var1) {
long var2 = this.lock.readLock();
try {
if (this.events.contains(var1)) {
class="kw">return false;
}
} class="kw">finally {
this.lock.unlockRead(var2);
}
long var4 = this.lock.writeLock();
try {
if (!this.events.add(var1)) {
class="kw">return false;
}
this.tasks.add((Runnable)() -> startEventInAllWorlds(var1));
class="kw">return true;
} class="kw">finally {
this.lock.unlockWrite(var4);
}
}
class="kw">public boolean contains(@Nonnull UUID var1) {
long var2 = this.lock.readLock();
try {
class="kw">return this.events.contains(var1);
} class="kw">finally {
this.lock.unlockRead(var2);
}
}
class="kw">public int activeCount() {
long var1 = this.lock.readLock();
try {
class="kw">return this.events.size();
} class="kw">finally {
this.lock.unlockRead(var1);
}
}
@Nonnull
class="kw">public UUID[] activeIds() {
long var2 = this.lock.readLock();
UUID[] var1;
try {
var1 = (UUID[])this.events.toArray(UUID[]::new);
} class="kw">finally {
this.lock.unlockRead(var2);
}
Arrays.sort(var1);
class="kw">return var1;
}
class="kw">public boolean remove(@Nonnull UUID var1) {
long var2 = this.lock.readLock();
try {
if (!this.events.contains(var1)) {
class="kw">return false;
}
} class="kw">finally {
this.lock.unlockRead(var2);
}
long var4 = this.lock.writeLock();
try {
if (!this.events.remove(var1)) {
class="kw">return false;
}
this.tasks.add((Runnable)() -> stopEventInAllWorlds(var1));
class="kw">return true;
} class="kw">finally {
this.lock.unlockWrite(var4);
}
}
class="kw">public void start(@Nonnull Store<EntityStore> var1, @Nonnull WorldEventRecord[] var2) {
long var3 = this.lock.readLock();
try {
for (WorldEventRecord var8 : var2) {
if (var8.id() != null && this.events.contains(var8.id())) {
EventStartAction.startEvent(var1, var8);
}
}
} class="kw">finally {
this.lock.unlockRead(var3);
}
}
class="kw">public CompletableFuture<GlobalWorldEventManager> loadAsync() {
class="kw">return CompletableFuture.supplyAsync(SneakyThrow.sneakySupplier(() -> {
Path var1 = Universe.get().getPath().resolve("events.json");
if (!Files.exists(var1)) {
class="kw">return INSTANCE;
}
GlobalWorldEventManager.Data var2 = RawJsonReader.readSyncWithBak(var1, GlobalWorldEventManager.Data.CODEC, LOGGER);
if (var2 == null) {
class="kw">return INSTANCE;
}
long var3 = this.lock.writeLock();
try {
this.events.clear();
Collections.addAll(this.events, var2.events);
} class="kw">finally {
this.lock.unlockWrite(var3);
}
class="kw">return INSTANCE;
}));
}
class="kw">public void saveAsync() {
CompletableFuture.<UUID[]>supplyAsync(() -> {
UUID[] var1 = GlobalWorldEventManager.Data.EMPTY_ID_ARRAY;
long var2 = this.lock.readLock();
try {
var1 = (UUID[])this.events.toArray(UUID[]::new);
} class="kw">finally {
this.lock.unlockRead(var2);
}
Arrays.sort(var1);
class="kw">return var1;
}).thenComposeAsync(var0 -> {
Path var1 = Universe.get().getPath().resolve("events.json");
if (!Files.exists(var1) && var0.length == 0) {
class="kw">return CompletableFuture.completedFuture(null);
}
GlobalWorldEventManager.Data var2 = new GlobalWorldEventManager.Data(var0);
BsonDocument var3 = GlobalWorldEventManager.Data.CODEC.encode(var2, ExtraInfo.THREAD_LOCAL.get());
class="kw">return BsonUtil.writeDocument(var1, var3);
}).whenCompleteAsync((var0, var1) -> {
if (var1 != null) {
((HytaleLogger.Api)((HytaleLogger.Api)LOGGER.atSevere()).withCause(new SkipSentryException(var1))).log("Failed to save %s", "events.json");
} else {
((HytaleLogger.Api)LOGGER.atFine()).log("Saved global world-events");
}
});
}
class="kw">public void startup() {
this.taskRunner
.updateAndGet(var1 -> var1 != null ? var1 : HytaleServer.SCHEDULED_EXECUTOR.scheduleAtFixedRate(this::runTasks, 1000L, 500L, TimeUnit.MILLISECONDS));
}
class="kw">public void shutdown() {
ScheduledFuture var1 = this.taskRunner.getAndSet(null);
if (var1 != null) {
var1.cancel(false);
}
}
class="kw">private void runTasks() {
if (!this.tasks.isEmpty()) {
long var1 = this.lock.writeLock();
try {
for (int var3 = 0; var3 < this.tasks.size(); var3++) {
((Runnable)this.tasks.get(var3)).run();
}
this.tasks.clear();
} class="kw">finally {
this.lock.unlockWrite(var1);
}
}
}
class="kw">public class="kw">static boolean startEvent(@Nonnull UUID var0) {
GlobalWorldEventManager var1 = INSTANCE;
if (var1.add(var0)) {
var1.saveAsync();
class="kw">return true;
} else {
class="kw">return false;
}
}
class="kw">public class="kw">static boolean stopEvent(@Nonnull UUID var0) {
GlobalWorldEventManager var1 = INSTANCE;
if (var1.remove(var0)) {
var1.saveAsync();
class="kw">return true;
} else {
class="kw">return false;
}
}
class="kw">public class="kw">static void scheduleStartEventInAllWorlds(@Nonnull UUID var0) {
GlobalWorldEventManager var1 = INSTANCE;
long var2 = var1.lock.writeLock();
try {
if (var1.events.contains(var0)) {
var1.tasks.add((Runnable)() -> startEventInAllWorlds(var0));
class="kw">return;
}
} class="kw">finally {
var1.lock.unlockWrite(var2);
}
}
class="kw">public class="kw">static void scheduleRestartEventInAllWorlds(@Nonnull UUID var0) {
GlobalWorldEventManager var1 = INSTANCE;
long var2 = var1.lock.writeLock();
try {
if (var1.events.contains(var0)) {
var1.tasks.add((Runnable)() -> {
stopEventInAllWorlds(var0);
startEventInAllWorlds(var0);
});
class="kw">return;
}
} class="kw">finally {
var1.lock.unlockWrite(var2);
}
}
class="kw">private class="kw">static void startEventInAllWorlds(@Nonnull UUID var0) {
((HytaleLogger.Api)LOGGER.atFine()).log("Starting global world-event: %s", var0);
for (World var2 : Universe.get().getWorlds().values()) {
WorldEventsConfig var3 = var2.getGameplayConfig().getPluginConfig().get(WorldEventsConfig.class);
if (var3 != null) {
for (WorldEventRecord var7 : var3.globalEvents) {
if (var7.id() != null && var7.id().equals(var0)) {
Store var8 = var2.getEntityStore().getStore();
CompletableFuture.runAsync(() -> EventStartAction.startEvent(var8, var7), var2);
break;
}
}
}
}
}
class="kw">private class="kw">static void stopEventInAllWorlds(@Nonnull UUID var0) {
((HytaleLogger.Api)LOGGER.atFine()).log("Stopping global world-event: %s", var0);
for (World var2 : Universe.get().getWorlds().values()) {
WorldEventsConfig var3 = var2.getGameplayConfig().getPluginConfig().get(WorldEventsConfig.class);
if (var3 != null) {
for (WorldEventRecord var7 : var3.globalEvents) {
if (var7.id() != null && var7.id().equals(var0)) {
Store var8 = var2.getEntityStore().getStore();
CompletableFuture.runAsync(() -> EventStopAction.stopEvent(var8, var7.id(), (var0x, var1x) -> var0x.uuid.equals(var1x)), var2);
break;
}
}
}
}
}
class="kw">private record Data(@Nonnull UUID[] events) {
class="kw">public class="kw">static class="kw">final RecordCodec<GlobalWorldEventManager.Data> CODEC = RecordCodec.builder(GlobalWorldEventManager.Data.class)
.append(new KeyedCodec<>("Events", new ArrayCodec<>(Codec.UUID_STRING, UUID[]::new)), GlobalWorldEventManager.Data::events)
.build(GlobalWorldEventManager.Data::new);
class="kw">private class="kw">static class="kw">final UUID[] EMPTY_ID_ARRAY = new UUID[0];
class="kw">private Data {
}
}
}