@@ -191,12 +191,34 @@ public static boolean restoreGroupToTimestamp(UUID groupUUID, LocalDateTime targ
191191 if (group == null ) {
192192 group = backup .toGroupData (); // 完全復元
193193 } else {
194+ saveBackupSnapshot (group );
194195 // storageData だけ置き換える
195196 StorageData restored = backup .storageData .toStorageData ();
196197 restored .attach (group );
197198 group .storageData = restored ;
198199 }
199200
201+ // 2_2旧データ削除
202+ // 旧データ削除(このグループ+このプラグインのページ・アイテム・タグ [+ storage])
203+ final String gid = groupUUID .toString ();
204+ final String plugin = group .ownerPlugin ;
205+
206+ try (PreparedStatement delItems = conn .prepareStatement (
207+ "DELETE FROM inventory_item_table WHERE group_uuid=? AND plugin_name=?" );
208+ PreparedStatement delTags = conn .prepareStatement (
209+ "DELETE FROM tag_table WHERE group_uuid=? AND plugin_name=?" );
210+ PreparedStatement delPages = conn .prepareStatement (
211+ "DELETE FROM inventory_table WHERE group_uuid=? AND plugin_name=?" );
212+ PreparedStatement delStorage = conn .prepareStatement ( // ← storage も入れ替える場合のみ
213+ "DELETE FROM storage_table WHERE group_uuid=? AND plugin_name=?" )) {
214+
215+ // 子 → 親(items → tags → pages → storage)の順で削除
216+ delItems .setString (1 , gid ); delItems .setString (2 , plugin ); delItems .executeUpdate ();
217+ delTags .setString (1 , gid ); delTags .setString (2 , plugin ); delTags .executeUpdate ();
218+ delPages .setString (1 , gid ); delPages .setString (2 , plugin ); delPages .executeUpdate ();
219+ delStorage .setString (1 , gid ); delStorage .setString (2 , plugin ); delStorage .executeUpdate (); // 不要なら削除
220+ }
221+
200222 // 3. 差分ログを snapshot → targetTime に適用
201223 boolean success = applyForwardDiffs (group , snapshotTime , targetTime );
202224
@@ -209,6 +231,7 @@ public static boolean restoreGroupToTimestamp(UUID groupUUID, LocalDateTime targ
209231
210232 } catch (Exception e ) {
211233 Bukkit .getLogger ().warning ("[BetterStorage] 巻き戻しに失敗: " + e .getMessage ());
234+ Bukkit .getLogger ().info ("復元中..." );
212235 return false ;
213236 }
214237 }
@@ -269,21 +292,23 @@ public static boolean applyForwardDiffs(GroupData groupData, LocalDateTime from,
269292 ps .setString (2 , groupData .ownerPlugin );
270293 ps .setString (3 , from .format (FORMATTER ));
271294 ps .setString (4 , to .format (FORMATTER ));
272-
295+ Bukkit . getLogger (). info ( "aiauwdh" );
273296 try (ResultSet rs = ps .executeQuery ()) {
297+ Bukkit .getLogger ().info ("ha?!" );
274298 while (rs .next ()) {
275299 String pageId = rs .getString ("page_id" );
276300 String op = rs .getString ("operation_type" );
277301 String metaJson = null ;
278302 try { metaJson = rs .getString ("meta_json" ); } catch (SQLException ignore ) {}
279-
303+ Bukkit . getLogger (). info ( "ayag!" );
280304 switch (op ) {
281305 case "PAGE_CREATE" : {
282306 ensurePagePresentOrCreate (groupData , pageId );
283307 break ;
284308 }
285309 case "PAGE_DELETE" : {
286310 groupData .storageData .storageInventory .remove (pageId );
311+ Bukkit .getLogger ().info ("削除!" );
287312 break ;
288313 }
289314 case "PAGE_META" : { // 任意:rows は final なら再生成 or 後でDBから拾う
@@ -336,26 +361,28 @@ public static boolean applyForwardDiffs(GroupData groupData, LocalDateTime from,
336361 while (rs .next ()) {
337362 String pageId = rs .getString ("page_id" );
338363 int slot = rs .getInt ("slot" );
339- String base64 = rs .getString ("itemstack" );
340- String timestampStr = rs .getString ("timestamp" );
341-
342- ItemStack item = ItemSerializer .deserializeFromBase64 (base64 );
343-
344- InventoryData inv = groupData .storageData .storageInventory .get (pageId );
345- if (inv != null && inv .itemStackSlot != null ) {
346- if (item == null || item .getType () == Material .AIR ) {
347- inv .itemStackSlot .remove (slot );
348- } else {
349- inv .itemStackSlot .put (slot , item );
364+ if (slot != -1 ){
365+ String base64 = rs .getString ("itemstack" );
366+ String timestampStr = rs .getString ("timestamp" );
367+
368+ ItemStack item = ItemSerializer .deserializeFromBase64 (base64 );
369+
370+ InventoryData inv = groupData .storageData .storageInventory .get (pageId );
371+ if (inv != null && inv .itemStackSlot != null ) {
372+ if (item == null || item .getType () == Material .AIR ) {
373+ inv .itemStackSlot .remove (slot );
374+ } else {
375+ inv .itemStackSlot .put (slot , item );
376+ }
350377 }
351- }
352378
353- // 差分適用された timestamp を記録
354- try {
355- LocalDateTime appliedTime = LocalDateTime .parse (timestampStr , FORMATTER );
356- appliedTimestamps .add (appliedTime );
357- } catch (Exception e ) {
358- Bukkit .getLogger ().warning ("timestampのパースに失敗: " + timestampStr );
379+ // 差分適用された timestamp を記録
380+ try {
381+ LocalDateTime appliedTime = LocalDateTime .parse (timestampStr , FORMATTER );
382+ appliedTimestamps .add (appliedTime );
383+ } catch (Exception e ) {
384+ Bukkit .getLogger ().warning ("timestampのパースに失敗: " + timestampStr );
385+ }
359386 }
360387 }
361388 }
@@ -597,7 +624,7 @@ private static Map<Integer, ItemStack> loadLatestLoggedItems(Connection conn, St
597624 int slot = rs .getInt ("slot" );
598625 String operationType = rs .getString ("operation_type" );
599626
600- if (seenSlots .contains (slot )) {
627+ if (seenSlots .contains (slot )|| slot == - 1 ) {
601628 continue ;
602629 }
603630 seenSlots .add (slot );
0 commit comments