ShopInstanceState class

Пакет: com.hypixel.hytale.builtin.adventure.shop.barter

Файл: com/hypixel/hytale/builtin/adventure/shop/barter/BarterShopState.java

Поля (13)

МодификаторыТипИмя
public static final BarterTrade[] BARTER_TRADES
public static final int[] INTS
private int[] currentStock
private Instant nextRefreshTime
private Long resolveSeed
private transient BarterTrade[] resolvedTrades
BarterTrade[] var2
BarterTrade[] var2
BarterTrade[] var2
TradeSlot[] var3
int[] var3
Random var4
List var5

Методы (22)

МодификаторыВозвратСигнатура
public boolean decrementStockpublic boolean decrementStock(int var1, int var2)
public boolean expandStockIfNeededpublic boolean expandStockIfNeeded(@Nonnull BarterShopAsset var1)
for for(TradeSlot var9 : var3)
for for(int var3 = 0; var3 < var2.length; var3++)
for for(int var3 = 0; var3 < var2.length; var3++)
for for(int var4 = this.currentStock.length; var4 < var2.length; var4++)
public int[] getCurrentStockpublic int[] getCurrentStock()
public Instant getNextRefreshTimepublic Instant getNextRefreshTime()
public Long getResolveSeedpublic Long getResolveSeed()
public BarterTrade[] getResolvedTradespublic BarterTrade[] getResolvedTrades(@Nonnull BarterShopAsset var1)
public int getStockpublic int getStock(int var1)
public boolean hasStockpublic boolean hasStock(int var1, int var2)
if if(this.resolvedTrades != null)
if if(this.resolveSeed == null)
if if(var3 != null && var3.length != 0)
if if(this.currentStock.length != var2.length)
if if(this.currentStock.length >= var2.length)
public void resetStockpublic void resetStock(@Nonnull BarterShopAsset var1)
public void resetStockAndResolvepublic void resetStockAndResolve(@Nonnull BarterShopAsset var1)
private static BarterTrade[] resolveTradeSlotsprivate static BarterTrade[] resolveTradeSlots(@Nonnull BarterShopAsset var0, long var1)
public void setNextRefreshTimepublic void setNextRefreshTime(@Nonnull Instant var1)
public void setResolveSeedpublic void setResolveSeed(Long var1)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.adventure.shop.barter;

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.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.map.MapCodec;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
class="kw">import com.hypixel.hytale.server.core.util.BsonUtil;
class="kw">import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.io.IOException;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.time.Duration;
class="kw">import java.time.Instant;
class="kw">import java.time.LocalDateTime;
class="kw">import java.time.ZoneOffset;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Random;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.bson.BsonDocument;

class="kw">public class BarterShopState {
   @Nonnull
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   @Nullable
   class="kw">private class="kw">static BarterShopState instance;
   class="kw">private class="kw">static Path saveDirectory;
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<BarterShopState.ShopInstanceState> SHOP_INSTANCE_CODEC = BuilderCodec.builder(
         BarterShopState.ShopInstanceState.class, BarterShopState.ShopInstanceState::new
      )
      .append(new KeyedCodec<>("Stock", Codec.INT_ARRAY), (var0, var1) -> var0.currentStock = var1, var0 -> var0.currentStock)
      .add()
      .append(new KeyedCodec<>("NextRefresh", Codec.INSTANT, true), (var0, var1) -> var0.nextRefreshTime = var1, var0 -> var0.nextRefreshTime)
      .add()
      .append(new KeyedCodec<>("ResolveSeed", Codec.LONG, true), (var0, var1) -> var0.resolveSeed = var1, var0 -> var0.resolveSeed)
      .add()
      .build();
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<BarterShopState> CODEC = BuilderCodec.builder(BarterShopState.class, BarterShopState::new)
      .append(
         new KeyedCodec<>("Shops", new MapCodec<>(SHOP_INSTANCE_CODEC, Object2ObjectOpenHashMap::new, false)),
         (var0, var1) -> var0.shopStates.putAll(var1),
         var0 -> new Object2ObjectOpenHashMap(var0.shopStates)
      )
      .add()
      .build();
   @Nonnull
   class="kw">private class="kw">final Map<String, BarterShopState.ShopInstanceState> shopStates = new ConcurrentHashMap<>();

   class="kw">public class="kw">static void initialize(@Nonnull Path var0) {
      saveDirectory = var0;
      load();
   }

   @Nonnull
   class="kw">public class="kw">static BarterShopState get() {
      if (instance == null) {
         instance = new BarterShopState();
      }

      class="kw">return instance;
   }

   class="kw">public class="kw">static void load() {
      if (saveDirectory == null) {
         LOGGER.at(Level.WARNING).log("Cannot load barter shop state: save directory not set");
         instance = new BarterShopState();
      } else {
         Path var0 = saveDirectory.resolve("barter_shop_state.json");
         if (!Files.exists(var0)) {
            LOGGER.at(Level.INFO).log("No saved barter shop state found, starting fresh");
            instance = new BarterShopState();
         } else {
            try {
               BsonDocument var1 = BsonUtil.readDocumentNow(var0);
               if (var1 != null) {
                  ExtraInfo var2 = ExtraInfo.THREAD_LOCAL.get();
                  instance = CODEC.decode(var1, var2);
                  var2.getValidationResults().logOrThrowValidatorExceptions(LOGGER);
                  LOGGER.at(Level.INFO).log("Loaded barter shop state with %d shops", instance.shopStates.size());
               } else {
                  instance = new BarterShopState();
               }
            } catch (Exception var3) {
               ((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(var3)).log("Failed to load barter shop state, starting fresh");
               instance = new BarterShopState();
            }
         }
      }
   }

   class="kw">public class="kw">static void save() {
      if (saveDirectory != null && instance != null) {
         try {
            if (!Files.exists(saveDirectory)) {
               Files.createDirectories(saveDirectory);
            }

            Path var0 = saveDirectory.resolve("barter_shop_state.json");
            BsonUtil.writeSync(var0, CODEC, instance, LOGGER);
            LOGGER.at(Level.FINE).log("Saved barter shop state");
         } catch (IOException var1) {
            ((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(var1)).log("Failed to save barter shop state");
         }
      }
   }

   class="kw">public class="kw">static void shutdown() {
      save();
      instance = null;
   }

   class="kw">public BarterShopState() {
   }

   @Nonnull
   class="kw">private class="kw">static Instant calculateNextScheduledRestock(@Nonnull Instant var0, int var1, int var2) {
      LocalDateTime var3 = LocalDateTime.ofInstant(var0, ZoneOffset.UTC);
      long var4 = Duration.between(WorldTimeResource.ZERO_YEAR, var0).toDays();
      long var6 = var4 / var1;
      long var8 = (var6 + 1L) * var1;
      boolean var10 = var4 % var1 == 0L;
      if (var10 && var3.getHour() < var2) {
         var8 = var4;
      }

      class="kw">return WorldTimeResource.ZERO_YEAR.plus(Duration.ofDays(var8)).plus(Duration.ofHours(var2));
   }

   @Nonnull
   class="kw">public BarterShopState.ShopInstanceState getOrCreateShopState(@Nonnull BarterShopAsset var1, @Nonnull Instant var2) {
      class="kw">return this.shopStates.computeIfAbsent(var1.getId(), var2x -> {
         BarterShopState.ShopInstanceState var3 = new BarterShopState.ShopInstanceState();
         var3.resetStockAndResolve(var1);
         RefreshInterval var4 = var1.getRefreshInterval();
         if (var4 != null) {
            var3.setNextRefreshTime(calculateNextScheduledRestock(var2, var4.getDays(), var1.getRestockHour()));
         }

         class="kw">return var3;
      });
   }

   class="kw">public void checkRefresh(@Nonnull BarterShopAsset var1, @Nonnull Instant var2) {
      RefreshInterval var3 = var1.getRefreshInterval();
      if (var3 != null) {
         BarterShopState.ShopInstanceState var4 = this.getOrCreateShopState(var1, var2);
         Instant var5 = var4.getNextRefreshTime();
         if (var5 == null) {
            var4.setNextRefreshTime(calculateNextScheduledRestock(var2, var3.getDays(), var1.getRestockHour()));
            save();
         } else {
            if (!var2.isBefore(var5)) {
               var4.resetStockAndResolve(var1);
               var4.setNextRefreshTime(calculateNextScheduledRestock(var2, var3.getDays(), var1.getRestockHour()));
               save();
            }
         }
      }
   }

   class="kw">public int[] getStockArray(@Nonnull BarterShopAsset var1, @Nonnull Instant var2) {
      this.checkRefresh(var1, var2);
      BarterShopState.ShopInstanceState var3 = this.getOrCreateShopState(var1, var2);
      if (var3.expandStockIfNeeded(var1)) {
         save();
      }

      class="kw">return (int[])var3.getCurrentStock().clone();
   }

   @Nonnull
   class="kw">public BarterTrade[] getResolvedTrades(@Nonnull BarterShopAsset var1, @Nonnull Instant var2) {
      this.checkRefresh(var1, var2);
      BarterShopState.ShopInstanceState var3 = this.getOrCreateShopState(var1, var2);
      class="kw">return var3.getResolvedTrades(var1);
   }

   class="kw">public boolean executeTrade(@Nonnull BarterShopAsset var1, int var2, int var3, @Nonnull Instant var4) {
      this.checkRefresh(var1, var4);
      BarterShopState.ShopInstanceState var5 = this.getOrCreateShopState(var1, var4);
      boolean var6 = var5.decrementStock(var2, var3);
      if (var6) {
         save();
      }

      class="kw">return var6;
   }

   class="kw">public class="kw">static class ShopInstanceState {
      @Nonnull
      class="kw">public class="kw">static class="kw">final BarterTrade[] BARTER_TRADES = new BarterTrade[0];
      @Nonnull
      class="kw">public class="kw">static class="kw">final int[] INTS = new int[0];
      class="kw">private int[] currentStock = INTS;
      @Nullable
      class="kw">private Instant nextRefreshTime;
      @Nullable
      class="kw">private Long resolveSeed;
      @Nullable
      class="kw">private class="kw">transient BarterTrade[] resolvedTrades;

      class="kw">public ShopInstanceState() {
      }

      class="kw">public ShopInstanceState(int var1) {
         this.currentStock = new int[var1];
         this.nextRefreshTime = null;
      }

      class="kw">public int[] getCurrentStock() {
         class="kw">return this.currentStock;
      }

      @Nullable
      class="kw">public Instant getNextRefreshTime() {
         class="kw">return this.nextRefreshTime;
      }

      class="kw">public void setNextRefreshTime(@Nonnull Instant var1) {
         this.nextRefreshTime = var1;
      }

      @Nullable
      class="kw">public Long getResolveSeed() {
         class="kw">return this.resolveSeed;
      }

      class="kw">public void setResolveSeed(Long var1) {
         this.resolveSeed = var1;
      }

      @Nonnull
      class="kw">public BarterTrade[] getResolvedTrades(@Nonnull BarterShopAsset var1) {
         if (!var1.hasTradeSlots()) {
            class="kw">return var1.getTrades() != null ? var1.getTrades() : BARTER_TRADES;
         }

         if (this.resolvedTrades != null) {
            class="kw">return this.resolvedTrades;
         }

         if (this.resolveSeed == null) {
            this.resolveSeed = ThreadLocalRandom.current().nextLong();
         }

         this.resolvedTrades = resolveTradeSlots(var1, this.resolveSeed);
         class="kw">return this.resolvedTrades;
      }

      @Nonnull
      class="kw">private class="kw">static BarterTrade[] resolveTradeSlots(@Nonnull BarterShopAsset var0, long var1) {
         TradeSlot[] var3 = var0.getTradeSlots();
         if (var3 != null && var3.length != 0) {
            Random var4 = new Random(var1);
            List var5 = new ObjectArrayList();

            for (TradeSlot var9 : var3) {
               var5.addAll(var9.resolve(var4));
            }

            class="kw">return var5.toArray(BARTER_TRADES);
         } else {
            class="kw">return BARTER_TRADES;
         }
      }

      class="kw">public void resetStockAndResolve(@Nonnull BarterShopAsset var1) {
         if (var1.hasTradeSlots()) {
            this.resolveSeed = ThreadLocalRandom.current().nextLong();
            this.resolvedTrades = resolveTradeSlots(var1, this.resolveSeed);
         } else {
            this.resolvedTrades = null;
         }

         BarterTrade[] var2 = this.getResolvedTrades(var1);
         this.currentStock = new int[var2.length];

         for (int var3 = 0; var3 < var2.length; var3++) {
            this.currentStock[var3] = var2[var3].getMaxStock();
         }
      }

      @Deprecated
      class="kw">public void resetStock(@Nonnull BarterShopAsset var1) {
         BarterTrade[] var2 = this.getResolvedTrades(var1);
         if (this.currentStock.length != var2.length) {
            this.currentStock = new int[var2.length];
         }

         for (int var3 = 0; var3 < var2.length; var3++) {
            this.currentStock[var3] = var2[var3].getMaxStock();
         }
      }

      class="kw">public boolean expandStockIfNeeded(@Nonnull BarterShopAsset var1) {
         BarterTrade[] var2 = this.getResolvedTrades(var1);
         if (this.currentStock.length >= var2.length) {
            class="kw">return false;
         }

         int[] var3 = new int[var2.length];
         System.arraycopy(this.currentStock, 0, var3, 0, this.currentStock.length);

         for (int var4 = this.currentStock.length; var4 < var2.length; var4++) {
            var3[var4] = var2[var4].getMaxStock();
         }

         this.currentStock = var3;
         class="kw">return true;
      }

      class="kw">public boolean hasStock(int var1, int var2) {
         class="kw">return var1 >= 0 && var1 < this.currentStock.length ? this.currentStock[var1] >= var2 : false;
      }

      class="kw">public boolean decrementStock(int var1, int var2) {
         if (!this.hasStock(var1, var2)) {
            class="kw">return false;
         }

         this.currentStock[var1] = this.currentStock[var1] - var2;
         class="kw">return true;
      }

      class="kw">public int getStock(int var1) {
         class="kw">return var1 >= 0 && var1 < this.currentStock.length ? this.currentStock[var1] : 0;
      }
   }
}