mami/src/mami.js/txtrigs.js

131 lines
4.1 KiB
JavaScript

const MamiTextTrigger = function(info) {
const type = info.type,
match = info.match;
for(const i in match) {
match[i] = match[i].split(';');
for(const j in match[i])
match[i][j] = match[i][j].trim().split(':');
}
const pub = {
getType: function() { return type; },
isSoundType: function() { return type === 'sound'; },
isAliasType: function() { return type === 'alias'; },
isMatch: function(matchText) {
for(const i in match) {
const out = (function(filters, text) {
let result = false;
for(const j in filters) {
const filter = filters[j];
switch(filter[0]) {
case 'lc':
text = text.toLowerCase();
break;
case 'is':
if(text === filter.slice(1).join(':'))
result = true;
break;
case 'starts':
if(text.indexOf(filter.slice(1).join(':')) === 0)
result = true;
break;
case 'has':
if(text.includes(filter.slice(1).join(':')))
result = true;
break;
case 'hasnot':
if(text.includes(filter.slice(1).join(':')))
result = false;
break;
default:
console.error('Unknown filter encountered: ' + filter.join(':'));
break;
}
}
return result;
})(match[i], matchText);
if(out) return true;
}
return false;
},
};
if(type === 'sound') {
const volume = info.volume || 1.0,
rate = info.rate || 1.0,
names = info.sounds || [];
pub.getVolume = function() { return volume; };
pub.getRate = function() {
if(rate === 'rng')
return 1.8 - (Math.random() * 1.5);
return rate;
};
pub.getSoundNames = function() { return names; };
pub.getRandomSoundName = function() { return names[Math.floor(Math.random() * names.length)]; };
} else if(type === 'alias') {
const aliasFor = info.for || [];
pub.getFor = function() { return aliasFor; };
} else
throw 'Unsupported trigger type.';
return pub;
};
const MamiTextTriggers = function() {
let triggers = [];
const addTrigger = function(triggerInfo) {
if(triggerInfo === null || typeof triggerInfo.type !== 'string')
throw 'triggerInfo is not a valid trigger';
triggers.push(new MamiTextTrigger(triggerInfo));
};
const getTrigger = function(text, returnAlias) {
for(const i in triggers) {
let trigger = triggers[i];
if(trigger.isMatch(text)) {
if(trigger.isAliasType() && !returnAlias) {
const aliasFor = trigger.getFor();
trigger = getTrigger(aliasFor[Math.floor(Math.random() * aliasFor.length)]);
}
return trigger;
}
}
throw 'no trigger that matches this text';
};
return {
addTrigger: addTrigger,
addTriggers: function(triggerInfos) {
for(const i in triggerInfos)
try {
addTrigger(triggerInfos[i]);
} catch(ex) {
console.error(ex);
}
},
clearTriggers: function() {
triggers = [];
},
hasTriggers: function() {
return triggers.length > 0;
},
getTrigger: getTrigger,
};
};