diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java b/chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java
new file mode 100644
index 0000000000..f5bcb174c0
--- /dev/null
+++ b/chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java
@@ -0,0 +1,92 @@
+package net.md_5.bungee.api.chat;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import net.md_5.bungee.api.ChatColor;
+
+@Getter
+@Setter
+@ToString
+@NoArgsConstructor
+public class KeybindComponent extends BaseComponent
+{
+
+ /**
+ * The keybind identifier to use.
+ *
+ * Will be replaced with the actual key the client is using.
+ */
+ private String keybind;
+
+ /**
+ * Creates a keybind component from the original to clone it.
+ *
+ * @param original the original for the new keybind component.
+ */
+ public KeybindComponent(KeybindComponent original)
+ {
+ super( original );
+ setKeybind( original.getKeybind() );
+ }
+
+ /**
+ * Creates a keybind component with the passed internal keybind value.
+ *
+ * @param keybind the keybind value
+ * @see Keybind
+ */
+ public KeybindComponent(String keybind)
+ {
+ setKeybind( keybind );
+ }
+
+ @Override
+ public BaseComponent duplicate()
+ {
+ return new KeybindComponent( this );
+ }
+
+ @Override
+ public BaseComponent duplicateWithoutFormatting()
+ {
+ return new KeybindComponent( keybind );
+ }
+
+ @Override
+ protected void toPlainText(StringBuilder builder)
+ {
+ builder.append( getKeybind() );
+ super.toPlainText( builder );
+ }
+
+ @Override
+ protected void toLegacyText(StringBuilder builder)
+ {
+ builder.append( getColor() );
+ if ( isBold() )
+ {
+ builder.append( ChatColor.BOLD );
+ }
+ if ( isItalic() )
+ {
+ builder.append( ChatColor.ITALIC );
+ }
+ if ( isUnderlined() )
+ {
+ builder.append( ChatColor.UNDERLINE );
+ }
+ if ( isStrikethrough() )
+ {
+ builder.append( ChatColor.STRIKETHROUGH );
+ }
+ if ( isObfuscated() )
+ {
+ builder.append( ChatColor.MAGIC );
+ }
+ builder.append( getKeybind() );
+
+ super.toLegacyText( builder );
+ }
+}
diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/Keybinds.java b/chat/src/main/java/net/md_5/bungee/api/chat/Keybinds.java
new file mode 100644
index 0000000000..d268889d13
--- /dev/null
+++ b/chat/src/main/java/net/md_5/bungee/api/chat/Keybinds.java
@@ -0,0 +1,51 @@
+package net.md_5.bungee.api.chat;
+
+/**
+ * All keybind values supported by vanilla Minecraft.
+ *
+ * Values may be removed if they are no longer supported.
+ *
+ * @see KeybindComponent
+ */
+public interface Keybinds
+{
+
+ String JUMP = "key.jump";
+ String SNEAK = "key.sneak";
+ String SPRINT = "key.sprint";
+ String LEFT = "key.left";
+ String RIGHT = "key.right";
+ String BACK = "key.back";
+ String FORWARD = "key.forward";
+
+ String ATTACK = "key.attack";
+ String PICK_ITEM = "key.pickItem";
+ String USE = "key.use";
+
+ String DROP = "key.drop";
+ String HOTBAR_1 = "key.hotbar.1";
+ String HOTBAR_2 = "key.hotbar.2";
+ String HOTBAR_3 = "key.hotbar.3";
+ String HOTBAR_4 = "key.hotbar.4";
+ String HOTBAR_5 = "key.hotbar.5";
+ String HOTBAR_6 = "key.hotbar.6";
+ String HOTBAR_7 = "key.hotbar.7";
+ String HOTBAR_8 = "key.hotbar.8";
+ String HOTBAR_9 = "key.hotbar.9";
+ String INVENTORY = "key.inventory";
+ String SWAP_HANDS = "key.swapHands";
+
+ String LOAD_TOOLBAR_ACTIVATOR = "key.loadToolbarActivator";
+ String SAVE_TOOLBAR_ACTIVATOR = "key.saveToolbarActivator";
+
+ String PLAYERLIST = "key.playerlist";
+ String CHAT = "key.chat";
+ String COMMAND = "key.command";
+
+ String ADVANCEMENTS = "key.advancements";
+ String SPECTATOR_OUTLINES = "key.spectatorOutlines";
+ String SCREENSHOT = "key.screenshot";
+ String SMOOTH_CAMERA = "key.smoothCamera";
+ String FULLSCREEN = "key.fullscreen";
+ String TOGGLE_PERSPECTIVE = "key.togglePerspective";
+}
diff --git a/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java b/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java
index 5756fc4afd..7d366e2464 100644
--- a/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java
+++ b/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java
@@ -8,6 +8,7 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import net.md_5.bungee.api.chat.BaseComponent;
+import net.md_5.bungee.api.chat.KeybindComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
@@ -21,6 +22,7 @@ public class ComponentSerializer implements JsonDeserializer
registerTypeAdapter( BaseComponent.class, new ComponentSerializer() ).
registerTypeAdapter( TextComponent.class, new TextComponentSerializer() ).
registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ).
+ registerTypeAdapter( KeybindComponent.class, new KeybindComponentSerializer() ).
create();
public final static ThreadLocal> serializedComponents = new ThreadLocal>();
@@ -59,6 +61,10 @@ public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializa
{
return context.deserialize( json, TranslatableComponent.class );
}
+ if ( object.has( "keybind" ) )
+ {
+ return context.deserialize( json, KeybindComponent.class );
+ }
return context.deserialize( json, TextComponent.class );
}
}
diff --git a/chat/src/main/java/net/md_5/bungee/chat/KeybindComponentSerializer.java b/chat/src/main/java/net/md_5/bungee/chat/KeybindComponentSerializer.java
new file mode 100644
index 0000000000..a86a40a6d1
--- /dev/null
+++ b/chat/src/main/java/net/md_5/bungee/chat/KeybindComponentSerializer.java
@@ -0,0 +1,34 @@
+package net.md_5.bungee.chat;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+import net.md_5.bungee.api.chat.KeybindComponent;
+
+public class KeybindComponentSerializer extends BaseComponentSerializer implements JsonSerializer, JsonDeserializer
+{
+
+ @Override
+ public KeybindComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
+ {
+ KeybindComponent component = new KeybindComponent();
+ JsonObject object = json.getAsJsonObject();
+ deserialize( object, component, context );
+ component.setKeybind( object.get( "keybind" ).getAsString() );
+ return component;
+ }
+
+ @Override
+ public JsonElement serialize(KeybindComponent src, Type typeOfSrc, JsonSerializationContext context)
+ {
+ JsonObject object = new JsonObject();
+ serialize( object, src, context );
+ object.addProperty( "keybind", src.getKeybind() );
+ return object;
+ }
+}