Include lb-players table in UTF8(mb4) checks

Mojang enforce a very restricted set of characters for names, however offline servers can be sent a much wider set of characters.
Also, fix not using UTF8mb4 on table creation if possible.

Fixes #630
This commit is contained in:
frymaster
2015-08-03 20:28:44 +01:00
parent a2c162489a
commit 080450a278

View File

@ -327,46 +327,6 @@ class Updater {
}
config.set("version", "1.9.0");
}
// 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 (configVersion.compareTo(new ComparableVersion("1.9.2")) < 0) {
getLogger().info("Updating tables to 1.9.2 ...");
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.9.2");
}
if (configVersion.compareTo(new ComparableVersion("1.9.4")) < 0) {
getLogger().info("Updating tables to 1.9.4 ...");
final Connection conn = logblock.getConnection();
@ -400,12 +360,55 @@ class Updater {
}
config.set("version", "1.9.4");
}
// 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 (configVersion.compareTo(new ComparableVersion("1.10.0")) < 0) {
getLogger().info("Updating tables to 1.10.0 ...");
final Connection conn = logblock.getConnection();
try {
conn.setAutoCommit(true);
final Statement st = conn.createStatement();
checkCharset("lb-players","name",st);
if (isLogging(Logging.CHAT)) {
checkCharset("lb-chat","message", st);
}
for (final WorldConfig wcfg : getLoggedWorlds()) {
if (wcfg.isLogging(Logging.SIGNTEXT)) {
checkCharset(wcfg.table + "-sign","signtext",st);
}
}
st.close();
conn.close();
} catch (final SQLException ex) {
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
return false;
}
config.set("version", "1.10.0");
}
logblock.saveConfig();
return true;
}
void checkCharset(String table, String column, Statement st) throws SQLException {
final ResultSet rs = st.executeQuery("SHOW FULL COLUMNS FROM `" + table + "` WHERE field = '" + column + "'");
String charset = "utf8";
if (Config.mb4) {
charset = "utf8mb4";
}
if (rs.next() && !rs.getString("Collation").substring(0, charset.length()).equalsIgnoreCase(charset)) {
st.execute("ALTER TABLE `" + table + "` CONVERT TO CHARSET " + charset);
getLogger().info("Table " + table + " modified");
} else {
getLogger().info("Table " + table + " already fine, skipping it");
}
}
void checkTables() throws SQLException {
String charset = "utf8";
if (Config.mb4) {
charset = "utf8mb4";
}
final Connection conn = logblock.getConnection();
if (conn == null) {
throw new SQLException("No connection");
@ -413,18 +416,18 @@ class Updater {
final Statement state = conn.createStatement();
final DatabaseMetaData dbm = conn.getMetaData();
conn.setAutoCommit(true);
createTable(dbm, state, "lb-players", "(playerid INT UNSIGNED NOT NULL AUTO_INCREMENT, UUID varchar(36) NOT NULL, playername varchar(32) NOT NULL, firstlogin DATETIME NOT NULL, lastlogin DATETIME NOT NULL, onlinetime INT UNSIGNED NOT NULL, ip varchar(255) NOT NULL, PRIMARY KEY (playerid), INDEX (UUID), INDEX (playername))");
createTable(dbm, state, "lb-players", "(playerid INT UNSIGNED NOT NULL AUTO_INCREMENT, UUID varchar(36) NOT NULL, playername varchar(32) NOT NULL, firstlogin DATETIME NOT NULL, lastlogin DATETIME NOT NULL, onlinetime INT UNSIGNED NOT NULL, ip varchar(255) NOT NULL, PRIMARY KEY (playerid), INDEX (UUID), INDEX (playername)) DEFAULT CHARSET " + charset);
// Players table must not be empty or inserts won't work - bug #492
final ResultSet rs = state.executeQuery("SELECT NULL FROM `lb-players` LIMIT 1;");
if (!rs.next()) {
state.execute("INSERT IGNORE INTO `lb-players` (UUID,playername) VALUES ('log_dummy_record','dummy_record')");
}
if (isLogging(Logging.CHAT)) {
createTable(dbm, state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, message VARCHAR(255) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid), FULLTEXT message (message)) ENGINE=MyISAM DEFAULT CHARSET utf8");
createTable(dbm, state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, message VARCHAR(255) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid), FULLTEXT message (message)) ENGINE=MyISAM DEFAULT CHARSET " + charset);
}
for (final WorldConfig wcfg : getLoggedWorlds()) {
createTable(dbm, state, wcfg.table, "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, replaced TINYINT UNSIGNED NOT NULL, type TINYINT UNSIGNED NOT NULL, data TINYINT UNSIGNED NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT UNSIGNED NOT NULL, z MEDIUMINT NOT NULL, PRIMARY KEY (id), KEY coords (x, z, y), KEY date (date), KEY playerid (playerid))");
createTable(dbm, state, wcfg.table + "-sign", "(id INT UNSIGNED NOT NULL, signtext VARCHAR(255) NOT NULL, PRIMARY KEY (id)) DEFAULT CHARSET utf8");
createTable(dbm, state, wcfg.table + "-sign", "(id INT UNSIGNED NOT NULL, signtext VARCHAR(255) NOT NULL, PRIMARY KEY (id)) DEFAULT CHARSET " + charset);
createTable(dbm, state, wcfg.table + "-chest", "(id INT UNSIGNED NOT NULL, itemtype SMALLINT UNSIGNED NOT NULL, itemamount SMALLINT NOT NULL, itemdata SMALLINT NOT NULL, PRIMARY KEY (id))");
if (wcfg.isLogging(Logging.KILL)) {
createTable(dbm, state, wcfg.table + "-kills", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, killer INT UNSIGNED, victim INT UNSIGNED NOT NULL, weapon SMALLINT UNSIGNED NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT NOT NULL, z MEDIUMINT NOT NULL, PRIMARY KEY (id))");