目的
Minecraft + spigot + MySQLを組み合わせてログインしたユーザーのデータを保存します。
RPGサーバーを作っているときに、ユーザーのデータを保存する必要が出てきたため、下記のような方法で行いました。
MySQL
インストール
Macの場合は
brew install mysql
Windowsの場合は
Windows環境でMySQL - Qiita
データベース&テーブルを作成
この後書くサンプルプログラムは以下のようにデータベースとテーブルを作成しています。
MySQLにログイン後
データベース作成
create database test_database;
テーブル作成
create table players(name varchar(20), uuid varchar(20));
Plugin
※ importは省略して書いてあります
public class Main extends JavaPlugin {
@Override
public void onEnable() {
new PlayerListener(this);
}
@Override
public void onDisable() {
}
}
MainでPlayerListenerを宣言しておきます。
public class PlayerListener implements Listener {
public PlayerListener(Main plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
StatusRecord statusRecord = new StatusRecord();
Status status = statusRecord.savePlayer(player);
}
}
これによってプレイヤーがログインした時にonPlayerJoinに書いてある部分が実行されるようになります。
getPlayer()でログインしたプレイヤーを取得して、
このあと説明するStatusRecordクラスのsavePlayer(player)でユーザーのデータをMySQLに保存しています。
public class StatusRecord {
private Connection connection;
private String host, database, username, password;
private int port;
public StatusRecord() {
host = "localhost";
port = 3306;
database = "test_database";
username = "root";
password = "";
}
public void savePlayer(Player player) {
try {
openConnection();
String name = player.getName();
UUID uuid = player.getUniqueId();
String sql = "INSERT INTO players (name, uuid) VALUES (?, ?);";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, name);
preparedStatement.setString(2, uuid.toString());
preparedStatement.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void openConnection() throws SQLException, ClassNotFoundException {
if (connection != null && !connection.isClosed()) {
return;
}
synchronized (this) {
if (connection != null && !connection.isClosed()) {
return;
}
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database, this.username, this.password);
}
}
}
MySQLのユーザー名とパスワード等の設定は以下のところを変えてください
public StatusRecord() {
host = "localhost";
port = 3306;
database = "test_database";
username = "root";
password = "";
}
SQLのINSERT文は個々で発行しています
String sql = "INSERT INTO players (name, uuid) VALUES (?, ?);";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, name);
preparedStatement.setString(2, uuid.toString());
preparedStatement.executeUpdate();
?はプレースホルダです。
ここで発行したいSQL文は
INSERT INTO players (name, uuid) VALUES (ユーザーの名前, ユーザーのUUID);
なので、
preparedStatement.setString(1, name)
といった感じでプレースホルダに代入しています。
確認
Spigotのpluginディレクトリにbuildしたjarファイルを入れて、サーバーを起動しログインすると、データが保存されているはずです
mysql> use test_database;
Database changed
mysql> select * from players;
+-------+--------------------------------------+
| name | uuid |
+-------+--------------------------------------+
| User | de6e193c-1a04-436d-ad2a-87727d0df335 |
+-------+--------------------------------------+
3 rows in set (0.00 sec)
拡張
これを利用してユーザーのいろいろな情報を保存できるようになります。
(RPGサーバーなら、パラメータ値など)
その場合、DBからデータを取り出す作業が必要になるのですが、別の機会にまとめてみようと思います。(現在試行錯誤中です;;)
あと、DBをガリガリつかうサーバーならO/Rマッパー導入したほうが良いかもしれないです。
こうすればいいよとかあればアドバイスお願いします!