Iterated on tabletops

This commit is contained in:
Thaum Rystra
2024-06-12 17:30:37 +02:00
parent a5292cf0f2
commit 621f284cff
12 changed files with 210 additions and 56 deletions

View File

@@ -9,6 +9,8 @@ import { getFilter, renewDocIds } from '/imports/api/parenting/parentingFunction
import { reifyNodeReferences, storeLibraryNodeReferences } from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables';
import Tabletops from '/imports/api/tabletop/Tabletops';
import { assertTabletopHasPropSpace } from '/imports/api/tabletop/methods/shared/tabletopLimits'
const addCreaturesFromLibraryToTabletop = new ValidatedMethod({
@@ -40,7 +42,9 @@ const addCreaturesFromLibraryToTabletop = new ValidatedMethod({
'You need to be logged in to remove a tabletop');
}
assertUserHasPaidBenefits(this.userId);
assertUserInTabletop(tabletopId, this.userId);
const tabletop = Tabletops.findOne(tabletopId);
assertUserInTabletop(tabletop, this.userId);
assertTabletopHasPropSpace(tabletop);
for (const nodeId of libraryNodeIds) {
const creatureNode = LibraryNodes.findOne({

View File

@@ -4,6 +4,8 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { assertUserInTabletop } from './shared/tabletopPermissions';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
import Creatures from '/imports/api/creature/creatures/Creatures';
import Tabletops from '/imports/api/tabletop/Tabletops';
import { assertTabletopHasPropSpace } from '/imports/api/tabletop/methods/shared/tabletopLimits';
const addCreaturesToTabletop = new ValidatedMethod({
@@ -12,6 +14,7 @@ const addCreaturesToTabletop = new ValidatedMethod({
validate: new SimpleSchema({
'creatureIds': {
type: Array,
max: 20,
},
'creatureIds.$': {
type: String,
@@ -24,7 +27,6 @@ const addCreaturesToTabletop = new ValidatedMethod({
}).validator(),
mixins: [RateLimiterMixin],
// @ts-expect-error Rate limit not defined
rateLimit: {
numRequests: 10,
timeInterval: 5000,
@@ -36,7 +38,9 @@ const addCreaturesToTabletop = new ValidatedMethod({
'You need to be logged in to remove a tabletop');
}
assertUserHasPaidBenefits(this.userId);
assertUserInTabletop(tabletopId, this.userId);
const tabletop = Tabletops.findOne(tabletopId);
assertUserInTabletop(tabletop, this.userId);
assertTabletopHasPropSpace(tabletop);
Creatures.update({
_id: { $in: creatureIds },

View File

@@ -1,53 +0,0 @@
import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { assertUserInTabletop } from './shared/tabletopPermissions';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
import Creatures from '/imports/api/creature/creatures/Creatures';
const addCreaturesToTabletop = new ValidatedMethod({
name: 'tabletops.addCreatures',
validate: new SimpleSchema({
creatureId: {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
tabletopId: {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
}).validator(),
mixins: [RateLimiterMixin],
// @ts-expect-error Rate limit not defined
rateLimit: {
numRequests: 10,
timeInterval: 5000,
},
run({ tabletopId, creatureIds }) {
if (!this.userId) {
throw new Meteor.Error('tabletops.addCreatures.denied',
'You need to be logged in to remove a tabletop');
}
assertUserHasPaidBenefits(this.userId);
assertUserInTabletop(tabletopId, this.userId);
Creatures.update({
_id: { $in: creatureIds },
$or: [
{ writers: this.userId },
{ owner: this.userId },
],
}, {
$set: { tabletop: tabletopId },
}, {
multi: true,
});
},
});
export default addCreaturesToTabletop;

View File

@@ -0,0 +1,89 @@
import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { assertUserInTabletop } from './shared/tabletopPermissions';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
import Creatures from '/imports/api/creature/creatures/Creatures';
import updateTabletopPropCount from '/imports/api/tabletop/functions/denormalizeTabletopPropCount';
import { getCreature } from '/imports/api/engine/loadCreatures';
import { removeCreatureWork } from '/imports/api/creature/creatures/methods/removeCreature';
import { assertOwnership } from '/imports/api/creature/creatures/creaturePermissions';
const removeCreatureFromTabletop = new ValidatedMethod({
name: 'tabletops.removeCreature',
validate: new SimpleSchema({
tabletopId: {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
'creatureIds': {
type: Array,
},
'creatureIds.$': {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 10,
timeInterval: 5000,
},
run({ tabletopId, creatureIds }) {
if (!this.userId) {
throw new Meteor.Error('tabletops.removeCreature.denied',
'You need to be logged in to remove creatures from tabletop');
}
assertUserHasPaidBenefits(this.userId);
assertUserInTabletop(tabletopId, this.userId);
const creaturesToRemove: any[] = [];
const creatureIdsToClearTabletopId: string[] = [];
for (const creatureId of creatureIds) {
const creature = getCreature(creatureId);
// Make sure the creature exists and is in this tabletop
if (!creature || creature.tabletopId !== tabletopId) continue;
switch (creature.type) {
// Remove character creatures from the tabletop
case 'pc':
creatureIdsToClearTabletopId.push(creatureId);
break;
// Delete non player characters and monsters
case 'npc':
case 'monster':
creaturesToRemove.push(creature);
break;
}
}
// Clear tabletopId from all player characters
if (creatureIdsToClearTabletopId.length) Creatures.update({
_id: { $in: creatureIdsToClearTabletopId },
$or: [
{ writers: this.userId },
{ owner: this.userId },
],
}, {
$unset: { tabletopId: 1 },
}, {
multi: true,
});
// Remove all non player characters and monsters
for (const creature of creaturesToRemove) {
assertOwnership(creature, this.userId)
removeCreatureWork(creature._id);
}
if (Meteor.isServer) {
updateTabletopPropCount(tabletopId);
}
},
});
export default removeCreatureFromTabletop;

View File

@@ -0,0 +1,13 @@
const MAX_PROP_COUNT = 10_000;
const MAX_CREATURE_COUNT = 110;
export function assertTabletopHasPropSpace(tabletop) {
if (tabletop.propCount >= MAX_PROP_COUNT) {
throw new Meteor.Error('tabletops.denied',
'This tabletop is full, either remove some creatures or reduce how many properties each creature has');
}
if (tabletop.creatureCount >= MAX_CREATURE_COUNT) {
throw new Meteor.Error('tabletops.denied',
'This tabletop is full, you can\'t add any more creatures to it');
}
}