2025-11-24 22:52:51 +03:00

161 lines
6.4 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.google.common.collect.Sets
* com.google.gson.Gson
* com.google.gson.GsonBuilder
* com.google.gson.JsonElement
* com.google.gson.JsonIOException
* com.google.gson.JsonObject
* com.google.gson.JsonParseException
* com.mojang.datafixers.DataFixer
* com.mojang.logging.LogUtils
* com.mojang.serialization.Codec
* com.mojang.serialization.DataResult
* com.mojang.serialization.Dynamic
* com.mojang.serialization.DynamicOps
* com.mojang.serialization.JsonOps
* it.unimi.dsi.fastutil.objects.Object2IntMap
* it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
* org.slf4j.Logger
*/
package net.minecraft.stats;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.mojang.datafixers.DataFixer;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.JsonOps;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import net.minecraft.SharedConstants;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.protocol.game.ClientboundAwardStatsPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stat;
import net.minecraft.stats.StatType;
import net.minecraft.stats.StatsCounter;
import net.minecraft.util.FileUtil;
import net.minecraft.util.StrictJsonParser;
import net.minecraft.util.Util;
import net.minecraft.util.datafix.DataFixTypes;
import net.minecraft.world.entity.player.Player;
import org.slf4j.Logger;
public class ServerStatsCounter
extends StatsCounter {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Logger LOGGER = LogUtils.getLogger();
private static final Codec<Map<Stat<?>, Integer>> STATS_CODEC = Codec.dispatchedMap(BuiltInRegistries.STAT_TYPE.byNameCodec(), Util.memoize(ServerStatsCounter::createTypedStatsCodec)).xmap(groupedStats -> {
HashMap stats = new HashMap();
groupedStats.forEach((type, values) -> stats.putAll(values));
return stats;
}, map -> map.entrySet().stream().collect(Collectors.groupingBy(entry -> ((Stat)entry.getKey()).getType(), Util.toMap())));
private final Path file;
private final Set<Stat<?>> dirty = Sets.newHashSet();
private static <T> Codec<Map<Stat<?>, Integer>> createTypedStatsCodec(StatType<T> type) {
Codec<T> valueCodec = type.getRegistry().byNameCodec();
Codec statCodec = valueCodec.flatComapMap(type::get, stat -> {
if (stat.getType() == type) {
return DataResult.success(stat.getValue());
}
return DataResult.error(() -> "Expected type " + String.valueOf(type) + ", but got " + String.valueOf(stat.getType()));
});
return Codec.unboundedMap((Codec)statCodec, (Codec)Codec.INT);
}
public ServerStatsCounter(MinecraftServer server, Path file) {
this.file = file;
if (Files.isRegularFile(file, new LinkOption[0])) {
try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8);){
JsonElement element = StrictJsonParser.parse(reader);
this.parse(server.getFixerUpper(), element);
}
catch (IOException e) {
LOGGER.error("Couldn't read statistics file {}", (Object)file, (Object)e);
}
catch (JsonParseException e) {
LOGGER.error("Couldn't parse statistics file {}", (Object)file, (Object)e);
}
}
}
public void save() {
try {
FileUtil.createDirectoriesSafe(this.file.getParent());
try (BufferedWriter writer = Files.newBufferedWriter(this.file, StandardCharsets.UTF_8, new OpenOption[0]);){
GSON.toJson(this.toJson(), GSON.newJsonWriter((Writer)writer));
}
}
catch (JsonIOException | IOException e) {
LOGGER.error("Couldn't save stats to {}", (Object)this.file, (Object)e);
}
}
@Override
public void setValue(Player player, Stat<?> stat, int count) {
super.setValue(player, stat, count);
this.dirty.add(stat);
}
private Set<Stat<?>> getDirty() {
HashSet result = Sets.newHashSet(this.dirty);
this.dirty.clear();
return result;
}
public void parse(DataFixer fixerUpper, JsonElement element) {
Dynamic data = new Dynamic((DynamicOps)JsonOps.INSTANCE, (Object)element);
data = DataFixTypes.STATS.updateToCurrentVersion(fixerUpper, data, NbtUtils.getDataVersion(data, 1343));
this.stats.putAll(STATS_CODEC.parse(data.get("stats").orElseEmptyMap()).resultOrPartial(error -> LOGGER.error("Failed to parse statistics for {}: {}", (Object)this.file, error)).orElse(Map.of()));
}
protected JsonElement toJson() {
JsonObject result = new JsonObject();
result.add("stats", (JsonElement)STATS_CODEC.encodeStart((DynamicOps)JsonOps.INSTANCE, (Object)this.stats).getOrThrow());
result.addProperty("DataVersion", (Number)SharedConstants.getCurrentVersion().dataVersion().version());
return result;
}
public void markAllDirty() {
this.dirty.addAll((Collection<Stat<?>>)this.stats.keySet());
}
public void sendStats(ServerPlayer player) {
Object2IntOpenHashMap statsToSend = new Object2IntOpenHashMap();
for (Stat<?> stat : this.getDirty()) {
statsToSend.put(stat, this.getValue(stat));
}
player.connection.send(new ClientboundAwardStatsPacket((Object2IntMap<Stat<?>>)statsToSend));
}
}