Fix bugs that were preventing the mod from loading due to datapack issues

Restructure the vault system
Remove JDBC Drivers as a runtime requirement
Restructure profiles
Restructure homes
Restructure warps
Switch to a FileTreeDatastore
This commit is contained in:
Aria 2023-02-24 01:27:35 -07:00
parent 553ff429f3
commit 5ee0aa47e9
62 changed files with 1385 additions and 705 deletions

View file

@ -0,0 +1,15 @@
package dev.zontreck.otemod.implementation.vault;
/**
* You cannot create or open the vault due to server settings
*/
public class NoMoreVaultException extends Exception
{
public int vault;
public NoMoreVaultException(String msg, int vaultNum)
{
super(msg);
vault=vaultNum;
}
}

View file

@ -0,0 +1,64 @@
package dev.zontreck.otemod.implementation.vault;
import java.io.File;
import java.io.IOException;
import dev.zontreck.otemod.implementation.profiles.Profile;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
public class Vault {
public int vaultNum;
public File file_location;
public Profile user;
public final boolean isNew;
private CompoundTag tag;
protected Vault(int num, File loc, Profile owner)
{
user=owner;
file_location=loc;
vaultNum=num;
isNew=!file_location.exists();
if(!isNew){
try {
tag = NbtIo.read(loc);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* This will return the contents of the NBT Vault
* @return
*/
public CompoundTag getContents(){
return tag;
}
/**
* This sets the internal compound tag of the vault provider, but also saves it to the file immediately.
* @param newTag
*/
public void setContents(CompoundTag newTag)
{
tag=newTag;
try {
NbtIo.write(newTag, file_location);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This is called to dispose of the vault and the vault file
*/
public void delete()
{
if(file_location.exists())
file_location.delete();
}
}

View file

@ -13,15 +13,23 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.otemod.OTEMod;
import dev.zontreck.otemod.chat.ChatServerOverride;
import dev.zontreck.otemod.implementation.events.VaultModifiedEvent;
import dev.zontreck.otemod.implementation.profiles.Profile;
import dev.zontreck.otemod.implementation.profiles.UserProfileNotYetExistsException;
import dev.zontreck.otemod.implementation.vault.VaultProvider.VaultAccessStrategy;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuConstructor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.items.ItemStackHandler;
public class VaultContainer
@ -29,13 +37,16 @@ public class VaultContainer
public static Map<UUID, VaultContainer> VAULT_REGISTRY = new HashMap<>();
public VaultMenu theContainer;
public ItemStackHandler myInventory;
public ItemStackHandler startingInventory;
public MenuConstructor serverMenu;
public UUID owner;
private MinecraftServer server;
public final int VAULT_NUMBER;
public final UUID VaultID;
public VaultContainer(ServerPlayer player, int vaultNum) {
public Vault main_accessor;
public VaultContainer(ServerPlayer player, int vaultNum) throws NoMoreVaultException {
myInventory = new ItemStackHandler(54); // Vaults have a fixed size at the same as a double chest
startingInventory = new ItemStackHandler(64);
theContainer = new VaultMenu(player.containerCounter+1, player.getInventory(), myInventory, BlockPos.ZERO, player, vaultNum);
VaultID = theContainer.VaultMenuID;
owner = player.getUUID();
@ -44,67 +55,66 @@ public class VaultContainer
VAULT_NUMBER=vaultNum;
if(VAULT_NUMBER == -1)return; // Trash ID
Connection con = OTEMod.DB.getConnection();
// Check database for vault
PreparedStatement pstat;
VaultAccessStrategy strategy;
try {
con.beginRequest();
pstat = con.prepareStatement("SELECT * FROM `vaults` WHERE `uuid`=? AND `number`=?;");
pstat.setString(1, player.getStringUUID());
pstat.setInt(2, vaultNum);
ResultSet rs = pstat.executeQuery();
while(rs.next())
strategy = VaultProvider.check(Profile.get_profile_of(player.getStringUUID()), vaultNum);
if(strategy == VaultAccessStrategy.CREATE || strategy == VaultAccessStrategy.OPEN)
{
// We have a vault, deserialize the container
String data = rs.getString("data");
CompoundTag inv = NbtUtils.snbtToStructure(data);
myInventory.deserializeNBT(inv);
Vault accessor = VaultProvider.get(Profile.get_profile_of(player.getStringUUID()), vaultNum);
if(accessor.isNew)
{
main_accessor=accessor;
return;
}else {
myInventory.deserializeNBT(accessor.getContents());
startingInventory.deserializeNBT(accessor.getContents());
}
main_accessor=accessor;
}else {
// DENY
throw new NoMoreVaultException("No more vaults can be created", vaultNum);
}
con.endRequest();
} catch (SQLException | CommandSyntaxException e) {
e.printStackTrace();
} catch (UserProfileNotYetExistsException e) {
throw new NoMoreVaultException("User profile not exists. No vault can be opened or created", -9999);
}
// Container is now ready to be sent to the client!
}
public void commit()
{
if(VAULT_NUMBER == -1)return; // We have no need to save the trash
boolean isEmpty=true;
CompoundTag saved = myInventory.serializeNBT();
ChatServerOverride.broadcastToAbove(owner, new TextComponent(ChatColor.BOLD+ChatColor.DARK_GREEN+"Saving the vault's contents..."), server);
String toSave= NbtUtils.structureToSnbt(saved);
Connection con = OTEMod.DB.getConnection();
try{
con.beginRequest();
PreparedStatement ps = con.prepareStatement("REPLACE INTO `vaults` (uuid, number, data) VALUES (?,?,?);");
ps.setString(1, owner.toString());
ps.setInt(2, VAULT_NUMBER);
ps.setString(3, toSave);
boolean has_items = false;
for (int i = 0; i< myInventory.getSlots(); i++){
ItemStack IS = myInventory.getStackInSlot(i);
if(!IS.isEmpty()){
has_items=true;
}
}
if(!has_items)
{
ps = con.prepareStatement("DELETE FROM `vaults` WHERE uuid=? AND number=?;");
ps.setString(1, owner.toString());
ps.setInt(2, VAULT_NUMBER);
}
ps.execute();
con.endRequest();
}catch(SQLException e){
Profile profile=null;
try {
profile = Profile.get_profile_of(owner.toString());
} catch (UserProfileNotYetExistsException e) {
e.printStackTrace();
return;
}
for(int i = 0;i<myInventory.getSlots();i++)
{
ItemStack is = myInventory.getStackInSlot(i);
if(!is.is(Items.AIR))
{
isEmpty=false;
}
}
if(!isEmpty)
main_accessor.setContents(saved);
else
main_accessor.delete();
VaultModifiedEvent vme = new VaultModifiedEvent(VAULT_NUMBER, profile, VaultProvider.getInUse(profile), myInventory, startingInventory);
OTEMod.bus.post(vme);
}
}

View file

@ -0,0 +1,98 @@
package dev.zontreck.otemod.implementation.vault;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import dev.zontreck.otemod.configs.OTEServerConfig;
import dev.zontreck.otemod.database.FileTreeDatastore;
import dev.zontreck.otemod.implementation.profiles.Profile;
public class VaultProvider extends FileTreeDatastore
{
public enum VaultAccessStrategy
{
OPEN,
CREATE,
DENY
}
public static final Path FILE_TREE_PATH = of("vaults");
public static VaultAccessStrategy check(Profile profile, int vaultNum)
{
if(!FILE_TREE_PATH.toFile().exists())
{
try {
Files.createDirectory(FILE_TREE_PATH);
} catch (IOException e) {
e.printStackTrace();
}
}
Path userVaultPath = FILE_TREE_PATH.resolve(profile.user_id);
File vaultFile = userVaultPath.resolve(String.valueOf(vaultNum)+".nbt").toFile();
if(!userVaultPath.toFile().exists()){
try {
Files.createDirectory(userVaultPath);
} catch (IOException e) {
e.printStackTrace();
}
}
if(vaultFile.exists())
{
return VaultAccessStrategy.OPEN;
}else {
List<File> files = getListOfFiles(userVaultPath);
if(isAtMaxVaults(profile, files.size()))
{
return VaultAccessStrategy.DENY;
}else {
return VaultAccessStrategy.CREATE;
}
}
}
public static int getInUse(Profile prof)
{
Path uservaults = FILE_TREE_PATH.resolve(prof.user_id);
return getListOfFiles(uservaults).size();
}
public static boolean isAtMaxVaults(Profile prof, int consumed)
{
if(OTEServerConfig.MAX_VAULTS.get()==0){
if(consumed < prof.available_vaults){
return false;
}else return true;
}
if(prof.available_vaults >= OTEServerConfig.MAX_VAULTS.get())
{
if(consumed<prof.available_vaults)
{
return false;
}
return true;
}else{
if(consumed<prof.available_vaults)return false;
else return true;
}
}
public static Vault get(Profile profile, int vault) throws NoMoreVaultException
{
VaultAccessStrategy strat = check(profile,vault);
if(strat == VaultAccessStrategy.CREATE || strat == VaultAccessStrategy.OPEN)
{
Path userVault = FILE_TREE_PATH.resolve(profile.user_id);
Vault v = new Vault(vault, userVault.resolve(String.valueOf(vault)+".nbt").toFile(), profile);
return v;
}else throw new NoMoreVaultException("Cannot open due to server limits", vault);
}
}