lsp-yggdrasil/src/telegram/player-commands.js

205 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Scenes } from 'telegraf'
import { telegraf, server } from '../index.js'
import { createHash } from 'crypto'
import axios from 'axios'
import { uuid } from '../generator.js'
import { Player } from '../models/player.js'
export const registerAllPlayerCommands = async () => {
await register()
}
const defaultSkin = "http://textures.minecraft.net/texture/ddb8684e59f771666bde5f411fcb2e495c452f2ecabc31981bc132ac71bdd394"
const registerWizard = new Scenes.WizardScene('REGISTRIATION_WIZARD',
(ctx) => {
ctx.reply('欢迎来到注册流程,如果想中途取消使用指令 "/cancle" ,请先告诉我您的用户名')
ctx.scene.session.data = {
username: ctx.from.username
}
return ctx.wizard.next()
},
(ctx) => {
if(!ctx.message.text || ctx.message.text < 3) {
return ctx.reply('用户名不能少于 3 个字符!请重新输入')
}
const username = ctx.from.username === 'Lapis_Apple' ? 'LSP' : ctx.message.text
ctx.reply(`请设置玩家 ${username} 的密码`)
ctx.scene.session.data.playerUsername = username
return ctx.wizard.next()
},
async (ctx) => {
if(!ctx.message.text || ctx.message.text < 6) {
return ctx.reply('密码不能少于 6 个字符!请重新输入')
}
ctx.scene.session.data.password = createHash('sha256').update(ctx.message.text).digest('hex')
const duplicated = await Player.findOne({ password: ctx.scene.session.data.password })
if(duplicated) {
return ctx.reply(`该密码hash为${ctx.scene.session.data.password.substring(3,10)} 已检测到数据库中存在重复密码(${JSON.stringify({d: duplicated})}),为了安全请重新输入`)
}
ctx.reply(`该密码hash为${ctx.scene.session.data.password.substring(3,10)} 请确认是否正确,若正确请输入 'confirm'`)
return ctx.wizard.next()
},
(ctx) => {
if(!ctx.message.text || ctx.message.text !== 'confirm') {
return ctx.reply('请输入 "confirm" 确认您的密码,或者输入 /cancle 取消注册')
}
ctx.replyWithMarkdownV2("请输入您的邮箱。**注意:我们并不会向您发送注册确认,邮箱仅作为符合 authlib\\-injector 登陆规范在登陆时使用**")
return ctx.wizard.next()
},
(ctx) => {
if(!ctx.message.text || ctx.message.text.length < 6) {
return ctx.reply('邮箱不能少于 6 个字符!请重新输入')
}
ctx.scene.session.data.email = ctx.message.text
ctx.reply(`是否需要同步同用户名正版玩家的皮肤和披风? 输入 'yes' 或者 'no'`)
return ctx.wizard.next()
},
(ctx) => {
if(!ctx.message.text || ctx.message.text !== 'yes' && ctx.message.text !== 'no') {
return ctx.reply('请输入 "yes" 或者 "no"')
}
ctx.scene.session.data.sync = ctx.message.text === 'yes'
ctx.reply(`请问您是否有注册邀请码? 有请输入邀请码,没有输入 'skip'`)
return ctx.wizard.next()
},
(ctx) => {
if(!ctx.message.text || ctx.message.text === 'skip') {
ctx.scene.session.data.inviteCode = null
} else {
if(!ctx.message.text || ctx.message.text.length < 6) {
return ctx.reply('邀请码不能少于 6 个字符!请重新输入')
}
ctx.scene.session.data.inviteCode = ctx.message.text
}
ctx.reply(
`好的现在来确认一下信息:\n`+
`用户名:${ctx.scene.session.data.playerUsername}\n`+
`密码:${ctx.scene.session.data.password.substring(3,10)}\n`+
`邮箱:${ctx.scene.session.data.email}\n`+
`同步皮肤和披风:${ctx.scene.session.data.sync ? '是' : '否'}\n`+
`邀请码:${ctx.scene.session.data.inviteCode ?? '无'}\n`+
`是否确认? 输入 'yes' 或者 'no'`
)
return ctx.wizard.next()
},
async (ctx) => {
if(!ctx.message.text || ctx.message.text !== 'yes' && ctx.message.text !== 'no') {
return ctx.reply('请输入 "yes" 或者 "no"')
}
if(ctx.message.text === 'no') {
ctx.reply("已取消注册")
return ctx.scene.leave()
} else {
let message = await ctx.reply("正在注册...")
let skin = defaultSkin
let cape = ""
if(ctx.scene.session.data.sync) {
try{
message = await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, '获取对应正版玩家皮肤中...')
const uuid = await axios({
method: 'GET',
url: "https://api.mojang.com/users/profiles/minecraft/" + ctx.scene.session.data.playerUsername,
})
if(uuid.status === 400) {
message = await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, '对应正版玩家不存在!已跳过皮肤获取')
} else {
const skinResponse = await axios({
method: 'GET',
url: `https://sessionserver.mojang.com/session/minecraft/profile/${uuid.data.id}`,
responseType: 'json',
})
const skinData = JSON.parse(Buffer.from(skinResponse.data.properties[0].value, 'base64').toString())
skin = skinData.textures.SKIN.url
cape = skinData.textures.CAPE?.url
message = await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, '成功同步皮肤和披风')
}
} catch(err) {
server.log.info(err.toJSON())
}
}
let verified = false
if(ctx.scene.session.data.inviteCode) {
await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, message.text + '\n验证邀请码中...')
const invi = Invitation.findOne({
token: ctx.scene.session.data.inviteCode
})
if(invi) {
message = await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, message.text + '\n邀请码验证成功邀请人: ' + invi.by)
verified = true
} else {
message = await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, message.text + '\n邀请码无效! 已跳过')
}
}
const player = new Player({
uuid: uuid("LSP-yggdrasil:" + ctx.scene.session.data.playerUsername),
username: ctx.scene.session.data.playerUsername,
password: ctx.scene.session.data.password,
email: ctx.scene.session.data.email,
textures: {
skin: skin,
cape: cape
},
registerDate: Date.now(),
permissions: [{ node: 'login', allowed: true, duration: 0, eternal: true, startDate: Date.now(), highPriority: false }],
telegramBind: {
username: ctx.from.username,
verified: verified
}
})
player.save()
message = await telegraf.telegram.editMessageText(ctx.chat.id, message.message_id, null, message.text + '\n注册成功')
ctx.scene.leave()
}
}
)
export const allScenes = [
registerWizard,
]
const register = async () => {
registerWizard.command('cancel', (ctx) => {
ctx.reply("注册已取消")
return ctx.scene.leave()
})
telegraf.command('register', async (ctx) => {
const username = ctx.from.username
if(!username) {
return ctx.reply("请设置 Telegram 用户名!")
}
const player = await Player.findOne({ "telegramBind.username": username })
server.log.info(player)
if(!player) {
return ctx.scene.enter('REGISTRIATION_WIZARD')
} else {
return ctx.reply(`您已绑定用户: ${player.username} (${player.uuid})`)
}
})
}