Moved tabletop characters to left side of the screen

This commit is contained in:
Thaum Rystra
2024-04-12 17:05:20 +02:00
parent 4793b34a55
commit 08640f2bf2
27 changed files with 496 additions and 1370 deletions

View File

@@ -2,7 +2,6 @@ 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 { assertAdmin } from '/imports/api/sharing/sharingPermissions';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
import Creatures from '/imports/api/creature/creatures/Creatures';
@@ -16,15 +15,16 @@ const addCreaturesToTabletop = new ValidatedMethod({
},
'creatureIds.$': {
type: String,
regEx: SimpleSchema.RegEx.id,
regEx: SimpleSchema.RegEx.Id,
},
tabletopId: {
type: String,
regEx: SimpleSchema.RegEx.id,
regEx: SimpleSchema.RegEx.Id,
},
}).validator(),
mixins: [RateLimiterMixin],
// @ts-expect-error Rate limit not defined
rateLimit: {
numRequests: 10,
timeInterval: 5000,
@@ -37,16 +37,16 @@ const addCreaturesToTabletop = new ValidatedMethod({
}
assertUserHasPaidBenefits(this.userId);
assertUserInTabletop(tabletopId, this.userId);
assertAdmin(this.userId);
Creatures.update({
_id: { $in: creatureIds },
// You must have write permission for the creatures you
$or: [
{ writers: this.userId },
{ owner: this.userId },
],
}, {
$set: { tabletop: tabletopId },
$set: { tabletopId },
}, {
multi: true,
});

View File

@@ -1,8 +1,7 @@
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import Tabletops from '../Tabletops';
import { assertAdmin } from '/imports/api/sharing/sharingPermissions';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
import { assertUserHasPaidBenefits, getUserTier } from '/imports/api/users/patreon/tiers';
const insertTabletop = new ValidatedMethod({
@@ -11,8 +10,9 @@ const insertTabletop = new ValidatedMethod({
validate: null,
mixins: [RateLimiterMixin],
// @ts-expect-error Rate limit not defined
rateLimit: {
numRequests: 5,
numRequests: 2,
timeInterval: 5000,
},
@@ -22,13 +22,24 @@ const insertTabletop = new ValidatedMethod({
'You need to be logged in to insert a tabletop');
}
assertUserHasPaidBenefits(this.userId);
assertAdmin(this.userId);
let tier = getUserTier(this.userId);
const currentTabletopCount = Tabletops.find({ owner: this.userId }).count();
if (tier.tabletopSlots !== -1 && tier.tabletopSlots <= currentTabletopCount) {
throw new Meteor.Error('limit-reached', 'You have reached your maximum number of tabletops');
}
return Tabletops.insert({
gameMaster: this.userId,
owner: this.userId,
gameMasters: [this.userId],
players: [],
spectators: [],
initiative: {
active: false,
roundNumber: 0,
},
});
},
});
export default insertTabletop;

View File

@@ -0,0 +1,53 @@
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

@@ -2,7 +2,6 @@ import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import Tabletops from '../Tabletops';
import { assertAdmin } from '/imports/api/sharing/sharingPermissions';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
import { assertUserIsTabletopOwner } from './shared/tabletopPermissions';
import Creatures from '/imports/api/creature/creatures/Creatures';
@@ -14,11 +13,12 @@ const removeTabletop = new ValidatedMethod({
validate: new SimpleSchema({
tabletopId: {
type: String,
regEx: SimpleSchema.RegEx.id,
regEx: SimpleSchema.RegEx.Id,
},
}).validator(),
mixins: [RateLimiterMixin],
// @ts-expect-error Rate limit not defined
rateLimit: {
numRequests: 5,
timeInterval: 5000,
@@ -31,7 +31,6 @@ const removeTabletop = new ValidatedMethod({
}
assertUserHasPaidBenefits(this.userId);
assertUserIsTabletopOwner(tabletopId, this.userId);
assertAdmin(this.userId);
let removed = Tabletops.remove({
_id: tabletopId,

View File

@@ -1,25 +0,0 @@
import Tabletops from '../../Tabletops';
export function assertUserInTabletop(tabletopId, userId) {
let tabletop = Tabletops.findOne(tabletopId);
if (!tabletop) {
throw new Meteor.Error('Tabletop does not exist',
'No tabletop could be found for the given tabletop id');
}
if (tabletop.gameMaster !== userId && !tabletop.players.includes(userId)) {
throw new Meteor.Error('Not in tabletop',
'The user is not the gamemaster or a player in the given tabletop');
}
}
export function assertUserIsTabletopOwner(tabletopId, userId) {
let tabletop = Tabletops.findOne(tabletopId);
if (!tabletop) {
throw new Meteor.Error('Tabletop does not exist',
'No tabletop could be found for the given tabletop id');
}
if (tabletop.gameMaster !== userId) {
throw new Meteor.Error('Not the owner',
'The user is not the owner of the given tabletop');
}
}

View File

@@ -0,0 +1,41 @@
import Tabletops, { Tabletop } from '/imports/api/tabletop/Tabletops';
function assertTabletopExists(tabletop: Tabletop | undefined): asserts tabletop is Tabletop {
if (!tabletop) {
throw new Meteor.Error('Tabletop does not exist',
'No tabletop could be found for the given tabletop id');
}
}
export function assertUserInTabletop(tabletopId, userId) {
const tabletop = Tabletops.findOne(tabletopId, {
fields: { gameMasters: 1, players: 1 }
});
assertTabletopExists(tabletop);
if (tabletop.gameMasters.includes(userId) && !tabletop.players.includes(userId)) {
throw new Meteor.Error('Not in tabletop',
'The user is not the gamemaster or a player in the given tabletop');
}
}
export function assertUserGameMasterOfTabletop(tabletopId, userId) {
const tabletop = Tabletops.findOne(tabletopId, {
fields: { gameMasters: 1 },
});
assertTabletopExists(tabletop);
if (tabletop.gameMasters.includes(userId)) {
throw new Meteor.Error('not-game-master',
'The user is not a game master in the given tabletop');
}
}
export function assertUserIsTabletopOwner(tabletopId, userId) {
const tabletop = Tabletops.findOne(tabletopId, {
fields: { owner: 1 },
});
assertTabletopExists(tabletop);
if (tabletop.owner === userId) {
throw new Meteor.Error('not-owner',
'The user is not the owner of the given tabletop');
}
}

View File

@@ -0,0 +1,53 @@
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import Tabletops from '../Tabletops';
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
import { assertUserIsTabletopOwner } from './shared/tabletopPermissions';
const removeTabletop = new ValidatedMethod({
name: 'tabletops.update',
validate({ _id, path }) {
if (!_id) return false;
// Allowed fields
let allowedFields = [
'name',
'description',
'imageUrl',
];
if (!allowedFields.includes(path[0])) {
throw new Meteor.Error('tabletops.update.denied',
'This field can\'t be updated using this method');
}
},
mixins: [RateLimiterMixin],
// @ts-expect-error Rate limit not defined
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
run({ _id, path, value }) {
if (!this.userId) {
throw new Meteor.Error('tabletops.remove.denied',
'You need to be logged in to remove a tabletop');
}
assertUserHasPaidBenefits(this.userId);
assertUserIsTabletopOwner(_id, this.userId);
if (value === undefined || value === null) {
Tabletops.update(_id, {
$unset: { [path.join('.')]: 1 },
});
} else {
Tabletops.update(_id, {
$set: { [path.join('.')]: value },
});
}
},
});
export default removeTabletop;