Merge branch 'version-2-dev' into version-2-tabletop
This commit is contained in:
@@ -9,6 +9,7 @@ import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||
import Experiences from '/imports/api/creature/experience/Experiences.js';
|
||||
import { removeCreatureWork } from '/imports/api/creature/creatures/methods/removeCreature.js';
|
||||
import ArchiveCreatureFiles from '/imports/api/creature/archive/ArchiveCreatureFiles.js';
|
||||
import { incrementFileStorageUsed } from '/imports/api/users/methods/updateFileStorageUsed.js';
|
||||
|
||||
export function getArchiveObj(creatureId){
|
||||
// Build the archive document
|
||||
@@ -31,7 +32,7 @@ export function getArchiveObj(creatureId){
|
||||
return archiveCreature;
|
||||
}
|
||||
|
||||
export function archiveCreature(creatureId){
|
||||
export function archiveCreature(creatureId, userId){
|
||||
const archive = getArchiveObj(creatureId);
|
||||
const buffer = Buffer.from(JSON.stringify(archive, null, 2));
|
||||
ArchiveCreatureFiles.write(buffer, {
|
||||
@@ -43,11 +44,12 @@ export function archiveCreature(creatureId){
|
||||
creatureId: archive.creature._id,
|
||||
creatureName: archive.creature.name,
|
||||
},
|
||||
}, (error) => {
|
||||
}, (error, file) => {
|
||||
if (error){
|
||||
throw error;
|
||||
} else {
|
||||
removeCreatureWork(creatureId);
|
||||
incrementFileStorageUsed(userId, file.size);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
@@ -68,7 +70,7 @@ const archiveCreatureToFile = new ValidatedMethod({
|
||||
async run({creatureId}) {
|
||||
assertOwnership(creatureId, this.userId);
|
||||
if (Meteor.isServer){
|
||||
archiveCreature(creatureId);
|
||||
archiveCreature(creatureId, this.userId);
|
||||
} else {
|
||||
removeCreatureWork(creatureId);
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
import '/imports/api/creature/archive/methods/archiveCreatureToFile.js';
|
||||
import '/imports/api/creature/archive/methods/restoreCreatures.js';
|
||||
import '/imports/api/creature/archive/methods/restoreCreatureFromFile.js';
|
||||
import '/imports/api/creature/archive/methods/removeArchiveCreature.js';
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import SCHEMA_VERSION from '/imports/constants/SCHEMA_VERSION.js';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||
import Experiences from '/imports/api/creature/experience/Experiences.js';
|
||||
import { removeCreatureWork } from '/imports/api/creature/creatures/methods/removeCreature.js';
|
||||
import ArchiveCreatureFiles from '/imports/api/creature/archive/ArchiveCreatureFiles.js';
|
||||
import assertHasCharactersSlots from '/imports/api/creature/creatures/methods/assertHasCharacterSlots.js';
|
||||
import { incrementFileStorageUsed } from '/imports/api/users/methods/updateFileStorageUsed.js';
|
||||
|
||||
const removeArchiveCreature = new ValidatedMethod({
|
||||
name: 'ArchiveCreatureFiles.methods.removeArchiveCreature',
|
||||
validate: new SimpleSchema({
|
||||
'fileId': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
},
|
||||
}).validator(),
|
||||
mixins: [RateLimiterMixin],
|
||||
rateLimit: {
|
||||
numRequests: 5,
|
||||
timeInterval: 5000,
|
||||
},
|
||||
async run({ fileId }) {
|
||||
// fetch the file
|
||||
const file = ArchiveCreatureFiles.findOne({ _id: fileId }).get();
|
||||
if (!file) {
|
||||
throw new Meteor.Error('File not found',
|
||||
'The requested creature archive does not exist');
|
||||
}
|
||||
// Assert ownership
|
||||
const userId = file?.userId;
|
||||
if (!userId || userId !== this.userId) {
|
||||
throw new Meteor.Error('Permission denied',
|
||||
'You can only restore creatures you own');
|
||||
}
|
||||
//Remove the archive once the restore succeeded
|
||||
ArchiveCreatureFiles.remove({ _id: fileId });
|
||||
// Update the user's file storage limits
|
||||
incrementFileStorageUsed(userId, -file.size);
|
||||
},
|
||||
});
|
||||
|
||||
export default removeArchiveCreature;
|
||||
@@ -8,6 +8,9 @@ import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||
import Experiences from '/imports/api/creature/experience/Experiences.js';
|
||||
import { removeCreatureWork } from '/imports/api/creature/creatures/methods/removeCreature.js';
|
||||
import ArchiveCreatureFiles from '/imports/api/creature/archive/ArchiveCreatureFiles.js';
|
||||
import assertHasCharactersSlots from '/imports/api/creature/creatures/methods/assertHasCharacterSlots.js';
|
||||
import { incrementFileStorageUsed } from '/imports/api/users/methods/updateFileStorageUsed.js';
|
||||
|
||||
let migrateArchive;
|
||||
if (Meteor.isServer){
|
||||
migrateArchive = require('/imports/migrations/server/migrateArchive.js').default;
|
||||
@@ -69,13 +72,18 @@ const restoreCreaturefromFile = new ValidatedMethod({
|
||||
throw new Meteor.Error('Permission denied',
|
||||
'You can only restore creatures you own');
|
||||
}
|
||||
|
||||
assertHasCharactersSlots(this.userId);
|
||||
|
||||
if (Meteor.isServer){
|
||||
// Read the file data
|
||||
const archive = await ArchiveCreatureFiles.readJSONFile(file);
|
||||
restoreCreature(archive);
|
||||
}
|
||||
//Remove the archive once the restore succeeded
|
||||
ArchiveCreatureFiles.remove({_id: fileId});
|
||||
ArchiveCreatureFiles.remove({ _id: fileId });
|
||||
// Update the user's file storage limits
|
||||
incrementFileStorageUsed(userId, -file.size);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { getUserTier } from '/imports/api/users/patreon/tiers.js';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
|
||||
export default function assertHasCharactersSlots(userId) {
|
||||
if (characterSlotsRemaining(userId) <= 0) {
|
||||
throw new Meteor.Error('characterSlotLimit',
|
||||
'No character slots left')
|
||||
}
|
||||
}
|
||||
|
||||
export function characterSlotsRemaining(userId) {
|
||||
let tier = getUserTier(userId);
|
||||
const currentCharacterCount = Creatures.find({
|
||||
owner: userId,
|
||||
}, {
|
||||
fields: { _id: 1 },
|
||||
}).count();
|
||||
if (tier.characterSlots === -1) {
|
||||
return Number.POSITIVE_INFINITY;
|
||||
}
|
||||
return tier.characterSlots - currentCharacterCount;
|
||||
}
|
||||
@@ -2,9 +2,9 @@ import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { getUserTier } from '/imports/api/users/patreon/tiers.js';
|
||||
import defaultCharacterProperties from '/imports/api/creature/creatures/defaultCharacterProperties.js';
|
||||
import insertPropertyFromLibraryNode from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js';
|
||||
import assertHasCharactersSlots from '/imports/api/creature/creatures/methods/assertHasCharacterSlots.js';
|
||||
|
||||
const insertCreature = new ValidatedMethod({
|
||||
|
||||
@@ -23,21 +23,8 @@ const insertCreature = new ValidatedMethod({
|
||||
throw new Meteor.Error('Creatures.methods.insert.denied',
|
||||
'You need to be logged in to insert a creature');
|
||||
}
|
||||
let tier = getUserTier(this.userId);
|
||||
|
||||
let currentCharacterCount = Creatures.find({
|
||||
owner: this.userId,
|
||||
}, {
|
||||
fields: {_id: 1},
|
||||
}).count();
|
||||
|
||||
if (
|
||||
tier.characterSlots !== -1 &&
|
||||
currentCharacterCount >= tier.characterSlots
|
||||
){
|
||||
throw new Meteor.Error('Creatures.methods.insert.denied',
|
||||
`You are already at your limit of ${tier.characterSlots} characters`)
|
||||
}
|
||||
assertHasCharactersSlots(this.userId);
|
||||
|
||||
// Create the creature document
|
||||
let creatureId = Creatures.insert({
|
||||
|
||||
Reference in New Issue
Block a user