diff --git a/src/main/java/pw/kaboom/extras/Main.java b/src/main/java/pw/kaboom/extras/Main.java
index ee0140e..9535658 100644
--- a/src/main/java/pw/kaboom/extras/Main.java
+++ b/src/main/java/pw/kaboom/extras/Main.java
@@ -1,5 +1,7 @@
 package pw.kaboom.extras;
 
+import java.io.File;
+import java.util.Collections;
 import org.bukkit.WorldCreator;
 import org.bukkit.WorldType;
 import org.bukkit.block.BlockFace;
@@ -35,6 +37,7 @@ import pw.kaboom.extras.modules.player.PlayerCommand;
 import pw.kaboom.extras.modules.player.PlayerConnection;
 import pw.kaboom.extras.modules.player.PlayerDamage;
 import pw.kaboom.extras.modules.player.PlayerInteract;
+import pw.kaboom.extras.modules.player.PlayerPrefix;
 import pw.kaboom.extras.modules.player.PlayerRecipe;
 import pw.kaboom.extras.modules.player.PlayerTeleport;
 import pw.kaboom.extras.modules.server.ServerCommand;
@@ -42,9 +45,6 @@ import pw.kaboom.extras.modules.server.ServerGameRule;
 import pw.kaboom.extras.modules.server.ServerTabComplete;
 import pw.kaboom.extras.modules.server.ServerTick;
 
-import java.io.File;
-import java.util.Collections;
-
 public final class Main extends JavaPlugin {
     private File prefixConfigFile;
     private FileConfiguration prefixConfig;
@@ -110,6 +110,7 @@ public final class Main extends JavaPlugin {
         this.getServer().getPluginManager().registerEvents(new PlayerInteract(), this);
         this.getServer().getPluginManager().registerEvents(new PlayerRecipe(), this);
         this.getServer().getPluginManager().registerEvents(new PlayerTeleport(), this);
+        this.getServer().getPluginManager().registerEvents(new PlayerPrefix(), this);
 
         /* Server-related modules */
         this.getServer().getPluginManager().registerEvents(new ServerCommand(), this);
diff --git a/src/main/java/pw/kaboom/extras/commands/CommandPrefix.java b/src/main/java/pw/kaboom/extras/commands/CommandPrefix.java
index c093d3f..e62c907 100644
--- a/src/main/java/pw/kaboom/extras/commands/CommandPrefix.java
+++ b/src/main/java/pw/kaboom/extras/commands/CommandPrefix.java
@@ -1,25 +1,17 @@
 package pw.kaboom.extras.commands;
 
+import javax.annotation.Nonnull;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
-import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.ConsoleCommandSender;
-import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
-import org.bukkit.plugin.java.JavaPlugin;
-import pw.kaboom.extras.Main;
-
-import javax.annotation.Nonnull;
-import java.io.File;
+import pw.kaboom.extras.modules.player.PlayerPrefix;
 
 public final class CommandPrefix implements CommandExecutor {
-    private static final File PREFIX_CONFIG_FILE = JavaPlugin
-            .getPlugin(Main.class).getPrefixConfigFile();
-    private static final FileConfiguration PREFIX_CONFIG = JavaPlugin
-            .getPlugin(Main.class).getPrefixConfig();
+
 
     public boolean onCommand(final @Nonnull CommandSender sender,
                              final @Nonnull Command cmd,
@@ -42,17 +34,15 @@ public final class CommandPrefix implements CommandExecutor {
 
         try {
             if ("off".equalsIgnoreCase(args[0])) {
-                PREFIX_CONFIG.set(player.getUniqueId().toString(), null);
-                PREFIX_CONFIG.save(PREFIX_CONFIG_FILE);
+                PlayerPrefix.removePrefix(player);
                 player.sendMessage(Component
                         .text("You no longer have a tag"));
             } else {
-                PREFIX_CONFIG.set(player.getUniqueId().toString(), String.join(" ", args));
-                PREFIX_CONFIG.save(PREFIX_CONFIG_FILE);
+                final Component prefix = PlayerPrefix.setPrefix(player, String.join(" ", args));
+
                 player.sendMessage(Component.text("You now have the tag: ")
-                        .append(LegacyComponentSerializer.legacyAmpersand()
-                                .deserialize(String.join(" ", args))));
-            }
+                        .append(prefix));
+             }
         } catch (Exception exception) {
             player.sendMessage(Component
                     .text("Something went wrong while saving the prefix. " +
diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java
index f21fb60..b898478 100644
--- a/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java
+++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerChat.java
@@ -2,30 +2,19 @@ package pw.kaboom.extras.modules.player;
 
 import io.papermc.paper.chat.ChatRenderer;
 import io.papermc.paper.event.player.AsyncChatEvent;
+import java.io.IOException;
+import java.util.UUID;
 import javax.annotation.Nonnull;
 import net.kyori.adventure.audience.Audience;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.TextComponent;
 import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
-import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.EventPriority;
 import org.bukkit.event.Listener;
-import org.bukkit.plugin.java.JavaPlugin;
-import pw.kaboom.extras.Main;
-
-import java.util.UUID;
 
 public final class PlayerChat implements Listener {
-    private static final FileConfiguration CONFIG = JavaPlugin.getPlugin(Main.class).getConfig();
-    private static final FileConfiguration PREFIX_CONFIG = JavaPlugin
-            .getPlugin(Main.class).getPrefixConfig();
-
-    private static final Component OP_TAG = LegacyComponentSerializer
-            .legacySection().deserialize(CONFIG.getString("opTag", ""));
-    private static final Component DEOP_TAG = LegacyComponentSerializer
-            .legacySection().deserialize(CONFIG.getString("deOpTag", ""));
     private static final PlayerChatRenderer CHAT_RENDERER = new PlayerChatRenderer();
 
     @EventHandler(priority = EventPriority.HIGHEST)
@@ -57,12 +46,17 @@ public final class PlayerChat implements Listener {
                                          @Nonnull Component component,
                                          @Nonnull Audience audience) {
             Component newComponent = Component.empty();
-            final String legacyPrefix = PREFIX_CONFIG.getString(player.getUniqueId().toString());
-            final Component prefix = legacyPrefix == null ?
-                    ((player.isOp()) ? OP_TAG : DEOP_TAG)
-                    : LegacyComponentSerializer.legacyAmpersand().deserialize(legacyPrefix)
-                    .append(Component.space());
+            final Component prefix;
+            Component prefix1;
 
+            try {
+                prefix1 = PlayerPrefix.getPrefix(player);
+            } catch (IOException e) {
+                e.printStackTrace();
+                prefix1 = PlayerPrefix.getDefaultPrefix(player);
+            }
+
+            prefix = prefix1;
             final String message = ((TextComponent) component).content();
 
             newComponent = newComponent
diff --git a/src/main/java/pw/kaboom/extras/modules/player/PlayerPrefix.java b/src/main/java/pw/kaboom/extras/modules/player/PlayerPrefix.java
new file mode 100644
index 0000000..b8ef1a1
--- /dev/null
+++ b/src/main/java/pw/kaboom/extras/modules/player/PlayerPrefix.java
@@ -0,0 +1,172 @@
+package pw.kaboom.extras.modules.player;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+import org.bukkit.Bukkit;
+import org.bukkit.Server;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerLoginEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitScheduler;
+import pw.kaboom.extras.Main;
+
+public class PlayerPrefix implements Listener {
+	private static final Main plugin = JavaPlugin.getPlugin(Main.class);
+	private static final File PREFIX_CONFIG_FILE = plugin.getPrefixConfigFile();
+	private static final FileConfiguration PREFIX_CONFIG = plugin.getPrefixConfig();
+	private static final FileConfiguration PLUGIN_CONFIGURATION = plugin.getConfig();
+	private static final Component opTag;
+	private static final Component deOpTag;
+	private static final Map<Player, Boolean> opMap = new HashMap<>();
+	private static final Map<Player, Component> displayNameMap = new HashMap<>();
+
+	static {
+		final String legacyOpTag = PLUGIN_CONFIGURATION.getString("opTag");
+		final String legacyDeOpTag = PLUGIN_CONFIGURATION.getString("deOpTag");
+
+		if (legacyOpTag == null || legacyDeOpTag == null) {
+			throw new RuntimeException("Invalid plugin configuration!");
+		}
+
+		opTag = LegacyComponentSerializer.legacySection().deserialize(legacyOpTag);
+		deOpTag = LegacyComponentSerializer.legacySection().deserialize(legacyDeOpTag);
+
+		final BukkitScheduler scheduler = Bukkit.getScheduler();
+
+		scheduler.runTaskTimerAsynchronously(plugin, PlayerPrefix::checkOpStatus,
+			0L, 1L);
+		scheduler.runTaskTimerAsynchronously(plugin, PlayerPrefix::checkDisplayNames,
+			0L, 1L);
+	}
+
+	public static void removePrefix(Player player) throws IOException {
+		final UUID playerUUID = player.getUniqueId();
+		final String stringifiedUUID = playerUUID.toString();
+
+		PREFIX_CONFIG.set(stringifiedUUID, null);
+		PREFIX_CONFIG.save(PREFIX_CONFIG_FILE);
+
+		onUpdate(player);
+	}
+
+	public static Component setPrefix(Player player, String legacyPrefix) throws IOException {
+		final Component prefix = LegacyComponentSerializer.legacySection()
+			.deserialize(legacyPrefix);
+		final UUID playerUUID = player.getUniqueId();
+		final String stringifiedUUID = playerUUID.toString();
+
+		PREFIX_CONFIG.set(stringifiedUUID, legacyPrefix);
+		PREFIX_CONFIG.save(PREFIX_CONFIG_FILE);
+
+		onUpdate(player);
+		return prefix;
+	}
+
+	public static Component getPrefix(Player player) throws IOException {
+		final UUID playerUUID = player.getUniqueId();
+		final String stringifiedUUID = playerUUID.toString();
+		final String legacyPrefix = PREFIX_CONFIG.getString(stringifiedUUID);
+
+		if (legacyPrefix == null) {
+			return player.isOp() ? opTag : deOpTag;
+		}
+
+		return LegacyComponentSerializer.legacyAmpersand()
+			.deserialize(legacyPrefix)
+			.append(Component.space());
+	}
+
+	public static Component getDefaultPrefix(Player player) {
+		return player.isOp() ? opTag : deOpTag;
+	}
+
+	private static void onUpdate(Player player) throws IOException {
+		final Component prefix = getPrefix(player);
+		final Component displayName = player.displayName();
+
+		player.playerListName(prefix.append(displayName));
+	}
+
+	@EventHandler(priority = EventPriority.MONITOR)
+	public void onPlayerLoginEvent(PlayerLoginEvent event) throws IOException {
+		final Player player = event.getPlayer();
+		final boolean isOp = player.isOp();
+
+		opMap.put(player, isOp);
+		displayNameMap.put(player, player.displayName());
+		onUpdate(player);
+	}
+
+	@EventHandler(priority = EventPriority.MONITOR)
+	public void onPlayerQuitEvent(PlayerQuitEvent event) {
+		final Player player = event.getPlayer();
+
+		opMap.remove(player);
+		displayNameMap.remove(player);
+	}
+
+	private static void checkOpStatus() {
+		final Server server = Bukkit.getServer();
+		final Collection<? extends Player> players = server.getOnlinePlayers();
+
+		for (Player player : players) {
+			final boolean isOp = player.isOp();
+
+			if (!opMap.containsKey(player)) {
+				return;
+			}
+
+			final boolean storedOp = opMap.get(player);
+
+			if (isOp == storedOp) {
+				continue;
+			}
+
+			opMap.put(player, isOp);
+
+			try {
+				onUpdate(player);
+			} catch (Exception e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+
+	private static void checkDisplayNames() {
+		final Server server = Bukkit.getServer();
+		final Collection<? extends Player> players = server.getOnlinePlayers();
+
+		for (Player player : players) {
+			final Component displayName = player.displayName();
+
+			if (!displayNameMap.containsKey(player)) {
+				return;
+			}
+
+			final Component storedDisplayName = displayNameMap.get(player);
+
+			if (displayName.equals(storedDisplayName)) {
+				continue;
+			}
+
+			displayNameMap.put(player, displayName);
+
+			try {
+				onUpdate(player);
+			} catch (Exception e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+}