173 lines
7.9 KiB
TypeScript
173 lines
7.9 KiB
TypeScript
import { Box, Button, CssBaseline, Grid, Paper, TextField, Link, ThemeProvider, Typography, Alert, Collapse, Checkbox, FormGroup, FormControlLabel, Dialog, DialogTitle, DialogContentText, DialogActions, DialogContent } from "@mui/material"
|
|
import { useNavigate } from "react-router-dom"
|
|
import { api, theme } from '../index'
|
|
import axios from "axios"
|
|
import { useRef, useState } from "react"
|
|
import "./custom.css"
|
|
|
|
export const PageRegister = () => {
|
|
const navigate = useNavigate()
|
|
const usernameInput = useRef<HTMLInputElement>(null)
|
|
const passwordInput = useRef<HTMLInputElement>(null)
|
|
const emailInput = useRef<HTMLInputElement>(null)
|
|
const invitationCodeInput = useRef<HTMLInputElement>(null)
|
|
const validationCodeInput = useRef<HTMLInputElement>(null)
|
|
const [useMojangSkin, setUseMojangSkin] = useState(false)
|
|
const [disableBtn, setDisableBtn] = useState(false)
|
|
const [cors, setCors] = useState(false)
|
|
const [illegal, setIllegal] = useState(false)
|
|
const [illegalMessgae, setIllegalMessgae] = useState("")
|
|
|
|
|
|
const handleRegister = () => {
|
|
setDisableBtn(true);
|
|
(async () => {
|
|
const username = usernameInput.current?.value
|
|
const password = passwordInput.current?.value
|
|
const email = emailInput.current?.value
|
|
const invitationCode = invitationCodeInput.current?.value
|
|
const validationCode = validationCodeInput.current?.value
|
|
if(!username || !password) {
|
|
setIllegalMessgae("请将以下内容全部输入")
|
|
setIllegal(true)
|
|
}
|
|
|
|
let textureMigrations = undefined
|
|
|
|
if(useMojangSkin) {
|
|
try {
|
|
const response = await axios.get("https://api.mojang.com/users/profiles/minecraft/" + username)
|
|
const profile = await axios.get("https://sessionserver.mojang.com/session/minecraft/profile/" + response.data.id)
|
|
profile.data.properties.forEach((prop: any) => {
|
|
if(prop.name === "textures") {
|
|
const texture = JSON.parse(atob(prop.value)).textures
|
|
|
|
if(texture.SKIN || texture.CAPE) {
|
|
textureMigrations = {
|
|
skin: texture.SKIN?.url ?? undefined,
|
|
cape: texture.CAPE?.url ?? undefined,
|
|
}
|
|
}
|
|
}
|
|
})
|
|
} catch(err: any) {
|
|
if(err.code === "ERR_NETWORK") {
|
|
setCors(true)
|
|
return
|
|
}
|
|
setIllegalMessgae(`无法同步正版皮肤,可能是用户不存在`)
|
|
setIllegal(true)
|
|
}
|
|
}
|
|
|
|
console.log(textureMigrations)
|
|
|
|
try {
|
|
const response = await axios.post(api("/api/register"), {
|
|
username,
|
|
password,
|
|
email,
|
|
invitationCode,
|
|
validationCode,
|
|
textureMigrations
|
|
})
|
|
|
|
if(response.data.err !== 1.048596) {
|
|
setIllegalMessgae(`注册失败! 错误代码 ${response.data.err} 原因: ${response.data.msg}`)
|
|
setIllegal(true)
|
|
} else {
|
|
navigate("/")
|
|
}
|
|
} catch (err: any) {
|
|
if(err.code === "ERR_NETWORK") {
|
|
setCors(true)
|
|
return
|
|
}
|
|
setIllegalMessgae(`注册失败! 错误代码 ${err.code} 原因: ${err.message}`)
|
|
setIllegal(true)
|
|
}
|
|
})().finally(() => {
|
|
setDisableBtn(false);
|
|
})
|
|
}
|
|
|
|
//TODO
|
|
|
|
return <ThemeProvider theme={theme}>
|
|
<CssBaseline />
|
|
|
|
<Dialog open={cors} aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description">
|
|
<DialogTitle id="alert-dialog-title">
|
|
{"无法发送请求!"}
|
|
</DialogTitle>
|
|
<DialogContent>
|
|
<DialogContentText id="alert-dialog-description">
|
|
由于您的浏览器有 CORS 限制导致页面无法向 Mojang API/LSP-Yggdrasil API 发送请求。您可以选择 <Link href="https://chrome.google.com/webstore/detail/cors-unblock/lfhmikememgdcahcdlaciloancbhjino">点我安装绕过CORS Chrome浏览器插件</Link>。或者添加 Chrome 启动参数: --disable-web-security 来解决。
|
|
</DialogContentText>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={() => {setCors(false)}}>我知道了</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
|
|
<div className="rootPanel">
|
|
|
|
<Box>
|
|
<Grid container direction="column" justifyContent="center" alignItems="center" spacing={1}>
|
|
<Paper elevation={3} className="inlineBox">
|
|
<Grid container direction="column" justifyContent="center" alignItems="center" spacing={2}>
|
|
<Grid item className="title">
|
|
<Typography variant="h5">
|
|
注册账户
|
|
</Typography>
|
|
|
|
</Grid>
|
|
<Grid container style={{maxWidth: '100%'}} spacing={2}>
|
|
<Grid style={{maxWidth: '100%'}} item>
|
|
<Collapse style={{maxWidth: '100%'}} in={illegal}>
|
|
<Alert style={{paddingRight: '1%', marginTop: '2px', maxWidth: '100%'}} severity="error">
|
|
{illegalMessgae}
|
|
</Alert>
|
|
</Collapse>
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
<TextField fullWidth required label="用户名" type="text" inputRef={usernameInput} onInput={() => setIllegal(false)} />
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
<TextField fullWidth required label="密码" type="password" inputRef={passwordInput} onInput={() => setIllegal(false)} />
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
<TextField fullWidth required label="邮箱" type="text" inputRef={emailInput} onInput={() => setIllegal(false)} />
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
<TextField fullWidth required label="邀请码" type="text" inputRef={invitationCodeInput} onInput={() => setIllegal(false)} />
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
<TextField fullWidth required label="校验码" type="text" inputRef={validationCodeInput} onInput={() => setIllegal(false)} />
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
<FormGroup>
|
|
<FormControlLabel label="使用同名正版用户皮肤" control={<Checkbox required checked={useMojangSkin} onClick={() => {setUseMojangSkin(!useMojangSkin)}} />}/>
|
|
</FormGroup>
|
|
</Grid>
|
|
|
|
<Grid item>
|
|
<Button onClick={handleRegister} variant="contained" color="primary" disabled={disableBtn} >
|
|
注册
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
</Paper>
|
|
</Grid>
|
|
</Box>
|
|
</div>
|
|
</ThemeProvider>
|
|
} |