1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-25 22:53:22 +00:00

Delete previous chat messages of the same type

This uses a custom ComputerCraft packet to send chat messages to the
client. When received, we delete all messages of the same category
before sending the new ones.

This avoids cluttering the chat with near-identical messages, and helps
make working with the "individual dump" command easier, as the previous
computer's dump output is deleted.

Also change the max height of the TextTable to 18, so it fits within
Minecraft's default chat limit.
This commit is contained in:
SquidDev 2018-05-15 11:44:23 +01:00
parent 5bf9f9e3c5
commit 7ec8ddcf7d
5 changed files with 100 additions and 27 deletions

View File

@ -34,8 +34,10 @@
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.entity.TurtleVisionCamera;
import dan200.computercraft.shared.util.Colour;
import gnu.trove.map.hash.TIntIntHashMap;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
@ -50,6 +52,7 @@
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
@ -71,6 +74,8 @@
public class ComputerCraftProxyClient extends ComputerCraftProxyCommon
{
private static TIntIntHashMap lastCounts = new TIntIntHashMap();
private long m_tick;
private long m_renderFrame;
private FixedWidthFontRenderer m_fixedWidthFontRenderer;
@ -384,6 +389,7 @@ public void handlePacket( final ComputerCraftPacket packet, final EntityPlayer p
case ComputerCraftPacket.ComputerTerminalChanged:
case ComputerCraftPacket.ComputerDeleted:
case ComputerCraftPacket.PlayRecord:
case ComputerCraftPacket.PostChat:
{
// Packet from Server to Client
IThreadListener listener = Minecraft.getMinecraft();
@ -450,6 +456,36 @@ private void processPacket( ComputerCraftPacket packet, EntityPlayer player )
{
mc.world.playRecord( pos, null );
}
break;
}
case ComputerCraftPacket.PostChat:
{
/*
This allows us to send delete chat messages of the same "category" as the previous one.
It's used by the various /computercraft commands to avoid filling the chat with repetitive
messages.
*/
int id = packet.m_dataInt[0];
ITextComponent[] components = new ITextComponent[packet.m_dataString.length];
for( int i = 0; i < packet.m_dataString.length; i++ )
{
components[i] = ITextComponent.Serializer.jsonToComponent( packet.m_dataString[i] );
}
GuiNewChat chat = Minecraft.getMinecraft().ingameGUI.getChatGUI();
// Keep track of how many lines we wrote last time, deleting any extra ones.
int lastCount = lastCounts.get( id );
for( int i = components.length; i < lastCount; i++ ) chat.deleteChatLine( i + id );
lastCounts.put( id, components.length );
// Add new lines
for( int i = 0; i < components.length; i++ )
{
chat.printChatMessageWithOptionalDeletion( components[i], id + i );
}
break;
}
}

View File

@ -99,7 +99,7 @@ public long get( TrackingField field )
if( field == TrackingField.TASKS ) return tasks;
if( field == TrackingField.MAX_TIME ) return maxTime;
if( field == TrackingField.TOTAL_TIME ) return totalTime;
if( field == TrackingField.AVERAGE_TIME ) return totalTime / tasks;
if( field == TrackingField.AVERAGE_TIME ) return tasks == 0 ? 0 : totalTime / tasks;
if( field == TrackingField.SERVER_COUNT ) return serverCount;
if( field == TrackingField.SERVER_TIME ) return serverTime;

View File

@ -31,6 +31,10 @@ public final class CommandComputerCraft extends CommandDelegate
{
public static final UUID SYSTEM_UUID = new UUID( 0, 0 );
private static final int DUMP_LIST_ID = 5373952;
private static final int DUMP_SINGLE_ID = 1844510720;
private static final int TRACK_ID = 373882880;
public CommandComputerCraft()
{
super( create() );
@ -55,7 +59,7 @@ public void execute( @Nonnull CommandContext context, @Nonnull List<String> argu
{
if( arguments.size() == 0 )
{
TextTable table = new TextTable( "Instance", "Id", "On", "Position" );
TextTable table = new TextTable( DUMP_LIST_ID, "Instance", "Id", "On", "Position" );
List<ServerComputer> computers = new ArrayList<>( ComputerCraft.serverComputerRegistry.getComputers() );
@ -101,7 +105,7 @@ else if( arguments.size() == 1 )
{
ServerComputer computer = ComputerSelector.getComputer( arguments.get( 0 ) );
TextTable table = new TextTable();
TextTable table = new TextTable( DUMP_SINGLE_ID );
table.addRow( header( "Instance" ), text( Integer.toString( computer.getInstanceID() ) ) );
table.addRow( header( "Id" ), text( Integer.toString( computer.getID() ) ) );
table.addRow( header( "Label" ), text( computer.getLabel() ) );
@ -464,8 +468,8 @@ private static void displayTimings( CommandContext context, List<ComputerTracker
TextTable table = defaultLayout
? new TextTable( "Computer", "Tasks", "Total", "Average", "Maximum" )
: new TextTable( "Computer", field.displayName() );
? new TextTable( TRACK_ID, "Computer", "Tasks", "Total", "Average", "Maximum" )
: new TextTable( TRACK_ID, "Computer", field.displayName() );
for( ComputerTracker entry : timings )
{

View File

@ -1,13 +1,17 @@
package dan200.computercraft.shared.command.framework;
import com.google.common.collect.Lists;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.network.ComputerCraftPacket;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import static dan200.computercraft.shared.command.framework.ChatHelpers.coloured;
@ -19,23 +23,27 @@ public class TextTable
private static final ITextComponent SEPARATOR = coloured( "| ", TextFormatting.GRAY );
private static final ITextComponent LINE = text( "\n" );
private final int id;
private int columns = -1;
private final ITextComponent[] header;
private final List<ITextComponent[]> rows = Lists.newArrayList();
public TextTable( @Nonnull ITextComponent... header )
public TextTable( int id, @Nonnull ITextComponent... header )
{
this.id = id;
this.header = header;
this.columns = header.length;
}
public TextTable()
public TextTable(int id)
{
header = null;
this.id = id;
this.header = null;
}
public TextTable( @Nonnull String... header )
public TextTable( int id, @Nonnull String... header )
{
this.id = id;
this.header = new ITextComponent[header.length];
for( int i = 0; i < header.length; i++ )
{
@ -72,9 +80,10 @@ public void displayTo( ICommandSender sender )
}
}
// Limit the number of rows to something sensible.
int limit = isPlayer( sender ) ? 30 : 100;
if( limit > rows.size() ) limit = rows.size();
// Limit the number of rows to fit within a single chat window on default Minecraft
// options.
int height = isPlayer( sender ) ? 18 : 100;
int limit = rows.size() <= height ? rows.size() : height - 1;
for( int y = 0; y < limit; y++ )
{
@ -95,43 +104,66 @@ public void displayTo( ICommandSender sender )
// TODO: Limit the widths of some entries if totalWidth > maxWidth
ITextComponent out = new TextComponentString( "" );
List<ITextComponent> out = new ArrayList<>();
if( header != null )
{
TextComponentString line = new TextComponentString( "" );
for( int i = 0; i < columns - 1; i++ )
{
appendFixedWidth( out, sender, header[i], maxWidths[i] );
out.appendSibling( SEPARATOR );
appendFixedWidth( line, sender, header[i], maxWidths[i] );
line.appendSibling( SEPARATOR );
}
out.appendSibling( header[columns - 1] );
out.appendSibling( LINE );
line.appendSibling( header[columns - 1] );
out.add( line );
// Round the width up rather than down
int rowCharWidth = getWidthFor( '=', sender );
int rowWidth = totalWidth / rowCharWidth + (totalWidth % rowCharWidth == 0 ? 0 : 1);
out.appendSibling( coloured( StringUtils.repeat( '=', rowWidth ), TextFormatting.GRAY ) );
out.appendSibling( LINE );
out.add( coloured( StringUtils.repeat( '=', rowWidth ), TextFormatting.GRAY ) );
}
for( int i = 0; i < limit; i++ )
{
TextComponentString line = new TextComponentString( "" );
ITextComponent[] row = rows.get( i );
if( i != 0 ) out.appendSibling( LINE );
for( int j = 0; j < columns - 1; j++ )
{
appendFixedWidth( out, sender, row[j], maxWidths[j] );
out.appendSibling( SEPARATOR );
appendFixedWidth( line, sender, row[j], maxWidths[j] );
line.appendSibling( SEPARATOR );
}
out.appendSibling( row[columns - 1] );
line.appendSibling( row[columns - 1] );
out.add( line );
}
if( limit != rows.size() )
if( rows.size() > limit )
{
out.appendSibling( LINE );
out.appendSibling( coloured( (rows.size() - limit) + " additional rows...", TextFormatting.AQUA ) );
out.add( coloured( (rows.size() - limit) + " additional rows...", TextFormatting.AQUA ) );
}
sender.sendMessage( out );
if( isPlayer( sender ) && id != 0 )
{
ComputerCraftPacket packet = new ComputerCraftPacket();
packet.m_packetType = ComputerCraftPacket.PostChat;
packet.m_dataInt = new int[]{ id };
String[] lines = packet.m_dataString = new String[out.size()];
for( int i = 0; i < out.size(); i++ )
{
lines[i] = ITextComponent.Serializer.componentToJson( out.get( i ) );
}
ComputerCraft.sendToPlayer( (EntityPlayerMP) sender, packet );
}
else
{
ITextComponent result = new TextComponentString( "" );
for( int i = 0; i < out.size(); i++ )
{
if( i > 0 ) result.appendSibling( LINE );
result.appendSibling( out.get( 0 ) );
}
sender.sendMessage( result );
}
}
}

View File

@ -33,6 +33,7 @@ public class ComputerCraftPacket
public static final byte ComputerTerminalChanged = 8;
public static final byte ComputerDeleted = 9;
public static final byte PlayRecord = 10;
public static final byte PostChat = 11;
// Packet class
public byte m_packetType;