Skip to content

Commit 37fc4ce

Browse files
committed
ログ記録機能追加
1 parent eb22e39 commit 37fc4ce

File tree

5 files changed

+176
-96
lines changed

5 files changed

+176
-96
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>dev.felnull</groupId>
88
<artifactId>BetterStorage</artifactId>
9-
<version>1.0.6</version>
9+
<version>1.0.7-SNAPSHOT</version>
1010
<packaging>jar</packaging>
1111

1212
<name>BetterStorage</name>

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

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import dev.felnull.Data.InventoryData;
88
import dev.felnull.Data.StorageData;
99
import org.bukkit.Bukkit;
10+
import org.bukkit.Material;
1011
import org.bukkit.OfflinePlayer;
1112
import org.bukkit.inventory.ItemStack;
1213

@@ -74,7 +75,6 @@ public static boolean saveGroupData(GroupData g, long clientVersion) {
7475

7576
// 成功したので差分ログを保存
7677
DiffLogManager.saveDiffLogs(BetterStorage.BSPlugin.getDatabaseManager(), g);
77-
Bukkit.getLogger().info("保存成功らしい");
7878
return true;
7979
} catch (SQLException e) {
8080
Bukkit.getLogger().warning("GroupDataの保存に失敗: " + e.getMessage());
@@ -96,57 +96,78 @@ private static void saveSinglePage(Connection conn, GroupData g, String pageId,
9696
}
9797

9898
// ---------- inventory_item_table ----------
99-
// 🔥 1. 既存スロットを取得
100-
Set<Integer> currentSlots = inv.itemStackSlot.keySet();
101-
Set<Integer> oldSlots = new HashSet<>();
102-
String fetchSql = "SELECT slot FROM inventory_item_table WHERE group_uuid = ? AND page_id = ?";
99+
// 🔥 1. 既存スロットとitemstack取得
100+
Map<Integer, String> oldSlotBase64Map = new HashMap<>();
101+
String fetchSql = "SELECT slot, itemstack FROM inventory_item_table WHERE group_uuid = ? AND page_id = ?";
103102
try (PreparedStatement ps = conn.prepareStatement(fetchSql)) {
104103
ps.setString(1, g.groupUUID.toString());
105104
ps.setString(2, pageId);
106105
try (ResultSet rs = ps.executeQuery()) {
107106
while (rs.next()) {
108-
oldSlots.add(rs.getInt("slot"));
107+
oldSlotBase64Map.put(rs.getInt("slot"), rs.getString("itemstack"));
109108
}
110109
}
111110
}
112111

113-
// 🔥 2. 削除されたスロットを DELETE
114-
if (!oldSlots.isEmpty()) {
115-
Set<Integer> slotsToDelete = new HashSet<>(oldSlots);
116-
slotsToDelete.removeAll(currentSlots);
117-
118-
if (!slotsToDelete.isEmpty()) {
119-
StringBuilder sb = new StringBuilder();
120-
sb.append("DELETE FROM inventory_item_table WHERE group_uuid = ? AND page_id = ? AND slot IN (");
121-
sb.append(slotsToDelete.stream().map(s -> "?").collect(Collectors.joining(",")));
122-
sb.append(")");
112+
Set<Integer> currentSlots = inv.itemStackSlot.keySet();
123113

124-
try (PreparedStatement ps = conn.prepareStatement(sb.toString())) {
125-
ps.setString(1, g.groupUUID.toString());
126-
ps.setString(2, pageId);
127-
int index = 3;
128-
for (Integer slot : slotsToDelete) {
129-
ps.setInt(index++, slot);
130-
}
131-
ps.executeUpdate();
114+
// 🔥 2. 削除されたスロットを DELETE & ログ記録
115+
Set<Integer> slotsToDelete = new HashSet<>(oldSlotBase64Map.keySet());
116+
slotsToDelete.removeAll(currentSlots);
117+
if (!slotsToDelete.isEmpty()) {
118+
StringBuilder sb = new StringBuilder();
119+
sb.append("DELETE FROM inventory_item_table WHERE group_uuid = ? AND page_id = ? AND slot IN (");
120+
sb.append(slotsToDelete.stream().map(s -> "?").collect(Collectors.joining(",")));
121+
sb.append(")");
122+
try (PreparedStatement ps = conn.prepareStatement(sb.toString())) {
123+
ps.setString(1, g.groupUUID.toString());
124+
ps.setString(2, pageId);
125+
int index = 3;
126+
for (Integer slot : slotsToDelete) {
127+
ps.setInt(index++, slot);
132128
}
129+
ps.executeUpdate();
130+
}
131+
132+
for (int slot : slotsToDelete) {
133+
ItemStack dummy = new ItemStack(Material.AIR); // ログ用にダミー
134+
logInventoryItemChangeAsync(BetterStorage.BSPlugin.getDatabaseManager(),
135+
g.groupUUID, g.ownerPlugin, pageId, slot, OperationType.REMOVE, dummy);
133136
}
134137
}
135138

136-
// 🔥 3. 現在のアイテムを REPLACE
139+
// 🔥 3. 追加・更新されたスロットを REPLACE & ログ記録
137140
String itemSql = "REPLACE INTO inventory_item_table (group_uuid, plugin_name, page_id, slot, itemstack, display_name, material, amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
138141
try (PreparedStatement ps = conn.prepareStatement(itemSql)) {
139142
for (Map.Entry<Integer, ItemStack> itemEntry : inv.itemStackSlot.entrySet()) {
143+
int slot = itemEntry.getKey();
140144
ItemStack item = itemEntry.getValue();
145+
String serialized = ItemSerializer.serializeToBase64(item);
146+
147+
boolean isNew = !oldSlotBase64Map.containsKey(slot);
148+
boolean isChanged = false;
149+
if (!isNew) {
150+
String oldBase64 = oldSlotBase64Map.get(slot);
151+
isChanged = !Objects.equals(serialized, oldBase64);
152+
}
153+
154+
if (!isNew && !isChanged) continue; // 差分なし
155+
156+
// DB書き込み
141157
ps.setString(1, g.groupUUID.toString());
142158
ps.setString(2, g.ownerPlugin);
143159
ps.setString(3, pageId);
144-
ps.setInt(4, itemEntry.getKey());
145-
ps.setString(5, ItemSerializer.serializeToBase64(item));
160+
ps.setInt(4, slot);
161+
ps.setString(5, serialized);
146162
ps.setString(6, item.hasItemMeta() ? item.getItemMeta().getDisplayName() : "");
147163
ps.setString(7, item.getType().name());
148164
ps.setInt(8, item.getAmount());
149165
ps.addBatch();
166+
167+
// ログ
168+
logInventoryItemChangeAsync(BetterStorage.BSPlugin.getDatabaseManager(),
169+
g.groupUUID, g.ownerPlugin, pageId, slot,
170+
isNew ? OperationType.ADD : OperationType.UPDATE, item);
150171
}
151172
ps.executeBatch();
152173
}
@@ -656,7 +677,41 @@ public static void deleteGroupData(Connection conn, UUID groupUUID, String plugi
656677
// ===== 4. LOG =============================================
657678
// ===========================================================
658679

659-
public static void logInventoryItemChange(Connection conn, UUID groupUUID, String pluginName, String pageId, int slot, String op, ItemStack item) throws SQLException {
680+
public static void logInventoryItemChangeAsync(DatabaseManager db, UUID groupUUID, String pluginName, String pageId, int slot, OperationType op, ItemStack item) {
681+
// 削除操作ならAIRでも保存する
682+
boolean isRemove = (op == OperationType.REMOVE);
683+
684+
// nullやAIRを除外(ただし削除は除外しない)
685+
if (item == null || (!isRemove && item.getType() == Material.AIR)) return;
686+
687+
String serializedItem = ItemSerializer.serializeToBase64(item);
688+
String displayName = item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : "";
689+
String material = item.getType().name();
690+
int amount = item.getAmount();
691+
692+
Bukkit.getScheduler().runTaskAsynchronously(BetterStorage.BSPlugin, () -> {
693+
try (Connection conn = db.getConnection()) {
694+
try (PreparedStatement ps = conn.prepareStatement(
695+
"INSERT INTO inventory_item_log (group_uuid, plugin_name, page_id, slot, operation_type, itemstack, display_name, material, amount, timestamp) " +
696+
"VALUES (?,?,?,?,?,?,?,?,?,NOW())")) {
697+
ps.setString(1, groupUUID.toString());
698+
ps.setString(2, pluginName);
699+
ps.setString(3, pageId);
700+
ps.setInt(4, slot);
701+
ps.setString(5, op.toDbString());
702+
ps.setString(6, serializedItem);
703+
ps.setString(7, displayName);
704+
ps.setString(8, material);
705+
ps.setInt(9, amount);
706+
ps.executeUpdate();
707+
}
708+
} catch (SQLException e) {
709+
Bukkit.getLogger().warning("[BetterStorage] 非同期ログ保存失敗: " + e.getMessage());
710+
}
711+
});
712+
}
713+
714+
private static void logInventoryItemChange(Connection conn, UUID groupUUID, String pluginName, String pageId, int slot, String op, ItemStack item) throws SQLException {
660715
try (PreparedStatement ps = conn.prepareStatement(
661716
"INSERT INTO inventory_item_log (group_uuid, plugin_name, page_id, slot, operation_type, itemstack, display_name, material, amount, timestamp) VALUES (?,?,?,?,?,?,?,?,?,NOW())")) {
662717
ps.setString(1, groupUUID.toString());
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package dev.felnull.DataIO;
2+
3+
public enum OperationType {
4+
ADD,
5+
REMOVE,
6+
UPDATE,
7+
CLEAR,
8+
MOVE;
9+
10+
/**
11+
* データベースに保存する文字列形式を取得(必要なら小文字にしても可)
12+
*/
13+
public String toDbString() {
14+
return this.name(); // 大文字で保存される(例: "ADD")
15+
}
16+
17+
/**
18+
* 文字列から enum に変換(安全な読み込み用)
19+
*/
20+
public static OperationType fromDbString(String s) {
21+
return OperationType.valueOf(s.toUpperCase());
22+
}
23+
}

0 commit comments

Comments
 (0)