Rewrite for commutative game

This commit is contained in:
Ilya 2023-01-23 00:37:18 +03:00
parent b0de760de9
commit b573453a8e
2 changed files with 69 additions and 150 deletions

View File

@ -5,125 +5,73 @@ class Database {
this.pool = new pg.Pool({connectionString: connectionStr}); this.pool = new pg.Pool({connectionString: connectionStr});
} }
async registerQRTeam(name, owner) { async checkAndRegisterUser(id, name) {
let client = await this.pool.connect(); let client = await this.pool.connect();
try { try {
await client.query('BEGIN'); let result = await client.query("SELECT * FROM qr_users WHERE user_id = $1", [id]);
await client.query('INSERT INTO qr_team (team_name, owner_id) values ($1,$2)', [name, owner]); if (result.rowCount === 0) {
await client.query('COMMIT'); await client.query("INSERT INTO qr_users (user_id, name) VALUES ($1, $2)", [id, name]);
}
} finally { } finally {
client.release(); client.release();
} }
} }
/** async codeExists(code) {
*
* @param code
* @returns {Promise<null|{id:number,task_text:number,code:string}>}
*/
async getQRTask(code) {
let client = await this.pool.connect(); let client = await this.pool.connect();
let task = null;
try { try {
await client.query('BEGIN'); let result = await client.query("SELECT * FROM qr_codes WHERE id = $1", [code]);
let res = await client.query('SELECT * FROM qr_tasks WHERE code = $1', [code]); return result.rowCount === 1;
await client.query('COMMIT');
task = res.rows[0];
} finally { } finally {
client.release(); client.release();
} }
return task;
} }
async getTask(id) { async useCode(code, user) {
if(id === 0) return {short_name: "Начало"}
let client = await this.pool.connect(); let client = await this.pool.connect();
let task = null;
try { try {
await client.query('BEGIN'); let result = await client.query("SELECT * FROM qr_codes WHERE id = $1", [code]);
let res = await client.query('SELECT * FROM qr_tasks WHERE id = $1', [id]); if (result.rowCount === 1) {
await client.query('COMMIT'); result = await client.query("SELECT * FROM qr_gots WHERE code_id = $1 AND user_id = $2", [code, user]);
task = res.rows[0]; if (result.rowCount === 0) {
await client.query("INSERT INTO qr_gots (code_id, user_id) VALUES ($1, $2)", [code, user]);
return true;
} else {
return false;
}
} else {
return false;
}
} finally {
client.release();
}
}
async getUserCodes(user) {
let client = await this.pool.connect();
try {
let result = await client.query("SELECT * FROM qr_gots WHERE user_id = $1", [user]);
return result.rows.length;
} finally {
client.release();
}
}
async getTotalCodes() {
let client = await this.pool.connect();
try {
let result = await client.query("SELECT * FROM qr_codes");
return result.rowCount;
} finally { } finally {
client.release(); client.release();
} }
return task;
} }
async getTop() { async getTop() {
let client = await this.pool.connect(); let client = await this.pool.connect();
let teams = [];
try { try {
await client.query('BEGIN'); let result = await client.query("SELECT qr_users.name as name, COUNT(qr_gots.user_id) AS count, qr_users.user_id as id FROM qr_gots INNER JOIN qr_users ON qr_gots.user_id = qr_users.user_id GROUP BY qr_users.user_id ORDER BY count DESC LIMIT 10");
let res = await client.query('SELECT qr_team.*, COUNT(task) as count\n' + return result.rows;
'FROM qr_team\n' +
' join qr_completion as com on qr_team.id = com.group_id\n' +
'group by id, team_name, owner_id\n' +
'ORDER BY count DESC', []);
await client.query('COMMIT');
teams = res.rows;
} finally {
client.release();
}
return teams;
}
/**
*
* @param team
* @param task
* @returns {Promise<boolean>}
*/
async checkPreviousTasks(team, task) {
if(task === 1) return true;
let client = await this.pool.connect();
let prevtasks = 0;
try {
await client.query('BEGIN');
let res = await client.query('SELECT * FROM qr_view WHERE task = $1 AND group_id = $2', [task-1, team]);
prevtasks = res.rowCount;
await client.query('COMMIT');
} finally {
client.release();
}
return prevtasks > 0;
}
async getTeam(user) {
let client = await this.pool.connect();
let team = null;
try {
await client.query('BEGIN');
let res = await client.query('SELECT * FROM qr_team WHERE owner_id = $1', [user]);
await client.query('COMMIT');
team = res.rows[0];
} finally {
client.release();
}
return team;
}
async addCompletion(team, task) {
let client = await this.pool.connect();
try {
await client.query('BEGIN');
//add completion if not exists
let res = await client.query('SELECT * FROM qr_completion WHERE group_id = $1 AND task = $2', [team, task]);
if(res.rowCount === 0) {
await client.query('INSERT INTO qr_completion (group_id, task) values ($1,$2)', [team, task]);
}
await client.query('COMMIT');
} finally {
client.release();
}
}
async addView(team, task) {
let client = await this.pool.connect();
try {
await client.query('BEGIN');
await client.query('INSERT INTO qr_view (group_id, task) values ($1,$2)', [team, task]);
await client.query('COMMIT');
} finally { } finally {
client.release(); client.release();
} }

View File

@ -13,79 +13,50 @@ bot.start(async (ctx) => {
return; return;
} }
switch (code) { await database.checkAndRegisterUser(ctx.from.id, ctx.from.first_name);
case "shaman": {
ctx.session.state = "register";
await ctx.reply("Введите название группы");
break;
}
default: {
let team = await database.getTeam(ctx.from.id);
if (team == null) return;
let task = await database.getQRTask(code);
if (task == null) return;
if (!await database.checkPreviousTasks(team.id, task.id)) {
await ctx.reply("Вы не выполнили предыдущие задания или это одно из прошлых заданий");
return;
}
await database.addView(team.id, task.id);
await database.addCompletion(team.id, task.id - 1);
let pTask = await database.getTask(task.id - 1);
await bot.telegram.sendMessage(-879242326, "Команда " + team.team_name + " получила задание " + task.short_name + "(" + task.id + ") и закончила задание " + pTask.short_name + "(" + (task.id - 1) + ")");
if (code === "freead") {
await ctx.reply(task.id + ") \n" + task.task_text, Telegraf.Extra.markup((m) => m.inlineKeyboard([[m.callbackButton("Проверить выполнение", "check")]])));
} else {
await ctx.reply(task.id + ") \n" + task.task_text);
}
}
}
});
bot.command("top", async (ctx) => {
if (ctx.chat.id !== -879242326) return;
let top = await database.getTop();
let message = "Топ команд:\n";
for (let i = 0; i < top.length; i++) {
message += (i + 1) + ". " + top[i].team_name + " - " + top[i].count + " заданий\n";
}
await ctx.reply(message);
});
bot.action("check", async (ctx) => {
bot.telegram.getChatMember("@ks54_op5", ctx.from.id).then(async (member) => { bot.telegram.getChatMember("@ks54_op5", ctx.from.id).then(async (member) => {
if(member.status === "left") { if(member.status === "left") {
await ctx.answerCbQuery("Вы не состоите в @ks54_op5"); await ctx.reply("Вы не состоите в @ks54_op5");
return; return;
} }
bot.telegram.getChatMember("@studsovet_ks54", ctx.from.id).then(async (mem) => { bot.telegram.getChatMember("@studsovet_ks54", ctx.from.id).then(async (mem) => {
if (mem.status === "left") { if (mem.status === "left") {
await ctx.answerCbQuery("Вы не состоите в @studsovet_ks54"); await ctx.reply("Вы не состоите в @studsovet_ks54");
return; return;
} }
let team = await database.getTeam(ctx.from.id); let exists = await database.codeExists(code);
if (team == null) return; if (!exists) {
await bot.telegram.sendMessage(-879242326, "Команда " + team.team_name + " завершила прохождение квеста!"); await ctx.reply("Код не найден, возможно вы криво отсканировали QR код или пытаете его подделать");
await ctx.editMessageText("Поздравляем с прохождением QR квеста! Вы можете спускаться к Деду Морозу.") return;
}
let used = await database.useCode(code, ctx.from.id);
if (used) {
let userCodes = await database.getUserCodes(ctx.from.id);
let totalCodes = await database.getTotalCodes();
await ctx.reply("Код успешно использован, собрано " + userCodes + " из " + totalCodes + " кодов");
await bot.telegram.sendMessage(-879242326, `<a href="tg://user?id=${ctx.from.id}">${ctx.from.first_name}</a> отсканировал код ${userCodes} из ${totalCodes}`, {parse_mode: "HTML"});
} else {
await ctx.reply("Код уже использован");
}
}).catch(async (err) => { }).catch(async (err) => {
await ctx.answerCbQuery("Вы не состоите в @studsovet_ks54"); await ctx.reply("Вы не состоите в @studsovet_ks54");
}); });
}).catch(async (err) => { }).catch(async (err) => {
await ctx.answerCbQuery("Вы не состоите в @ks54_op5"); await ctx.reply("Вы не состоите в @ks54_op5");
}); });
}); });
bot.on('text', async (ctx) => { bot.command("top", async (ctx) => {
switch (ctx.session.state) { if (ctx.chat.id !== -879242326) return;
case "register": { let top = await database.getTop();
let group = ctx.message.text; let message = "Топ игроков:\n";
await database.registerQRTeam(group, ctx.from.id); for (let i = 0; i < top.length; i++) {
await ctx.reply("Группа зарегистрирована.\nЛиса на девятом небе отдыхает, найдёшь ли ты её?"); message += `${(i + 1)}. <a href="tg://user?id=${top[i].id}">${top[i].name}</a> - ${top[i].count} кодов\n`;
ctx.session.state = undefined;
await bot.telegram.sendMessage(-879242326, "Группа " + group + " зарегистрирована by <a href=\"tg://user?id=" + ctx.from.id + "\">" + ctx.from.first_name + "</a>", {parse_mode: "HTML"});
}
} }
await ctx.reply(message, {parse_mode: "HTML"});
}); });
bot.startPolling(); bot.startPolling();