@@ -30,36 +30,14 @@ public class DataIO {
3030 // ===========================================================
3131
3232 /** グループ全体を保存(各テーブルへの分割保存) */
33- public static boolean saveGroupData (GroupData g , long clientVersion ) {
34-
35- Bukkit .getLogger ().info ("[DEBUG] 保存対象 groupUUID: " + g .groupUUID );
36- Bukkit .getLogger ().info ("[DEBUG] 保存対象 groupName: " + g .groupName );
33+ public static boolean saveGroupData (GroupData g ) {
3734 try (Connection conn = db .getConnection ()) {
38- // 最新version取得
39- String selectSql = "SELECT version FROM group_table WHERE group_uuid = ?" ;
40- long dbVersion = 0 ;
41- try (PreparedStatement ps = conn .prepareStatement (selectSql )) {
42- ps .setString (1 , g .groupUUID .toString ());
43- try (ResultSet rs = ps .executeQuery ()) {
44- if (rs .next ()) dbVersion = rs .getLong ("version" );
45- }
46- }
47-
48- // バージョン不一致なら競合
49- if (dbVersion != clientVersion ) {
50- Bukkit .getLogger ().info ("V不一致" );
51- return false ;
52- }
53-
54- // versionを+1
55- g .version = dbVersion + 1 ;
56-
57- // ---- 保存処理 ----
58- saveGroupTable (conn , g ); // group_table
59- saveGroupMembers (conn , g ); // group_member_table
35+ // group_table
36+ saveGroupTable (conn , g );
37+ saveGroupMembers (conn , g );
6038
6139 if (g .storageData != null ) {
62- saveStorageData (conn , g ); // storage_table
40+ saveStorageData (conn , g );
6341
6442 for (Map .Entry <String , InventoryData > entry : g .storageData .storageInventory .entrySet ()) {
6543 String pageId = entry .getKey ();
@@ -70,33 +48,47 @@ public static boolean saveGroupData(GroupData g, long clientVersion) {
7048 continue ;
7149 }
7250
73- // 個別保存
74- saveSinglePage (conn , g , pageId , inv );
51+ if (!saveSinglePage (conn , g , pageId , inv )) {
52+ return false ; // ここで失敗通知
53+ }
7554 }
7655 }
7756
78- // 成功したので差分ログを保存
57+ // 差分ログを保存
7958 UnifiedLogManager .saveDiffLogs (BetterStorage .BSPlugin .getDatabaseManager (), g );
8059 return true ;
60+
8161 } catch (SQLException e ) {
8262 Bukkit .getLogger ().warning ("GroupDataの保存に失敗: " + e .getMessage ());
8363 return false ;
8464 }
8565 }
8666
87- private static void saveSinglePage (Connection conn , GroupData g , String pageId , InventoryData inv ) throws SQLException {
67+ private static boolean saveSinglePage (Connection conn , GroupData g , String pageId , InventoryData inv ) throws SQLException {
68+ // 🔁 versionチェック
69+ long dbPageVersion = getInventoryPageVersion (conn , g .groupUUID , pageId );
70+ if (dbPageVersion != inv .version ) {
71+ Bukkit .getLogger ().warning ("[BetterStorage] ページバージョン不一致: " + pageId );
72+ return false ;
73+ }
74+ inv .version = dbPageVersion + 1 ;
75+
8876 // ---------- inventory_table ----------
89- String invSql = "REPLACE INTO inventory_table (group_uuid, plugin_name, page_id, display_name, row_count, require_permission) VALUES (?, ?, ?, ?, ?, ?)" ;
77+ String invSql = "REPLACE INTO inventory_table " +
78+ "(group_uuid, plugin_name, page_id, display_name, row_count, require_permission, version) " +
79+ "VALUES (?, ?, ?, ?, ?, ?, ?)" ;
9080 try (PreparedStatement ps = conn .prepareStatement (invSql )) {
9181 ps .setString (1 , g .groupUUID .toString ());
9282 ps .setString (2 , g .ownerPlugin );
9383 ps .setString (3 , pageId );
9484 ps .setString (4 , inv .displayName );
9585 ps .setInt (5 , inv .rows );
9686 ps .setString (6 , gson .toJson (inv .requirePermission ));
87+ ps .setLong (7 , inv .version );
9788 ps .executeUpdate ();
9889 }
9990
91+
10092 // ---------- inventory_item_table ----------
10193 // 🔥 1. 既存スロットとitemstack取得
10294 Map <Integer , String > oldSlotBase64Map = new HashMap <>();
@@ -191,20 +183,20 @@ private static void saveSinglePage(Connection conn, GroupData g, String pageId,
191183 ps .executeBatch ();
192184 }
193185 }
186+ return true ;
194187 }
195188
196189
197190
198191 // ---------- SAVE / group ----------
199192 private static void saveGroupTable (Connection conn , GroupData g ) throws SQLException {
200- String sql = "REPLACE INTO group_table (group_uuid, group_name, display_name, is_private, owner_plugin, version ) VALUES (?, ?, ?, ?, ?, ?)" ;
193+ String sql = "REPLACE INTO group_table (group_uuid, group_name, display_name, is_private, owner_plugin) VALUES (?, ?, ?, ?, ?)" ;
201194 try (PreparedStatement ps = conn .prepareStatement (sql )) {
202195 ps .setString (1 , g .groupUUID .toString ());
203196 ps .setString (2 , g .groupName );
204197 ps .setString (3 , g .displayName );
205198 ps .setBoolean (4 , g .isPrivate );
206199 ps .setString (5 , g .ownerPlugin );
207- ps .setLong (6 , g .version );
208200 ps .executeUpdate ();
209201 }
210202 }
@@ -255,16 +247,15 @@ public static boolean saveInventoryOnly(GroupData g, StorageData storageData, St
255247 g .storageData .loadPage (conn , g .ownerPlugin , pageId );
256248 }
257249
258- long dbVersion = getGroupVersion (conn , g .groupUUID );
259- if (dbVersion != g .version ) {
250+ long dbPageVersion = getInventoryPageVersion (conn , g .groupUUID , pageId );
251+ if (dbPageVersion != inv .version ) {
260252 return false ;
261253 }
262- g .version = dbVersion + 1 ;
254+ inv .version = dbPageVersion + 1 ;
263255
264256 saveSinglePage (conn , g , pageId , inv );
265- saveGroupTable (conn , g );
257+ saveGroupTable (conn , g ); // group_tableは必須(versionが無くても更新してOK)
266258
267- // 成功したので差分ログを保存
268259 UnifiedLogManager .saveDiffLogs (BetterStorage .BSPlugin .getDatabaseManager (), g );
269260 return true ;
270261 } catch (SQLException e ) {
@@ -273,16 +264,6 @@ public static boolean saveInventoryOnly(GroupData g, StorageData storageData, St
273264 }
274265 }
275266
276- public static long getGroupVersion (Connection conn , UUID groupUUID ) throws SQLException {
277- String sql = "SELECT version FROM group_table WHERE group_uuid = ?" ;
278- try (PreparedStatement ps = conn .prepareStatement (sql )) {
279- ps .setString (1 , groupUUID .toString ());
280- try (ResultSet rs = ps .executeQuery ()) {
281- return rs .next () ? rs .getLong ("version" ) : 0 ;
282- }
283- }
284- }
285-
286267 private static void saveTags (Connection conn , GroupData g ) throws SQLException {
287268 String sql = "REPLACE INTO tag_table (group_uuid, plugin_name, page_id, user_tag) VALUES (?, ?, ?, ?)" ;
288269 try (PreparedStatement ps = conn .prepareStatement (sql )) {
@@ -303,36 +284,6 @@ private static void saveTags(Connection conn, GroupData g) throws SQLException {
303284 ps .executeBatch ();
304285 }
305286 }
306-
307- /** ロールバック用メソッド **/
308- public static void saveGroupDataWithoutVersionCheck (GroupData g ) {
309- try (Connection conn = db .getConnection ()) {
310- // group_table
311- saveGroupTable (conn , g );
312- saveGroupMembers (conn , g );
313-
314- if (g .storageData != null ) {
315- saveStorageData (conn , g );
316-
317- for (Map .Entry <String , InventoryData > entry : g .storageData .storageInventory .entrySet ()) {
318- String pageId = entry .getKey ();
319- InventoryData inv = entry .getValue ();
320-
321- if (!inv .isFullyLoaded ()) {
322- Bukkit .getLogger ().info ("[BetterStorage] スキップ: " + g .groupName + "/" + pageId + " は未完全のため保存されません" );
323- continue ;
324- }
325-
326- saveSinglePage (conn , g , pageId , inv );
327- }
328- }
329-
330- // 差分ログは保存しない(ロールバック時)
331- } catch (SQLException e ) {
332- Bukkit .getLogger ().warning ("[BetterStorage] ロールバック時の保存に失敗: " + e .getMessage ());
333- }
334- }
335-
336287 // ===========================================================
337288 // ===== 2. LOAD ============================================
338289 // ===========================================================
@@ -344,20 +295,18 @@ public static GroupData loadGroupData(UUID groupUUID) {
344295 String groupName = null ;
345296 String displayName ;
346297 boolean isPrivate ;
347- long version ;
348298 String ownerPlugin ;
349299
350300 // --- group_table ------------------------------------
351301 try (PreparedStatement ps = conn .prepareStatement (
352- "SELECT group_name, display_name, is_private, version, owner_plugin FROM group_table WHERE group_uuid = ?" )) {
302+ "SELECT group_name, display_name, is_private, owner_plugin FROM group_table WHERE group_uuid = ?" )) {
353303 ps .setString (1 , groupUUID .toString ());
354304 Bukkit .getLogger ().info ("UUID検索: '" + groupUUID .toString () + "'" );
355305 try (ResultSet rs = ps .executeQuery ()) {
356306 if (!rs .next ()) return null ;
357307 groupName = rs .getString ("group_name" );
358308 displayName = rs .getString ("display_name" );
359309 isPrivate = rs .getBoolean ("is_private" );
360- version = rs .getLong ("version" );
361310 ownerPlugin = rs .getString ("owner_plugin" );
362311 }
363312 }
@@ -385,9 +334,8 @@ public static GroupData loadGroupData(UUID groupUUID) {
385334 // --- storage + inventory + tags ----------------------
386335 StorageData storage = loadStorageData (conn , groupUUID );
387336
388- GroupData groupData = new GroupData (groupName , displayName , playerList , playerPerm , isPrivate , storage , ownerPlugin , groupUUID );
389- groupData .version = version ;
390- return groupData ;
337+ // GroupDataを生成(versionは不要)
338+ return new GroupData (groupName , displayName , playerList , playerPerm , isPrivate , storage , ownerPlugin , groupUUID );
391339
392340 } catch (SQLException e ) {
393341 Bukkit .getLogger ().warning ("GroupData の読み込みに失敗: " + e .getMessage ());
@@ -450,7 +398,7 @@ private static StorageData loadStorageData(Connection conn, UUID groupUUID) thro
450398 /** inventory_table + items + tags を読み込み */
451399 private static Map <String , InventoryData > loadInventoryData (Connection conn , UUID groupUUID , String pluginName ) throws SQLException {
452400 Map <String , InventoryData > map = new HashMap <>();
453- String sql = "SELECT page_id, display_name, row_count, require_permission FROM inventory_table WHERE group_uuid = ? AND plugin_name = ?" ;
401+ String sql = "SELECT page_id, display_name, row_count, require_permission, version FROM inventory_table WHERE group_uuid = ? AND plugin_name = ?" ;
454402 try (PreparedStatement ps = conn .prepareStatement (sql )) {
455403 ps .setString (1 , groupUUID .toString ());
456404 ps .setString (2 , pluginName );
@@ -460,8 +408,13 @@ private static Map<String, InventoryData> loadInventoryData(Connection conn, UUI
460408 String display = rs .getString ("display_name" );
461409 int rows = rs .getInt ("row_count" );
462410 Set <String > reqPerm = gson .fromJson (rs .getString ("require_permission" ), new TypeToken <Set <String >>(){}.getType ());
411+ long version = rs .getLong ("version" ); // ← 追加!
412+
463413 Map <Integer , ItemStack > slotMap = loadInventoryItems (conn , groupUUID , pluginName , pageId );
464- map .put (pageId , new InventoryData (display , rows , reqPerm , slotMap ));
414+
415+ InventoryData inv = new InventoryData (display , rows , reqPerm , slotMap );
416+ inv .version = version ; // ← version設定!
417+ map .put (pageId , inv );
465418 }
466419 }
467420 }
@@ -535,7 +488,7 @@ public static StorageData loadStorageMetaOnly(UUID groupUUID) {
535488 */
536489 private static Map <String , InventoryData > loadInventoryMetaOnly (Connection conn , UUID groupUUID , String pluginName ) throws SQLException {
537490 Map <String , InventoryData > map = new HashMap <>();
538- String sql = "SELECT page_id, display_name, row_count, require_permission FROM inventory_table WHERE group_uuid = ? AND plugin_name = ?" ;
491+ String sql = "SELECT page_id, display_name, row_count, require_permission, version FROM inventory_table WHERE group_uuid = ? AND plugin_name = ?" ;
539492 try (PreparedStatement ps = conn .prepareStatement (sql )) {
540493 ps .setString (1 , groupUUID .toString ());
541494 ps .setString (2 , pluginName );
@@ -545,7 +498,10 @@ private static Map<String, InventoryData> loadInventoryMetaOnly(Connection conn,
545498 String display = rs .getString ("display_name" );
546499 int rows = rs .getInt ("row_count" );
547500 Set <String > reqPerm = gson .fromJson (rs .getString ("require_permission" ), new TypeToken <Set <String >>() {}.getType ());
501+ long version = rs .getLong ("version" ); // ← ここ追加!
502+
548503 InventoryData inv = new InventoryData (display , rows , reqPerm , new HashMap <>());
504+ inv .version = version ; // ← versionをセット!
549505 inv .setFullyLoaded (false );
550506 map .put (pageId , inv );
551507 }
@@ -650,6 +606,24 @@ private static String loadOwnerPlugin(Connection conn, UUID groupUUID) throws SQ
650606 return null ;
651607 }
652608
609+ /**
610+ * 各ページのバージョンを取得するメソッド
611+ * @param conn
612+ * @param groupUUID
613+ * @param pageId
614+ * @return
615+ * @throws SQLException
616+ */
617+ public static long getInventoryPageVersion (Connection conn , UUID groupUUID , String pageId ) throws SQLException {
618+ String sql = "SELECT version FROM inventory_table WHERE group_uuid = ? AND page_id = ?" ;
619+ try (PreparedStatement ps = conn .prepareStatement (sql )) {
620+ ps .setString (1 , groupUUID .toString ());
621+ ps .setString (2 , pageId );
622+ try (ResultSet rs = ps .executeQuery ()) {
623+ return rs .next () ? rs .getLong ("version" ) : 0 ;
624+ }
625+ }
626+ }
653627
654628 // ===========================================================
655629 // ===== 3. DELETE ==========================================
0 commit comments