Skip to content
Closed
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,8 @@ CLAUDE.md
## run-paper test server
##############################
run/

##############################
## Internal design notes (not shipped)
##############################
STORAGE_REDESIGN.md
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,22 @@ All notable changes to SmartSpawner are documented in this file.
- Sulfur Cube spawner support for servers on Minecraft 26.2. Its spawner drops no items and gives 2 experience.

### Changed
- The storage menu now works like a normal chest. Items can be picked up, shift-clicked and dragged out with the usual controls. Items still cannot be placed into storage.
- Only one player can open a spawner's storage at a time. Anyone who tries to open it while another player is inside is told it is in use, and can open it once that player leaves.
- Items in the storage menu keep their position while it is open. New drops fill empty spaces from the top instead of rearranging everything.
- Storage capacity is now set in slots instead of pages. See the details below.
- Happy Ghast, Copper Golem and Sulfur Cube now show a translated name in every language.

### Notes
- Existing spawner data is read and upgraded automatically. No action is required.

<details>
<summary>Configuration file details</summary>

- `spawner_properties.default.max_storage_pages` became `max_storage_slots`. Existing values are converted automatically, one page to 45 slots.

</details>

## 1.8.1

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ tasks.build {


tasks.runServer {
minecraftVersion("26.1.2")
minecraftVersion("26.2")
runDirectory.set(rootProject.layout.projectDirectory.dir("run"))
// Minecraft bundles JOML 1.10.8, whose Unsafe path is deprecated on Java 25.
// Prefer JOML's NIO implementation and allow remaining upstream users (such as spark)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ preferred_sort_item VARCHAR(64) DEFAULT NULL,
-- Virtual inventory, see SpawnerInventoryCodec
storage_items MEDIUMBLOB DEFAULT NULL,

-- Optimistic-concurrency revision, bumped on every write (schema v5). Detects a
-- foreign writer (another server, a manual DB edit) surviving across a flush cycle.
rev BIGINT NOT NULL DEFAULT 0,

-- Indexes. The table is one server's data, so none of these carry a server name.
UNIQUE KEY uk_spawner (spawner_id),
UNIQUE KEY uk_location (world, loc_x, loc_y, loc_z),
Expand Down Expand Up @@ -202,6 +206,9 @@ preferred_sort_item VARCHAR(64) DEFAULT NULL,
-- Virtual inventory, see SpawnerInventoryCodec
storage_items BLOB DEFAULT NULL,

-- Optimistic-concurrency revision, bumped on every write (schema v5)
rev BIGINT NOT NULL DEFAULT 0,

-- Unique constraints
UNIQUE (spawner_id),
UNIQUE (world, loc_x, loc_y, loc_z)
Expand All @@ -217,7 +224,7 @@ preferred_sort_item VARCHAR(64) DEFAULT NULL,

private static final String SCHEMA_VERSION_KEY = "schema_version";
private static final int LEGACY_SCHEMA_VERSION = 1;
private static final int CURRENT_SCHEMA_VERSION = 4;
private static final int CURRENT_SCHEMA_VERSION = 5;

/** Rows converted per transaction while rewriting inventories during the v3 migration. */
private static final int MIGRATION_BATCH_SIZE = 250;
Expand Down Expand Up @@ -557,7 +564,7 @@ private void runSchemaMigrations() throws SQLException {
entity_type, itemspawner_type, stack_size, max_stack_size,
active, stop, activation_range, delay, last_spawn_time, min_mobs, max_mobs,
max_loot_slots, is_at_capacity, total_items, exp, max_stored_exp,
last_interacted_player, preferred_sort_item, filtered_items, storage_items
last_interacted_player, preferred_sort_item, filtered_items, storage_items, rev
""";

/**
Expand Down Expand Up @@ -697,6 +704,9 @@ private Integer getSchemaVersionFromMeta() throws SQLException {
}

private int detectInitialSchemaVersion() throws SQLException {
if (columnExists(tableSpawners, "rev")) {
return 5;
}
if (columnExists(tableSpawners, "config_name")) {
return 4;
}
Expand Down Expand Up @@ -724,6 +734,7 @@ private void applyMigrationStep(int targetVersion) throws SQLException {
case 2 -> migrateXpColumnsToBigIntIfNeeded();
case 3 -> migrateToChunkAndItemBlobColumns();
case 4 -> addColumnIfMissing("config_name", "VARCHAR(128) DEFAULT NULL");
case 5 -> addColumnIfMissing("rev", "BIGINT NOT NULL DEFAULT 0");
default -> throw new SQLException("No database migration handler found for schema version: " + targetVersion);
}
}
Expand Down
Loading
Loading