105 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import Telegraf from 'telegraf'
 | ||
| import TelegrafExtra from 'telegraf/extra'
 | ||
| import { saveChat, getChats, saveLogoutTime, getLastLogoutTime, saveKillCount, getKillCount,
 | ||
|   saveLevelUp, getLevelUpCount, saveLevel, setOnlineState, setOfflineState, getPlayersData, getAllKills
 | ||
| } from './database'
 | ||
| import {
 | ||
|   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, getKillNotificationEachKillsCount } from './data'
 | ||
| import stringTable from 'string-table'
 | ||
| 
 | ||
| const bot = new Telegraf('643297173:AAGuqfZx3GhiiARwvY7AtWTTFw1T-2FiwCM')
 | ||
| const markdown = TelegrafExtra.markdown()
 | ||
| const formattedStringTable = data => stringTable.create(data)
 | ||
|   .split('\n')
 | ||
|   .map(line => `\`\`\`${line.slice(0, -1)}\`\`\``)
 | ||
|   .join('\n')
 | ||
| 
 | ||
| bot.start(({ message: { chat: { id } } }) => saveChat(id))
 | ||
| bot.command(
 | ||
|   'players',
 | ||
|   ({ replyWithMarkdown }) => getPlayersData()
 | ||
|     .then(playersData => replyWithMarkdown(
 | ||
|       formattedStringTable(
 | ||
|         playersData.map(({ displayName, level, online }) => ({
 | ||
|           'имя': `👤 ${displayName}`,
 | ||
|           'уровень': level,
 | ||
|           'статус': `${online ? '✅ онлайн' : '❔ оффлайн'}`
 | ||
|         }))
 | ||
|       )
 | ||
|     ))
 | ||
| )
 | ||
| bot.hears(
 | ||
|   /^\/kills[ =](.+)$/,
 | ||
|   ctx => getAllKills(ctx.match[1])
 | ||
|     .then(allKills => {
 | ||
|       if (!allKills) {
 | ||
|         ctx.reply('Не найдено')
 | ||
|         return
 | ||
|       }
 | ||
|       ctx.replyWithMarkdown(
 | ||
|         formattedStringTable(
 | ||
|           allKills.map(kills => ({
 | ||
|             'монстр': getEntityName(kills),
 | ||
|             'убийств': kills.killCount
 | ||
|           }))
 | ||
|         )
 | ||
|       )
 | ||
|     })
 | ||
| )
 | ||
| bot.launch()
 | ||
| 
 | ||
| const sendMessageToAll = text => getChats()
 | ||
|   .then(chats => chats.map(({ chatId }) => chatId)
 | ||
|     .forEach(chatId => bot.telegram.sendMessage(chatId, text, markdown))
 | ||
|   )
 | ||
| 
 | ||
| const JOIN_NOTIFICATION_TIME_DELTA = 60 * 60 // 1h
 | ||
| const LEVEL_NOFIFICATION_EACH_LEVELS = 5
 | ||
| 
 | ||
| export const sendEvent = async ({ type, displayName, ...payload }) => {
 | ||
|   switch (type) {
 | ||
|     case EVENT_TYPE_JOIN:
 | ||
|       setOnlineState(displayName)
 | ||
|       const lastLogoutTime = await getLastLogoutTime(displayName)
 | ||
|       if (lastLogoutTime < currentTime() - JOIN_NOTIFICATION_TIME_DELTA) {
 | ||
|         sendMessageToAll(`👤 *${displayName}* присоединился 😼`)
 | ||
|       }
 | ||
|       break
 | ||
|     case EVENT_TYPE_QUIT:
 | ||
|       setOfflineState(displayName)
 | ||
|       saveLogoutTime(displayName)
 | ||
|       break
 | ||
|     case EVENT_TYPE_DEATH:
 | ||
|       sendMessageToAll(`👤 *${displayName}* ☠️ ${getEntityDeathMessage(payload)} ☠️`)
 | ||
|       break
 | ||
|     case EVENT_TYPE_PLAYER_LEVEL_CHANGE:
 | ||
|       const { newLevel, oldLevel } = payload
 | ||
|       saveLevel(displayName, newLevel)
 | ||
|       if (newLevel < oldLevel) {
 | ||
|         return
 | ||
|       }
 | ||
|       const levelUpCount = await getLevelUpCount(displayName)
 | ||
|       if (newLevel % LEVEL_NOFIFICATION_EACH_LEVELS === 0 &&
 | ||
|         levelUpCount >= LEVEL_NOFIFICATION_EACH_LEVELS
 | ||
|       ) {
 | ||
|         sendMessageToAll(`👤 *${displayName}* теперь уровня *${newLevel}* 👍`)
 | ||
|         saveLevelUp(displayName, 0)
 | ||
|       } else {
 | ||
|         saveLevelUp(displayName, levelUpCount + 1)
 | ||
|       }
 | ||
|       break
 | ||
|     case EVENT_TYPE_PLAYER_KILLED_ENTITY:
 | ||
|       const killCount = await getKillCount(displayName, payload.entityName)
 | ||
|       const newKillCount = killCount + 1
 | ||
|       saveKillCount(displayName, payload.entityName, newKillCount)
 | ||
|       if (newKillCount % getKillNotificationEachKillsCount(payload) === 0) {
 | ||
|         sendMessageToAll(`👤 *${displayName}* 👻 VS 👻 *${getEntityName(payload)}*. Убито ещё ${getKillNotificationEachKillsCount(payload)}! Всего: ${newKillCount} 👍`)
 | ||
|       }
 | ||
|       break
 | ||
|   }
 | ||
| }
 |