Skip to content

Instantly share code, notes, and snippets.

@drewhoener
Created March 25, 2020 00:38
Show Gist options
  • Save drewhoener/1419cac5fa703c9990512c686c23ef1d to your computer and use it in GitHub Desktop.
Save drewhoener/1419cac5fa703c9990512c686c23ef1d to your computer and use it in GitHub Desktop.
async execute(message: Message, args: string[]) {
const cur_encounter = await get_encounter(message.channel.id);
if (!cur_encounter) {
message.channel.send(`There isn't an Encounter/RP going on in this channel.\nTo start one, run \`!start [users]\``);
return;
}
if (!cur_encounter.members.find(obj => obj.id === message.author.id)) {
let guild_member = message.guild.members.cache.get(message.author.id);
if (!guild_member || !guild_member.hasPermission('MANAGE_CHANNELS')) {
message.channel.send(`You aren't part of this session ${message.author.toString()}! Have someone participating end it.`);
return;
}
}
let end_time = now();
let response = bot_embed(message.client.user, 'Session Results', null, 'Point Totals');
let history = {};
let date = moment().hour(0).minute(0).second(0).millisecond(0);
for (let elem of cur_encounter.members) {
//Get name for pretty display formatting
let name = `${elem.id}`;
try {
name = await message.guild.members.get(elem.id).displayName;
} catch (err) {
logger.error('', err);
}
//Duration of play and points calculation
if (cur_encounter.type === 1) {
logger.info(`Encounter is quest, not using mod time`);
}
let last_message = (!cur_encounter.hasOwnProperty('type') || cur_encounter.type === 0) ? cur_encounter.last_message : moment.now();
let hour_mod_offset = moment.duration(moment.now() - last_message);
//logger.info(`Duration Difference is: ${dur.asMinutes().toFixed(2)}`);
let mod_hours = hour_mod_offset.asHours();
if (mod_hours < 1 || isNaN(mod_hours)) mod_hours = 0;
logger.silly(`Last sent message was ${mod_hours} hour(s). New subtraction will be ${cur_encounter.hour_mod + mod_hours}`);
let duration = moment.duration(end_time - elem.joinedAt);
logger.silly(`Amount is ${duration.asHours().toFixed(2)}. Subtracting ${cur_encounter.hour_mod + mod_hours}`);
duration.subtract(cur_encounter.hour_mod + mod_hours, 'h');
let hours = Math.abs(duration.asHours()).toFixed(2);
if (hours < 1) {
response.addField(`${name} → ${Math.abs(duration.asMinutes()).toFixed(2)} minute(s)`, `0 Points, > 1 hour played`);
continue;
}
let points = Math.round(Math.abs(duration.asHours()) * 5);
//ID checking
let id = await enjin_from_guild(message.guild.id, elem.id);
if (!id) {
response.addField(`${name} → ${hours} hour(s)`, `No Enjin Profile linked, manual entry required. Make a forum post to claim.`);
continue;
}
await add_points(id, points)
.then(async result => {
response.addField(`${name} → ${hours} hour(s)`, `${points} point(s)`);
logger.info(`Credited user ${id} (${elem.id}) ${points} point(s) for duration of ${hours} hours`);
history[`dates.$[elem].${elem.id}`] = duration.asHours();
})
.catch(err => {
response.addField(`${name} → ${hours} hour(s)`, `Failed to credit, talk to a mod`);
logger.error(`Failed to credit user ${id} (${elem.id}) ${points} point(s) for duration of ${hours} hours`);
});
}
remove_encounter(message.guild.id, message.channel.id)
.then(result => logger.info('Encounter deleted'))
.catch(err => logger.error(err));
if (Object.keys(history).length) {
add_history(message.guild.id, message.channel.id, date, end_time, history, message.channel.name).then(result => {
logger.info(`Added user history: `, history);
logger.info(JSON.stringify(result));
}).catch(logger.error);
}
let bonuses = message.content.match(global);
logger.info(JSON.stringify(bonuses));
logger.info(message.content.toString());
let roles = await get_quest_roles(message.guild.id);
let message_member = message.guild.members.get(message.author.id);
if (!bonuses) {
message.channel.send(response);
return;
}
response.addBlankField();
if (cur_encounter.type !== 1) {
response.addField(`Bonuses`, `Bonuses were listed but will not be applied. Bonuses can be applied in a Quest`);
message.channel.send(response);
return;
}
if (!message_member || !roles || !roles.find(role => message_member.roles.has(role))) {
if (message.author.id !== '173923836054470656') {
response.addField(`Bonuses`, `You don't have permission to add bonuses to this Quest`);
message.channel.send(response);
return;
}
}
logger.silly(`Starting Bonus Points`);
let val = '';
for (let index in bonuses) {
let bonus = bonuses[index];
let groups = bonus.match(pattern).groups;
let guild_member = message.guild.members.get(groups.user);
let user_id = groups.user;
let displayName = `<@${user_id}>`;
if (guild_member) {
displayName = guild_member.displayName;
}
let newline = index < bonuses.length - 1 ? '\n' : '';
let id = await enjin_from_guild(message.guild.id, guild_member.id);
if (!id) {
val += `No Enjin profile for ${displayName}. Bonus of ${groups.bonus} will not be applied${newline}`;
logger.info(`No enjin profile for ${user_id}, bonus of ${groups.bonus} points not applied`);
continue;
}
await add_points(id, groups.bonus)
.then(async result => {
val += `${displayName}: ${groups.bonus}${newline}`;
logger.info(`Credited user ${id} (${user_id}) ${groups.bonus} bonus point(s)`);
})
.catch(err => {
val += `Failed to credit ${displayName}: ${groups.bonus} bonus points${newline}`;
logger.error(`Failed to credit user ${id} (${user_id}) ${groups.bonus} bonus point(s)`);
});
}
response.addField(`Bonuses`, val);
message.channel.send(response);
}
const awardPoints = async (message: Message, encounter: IEncounter, response: MessageEmbed, endTime: number) => {
if (!message.guild) {
response.addField('ERROR', 'Reached awardPoints with null guild. Report points manually');
logger.error('For some reason we\'ve reached awardPoints and message guild is null');
return;
}
for (const timeResult of encounter.getTimes(endTime)) {
// Get name for display formatting
let name = `${ timeResult.userId }`;
const guildMember = message.guild.members.cache.get(name);
if (guildMember) {
name = guildMember.displayName;
}
// Start time formatting
const playDuration = duration(timeResult.playTime);
if (playDuration.asHours() < 1) {
response.addField(`${ name } → ${ Math.abs(playDuration.asMinutes()).toFixed(2) } minute(s)`, '0 Points, > 1 hour played');
continue;
}
const points = Math.round(Math.abs(playDuration.asHours()) * 5);
// ID checking
const profile = await Profile.findOne({ discord: timeResult.userId });
if (!profile || !profile.hasEnjin(message.guild.id)) {
response.addField(`${ name } → ${ playDuration.asHours() } hour(s)`, 'No Enjin Profile linked, manual entry required. Make a forum post to claim.');
continue;
}
const hourStr = playDuration.asHours().toFixed(2);
const enjin = profile.getEnjin(message.guild.id);
await profile.addPoints(message.guild.id, points)
.then(() => {
response.addField(`${ name } → ${ hourStr } hour(s)`, `${ points } point(s)`);
// history[`dates.$[elem].${ elem.id }`] = duration.asHours();
if (enjin) {
logger.info(`Credited user ${ enjin.enjin } (${ timeResult.userId }) ${ points } point(s) for duration of ${ hourStr } hours`);
}
}).catch(() => {
response.addField(`${ name } → ${ hourStr } hour(s)`, 'Failed to credit, talk to a mod');
if (enjin) {
logger.error(`Failed to credit user ${ enjin.enjin } (${ timeResult.userId }) ${ points } point(s) for duration of ${ hourStr } hours`);
}
});
}
};
const awardBonus = async (message: Message, response: MessageEmbed, isQuest: boolean): Promise<Message | void> => {
const bonuses = message.content.match(global);
logger.info(JSON.stringify(bonuses));
logger.info(message.content.toString());
if (!message.guild) {
response.addField('ERROR', 'Reached awardBonus with null guild. Report bonus points manually or try again');
logger.error('For some reason we\'ve reached awardBonus and message guild is null');
return;
}
if (!bonuses) {
return;
}
response.addField('\u200b', '\u200b');
const settings = await getSettings(message.guild.id);
if (!settings) {
response.addField('ERROR', 'Bonuses were listed, but the database ran into an error getting the quest roles. Try again or report manually');
return;
}
const roles = settings.quest_roles;
const authorMember = message.guild.members.cache.get(message.author.id);
if (!isQuest) {
response.addField('Bonuses', 'Bonuses were listed but will not be applied. Bonuses can be applied in a Quest');
return;
}
if (!authorMember || !roles || !roles.some(role => authorMember.roles.cache.has(role))) {
if (message.author.id !== '173923836054470656') {
response.addField('Bonuses', 'You don\'t have permission to add bonuses to this Quest');
return;
}
}
logger.silly('Starting Bonus Points');
let val = '';
for (let index = 0; index < bonuses.length; index++) {
// noinspection JSUnfilteredForInLoop
const bonusMatch = bonuses[index].match(pattern);
if (!bonusMatch) {
continue;
}
const groups = bonusMatch.groups;
if (!groups) {
continue;
}
const bonusGuildMember = message.guild.members.cache.get(groups.user);
let displayName = `<@${ groups.user }>`;
if (bonusGuildMember) {
displayName = bonusGuildMember.displayName;
}
const newline = index < bonuses.length - 1 ? '\n' : '';
const profile: IProfile | null = await Profile.findOne({ discord: bonusGuildMember ? bonusGuildMember.id : '-1' });
if (!profile || !profile.hasEnjin(message.guild.id)) {
val += `No Enjin profile for ${ displayName }. Bonus of ${ groups.bonus } will not be applied${ newline }`;
logger.info(`No enjin profile for ${ bonusGuildMember ? bonusGuildMember.id : 'NULL' }, bonus of ${ groups.bonus } points not applied`);
continue;
}
const enjin = profile.getEnjin(message.guild.id);
await profile.addPoints(message.guild.id, parseInt(groups.bonus))
.then(() => {
val += `${ displayName }: ${ groups.bonus }${ newline }`;
if(enjin) {
logger.info(`Credited user ${ enjin.enjin } (${ profile.discord }) ${ groups.bonus } bonus point(s)`);
}
})
.catch(() => {
val += `Failed to credit ${ displayName }: ${ groups.bonus } bonus points${ newline }`;
if(enjin) {
logger.error(`Failed to credit user ${ enjin.enjin } (${ profile.discord }) ${ groups.bonus } bonus point(s)`);
}
});
}
response.addField('Bonuses', val);
};
const execute = async (message: Message, args: string[]): Promise<Message | void> => {
try {
if (!message.guild) {
return;
}
const encounter: IEncounter | null = await Encounter.findOne({ channel: message.channel.id });
if (!encounter) {
return message.channel.send('There isn\'t an Encounter/RP going on in this channel.\nTo start one, run `!start [users]`');
}
// Check to make sure they're either in the session or they have permission to end it
const members = encounter.members;
if (!members || !members.some(elem => elem.id === message.author.id)) {
const guildMember = message.guild.members.cache.get(message.author.id);
if (!guildMember || !guildMember.hasPermission('MANAGE_CHANNELS')) {
return message.channel.send(`You aren't part of this session ${ message.author.toString() }! Have someone participating end it.`);
}
}
const endTime = now();
const isQuest = encounter.type === 1;
const response: MessageEmbed = generateEmbed(message.client.user as User, 'Session Results', null, null, 'Point Totals');
const history = {};
const date = moment().hour(0).minute(0).second(0).millisecond(0);
await awardPoints(message, encounter, response, endTime);
Encounter.deleteOne({ _id: new ObjectId(encounter._id) });
/*
if (Object.keys(history).length) {
add_history(message.guild.id, message.channel.id, date, end_time, history, message.channel.name).then(result => {
logger.info('Added user history: ', history);
logger.info(JSON.stringify(result));
}).catch(logger.error);
}
*/
await awardBonus(message, response, isQuest);
return message.channel.send(response);
} catch (err) {
logger.error(err);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment