From 919257e2f0393cebed02fb58166190f7ded7e119 Mon Sep 17 00:00:00 2001 From: smsteel Date: Sat, 9 Feb 2019 20:15:43 +0300 Subject: [PATCH] level up fix --- bot.js | 98 +++++++++++------------------------------ database.js | 50 +++++++++++++++------ ru.js | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ types.js | 8 ++-- 4 files changed, 191 insertions(+), 87 deletions(-) create mode 100644 ru.js diff --git a/bot.js b/bot.js index d35e595..dc22fa9 100644 --- a/bot.js +++ b/bot.js @@ -1,15 +1,10 @@ import Telegraf from 'telegraf' -import { saveChat, getChats, saveLogout, getLastLogoutTime } from './database' +import { saveChat, getChats, saveLogout, getLastLogoutTime, saveKillCount, getKillCount } from './database' import { - TYPE_JOIN, TYPE_DEATH, DEATH_TYPE_CONTACT, DEATH_TYPE_BLOCK_EXPLOSION, DEATH_TYPE_ENTITY_ATTACK, - DEATH_TYPE_ENTITY_SWEEP_ATTACK, DEATH_TYPE_PROJECTILE, DEATH_TYPE_FALL, DEATH_TYPE_FIRE, - DEATH_TYPE_FIRE_TICK, DEATH_TYPE_SUFFOCATION, DEATH_TYPE_MELTING, DEATH_TYPE_LAVA, DEATH_TYPE_DROWNING, - DEATH_TYPE_ENTITY_EXPLOSION, DEATH_TYPE_VOID, DEATH_TYPE_LIGHTNING, DEATH_TYPE_SUICIDE, - DEATH_TYPE_STARVATION, DEATH_TYPE_POISON, DEATH_TYPE_MAGIC, DEATH_TYPE_FALLING_BLOCK, - DEATH_TYPE_THORNS, DEATH_TYPE_DRAGON_BREATH, DEATH_TYPE_CUSTOM, DEATH_TYPE_HOT_FLOOR, - DEATH_TYPE_FLY_INTO_WALL, DEATH_TYPE_CRAMMING, DEATH_TYPE_DRYOUT, TYPE_QUIT + EVENT_TYPE_JOIN, EVENT_TYPE_DEATH, EVENT_TYPE_QUIT, EVENT_TYPE_PLAYER_LEVEL_CHANGE, EVENT_TYPE_PLAYER_KILLED_ENTITY } from './types' import { currentTime } from './utility' +import { getEntityDeathMessage, getEntityName } from './ru' const bot = new Telegraf('643297173:AAGuqfZx3GhiiARwvY7AtWTTFw1T-2FiwCM') @@ -21,79 +16,38 @@ const sendMessageToAll = text => getChats() .forEach(chatId => bot.telegram.sendMessage(chatId, text)) ) -const getEntityDeathMessage = payload => { - switch (payload.deathType) { - case DEATH_TYPE_CONTACT: - return 'умер от соприкосновения' - case DEATH_TYPE_BLOCK_EXPLOSION: - return 'взорвался' - case DEATH_TYPE_ENTITY_ATTACK: - return 'умер от существа' - case DEATH_TYPE_ENTITY_SWEEP_ATTACK: - return 'умер от урона по области' - case DEATH_TYPE_PROJECTILE: - return 'застрелили' - case DEATH_TYPE_SUFFOCATION: - return 'сплющило' - case DEATH_TYPE_FALL: - return 'упал насмерть' - case DEATH_TYPE_FIRE: - return 'сгорел' - case DEATH_TYPE_FIRE_TICK: - return 'умер от ожогов' - case DEATH_TYPE_MELTING: - return 'замерз' - case DEATH_TYPE_LAVA: - return 'от лавы' - case DEATH_TYPE_DROWNING: - return 'утонул' - case DEATH_TYPE_ENTITY_EXPLOSION: - return 'взорван вместе с существом' - case DEATH_TYPE_VOID: - return 'упал в бездну' - case DEATH_TYPE_LIGHTNING: - return 'скончался от удара молнией' - case DEATH_TYPE_SUICIDE: - return 'совершил самоубийство' - case DEATH_TYPE_STARVATION: - return 'скончался от голода' - case DEATH_TYPE_POISON: - return 'умер от яда' - case DEATH_TYPE_MAGIC: - return 'умер от магии' - case DEATH_TYPE_FALLING_BLOCK: - return 'погиб под упавшим блоком' - case DEATH_TYPE_THORNS: - return 'умер от шипов' - case DEATH_TYPE_DRAGON_BREATH: - return 'убит драконом' - case DEATH_TYPE_CUSTOM: - return '' - case DEATH_TYPE_FLY_INTO_WALL: - return 'убил сибя ап стену' - case DEATH_TYPE_HOT_FLOOR: - return 'не увидел, что пол - магма' - case DEATH_TYPE_CRAMMING: - return '' - case DEATH_TYPE_DRYOUT: - return '' - } -} - -const JOIN_NOTIFICATION_LIMIT = 60 * 60 // 1h +const JOIN_NOTIFICATION_TIME_DELTA = 60 * 60 // 1h +const LEVEL_NOFIFICATION_EACH_LEVELS = 5 +const KILL_NOTIFICATION_EACH_KILLS = 50 export const sendEvent = ({ type, ...payload }) => { switch (type) { - case TYPE_JOIN: + case EVENT_TYPE_JOIN: getLastLogoutTime(payload.displayName) - .then(lastLogoutTime => lastLogoutTime < currentTime() - JOIN_NOTIFICATION_LIMIT && + .then(lastLogoutTime => lastLogoutTime < currentTime() - JOIN_NOTIFICATION_TIME_DELTA && sendMessageToAll(`Игрок ${payload.displayName} присоединился!`)) break - case TYPE_QUIT: + case EVENT_TYPE_QUIT: saveLogout(payload.displayName) break - case TYPE_DEATH: + case EVENT_TYPE_DEATH: sendMessageToAll(`Игрок ${payload.displayName} ${getEntityDeathMessage(payload)} :(`) break + case EVENT_TYPE_PLAYER_LEVEL_CHANGE: + const { newLevel } = payload + if (newLevel % LEVEL_NOFIFICATION_EACH_LEVELS === 0) { + sendMessageToAll(`Игрок ${payload.displayName} прокачался до уровня ${newLevel}!`) + } + break + case EVENT_TYPE_PLAYER_KILLED_ENTITY: + getKillCount(payload.displayName, payload.entityName) + .then(killCount => { + const newKillCount = killCount + 1 + saveKillCount(payload.displayName, payload.entityName, newKillCount) + if (newKillCount % KILL_NOTIFICATION_EACH_KILLS === 0) { + sendMessageToAll(`${getEntityName(payload)} повержен(а) игроком ${payload.displayName}. Он убил ещё ${KILL_NOTIFICATION_EACH_KILLS}! Всего: ${newKillCount}`) + } + }) + break } } diff --git a/database.js b/database.js index 4d70b8f..80207ff 100644 --- a/database.js +++ b/database.js @@ -9,12 +9,20 @@ db.run( )`) db.run( - `CREATE TABLE IF NOT EXISTS logouts ( - displayName INTEGER, + `CREATE TABLE IF NOT EXISTS playerLogouts ( + displayName STRING, lastLogoutTime DATETIME, UNIQUE(displayName) )`) +db.run( + `CREATE TABLE IF NOT EXISTS playerKills ( + displayName STRING, + entityName STRING, + killCount INTEGER, + UNIQUE(displayName, entityName) + )`) + const run = (sql, params) => new Promise((resolve, reject) => { db.run(sql, params, (err) => { if (err) { @@ -25,6 +33,16 @@ const run = (sql, params) => new Promise((resolve, reject) => { }) }) +const get = (sql, params, column, defaultParam = null) => new Promise((resolve, reject) => { + db.get(sql, params, (err, row) => { + if (err) { + reject(err) + } else { + resolve(row ? row[column] : defaultParam) + } + }) +}) + export const saveChat = id => run(`INSERT OR IGNORE INTO chats (chatId) VALUES (?)`, [ id ]) export const getChats = () => new Promise((resolve, reject) => { db.all('SELECT * FROM chats', [], (err, rows) => { @@ -37,15 +55,23 @@ export const getChats = () => new Promise((resolve, reject) => { }) export const saveLogout = displayName => run( - `INSERT OR REPLACE INTO logouts (displayName, lastLogoutTime) VALUES (?, ?)`, + `INSERT OR REPLACE INTO playerLogouts (displayName, lastLogoutTime) VALUES (?, ?)`, [ displayName, currentTime() ] ) -export const getLastLogoutTime = displayName => new Promise((resolve, reject) => { - db.get(`SELECT lastLogoutTime FROM logouts WHERE displayName = ?`, [ displayName ], (err, row) => { - if (err) { - reject(err) - } else { - resolve(row ? row.lastLogoutTime : null) - } - }) -}) +export const getLastLogoutTime = displayName => get( + `SELECT lastLogoutTime FROM playerLogouts WHERE displayName = ?`, + [ displayName ], + 'lastLogoutTime', + null +) + +export const saveKillCount = (displayName, entityName, killCount) => run( + `INSERT OR REPLACE INTO playerKills (displayName, entityName, killCount) VALUES (?, ?, ?)`, + [ displayName, entityName, killCount ] +) +export const getKillCount = (displayName, entityName) => get( + `SELECT killCount FROM playerKills WHERE displayName = ? AND entityName = ?`, + [ displayName, entityName ], + 'killCount', + 0 +) diff --git a/ru.js b/ru.js new file mode 100644 index 0000000..e8d2164 --- /dev/null +++ b/ru.js @@ -0,0 +1,122 @@ +import { DEATH_TYPE_CONTACT, DEATH_TYPE_BLOCK_EXPLOSION, DEATH_TYPE_ENTITY_ATTACK, + DEATH_TYPE_ENTITY_SWEEP_ATTACK, DEATH_TYPE_PROJECTILE, DEATH_TYPE_FALL, DEATH_TYPE_FIRE, + DEATH_TYPE_FIRE_TICK, DEATH_TYPE_SUFFOCATION, DEATH_TYPE_MELTING, DEATH_TYPE_LAVA, DEATH_TYPE_DROWNING, + DEATH_TYPE_ENTITY_EXPLOSION, DEATH_TYPE_VOID, DEATH_TYPE_LIGHTNING, DEATH_TYPE_SUICIDE, + DEATH_TYPE_STARVATION, DEATH_TYPE_POISON, DEATH_TYPE_MAGIC, DEATH_TYPE_FALLING_BLOCK, + DEATH_TYPE_THORNS, DEATH_TYPE_DRAGON_BREATH, DEATH_TYPE_CUSTOM, DEATH_TYPE_HOT_FLOOR, + DEATH_TYPE_FLY_INTO_WALL, DEATH_TYPE_CRAMMING, DEATH_TYPE_DRYOUT +} from './types' + +export const getEntityDeathMessage = payload => { + switch (payload.deathType) { + case DEATH_TYPE_CONTACT: + return 'умер от соприкосновения' + case DEATH_TYPE_BLOCK_EXPLOSION: + return 'взорвался' + case DEATH_TYPE_ENTITY_ATTACK: + return 'умер от существа' + case DEATH_TYPE_ENTITY_SWEEP_ATTACK: + return 'умер от урона по области' + case DEATH_TYPE_PROJECTILE: + return 'застрелили' + case DEATH_TYPE_SUFFOCATION: + return 'сплющило' + case DEATH_TYPE_FALL: + return 'упал насмерть' + case DEATH_TYPE_FIRE: + return 'сгорел' + case DEATH_TYPE_FIRE_TICK: + return 'умер от ожогов' + case DEATH_TYPE_MELTING: + return 'замерз' + case DEATH_TYPE_LAVA: + return 'сгорел в лаве' + case DEATH_TYPE_DROWNING: + return 'утонул' + case DEATH_TYPE_ENTITY_EXPLOSION: + return 'взорван вместе с существом' + case DEATH_TYPE_VOID: + return 'упал в бездну' + case DEATH_TYPE_LIGHTNING: + return 'скончался от удара молнией' + case DEATH_TYPE_SUICIDE: + return 'совершил самоубийство' + case DEATH_TYPE_STARVATION: + return 'скончался от голода' + case DEATH_TYPE_POISON: + return 'умер от яда' + case DEATH_TYPE_MAGIC: + return 'умер от магии' + case DEATH_TYPE_FALLING_BLOCK: + return 'погиб под упавшим блоком' + case DEATH_TYPE_THORNS: + return 'умер от шипов' + case DEATH_TYPE_DRAGON_BREATH: + return 'убит драконом' + case DEATH_TYPE_CUSTOM: + return '' + case DEATH_TYPE_FLY_INTO_WALL: + return 'убил сибя ап стену' + case DEATH_TYPE_HOT_FLOOR: + return 'не увидел, что пол - магма' + case DEATH_TYPE_CRAMMING: + return '' + case DEATH_TYPE_DRYOUT: + return '' + } +} + +export const getEntityName = payload => { + switch (payload.entityName) { + case 'Cow': + return 'Корова' + case 'Zombie Villager': + return 'Зомби житель' + // case 'Skeleton Horse': + // return '' + // case 'Zombie Horse': + // return '' + // case 'Donkey': + // return '' + // case 'Mule': + // return '' + // case 'Evocation Fangs': + // return '' + // case 'Creeper': + // return '' + // case 'Skeleton': + // return '' + // case 'Spider': + // return '' + // case 'Giant Zombie': + // return '' + case 'Zombie': + return 'Зомби' + case 'Slime': + return 'Слайм' + // case 'Ghast': + // return '' + // case 'Enderman': + // return '' + // case 'Cave Spider': + // return '' + // case 'Silverfish': + // return '' + // case 'Blaze': + // return '' + // case 'Magma Cube': + // return '' + // case 'Witch': + // return '' + case 'Pig': + return 'Свинья' + case 'Sheep': + return 'Овца' + case 'Chicken': + return 'Курица' + case 'Squid': + return 'Медуза' + default: + return payload.entityName + } +} diff --git a/types.js b/types.js index 555bd40..25b4a06 100644 --- a/types.js +++ b/types.js @@ -1,6 +1,8 @@ -export const TYPE_JOIN = 'join' -export const TYPE_QUIT = 'quit' -export const TYPE_DEATH = 'death' +export const EVENT_TYPE_JOIN = 'join' +export const EVENT_TYPE_QUIT = 'quit' +export const EVENT_TYPE_DEATH = 'death' +export const EVENT_TYPE_PLAYER_LEVEL_CHANGE = 'playerLevelChange' +export const EVENT_TYPE_PLAYER_KILLED_ENTITY = 'playerKilledEntity' /** * Damage caused when an entity contacts a block such as a Cactus.