diff --git a/build.gradle b/build.gradle index 0a782f2..c8f421e 100644 --- a/build.gradle +++ b/build.gradle @@ -153,7 +153,7 @@ jar { "Specification-Vendor" : "zontreck", "Specification-Version" : "1", // We are version 1 of ourselves "Implementation-Title" : project.name, - "Implementation-Version" : project.jar.archiveVersion, + "Implementation-Version" : version, "Implementation-Vendor" : "zontreck", "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) @@ -176,7 +176,7 @@ task devJar(type: Jar) { "Specification-Vendor": "zontreck", "Specification-Version": "1", "Implementation-Title": project.name, - "Implementation-Version": project.jar.archiveVersion, + "Implementation-Version": version, "Implementation-Vendor": "zontreck", "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) diff --git a/gradle.properties b/gradle.properties index 13f77c1..fbbed54 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.0228230925 +myversion=1.0.5.0228232222 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 f408fb5..715e567 100644 --- a/src/main/java/dev/zontreck/libzontreck/LibZontreck.java +++ b/src/main/java/dev/zontreck/libzontreck/LibZontreck.java @@ -13,14 +13,18 @@ import org.slf4j.Logger; import com.mojang.logging.LogUtils; +import dev.zontreck.libzontreck.commands.Commands; import dev.zontreck.libzontreck.events.ForgeEventHandlers; 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.networking.ModMessages; import dev.zontreck.libzontreck.profiles.Profile; +import dev.zontreck.libzontreck.types.ModMenuTypes; import dev.zontreck.libzontreck.util.DelayedExecutorService; import dev.zontreck.libzontreck.util.FileTreeDatastore; +import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.common.MinecraftForge; @@ -32,6 +36,7 @@ import net.minecraftforge.event.server.ServerStoppingEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @@ -45,6 +50,10 @@ public class LibZontreck { public static boolean ALIVE; public static final String FILESTORE = FileTreeDatastore.get(); public static final Path BASE_CONFIG; + public static final String PLAYER_INFO_URL = "https://api.mojang.com/users/profiles/minecraft/"; + public static final String PLAYER_SKIN_URL = "https://sessionserver.mojang.com/session/minecraft/profile/"; + + static{ PROFILES = new HashMap<>(); @@ -69,10 +78,12 @@ public class LibZontreck { MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new ForgeEventHandlers()); + MinecraftForge.EVENT_BUS.register(new Commands()); } private void setup(final FMLCommonSetupEvent event) { + ModMessages.register(); } @@ -97,4 +108,14 @@ public class LibZontreck { } } + @Mod.EventBusSubscriber(modid = MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) + public static class ClientModEvents + { + @SubscribeEvent + public static void onClientSetup(FMLClientSetupEvent ev) + { + //MenuScreens.register(ModMenuTypes.CHESTGUI.get(), ChestGuiScreen::new); + } + } + } diff --git a/src/main/java/dev/zontreck/libzontreck/commands/Commands.java b/src/main/java/dev/zontreck/libzontreck/commands/Commands.java new file mode 100644 index 0000000..9ce7713 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/commands/Commands.java @@ -0,0 +1,17 @@ +package dev.zontreck.libzontreck.commands; + +import dev.zontreck.libzontreck.LibZontreck; +import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber(modid=LibZontreck.MOD_ID, bus=Mod.EventBusSubscriber.Bus.FORGE) +public class Commands { + @SubscribeEvent + public void onCommandsRegister(RegisterCommandsEvent ev) + { + CreditsCommand.register(ev.getDispatcher()); + GetHead.register(ev.getDispatcher()); + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/commands/CreditsCommand.java b/src/main/java/dev/zontreck/libzontreck/commands/CreditsCommand.java new file mode 100644 index 0000000..239e3c5 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/commands/CreditsCommand.java @@ -0,0 +1,30 @@ +package dev.zontreck.libzontreck.commands; + +import com.mojang.brigadier.CommandDispatcher; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.PlayerHeadItem; + +public class CreditsCommand { + public static void register(CommandDispatcher dispatch) + { + dispatch.register(Commands.literal("aria_credits").executes(s->credits(s.getSource()))); + } + + private static int credits(CommandSourceStack source) { + // Open the credits GUI + if(source.getEntity() instanceof Player) + { + // OK. + ServerPlayer play = (ServerPlayer)source.getEntity(); + + + return 0; + }else return 1; + } + + +} diff --git a/src/main/java/dev/zontreck/libzontreck/commands/GetHead.java b/src/main/java/dev/zontreck/libzontreck/commands/GetHead.java new file mode 100644 index 0000000..1fe9af8 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/commands/GetHead.java @@ -0,0 +1,37 @@ +package dev.zontreck.libzontreck.commands; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import dev.zontreck.libzontreck.util.HeadUtilities; +import dev.zontreck.libzontreck.util.HeadCache.HeadCacheItem; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.PlayerHeadItem; + +public class GetHead { + public static void register(CommandDispatcher dispatch) + { + dispatch.register(Commands.literal("aria_debug_get_head").executes(c-> getHead(c.getSource(), c.getSource().getEntity().getName().getContents())).then(Commands.argument("name", StringArgumentType.string()).executes(c -> getHead(c.getSource(), StringArgumentType.getString(c, "name"))))); + + } + + private static int getHead(CommandSourceStack source, String string) { + try { + ServerPlayer player= source.getPlayerOrException(); + ItemStack head = HeadUtilities.get(string); + + player.addItem(head); + } catch (CommandSyntaxException e) { + e.printStackTrace(); + } + + + return 0; + } + +} diff --git a/src/main/java/dev/zontreck/libzontreck/dynamicchest/ChestGuiMenu.java b/src/main/java/dev/zontreck/libzontreck/dynamicchest/ChestGuiMenu.java new file mode 100644 index 0000000..1e5b0b3 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/dynamicchest/ChestGuiMenu.java @@ -0,0 +1,48 @@ +package dev.zontreck.libzontreck.dynamicchest; + +import dev.zontreck.libzontreck.networking.structures.OpenGUIRequest; +import dev.zontreck.libzontreck.types.ModMenuTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.SlotItemHandler; + +public class ChestGuiMenu extends AbstractContainerMenu +{ + public final Player player; + + public ChestGuiMenu(int id, Inventory player) + { + this(id, player, new ItemStackHandler(36), BlockPos.ZERO, player.player, null); + } + + public ChestGuiMenu(int id, Inventory player, IItemHandler handler, BlockPos pos, Player play, OpenGUIRequest request) + { + super(ModMenuTypes.CHESTGUI.get(), id); + this.player=play; + + int slotSize=18; + int startX=11; + int startY=11; + + for(int row=0; row<4; row++) + { + for(int column = 0; column<9;column++) + { + addSlot(new SlotItemHandler(handler, row * 9 + column, startX + column * slotSize, startY + row * slotSize)); + } + } + + } + + @Override + public boolean stillValid(Player pPlayer) { + return true; // This is dynamic. We have no block entity! + } + +} diff --git a/src/main/java/dev/zontreck/libzontreck/dynamicchest/ChestGuiScreen.java b/src/main/java/dev/zontreck/libzontreck/dynamicchest/ChestGuiScreen.java new file mode 100644 index 0000000..388b6b5 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/dynamicchest/ChestGuiScreen.java @@ -0,0 +1,5 @@ +package dev.zontreck.libzontreck.dynamicchest; + +public class ChestGuiScreen { + +} diff --git a/src/main/java/dev/zontreck/libzontreck/networking/ModMessages.java b/src/main/java/dev/zontreck/libzontreck/networking/ModMessages.java new file mode 100644 index 0000000..e29fc26 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/networking/ModMessages.java @@ -0,0 +1,54 @@ +package dev.zontreck.libzontreck.networking; + +import dev.zontreck.libzontreck.LibZontreck; +import dev.zontreck.libzontreck.networking.packets.ChestGUIOpenC2S; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.network.NetworkDirection; +import net.minecraftforge.network.NetworkRegistry; +import net.minecraftforge.network.PacketDistributor; +import net.minecraftforge.network.simple.SimpleChannel; + +/** + * Networking system! + */ +public class ModMessages { + private static SimpleChannel INSTANCE; + private static int PACKET_ID=0; + private static int id() + { + return PACKET_ID++; + } + public static void register() + { + SimpleChannel net = NetworkRegistry.ChannelBuilder.named(new ResourceLocation(LibZontreck.MOD_ID, "messages")) + .networkProtocolVersion(()->"1.0") + .clientAcceptedVersions(s->true) + .serverAcceptedVersions(s->true) + .simpleChannel(); + + INSTANCE=net; + + net.messageBuilder(ChestGUIOpenC2S.class, id(), NetworkDirection.PLAY_TO_SERVER) + .decoder(ChestGUIOpenC2S::new) + .encoder(ChestGUIOpenC2S::toBytes) + .consumer(ChestGUIOpenC2S::handle) + .add(); + + } + + + public static void sendToServer(MSG message){ + INSTANCE.sendToServer(message); + } + + public static void sendToPlayer(MSG message, ServerPlayer player) + { + INSTANCE.send(PacketDistributor.PLAYER.with(()->player), message); + } + + public static void sendToAll(MSG message) + { + INSTANCE.send(PacketDistributor.ALL.noArg(), message); + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/networking/chestGUI.md b/src/main/java/dev/zontreck/libzontreck/networking/chestGUI.md new file mode 100644 index 0000000..e166384 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/networking/chestGUI.md @@ -0,0 +1,21 @@ +About Chest GUI +===== + +A chest GUI is basically a dynamic menu that uses items and the standard chest layout to present a list of options in game. + +These items cannot be removed from the chest and the click event is instead passed on as a ChestGUIEvent. Because the mod requesting this might not be on the client, the event is sent in both locations by utilizing a network packet. + + + +ChestGUIEvent +==== + +This event is the parent of several other events. + +OptionInteractEvent +---- +This event gets dispatched on both the client and server when a option is interacted with. + +OptionUpdateEvent +---- +To be sent by the mod originating this dynamic menu. This event will instruct the ChestGUI to update a item, or multiple items after a interaction, or something else occuring. If the GUI is not open, this event gets ignored. This event should only be sent when we know the GUI is actually open! \ No newline at end of file diff --git a/src/main/java/dev/zontreck/libzontreck/networking/packets/ChestGUIOpenC2S.java b/src/main/java/dev/zontreck/libzontreck/networking/packets/ChestGUIOpenC2S.java new file mode 100644 index 0000000..bf69280 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/networking/packets/ChestGUIOpenC2S.java @@ -0,0 +1,43 @@ +package dev.zontreck.libzontreck.networking.packets; + +import java.util.function.Supplier; + +import dev.zontreck.libzontreck.networking.structures.OpenGUIRequest; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.network.NetworkEvent; + +/** + * To be used by first-party and third-party mods to assemble a menu + * NOTE: Without the server, only the credits menu will be able to be opened, which is the only built-in menu utilizing this system. + */ +public class ChestGUIOpenC2S { + private CompoundTag data; + + public ChestGUIOpenC2S(OpenGUIRequest request) + { + data = request.serialize(); + } + + public ChestGUIOpenC2S(FriendlyByteBuf buf) + { + data = buf.readAnySizeNbt(); + } + + public void toBytes(FriendlyByteBuf buf) + { + buf.writeNbt(data); + } + + public boolean handle(Supplier supplier) + { + NetworkEvent.Context ctx = supplier.get(); + + ctx.enqueueWork(()->{ + // We are on the server! + OpenGUIRequest req = new OpenGUIRequest(data); + }); + + return true; + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/networking/structures/OpenGUIRequest.java b/src/main/java/dev/zontreck/libzontreck/networking/structures/OpenGUIRequest.java new file mode 100644 index 0000000..f66b183 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/networking/structures/OpenGUIRequest.java @@ -0,0 +1,48 @@ +package dev.zontreck.libzontreck.networking.structures; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; + +public class OpenGUIRequest { + public List options = new ArrayList<>(); + public String GUITitle; + public UUID playerID; + + public OpenGUIRequest(CompoundTag tag) + { + ListTag items = tag.getList("items", Tag.TAG_COMPOUND); + + for(Tag tags : items) + { + ItemStack is = ItemStack.of((CompoundTag)tags); + options.add(is); + } + + GUITitle = tag.getString("title"); + playerID = tag.getUUID("player"); + } + + public CompoundTag serialize() + { + CompoundTag tag = new CompoundTag(); + tag.putString("title", GUITitle); + tag.putUUID("player", playerID); + ListTag lst = new ListTag(); + for (ItemStack itemStack : options) { + lst.add(itemStack.serializeNBT()); + } + tag.put("items", lst); + + return tag; + } + + public OpenGUIRequest(){} +} diff --git a/src/main/java/dev/zontreck/libzontreck/types/ModMenuTypes.java b/src/main/java/dev/zontreck/libzontreck/types/ModMenuTypes.java new file mode 100644 index 0000000..ce4c4fa --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/types/ModMenuTypes.java @@ -0,0 +1,23 @@ +package dev.zontreck.libzontreck.types; + +import dev.zontreck.libzontreck.LibZontreck; +import dev.zontreck.libzontreck.dynamicchest.ChestGuiMenu; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraftforge.common.extensions.IForgeMenuType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.network.IContainerFactory; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public class ModMenuTypes { + public static DeferredRegister> REGISTER = DeferredRegister.create(ForgeRegistries.CONTAINERS, LibZontreck.MOD_ID); + + public static final RegistryObject> CHESTGUI = REGISTER.register("dynchest", ()->new MenuType<>(ChestGuiMenu::new)); + + public static void register(IEventBus bus) + { + REGISTER.register(bus); + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/util/ChatHelpers.java b/src/main/java/dev/zontreck/libzontreck/util/ChatHelpers.java index 26a99bb..5703678 100644 --- a/src/main/java/dev/zontreck/libzontreck/util/ChatHelpers.java +++ b/src/main/java/dev/zontreck/libzontreck/util/ChatHelpers.java @@ -5,6 +5,7 @@ import java.util.UUID; import dev.zontreck.libzontreck.LibZontreck; import dev.zontreck.libzontreck.chat.ChatColor; 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.Player; @@ -74,6 +75,16 @@ public class ChatHelpers { broadcastTo(ID.getUUID(), message, server, true); } + /** + * Returns the output with colors applied, and chat entries replaced using [number] as the format + * @param input + * @param inputs Entries to replace with in input + * @return + */ + public static TextComponent macro(String input, String... inputs) + { + return new TextComponent(macroize(input,inputs)); + } /** * Returns the output with colors applied, and chat entries replaced using [number] as the format * @param input diff --git a/src/main/java/dev/zontreck/libzontreck/util/HeadCache.java b/src/main/java/dev/zontreck/libzontreck/util/HeadCache.java new file mode 100644 index 0000000..eaaa4d8 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/util/HeadCache.java @@ -0,0 +1,184 @@ +package dev.zontreck.libzontreck.util; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import dev.zontreck.libzontreck.LibZontreck; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.PlayerHeadItem; + +public class HeadCache +{ + public static final Path CACHE_FILE; + public static final HeadCache CACHE = new HeadCache(); + public List items = new ArrayList<>(); + + public class HeadCacheItem + { + public UUID owner; + public String texture; + public String name; + + public CompoundTag serialize() + { + CompoundTag tag = new CompoundTag(); + tag.putUUID("id", owner); + tag.putString("texture", texture); + tag.putString("name", name); + + return tag; + } + + public HeadCacheItem(CompoundTag tag) + { + owner = tag.getUUID("id"); + texture = tag.getString("texture"); + name = tag.getString("name"); + } + + private HeadCacheItem() + {} + + public ItemStack getAsItem() + { + ItemStack head = new ItemStack(Items.PLAYER_HEAD, 1); + + CompoundTag skullOwner = new CompoundTag(); + skullOwner.putUUID("Id", owner); + + CompoundTag properties = new CompoundTag(); + ListTag textures = new ListTag(); + CompoundTag item = new CompoundTag(); + item.putString("Value", texture); + textures.add(item); + properties.put("textures", textures); + + skullOwner.put("Properties", properties); + head.addTagElement(PlayerHeadItem.TAG_SKULL_OWNER, skullOwner); + + TextComponent headname = ChatHelpers.macro("!Dark_red![0]'s Head", name); + head.setHoverName(headname); + + return head; + + } + + public static UUID toNewID(final String input) { + return UUID.fromString(input.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")); + } + public String getOldID() + { + return owner.toString().replaceAll("-", ""); + } + } + + static{ + CACHE_FILE = LibZontreck.BASE_CONFIG.resolve("head_cache.nbt"); + + if(CACHE_FILE.toFile().exists()) + { + // Deserialize heads + try { + CompoundTag tag = NbtIo.read(CACHE_FILE.toFile()); + CACHE.initFromCache(tag); + } catch (IOException e) { + e.printStackTrace(); + } + }else { + CACHE.resetCache(); + } + } + + private void initFromCache(CompoundTag tag) + { + ListTag heads = tag.getList("heads", Tag.TAG_COMPOUND); + + for (Tag tag2 : heads) { + CompoundTag tag3 = (CompoundTag)tag2; + items.add(new HeadCacheItem(tag3)); + } + } + + public void saveCache() + { + try { + NbtIo.write(serialize(), CACHE_FILE.toFile()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public CompoundTag serialize() + { + ListTag heads = new ListTag(); + for (HeadCacheItem item : items) { + heads.add(item.serialize()); + } + + CompoundTag tag = new CompoundTag(); + tag.put("heads", heads); + + return tag; + } + + /** + * Adds a new head to the cache + * @param owner + * @param texture + * @param name + * @return The item added to the cache + * @return Null if not added! + */ + public HeadCacheItem addToCache(UUID owner, String texture, String name) + { + HeadCacheItem item = new HeadCacheItem(); + item.name=name; + item.texture=texture; + item.owner=owner; + if(!hasHead(name)) + { + items.add(item); + saveCache(); + return item; + } + return null; + } + + /** + * Initializes the cache fresh using the default heads for the developer(s), contributors/testers, and patreon supporters + */ + public void resetCache() + { + HeadUtilities.get("zontreck"); + HeadUtilities.get("PossumTheWarrior"); + HeadUtilities.get("GemMD"); + } + + public boolean hasHead(String playerName) + { + for (HeadCacheItem item : items) { + if(item.name.equals(playerName)) return true; + } + return false; + } + + + public HeadCacheItem getHead(String playerName) + { + for (HeadCacheItem item : items) { + if(item.name.equals(playerName)) return item; + } + return null; + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/util/HeadUtilities.java b/src/main/java/dev/zontreck/libzontreck/util/HeadUtilities.java new file mode 100644 index 0000000..1152415 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/util/HeadUtilities.java @@ -0,0 +1,67 @@ +package dev.zontreck.libzontreck.util; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Scanner; +import java.util.UUID; + +import com.google.gson.Gson; + +import dev.zontreck.libzontreck.LibZontreck; +import dev.zontreck.libzontreck.util.HeadCache.HeadCacheItem; +import net.minecraft.world.item.ItemStack; + +/** + * Added to showcase Patreon supporters and those who have helped test or provide feedback and suggestions! + */ +public class HeadUtilities { + private static HeadCacheItem cachedLookup(String playerName) + { + if(HeadCache.CACHE.hasHead(playerName)) + { + HeadCacheItem item = HeadCache.CACHE.getHead(playerName); + return item; + }else { + // Look up head then add to cache + return externalHeadRequest(playerName); + } + } + + public static ItemStack get(String playerName) + { + return cachedLookup(playerName).getAsItem(); + } + + private static HeadCacheItem externalHeadRequest(String playerName) + { + String data=""; + try { + data = HttpHelper.getFrom(new URL(LibZontreck.PLAYER_INFO_URL + playerName)); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + + if(data.equals("")){ + return null; + } + + UUID PlayerID = null; + String playerTexture=""; + try{ + Gson gson = new Gson(); + PlayerInfo info = gson.fromJson(data, PlayerInfo.class); + + String data2 = HttpHelper.getFrom(new URL(LibZontreck.PLAYER_SKIN_URL + info.id)); + + PlayerProfileInfo info2 = gson.fromJson(data2, PlayerProfileInfo.class); + playerTexture = info2.properties.get(0).value; + PlayerID = HeadCache.HeadCacheItem.toNewID(info.id); + + + return HeadCache.CACHE.addToCache(PlayerID, playerTexture, playerName); + }catch(Exception e) + { + return null; + } + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/util/HttpHelper.java b/src/main/java/dev/zontreck/libzontreck/util/HttpHelper.java new file mode 100644 index 0000000..b588c9d --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/util/HttpHelper.java @@ -0,0 +1,22 @@ +package dev.zontreck.libzontreck.util; + +import java.net.URL; +import java.util.Scanner; + +public class HttpHelper { + public static String getFrom(URL url) + { + String data = ""; + try (Scanner s = new Scanner(url.openStream())) + { + s.useDelimiter("\\A"); + data = s.hasNext() ? s.next() : ""; + }catch(Exception e) + { + + } + + + return data; + } +} diff --git a/src/main/java/dev/zontreck/libzontreck/util/PlayerInfo.java b/src/main/java/dev/zontreck/libzontreck/util/PlayerInfo.java new file mode 100644 index 0000000..1ca1b71 --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/util/PlayerInfo.java @@ -0,0 +1,8 @@ +package dev.zontreck.libzontreck.util; + +import java.util.UUID; + +public class PlayerInfo { + public String name; + public String id; +} diff --git a/src/main/java/dev/zontreck/libzontreck/util/PlayerProfileInfo.java b/src/main/java/dev/zontreck/libzontreck/util/PlayerProfileInfo.java new file mode 100644 index 0000000..cf6fdbd --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/util/PlayerProfileInfo.java @@ -0,0 +1,9 @@ +package dev.zontreck.libzontreck.util; + +import java.util.List; + +public class PlayerProfileInfo { + public String id; + public String name; + public List properties; +} diff --git a/src/main/java/dev/zontreck/libzontreck/util/PlayerTextureContainer.java b/src/main/java/dev/zontreck/libzontreck/util/PlayerTextureContainer.java new file mode 100644 index 0000000..a6e54bc --- /dev/null +++ b/src/main/java/dev/zontreck/libzontreck/util/PlayerTextureContainer.java @@ -0,0 +1,6 @@ +package dev.zontreck.libzontreck.util; + +public class PlayerTextureContainer { + public String name; + public String value; +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index b107e9d..8156823 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -9,9 +9,9 @@ modLoader="javafml" #mandatory loaderVersion="[40,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. -license="All rights reserved" +license="GPLv3" # A URL to refer people to when problems occur with this mod -#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional +issueTrackerURL="https://github.com/zontreck/LibZontreckMod/issues" #optional # A list of mods - how many allowed here is determined by the individual mod loader [[mods]] #mandatory # The modid of the mod @@ -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.0228230925" #mandatory +version="${file.jarVersion}" #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/ @@ -42,7 +42,8 @@ authors="Zontreck" #optional # The description text for the mod (multi line!) (#mandatory) description=''' -This mod provides common code to all of zontreck's mods. It by itself does absolutely nothing +This mod provides common code to all of zontreck's mods. + ''' # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.libzontreck]] #optional diff --git a/src/main/resources/assets/libzontreck/textures/gui/chest_gui.png b/src/main/resources/assets/libzontreck/textures/gui/chest_gui.png new file mode 100644 index 0000000..a7aef95 Binary files /dev/null and b/src/main/resources/assets/libzontreck/textures/gui/chest_gui.png differ diff --git a/src/main/resources/assets/libzontreck/textures/gui/gui.aseprite b/src/main/resources/assets/libzontreck/textures/gui/gui.aseprite new file mode 100644 index 0000000..55217e3 Binary files /dev/null and b/src/main/resources/assets/libzontreck/textures/gui/gui.aseprite differ