Farmstead Mods
EN

Хранилище

Подключаемые бэкенды JSON, YAML, SQLite и MySQL для всех данных мода.

На этой странице

Примеры#

Переехать с JSON на MySQL для сети серверов#

Баны, экономика и права должны быть общими, без копирования файлов.

/neoe reload

Пропишите storage.type: mysql и блок storage.mysql.*, затем рестарт (не reload): бэкенд выбирается на старте. Если коллекция в MySQL пустая и autoMigrate: true, мод один раз импортирует данные из текущего JSON/legacy. Старые файлы не удаляются. Если MySQL на старте недоступен, мод молча падает обратно на JSON и сервер всё равно поднимается.

Тонкие места#

Почта не в DataStore#

/mail по-прежнему живёт в config/neoessentials/mail_data.json независимо от storage.type. Смена бэкенда почту не переедет.

Что делать: На сети серверов не ждите общей почты через MySQL — её там нет. Остальные коллекции (включая auction_listings) — да.

runServer в Gradle не видит sqlite/mysql/yaml драйверы#

Драйверы сидят в JarJar внутри собранного jar. Dev-классloader runServer их не видит → ClassNotFoundException при type ≠ json. На установленном jar всё штатно.

Что делать: Локально оставляйте storage.type: json. Проверять MySQL — на собранном моде, не на gradlew runServer.

Права пишутся целиком, не по записи#

Большинство коллекций обновляют один документ. permission_groups / permission_users при save() заменяют всё состояние: иначе удаление группы оставило бы призрак в бэкенде.

Что делать: Не редактируйте одну строку в permission_users.json, пока сервер запущен — следующий save затрёт правку полным дампом.

Подробное руководство#

Раздел ниже — исходная документация проекта (docs/Wiki/Storage.md). Ссылки на другие страницы вики переписаны на этот сайт; текст самих руководств не редактируется, чтобы синк с апстримом не давал конфликтов.

Version: 1.0.5+build.54 · Config: config.json → storage section


Overview#

Almost everything NeoEssentials persists — moderation records, economy balances, homes/warps/spawn, kits, chat state, holograms, shops, permissions, the dashboard's own accounts, and the Auction House — goes through a single pluggable DataStore abstraction instead of each manager writing its own bespoke JSON file. One config setting picks the backend for the whole mod:

"storage": {
  "type": "json",
  "autoMigrate": true,
  "sqlite": { "file": "data.db" },
  "mysql": { "host": "localhost", "port": 3306, "database": "neoessentials", "username": "neoessentials", "password": "", "useSSL": false, "poolSize": 10 }
}
Key Default Description
type "json" Backend to use: json, yaml, sqlite, or mysql
autoMigrate true On first boot with an empty collection, import that manager's existing legacy JSON data automatically and losslessly
sqlite.file "data.db" SQLite database filename (under neoessentials/store/)
mysql.* — Connection details for a shared MySQL database — point every server in a network at the same database to share bans, economy, permissions, etc. in real time

If type is mysql but the connection fails at boot, the mod automatically falls back to the JSON backend instead of failing to start — fix storage.mysql.* and restart to pick MySQL back up.

With the default json backend, each collection lives at neoessentials/store/<collection>.json. With yaml, neoessentials/store/<collection>.yml. With sqlite, every collection is a table in neoessentials/store/data.db. With mysql, every collection is a table in the configured database.


How Migration Works#

Each manager keeps its old bespoke JSON file(s) around and, on first boot after updating, checks whether its DataStore collection is still empty. If it is (and autoMigrate is enabled), it imports the legacy file(s) once — losslessly, preserving IDs, history, and audit trails where applicable — and from then on reads/writes exclusively through DataStore. Legacy files are never deleted automatically; they're simply no longer written to, so you can always cross-check or roll back manually if needed.

Switching storage.type later (e.g. from json to mysql for a multi-server setup) re-triggers this same import path for any collection that's empty in the new backend — so you can migrate from JSON straight to MySQL in one step, not just from legacy files to JSON first.


Dev-Environment Caveat: sqlite/mysql/yaml Backends Need the Built Jar#

The sqlite, mysql, and yaml backends depend on bundled libraries (sqlite-jdbc, mysql-connector-j + HikariCP, and SnakeYAML respectively) that are shaded into the mod via JarJar. NeoForge's Gradle runServer dev task loads each mod through a per-mod module classloader that only sees dependencies from the packaged mod jar (build/generated/jarJar/...), not the plain Gradle classpath — so running ./gradlew runServer with storage.type set to anything other than json will fail to load the driver class (ClassNotFoundException) and log an error, even though the dependency is correctly bundled for a real install.

This only affects local development via runServer — installing the built mod jar on an actual server resolves the bundled dependency normally, same as it always has for sqlite-jdbc (used directly by the Auction House before this release). If a manager's one-time legacy-file migration hits this in a dev session, it logs the error and continues normally on whichever backend is actually active — nothing crashes, and the migration will succeed once run from a real packaged jar.


Collections by System#

System Collections Wiki page
Moderation player_bans, ip_bans, mutes, ip_mutes, kicks, warns, notes, reports, jails, jail_locations, freezes, vanishes Moderation System
Economy economy_balances, pay_toggles, transaction_history, item_worth Economy System
Kits kits, kit_cooldowns, kit_usages Kit Management
Teleportation warps, player_warps, spawn, playerdata_homes, playerdata_back_locations Teleportation System
Chat afk_data, ignore_lists, chat_formats Chat System
Holograms holograms Hologram System
Shops chest_shops, npc_shops Utility Systems
Auction House auction_listings, auction_expired Utility Systems
Permissions permission_groups, permission_users, permission_meta, permission_aliases Permission System
Localization language_overrides Localization System / Custom Languages
Utility motd_profiles, motd_meta, resource_packs Utility Systems
Web Dashboard dashboard_users, dashboard_registrations Web Dashboard

playerdata_homes and playerdata_back_locations are one record per player (id = UUID) rather than the old one-file-per-player-per-type layout under neoessentials/playerdata/<type>/<uuid>.json — both old and new per-player layouts migrate automatically the same way as every other collection.


Notes on Specific Systems#

  • Permissions (permission_groups/permission_users) preserve group inheritance, priorities, temp permissions, contextual permissions, and per-node conditions exactly as before — this is the one system where save() replaces the entire current state rather than writing one record at a time, since deleting a group or resetting a user has to actually remove its record from the backend, not just stop referencing it.
  • Auction House (auction_listings/auction_expired) no longer opens its own dedicated SQLite database (auctionhouse.db) — it now uses the same backend as everything else. A listing keeps the same numeric ID when it moves from active to expired, matching the previous behavior; existing auctionhouse.db data is imported automatically on first boot.
  • Vanish: the "who can see vanished players" viewer-priority toggle is intentionally session-only (not persisted) — only the vanished-state itself survives a restart.
  • Mail (/mail) is the one system not yet migrated onto DataStore — it still persists directly to its own file, config/neoessentials/mail_data.json, regardless of storage.type.

Back to Wiki Home