Improved custom rolls on log tab

This commit is contained in:
Stefan Zermatten
2020-10-06 09:53:08 +02:00
parent 844588cdbf
commit a87cb1286a
3 changed files with 115 additions and 14 deletions

View File

@@ -1,4 +1,11 @@
import SimpleSchema from 'simpl-schema';
import Creatures from '/imports/api/creature/Creatures.js';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import {assertEditPermission} from '/imports/api/creature/creaturePermissions.js';
import { parse, CompilationContext } from '/imports/parser/parser.js';
const PER_CREATURE_LOG_LIMIT = 100;
if (Meteor.isServer){
var sendWebhookAsCreature = require('/imports/server/discord/sendWebhook.js').sendWebhookAsCreature;
}
@@ -36,11 +43,28 @@ CreatureLogs.attachSchema(CreatureLogSchema);
// This function should only be called by trusted code. No permission checks
const insertCreatureLog = function({log, creature}){
const creatureId = creature._id;
// Build the new log
if (typeof log === 'string'){
log = {text: log};
}
log.creatureId = creature._id;
log.creatureId = creatureId;
// Insert it
let id = CreatureLogs.insert(log);
// Find the first log that is over the limit
let firstExpiredLog = CreatureLogs.find({
creatureId
}, {
sort: {date: -1},
skip: PER_CREATURE_LOG_LIMIT,
});
// Remove all logs older than the one over the limit
CreatureLogs.remove({
creatureId,
date: {$lte: firstExpiredLog.date},
});
//TODO unblock before sending webhooks
// Send webhooks
if (Meteor.isServer){
sendWebhookAsCreature({
creature,
@@ -50,5 +74,55 @@ const insertCreatureLog = function({log, creature}){
return id;
};
function equalIgnoringWhitespace(a, b){
if (typeof a !== 'string' || typeof b !== 'string') return a === b;
return a.replace(/\s/g,'') === b.replace(/\s/g, '');
}
const logRoll = new ValidatedMethod({
name: 'creatureLogs.methods.logForCreature',
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
validate: new SimpleSchema({
roll: {
type: String,
},
creatureId: {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
}).validator(),
run({roll, creatureId}){
const creature = Creatures.findOne(creatureId);
assertEditPermission(creature, this.userId);
let parsedResult = parse(roll);
let log;
if (parsedResult === null) {
log = 'Unexpected end of input';
}
else try {
let logText = [];
let rollContext = new CompilationContext();
let compiled = parsedResult.compile(creature.variables, rollContext);
let compiledString = compiled.toString();
if (!equalIgnoringWhitespace(compiledString, roll)) logText.push(roll);
logText.push(compiledString);
let rolled = compiled.roll(creature.variables, rollContext);
let rolledString = rolled.toString();
if (rolledString !== compiledString) logText.push(rolled.toString());
let result = rolled.reduce(creature.variables, rollContext);
let resultString = result.toString();
if (resultString !== rolledString) logText.push(resultString);
log = logText.join('\n\n');
} catch (e){
log = 'Calculation error';
}
return insertCreatureLog({log, creature});
},
});
export default CreatureLogs;
export { CreatureLogSchema, insertCreatureLog};
export { CreatureLogSchema, insertCreatureLog, logRoll};