Skip to content

Commit e179cd9

Browse files
committed
invdataとstoragedataのcloneメソッドを追加
1 parent f8dd8c8 commit e179cd9

File tree

3 files changed

+146
-116
lines changed

3 files changed

+146
-116
lines changed

src/main/java/dev/felnull/Data/InventoryData.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,20 @@ public void setFullyLoaded(boolean fullyLoaded) {
5151
public boolean isFullyLoaded() {
5252
return fullyLoaded;
5353
}
54+
55+
public InventoryData deepClone() {
56+
InventoryData clone = new InventoryData(this.displayName, this.rows,
57+
new HashSet<>(this.requirePermission),
58+
new HashMap<>()); // itemStackSlotは後でコピー
59+
60+
// ItemStackを安全にコピー(浅いコピーで十分ならそのまま)
61+
for (Map.Entry<Integer, ItemStack> entry : this.itemStackSlot.entrySet()) {
62+
clone.itemStackSlot.put(entry.getKey(), entry.getValue().clone()); // deep copy推奨
63+
}
64+
65+
clone.userTags = new ArrayList<>(this.userTags);
66+
clone.version = this.version;
67+
clone.fullyLoaded = this.fullyLoaded;
68+
return clone;
69+
}
5470
}

src/main/java/dev/felnull/Data/StorageData.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55

66
import java.sql.Connection;
77
import java.sql.SQLException;
8-
import java.util.HashMap;
9-
import java.util.Map;
10-
import java.util.Set;
11-
import java.util.UUID;
8+
import java.util.*;
129

1310
public class StorageData {
1411
public UUID groupUUID; // ← UUIDベースに変更
@@ -81,5 +78,20 @@ public void updateInventoryData(String pageId) {
8178
public InventoryData getInventoryData(String pageId) {
8279
return storageInventory.get(pageId);
8380
}
81+
public StorageData deepClone() {
82+
Map<String, InventoryData> clonedInventoryMap = new HashMap<>();
83+
for (Map.Entry<String, InventoryData> entry : this.storageInventory.entrySet()) {
84+
clonedInventoryMap.put(entry.getKey(), entry.getValue().deepClone());
85+
}
86+
87+
// Setはimmutableじゃないと事故るのでコピー
88+
Set<String> clonedRequirePerm = new HashSet<>(this.requireBankPermission);
89+
90+
StorageData clone = new StorageData(clonedRequirePerm, clonedInventoryMap, this.bankMoney);
91+
clone.groupUUID = this.groupUUID; // UUIDは共有で問題なし
92+
clone.fullyLoaded = this.fullyLoaded; // 同期状態も継承
93+
94+
return clone;
95+
}
8496
}
8597

src/main/java/dev/felnull/DataIO/DataIO.java

Lines changed: 114 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -29,50 +29,55 @@ public class DataIO {
2929
// ===== 1. SAVE ============================================
3030
// ===========================================================
3131

32-
/** グループ全体を保存(各テーブルへの分割保存) */
33-
public static boolean saveGroupData(GroupData g) {
34-
try (Connection conn = db.getConnection()) {
35-
// group_table
36-
saveGroupTable(conn, g);
37-
saveGroupMembers(conn, g);
32+
/** グループ全体を保存(各テーブルへの分割保存) */
33+
public static boolean saveGroupData(GroupData g) {
34+
try (Connection conn = db.getConnection()) {
35+
// group_table
36+
saveGroupTable(conn, g);
37+
saveGroupMembers(conn, g);
3838

39-
if (g.storageData != null) {
40-
saveStorageData(conn, g);
39+
if (g.storageData != null) {
40+
saveStorageData(conn, g);
4141

42-
for (Map.Entry<String, InventoryData> entry : g.storageData.storageInventory.entrySet()) {
43-
String pageId = entry.getKey();
44-
InventoryData inv = entry.getValue();
42+
for (Map.Entry<String, InventoryData> entry : g.storageData.storageInventory.entrySet()) {
43+
String pageId = entry.getKey();
44+
InventoryData inv = entry.getValue();
4545

46-
if (!inv.isFullyLoaded()) {
47-
Bukkit.getLogger().info("[BetterStorage] スキップ: " + g.groupName + "/" + pageId + " は未完全のため保存されません");
48-
continue;
49-
}
46+
if (!inv.isFullyLoaded()) {
47+
Bukkit.getLogger().info("[BetterStorage] スキップ: " + g.groupName + "/" + pageId + " は未完全のため保存されません");
48+
continue;
49+
}
5050

51-
if (!saveSinglePage(conn, g, pageId, inv)) {
52-
return false; // ここで失敗通知
51+
if (!saveSinglePage(conn, g, pageId, inv)) {
52+
return false; // ここで失敗通知
53+
}
5354
}
5455
}
55-
}
5656

57-
// 差分ログを保存
58-
UnifiedLogManager.saveDiffLogs(BetterStorage.BSPlugin.getDatabaseManager(), g);
59-
return true;
57+
// 差分ログを保存
58+
UnifiedLogManager.saveDiffLogs(BetterStorage.BSPlugin.getDatabaseManager(), g);
59+
return true;
6060

61-
} catch (SQLException e) {
62-
Bukkit.getLogger().warning("GroupDataの保存に失敗: " + e.getMessage());
63-
return false;
61+
} catch (SQLException e) {
62+
Bukkit.getLogger().warning("GroupDataの保存に失敗: " + e.getMessage());
63+
return false;
64+
}
6465
}
65-
}
6666

6767
private static boolean saveSinglePage(Connection conn, GroupData g, String pageId, InventoryData inv) throws SQLException {
6868
// 🔁 versionチェック
6969
long dbPageVersion = getInventoryPageVersion(conn, g.groupUUID, g.ownerPlugin, pageId);
70-
Bukkit.getLogger().info("[Debug] pageId=" + pageId + ", client=" + inv.version + ", db=" + dbPageVersion);
71-
if (dbPageVersion != 0 && dbPageVersion != inv.version) {
70+
Bukkit.getLogger().info("[Debug]保存前最終チェック pageId=" + pageId + ", client=" + inv.version + ", db=" + dbPageVersion);
71+
72+
if (dbPageVersion != inv.version) {
7273
Bukkit.getLogger().warning("[BetterStorage] ページバージョン不一致: " + pageId);
7374
return false;
7475
}
7576

77+
// ✅ 楽観ロック:保存前に version を進める
78+
inv.version++;
79+
80+
Bukkit.getLogger().info("[Debug]この内容で保存します pageId=" + pageId + ", client=" + inv.version + ", db=" + dbPageVersion);
7681

7782
// ---------- inventory_table ----------
7883
String invSql = "REPLACE INTO inventory_table " +
@@ -85,13 +90,11 @@ private static boolean saveSinglePage(Connection conn, GroupData g, String pageI
8590
ps.setString(4, inv.displayName);
8691
ps.setInt(5, inv.rows);
8792
ps.setString(6, gson.toJson(inv.requirePermission));
88-
ps.setLong(7, inv.version);
93+
ps.setLong(7, inv.version); // 新しいバージョンで保存
8994
ps.executeUpdate();
9095
}
9196

92-
9397
// ---------- inventory_item_table ----------
94-
// 🔥 1. 既存スロットとitemstack取得
9598
Map<Integer, String> oldSlotBase64Map = new HashMap<>();
9699
String fetchSql = "SELECT slot, itemstack FROM inventory_item_table WHERE group_uuid = ? AND page_id = ?";
97100
try (PreparedStatement ps = conn.prepareStatement(fetchSql)) {
@@ -106,7 +109,7 @@ private static boolean saveSinglePage(Connection conn, GroupData g, String pageI
106109

107110
Set<Integer> currentSlots = inv.itemStackSlot.keySet();
108111

109-
// 🔥 2. 削除されたスロットを DELETE & ログ記録
112+
// 削除されたスロット
110113
Set<Integer> slotsToDelete = new HashSet<>(oldSlotBase64Map.keySet());
111114
slotsToDelete.removeAll(currentSlots);
112115
if (!slotsToDelete.isEmpty()) {
@@ -131,7 +134,7 @@ private static boolean saveSinglePage(Connection conn, GroupData g, String pageI
131134
}
132135
}
133136

134-
// 🔥 3. 追加・更新されたスロットを REPLACE & ログ記録
137+
// 追加・更新スロット
135138
String itemSql = "REPLACE INTO inventory_item_table (group_uuid, plugin_name, page_id, slot, itemstack, display_name, display_name_plain, material, amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
136139
try (PreparedStatement ps = conn.prepareStatement(itemSql)) {
137140
for (Map.Entry<Integer, ItemStack> itemEntry : inv.itemStackSlot.entrySet()) {
@@ -169,7 +172,6 @@ private static boolean saveSinglePage(Connection conn, GroupData g, String pageI
169172
ps.executeBatch();
170173
}
171174

172-
173175
// ---------- tag_table ----------
174176
String tagSql = "REPLACE INTO tag_table (group_uuid, plugin_name, page_id, user_tag) VALUES (?, ?, ?, ?)";
175177
try (PreparedStatement ps = conn.prepareStatement(tagSql)) {
@@ -185,110 +187,110 @@ private static boolean saveSinglePage(Connection conn, GroupData g, String pageI
185187
}
186188
}
187189

188-
inv.version = dbPageVersion + 1;
189190
return true;
190191
}
191192

192193

193194

195+
194196
// ---------- SAVE / group ----------
195-
private static void saveGroupTable(Connection conn, GroupData g) throws SQLException {
196-
String sql = "REPLACE INTO group_table (group_uuid, group_name, display_name, is_private, owner_plugin) VALUES (?, ?, ?, ?, ?)";
197-
try (PreparedStatement ps = conn.prepareStatement(sql)) {
198-
ps.setString(1, g.groupUUID.toString());
199-
ps.setString(2, g.groupName);
200-
ps.setString(3, g.displayName);
201-
ps.setBoolean(4, g.isPrivate);
202-
ps.setString(5, g.ownerPlugin);
203-
ps.executeUpdate();
197+
private static void saveGroupTable(Connection conn, GroupData g) throws SQLException {
198+
String sql = "REPLACE INTO group_table (group_uuid, group_name, display_name, is_private, owner_plugin) VALUES (?, ?, ?, ?, ?)";
199+
try (PreparedStatement ps = conn.prepareStatement(sql)) {
200+
ps.setString(1, g.groupUUID.toString());
201+
ps.setString(2, g.groupName);
202+
ps.setString(3, g.displayName);
203+
ps.setBoolean(4, g.isPrivate);
204+
ps.setString(5, g.ownerPlugin);
205+
ps.executeUpdate();
206+
}
204207
}
205-
}
206208

207-
private static void saveGroupMembers(Connection conn, GroupData g) throws SQLException {
208-
String sql = "REPLACE INTO group_member_table (group_uuid, member_uuid, role) VALUES (?, ?, ?)";
209-
try (PreparedStatement ps = conn.prepareStatement(sql)) {
210-
for (OfflinePlayer member : g.playerList) {
211-
String[] roles = g.playerPermission.get(member);
212-
if (roles != null) {
213-
for (String role : roles) {
214-
ps.setString(1, g.groupUUID.toString());
215-
ps.setString(2, member.getUniqueId().toString());
216-
ps.setString(3, role);
217-
ps.addBatch();
209+
private static void saveGroupMembers(Connection conn, GroupData g) throws SQLException {
210+
String sql = "REPLACE INTO group_member_table (group_uuid, member_uuid, role) VALUES (?, ?, ?)";
211+
try (PreparedStatement ps = conn.prepareStatement(sql)) {
212+
for (OfflinePlayer member : g.playerList) {
213+
String[] roles = g.playerPermission.get(member);
214+
if (roles != null) {
215+
for (String role : roles) {
216+
ps.setString(1, g.groupUUID.toString());
217+
ps.setString(2, member.getUniqueId().toString());
218+
ps.setString(3, role);
219+
ps.addBatch();
220+
}
218221
}
219222
}
223+
ps.executeBatch();
220224
}
221-
ps.executeBatch();
222225
}
223-
}
224226

225-
// ---------- SAVE / storage ----------
226-
private static void saveStorageData(Connection conn, GroupData g) throws SQLException {
227-
StorageData s = g.storageData;
228-
String sql = "REPLACE INTO storage_table (group_uuid, plugin_name, bank_money, require_bank_permission) VALUES (?, ?, ?, ?)";
229-
try (PreparedStatement ps = conn.prepareStatement(sql)) {
230-
ps.setString(1, g.groupUUID.toString());
231-
ps.setString(2, g.ownerPlugin);
232-
ps.setDouble(3, s.bankMoney);
233-
ps.setString(4, gson.toJson(s.requireBankPermission));
234-
ps.executeUpdate();
227+
// ---------- SAVE / storage ----------
228+
private static void saveStorageData(Connection conn, GroupData g) throws SQLException {
229+
StorageData s = g.storageData;
230+
String sql = "REPLACE INTO storage_table (group_uuid, plugin_name, bank_money, require_bank_permission) VALUES (?, ?, ?, ?)";
231+
try (PreparedStatement ps = conn.prepareStatement(sql)) {
232+
ps.setString(1, g.groupUUID.toString());
233+
ps.setString(2, g.ownerPlugin);
234+
ps.setDouble(3, s.bankMoney);
235+
ps.setString(4, gson.toJson(s.requireBankPermission));
236+
ps.executeUpdate();
237+
}
235238
}
236-
}
237239

238-
public static boolean saveInventoryOnly(GroupData g, StorageData storageData, String pageId) {
239-
try (Connection conn = db.getConnection()) {
240-
InventoryData inv = storageData.storageInventory.get(pageId);
241-
storageData.groupUUID = g.groupUUID;
242-
g.storageData = storageData;
243-
if (inv == null) {
244-
Bukkit.getLogger().warning("インベントリが空のままセーブしようとしたため失敗しました");
245-
return false;
246-
}
240+
public static boolean saveInventoryOnly(GroupData g, StorageData storageData, String pageId) {
241+
try (Connection conn = db.getConnection()) {
242+
InventoryData inv = storageData.storageInventory.get(pageId);
243+
storageData.groupUUID = g.groupUUID;
244+
g.storageData = storageData;
245+
if (inv == null) {
246+
Bukkit.getLogger().warning("インベントリが空のままセーブしようとしたため失敗しました");
247+
return false;
248+
}
247249

248-
if (!inv.isFullyLoaded()) {
249-
Bukkit.getLogger().warning("ロードされていないデータをセーブしようとしました");
250-
g.storageData.loadPage(conn, g.ownerPlugin, pageId);
251-
inv = g.storageData.storageInventory.get(pageId);
252-
}
250+
if (!inv.isFullyLoaded()) {
251+
Bukkit.getLogger().warning("ロードされていないデータをセーブしようとしました");
252+
g.storageData.loadPage(conn, g.ownerPlugin, pageId);
253+
inv = g.storageData.storageInventory.get(pageId);
254+
}
253255

254-
long dbPageVersion = getInventoryPageVersion(conn, g.groupUUID, g.ownerPlugin, pageId);
255-
if (dbPageVersion != inv.version) {
256-
Bukkit.getLogger().warning("[BetterStorage]Error:InventoryDataVersion不一致:" + g.groupName);
257-
Bukkit.getLogger().warning("[BetterStorage]DB上のVer:" + dbPageVersion + "保存しようとしたVer:" + inv.version);
258-
return false;
259-
}
256+
long dbPageVersion = getInventoryPageVersion(conn, g.groupUUID, g.ownerPlugin, pageId);
257+
if (dbPageVersion != inv.version) {
258+
Bukkit.getLogger().warning("[BetterStorage]Error:InventoryDataVersion不一致:" + g.groupName);
259+
Bukkit.getLogger().warning("[BetterStorage]DB上のVer:" + dbPageVersion + "保存しようとしたVer:" + inv.version);
260+
return false;
261+
}
260262

261-
saveSinglePage(conn, g, pageId, inv);
262-
saveGroupTable(conn, g); // group_tableは必須(versionが無くても更新してOK)
263+
saveSinglePage(conn, g, pageId, inv);
264+
saveGroupTable(conn, g); // group_tableは必須(versionが無くても更新してOK)
263265

264-
UnifiedLogManager.saveDiffLogs(BetterStorage.BSPlugin.getDatabaseManager(), g);
265-
return true;
266-
} catch (SQLException e) {
267-
Bukkit.getLogger().warning("Inventory保存失敗: " + e.getMessage());
268-
return false;
266+
UnifiedLogManager.saveDiffLogs(BetterStorage.BSPlugin.getDatabaseManager(), g);
267+
return true;
268+
} catch (SQLException e) {
269+
Bukkit.getLogger().warning("Inventory保存失敗: " + e.getMessage());
270+
return false;
271+
}
269272
}
270-
}
271273

272-
private static void saveTags(Connection conn, GroupData g) throws SQLException {
273-
String sql = "REPLACE INTO tag_table (group_uuid, plugin_name, page_id, user_tag) VALUES (?, ?, ?, ?)";
274-
try (PreparedStatement ps = conn.prepareStatement(sql)) {
275-
for (Map.Entry<String, InventoryData> entry : g.storageData.storageInventory.entrySet()) {
276-
String pageId = entry.getKey();
277-
List<String> tags = entry.getValue().userTags;
278-
279-
if (tags != null && !tags.isEmpty()) {
280-
for (String tag : tags) {
281-
ps.setString(1, g.groupUUID.toString());
282-
ps.setString(2, g.ownerPlugin);
283-
ps.setString(3, pageId);
284-
ps.setString(4, tag);
285-
ps.addBatch();
274+
private static void saveTags(Connection conn, GroupData g) throws SQLException {
275+
String sql = "REPLACE INTO tag_table (group_uuid, plugin_name, page_id, user_tag) VALUES (?, ?, ?, ?)";
276+
try (PreparedStatement ps = conn.prepareStatement(sql)) {
277+
for (Map.Entry<String, InventoryData> entry : g.storageData.storageInventory.entrySet()) {
278+
String pageId = entry.getKey();
279+
List<String> tags = entry.getValue().userTags;
280+
281+
if (tags != null && !tags.isEmpty()) {
282+
for (String tag : tags) {
283+
ps.setString(1, g.groupUUID.toString());
284+
ps.setString(2, g.ownerPlugin);
285+
ps.setString(3, pageId);
286+
ps.setString(4, tag);
287+
ps.addBatch();
288+
}
286289
}
287290
}
291+
ps.executeBatch();
288292
}
289-
ps.executeBatch();
290293
}
291-
}
292294
// ===========================================================
293295
// ===== 2. LOAD ============================================
294296
// ===========================================================

0 commit comments

Comments
 (0)