Security fixes (#32)
* Generic Object Injection Sink * (fix) "Character" is not defined. * added eslint * improve code quality, use refactored function * (fix) eslint jest * "Character" is not defined * removed unused file Compare.js * (fix) PointsUsed is not defined * (fix) eslint moans jsconfig * turn off "no-prototype-builtins" * push code coverage
This commit is contained in:
75
.eslintrc.json
Normal file
75
.eslintrc.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 10,
|
||||
"sourceType": "script",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"constructor-super": 2,
|
||||
"for-direction": 2,
|
||||
"getter-return": 2,
|
||||
"no-async-promise-executor": 2,
|
||||
"no-case-declarations": 2,
|
||||
"no-class-assign": 2,
|
||||
"no-compare-neg-zero": 2,
|
||||
"no-cond-assign": 2,
|
||||
"no-const-assign": 2,
|
||||
"no-constant-condition": 2,
|
||||
"no-control-regex": 2,
|
||||
"no-debugger": 2,
|
||||
"no-delete-var": 2,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-class-members": 2,
|
||||
"no-dupe-else-if": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-empty": 2,
|
||||
"no-empty-character-class": 2,
|
||||
"no-empty-pattern": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extra-boolean-cast": 2,
|
||||
"no-extra-semi": 2,
|
||||
"no-fallthrough": 2,
|
||||
"no-func-assign": 2,
|
||||
"no-global-assign": 2,
|
||||
"no-import-assign": 2,
|
||||
"no-inner-declarations": 2,
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-misleading-character-class": 2,
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"no-new-symbol": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-octal": 2,
|
||||
"no-prototype-builtins": 0,
|
||||
"no-redeclare": 2,
|
||||
"no-regex-spaces": 2,
|
||||
"no-self-assign": 2,
|
||||
"no-setter-return": 2,
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-sparse-arrays": 2,
|
||||
"no-this-before-super": 2,
|
||||
"no-undef": 2,
|
||||
"no-unexpected-multiline": 2,
|
||||
"no-unreachable": 2,
|
||||
"no-unsafe-finally": 2,
|
||||
"no-unsafe-negation": 2,
|
||||
"no-unused-labels": 2,
|
||||
"no-unused-vars": 2,
|
||||
"no-useless-catch": 2,
|
||||
"no-useless-escape": 2,
|
||||
"no-with": 2,
|
||||
"require-yield": 2,
|
||||
"use-isnan": 2,
|
||||
"valid-typeof": 2
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
"jest": true,
|
||||
"commonjs": true,
|
||||
"es2017": true
|
||||
},
|
||||
"extends": ["prettier"]
|
||||
}
|
6
.github/workflows/node.js.yml
vendored
6
.github/workflows/node.js.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x, 15.x]
|
||||
node-version: [15.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@ -30,6 +30,10 @@ jobs:
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
- name: Run codacy-coverage-reporter
|
||||
uses: codacy/codacy-coverage-reporter-action@v1
|
||||
with:
|
||||
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
|
||||
|
||||
deploy:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# DSA Discord Bot
|
||||
|
||||
     [](https://github.com/TobenderZephyr/dsabot/actions/workflows/codeql-analysis.yml)
|
||||
     [](https://github.com/TobenderZephyr/dsabot/actions/workflows/codeql-analysis.yml) [](https://www.codacy.com/gh/TobenderZephyr/dsabot/dashboard?utm_source=github.com&utm_medium=referral&utm_content=TobenderZephyr/dsabot&utm_campaign=Badge_Grade)
|
||||
|
||||
This Project is a fork of LucaSchwan/dsa-bot.
|
||||
|
||||
|
@ -139,7 +139,7 @@ it('should abort with a message: no entry found', () => {
|
||||
};
|
||||
const handleAttack = rewireUtils.__get__('handleAttack');
|
||||
//expect(handleAttack(err)).toThrowError();
|
||||
expect(handleAttack(null, [], { message: message })).toEqual(
|
||||
expect(handleAttack([], { message: message })).toEqual(
|
||||
'Sorry, für dich habe ich leider keinen Eintrag 😥'
|
||||
);
|
||||
});
|
||||
@ -152,7 +152,7 @@ it('should abort with a message: No such weapon', () => {
|
||||
};
|
||||
const handleAttack = rewireUtils.__get__('handleAttack');
|
||||
const args = [''];
|
||||
expect(handleAttack(null, [{ character: {} }], { message: message, args: args })).toEqual(
|
||||
expect(handleAttack([{ character: {} }], { message: message, args: args })).toEqual(
|
||||
'Diese Waffe gibt es nicht.'
|
||||
);
|
||||
});
|
||||
@ -178,9 +178,9 @@ it('complete run with melee weapon', () => {
|
||||
};
|
||||
const handleAttack = rewireUtils.__get__('handleAttack');
|
||||
const args = ['messer'];
|
||||
expect(
|
||||
handleAttack(null, [{ character: character }], { message: message, args: args })
|
||||
).toEqual(expect.any(String));
|
||||
expect(handleAttack([{ character: character }], { message: message, args: args })).toEqual(
|
||||
expect.any(String)
|
||||
);
|
||||
});
|
||||
|
||||
it('complete run with ranged weapon', () => {
|
||||
@ -204,7 +204,7 @@ it('complete run with ranged weapon', () => {
|
||||
};
|
||||
const handleAttack = rewireUtils.__get__('handleAttack');
|
||||
const args = ['langbogen'];
|
||||
expect(
|
||||
handleAttack(null, [{ character: character }], { message: message, args: args })
|
||||
).toEqual(expect.any(String));
|
||||
expect(handleAttack([{ character: character }], { message: message, args: args })).toEqual(
|
||||
expect.any(String)
|
||||
);
|
||||
});
|
||||
|
@ -17,8 +17,17 @@ const TestValues = [
|
||||
[13, 5],
|
||||
[14, 5],
|
||||
[15, 5],
|
||||
[16, 6],
|
||||
[17, 6],
|
||||
[18, 6],
|
||||
[19, 6],
|
||||
[20, 6],
|
||||
];
|
||||
|
||||
test.each(TestValues)('Retrieving Quality for %s', (input, output) => {
|
||||
expect(CalculateQuality(input)).toBe(output);
|
||||
});
|
||||
|
||||
it('should return 1 without input', () => {
|
||||
expect(CalculateQuality()).toBe(1);
|
||||
});
|
||||
|
@ -4,3 +4,7 @@ const { Capitalize } = require('@dsabot/Capitalize');
|
||||
it('should capitalize the first letter.', () => {
|
||||
expect(Capitalize('mother')).toBe('Mother');
|
||||
});
|
||||
|
||||
it('should capitalize without any word given', () => {
|
||||
expect(Capitalize()).toBe('None');
|
||||
});
|
||||
|
@ -7,3 +7,13 @@ it('turn any number into a string', () => {
|
||||
expect(f(0)).toBe('0');
|
||||
expect(f(-1)).toBe('-1');
|
||||
});
|
||||
|
||||
it('should return a string', () => {
|
||||
const obj = {
|
||||
Attributes: [8, 8, 8],
|
||||
Throws: [7, 7, 7],
|
||||
PointsUsed: [0, 0, 0],
|
||||
Bonus: 0,
|
||||
};
|
||||
expect(CreateResultTable(obj)).toEqual(expect.any(String));
|
||||
});
|
||||
|
@ -13,16 +13,21 @@ module.exports = {
|
||||
|
||||
async exec(message, args) {
|
||||
try {
|
||||
db.find({ user: message.author.tag }, (err, docs) =>
|
||||
handleAttack(err, docs, { message: message, args: args })
|
||||
);
|
||||
db.find({ user: message.author.tag }, (err, docs) => {
|
||||
if (err) {
|
||||
message.reply(findMessage('ERROR'));
|
||||
throw new Error(err);
|
||||
}
|
||||
handleAttack(docs, { message: message, args: args });
|
||||
});
|
||||
} catch (e) {
|
||||
message.reply(findMessage('ERROR'));
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function handleAttack(err, docs, { message: message, args: args }) {
|
||||
function handleAttack(docs, { message: message, args: args }) {
|
||||
if (docs.length === 0) {
|
||||
return message.reply(findMessage('NOENTRY'));
|
||||
}
|
||||
|
@ -1,96 +1,116 @@
|
||||
const globals = require('../globals');
|
||||
const { CountOccurences } = require('@dsabot/CountOccurences');
|
||||
const { findMessage } = require('@dsabot/findMessage');
|
||||
const { CountOccurences } = require('@dsabot/CountOccurences');
|
||||
const Random = require('random');
|
||||
const db = globals.db;
|
||||
|
||||
module.exports = {
|
||||
name: 'attribute',
|
||||
description: '',
|
||||
aliases: ['ap', 'ep'],
|
||||
usage: '<Eigenschaft> / <Eigenschaftswert>',
|
||||
needs_args: true,
|
||||
async exec(message, args) {
|
||||
try {
|
||||
let Attribute;
|
||||
let AttributeName;
|
||||
let Level = 8;
|
||||
await db.find({
|
||||
user: message.author.tag,
|
||||
}, async (err, docs) => {
|
||||
name: 'attribute',
|
||||
description: '',
|
||||
aliases: ['ap', 'ep'],
|
||||
usage: '<Eigenschaft> / <Eigenschaftswert>',
|
||||
needs_args: true,
|
||||
async exec(message, args) {
|
||||
let Attribute;
|
||||
let AttributeName;
|
||||
let Level = 8;
|
||||
await db.find(
|
||||
{
|
||||
user: message.author.tag,
|
||||
},
|
||||
async (err, docs) => {
|
||||
// user calls with text, let's look him up in the database.
|
||||
if (isNaN(args[0])) {
|
||||
Attribute = HandleNamedAttributes({
|
||||
Character: docs[0].character,
|
||||
args: args,
|
||||
});
|
||||
AttributeName = Attribute.Name;
|
||||
Level = Attribute.Level;
|
||||
} else {
|
||||
Level = args[0];
|
||||
}
|
||||
Random.use(message.author.tag);
|
||||
|
||||
// user calls with text, let's look him up in the database.
|
||||
if (isNaN(args[0])) {
|
||||
Attribute = HandleNamedAttributes({
|
||||
Character: docs[0].character,
|
||||
args: args
|
||||
});
|
||||
AttributeName = Attribute.Name;
|
||||
Level = Attribute.Level;
|
||||
} else {
|
||||
Level = args[0];
|
||||
}
|
||||
Random.use(message.author.tag);
|
||||
|
||||
const dice = [];
|
||||
dice.push(Random.int(1, 20));
|
||||
if (dice[0] == 1 || dice[0] == 20) {
|
||||
dice.push(Random.int(1, 20));
|
||||
}
|
||||
// handle crits
|
||||
if (CountOccurences(dice, 1) == 2) {
|
||||
message.reply('Du hast einen kritischen Erfolg erzielt (' + dice.join(', ') + ')! 🎉🥳🎆');
|
||||
return;
|
||||
} else if (CountOccurences(dice, 20) == 2) {
|
||||
message.reply('Du hast einen Patzer (' + dice.join(', ') + ')! 😭 Viel Erfolg beim nächsten mal!');
|
||||
return;
|
||||
}
|
||||
if ((dice.length == 2 && dice[0] != 20 && dice[1] <= Level) || (dice.length == 1 && dice[0] <= Level)) {
|
||||
if (AttributeName) {
|
||||
message.reply('Du hast die Probe auf ' + AttributeName + ' (Stufe ' + Level + ') bestanden.\n' +
|
||||
'Deine 🎲: ' + dice.join(', '));
|
||||
} else {
|
||||
message.reply('Du hast die Probe (Stufe ' + Level + ') bestanden.\n' +
|
||||
'Deine 🎲: ' + dice.join(', '));
|
||||
}
|
||||
} else if (AttributeName) {
|
||||
message.reply('Du hast die Probe auf ' + AttributeName + ' (Stufe ' + Level + ') leider nicht bestanden 😢.\n' +
|
||||
'Deine 🎲: ' + dice.join(', '));
|
||||
} else {
|
||||
message.reply('Du hast die Probe (Stufe ' + Level + ') leider nicht bestanden 😢.\n' +
|
||||
'Deine 🎲: ' + dice.join(', '));
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
const dice = [];
|
||||
dice.push(Random.int(1, 20));
|
||||
if (dice[0] === 1 || dice[0] === 20) {
|
||||
dice.push(Random.int(1, 20));
|
||||
}
|
||||
// handle crits
|
||||
if (CountOccurences(dice, 1) === 2) {
|
||||
message.reply(
|
||||
`Du hast einen kritischen Erfolg erzielt (${dice.join(', ')})! 🎉🥳🎆`
|
||||
);
|
||||
return;
|
||||
} else if (CountOccurences(dice, 20) === 2) {
|
||||
message.reply(
|
||||
'Du hast einen Patzer (' +
|
||||
dice.join(', ') +
|
||||
')! 😭 Viel Erfolg beim nächsten mal!'
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
(dice.length == 2 && dice[0] != 20 && dice[1] <= Level) ||
|
||||
(dice.length == 1 && dice[0] <= Level)
|
||||
) {
|
||||
if (AttributeName) {
|
||||
message.reply(
|
||||
'Du hast die Probe auf ' +
|
||||
AttributeName +
|
||||
' (Stufe ' +
|
||||
Level +
|
||||
') bestanden.\n' +
|
||||
'Deine 🎲: ' +
|
||||
dice.join(', ')
|
||||
);
|
||||
} else {
|
||||
message.reply(
|
||||
'Du hast die Probe (Stufe ' +
|
||||
Level +
|
||||
') bestanden.\n' +
|
||||
'Deine 🎲: ' +
|
||||
dice.join(', ')
|
||||
);
|
||||
}
|
||||
} else if (AttributeName) {
|
||||
message.reply(
|
||||
'Du hast die Probe auf ' +
|
||||
AttributeName +
|
||||
' (Stufe ' +
|
||||
Level +
|
||||
') leider nicht bestanden 😢.\n' +
|
||||
'Deine 🎲: ' +
|
||||
dice.join(', ')
|
||||
);
|
||||
} else {
|
||||
message.reply(
|
||||
`Du hast die Probe (Stufe ${Level}) leider nicht bestanden 😢.\nDeine 🎲: ${dice.join(
|
||||
', '
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
const HandleCrits = (dice) => {
|
||||
function HandleNamedAttributes({ Character: Character = [], args: args = [] } = {}) {
|
||||
let Attribute = getAttribute(args[0]);
|
||||
let Level = getAttributeLevel(Character, Attribute) || 8;
|
||||
|
||||
};
|
||||
return {
|
||||
Name: Attribute.name,
|
||||
Level: Level,
|
||||
};
|
||||
}
|
||||
|
||||
const HandleNamedAttributes = ({Character: Character = [], args: args = []} = {}) => {
|
||||
function getAttributeLevel(Character = {}, Attribute = {}) {
|
||||
return Character.attributes.find(attribute => attribute.id === Attribute.id).level;
|
||||
}
|
||||
|
||||
let Attributes = globals.Werte;
|
||||
let Level = 8; // This is the minimum attributes value.
|
||||
let AttributeName;
|
||||
let AttributeId;
|
||||
|
||||
if (args[0].length == 2) {
|
||||
AttributeId = Attributes.find(attribute => attribute.kuerzel === args[0].toUpperCase()).id;
|
||||
} else {
|
||||
AttributeId = args[0].toLowerCase() ||
|
||||
Attributes.find(attribute => attribute.name.toLowerCase() === args[0].toLowerCase()).id;
|
||||
}
|
||||
|
||||
Level = Character.attributes.find(attribute => attribute.id === AttributeId).level;
|
||||
AttributeName = Attributes.find(attribute => attribute.id === AttributeId).name;
|
||||
|
||||
return {
|
||||
Name: AttributeName,
|
||||
Level: Level
|
||||
};
|
||||
|
||||
};
|
||||
function getAttribute(attribute = '') {
|
||||
return attribute.length === 2
|
||||
? globals.Werte.find(a => a.kuerzel === attribute.toUpperCase())
|
||||
: globals.Werte.find(a => a.name.toLowerCase() === attribute.toLowerCase());
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ module.exports = {
|
||||
if (docs.length === 0) {
|
||||
return message.reply(findMessage('NOENTRY'));
|
||||
}
|
||||
Character = docs[0].character;
|
||||
const Character = docs[0].character;
|
||||
if (!Character.hasOwnProperty('chants')) return message.reply(findMessage('NO_CHANTS'));
|
||||
if (args.length === 0) {
|
||||
const Embed = new Discord.MessageEmbed()
|
||||
|
@ -1,17 +1,21 @@
|
||||
const { findMessage }= require('@dsabot/findMessage');
|
||||
const { findMessage } = require('@dsabot/findMessage');
|
||||
const globals = require('../globals');
|
||||
const db = globals.db;
|
||||
module.exports = {
|
||||
name: 'remove',
|
||||
description: 'Löscht deinen Charakter aus der Datenbank. Sinnvoll, wenn du mir eine neue zusenden möchtest.',
|
||||
aliases: [],
|
||||
usage: '',
|
||||
needs_args: false,
|
||||
async exec(message, args) {
|
||||
db.remove({
|
||||
user: message.author.tag,
|
||||
}, {}, function(err, numRemoved) {
|
||||
return message.reply(findMessage('DELETED_DATA'));
|
||||
});
|
||||
},
|
||||
};
|
||||
name: 'remove',
|
||||
description:
|
||||
'Löscht deinen Charakter aus der Datenbank. Sinnvoll, wenn du mir eine neue zusenden möchtest.',
|
||||
aliases: [],
|
||||
usage: '',
|
||||
needs_args: false,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async exec(message, args) {
|
||||
db.remove({ user: message.author.tag }, err => {
|
||||
if (err) {
|
||||
message.reply(findMessage('ERROR'));
|
||||
throw new Error(err);
|
||||
}
|
||||
return message.reply(findMessage('DELETED_DATA'));
|
||||
});
|
||||
},
|
||||
};
|
||||
|
@ -2,40 +2,48 @@
|
||||
const globals = require('../globals');
|
||||
const Discord = require('discord.js');
|
||||
const db = globals.db;
|
||||
const { findMessage }= require('@dsabot/findMessage');
|
||||
const { findMessage } = require('@dsabot/findMessage');
|
||||
|
||||
module.exports = {
|
||||
name: 'show',
|
||||
description: '',
|
||||
aliases: [],
|
||||
usage: '',
|
||||
needs_args: false,
|
||||
name: 'show',
|
||||
description: '',
|
||||
aliases: [],
|
||||
usage: '',
|
||||
needs_args: false,
|
||||
|
||||
async exec(message, args) {
|
||||
try {
|
||||
db.find({
|
||||
user: message.author.tag,
|
||||
}, function(err, docs) {
|
||||
if (docs.length === 0) {
|
||||
return message.reply(findMessage('NOENTRY'));
|
||||
}
|
||||
else {
|
||||
const Character = docs[0].character;
|
||||
let Gender;
|
||||
if (Character.sex == 'female') { Gender = '♀️'; }
|
||||
else { Gender = '♂️'; }
|
||||
const Reply = new Discord.MessageEmbed();
|
||||
Reply.setColor('#0099ff');
|
||||
Reply.setTitle(`${Gender} ${Character.name}`);
|
||||
Reply.setDescription(`${Character.age} Jahre, ${Character.race}/${Character.culture}`);
|
||||
Reply.addField(Character.professionname, Character.xp.startinglevel);
|
||||
|
||||
message.reply( Reply );
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
};
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async exec(message, args) {
|
||||
try {
|
||||
db.find(
|
||||
{
|
||||
user: message.author.tag,
|
||||
},
|
||||
function (err, docs) {
|
||||
if (docs.length === 0) {
|
||||
return message.reply(findMessage('NOENTRY'));
|
||||
} else {
|
||||
const Character = docs[0].character;
|
||||
let Gender;
|
||||
if (Character.sex == 'female') {
|
||||
Gender = '♀️';
|
||||
} else {
|
||||
Gender = '♂️';
|
||||
}
|
||||
const Reply = new Discord.MessageEmbed();
|
||||
Reply.setColor('#0099ff');
|
||||
Reply.setTitle(`${Gender} ${Character.name}`);
|
||||
Reply.setDescription(
|
||||
`${Character.age} Jahre, ${Character.race}/${Character.culture}`
|
||||
);
|
||||
Reply.addField(Character.professionname, Character.xp.startinglevel);
|
||||
|
||||
message.reply(Reply);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
message.reply(findMessage('ERROR'));
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -16,7 +16,7 @@ module.exports = {
|
||||
if (docs.length === 0) {
|
||||
return message.reply(findMessage('NOENTRY'));
|
||||
}
|
||||
Character = docs[0].character;
|
||||
const Character = docs[0].character;
|
||||
if (!Character.hasOwnProperty('spells')) return message.reply(findMessage('NO_SPELLS'));
|
||||
if (args.length === 0) {
|
||||
const Embed = new Discord.MessageEmbed()
|
||||
@ -52,6 +52,8 @@ const ReplySpell = (Spell = {}) => {
|
||||
const createSpellList = (Character = {}) => {
|
||||
if (!Character || !Character.hasOwnProperty('spells')) return;
|
||||
let SpellList = [];
|
||||
Character.spells.forEach(spell => SpellList.push(getSpell({ Character: Character, spell_name: spell.id })));
|
||||
Character.spells.forEach(spell =>
|
||||
SpellList.push(getSpell({ Character: Character, spell_name: spell.id }))
|
||||
);
|
||||
return SpellList.filter(value => value !== undefined); //?+
|
||||
};
|
||||
|
131
commands/Tp.js
131
commands/Tp.js
@ -1,85 +1,64 @@
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const Random = require('random');
|
||||
const globals = require('../globals');
|
||||
const Discord = require('discord.js');
|
||||
const { roll } = require('@dsabot/Roll');
|
||||
const { findMessage }= require('@dsabot/findMessage');
|
||||
const { findMessage } = require('@dsabot/findMessage');
|
||||
const { CompareResults } = require('@dsabot/CompareResults');
|
||||
module.exports = {
|
||||
name: 'tp',
|
||||
description: 'Du machst eine Fertigkeitsprobe.\n' +
|
||||
' Es werden drei Würfel auf deine Eigenschaftswerte geworfen. Hast du Boni auf dein Talent und/oder' +
|
||||
' ist der Wurf erleichtert oder erschwert, wird dies in die Berechnung einbezogen.',
|
||||
aliases: ['talentprobe'],
|
||||
usage: '<Eigenschaftswert1> <Eigenschaftswert2> <Eigenschaftswert3> [<Fertigkeitswert>] [<-Erschwernis> / <+Erleichterung>]',
|
||||
needs_args: true,
|
||||
name: 'tp',
|
||||
description:
|
||||
'Du machst eine Fertigkeitsprobe.\n' +
|
||||
' Es werden drei Würfel auf deine Eigenschaftswerte geworfen. Hast du Boni auf dein Talent und/oder' +
|
||||
' ist der Wurf erleichtert oder erschwert, wird dies in die Berechnung einbezogen.',
|
||||
aliases: ['talentprobe'],
|
||||
usage:
|
||||
'<Eigenschaftswert1> <Eigenschaftswert2> <Eigenschaftswert3> [<Fertigkeitswert>] [<-Erschwernis> / <+Erleichterung>]',
|
||||
needs_args: true,
|
||||
|
||||
async exec(message, args) {
|
||||
async exec(message, args) {
|
||||
if (isNaN(args[0])) {
|
||||
return message.reply(findMessage('WRONG_ARGUMENTS'));
|
||||
}
|
||||
|
||||
if(isNaN(args[0])) {
|
||||
return message.reply(findMessage('WRONG_ARGUMENTS'));
|
||||
}
|
||||
let Bonus = parseInt(args[3]) || 0;
|
||||
let Erschwernis = parseInt(args[4]) || 0;
|
||||
|
||||
//Random.use(message.author.tag);
|
||||
//const dice = [];
|
||||
let bonus = 0;
|
||||
let bonus_orig = 0;
|
||||
let erschwernis = 0;
|
||||
if (args[3]) {
|
||||
bonus_orig = parseInt(args[3]);
|
||||
bonus = bonus_orig;
|
||||
}
|
||||
if (args[4]) {
|
||||
erschwernis = parseInt(args[4]);
|
||||
}
|
||||
/*for (let i = 1; i <= 3; i++) {
|
||||
roll.push(Random.int(1, 20));
|
||||
}*/
|
||||
const dice = roll(3,20,message.author.tag).dice;
|
||||
const dice = roll(3, 20, message.author.tag).dice;
|
||||
|
||||
let ok = 0;
|
||||
let patzer = 0;
|
||||
let crit = 0;
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (Math.floor(parseInt(args[i]) + parseInt(erschwernis)) >= dice[i]) {
|
||||
ok++;
|
||||
} else if (
|
||||
Math.floor(parseInt(args[i]) + parseInt(bonus) + parseInt(erschwernis)) >= dice[i]) {
|
||||
ok++;
|
||||
bonus = bonus - (dice[i] - parseInt(erschwernis) - parseInt(args[i]));
|
||||
}
|
||||
if (dice[i] == 1) {crit++;}
|
||||
if (dice[i] == 20) {patzer++;}
|
||||
}
|
||||
const {
|
||||
Passed: Passed,
|
||||
CriticalHit: CriticalHit,
|
||||
Fumbles: Fumbles,
|
||||
PointsRemaining: PointsRemaining} = CompareResults(dice, [args[0], args[1], args[2]], Bonus, Erschwernis);
|
||||
|
||||
const Reply = new Discord.MessageEmbed();
|
||||
Reply.setTitle(`${findMessage('ROLL')} ${dice.join(', ')}.`);
|
||||
if (patzer >= 2) {
|
||||
Reply.setColor('#900c3f');
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_CRIT_FAILURE'),
|
||||
value: findMessage('MSG_CRIT_FAILURE'),
|
||||
inline: false
|
||||
});
|
||||
} else if (crit >= 2) {
|
||||
Reply.setColor('#1E8449');
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_CRIT_SUCCESS'),
|
||||
value: findMessage('MSG_CRIT_SUCCESS'),
|
||||
inline: false
|
||||
});
|
||||
} else if (ok < 3) {
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_FAILURE'),
|
||||
value: 'Nur ' + ok + '/3 Proben erfolgreich. 😪',
|
||||
inline: false
|
||||
});
|
||||
} else {
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_SUCCESS'),
|
||||
value: ok + '/3 Proben erfolgreich. Dein Bonus: ' + bonus + '/' + bonus_orig + '.',
|
||||
inline: false
|
||||
});
|
||||
}
|
||||
message.reply(Reply);
|
||||
}
|
||||
};
|
||||
const Reply = new Discord.MessageEmbed();
|
||||
Reply.setTitle(`${findMessage('ROLL')} ${dice.join(', ')}.`);
|
||||
if (Fumbles >= 2) {
|
||||
Reply.setColor('#900c3f');
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_CRIT_FAILURE'),
|
||||
value: findMessage('MSG_CRIT_FAILURE'),
|
||||
inline: false,
|
||||
});
|
||||
} else if (CriticalHit >= 2) {
|
||||
Reply.setColor('#1E8449');
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_CRIT_SUCCESS'),
|
||||
value: findMessage('MSG_CRIT_SUCCESS'),
|
||||
inline: false,
|
||||
});
|
||||
} else if (Passed < 3) {
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_FAILURE'),
|
||||
value: `${Passed ? `Nur ${Passed}/3 Proben` : `Keine Probe`} erfolgreich. 😪`,
|
||||
inline: false,
|
||||
});
|
||||
} else {
|
||||
Reply.addFields({
|
||||
name: findMessage('TITLE_SUCCESS'),
|
||||
value: `${Passed}/3 Proben erfolgreich. Dein Bonus: ${PointsRemaining}/${Bonus}`,
|
||||
inline: false,
|
||||
});
|
||||
}
|
||||
message.reply(Reply);
|
||||
},
|
||||
};
|
||||
|
@ -1,15 +1,9 @@
|
||||
const CalculateQuality = (PointsAvailable = 0) => {
|
||||
if (PointsAvailable <= 3)
|
||||
return 1;
|
||||
else if (PointsAvailable > 3 && PointsAvailable <= 6)
|
||||
return 2;
|
||||
else if (PointsAvailable > 6 && PointsAvailable <= 9)
|
||||
return 3;
|
||||
else if (PointsAvailable > 9 && PointsAvailable <= 12)
|
||||
return 4;
|
||||
else if (PointsAvailable > 12 && PointsAvailable <= 15)
|
||||
return 5;
|
||||
else if (PointsAvailable > 15)
|
||||
return 6;
|
||||
if (PointsAvailable <= 3) return 1;
|
||||
else if (PointsAvailable > 3 && PointsAvailable <= 6) return 2;
|
||||
else if (PointsAvailable > 6 && PointsAvailable <= 9) return 3;
|
||||
else if (PointsAvailable > 9 && PointsAvailable <= 12) return 4;
|
||||
else if (PointsAvailable > 12 && PointsAvailable <= 15) return 5;
|
||||
else return 6;
|
||||
};
|
||||
module.exports = { CalculateQuality };
|
||||
|
@ -1,6 +0,0 @@
|
||||
const Compare = () => {
|
||||
|
||||
return { result };
|
||||
};
|
||||
|
||||
module.exports = { Compare };
|
@ -18,28 +18,28 @@ const CompareResults = (
|
||||
let CriticalHit = 0;
|
||||
let AllPointsUsed = [];
|
||||
|
||||
for (let i = 0; i < Throws.length; i++) {
|
||||
Throws.forEach((Throw, key) => {
|
||||
let PointsUsed = 0;
|
||||
if (Math.floor(AttributeLevels[i] + Bonus) >= Throws[i]) {
|
||||
let AttributeLevel = AttributeLevels.find((v, k) => key === k);
|
||||
if (Math.floor(AttributeLevel + Bonus) >= Throw) {
|
||||
Passed++;
|
||||
} else if (Math.floor(AttributeLevels[i] + PointsRemaining + Bonus) >= Throws[i]) {
|
||||
} else if (Math.floor(AttributeLevel + PointsRemaining + Bonus) >= Throw) {
|
||||
Passed++;
|
||||
PointsUsed = Throws[i] - Bonus - AttributeLevels[i];
|
||||
PointsUsed = Throw - Bonus - AttributeLevel;
|
||||
PointsRemaining -= PointsUsed;
|
||||
} else {
|
||||
// We need to use all our points, so that next die/dice
|
||||
// would not return a 'Passed'.
|
||||
PointsUsed = PointsRemaining;
|
||||
PointsRemaining -= PointsUsed;
|
||||
}
|
||||
if (Throws[i] == 1) {
|
||||
if (Throw === 1) {
|
||||
CriticalHit++;
|
||||
}
|
||||
if (Throws[i] == 20) {
|
||||
if (Throw === 20) {
|
||||
Fumbles++;
|
||||
}
|
||||
AllPointsUsed.push(PointsUsed);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
Passed: Passed,
|
||||
CriticalHit: CriticalHit,
|
||||
|
@ -7,10 +7,10 @@
|
||||
"@data/*": ["./data/*"],
|
||||
"@Commands/*": ["./commands/*"],
|
||||
"@Lib/*": ["./lib/*"]
|
||||
},
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules"],
|
||||
"typeAcquisition": {
|
||||
"exclude": [ "dotenv", "source-map" ]
|
||||
},
|
||||
}
|
||||
"exclude": ["dotenv", "source-map"]
|
||||
}
|
||||
}
|
||||
|
45
package-lock.json
generated
45
package-lock.json
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "dsabot",
|
||||
"version": "1.5.0",
|
||||
"version": "1.5.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.5.0",
|
||||
"version": "1.5.2",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"discord.js": "^12.5.3",
|
||||
@ -17,6 +17,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.23",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.8.0",
|
||||
"jest": "^26.6.3",
|
||||
"rewire": "^5.0.0"
|
||||
}
|
||||
@ -2027,6 +2029,21 @@
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-prettier": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.8.0.tgz",
|
||||
"integrity": "sha512-aq4M7mjjVregZ2l45O9qz6Mv6f5zVMl/IqfmUL8hNOoDAzVKYMhYPJytbqE/lPIVO1iMDXIFqjiEE59BfJZpZw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"get-stdin": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"eslint-config-prettier-check": "bin/cli.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=3.14.1"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
@ -2857,6 +2874,15 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stdin": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
|
||||
"integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
@ -8924,6 +8950,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-config-prettier": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.8.0.tgz",
|
||||
"integrity": "sha512-aq4M7mjjVregZ2l45O9qz6Mv6f5zVMl/IqfmUL8hNOoDAzVKYMhYPJytbqE/lPIVO1iMDXIFqjiEE59BfJZpZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-stdin": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
@ -9423,6 +9458,12 @@
|
||||
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"get-stdin": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
|
||||
"integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
|
||||
"dev": true
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
|
@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"lint": "eslint commands/",
|
||||
"start": "node index.js",
|
||||
"test": "jest"
|
||||
"test": "jest --collectCoverage"
|
||||
},
|
||||
"_moduleAliases": {
|
||||
"@dsabot": "functions",
|
||||
@ -26,6 +26,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.23",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.8.0",
|
||||
"jest": "^26.6.3",
|
||||
"rewire": "^5.0.0"
|
||||
},
|
||||
@ -35,6 +37,7 @@
|
||||
"**/*.{js,jsx}",
|
||||
"!**/node_modules/**",
|
||||
"!**/vendor/**"
|
||||
]
|
||||
],
|
||||
"coverageDirectory": "coverage"
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user