Update major API Version to add some new interfaces.

This commit is contained in:
Aria 2023-03-18 21:01:18 -07:00
parent 1378a6fb21
commit 5d024f425c
26 changed files with 496 additions and 111 deletions

View file

@ -5,36 +5,26 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import dev.zontreck.libzontreck.permissions.PermissionStorage;
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;
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;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
@ -54,6 +44,9 @@ public class LibZontreck {
public static final String PLAYER_SKIN_URL = "https://sessionserver.mojang.com/session/minecraft/profile/";
public static LogicalSide CURRENT_SIDE;
static{
PROFILES = new HashMap<>();
@ -92,12 +85,18 @@ public class LibZontreck {
{
THE_SERVER = event.getServer();
ALIVE=true;
CURRENT_SIDE = LogicalSide.SERVER;
}
@SubscribeEvent
public void onServerStopping(final ServerStoppingEvent ev)
{
ALIVE=false;
try {
PermissionStorage.save();
} catch (IOException e) {
throw new RuntimeException(e);
}
Iterator<Profile> iProfile = PROFILES.values().iterator();
while(iProfile.hasNext())
@ -114,6 +113,9 @@ public class LibZontreck {
@SubscribeEvent
public static void onClientSetup(FMLClientSetupEvent ev)
{
LibZontreck.CURRENT_SIDE = LogicalSide.CLIENT;
LibZontreck.ALIVE=false; // Prevents loops on the client that are meant for server tick processing
//MenuScreens.register(ModMenuTypes.CHESTGUI.get(), ChestGuiScreen::new);
}
}

View file

@ -0,0 +1,23 @@
package dev.zontreck.libzontreck.events;
import dev.zontreck.libzontreck.profiles.Profile;
import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.eventbus.api.Event;
/**
* This class is not cancelable.
* This event is fired while the profile is saving. It is used to acquire misc data.
*
* The only part of this that is modifiable at this stage of saving is the tag.
*/
public class ProfileSavingEvent extends Event
{
public final Profile profile;
public CompoundTag tag;
public ProfileSavingEvent(Profile profile, CompoundTag tag)
{
this.profile=profile;
this.tag=tag;
}
}

View file

@ -0,0 +1,17 @@
package dev.zontreck.libzontreck.events;
import java.util.ArrayList;
import java.util.List;
import dev.zontreck.libzontreck.networking.packets.IPacket;
import net.minecraftforge.eventbus.api.Event;
/**
* Used to register your packets with LibZontreck. Packets must extend IPacket and implement PacketSerializable. This is dispatched on both logical sides, and is considered a final event. It is not cancelable
* @see IPacket
* @see PacketSerializable
*/
public class RegisterPacketsEvent extends Event
{
public final List<IPacket> packets = new ArrayList<>();
}

View file

@ -1,9 +1,12 @@
package dev.zontreck.libzontreck.networking;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.events.RegisterPacketsEvent;
import dev.zontreck.libzontreck.networking.packets.ChestGUIOpenC2S;
import dev.zontreck.libzontreck.networking.packets.IPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
@ -15,7 +18,11 @@ import net.minecraftforge.network.simple.SimpleChannel;
public class ModMessages {
private static SimpleChannel INSTANCE;
private static int PACKET_ID=0;
private static int id()
/**
* INTERNAL USE ONLY. DO NOT USE THIS, IF YOU ARE NOT LIBZONTRECK!!!!!!
* @return
*/
public static int id()
{
return PACKET_ID++;
}
@ -26,9 +33,17 @@ public class ModMessages {
.clientAcceptedVersions(s->true)
.serverAcceptedVersions(s->true)
.simpleChannel();
RegisterPacketsEvent event = new RegisterPacketsEvent();
MinecraftForge.EVENT_BUS.post(event);
INSTANCE=net;
for(IPacket packet : event.packets)
{
packet.register(net);
}
net.messageBuilder(ChestGUIOpenC2S.class, id(), NetworkDirection.PLAY_TO_SERVER)
.decoder(ChestGUIOpenC2S::new)
.encoder(ChestGUIOpenC2S::toBytes)

View file

@ -0,0 +1,35 @@
package dev.zontreck.libzontreck.networking.packets;
import java.util.function.Supplier;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.simple.SimpleChannel;
public interface IPacket {
void deserialize(CompoundTag data);
void serialize(CompoundTag data);
void toBytes(FriendlyByteBuf buf);
boolean handle(Supplier<NetworkEvent.Context> supplier);
/**
* @return The network direction of the packet
*/
NetworkDirection getDirection();
/**
* EXAMPLE:
* chan.messageBuilder(S2CPlaySoundPacket.class, ModMessages.id(), getDirection())
* .encoder(S2CPlaySoundPacket::toBytes)
* .decoder(S2CPlaySoundPacket::new)
* .consumer(S2CPlaySoundPacket::handle)
* .add();
* @param chan
*/
void register(SimpleChannel chan);
}

View file

@ -0,0 +1,71 @@
package dev.zontreck.libzontreck.networking.packets;
import java.util.function.Supplier;
import dev.zontreck.libzontreck.networking.ModMessages;
import dev.zontreck.libzontreck.util.BinUtil;
import dev.zontreck.libzontreck.util.ServerUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.network.simple.SimpleChannel;
public class S2CPlaySoundPacket implements IPacket
{
public ResourceLocation sound;
public S2CPlaySoundPacket(FriendlyByteBuf buf) {
sound = buf.readResourceLocation();
}
public S2CPlaySoundPacket(ResourceLocation loc) {
sound=loc;
}
@Override
public void deserialize(CompoundTag data) {
// Deserializes the play sound packet
throw new UnsupportedOperationException("This operation is not supported in the play sound packet!");
}
@Override
public void serialize(CompoundTag data) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'serialize'");
}
@Override
public void toBytes(FriendlyByteBuf buf) {
buf.writeResourceLocation(sound);
}
@Override
public boolean handle(Supplier<Context> supplier) {
NetworkEvent.Context ctx=supplier.get();
ctx.enqueueWork(()->{
// We are on the client now, enqueue the sound!
SoundEvent ev = new SoundEvent(sound);
// Play sound for player!
Minecraft.getInstance().player.playSound(ev, 1, BinUtil.getARandomInstance().nextFloat(0, 1));
});
return true;
}
@Override
public NetworkDirection getDirection() {
return NetworkDirection.PLAY_TO_CLIENT;
}
@Override
public void register(SimpleChannel chan) {
ServerUtilities.registerPacket(chan, S2CPlaySoundPacket.class, this, S2CPlaySoundPacket::new);
}
}

View file

@ -0,0 +1,28 @@
package dev.zontreck.libzontreck.permissions;
import net.minecraft.nbt.CompoundTag;
public class Permission {
public String permName;
boolean isGroup(){
return false;
}
public Permission(String name){
this.permName = name;
}
public CompoundTag save()
{
CompoundTag tag=new CompoundTag();
tag.putString("name", permName);
return tag;
}
public Permission(CompoundTag tag)
{
this(tag.getString("name"));
}
}

View file

@ -0,0 +1,72 @@
package dev.zontreck.libzontreck.permissions;
import com.google.common.collect.Lists;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.util.FileTreeDatastore;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.Tag;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class PermissionStorage extends FileTreeDatastore
{
public static final Path BASE = LibZontreck.BASE_CONFIG.resolve(
"permissions.nbt");
private static final List<PermissionUser> permissionUsers;
public static List<PermissionUser> getListOfUsers()
{
return Lists.newArrayList(permissionUsers);
}
static{
// Load the permission storage!
List<PermissionUser> perms = new ArrayList<>();
try {
CompoundTag file = NbtIo.read(BASE.toFile());
ListTag lst = file.getList("perms", Tag.TAG_COMPOUND);
for (Tag tag :
lst) {
CompoundTag ct = (CompoundTag) tag;
perms.add(new PermissionUser(ct));
}
} catch (IOException e) {
}
permissionUsers=perms;
}
public PermissionUser getUser(UUID user)
{
try{
return permissionUsers.stream()
.filter(C->C.player.equals(user))
.collect(Collectors.toList()).get(0);
}catch(Exception e)
{
return new PermissionUser(user);
}
}
public static void save() throws IOException {
CompoundTag ct = new CompoundTag();
ListTag tag = new ListTag();
for (PermissionUser user :
permissionUsers) {
tag.add(user.save());
}
ct.put("perms", tag);
NbtIo.write(ct, BASE.toFile());
}
}

View file

@ -0,0 +1,61 @@
package dev.zontreck.libzontreck.permissions;
import com.google.common.collect.Lists;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.player.Player;
import java.util.List;
import java.util.UUID;
public class PermissionUser {
public UUID player;
public List<Permission> permissions = Lists.newArrayList();
public PermissionUser(Player player)
{
this(player.getUUID());
}
public PermissionUser(UUID ID)
{
player=ID;
}
public CompoundTag save()
{
CompoundTag tag = new CompoundTag();
tag.putUUID("id", player);
ListTag perms = new ListTag();
for (Permission perm :
permissions) {
perms.add(perm.save());
}
tag.put("perms", perms);
return tag;
}
public PermissionUser(CompoundTag tag)
{
player = tag.getUUID("id");
ListTag lst = tag.getList("perms", Tag.TAG_COMPOUND);
for (Tag t :
lst) {
CompoundTag ct = (CompoundTag) t;
permissions.add(new Permission(ct));
}
}
public boolean hasPermission(String node)
{
return permissions.stream()
.filter(CPRED-> CPRED.permName.equals(node))
.count()>0;
}
}

View file

@ -4,14 +4,12 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileAttribute;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.events.ProfileCreatedEvent;
import dev.zontreck.libzontreck.events.ProfileSavingEvent;
import dev.zontreck.libzontreck.events.ProfileUnloadedEvent;
import dev.zontreck.libzontreck.events.ProfileUnloadingEvent;
import dev.zontreck.libzontreck.util.FileTreeDatastore;
import dev.zontreck.libzontreck.util.ServerUtilities;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
@ -30,8 +28,8 @@ public class Profile {
public int available_vaults;
public int deaths;
public ServerPlayer player;
private File accessor;
private CompoundTag miscData;
public static final Path BASE;
static{
@ -48,7 +46,7 @@ public class Profile {
}
}
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, int deathCount, ServerPlayer player) {
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, int deathCount, ServerPlayer player, CompoundTag misc) {
this.username = username;
this.prefix = prefix;
this.nickname = nickname;
@ -60,6 +58,7 @@ public class Profile {
this.available_vaults=vaults;
this.deaths=deathCount;
this.player=player;
miscData = misc;
this.accessor = vaultFile;
@ -102,7 +101,7 @@ public class Profile {
private static Profile load(CompoundTag tag, File accessor, ServerPlayer player)
{
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, tag.getInt("deaths"), player);
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, tag.getInt("deaths"), player, tag.getCompound("misc"));
}
private static void generateNewProfile(ServerPlayer player)
@ -113,7 +112,7 @@ public class Profile {
{
// Load profile data
File ace = userProfile.resolve("profile.nbt").toFile();
Profile template = new Profile(player.getName().getString(), "Member", player.getDisplayName().getString(), ChatColor.GREEN, player.getStringUUID(), ChatColor.AQUA, ChatColor.WHITE, false, 0, ace, 0, player);
Profile template = new Profile(player.getName().getString(), "Member", player.getDisplayName().getString(), ChatColor.GREEN, player.getStringUUID(), ChatColor.AQUA, ChatColor.WHITE, false, 0, ace, 0, player, new CompoundTag());
template.commit();
@ -173,6 +172,9 @@ public class Profile {
serial.putBoolean("flying", flying);
serial.putInt("vaults", available_vaults);
serial.putInt("deaths", deaths);
ProfileSavingEvent event = new ProfileSavingEvent(this, miscData);
MinecraftForge.EVENT_BUS.post(event);
serial.put("misc", event.tag);

View file

@ -1,14 +1,10 @@
package dev.zontreck.libzontreck.types;
import dev.zontreck.libzontreck.LibZontreck;
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<MenuType<?>> REGISTER = DeferredRegister.create(ForgeRegistries.CONTAINERS, LibZontreck.MOD_ID);

View file

@ -1,5 +1,8 @@
package dev.zontreck.libzontreck.util;
import java.time.Instant;
import java.util.Random;
public class BinUtil {
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
@ -17,4 +20,12 @@ public class BinUtil {
}
return new String(hexChars);
}
/**
* @return A random instance backed by the time including milliseconds as the seed.
*/
public static Random getARandomInstance()
{
return new Random(Instant.now().toEpochMilli());
}
}

View file

@ -1,17 +1,16 @@
package dev.zontreck.libzontreck.util;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import dev.zontreck.libzontreck.LibZontreck;
public class DelayedExecutorService {
private static int COUNT = 0;
private static AtomicInteger COUNT = new AtomicInteger(0);
private static final DelayedExecutorService inst;
private static final Timer repeater;
static{
@ -46,6 +45,7 @@ public class DelayedExecutorService {
public void schedule(final Runnable run, int seconds)
{
if(!LibZontreck.ALIVE)return;
//long unix = Instant.now().getEpochSecond()+ (seconds);
TimerTask task = new TimerTask() {
@Override
@ -88,7 +88,6 @@ public class DelayedExecutorService {
public static int getNext()
{
COUNT++;
return COUNT;
return COUNT.getAndIncrement();
}
}

View file

@ -0,0 +1,27 @@
package dev.zontreck.libzontreck.util;
import dev.zontreck.libzontreck.permissions.PermissionStorage;
import dev.zontreck.libzontreck.permissions.PermissionUser;
import java.io.IOException;
import java.util.List;
public class PermissionsWatchdog implements Runnable
{
public List<PermissionUser> perms;
@Override
public void run() {
if(!perms.equals(PermissionStorage.getListOfUsers()))
{
try {
PermissionStorage.save();
} catch (IOException e) {
throw new RuntimeException(e);
}
perms = PermissionStorage.getListOfUsers();
}
DelayedExecutorService.getInstance().schedule(this, 10);
}
}

View file

@ -1,14 +1,77 @@
package dev.zontreck.libzontreck.util;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Supplier;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.networking.ModMessages;
import dev.zontreck.libzontreck.networking.packets.IPacket;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.simple.SimpleChannel;
public class ServerUtilities
{
/**
* This function only exists on the server
* @param id Player ID
* @return The server player associated with the ID
*/
public static ServerPlayer getPlayerByID(String id)
{
return LibZontreck.THE_SERVER.getPlayerList().getPlayer(UUID.fromString(id));
}
/**
* Handles the registration of packets
* @param <X>
* @param channel
* @param type
* @param inst
* @param decoder
*/
public static <X extends IPacket> void registerPacket(SimpleChannel channel, Class<X> type, X inst, Function<FriendlyByteBuf, X> decoder)
{
IPacket packet = (IPacket) inst;
channel.messageBuilder(type, ModMessages.id(), packet.getDirection())
.decoder(decoder)
.encoder(X::toBytes)
.consumer(X::handle)
.add();
}
/**
* Handles the tedious and repetitive actions in the handle packet segment of code
* @param context
* @param run
* @return
*/
public static boolean handlePacket(Supplier<NetworkEvent.Context> context, Runnable run)
{
NetworkEvent.Context ctx = context.get();
ctx.enqueueWork(run);
return true;
}
/**
* Checks if the mod is running on the server
* @return True if the mod is on the server
*/
public static boolean isServer()
{
return (LibZontreck.CURRENT_SIDE == LogicalSide.SERVER);
}
/**
* Checks if the mod is running on the client
* @return True if the mod is on the client
*/
public static boolean isClient()
{
return !isServer();
}
}

View file

@ -1,16 +1,11 @@
package dev.zontreck.libzontreck.util.heads;
import java.util.Properties;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.items.lore.LoreContainer;
import dev.zontreck.libzontreck.items.lore.LoreEntry;
import dev.zontreck.libzontreck.util.heads.HeadCache.HeadCacheItem;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.world.item.BookItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.WrittenBookItem;
import net.minecraft.world.scores.Team;
public class CreditsEntry {
public HeadCacheItem player;

View file

@ -9,16 +9,13 @@ import java.util.UUID;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.util.ChatHelpers;
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;
import net.minecraftforge.items.ItemStackHandler;
public class HeadCache
{

View file

@ -2,7 +2,6 @@ package dev.zontreck.libzontreck.util.heads;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
import java.util.UUID;
import com.google.gson.Gson;

View file

@ -1,7 +1,5 @@
package dev.zontreck.libzontreck.util.heads;
import java.util.UUID;
public class PlayerInfo {
public String name;
public String id;