Skip to content

Fix data migration not executing when data_version is outdated#80

Merged
ptthanh02 merged 8 commits into
mainfrom
copilot/fix-smartspawner-migration-issue
Oct 25, 2025
Merged

Fix data migration not executing when data_version is outdated#80
ptthanh02 merged 8 commits into
mainfrom
copilot/fix-smartspawner-migration-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Oct 25, 2025

Fix data migration not executing when data_version exists but is outdated

Problem Analysis:
The migration was reporting "Successfully migrated 0 spawners" because version 2 data actually has 12 fields (not 11), but the migration code was only checking for exactly 11 fields. The old converter created 12 fields including allowEquipmentItems, but the migration logic was looking for 11 fields only.

Root Cause:

  • Version 2 data can have either 11 or 12 fields (12 if allowEquipmentItems was included)
  • Migration code was checking if (settings.length == 11) which never matched the actual data with 12 fields
  • This caused 0 spawners to be migrated even though 8359 spawners existed

Changes Made:

  • Updated constants to reflect version 2 can have 11-12 fields
  • Changed migration condition to check range: settings.length >= 11 && settings.length <= 12
  • Handle both 11-field and 12-field version 2 formats
  • Preserve allowEquipmentItems value as isAtCapacity when migrating 12-field format
  • Test the migration with actual data
  • Reply to user

Technical Details:
Modified SpawnerDataMigration.java:

  1. Changed VERSION_2_SETTINGS_FIELD_COUNT = 11 to VERSION_2_MIN_SETTINGS_FIELD_COUNT = 11 and VERSION_2_MAX_SETTINGS_FIELD_COUNT = 12
  2. Updated migration condition to accept 11-12 fields
  3. Added logic to preserve allowEquipmentItems (field 11 in 12-field version) as isAtCapacity when migrating

Migration Logic:

  • Version 2 (11 fields): exp,active,range,stop,delay,maxLoot,maxExp,minMobs,maxMobs,stack,lastSpawnTime
  • Version 2 (12 fields): exp,active,range,stop,delay,maxLoot,maxExp,minMobs,maxMobs,stack,lastSpawnTime,allowEquipmentItems
  • Version 3 (13 fields): exp,active,range,stop,delay,maxLoot,maxExp,minMobs,maxMobs,stack,maxStack,lastSpawnTime,isAtCapacity

The migration now inserts maxStackSize at position 10 and uses allowEquipmentItems (if present) for isAtCapacity.

Original prompt

[13:11:02 INFO]: Time elapsed: 405 ms
[13:11:02 INFO]: [SmartSpawner] Enabling SmartSpawner v1.5.4.3
[13:11:03 INFO]: [SmartSpawner] Running on standard Paper server.
[13:11:03 WARN]: [SmartSpawner] Vault not found! Selling items from spawner will be disabled.
[13:11:03 INFO]: [SmartSpawner] No compatible shop plugins found. Shop integration is disabled.
[13:11:03 INFO]: [SmartSpawner] Data version 2 detected. Current version is 3.
[13:11:03 INFO]: [SmartSpawner] A migration will be attempted when the plugin fully loads.
[13:11:03 INFO]: [SmartSpawner] Loaded storage GUI layout: default
[13:11:03 INFO]: [SmartSpawner] Loaded main GUI layout: default
[13:11:07 INFO]: [SmartSpawner] Initial spawner load complete. Loaded: 8359, Pending (missing worlds): 0
[13:11:07 INFO]: [SmartSpawner] SmartSpawner has been enabled! (Loaded in 5015ms)
[13:11:07 INFO]: [spark] Starting background profiler...
[13:11:07 INFO]: [spark] The async-profiler engine is not supported for your os/arch (windows11/amd64), so the built-in Java engine will be used instead.
[13:11:07 INFO]: Done preparing level "world" (50.408s)
[13:11:07 INFO]: Running delayed init tasks
[13:11:07 INFO]: Done (78.249s)! For help, type "help"

data không migrate kể cả khi plugin đã full load


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI self-assigned this Oct 25, 2025
@ptthanh02 ptthanh02 marked this pull request as ready for review October 25, 2025 06:27
Copilot AI and others added 3 commits October 25, 2025 06:31
Co-authored-by: ptthanh02 <73684260+ptthanh02@users.noreply.github.com>
Co-authored-by: ptthanh02 <73684260+ptthanh02@users.noreply.github.com>
Co-authored-by: ptthanh02 <73684260+ptthanh02@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix migration issue for SmartSpawner plugin Fix data migration not executing when data_version is outdated Oct 25, 2025
Copilot AI requested a review from ptthanh02 October 25, 2025 06:38
@ptthanh02
Copy link
Copy Markdown
Contributor

@copilot
[13:48:38 INFO]: [SmartSpawner] Enabling SmartSpawner v1.5.4.3
[13:48:39 INFO]: [SmartSpawner] Data version 2 is outdated. Current version is 3.
[13:48:39 INFO]: [SmartSpawner] Data structure is already in current format. Updating version flag...
[13:48:40 INFO]: [SmartSpawner] Running on standard Paper server.
[13:48:40 WARN]: [SmartSpawner] Vault not found! Selling items from spawner will be disabled.
[13:48:40 INFO]: [SmartSpawner] No compatible shop plugins found. Shop integration is disabled.
[13:48:40 INFO]: [SmartSpawner] Loaded storage GUI layout: default
[13:48:40 INFO]: [SmartSpawner] Loaded main GUI layout: default
[13:48:43 INFO]: [SmartSpawner] Initial spawner load complete. Loaded: 8359, Pending (missing worlds): 0
[13:48:43 INFO]: [SmartSpawner] SmartSpawner has been enabled! (Loaded in 4556ms)

But the data is not in the same struture you can check
https://github.com/NighterDevelopment/smartspawner/blob/4e33aaa957786bcb432b7850faaafdf8e92fb17e/core/src/main/java/github/nighter/smartspawner/spawner/utils/SpawnerFileHandler.java#L348

Copilot AI and others added 3 commits October 25, 2025 06:56
…nces

Co-authored-by: ptthanh02 <73684260+ptthanh02@users.noreply.github.com>
…ilding

Co-authored-by: ptthanh02 <73684260+ptthanh02@users.noreply.github.com>
Co-authored-by: ptthanh02 <73684260+ptthanh02@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Oct 25, 2025

@copilot
[13:48:38 INFO]: [SmartSpawner] Enabling SmartSpawner v1.5.4.3
[13:48:39 INFO]: [SmartSpawner] Data version 2 is outdated. Current version is 3.
...

Fixed in commit cacd29a. The issue was that version 2 data already has .location, .settings, .inventory structure, but the settings string has only 11 fields instead of 13 required for version 3. Added proper version 2 → version 3 migration that:

  1. Checks settings field count (must be 13 for v3)
  2. Migrates v2 settings (11 fields) to v3 (13 fields) by inserting maxStackSize at position 10 and isAtCapacity at position 12

The migration should now properly detect and migrate version 2 data to version 3.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • jitpack.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • maven.enginehub.org
  • mvn.lumine.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • nexus.iridiumdevelopment.net
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • repo.bg-software.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • repo.codemc.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • repo.glaremasters.me
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • repo.nightexpressdev.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • repo.opencollab.dev
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • repo.papermc.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/gradle-launcher-8.8.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.8-bin/dl7vupf4psengwqhwktix4v1/gradle-8.8/lib/agents/gradle-instrumentation-agent-8.8.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.8 (dns block)
  • repository.minecodes.pl

If you need me to access, download, or install something from one of these locations, you can either:

@ptthanh02
Copy link
Copy Markdown
Contributor

@copilot Successfully migrated 0 spawners from version 2 to version 3 why 0 spawner, in data file I'm currently having 8359

[14:24:56 INFO]: [SmartSpawner] Enabling SmartSpawner v1.5.4.3
[14:24:57 INFO]: [SmartSpawner] Data version 2 is outdated. Current version is 3.
[14:24:58 INFO]: [SmartSpawner] Starting data migration process...
[14:24:58 INFO]: [SmartSpawner] Backup created successfully at: plugins\SmartSpawner\spawners_data_backup.yml
[14:24:58 INFO]: [SmartSpawner] Migrating from version 2 to version 3...
[14:24:59 INFO]: [SmartSpawner] Successfully migrated 0 spawners from version 2 to version 3
[14:24:59 INFO]: [SmartSpawner] Data migration completed. Loading with new format...
[14:24:59 INFO]: [SmartSpawner] Running on standard Paper server.
[14:24:59 WARN]: [SmartSpawner] Vault not found! Selling items from spawner will be disabled.
[14:24:59 INFO]: [SmartSpawner] No compatible shop plugins found. Shop integration is disabled.
[14:25:00 INFO]: [SmartSpawner] Loaded storage GUI layout: default
[14:25:00 INFO]: [SmartSpawner] Loaded main GUI layout: default
[14:25:03 INFO]: [SmartSpawner] Initial spawner load complete. Loaded: 8359, Pending (missing worlds): 0
[14:25:03 INFO]: [SmartSpawner] SmartSpawner has been enabled! (Loaded in 6311ms)
[14:25:03 INFO]: [spark] Starting background profiler...
[14:25:03 INFO]: [spark] The async-profiler engine is not supported for your os/arch (windows11/amd64), so the built-in Java engine will be used instead.
[14:25:03 INFO]: Done preparing level "world" (15.771s)
[14:25:03 INFO]: Running delayed init tasks
[14:25:03 INFO]: Done (49.706s)! For help, type "help"

Co-authored-by: ptthanh02 <73684260+ptthanh02@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Oct 25, 2025

@copilot Successfully migrated 0 spawners from version 2 to version 3 why 0 spawner, in data file I'm currently having 8359

[14:24:56 INFO]: [SmartSpawner] Enabling SmartSpawner v1.5.4.3
...

Fixed in commit d9c13e7. The issue was that version 2 data has 12 fields (not 11 as initially assumed). The old converter created 12 fields including allowEquipmentItems, but the migration was only checking for exactly 11 fields, causing the condition to never match.

Updated the migration to handle both 11 and 12 field formats:

  • Changed check from settings.length == 11 to settings.length >= 11 && settings.length <= 12
  • Preserves allowEquipmentItems value as isAtCapacity when migrating 12-field format

The migration should now properly detect and migrate all 8359 spawners from version 2 to version 3.

@ptthanh02 ptthanh02 merged commit 6715f28 into main Oct 25, 2025
2 checks passed
@ptthanh02 ptthanh02 deleted the copilot/fix-smartspawner-migration-issue branch October 25, 2025 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants