diff --git a/src/main/java/de/diddiz/LogBlock/BlockChange.java b/src/main/java/de/diddiz/LogBlock/BlockChange.java index 6e823a0..493e52d 100644 --- a/src/main/java/de/diddiz/LogBlock/BlockChange.java +++ b/src/main/java/de/diddiz/LogBlock/BlockChange.java @@ -8,6 +8,7 @@ import de.diddiz.util.BukkitUtils; import org.bukkit.Location; import de.diddiz.LogBlock.config.Config; +import static de.diddiz.util.LoggingUtil.checkText; import org.bukkit.Material; public class BlockChange implements LookupCacheElement @@ -29,7 +30,7 @@ public class BlockChange implements LookupCacheElement this.replaced = replaced; this.type = type; this.data = data; - this.signtext = signtext; + this.signtext = checkText(signtext); this.ca = ca; this.playerName = actor == null ? null : actor.getName(); } diff --git a/src/main/java/de/diddiz/LogBlock/ChatMessage.java b/src/main/java/de/diddiz/LogBlock/ChatMessage.java index a060317..ec5920e 100644 --- a/src/main/java/de/diddiz/LogBlock/ChatMessage.java +++ b/src/main/java/de/diddiz/LogBlock/ChatMessage.java @@ -1,5 +1,6 @@ package de.diddiz.LogBlock; +import static de.diddiz.util.LoggingUtil.checkText; import java.sql.ResultSet; import java.sql.SQLException; import org.bukkit.Location; @@ -14,7 +15,7 @@ public class ChatMessage implements LookupCacheElement id = 0; date = System.currentTimeMillis() / 1000; this.player = player; - this.message = message; + this.message = checkText(message); this.playerName = player == null ? null : player.getName(); } diff --git a/src/main/java/de/diddiz/LogBlock/LogBlock.java b/src/main/java/de/diddiz/LogBlock/LogBlock.java index f7d8687..322eeb1 100644 --- a/src/main/java/de/diddiz/LogBlock/LogBlock.java +++ b/src/main/java/de/diddiz/LogBlock/LogBlock.java @@ -86,6 +86,13 @@ public class LogBlock extends JavaPlugin noDb = true; return; } + final Statement st = conn.createStatement(); + final ResultSet rs = st.executeQuery("SHOW CHARACTER SET where charset='utf8mb4';"); + if (rs.next()) { + Config.mb4=true; + // Allegedly JDBC driver since 2010 hasn't needed this. I did. + st.executeQuery("SET NAMES utf8mb4;"); + } conn.close(); if (updater.update()) load(this); diff --git a/src/main/java/de/diddiz/LogBlock/Updater.java b/src/main/java/de/diddiz/LogBlock/Updater.java index 26e9e80..5fadc84 100644 --- a/src/main/java/de/diddiz/LogBlock/Updater.java +++ b/src/main/java/de/diddiz/LogBlock/Updater.java @@ -1,5 +1,6 @@ package de.diddiz.LogBlock; +import de.diddiz.LogBlock.config.Config; import de.diddiz.LogBlock.config.WorldConfig; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; @@ -208,42 +209,6 @@ class Updater } config.set("version", "1.52"); } - // Ensure charset for free-text fields is UTF-8 - // As this may be an expensive operation and the database default may already be UTF-8, check on a table-by-table basis before converting - if (config.getString("version").compareTo("1.71") < 0) { - getLogger().info("Updating tables to 1.71 ..."); - final Connection conn = logblock.getConnection(); - try { - conn.setAutoCommit(true); - final Statement st = conn.createStatement(); - if (isLogging(Logging.CHAT)) { - final ResultSet rs = st.executeQuery("SHOW FULL COLUMNS FROM `lb-chat` WHERE field = 'message'"); - if (rs.next() && !rs.getString("Collation").substring(0,4).equalsIgnoreCase("utf8")) { - st.execute("ALTER TABLE `lb-chat` CONVERT TO CHARSET utf8"); - getLogger().info("Table lb-chat modified"); - } else { - getLogger().info("Table lb-chat already fine, skipping it"); - } - } - for (final WorldConfig wcfg : getLoggedWorlds()) { - if (wcfg.isLogging(Logging.SIGNTEXT)) { - final ResultSet rs = st.executeQuery("SHOW FULL COLUMNS FROM `"+wcfg.table+"-sign` WHERE field = 'signtext'"); - if (rs.next() && !rs.getString("Collation").substring(0,4).equalsIgnoreCase("utf8")) { - st.execute("ALTER TABLE `"+wcfg.table+"-sign` CONVERT TO CHARSET utf8"); - getLogger().info("Table "+wcfg.table+"-sign modified"); - } else { - getLogger().info("Table "+wcfg.table+"-sign already fine, skipping it"); - } - } - } - st.close(); - conn.close(); - } catch (final SQLException ex) { - Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex); - return false; - } - config.set("version", "1.71"); - } if (config.getString("version").compareTo("1.81") < 0) { getLogger().info("Updating tables to 1.81 ..."); final Connection conn = logblock.getConnection(); @@ -342,7 +307,6 @@ class Updater } config.set("version", "1.90"); } - if (config.getString("version").compareTo("1.91") < 0) { getLogger().info("Updating tables to 1.91 ..."); final Connection conn = logblock.getConnection(); @@ -375,6 +339,44 @@ class Updater } config.set("version", "1.91"); } + // Ensure charset for free-text fields is UTF-8, or UTF8-mb4 if possible + // As this may be an expensive operation and the database default may already be this, check on a table-by-table basis before converting + if (config.getString("version").compareTo("1.92") < 0) { + getLogger().info("Updating tables to 1.92 ..."); + String charset = "utf8"; + if ( Config.mb4) charset="utf8mb4"; + final Connection conn = logblock.getConnection(); + try { + conn.setAutoCommit(true); + final Statement st = conn.createStatement(); + if (isLogging(Logging.CHAT)) { + final ResultSet rs = st.executeQuery("SHOW FULL COLUMNS FROM `lb-chat` WHERE field = 'message'"); + if (rs.next() && !rs.getString("Collation").substring(0,4).equalsIgnoreCase(charset)) { + st.execute("ALTER TABLE `lb-chat` CONVERT TO CHARSET " + charset); + getLogger().info("Table lb-chat modified"); + } else { + getLogger().info("Table lb-chat already fine, skipping it"); + } + } + for (final WorldConfig wcfg : getLoggedWorlds()) { + if (wcfg.isLogging(Logging.SIGNTEXT)) { + final ResultSet rs = st.executeQuery("SHOW FULL COLUMNS FROM `"+wcfg.table+"-sign` WHERE field = 'signtext'"); + if (rs.next() && !rs.getString("Collation").substring(0,4).equalsIgnoreCase(charset)) { + st.execute("ALTER TABLE `"+wcfg.table+"-sign` CONVERT TO CHARSET " + charset); + getLogger().info("Table "+wcfg.table+"-sign modified"); + } else { + getLogger().info("Table "+wcfg.table+"-sign already fine, skipping it"); + } + } + } + st.close(); + conn.close(); + } catch (final SQLException ex) { + Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex); + return false; + } + config.set("version", "1.92"); + } logblock.saveConfig(); return true; } diff --git a/src/main/java/de/diddiz/LogBlock/config/Config.java b/src/main/java/de/diddiz/LogBlock/config/Config.java index ff78a69..88812e8 100644 --- a/src/main/java/de/diddiz/LogBlock/config/Config.java +++ b/src/main/java/de/diddiz/LogBlock/config/Config.java @@ -47,6 +47,8 @@ public class Config public static SimpleDateFormat formatter; public static boolean safetyIdCheck; public static boolean logEnvironmentalKills; + // Not loaded from config - checked at runtime + public static boolean mb4 = false; public static enum LogKillsLevel { diff --git a/src/main/java/de/diddiz/util/LoggingUtil.java b/src/main/java/de/diddiz/util/LoggingUtil.java index 8dca8be..0b4d67a 100644 --- a/src/main/java/de/diddiz/util/LoggingUtil.java +++ b/src/main/java/de/diddiz/util/LoggingUtil.java @@ -4,6 +4,7 @@ import de.diddiz.LogBlock.Actor; import de.diddiz.LogBlock.Consumer; import de.diddiz.LogBlock.Logging; import static de.diddiz.LogBlock.config.Config.getWorldConfig; +import static de.diddiz.LogBlock.config.Config.mb4; import de.diddiz.LogBlock.config.WorldConfig; import java.util.List; import org.bukkit.Location; @@ -200,4 +201,10 @@ public class LoggingUtil { // Do this down here so that the block is added after blocks sitting on it consumer.queueBlockBreak(actor, origin.getState()); } + + public static String checkText(String text) { + if (text==null) return text; + if (mb4) return text; + return text.replaceAll("[^\\u0000-\\uFFFF]", "?"); + } } diff --git a/src/main/java/de/diddiz/util/MySQLConnectionPool.java b/src/main/java/de/diddiz/util/MySQLConnectionPool.java index d78af21..a986976 100644 --- a/src/main/java/de/diddiz/util/MySQLConnectionPool.java +++ b/src/main/java/de/diddiz/util/MySQLConnectionPool.java @@ -1,5 +1,6 @@ package de.diddiz.util; +import static de.diddiz.LogBlock.config.Config.mb4; import java.io.Closeable; import java.sql.Array; import java.sql.Blob; @@ -76,6 +77,7 @@ public class MySQLConnectionPool implements Closeable throw new SQLException("Failed to validate a brand new connection"); } connections.add(conn); + if (mb4) conn.createStatement().executeQuery("SET NAMES utf8mb4"); return conn; } finally { lock.unlock(); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6fc1756..e143a31 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: ${project.name} -version: '1.91' +version: '1.92' author: DiddiZ authors: [md_5, ammar2, frymaster] website: http://dev.bukkit.org/server-mods/logblock/