diff --git a/Spigot-Server-Patches/0676-Add-support-for-hex-color-codes-in-console.patch b/Spigot-Server-Patches/0676-Add-support-for-hex-color-codes-in-console.patch
new file mode 100644
index 000000000..dc392d552
--- /dev/null
+++ b/Spigot-Server-Patches/0676-Add-support-for-hex-color-codes-in-console.patch
@@ -0,0 +1,224 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Josh Roy <10731363+JRoy@users.noreply.github.com>
+Date: Sat, 20 Feb 2021 13:09:59 -0500
+Subject: [PATCH] Add support for hex color codes in console
+
+Converts upstream's hex color code legacy format into actual hex color codes in the console.
+
+diff --git a/src/main/java/io/papermc/paper/console/HexFormattingConverter.java b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..d51db8864fce4b7eade5f39d84329a3f8591611d
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
+@@ -0,0 +1,181 @@
++package io.papermc.paper.console;
++
++import net.minecrell.terminalconsole.TerminalConsoleAppender;
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.config.Configuration;
++import org.apache.logging.log4j.core.config.plugins.Plugin;
++import org.apache.logging.log4j.core.layout.PatternLayout;
++import org.apache.logging.log4j.core.pattern.*;
++import org.apache.logging.log4j.util.PerformanceSensitive;
++import org.apache.logging.log4j.util.PropertiesUtil;
++
++import java.awt.*;
++import java.util.List;
++import java.util.regex.Matcher;
++import java.util.regex.Pattern;
++
++import static net.minecrell.terminalconsole.MinecraftFormattingConverter.KEEP_FORMATTING_PROPERTY;
++
++/**
++ * Modified version of
++ * TerminalConsoleAppender's MinecraftFormattingConverter to support hex color codes using the md_5 &x&r&r&g&g&b&b format.
++ */
++@Plugin(name = "paperMinecraftFormatting", category = PatternConverter.CATEGORY)
++@ConverterKeys({ "paperMinecraftFormatting" })
++@PerformanceSensitive("allocation")
++public final class HexFormattingConverter extends LogEventPatternConverter {
++
++ private static final boolean KEEP_FORMATTING = PropertiesUtil.getProperties().getBooleanProperty(KEEP_FORMATTING_PROPERTY);
++
++ private static final String ANSI_RESET = "\u001B[m";
++
++ private static final char COLOR_CHAR = '§';
++ private static final String LOOKUP = "0123456789abcdefklmnor";
++
++ private static final String RGB_ANSI = "\u001B[38;2;%d;%d;%dm";
++ private static final Pattern RGB_PATTERN = Pattern.compile(COLOR_CHAR + "x(" + COLOR_CHAR + "[0-9a-fA-F]){6}");
++
++ private static final String[] ansiCodes = new String[] {
++ "\u001B[0;30m", // Black §0
++ "\u001B[0;34m", // Dark Blue §1
++ "\u001B[0;32m", // Dark Green §2
++ "\u001B[0;36m", // Dark Aqua §3
++ "\u001B[0;31m", // Dark Red §4
++ "\u001B[0;35m", // Dark Purple §5
++ "\u001B[0;33m", // Gold §6
++ "\u001B[0;37m", // Gray §7
++ "\u001B[0;30;1m", // Dark Gray §8
++ "\u001B[0;34;1m", // Blue §9
++ "\u001B[0;32;1m", // Green §a
++ "\u001B[0;36;1m", // Aqua §b
++ "\u001B[0;31;1m", // Red §c
++ "\u001B[0;35;1m", // Light Purple §d
++ "\u001B[0;33;1m", // Yellow §e
++ "\u001B[0;37;1m", // White §f
++ "\u001B[5m", // Obfuscated §k
++ "\u001B[21m", // Bold §l
++ "\u001B[9m", // Strikethrough §m
++ "\u001B[4m", // Underline §n
++ "\u001B[3m", // Italic §o
++ ANSI_RESET, // Reset §r
++ };
++
++ private final boolean ansi;
++ private final List formatters;
++
++ /**
++ * Construct the converter.
++ *
++ * @param formatters The pattern formatters to generate the text to manipulate
++ * @param strip If true, the converter will strip all formatting codes
++ */
++ protected HexFormattingConverter(List formatters, boolean strip) {
++ super("minecraftFormatting", null);
++ this.formatters = formatters;
++ this.ansi = !strip;
++ }
++
++ @Override
++ public void format(LogEvent event, StringBuilder toAppendTo) {
++ int start = toAppendTo.length();
++ //noinspection ForLoopReplaceableByForEach
++ for (int i = 0, size = formatters.size(); i < size; i++) {
++ formatters.get(i).format(event, toAppendTo);
++ }
++
++ if (KEEP_FORMATTING || toAppendTo.length() == start) {
++ // Skip replacement if disabled or if the content is empty
++ return;
++ }
++
++ boolean useAnsi = ansi && TerminalConsoleAppender.isAnsiSupported();
++ String content = useAnsi ? convertRGBColors(toAppendTo.substring(start)) : stripRGBColors(toAppendTo.substring(start));
++ format(content, toAppendTo, start, useAnsi);
++ }
++
++ private static String convertRGBColors(String input) {
++ Matcher matcher = RGB_PATTERN.matcher(input);
++ StringBuffer buffer = new StringBuffer();
++ while (matcher.find()) {
++ String s = matcher.group().replace(String.valueOf(COLOR_CHAR), "").replace('x', '#');
++ Color color = Color.decode(s);
++ int red = color.getRed();
++ int blue = color.getBlue();
++ int green = color.getGreen();
++ String replacement = String.format(RGB_ANSI, red, green, blue);
++ matcher.appendReplacement(buffer, replacement);
++ }
++ matcher.appendTail(buffer);
++ return buffer.toString();
++ }
++
++ private static String stripRGBColors(String input) {
++ Matcher matcher = RGB_PATTERN.matcher(input);
++ StringBuffer buffer = new StringBuffer();
++ while (matcher.find()) {
++ matcher.appendReplacement(buffer, "");
++ }
++ matcher.appendTail(buffer);
++ return buffer.toString();
++ }
++
++ static void format(String s, StringBuilder result, int start, boolean ansi) {
++ int next = s.indexOf(COLOR_CHAR);
++ int last = s.length() - 1;
++ if (next == -1 || next == last) {
++ return;
++ }
++
++ result.setLength(start + next);
++
++ int pos = next;
++ do {
++ int format = LOOKUP.indexOf(Character.toLowerCase(s.charAt(next + 1)));
++ if (format != -1) {
++ if (pos != next) {
++ result.append(s, pos, next);
++ }
++ if (ansi) {
++ result.append(ansiCodes[format]);
++ }
++ pos = next += 2;
++ } else {
++ next++;
++ }
++
++ next = s.indexOf(COLOR_CHAR, next);
++ } while (next != -1 && next < last);
++
++ result.append(s, pos, s.length());
++ if (ansi) {
++ result.append(ANSI_RESET);
++ }
++ }
++
++ /**
++ * Gets a new instance of the {@link HexFormattingConverter} with the
++ * specified options.
++ *
++ * @param config The current configuration
++ * @param options The pattern options
++ * @return The new instance
++ *
++ * @see HexFormattingConverter
++ */
++ public static HexFormattingConverter newInstance(Configuration config, String[] options) {
++ if (options.length < 1 || options.length > 2) {
++ LOGGER.error("Incorrect number of options on paperMinecraftFormatting. Expected at least 1, max 2 received " + options.length);
++ return null;
++ }
++ if (options[0] == null) {
++ LOGGER.error("No pattern supplied on paperMinecraftFormatting");
++ return null;
++ }
++
++ PatternParser parser = PatternLayout.createPatternParser(config);
++ List formatters = parser.parse(options[0]);
++ boolean strip = options.length > 1 && "strip".equals(options[1]);
++ return new HexFormattingConverter(formatters, strip);
++ }
++
++}
+diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
+index 8af159abd3d0cc94cf155fec5b384c42f69551bf..67da1aa7a21622fb231d19dede3775a282a4a12e 100644
+--- a/src/main/resources/log4j2.xml
++++ b/src/main/resources/log4j2.xml
+@@ -6,21 +6,21 @@
+
+
+
+-
++
+
+
+
++ pattern="%highlightError{[%d{HH:mm:ss} %level]: %paperMinecraftFormatting{%msg}%n%xEx{full}}" />
+
+
+
+
+
+-
++
+
+
+
++ pattern="[%d{HH:mm:ss}] [%t/%level]: %paperMinecraftFormatting{%msg}{strip}%n%xEx{full}" />
+
+
+