This commit is contained in:
kirillsaint 2023-07-02 00:29:36 +06:00
parent a6d5310e96
commit 1a5567b15b
21 changed files with 542 additions and 3 deletions

View File

@ -34,6 +34,7 @@ minecraft {
runDir = "run"
mappings = "stable_22"
makeObfSourceJar = false
accessTransformer(rootProject.file("src/main/resources/silentclient_at.cfg"))
}
repositories {

View File

@ -0,0 +1,46 @@
package net.silentclient.client.hooks;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import net.minecraft.client.resources.ResourcePackRepository;
import net.silentclient.client.mixin.accessors.ResourcePackRepositoryAccessor;
public class ResourcePackRepositoryHook {
public static void updateRepositoryEntriesAll(ResourcePackRepository repository) {
ResourcePackRepositoryAccessor accessor = (ResourcePackRepositoryAccessor) repository;
final Map<Integer, ResourcePackRepository.Entry> all = new HashMap<>();
for (ResourcePackRepository.Entry entry : repository.getRepositoryEntriesAll()) {
all.put(entry.hashCode(), entry);
}
final Set<ResourcePackRepository.Entry> newSet = new LinkedHashSet<>();
for (File file : accessor.invokeGetResourcePackFiles()) {
final ResourcePackRepository.Entry entry = repository.new Entry(file);
final int entryHash = entry.hashCode();
if (!all.containsKey(entryHash)) {
try {
entry.updateResourcePack();
newSet.add(entry);
} catch (Exception ignored) {
newSet.remove(entry);
}
} else {
newSet.add(all.get(entryHash));
}
}
for (ResourcePackRepository.Entry entry : all.values()) {
if (!newSet.contains(entry)) {
entry.closeResourcePack();
}
}
accessor.setRepositoryEntriesAll(new ArrayList<>(newSet));
}
}

View File

@ -0,0 +1,18 @@
package net.silentclient.client.mixin.accessors;
import net.minecraft.client.resources.ResourcePackRepository;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.io.File;
import java.util.List;
@Mixin(ResourcePackRepository.class)
public interface ResourcePackRepositoryAccessor {
@Invoker
List<File> invokeGetResourcePackFiles();
@Accessor
void setRepositoryEntriesAll(List<ResourcePackRepository.Entry> entries);
}

View File

@ -0,0 +1,5 @@
package net.silentclient.client.mixin.ducks;
public interface VisGraphExt {
void silent$setLimitScan(boolean limitScan);
}

View File

@ -0,0 +1,131 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Vec3i;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
@Mixin(BlockPos.class)
public abstract class BlockPosMixin extends Vec3i {
public BlockPosMixin(int xIn, int yIn, int zIn) {
super(xIn, yIn, zIn);
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos up() {
return new BlockPos(this.getX(), this.getY() + 1, this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos up(int offset) {
return offset == 0 ? (BlockPos) (Object) this : new BlockPos(this.getX(), this.getY() + offset, this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos down() {
return new BlockPos(this.getX(), this.getY() - 1, this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos down(int offset) {
return offset == 0 ? (BlockPos) (Object) this : new BlockPos(this.getX(), this.getY() - offset, this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos north() {
return new BlockPos(this.getX(), this.getY(), this.getZ() - 1);
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos north(int offset) {
return offset == 0 ? (BlockPos) (Object) this : new BlockPos(this.getX(), this.getY(), this.getZ() - offset);
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos south() {
return new BlockPos(this.getX(), this.getY(), this.getZ() + 1);
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos south(int offset) {
return offset == 0 ? (BlockPos) (Object) this : new BlockPos(this.getX(), this.getY(), this.getZ() + offset);
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos west() {
return new BlockPos(this.getX() - 1, this.getY(), this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos west(int offset) {
return offset == 0 ? (BlockPos) (Object) this : new BlockPos(this.getX() - offset, this.getY(), this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos east() {
return new BlockPos(this.getX() + 1, this.getY(), this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos east(int offset) {
return offset == 0 ? (BlockPos) (Object) this : new BlockPos(this.getX() + offset, this.getY(), this.getZ());
}
/**
* @author asbyth
* @reason Inline method to reduce allocations
*/
@Overwrite
public BlockPos offset(EnumFacing direction) {
return new BlockPos(this.getX() + direction.getFrontOffsetX(), this.getY() + direction.getFrontOffsetY(), this.getZ() + direction.getFrontOffsetZ());
}
}

View File

@ -1,15 +1,38 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.BlockPos;
import net.minecraft.world.chunk.Chunk;
import net.silentclient.client.Client;
import net.silentclient.client.hooks.ChunkHook;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Chunk.class)
public class ChunkMixin {
@ModifyArg(
method = "setBlockState",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/Chunk;relightBlock(III)V", ordinal = 0),
index = 1
)
private int silent$subtractOneFromY(int y) {
return y - 1;
}
/**
* @author LlamaLad7
* @reason Optimization
*/
@Overwrite
public IBlockState getBlockState(BlockPos pos) {
return ChunkHook.getBlockState((Chunk) (Object) this, pos);
}
@Inject(method = {"getLightFor", "getLightSubtracted"}, at = @At("HEAD"), cancellable = true)
private void patchFullbright(CallbackInfoReturnable<Integer> cir) {
if (Client.getInstance().getModInstances().getFullBrightMod().isEnabled()) {

View File

@ -0,0 +1,46 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.entity.Entity;
import net.minecraft.event.HoverEvent;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.IChatComponent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Entity.class)
public abstract class EntityMixin {
@Shadow protected abstract HoverEvent getHoverEvent();
private long silent$displayNameCachedAt;
private IChatComponent silent$cachedDisplayName;
@Inject(method = "getDisplayName", at = @At("RETURN"))
protected void silent$cacheDisplayName(CallbackInfoReturnable<IChatComponent> cir) {
silent$cachedDisplayName = cir.getReturnValue();
silent$displayNameCachedAt = System.currentTimeMillis();
}
@Inject(method = "getDisplayName", at = @At("HEAD"), cancellable = true)
protected void silent$returnCachedDisplayName(CallbackInfoReturnable<IChatComponent> cir) {
if (System.currentTimeMillis() - silent$displayNameCachedAt < 50L) {
cir.setReturnValue(silent$cachedDisplayName);
}
}
@Redirect(method = "getDisplayName", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getHoverEvent()Lnet/minecraft/event/HoverEvent;"))
private HoverEvent silent$doNotGetHoverEvent(Entity instance) {
// When is a non-player entity going to be sending a chat message?
return null;
}
@Redirect(method = "getDisplayName", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ChatStyle;setChatHoverEvent(Lnet/minecraft/event/HoverEvent;)Lnet/minecraft/util/ChatStyle;"))
private ChatStyle silent$doNotSetHoverEvent(ChatStyle instance, HoverEvent event) {
// Let's not set it to null...
return null;
}
}

View File

@ -0,0 +1,15 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(EntityOtherPlayerMP.class)
public class EntityOtherPlayerMPMixin {
@Inject(method = "onLivingUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityOtherPlayerMP;updateArmSwingProgress()V", shift = At.Shift.AFTER), cancellable = true)
private void silent$removeUselessAnimations(CallbackInfo ci) {
ci.cancel();
}
}

View File

@ -1,15 +1,46 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.event.HoverEvent;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.IChatComponent;
import net.silentclient.client.event.impl.EntityAttackEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(EntityPlayer.class)
public class EntityPlayerMixin {
public abstract class EntityPlayerMixin extends EntityMixin {
@Inject(method = "getDisplayName", at = @At("RETURN"))
private void silent$cachePlayerDisplayName(CallbackInfoReturnable<IChatComponent> cir) {
super.silent$cacheDisplayName(cir);
}
@Inject(method = "getDisplayName", at = @At("HEAD"), cancellable = true)
private void silent$returnCachedPlayerDisplayName(CallbackInfoReturnable<IChatComponent> cir) {
super.silent$returnCachedDisplayName(cir);
}
@Redirect(method = "getDisplayName", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayer;getHoverEvent()Lnet/minecraft/event/HoverEvent;"))
private HoverEvent silent$onlyGetHoverEventInSinglePlayer(EntityPlayer instance) {
// Only needed in single player
return Minecraft.getMinecraft().isIntegratedServerRunning()
? ((EntityPlayerMixin) (Object) instance).getHoverEvent()
: null;
}
@Redirect(method = "getDisplayName", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ChatStyle;setChatHoverEvent(Lnet/minecraft/event/HoverEvent;)Lnet/minecraft/util/ChatStyle;"))
private ChatStyle silent$onlySetHoverEventInSinglePlayer(ChatStyle instance, HoverEvent event) {
return Minecraft.getMinecraft().isIntegratedServerRunning()
? instance.setChatHoverEvent(event)
: null;
}
@Inject(method = "attackTargetEntityWithCurrentItem", at = @At("HEAD"))
public void callEntityAttackEvent(Entity targetEntity, CallbackInfo ci) {
if (targetEntity.canAttackWithItem()) {

View File

@ -232,4 +232,11 @@ public abstract class EntityRendererMixin implements EntityRendererExt {
public void renderCachedHUD(GuiIngame guiIngame, float partialTicks) {
HUDCaching.renderCachedHud((EntityRenderer) (Object) this, guiIngame, partialTicks);
}
//#if MC==10809
@Inject(method = "renderStreamIndicator", at = @At("HEAD"), cancellable = true)
private void silent$cancelStreamIndicator(CallbackInfo ci) {
ci.cancel();
}
//#endif
}

View File

@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(FontRenderer.class)
@Mixin(value = FontRenderer.class, priority = 1100)
public class FontRendererMixin {
@ModifyVariable(method = "renderString", at = @At("HEAD"), ordinal = 0)
public String renderString(String text) {

View File

@ -0,0 +1,22 @@
package net.silentclient.client.mixin.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
@Mixin(targets = "net.minecraft.world.GameRules$Value")
public class GameRulesValueMixin {
@Shadow
private String valueString;
@Inject(method = "setValue(Ljava/lang/String;)V", at = @At("HEAD"), cancellable = true)
private void silentr$cancelIfUnchanged(String value, CallbackInfo ci) {
if (Objects.equals(this.valueString, value)) {
ci.cancel();
}
}
}

View File

@ -2,11 +2,14 @@ package net.silentclient.client.mixin.mixins;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.resources.data.IMetadataSerializer;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.client.stream.IStream;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.ResourceLocation;
@ -95,6 +98,10 @@ public abstract class MinecraftMixin {
@Shadow public int displayHeight;
@Shadow public WorldClient theWorld;
@Shadow public EntityRenderer entityRenderer;
@Inject(method = "displayGuiScreen", at = @At("RETURN"), cancellable = true)
public void displayGuiScreenInject(GuiScreen guiScreenIn, CallbackInfo ci) {
if(Client.backgroundPanorama == null) {
@ -192,4 +199,37 @@ public abstract class MinecraftMixin {
ci.cancel();
}
}
@Inject(method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V", at = @At("HEAD"))
private void clearLoadedMaps(WorldClient worldClientIn, String loadingMessage, CallbackInfo ci) {
if (worldClientIn != this.theWorld) {
this.entityRenderer.getMapItemRenderer().clearLoadedMaps();
}
}
@Redirect(
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
at = @At(value = "INVOKE", target = "Ljava/lang/System;gc()V")
)
private void optimizedWorldSwapping() {
System.gc();
}
//#if MC==10809
@Redirect(
method = "runGameLoop",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/stream/IStream;func_152935_j()V")
)
private void skipTwitchCode1(IStream instance) {
// No-op
}
@Redirect(
method = "runGameLoop",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/stream/IStream;func_152922_k()V")
)
private void skipTwitchCode2(IStream instance) {
// No-op
}
//#endif
}

View File

@ -0,0 +1,20 @@
package net.silentclient.client.mixin.mixins;
import io.netty.buffer.ByteBuf;
import net.minecraft.server.MinecraftServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(MinecraftServer.class)
public class MinecraftServerMixin {
@ModifyVariable(
method = "addFaviconToStatusResponse",
at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerStatusResponse;setFavicon(Ljava/lang/String;)V", shift = At.Shift.AFTER),
ordinal = 1
)
private ByteBuf patcher$releaseByteBuf(ByteBuf buf1) {
buf1.release();
return buf1;
}
}

View File

@ -0,0 +1,34 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.nbt.NBTTagString;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(NBTTagString.class)
public class NBTTagStringMixin {
@Shadow private String data;
@Unique private String silent$dataCache;
@Inject(method = "read", at = @At("HEAD"))
private void silent$emptyDataCache(CallbackInfo ci) {
this.silent$dataCache = null;
}
/**
* @author asbyth
* @reason Utilize data cache
*/
@Overwrite
public String toString() {
if (this.silent$dataCache == null) {
this.silent$dataCache = "\"" + this.data.replace("\"", "\\\"") + "\"";
}
return this.silent$dataCache;
}
}

View File

@ -0,0 +1,21 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.world.IBlockAccess;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.world.pathfinder.NodeProcessor;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(NodeProcessor.class)
public class NodeProcessorMixin {
//#if MC==10809
@Shadow protected IBlockAccess blockaccess;
@Inject(method = "postProcess", at = @At("HEAD"))
private void patcher$cleanupBlockAccess(CallbackInfo ci) {
this.blockaccess = null;
}
//#endif
}

View File

@ -1,16 +1,19 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.chunk.VisGraph;
import net.minecraft.client.renderer.culling.ICamera;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MovingObjectPosition;
import net.silentclient.client.event.impl.RenderTickEvent;
import net.silentclient.client.mixin.ducks.VisGraphExt;
import net.silentclient.client.mods.render.BlockOverlayMod;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(RenderGlobal.class)
@ -29,4 +32,10 @@ public class RenderGlobalMixin {
{
BlockOverlayMod.drawSelectionBox(player, movingObjectPositionIn, p_72731_3_, partialTicks);
}
@ModifyVariable(method = "getVisibleFacings", name = "visgraph", at = @At(value = "STORE", ordinal = 0))
private VisGraph patcher$setLimitScan(VisGraph visgraph) {
((VisGraphExt) visgraph).silent$setLimitScan(true);
return visgraph;
}
}

View File

@ -0,0 +1,17 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.client.resources.ResourcePackRepository;
import net.silentclient.client.hooks.ResourcePackRepositoryHook;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ResourcePackRepository.class)
public class ResourcePackRepositoryMixin {
@Inject(method = "updateRepositoryEntriesAll", at = @At("HEAD"), cancellable = true)
private void patcher$searchUsingSet(CallbackInfo ci) {
ResourcePackRepositoryHook.updateRepositoryEntriesAll((ResourcePackRepository) (Object) this);
ci.cancel();
}
}

View File

@ -0,0 +1,32 @@
package net.silentclient.client.mixin.mixins;
import net.minecraft.client.renderer.chunk.VisGraph;
import net.minecraft.util.EnumFacing;
import net.silentclient.client.mixin.ducks.VisGraphExt;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.Queue;
import java.util.Set;
@Mixin(VisGraph.class)
public class VisGraphMixin implements VisGraphExt {
@Unique
private boolean silent$limitScan;
@Inject(method = "func_178604_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/chunk/VisGraph;func_178610_a(ILjava/util/Set;)V", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILSOFT, cancellable = true)
private void silent$checkLimitScan(int enumfacing, CallbackInfoReturnable<Set<EnumFacing>> cir, Set<EnumFacing> set, Queue<Integer> queue, int i) {
if (this.silent$limitScan && set.size() > 1) {
cir.setReturnValue(set);
}
}
@Override
public void silent$setLimitScan(boolean limitScan) {
this.silent$limitScan = limitScan;
}
}

View File

@ -63,6 +63,14 @@
"mixins.LayerArrowMixin",
"mixins.BlockLiquidMixin",
"mixins.TileEntitySkullRendererMixin",
"accessors.EntityArrowAccessor"
"accessors.EntityArrowAccessor",
"mixins.BlockPosMixin",
"mixins.EntityMixin",
"mixins.EntityOtherPlayerMPMixin",
"mixins.GameRulesValueMixin",
"mixins.MinecraftServerMixin",
"mixins.NBTTagStringMixin",
"mixins.NodeProcessorMixin",
"mixins.VisGraphMixin"
]
}

View File

@ -0,0 +1,13 @@
# GlStateManager
public net.minecraft.client.renderer.GlStateManager$Color
public net.minecraft.client.renderer.GlStateManager$TextureState
# ResourcePackRepository
public net.minecraft.client.resources.ResourcePackRepository$Entry <init>(Lnet/minecraft/client/resources/ResourcePackRepository;Ljava/io/File;)V # constructor
# TileEntityBannerRenderer
public net.minecraft.client.renderer.tileentity.TileEntityBannerRenderer$TimedBannerTexture
public net.minecraft.client.renderer.tileentity.TileEntityBannerRenderer$TimedBannerTexture <init>()V # constructor
# BlockRedstoneTorch
public net.minecraft.block.BlockRedstoneTorch$Toggle