Minestom/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java

137 lines
4.8 KiB
Java

package net.minestom.server.gamedata.loottables;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;
import net.minestom.server.MinecraftServer;
import net.minestom.server.gamedata.Condition;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.utils.NamespaceIDHashMap;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
/**
* Handles loading and configuration of loot tables
*/
public final class LootTableManager {
private NamespaceIDHashMap<JsonDeserializer<? extends Condition>> conditionDeserializers = new NamespaceIDHashMap<>();
private NamespaceIDHashMap<LootTableType> tableTypes = new NamespaceIDHashMap<>();
private NamespaceIDHashMap<LootTableEntryType> entryTypes = new NamespaceIDHashMap<>();
private NamespaceIDHashMap<LootTableFunction> functions = new NamespaceIDHashMap<>();
private NamespaceIDHashMap<LootTable> cache = new NamespaceIDHashMap<>();
private Gson gson;
public LootTableManager() {
gson = new GsonBuilder()
.registerTypeAdapter(RangeContainer.class, new RangeContainer.Deserializer())
.registerTypeAdapter(ConditionContainer.class, new ConditionContainer.Deserializer(this))
.create();
}
/**
* Registers a condition factory to the given namespaceID
*
* @param namespaceID
* @param factory
*/
public <T extends Condition> void registerConditionDeserializer(NamespaceID namespaceID, JsonDeserializer<T> factory) {
conditionDeserializers.put(namespaceID, factory);
}
/**
* Registers a loot table type to the given namespaceID
*
* @param namespaceID
* @param type
*/
public void registerTableType(NamespaceID namespaceID, LootTableType type) {
tableTypes.put(namespaceID, type);
}
/**
* Registers a loot table entry type to the given namespaceID
*
* @param namespaceID
* @param type
*/
public void registerEntryType(NamespaceID namespaceID, LootTableEntryType type) {
entryTypes.put(namespaceID, type);
}
/**
* Registers a loot table function to the given namespaceID
*
* @param namespaceID
* @param function
*/
public void registerFunction(NamespaceID namespaceID, LootTableFunction function) {
functions.put(namespaceID, function);
}
public LootTable load(NamespaceID name) throws FileNotFoundException {
return null; // FIXME
//return load(name, new FileReader(new File(ResourceGatherer.DATA_FOLDER, "data/" + name.getDomain() + "/loot_tables/" + name.getPath() + ".json")));
}
/**
* Loads a loot table with the given name. Loot tables can be cached, so 'reader' is used only on cache misses
*
* @param name the name to cache the loot table with
* @param reader the reader to read the loot table from, if none cached. **Will** be closed no matter the results of this call
* @return
*/
public LootTable load(NamespaceID name, Reader reader) {
try (reader) {
return cache.computeIfAbsent(name, _name -> create(reader));
} catch (IOException e) {
MinecraftServer.getExceptionManager().handleException(e);
return null;
}
}
private LootTable create(Reader reader) {
LootTableContainer container = gson.fromJson(reader, LootTableContainer.class);
return container.createTable(this);
}
/**
* Returns the registered table type corresponding to the given namespace ID. If none is registered, throws {@link IllegalArgumentException}
*
* @param id
* @return
*/
public LootTableType getTableType(NamespaceID id) {
if (!tableTypes.containsKey(id))
throw new IllegalArgumentException("Unknown table type: " + id);
return tableTypes.get(id);
}
/**
* Returns the registered entry type corresponding to the given namespace ID. If none is registered, throws {@link IllegalArgumentException}
*
* @param id
* @return
*/
public LootTableEntryType getEntryType(NamespaceID id) {
if (!entryTypes.containsKey(id))
throw new IllegalArgumentException("Unknown entry type: " + id);
return entryTypes.get(id);
}
/**
* Returns the registered table type corresponding to the given namespace ID. If none is registered, returns {@link LootTableFunction#IDENTITY}
*
* @param id
* @return
*/
public LootTableFunction getFunction(NamespaceID id) {
return functions.getOrDefault(id, LootTableFunction.IDENTITY);
}
public JsonDeserializer<? extends Condition> getConditionDeserializer(NamespaceID id) {
return conditionDeserializers.getOrDefault(id, (json, typeOfT, context) -> Condition.ALWAYS_NO);
}
}