diff --git a/app/imports/api/creature/log/CreatureLogs.js b/app/imports/api/creature/log/CreatureLogs.js index 633d1ff3..dddd2cc5 100644 --- a/app/imports/api/creature/log/CreatureLogs.js +++ b/app/imports/api/creature/log/CreatureLogs.js @@ -43,13 +43,10 @@ let CreatureLogSchema = new SimpleSchema({ type: String, index: 1, }, - // creatures targeted by any of the logged events - targetIds: { - type: Array, - optional: true, - }, - 'targetIds.$': { + // The tabletops this log is associated with + tabletopId: { type: String, + optional: true, index: 1, }, creatureName: { diff --git a/app/imports/api/engine/action/EngineActions.ts b/app/imports/api/engine/action/EngineActions.ts index 46a7e7c0..cd8160a1 100644 --- a/app/imports/api/engine/action/EngineActions.ts +++ b/app/imports/api/engine/action/EngineActions.ts @@ -11,6 +11,7 @@ export interface EngineAction { _decisions?: any[], creatureId: string; rootPropId?: string; + tabletopId: string; targetIds?: string[]; results: TaskResult[]; taskCount: number; @@ -20,11 +21,18 @@ const ActionSchema = new SimpleSchema({ creatureId: { type: String, regEx: SimpleSchema.RegEx.Id, + index: 1, }, rootPropId: { type: String, regEx: SimpleSchema.RegEx.Id, }, + tabletopId: { + type: String, + regEx: SimpleSchema.RegEx.Id, + optional: true, + index: 1, + }, targetIds: { type: Array, defaultValue: [], diff --git a/app/imports/api/engine/action/functions/writeActionResults.ts b/app/imports/api/engine/action/functions/writeActionResults.ts index 5b3f51b6..b8f08309 100644 --- a/app/imports/api/engine/action/functions/writeActionResults.ts +++ b/app/imports/api/engine/action/functions/writeActionResults.ts @@ -26,7 +26,7 @@ export default async function writeActionResults(action: EngineAction) { const logPromise = CreatureLogs.insertAsync({ content: logContents, creatureId: action.creatureId, - targetIds: allTargetIds, + tabletopId: action.tabletopId, }); // Write the bulk updates diff --git a/app/imports/api/engine/action/methods/insertAction.ts b/app/imports/api/engine/action/methods/insertAction.ts index ebafe622..7b4c0327 100644 --- a/app/imports/api/engine/action/methods/insertAction.ts +++ b/app/imports/api/engine/action/methods/insertAction.ts @@ -9,8 +9,29 @@ export const insertAction = new ValidatedMethod({ validate: new SimpleSchema({ action: ActionSchema }).validator({ clean: true }), + rateLimit: { + numRequests: 5, + timeInterval: 1000, + }, run: function ({ action }: { action: EngineAction }) { - assertEditPermission(getCreature(action.creatureId), this.userId); + const creature = getCreature(action.creatureId); + assertEditPermission(getCreature(creature), this.userId); + // Make sure the action shares the creature's tabletopId + // It is assumed that if a character you control is in a tabletop, you have the rights + // to do actions in that tabletop + action.tabletopId = creature.tabletopId; + + // Ensure that all the targeted creatures exist and share a tabletop + if (action.targetIds) for (const targetId of action.targetIds) { + const target = getCreature(targetId); + if (!target) { + throw new Meteor.Error('not-found', 'Target creature does not exist'); + } + if (target.tabletopId !== action.tabletopId) { + throw new Meteor.Error('permission-denied', 'Target creature does not share a tabletop with the acting creature'); + } + } + // First remove all other actions on this creature // only do one action at a time, don't wait for this to finish EngineActions.remove({ creatureId: action.creatureId }); diff --git a/app/imports/client/ui/log/CharacterLog.vue b/app/imports/client/ui/log/CharacterLog.vue index 87ee5eee..bde5c6aa 100644 --- a/app/imports/client/ui/log/CharacterLog.vue +++ b/app/imports/client/ui/log/CharacterLog.vue @@ -41,7 +41,8 @@ import Creatures from '/imports/api/creature/creatures/Creatures'; import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables'; import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions'; import { parse, prettifyParseError } from '/imports/parser/parser'; -import resolve, { toString } from '/imports/parser/resolve'; +import resolve from '/imports/parser/resolve'; +import toString from '/imports/parser/toString'; import LogEntry from '/imports/client/ui/log/LogEntry.vue'; import { Tracker } from 'meteor/tracker' @@ -110,14 +111,14 @@ export default { if (this.history.length > 50) this.history.shift(); this.historyIndex = this.history.length; }, - recalculate() { + async recalculate() { this.inputHint = this.inputError = undefined; if (!this.input) return; let result; try { result = parse(this.input); } catch (e){ - if (e.constructor.name === 'EndOfInputError'){ + if (e?.constructor?.name === 'EndOfInputError'){ this.inputError = '...'; } else { let error = prettifyParseError(e); @@ -126,7 +127,7 @@ export default { return; } try { - let {result: compiled} = resolve('compile', result, this.variables); + let {result: compiled} = await resolve('compile', result, this.variables); this.inputHint = toString(compiled); return; } catch (e){ @@ -146,7 +147,6 @@ export default { } } }, - // @ts-ignore meteor: { logs() { const filter = {}; diff --git a/app/imports/client/ui/log/TabletopLog.vue b/app/imports/client/ui/log/TabletopLog.vue new file mode 100644 index 00000000..0b5feb5c --- /dev/null +++ b/app/imports/client/ui/log/TabletopLog.vue @@ -0,0 +1,188 @@ + + + + + +resolveimport { toString } from '/imports/parser/toString'; diff --git a/app/imports/client/ui/log/TabletopLogContent.vue b/app/imports/client/ui/log/TabletopLogContent.vue new file mode 100644 index 00000000..33dfb2b7 --- /dev/null +++ b/app/imports/client/ui/log/TabletopLogContent.vue @@ -0,0 +1,63 @@ + + + + + + + diff --git a/app/imports/client/ui/log/TabletopLogEntry.vue b/app/imports/client/ui/log/TabletopLogEntry.vue new file mode 100644 index 00000000..77ebadaf --- /dev/null +++ b/app/imports/client/ui/log/TabletopLogEntry.vue @@ -0,0 +1,59 @@ + + + diff --git a/app/imports/client/ui/tabletop/TabletopLog.vue b/app/imports/client/ui/tabletop/TabletopLog.vue deleted file mode 100644 index 5775dfcc..00000000 --- a/app/imports/client/ui/tabletop/TabletopLog.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - - - diff --git a/app/imports/client/ui/tabletop/TabletopRightDrawer.vue b/app/imports/client/ui/tabletop/TabletopRightDrawer.vue index 4a82217d..59058bc5 100644 --- a/app/imports/client/ui/tabletop/TabletopRightDrawer.vue +++ b/app/imports/client/ui/tabletop/TabletopRightDrawer.vue @@ -10,7 +10,7 @@