mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-11-04 15:43:00 +00:00 
			
		
		
		
	Add button to view computer's folder
Implementation is a little awkward, as we can't send OPEN_FILE links from the server, so we ensure the client runs a /computercraft open-computer ID command instead. We then intercept this on the client side and use that to open the folder.
This commit is contained in:
		@@ -0,0 +1,58 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of ComputerCraft - http://www.computercraft.info
 | 
			
		||||
 * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
 | 
			
		||||
 * Send enquiries to dratcliffe@gmail.com
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared.command;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import dan200.computercraft.shared.util.IDAssigner;
 | 
			
		||||
import net.minecraft.util.Util;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.client.event.ClientChatEvent;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
import net.minecraftforge.fml.common.Mod;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Basic client-side commands.
 | 
			
		||||
 *
 | 
			
		||||
 * Simply hooks into client chat messages and intercepts matching strings.
 | 
			
		||||
 */
 | 
			
		||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
 | 
			
		||||
public final class ClientCommands
 | 
			
		||||
{
 | 
			
		||||
    public static final String OPEN_COMPUTER = "/computercraft open-computer ";
 | 
			
		||||
 | 
			
		||||
    private ClientCommands()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    public static void onClientSendMessage( ClientChatEvent event )
 | 
			
		||||
    {
 | 
			
		||||
        // Emulate the command on the client side
 | 
			
		||||
        if( event.getMessage().startsWith( OPEN_COMPUTER ) )
 | 
			
		||||
        {
 | 
			
		||||
            event.setCanceled( true );
 | 
			
		||||
 | 
			
		||||
            String idStr = event.getMessage().substring( OPEN_COMPUTER.length() ).trim();
 | 
			
		||||
            int id;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                id = Integer.parseInt( idStr );
 | 
			
		||||
            }
 | 
			
		||||
            catch( NumberFormatException ignore )
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            File file = new File( IDAssigner.getDir(), "computer/" + id );
 | 
			
		||||
            if( !file.isDirectory() ) return;
 | 
			
		||||
 | 
			
		||||
            Util.getPlatform().openFile( file );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -21,6 +21,7 @@ import dan200.computercraft.shared.computer.core.ComputerFamily;
 | 
			
		||||
import dan200.computercraft.shared.computer.core.ServerComputer;
 | 
			
		||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
 | 
			
		||||
import dan200.computercraft.shared.network.container.ViewComputerContainerData;
 | 
			
		||||
import dan200.computercraft.shared.util.IDAssigner;
 | 
			
		||||
import net.minecraft.command.CommandSource;
 | 
			
		||||
import net.minecraft.entity.Entity;
 | 
			
		||||
import net.minecraft.entity.player.PlayerEntity;
 | 
			
		||||
@@ -37,6 +38,7 @@ import net.minecraft.world.World;
 | 
			
		||||
import net.minecraft.world.server.ServerWorld;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.shared.command.CommandUtils.isPlayer;
 | 
			
		||||
@@ -320,6 +322,12 @@ public final class CommandComputerCraft
 | 
			
		||||
                ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( UserLevel.OWNER.test( source ) && isPlayer( source ) )
 | 
			
		||||
        {
 | 
			
		||||
            ITextComponent linkPath = linkStorage( computerId );
 | 
			
		||||
            if( linkPath != null ) out.append( " " ).append( linkPath );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -339,6 +347,18 @@ public final class CommandComputerCraft
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static ITextComponent linkStorage( int id )
 | 
			
		||||
    {
 | 
			
		||||
        File file = new File( IDAssigner.getDir(), "computer/" + id );
 | 
			
		||||
        if( !file.isDirectory() ) return null;
 | 
			
		||||
 | 
			
		||||
        return link(
 | 
			
		||||
            text( "\u270E" ),
 | 
			
		||||
            ClientCommands.OPEN_COMPUTER + id,
 | 
			
		||||
            translate( "commands.computercraft.dump.open_path" )
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private static TrackingContext getTimingContext( CommandSource source )
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of ComputerCraft - http://www.computercraft.info
 | 
			
		||||
 * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
 | 
			
		||||
 * Send enquiries to dratcliffe@gmail.com
 | 
			
		||||
 */
 | 
			
		||||
package dan200.computercraft.shared.command;
 | 
			
		||||
 | 
			
		||||
import com.mojang.brigadier.CommandDispatcher;
 | 
			
		||||
import com.mojang.brigadier.arguments.StringArgumentType;
 | 
			
		||||
import dan200.computercraft.ComputerCraft;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.command.CommandSource;
 | 
			
		||||
import net.minecraft.util.text.ITextComponent;
 | 
			
		||||
import net.minecraft.util.text.StringTextComponent;
 | 
			
		||||
import net.minecraft.util.text.TranslationTextComponent;
 | 
			
		||||
import net.minecraft.util.text.event.ClickEvent;
 | 
			
		||||
import net.minecraft.util.text.event.HoverEvent;
 | 
			
		||||
import net.minecraftforge.api.distmarker.Dist;
 | 
			
		||||
import net.minecraftforge.client.event.ClientChatEvent;
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
 | 
			
		||||
import net.minecraftforge.fml.common.Mod;
 | 
			
		||||
 | 
			
		||||
import static net.minecraft.command.Commands.argument;
 | 
			
		||||
import static net.minecraft.command.Commands.literal;
 | 
			
		||||
 | 
			
		||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
 | 
			
		||||
public final class CommandCopy
 | 
			
		||||
{
 | 
			
		||||
    private static final String PREFIX = "/computercraft copy ";
 | 
			
		||||
 | 
			
		||||
    private CommandCopy()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void register( CommandDispatcher<CommandSource> registry )
 | 
			
		||||
    {
 | 
			
		||||
        registry.register( literal( "computercraft" )
 | 
			
		||||
            .then( literal( "copy" ) )
 | 
			
		||||
            .then( argument( "message", StringArgumentType.greedyString() ) )
 | 
			
		||||
            .executes( context -> {
 | 
			
		||||
                Minecraft.getInstance().keyboardHandler.setClipboard( context.getArgument( "message", String.class ) );
 | 
			
		||||
                return 1;
 | 
			
		||||
            } )
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    public static void onClientSendMessage( ClientChatEvent event )
 | 
			
		||||
    {
 | 
			
		||||
        // Emulate the command on the client side
 | 
			
		||||
        if( event.getMessage().startsWith( PREFIX ) )
 | 
			
		||||
        {
 | 
			
		||||
            Minecraft.getInstance().keyboardHandler.setClipboard( event.getMessage().substring( PREFIX.length() ) );
 | 
			
		||||
            event.setCanceled( true );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ITextComponent createCopyText( String text )
 | 
			
		||||
    {
 | 
			
		||||
        StringTextComponent name = new StringTextComponent( text );
 | 
			
		||||
        name.getStyle()
 | 
			
		||||
            .setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, PREFIX + text ) )
 | 
			
		||||
            .setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslationTextComponent( "gui.computercraft.tooltip.copy" ) ) );
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -57,14 +57,15 @@ public enum UserLevel implements Predicate<CommandSource>
 | 
			
		||||
    {
 | 
			
		||||
        if( this == ANYONE ) return true;
 | 
			
		||||
 | 
			
		||||
        // We *always* allow level 0 stuff, even if the
 | 
			
		||||
        if( this == OWNER || this == OWNER_OP )
 | 
			
		||||
        {
 | 
			
		||||
            MinecraftServer server = source.getServer();
 | 
			
		||||
            Entity sender = source.getEntity();
 | 
			
		||||
 | 
			
		||||
            if( server.isSingleplayer() && sender instanceof PlayerEntity &&
 | 
			
		||||
                ((PlayerEntity) sender).getGameProfile().getName().equalsIgnoreCase( server.getServerModName() ) )
 | 
			
		||||
            {
 | 
			
		||||
            if( this == OWNER || this == OWNER_OP ) return true;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return source.hasPermission( toLevel() );
 | 
			
		||||
 
 | 
			
		||||
@@ -71,11 +71,16 @@ public final class ChatHelpers
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ITextComponent link( ITextComponent component, String command, ITextComponent toolTip )
 | 
			
		||||
    {
 | 
			
		||||
        return link( component, new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ), toolTip );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ITextComponent link( ITextComponent component, ClickEvent click, ITextComponent toolTip )
 | 
			
		||||
    {
 | 
			
		||||
        Style style = component.getStyle();
 | 
			
		||||
 | 
			
		||||
        if( style.getColor() == null ) style.setColor( TextFormatting.YELLOW );
 | 
			
		||||
        style.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ) );
 | 
			
		||||
        style.setClickEvent( click );
 | 
			
		||||
        style.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) );
 | 
			
		||||
 | 
			
		||||
        return component;
 | 
			
		||||
@@ -85,4 +90,13 @@ public final class ChatHelpers
 | 
			
		||||
    {
 | 
			
		||||
        return coloured( text, HEADER );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ITextComponent copy( String text )
 | 
			
		||||
    {
 | 
			
		||||
        StringTextComponent name = new StringTextComponent( text );
 | 
			
		||||
        name.getStyle()
 | 
			
		||||
            .setClickEvent( new ClickEvent( ClickEvent.Action.COPY_TO_CLIPBOARD, text ) )
 | 
			
		||||
            .setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslationTextComponent( "gui.computercraft.tooltip.copy" ) ) );
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ import dan200.computercraft.api.network.wired.IWiredElement;
 | 
			
		||||
import dan200.computercraft.api.network.wired.IWiredNode;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
			
		||||
import dan200.computercraft.shared.Registry;
 | 
			
		||||
import dan200.computercraft.shared.command.CommandCopy;
 | 
			
		||||
import dan200.computercraft.shared.command.text.ChatHelpers;
 | 
			
		||||
import dan200.computercraft.shared.common.TileGeneric;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
 | 
			
		||||
import dan200.computercraft.shared.util.CapabilityUtil;
 | 
			
		||||
@@ -268,12 +268,12 @@ public class TileCable extends TileGeneric
 | 
			
		||||
            if( oldName != null )
 | 
			
		||||
            {
 | 
			
		||||
                player.displayClientMessage( new TranslationTextComponent( "chat.computercraft.wired_modem.peripheral_disconnected",
 | 
			
		||||
                    CommandCopy.createCopyText( oldName ) ), false );
 | 
			
		||||
                    ChatHelpers.copy( oldName ) ), false );
 | 
			
		||||
            }
 | 
			
		||||
            if( newName != null )
 | 
			
		||||
            {
 | 
			
		||||
                player.displayClientMessage( new TranslationTextComponent( "chat.computercraft.wired_modem.peripheral_connected",
 | 
			
		||||
                    CommandCopy.createCopyText( newName ) ), false );
 | 
			
		||||
                    ChatHelpers.copy( newName ) ), false );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ import dan200.computercraft.api.ComputerCraftAPI;
 | 
			
		||||
import dan200.computercraft.api.network.wired.IWiredElement;
 | 
			
		||||
import dan200.computercraft.api.network.wired.IWiredNode;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
			
		||||
import dan200.computercraft.shared.command.CommandCopy;
 | 
			
		||||
import dan200.computercraft.shared.command.text.ChatHelpers;
 | 
			
		||||
import dan200.computercraft.shared.common.TileGeneric;
 | 
			
		||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
 | 
			
		||||
import dan200.computercraft.shared.util.CapabilityUtil;
 | 
			
		||||
@@ -218,7 +218,7 @@ public class TileWiredModemFull extends TileGeneric
 | 
			
		||||
        for( int i = 0; i < names.size(); i++ )
 | 
			
		||||
        {
 | 
			
		||||
            if( i > 0 ) base.append( ", " );
 | 
			
		||||
            base.append( CommandCopy.createCopyText( names.get( i ) ) );
 | 
			
		||||
            base.append( ChatHelpers.copy( names.get( i ) ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        player.displayClientMessage( new TranslationTextComponent( kind, base ), false );
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,7 @@
 | 
			
		||||
    "commands.computercraft.dump.synopsis": "Display the status of computers.",
 | 
			
		||||
    "commands.computercraft.dump.desc": "Display the status of all computers or specific information about one computer. You can specify the computer's instance id (e.g. 123), computer id (e.g #123) or label (e.g. \"@My Computer\").",
 | 
			
		||||
    "commands.computercraft.dump.action": "View more info about this computer",
 | 
			
		||||
    "commands.computercraft.dump.open_path": "View this computer's files",
 | 
			
		||||
    "commands.computercraft.shutdown.synopsis": "Shutdown computers remotely.",
 | 
			
		||||
    "commands.computercraft.shutdown.desc": "Shutdown the listed computers or all if none are specified. You can specify the computer's instance id (e.g. 123), computer id (e.g #123) or label (e.g. \"@My Computer\").",
 | 
			
		||||
    "commands.computercraft.shutdown.done": "Shutdown %s/%s computers",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user