Working on Compatibility for FVTT v10
updated migration stuff
This commit is contained in:
@@ -16,7 +16,7 @@ export default class HooksL5r5e {
|
|||||||
* Do anything once the system is ready
|
* Do anything once the system is ready
|
||||||
*/
|
*/
|
||||||
static async ready() {
|
static async ready() {
|
||||||
// If multiple GM connected, tag the 1st alive, useful for some traitements
|
// If multiple GM connected, tag the 1st alive, useful for some traitements that need to be done once (migration, delete...)
|
||||||
Object.defineProperty(game.user, "isFirstGM", {
|
Object.defineProperty(game.user, "isFirstGM", {
|
||||||
get: function () {
|
get: function () {
|
||||||
return game.user.isGM && game.user.id === game.users.find((u) => u.active && u.isGM)?.id;
|
return game.user.isGM && game.user.id === game.users.find((u) => u.active && u.isGM)?.id;
|
||||||
@@ -24,8 +24,8 @@ export default class HooksL5r5e {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Migration stuff
|
// Migration stuff
|
||||||
if (game.l5r5e.migrations.needUpdate(game.l5r5e.migrations.NEEDED_VERSION)) {
|
if (game.user.isFirstGM && game.l5r5e.migrations.needUpdate(game.l5r5e.migrations.NEEDED_VERSION)) {
|
||||||
game.l5r5e.migrations.migrateWorld({ force: false });
|
game.l5r5e.migrations.migrateWorld({ force: false }).then();
|
||||||
}
|
}
|
||||||
|
|
||||||
// For some reasons, not always really ready, so wait a little
|
// For some reasons, not always really ready, so wait a little
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ export class MigrationL5r5e {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the version need some updates
|
* Return true if the version need some updates
|
||||||
* @param {string} version
|
* @param {string} version Version number to contest against the current version
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
static needUpdate(version) {
|
static needUpdate(version) {
|
||||||
const currentVersion = game.settings.get("l5r5e", "systemMigrationVersion");
|
const currentVersion = game.settings.get("l5r5e", "systemMigrationVersion");
|
||||||
return currentVersion && foundry.utils.isNewerVersion(version, currentVersion);
|
return !currentVersion || foundry.utils.isNewerVersion(version, currentVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,11 +44,11 @@ export class MigrationL5r5e {
|
|||||||
try {
|
try {
|
||||||
const updateData = MigrationL5r5e._migrateActorData(actor, options);
|
const updateData = MigrationL5r5e._migrateActorData(actor, options);
|
||||||
if (!foundry.utils.isEmpty(updateData)) {
|
if (!foundry.utils.isEmpty(updateData)) {
|
||||||
console.log(`L5R5E | Migrating Actor entity ${actor.name}`);
|
console.log(`L5R5E | Migrating Actor document ${actor.name}[${actor._id}]`);
|
||||||
await actor.update(updateData);
|
await actor.update(updateData);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `L5R5E | Failed L5R5e system migration for Actor ${actor.name}: ${err.message}`;
|
err.message = `L5R5E | Failed L5R5e system migration for Actor ${actor.name}[${actor._id}]: ${err.message}`;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,11 +58,11 @@ export class MigrationL5r5e {
|
|||||||
try {
|
try {
|
||||||
const updateData = MigrationL5r5e._migrateItemData(item, options);
|
const updateData = MigrationL5r5e._migrateItemData(item, options);
|
||||||
if (!foundry.utils.isEmpty(updateData)) {
|
if (!foundry.utils.isEmpty(updateData)) {
|
||||||
console.log(`L5R5E | Migrating Item entity ${item.name}`);
|
console.log(`L5R5E | Migrating Item document ${item.name}[${item._id}]`);
|
||||||
await item.update(updateData);
|
await item.update(updateData);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `L5R5E | Failed L5R5e system migration for Item ${item.name}: ${err.message}`;
|
err.message = `L5R5E | Failed L5R5e system migration for Item ${item.name}[${item._id}]: ${err.message}`;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,21 +72,21 @@ export class MigrationL5r5e {
|
|||||||
try {
|
try {
|
||||||
const updateData = MigrationL5r5e._migrateSceneData(scene, options);
|
const updateData = MigrationL5r5e._migrateSceneData(scene, options);
|
||||||
if (!foundry.utils.isEmpty(updateData)) {
|
if (!foundry.utils.isEmpty(updateData)) {
|
||||||
console.log(`L5R5E | Migrating Scene entity ${scene.name}`);
|
console.log(`L5R5E | Migrating Scene document ${scene.name}[${scene._id}]`);
|
||||||
await scene.update(updateData);
|
await scene.update(updateData);
|
||||||
// If we do not do this, then synthetic token actors remain in cache
|
// If we do not do this, then synthetic token actors remain in cache
|
||||||
// with the un-updated actorData.
|
// with the un-updated actorData.
|
||||||
scene.tokens.contents.forEach((t) => (t._actor = null));
|
scene.tokens.contents.forEach((t) => (t._actor = null));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `L5R5E | Failed L5R5e system migration for Scene ${scene.name}: ${err.message}`;
|
err.message = `L5R5E | Failed L5R5e system migration for Scene ${scene.name}[${scene._id}]: ${err.message}`;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate World Compendium Packs
|
// Migrate World Compendium Packs
|
||||||
for (let pack of game.packs) {
|
for (let pack of game.packs) {
|
||||||
if (pack.metadata.package !== "world" || !["Actor", "Item", "Scene"].includes(pack.metadata.entity)) {
|
if (pack.metadata.packageType !== "world" || !["Actor", "Item", "Scene"].includes(pack.metadata.type)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
await MigrationL5r5e._migrateCompendium(pack, options);
|
await MigrationL5r5e._migrateCompendium(pack, options);
|
||||||
@@ -104,7 +104,7 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
// Save all the modified entries at once
|
// Save all the modified entries at once
|
||||||
if (updatedChatList.length > 0) {
|
if (updatedChatList.length > 0) {
|
||||||
console.log(`L5R5E | Migrating ${updatedChatList.length} ChatMessage entities`);
|
console.log(`L5R5E | Migrating ${updatedChatList.length} ChatMessage documents`);
|
||||||
await ChatMessage.updateDocuments(updatedChatList);
|
await ChatMessage.updateDocuments(updatedChatList);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -120,17 +120,13 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply migration rules to all Entities within a single Compendium pack
|
* Apply migration rules to all documents within a single Compendium pack
|
||||||
* @param {Compendium} pack
|
* @param {CompendiumCollection} pack
|
||||||
* @param options
|
* @param options
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
static async _migrateCompendium(pack, options = { force: false }) {
|
static async _migrateCompendium(pack, options = { force: false }) {
|
||||||
const entity = pack.metadata.entity;
|
const docType = pack.metadata.type;
|
||||||
if (!["Actor", "Item", "Scene"].includes(entity)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wasLocked = pack.locked;
|
const wasLocked = pack.locked;
|
||||||
try {
|
try {
|
||||||
// Unlock the pack for editing
|
// Unlock the pack for editing
|
||||||
@@ -142,18 +138,18 @@ export class MigrationL5r5e {
|
|||||||
|
|
||||||
// Iterate over compendium entries - applying fine-tuned migration functions
|
// Iterate over compendium entries - applying fine-tuned migration functions
|
||||||
const updateDatasList = [];
|
const updateDatasList = [];
|
||||||
for (let ent of documents) {
|
for (let doc of documents) {
|
||||||
let updateData = {};
|
let updateData = {};
|
||||||
|
|
||||||
switch (entity) {
|
switch (docType) {
|
||||||
case "Actor":
|
case "Actor":
|
||||||
updateData = MigrationL5r5e._migrateActorData(ent);
|
updateData = MigrationL5r5e._migrateActorData(doc);
|
||||||
break;
|
break;
|
||||||
case "Item":
|
case "Item":
|
||||||
updateData = MigrationL5r5e._migrateItemData(ent);
|
updateData = MigrationL5r5e._migrateItemData(doc);
|
||||||
break;
|
break;
|
||||||
case "Scene":
|
case "Scene":
|
||||||
updateData = MigrationL5r5e._migrateSceneData(ent);
|
updateData = MigrationL5r5e._migrateSceneData(doc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (foundry.utils.isEmpty(updateData)) {
|
if (foundry.utils.isEmpty(updateData)) {
|
||||||
@@ -161,10 +157,12 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the entry, if data was changed
|
// Add the entry, if data was changed
|
||||||
updateData["_id"] = ent._id;
|
updateData["_id"] = doc._id;
|
||||||
updateDatasList.push(updateData);
|
updateDatasList.push(updateData);
|
||||||
|
|
||||||
console.log(`L5R5E | Migrating ${entity} entity ${ent.name} in Compendium ${pack.collection}`);
|
console.log(
|
||||||
|
`L5R5E | Migrating ${docType} document ${doc.name}[${doc._id}] in Compendium ${pack.collection}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the modified entries
|
// Save the modified entries
|
||||||
@@ -173,20 +171,20 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Handle migration failures
|
// Handle migration failures
|
||||||
err.message = `L5R5E | Failed system migration for entities ${entity} in pack ${pack.collection}: ${err.message}`;
|
err.message = `L5R5E | Failed system migration for documents ${docType} in pack ${pack.collection}: ${err.message}`;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the original locked status for the pack
|
// Apply the original locked status for the pack
|
||||||
pack.configure({ locked: wasLocked });
|
await pack.configure({ locked: wasLocked });
|
||||||
console.log(`L5R5E | Migrated all ${entity} contents from Compendium ${pack.collection}`);
|
console.log(`L5R5E | Migrated all ${docType} contents from Compendium ${pack.collection}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate a single Scene entity to incorporate changes to the data model of it's actor data overrides
|
* Migrate a single Scene document to incorporate changes to the data model of its actor data overrides
|
||||||
* Return an Object of updateData to be applied
|
* Return an Object of updateData to be applied
|
||||||
* @param {Object} scene The Scene data to Update
|
* @param {Scene} scene The Scene data to Update
|
||||||
* @param options
|
* @param options
|
||||||
* @return {Object} The updateData to apply
|
* @return {Object} The updateData to apply
|
||||||
*/
|
*/
|
||||||
static _migrateSceneData(scene, options = { force: false }) {
|
static _migrateSceneData(scene, options = { force: false }) {
|
||||||
@@ -223,38 +221,37 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate a single Actor entity to incorporate latest data model changes
|
* Migrate a single Actor document to incorporate latest data model changes
|
||||||
* Return an Object of updateData to be applied
|
* Return an Object of updateData to be applied
|
||||||
* @param {Actor} actor The actor to Update
|
* @param {ActorL5r5e|Object} actor The actor, or the TokenDocument.actorData to Update
|
||||||
* @param options
|
* @param options
|
||||||
* @return {Object} The updateData to apply
|
* @return {Object} The updateData to apply
|
||||||
*/
|
*/
|
||||||
static _migrateActorData(actor, options = { force: false }) {
|
static _migrateActorData(actor, options = { force: false }) {
|
||||||
const updateData = {};
|
const updateData = {};
|
||||||
const actorData = actor.system;
|
const system = actor.system;
|
||||||
|
|
||||||
// We need to be careful for unlinked tokens, only the diff is store in "data".
|
// We need to be careful with unlinked tokens, only the diff is store in "actorData".
|
||||||
// ex no diff : actor = {type: "npc"}, actorData = undefined
|
// ex no diff : actor = {type: "npc"}, actorData = undefined
|
||||||
if (!actorData) {
|
if (!system) {
|
||||||
return updateData;
|
return updateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***** Start of 1.1.0 *****
|
// ***** Start of 1.1.0 *****
|
||||||
if (options?.force || MigrationL5r5e.needUpdate("1.1.0")) {
|
if (options?.force || MigrationL5r5e.needUpdate("1.1.0")) {
|
||||||
// Add "Prepared" in actor
|
// Add "Prepared" in actor
|
||||||
if (actorData.prepared === undefined) {
|
if (system.prepared === undefined) {
|
||||||
updateData["system.prepared"] = true;
|
updateData["system.prepared"] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NPC are now without autostats, we need to save the value
|
// NPC are now without autostats, we need to save the value
|
||||||
if (actor.type === "npc") {
|
if (actor.type === "npc") {
|
||||||
if (actorData.endurance < 1) {
|
if (system.endurance < 1) {
|
||||||
updateData["system.endurance"] = (Number(actorData.rings.earth) + Number(actorData.rings.fire)) * 2;
|
updateData["system.endurance"] = (Number(system.rings.earth) + Number(system.rings.fire)) * 2;
|
||||||
updateData["system.composure"] =
|
updateData["system.composure"] = (Number(system.rings.earth) + Number(system.rings.water)) * 2;
|
||||||
(Number(actorData.rings.earth) + Number(actorData.rings.water)) * 2;
|
updateData["system.focus"] = Number(system.rings.air) + Number(system.rings.fire);
|
||||||
updateData["system.focus"] = Number(actorData.rings.air) + Number(actorData.rings.fire);
|
|
||||||
updateData["system.vigilance"] = Math.ceil(
|
updateData["system.vigilance"] = Math.ceil(
|
||||||
(Number(actorData.rings.air) + Number(actorData.rings.water)) / 2
|
(Number(system.rings.air) + Number(system.rings.water)) / 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,13 +261,13 @@ export class MigrationL5r5e {
|
|||||||
// ***** Start of 1.3.0 *****
|
// ***** Start of 1.3.0 *****
|
||||||
if (options?.force || MigrationL5r5e.needUpdate("1.3.0")) {
|
if (options?.force || MigrationL5r5e.needUpdate("1.3.0")) {
|
||||||
// PC/NPC removed notes useless props "value"
|
// PC/NPC removed notes useless props "value"
|
||||||
if (actorData.notes?.value) {
|
if (system.notes?.value) {
|
||||||
updateData["system.notes"] = actorData.notes.value;
|
updateData["system.notes"] = system.notes.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NPC have now more thant a Strength and a Weakness
|
// NPC have now more than a Strength and a Weakness
|
||||||
if (actor.type === "npc" && actorData.rings_affinities?.strength) {
|
if (actor.type === "npc" && system.rings_affinities?.strength) {
|
||||||
const aff = actorData.rings_affinities;
|
const aff = system.rings_affinities;
|
||||||
updateData["system.rings_affinities." + aff.strength.ring] = aff.strength.value;
|
updateData["system.rings_affinities." + aff.strength.ring] = aff.strength.value;
|
||||||
updateData["system.rings_affinities." + aff.weakness.ring] = aff.weakness.value;
|
updateData["system.rings_affinities." + aff.weakness.ring] = aff.weakness.value;
|
||||||
|
|
||||||
@@ -285,19 +282,8 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrub an Actor's system data, removing all keys which are not explicitly defined in the system template
|
* Migrate a single Item document to incorporate latest data model changes
|
||||||
* @param {Object} actorData The data object for an Actor
|
* @param {ItemL5r5e} item
|
||||||
* @return {Object} The scrubbed Actor data
|
|
||||||
*/
|
|
||||||
static cleanActorData(actorData) {
|
|
||||||
const model = game.system.model.Actor[actorData.type];
|
|
||||||
actorData = foundry.utils.filterObject(actorData, model);
|
|
||||||
return actorData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Migrate a single Item entity to incorporate latest data model changes
|
|
||||||
* @param item
|
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
static _migrateItemData(item, options = { force: false }) {
|
static _migrateItemData(item, options = { force: false }) {
|
||||||
@@ -306,8 +292,8 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate a single Item entity to incorporate latest data model changes
|
* Migrate a single Item document to incorporate latest data model changes
|
||||||
* @param {ChatMessageData} message
|
* @param {ChatMessage} message
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
static _migrateChatMessage(message, options = { force: false }) {
|
static _migrateChatMessage(message, options = { force: false }) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Vlyan",
|
"name": "Vlyan",
|
||||||
"discord": "Vlyan#6771",
|
"discord": "Vlyan#6771",
|
||||||
"ko-fi": "vlyan"
|
"url": "https://ko-fi.com/vlyan"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Mandar",
|
"name": "Mandar",
|
||||||
|
|||||||
Reference in New Issue
Block a user