修正mcmmo和mcpc升级后导致使用MySQL数据库的mcMMO无法正确加载用户技能

2015-5-13 23:30:56

之前服务器要加竹mod的时候提示forge版本过低,于是升级了mcpc,同时看到mcmmo也发布了新版,于是就打算顺手升个级。
但是不料升级后我登陆正常,部分其他用户登陆后无法加载mcmmo等级,后台的log显示

[08:52:11] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] Location: sun.reflect.NativeConstructorAccessorImpl newInstance0 -2
[08:52:11] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] SQLException: Duplicate entry 'Bond_Girl' for key 'user'
[08:52:11] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] SQLState: 23000
[08:52:11] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] VendorError: 1062
[08:52:16] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] Location: sun.reflect.NativeConstructorAccessorImpl newInstance0 -2
[08:52:16] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] SQLException: Duplicate entry 'Bond_Girl' for key 'user'
[08:52:16] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] SQLState: 23000
[08:52:16] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] VendorError: 1062
[08:52:26] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] Location: sun.reflect.NativeConstructorAccessorImpl newInstance0 -2
[08:52:26] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] SQLException: Duplicate entry 'Bond_Girl' for key 'user'
[08:52:26] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] SQLState: 23000
[08:52:26] [Craft Scheduler Thread - 1482/ERROR]: [mcMMO] VendorError: 1062
[08:52:41] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] Location: sun.reflect.NativeConstructorAccessorImpl newInstance0 -2
[08:52:41] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] SQLException: Duplicate entry 'Bond_Girl' for key 'user'
[08:52:41] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] SQLState: 23000
[08:52:41] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] VendorError: 1062
[08:53:01] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] Location: sun.reflect.NativeConstructorAccessorImpl newInstance0 -2
[08:53:01] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] SQLException: Duplicate entry 'Bond_Girl' for key 'user'
[08:53:01] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] SQLState: 23000
[08:53:01] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] VendorError: 1062
[08:53:01] [Craft Scheduler Thread - 1481/ERROR]: [mcMMO] Giving up on attempting to load the PlayerProfile for Bond_Girl

去数据一看,数据库里记录的uuid和用户现在使用的uuid不同。导致mcmmo找不见用户,而要插入新数据的时候则user字段上的unique索引冲突。

最初以为是个例,因为我是能够正常使用的。于是帮着上线了的几个用户修改了数据库,不过随着发现这个问题的玩家越来越多,这么下去也不是办法,于是看了一下mcmmo的源码,
com.gmail.nossr50.database.SQLDatabaseManager#newUser(java.sql.Connection, java.lang.String, java.util.UUID)
这个方法里的sql语句使用的是INSERT INTO,会导致插入时报错,于是干脆改成REPLACE INTO,让MySQL自行处理冲突去。
不过使用了主从同步的服务器请谨慎使用REPLACE INTO,请使用 ON DUPLICATE KEY方法进行处理,比如

"INSERT INTO " + tablePrefix + "users (user, uuid, lastlogin) VALUES (?, ?, UNIX_TIMESTAMP()) ON DUPLICATE KEY UPDATE uuid=?"

然后在

statement.setString(2, uuid != null ? uuid.toString() : null);

之后添加一行

statement.setString(3, uuid != null ? uuid.toString() : null);