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 {
      }
   }
}