mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +00:00 
			
		
		
		
	Fix: register missing data pack reload listener.
Fixes "ComputerCraft may be installed incorrectly" and "File not found" errors that sometimes happened after switching single player worlds or running /reload.
This commit is contained in:
		| @@ -33,6 +33,7 @@ import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; | |||||||
| import net.fabricmc.loader.api.FabricLoader; | import net.fabricmc.loader.api.FabricLoader; | ||||||
| import net.minecraft.block.entity.BlockEntity; | import net.minecraft.block.entity.BlockEntity; | ||||||
| import net.minecraft.resource.ReloadableResourceManager; | import net.minecraft.resource.ReloadableResourceManager; | ||||||
|  | import net.minecraft.resource.ResourceManager; | ||||||
| import net.minecraft.server.MinecraftServer; | import net.minecraft.server.MinecraftServer; | ||||||
| import net.minecraft.util.Identifier; | import net.minecraft.util.Identifier; | ||||||
| import net.minecraft.util.math.BlockPos; | import net.minecraft.util.math.BlockPos; | ||||||
| @@ -116,7 +117,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI | |||||||
|         MinecraftServer server = GameInstanceUtils.getServer(); |         MinecraftServer server = GameInstanceUtils.getServer(); | ||||||
|         if( server != null ) |         if( server != null ) | ||||||
|         { |         { | ||||||
|             ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess) server).getServerResourceManager().getResourceManager(); |             ResourceManager manager = ((MinecraftServerAccess) server).getServerResourceManager().getResourceManager(); | ||||||
|             ResourceMount mount = ResourceMount.get( domain, subPath, manager ); |             ResourceMount mount = ResourceMount.get( domain, subPath, manager ); | ||||||
|             return mount.exists( "" ) ? mount : null; |             return mount.exists( "" ) ? mount : null; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -7,16 +7,15 @@ package dan200.computercraft.core.filesystem; | |||||||
|  |  | ||||||
| import com.google.common.cache.Cache; | import com.google.common.cache.Cache; | ||||||
| import com.google.common.cache.CacheBuilder; | import com.google.common.cache.CacheBuilder; | ||||||
| import com.google.common.collect.MapMaker; |  | ||||||
| import com.google.common.io.ByteStreams; | import com.google.common.io.ByteStreams; | ||||||
| import dan200.computercraft.ComputerCraft; | import dan200.computercraft.ComputerCraft; | ||||||
| import dan200.computercraft.api.filesystem.IMount; | import dan200.computercraft.api.filesystem.IMount; | ||||||
| import dan200.computercraft.core.apis.handles.ArrayByteChannel; | import dan200.computercraft.core.apis.handles.ArrayByteChannel; | ||||||
| import dan200.computercraft.shared.util.IoUtil; | import dan200.computercraft.shared.util.IoUtil; | ||||||
| import net.minecraft.resource.ReloadableResourceManager; | import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; | ||||||
|  | import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener; | ||||||
| import net.minecraft.resource.Resource; | import net.minecraft.resource.Resource; | ||||||
| import net.minecraft.resource.ResourceManager; | import net.minecraft.resource.ResourceManager; | ||||||
| import net.minecraft.resource.ResourceReloadListener; |  | ||||||
| import net.minecraft.util.Identifier; | import net.minecraft.util.Identifier; | ||||||
| import net.minecraft.util.InvalidIdentifierException; | import net.minecraft.util.InvalidIdentifierException; | ||||||
| import net.minecraft.util.profiler.Profiler; | import net.minecraft.util.profiler.Profiler; | ||||||
| @@ -28,7 +27,9 @@ import java.io.IOException; | |||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.nio.channels.Channels; | import java.nio.channels.Channels; | ||||||
| import java.nio.channels.ReadableByteChannel; | import java.nio.channels.ReadableByteChannel; | ||||||
| import java.util.*; | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
| import java.util.concurrent.CompletableFuture; | import java.util.concurrent.CompletableFuture; | ||||||
| import java.util.concurrent.Executor; | import java.util.concurrent.Executor; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
| @@ -59,50 +60,37 @@ public final class ResourceMount implements IMount | |||||||
|         .<FileEntry, byte[]>weigher( ( k, v ) -> v.length ) |         .<FileEntry, byte[]>weigher( ( k, v ) -> v.length ) | ||||||
|         .build(); |         .build(); | ||||||
|  |  | ||||||
|     private static final MapMaker CACHE_TEMPLATE = new MapMaker().weakValues().concurrencyLevel( 1 ); |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Maintain a cache of currently loaded resource mounts. This cache is invalidated when currentManager changes. |      * Maintain a cache of currently loaded resource mounts. This cache is invalidated when currentManager changes. | ||||||
|      */ |      */ | ||||||
|     private static final Map<ReloadableResourceManager, Map<Identifier, ResourceMount>> MOUNT_CACHE = new WeakHashMap<>( 2 ); |     private static final Map<Identifier, ResourceMount> MOUNT_CACHE = new HashMap<>( 2 ); | ||||||
|  |  | ||||||
|     private final String namespace; |     private final String namespace; | ||||||
|     private final String subPath; |     private final String subPath; | ||||||
|     private final ReloadableResourceManager manager; |     private ResourceManager manager; | ||||||
|  |  | ||||||
|     @Nullable |     @Nullable | ||||||
|     private FileEntry root; |     private FileEntry root; | ||||||
|  |  | ||||||
|     public static ResourceMount get( String namespace, String subPath, ReloadableResourceManager manager ) |     public static ResourceMount get( String namespace, String subPath, ResourceManager manager ) | ||||||
|     { |     { | ||||||
|         Map<Identifier, ResourceMount> cache; |         Identifier path = new Identifier( namespace, subPath ); | ||||||
|  |  | ||||||
|         synchronized( MOUNT_CACHE ) |         synchronized( MOUNT_CACHE ) | ||||||
|         { |         { | ||||||
|             cache = MOUNT_CACHE.get( manager ); |             ResourceMount mount = MOUNT_CACHE.get( path ); | ||||||
|             if( cache == null ) MOUNT_CACHE.put( manager, cache = CACHE_TEMPLATE.makeMap() ); |             if( mount == null ) MOUNT_CACHE.put( path, mount = new ResourceMount( namespace, subPath, manager ) ); | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Identifier path = new Identifier( namespace, subPath ); |  | ||||||
|         synchronized( cache ) |  | ||||||
|         { |  | ||||||
|             ResourceMount mount = cache.get( path ); |  | ||||||
|             if( mount == null ) cache.put( path, mount = new ResourceMount( namespace, subPath, manager ) ); |  | ||||||
|             return mount; |             return mount; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private ResourceMount( String namespace, String subPath, ReloadableResourceManager manager ) |     private ResourceMount( String namespace, String subPath, ResourceManager manager ) | ||||||
|     { |     { | ||||||
|         this.namespace = namespace; |         this.namespace = namespace; | ||||||
|         this.subPath = subPath; |         this.subPath = subPath; | ||||||
|         this.manager = manager; |         load( manager ); | ||||||
|  |  | ||||||
|         Listener.INSTANCE.add( manager, this ); |  | ||||||
|         if( root == null ) load(); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void load() |     private void load( ResourceManager manager ) | ||||||
|     { |     { | ||||||
|         boolean hasAny = false; |         boolean hasAny = false; | ||||||
|         String existingNamespace = null; |         String existingNamespace = null; | ||||||
| @@ -119,6 +107,7 @@ public final class ResourceMount implements IMount | |||||||
|             hasAny = true; |             hasAny = true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         this.manager = manager; | ||||||
|         root = hasAny ? newRoot : null; |         root = hasAny ? newRoot : null; | ||||||
|  |  | ||||||
|         if( !hasAny ) |         if( !hasAny ) | ||||||
| @@ -294,38 +283,37 @@ public final class ResourceMount implements IMount | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * A {@link ResourceReloadListener} which reloads any associated mounts. |      * An {@link IdentifiableResourceReloadListener} which reloads any associated mounts and correctly updates the resource manager they | ||||||
|      * |      * point to. | ||||||
|      * While people should really be keeping a permanent reference to this, some people construct it every |  | ||||||
|      * method call, so let's make this as small as possible. |  | ||||||
|      */ |      */ | ||||||
|     static class Listener implements ResourceReloadListener |     public static final IdentifiableResourceReloadListener RELOAD_LISTENER = new SimpleResourceReloadListener<Void>() | ||||||
|     { |     { | ||||||
|         private static final Listener INSTANCE = new Listener(); |         @Override | ||||||
|  |         public Identifier getFabricId() | ||||||
|         private final Set<ResourceMount> mounts = Collections.newSetFromMap( new WeakHashMap<>() ); |         { | ||||||
|         private final Set<ReloadableResourceManager> managers = Collections.newSetFromMap( new WeakHashMap<>() ); |             return new Identifier( ComputerCraft.MOD_ID, "resource_mount_reload_listener" ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         @Override |         @Override | ||||||
|         public CompletableFuture<Void> reload( Synchronizer synchronizer, ResourceManager manager, Profiler prepareProfiler, Profiler applyProfiler, Executor prepareExecutor, Executor applyExecutor ) |         public CompletableFuture<Void> load( ResourceManager manager, Profiler profiler, Executor executor ) | ||||||
|         { |         { | ||||||
|             return CompletableFuture.runAsync( () -> { |             return CompletableFuture.runAsync( () -> { | ||||||
|                 prepareProfiler.push( "Mount reloading" ); |                 profiler.push( "Reloading ComputerCraft mounts" ); | ||||||
|                 try |                 try | ||||||
|                 { |                 { | ||||||
|                     for( ResourceMount mount : mounts ) mount.load(); |                     for( ResourceMount mount : MOUNT_CACHE.values() ) mount.load( manager ); | ||||||
|                 } |                 } | ||||||
|                 finally |                 finally | ||||||
|                 { |                 { | ||||||
|                     prepareProfiler.pop(); |                     profiler.pop(); | ||||||
|                 } |                 } | ||||||
|             }, prepareExecutor ); |             }, executor ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         synchronized void add( ReloadableResourceManager manager, ResourceMount mount ) |         @Override | ||||||
|  |         public CompletableFuture<Void> apply( Void data, ResourceManager manager, Profiler profiler, Executor executor ) | ||||||
|         { |         { | ||||||
|             if( managers.add( manager ) ) manager.registerListener( this ); |             return CompletableFuture.runAsync( () -> { }, executor ); | ||||||
|             mounts.add( mount ); |  | ||||||
|         } |         } | ||||||
|     } |     }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import dan200.computercraft.api.media.IMedia; | |||||||
| import dan200.computercraft.api.peripheral.IPeripheralTile; | import dan200.computercraft.api.peripheral.IPeripheralTile; | ||||||
| import dan200.computercraft.api.turtle.event.TurtleEvent; | import dan200.computercraft.api.turtle.event.TurtleEvent; | ||||||
| import dan200.computercraft.core.computer.MainThread; | import dan200.computercraft.core.computer.MainThread; | ||||||
|  | import dan200.computercraft.core.filesystem.ResourceMount; | ||||||
| import dan200.computercraft.core.tracking.Tracking; | import dan200.computercraft.core.tracking.Tracking; | ||||||
| import dan200.computercraft.shared.TurtlePermissions; | import dan200.computercraft.shared.TurtlePermissions; | ||||||
| import dan200.computercraft.shared.command.CommandComputerCraft; | import dan200.computercraft.shared.command.CommandComputerCraft; | ||||||
| @@ -33,11 +34,13 @@ import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; | |||||||
| import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents; | import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents; | ||||||
| import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; | import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; | ||||||
| import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; | import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; | ||||||
|  | import net.fabricmc.fabric.api.resource.ResourceManagerHelper; | ||||||
| import net.minecraft.block.entity.BlockEntity; | import net.minecraft.block.entity.BlockEntity; | ||||||
| import net.minecraft.block.entity.CommandBlockBlockEntity; | import net.minecraft.block.entity.CommandBlockBlockEntity; | ||||||
| import net.minecraft.item.Item; | import net.minecraft.item.Item; | ||||||
| import net.minecraft.item.MusicDiscItem; | import net.minecraft.item.MusicDiscItem; | ||||||
| import net.minecraft.loot.condition.LootConditionType; | import net.minecraft.loot.condition.LootConditionType; | ||||||
|  | import net.minecraft.resource.ResourceType; | ||||||
| import net.minecraft.server.MinecraftServer; | import net.minecraft.server.MinecraftServer; | ||||||
| import net.minecraft.util.Identifier; | import net.minecraft.util.Identifier; | ||||||
| import net.minecraft.util.registry.Registry; | import net.minecraft.util.registry.Registry; | ||||||
| @@ -129,6 +132,8 @@ public final class ComputerCraftProxyCommon | |||||||
|         TurtleEvent.EVENT_BUS.register( FurnaceRefuelHandler.INSTANCE ); |         TurtleEvent.EVENT_BUS.register( FurnaceRefuelHandler.INSTANCE ); | ||||||
|         TurtleEvent.EVENT_BUS.register( new TurtlePermissions() ); |         TurtleEvent.EVENT_BUS.register( new TurtlePermissions() ); | ||||||
|         TurtleEvent.EVENT_BUS.register( new SignInspectHandler() ); |         TurtleEvent.EVENT_BUS.register( new SignInspectHandler() ); | ||||||
|  |  | ||||||
|  |         ResourceManagerHelper.get( ResourceType.SERVER_DATA ).registerReloadListener( ResourceMount.RELOAD_LISTENER ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void registerLoot() |     public static void registerLoot() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Toad-Dev
					Toad-Dev