diff --git a/gradle.properties b/gradle.properties index c953804..d617e37 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,5 +5,5 @@ org.gradle.daemon=false mc_version=1.18.2 forge_version=40.2.1 -myversion=1.0.5.2 +myversion=1.0.5.3 parchment_version=2022.11.06 \ No newline at end of file diff --git a/src/main/java/dev/zontreck/libzontreck/LibZontreck.java b/src/main/java/dev/zontreck/libzontreck/LibZontreck.java index 9eb1522..ec22475 100644 --- a/src/main/java/dev/zontreck/libzontreck/LibZontreck.java +++ b/src/main/java/dev/zontreck/libzontreck/LibZontreck.java @@ -1,18 +1,26 @@ package dev.zontreck.libzontreck; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + import org.slf4j.Logger; import com.mojang.logging.LogUtils; import dev.zontreck.libzontreck.events.PlayerChangedPositionEvent; +import dev.zontreck.libzontreck.events.ProfileLoadedEvent; import dev.zontreck.libzontreck.memory.PlayerContainer; import dev.zontreck.libzontreck.memory.VolatilePlayerStorage; +import dev.zontreck.libzontreck.profiles.Profile; import dev.zontreck.libzontreck.util.DelayedExecutorService; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; +import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.server.ServerStartedEvent; import net.minecraftforge.event.server.ServerStoppingEvent; import net.minecraftforge.eventbus.api.IEventBus; @@ -25,10 +33,15 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; public class LibZontreck { public static final Logger LOGGER = LogUtils.getLogger(); public static final String MOD_ID = "libzontreck"; + public static final Map PROFILES; public static MinecraftServer THE_SERVER; public static VolatilePlayerStorage playerStorage; public static boolean ALIVE; + static{ + PROFILES = new HashMap<>(); + } + public LibZontreck(){ LibZontreck.playerStorage=new VolatilePlayerStorage(); IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); @@ -81,5 +94,17 @@ public class LibZontreck { } } } + + + @SubscribeEvent + public void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent ev) + { + if(ev.getEntity().level.isClientSide)return; + + ServerPlayer player = (ServerPlayer)ev.getPlayer(); + Profile prof = Profile.factory(player); + + MinecraftForge.EVENT_BUS.post(new ProfileLoadedEvent(prof)); + } } } diff --git a/src/main/java/dev/zontreck/libzontreck/events/ProfileCreatedEvent.java b/src/main/java/dev/zontreck/libzontreck/events/ProfileCreatedEvent.java new file mode 100644 index 0000000..cff89e9 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/events/ProfileCreatedEvent.java @@ -0,0 +1,13 @@ +package dev.zontreck.libzontreck.events; + +import dev.zontreck.libzontreck.profiles.Profile; +import net.minecraftforge.eventbus.api.Event; + +public class ProfileCreatedEvent extends Event +{ + public String playerID; + public ProfileCreatedEvent(Profile newProfile) + { + playerID = newProfile.user_id; + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/events/ProfileLoadedEvent.java b/src/main/java/dev/zontreck/libzontreck/events/ProfileLoadedEvent.java new file mode 100644 index 0000000..02c8760 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/events/ProfileLoadedEvent.java @@ -0,0 +1,13 @@ +package dev.zontreck.libzontreck.events; + +import dev.zontreck.libzontreck.profiles.Profile; +import net.minecraftforge.eventbus.api.Event; + +public class ProfileLoadedEvent extends Event +{ + public Profile profile; + public ProfileLoadedEvent(Profile prof) + { + profile=prof; + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/events/ProfileUnloadedEvent.java b/src/main/java/dev/zontreck/libzontreck/events/ProfileUnloadedEvent.java new file mode 100644 index 0000000..95ebda3 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/events/ProfileUnloadedEvent.java @@ -0,0 +1,12 @@ +package dev.zontreck.libzontreck.events; + +import net.minecraftforge.eventbus.api.Event; + +public class ProfileUnloadedEvent extends Event +{ + public String user_id; + public ProfileUnloadedEvent(String id) + { + user_id=id; + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/profiles/Profile.java b/src/main/java/dev/zontreck/libzontreck/profiles/Profile.java new file mode 100644 index 0000000..b02e3cd --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/profiles/Profile.java @@ -0,0 +1,157 @@ +package dev.zontreck.libzontreck.profiles; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import dev.zontreck.libzontreck.LibZontreck; +import dev.zontreck.libzontreck.chat.ChatColor; +import dev.zontreck.libzontreck.events.ProfileCreatedEvent; +import dev.zontreck.libzontreck.events.ProfileUnloadedEvent; +import dev.zontreck.libzontreck.util.FileTreeDatastore; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.common.MinecraftForge; + +public class Profile { + public String username; + public String user_id; + public String prefix; + public String nickname; + public String name_color; // ChatColor.X + public String prefix_color; + public String chat_color; + public Boolean flying; + public int available_vaults; + + private File accessor; + + public static final Path BASE = FileTreeDatastore.of("libzontreck").resolve("profiles"); + + public Profile(String username, String prefix, String nickname, String name_color, String ID, String prefix_color, String chat_color, Boolean isFlying, int vaults, File vaultFile) { + this.username = username; + this.prefix = prefix; + this.nickname = nickname; + this.name_color = name_color; + this.user_id = ID; + this.prefix_color = prefix_color; + this.chat_color = chat_color; + this.flying=isFlying; + this.available_vaults=vaults; + + + this.accessor = vaultFile; + } + + + public static Profile get_profile_of(String UUID) throws UserProfileNotYetExistsException + { + if(LibZontreck.PROFILES.containsKey(UUID)){ + return LibZontreck.PROFILES.get(UUID); + }else { + // Create or load profile + Path userProfile = BASE.resolve(UUID); + if(userProfile.toFile().exists()) + { + // Load profile data + File ace = userProfile.resolve("profile.nbt").toFile(); + try { + Profile actual = load(NbtIo.read(ace), ace); + LibZontreck.PROFILES.put(UUID, actual); + return actual; + } catch (IOException e) { + throw new UserProfileNotYetExistsException(UUID); + } + + }else { + // Create directory, then throw a exception so a new profile gets created + try { + Files.createDirectories(userProfile); + } catch (IOException e) { + e.printStackTrace(); + } + throw new UserProfileNotYetExistsException(UUID); + } + } + } + + private static Profile load(CompoundTag tag, File accessor) + { + return new Profile(tag.getString("user"), tag.getString("prefix"), tag.getString("nick"), tag.getString("nickc"), tag.getString("id"), tag.getString("prefixc"), tag.getString("chatc"), tag.getBoolean("flying"), tag.getInt("vaults"), accessor); + } + + private static void generateNewProfile(ServerPlayer player) + { + + Path userProfile = BASE.resolve(player.getStringUUID()); + if(userProfile.toFile().exists()) + { + // Load profile data + File ace = userProfile.resolve("profile.dat").toFile(); + Profile template = new Profile(player.getName().getString(), "Member", player.getDisplayName().getString(), ChatColor.GREEN, player.getStringUUID(), ChatColor.AQUA, ChatColor.WHITE, false, 0, ace); + template.commit(); + + + MinecraftForge.EVENT_BUS.post(new ProfileCreatedEvent(template)); + + template=null; + return; + }else { + try { + Files.createDirectories(userProfile); + } catch (IOException e) { + e.printStackTrace(); + } + + generateNewProfile(player); + } + } + + @Override + public void finalize() + { + LibZontreck.LOGGER.info("Profile is unloaded for "+username); + MinecraftForge.EVENT_BUS.post(new ProfileUnloadedEvent(user_id)); + } + + public static void unload(Profile prof) + { + LibZontreck.PROFILES.remove(prof.user_id); + prof=null; + } + + public static Profile factory(ServerPlayer play) + { + try { + return get_profile_of(play.getStringUUID()); + } catch (UserProfileNotYetExistsException e) { + generateNewProfile(play); + return factory(play); + } + } + + public void commit() + { + // Save data to FileTree + CompoundTag serial = new CompoundTag(); + serial.putString("user", username); + serial.putString("prefix", prefix); + serial.putString("nick", nickname); + serial.putString("id", user_id); + serial.putString("nickc", name_color); + serial.putString("prefixc", prefix_color); + serial.putString("chatc", chat_color); + serial.putBoolean("flying", flying); + serial.putInt("vaults", available_vaults); + + + + try { + NbtIo.write(serial, accessor); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/profiles/UserProfileNotYetExistsException.java b/src/main/java/dev/zontreck/libzontreck/profiles/UserProfileNotYetExistsException.java new file mode 100644 index 0000000..c8e1780 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/profiles/UserProfileNotYetExistsException.java @@ -0,0 +1,9 @@ +package dev.zontreck.libzontreck.profiles; + +public class UserProfileNotYetExistsException extends Exception{ + String playerID; + public UserProfileNotYetExistsException(String id){ + super("A user profile does not yet exist"); + playerID=id; + } +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 5399500..4f361c7 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -19,7 +19,7 @@ modId="libzontreck" #mandatory # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it # ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata # see the associated build.gradle script for how to populate this completely automatically during a build -version="1.0.5.2" #mandatory +version="1.0.5.3" #mandatory # A display name for the mod displayName="LibZontreck" #mandatory # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/