rename com.imyeyu.server to com.imyeyu.api

This commit is contained in:
Timi
2025-07-22 15:26:14 +08:00
parent e816b885b2
commit 323e038e86
340 changed files with 1174 additions and 1175 deletions
@@ -0,0 +1,20 @@
package com.imyeyu.api.modules.minecraft.annotation;
import org.springframework.stereotype.Component;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 需要令牌
*
* @author 夜雨
* @since 2024-08-06 16:38
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface RequiredFMCServerToken {
}
@@ -0,0 +1,51 @@
package com.imyeyu.api.modules.minecraft.annotation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.api.modules.common.bean.SettingKey;
import com.imyeyu.api.modules.common.service.SettingService;
import com.imyeyu.spring.TimiSpring;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
/**
* Minecraft 服务器接口验证令牌
*
* @author 夜雨
* @since 2024-08-06 16:40
*/
@Component
@RequiredArgsConstructor
public class RequiredFMCServerTokenInterceptor implements HandlerInterceptor {
private final SettingService settingService;
/**
* 处理请求
*
* @param req 请求
* @param resp 返回
* @param handler 处理方法
* @return true 为通过
*/
@Override
public boolean preHandle(@NonNull HttpServletRequest req, @NonNull HttpServletResponse resp, @NonNull Object handler) {
// 方法注解
if (handler instanceof HandlerMethod handlerMethod) {
RequiredFMCServerToken requiredFMCServerToken = handlerMethod.getMethodAnnotation(RequiredFMCServerToken.class);
if (requiredFMCServerToken == null) {
return true;
}
if (!settingService.getAsString(SettingKey.FMC_SERVER_TOKEN).equals(TimiSpring.getToken())) {
throw new TimiException(TimiCode.ARG_MISS).msgKey("token.illegal");
}
return true;
}
return true;
}
}
@@ -0,0 +1,12 @@
package com.imyeyu.api.modules.minecraft.bean;
/**
* @author 夜雨
* @since 2024-04-28 22:06
*/
public enum AttachType {
LAUNCHER_BG,
LAUNCHER_BGM
}
@@ -0,0 +1,78 @@
package com.imyeyu.api.modules.minecraft.controller;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.api.annotation.EnableSetting;
import com.imyeyu.api.modules.blog.util.UserToken;
import com.imyeyu.api.modules.common.bean.SettingKey;
import com.imyeyu.api.modules.minecraft.service.FMCImageMapService;
import com.imyeyu.spring.annotation.AOPLog;
import com.imyeyu.spring.annotation.RequestRateLimit;
import com.imyeyu.spring.annotation.RequiredToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* Minecraft 相关接口
*
* @author 夜雨
* @since 2021-05-20 00:24
*/
@Slf4j
@Validated
@RestController
@RequestMapping("/fmc")
public class MinecraftController {
@Autowired
private FMCImageMapService fmcImageMapService;
@Autowired
private UserToken userToken;
/**
* 上传 FMCImageMap 插件图床图片
*
* @param file 文件
* @return 头像资源路径
*/
@AOPLog
@RequiredToken
@EnableSetting(value = SettingKey.FMC_ENABLE_IMAGE_MAP_UPLOAD, message = "minecraft.fmc_image_map.off_service")
@RequestRateLimit
@PostMapping("/imagemap/upload")
public String uploadFMCImageMap(@NotNull @RequestParam("request") MultipartFile file) {
if (file.getOriginalFilename() != null && !file.getOriginalFilename().endsWith(".png")) {
throw new TimiException(TimiCode.ARG_BAD).msgKey("minecraft.fmc_image_map.png_only");
}
return fmcImageMapService.upload(file);
}
@AOPLog
@RequiredToken
@RequestRateLimit
@PostMapping("/imagemap/list")
public List<String> listAllFMCImageMap() {
return fmcImageMapService.findAll();
}
@AOPLog
@RequiredToken
@RequestRateLimit
@PostMapping("/imagemap/delete")
public void deleteFMCImageMap(@NotBlank @Valid @RequestBody String fileName) {
fmcImageMapService.delete(fileName);
}
}
@@ -0,0 +1,47 @@
package com.imyeyu.api.modules.minecraft.controller;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiResponse;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPack;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPackSource;
import com.imyeyu.api.modules.minecraft.service.PackService;
import com.imyeyu.spring.annotation.RequestRateLimit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 客户端接口,通常是 ForeverMC 启动器请求
*
* @author 夜雨
* @since 2023-06-13 17:15
*/
@Slf4j
@RestController
@RequestMapping("/fmc/pack")
public class PackController {
@Autowired
private PackService service;
/**
* 可用客户端列表
*
* @return 客户端列表
*/
@RequestRateLimit
@RequestMapping("/list")
public TimiResponse<?> listPacks() {
List<MinecraftPack> list = service.listPacks();
for (int i = 0; i < list.size(); i++) {
List<MinecraftPackSource> sourceList = list.get(i).getSourceList();
for (int j = 0; j < sourceList.size(); j++) {
sourceList.get(j).setOrder(null);
}
}
return new TimiResponse<>(TimiCode.SUCCESS, list);
}
}
@@ -0,0 +1,127 @@
package com.imyeyu.api.modules.minecraft.controller;
import jakarta.annotation.PostConstruct;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.api.annotation.EnableSetting;
import com.imyeyu.api.config.RedisConfig;
import com.imyeyu.api.modules.blog.util.UserToken;
import com.imyeyu.api.modules.common.bean.SettingKey;
import com.imyeyu.api.modules.common.service.UserService;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer;
import com.imyeyu.api.modules.minecraft.service.PlayerService;
import com.imyeyu.api.modules.minecraft.vo.TokenRequest;
import com.imyeyu.api.modules.minecraft.vo.TokenResponse;
import com.imyeyu.spring.annotation.AOPLog;
import com.imyeyu.spring.annotation.RequestRateLimit;
import com.imyeyu.spring.annotation.RequestSingleParam;
import com.imyeyu.spring.annotation.RequiredToken;
import com.imyeyu.spring.util.Redis;
import com.imyeyu.spring.util.RedisSerializers;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 玩家控制(登录或账号管理)
*
* @author 夜雨
* @since 2024-03-29 12:55
*/
@RestController
@RequestMapping("/fmc/player")
@RequiredArgsConstructor
public class PlayerController {
private final RedisConfig redisConfig;
private final UserService userService;
private final PlayerService service;
private final UserToken userToken;
private Redis<String, Long> redis;
@PostConstruct
private void postConstruct() {
redis = redisConfig.getRedis(redisConfig.getDatabase().getFmcPlayerToken(), RedisSerializers.STRING, RedisSerializers.LONG);
}
/**
* 该玩家名是否已绑定
*
* @param name 玩家名
* @return true 为已绑定
*/
@RequestRateLimit
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
@GetMapping("/bound/{name}")
public boolean isBound(@PathVariable("name") String name) {
return service.getByName(name) != null;
}
@AOPLog
@RequiredToken
@RequestRateLimit
@PostMapping("/bind")
public void bind(@RequestSingleParam String name) {
MinecraftPlayer player = new MinecraftPlayer();
player.setName(name);
player.setUserId(userService.getLoginUser().getId());
service.create(player);
}
@AOPLog
@RequiredToken
@RequestRateLimit
@PostMapping("/unbind")
public void unbind(@RequestSingleParam Long id) {
service.listByUserId(userService.getLoginUser().getId())
.stream()
.filter(player -> player.getId().equals(id))
.findFirst()
.ifPresent(player -> service.delete(player.getId()));
}
@RequestRateLimit
@PostMapping("/list")
public List<MinecraftPlayer> listPlayer(@RequestHeader("Token") String token) {
Long userId = TimiJava.firstNotNull(redis.get(token), userToken.getUserId(token));
if (userId == null) {
throw new TimiException(TimiCode.RESULT_BAD).msgKey("token.illegal");
}
List<MinecraftPlayer> result = service.listByUserId(userId);
for (int i = 0; i < result.size(); i++) {
MinecraftPlayer player = result.get(i);
player.setLastLoginIP(null);
player.setCreatedAt(null);
player.setUpdatedAt(null);
}
return result;
}
@AOPLog
@RequestRateLimit
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
@PostMapping("/login")
public TokenResponse login(@RequestSingleParam Long playerId, @RequestHeader("Token") String token) {
return service.login(playerId, token);
}
@AOPLog
@RequestRateLimit
@EnableSetting(value = SettingKey.FMC_PLAYER_LOGIN_ENABLE, message = "登录服务未启用")
@PostMapping("/login/token")
public TokenResponse genLoginToken(@Valid @RequestBody TokenRequest request) {
return service.genLoginToken(request);
}
}
@@ -0,0 +1,45 @@
package com.imyeyu.api.modules.minecraft.entity;
import com.imyeyu.spring.entity.Entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* 整合包
*
* @author 夜雨
* @since 2023-06-13 17:17
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MinecraftPack extends Entity {
/** 名称 */
private String name;
/** 整合包版本 */
private String ver;
/** 标题 */
private String title;
/** 说明 */
private String description;
/** 游戏版本 */
private String gameVer;
/** 默认配置 */
private String defOption;
/** 文件大小 */
private long size;
/** true 为已过时 */
private boolean isDeprecated;
/** 下载源列表 */
private List<MinecraftPackSource> sourceList;
}
@@ -0,0 +1,47 @@
package com.imyeyu.api.modules.minecraft.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.imyeyu.spring.entity.Entity;
/**
* 整合包下载源
*
* @author 夜雨
* @since 2023-06-13 17:32
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MinecraftPackSource extends Entity {
/**
*
*
* @author 夜雨
* @since 2024-06-18 12:53
*/
public enum Type {
ATTACH,
URL
}
/** 整合包 ID */
private Long packId;
/** 名称 */
private String name;
/** 类型 */
private Type type;
/** 地址 */
private String data;
/** 排序 */
private Integer order;
/** true 为默认 */
private boolean isDefault;
}
@@ -0,0 +1,28 @@
package com.imyeyu.api.modules.minecraft.entity;
import com.imyeyu.spring.entity.Entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* @author 夜雨
* @since 2024-03-29 10:08
*/
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class MinecraftPlayer extends Entity {
private Long userId;
private String name;
private String lastLoginIP;
private Long lastLoginAt;
public MinecraftPlayer(Long userId) {
this.userId = userId;
}
}
@@ -0,0 +1,14 @@
package com.imyeyu.api.modules.minecraft.mapper;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPack;
import java.util.List;
/**
* @author 夜雨
* @since 2023-06-13 17:34
*/
public interface PackMapper {
List<MinecraftPack> listPacks();
}
@@ -0,0 +1,20 @@
package com.imyeyu.api.modules.minecraft.mapper;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer;
import com.imyeyu.spring.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author 夜雨
* @since 2024-03-29 10:08
*/
public interface PlayerMapper extends BaseMapper<MinecraftPlayer, Long> {
@Select("SELECT * FROM minecraft_player WHERE user_id = #{userId}" + NOT_DELETE)
List<MinecraftPlayer> listByUserId(Long userId);
@Select("SELECT * FROM minecraft_player WHERE name = #{name}" + NOT_DELETE + LIMIT_1)
MinecraftPlayer selectByName(String name);
}
@@ -0,0 +1,38 @@
package com.imyeyu.api.modules.minecraft.service;
import com.imyeyu.java.bean.timi.TimiException;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @author 夜雨
* @since 2023-07-15 18:11
*/
public interface FMCImageMapService {
/**
* 上传 FMCImageMap 插件图床图片
*
* @param file 上传文件对象
* @return 回调该资源路径
* @throws TimiException 服务异常
*/
String upload(MultipartFile file);
/**
* 获取该用户上传 FMCImageMap 插件图床的图片
*
* @return 文件名
* @throws TimiException 服务异常
*/
List<String> findAll();
/**
* 删除上传 IMCImgMap 插件图床的图片
*
* @param fileName 图片文件名
* @throws TimiException 服务异常
*/
void delete(String fileName);
}
@@ -0,0 +1,14 @@
package com.imyeyu.api.modules.minecraft.service;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPack;
import java.util.List;
/**
* @author 夜雨
* @since 2023-06-13 17:33
*/
public interface PackService {
List<MinecraftPack> listPacks();
}
@@ -0,0 +1,38 @@
package com.imyeyu.api.modules.minecraft.service;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer;
import com.imyeyu.api.modules.minecraft.vo.TokenRequest;
import com.imyeyu.api.modules.minecraft.vo.TokenResponse;
import com.imyeyu.spring.service.CreatableService;
import com.imyeyu.spring.service.DeletableService;
import java.util.List;
/**
* @author 夜雨
* @version 2024-03-29 10:08
*/
public interface PlayerService extends CreatableService<MinecraftPlayer>, DeletableService<Long> {
/**
* 根据绑定玩家名获取玩家
*
* @param name 绑定玩家名
* @return 玩家
* @throws TimiException 服务异常
*/
MinecraftPlayer getByName(String name) throws TimiException;
/**
* 获取玩家
*
* @return 玩家
* @throws TimiException 服务异常
*/
List<MinecraftPlayer> listByUserId(Long userId) throws TimiException;
TokenResponse login(Long playerId, String loginToken) throws TimiException;
TokenResponse genLoginToken(TokenRequest request) throws TimiException;
}
@@ -0,0 +1,62 @@
package com.imyeyu.api.modules.minecraft.service.implement;
import lombok.RequiredArgsConstructor;
import com.imyeyu.api.modules.common.service.UserService;
import com.imyeyu.api.modules.minecraft.service.FMCImageMapService;
import com.imyeyu.api.modules.system.service.FileService;
import com.imyeyu.utils.OS;
import org.jcodec.api.NotSupportedException;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @author 夜雨
* @version 2023-07-15 18:11
*/
@Service
@RequiredArgsConstructor
public class FMCImageMapServiceImplement implements FMCImageMapService, OS.FileSystem {
private final UserService userService;
private final FileService fileService;
@Override
public String upload(MultipartFile file) {
throw new NotSupportedException("TODO update");
// try {
// User user = userService.getLoginUser();
// BufferedImage img = ImageIO.read(file.getInputStream());
// // 限制尺寸为 128
// if (img.getWidth() != 128 || img.getHeight() != 128) {
// throw new TimiException(TimiCode.ARG_BAD).msgKey("图片尺寸需为 128 × 128 像素");
// }
// // 文件夹
// fileService.mkdirs(config.getResources().getMcMap() + SEP + user.getId() + SEP);
// // 处理文件
// ResourceFile res = new ResourceFile();
// res.setName(System.currentTimeMillis() + "_" + Digest.md5(String.valueOf(Math.random())).substring(0, 8) + ".png");
// res.setPath(config.getResources().getMcMap() + SEP + user.getId() + SEP);
// res.setInputStream(file.getInputStream());
// fileService.upload(res);
// return res.getFullPath();
// } catch (Exception e) {
// throw new TimiException(TimiCode.ERROR).msgKey("上传文件异常:" + e.getMessage());
// }
}
@Override
public List<String> findAll() {
throw new NotSupportedException("TODO update");
// User user = userService.getLoginUser();
// return fileService.list4TimiServer(config.getResources().getMcMap() + SEP + user.getId() + SEP).stream().map(File::getName).collect(Collectors.toList());
}
@Override
public void delete(String fileName) {
throw new NotSupportedException("TODO update");
// User user = userService.getLoginUser();
// fileService.destroy(config.getResources().getMcMap() + SEP + user.getId() + SEP + fileName);
}
}
@@ -0,0 +1,25 @@
package com.imyeyu.api.modules.minecraft.service.implement;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPack;
import com.imyeyu.api.modules.minecraft.mapper.PackMapper;
import com.imyeyu.api.modules.minecraft.service.PackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author 夜雨
* @version 2023-06-13 17:34
*/
@Service
public class PackServiceImplement implements PackService {
@Autowired
private PackMapper mapper;
@Override
public List<MinecraftPack> listPacks() {
return mapper.listPacks();
}
}
@@ -0,0 +1,151 @@
package com.imyeyu.api.modules.minecraft.service.implement;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.api.config.RedisConfig;
import com.imyeyu.api.modules.common.bean.SettingKey;
import com.imyeyu.api.modules.common.entity.User;
import com.imyeyu.api.modules.common.service.SettingService;
import com.imyeyu.api.modules.common.service.UserService;
import com.imyeyu.api.modules.minecraft.entity.MinecraftPlayer;
import com.imyeyu.api.modules.minecraft.mapper.PlayerMapper;
import com.imyeyu.api.modules.minecraft.service.PlayerService;
import com.imyeyu.api.modules.minecraft.vo.TokenRequest;
import com.imyeyu.api.modules.minecraft.vo.TokenResponse;
import com.imyeyu.spring.TimiSpring;
import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.service.AbstractEntityService;
import com.imyeyu.spring.util.Redis;
import com.imyeyu.spring.util.RedisSerializers;
import com.imyeyu.utils.Calc;
import com.imyeyu.utils.Time;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
/**
* @author 夜雨
* @version 2024-03-29 10:08
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class PlayerServiceImplement extends AbstractEntityService<MinecraftPlayer, Long> implements PlayerService {
private final RedisConfig redisConfig;
private final UserService userService;
private final SettingService settingService;
private final PlayerMapper mapper;
private Redis<String, Long> redis;
@Override
protected BaseMapper<MinecraftPlayer, Long> mapper() {
return mapper;
}
@PostConstruct
private void postConstruct() {
redis = redisConfig.getRedis(redisConfig.getDatabase().getFmcPlayerToken(), RedisSerializers.STRING, RedisSerializers.LONG);
}
@Override
public void create(MinecraftPlayer player) {
if (player.getName().contains(" ")) {
throw new TimiException(TimiCode.ARG_BAD).msgKey("绑定玩家昵称不允许有空格");
}
// 自查重
List<MinecraftPlayer> playerList = listByUserId(player.getUserId());
if (settingService.getAsInt(SettingKey.FMC_MAX_BIND) <= playerList.size()) {
throw new TimiException(TimiCode.RESULT_BAD).msgKey("已达到最大绑定数量:%s 个".formatted(settingService.getAsInt(SettingKey.FMC_MAX_BIND)));
}
for (int i = 0; i < playerList.size(); i++) {
if (playerList.get(i).getName().equals(player.getName())) {
throw new TimiException(TimiCode.RESULT_BAD).msgKey("已绑定此玩家名称");
}
}
// 全局查重
MinecraftPlayer playerByName = getByName(player.getName());
if (playerByName != null && !playerByName.getUserId().equals(player.getUserId())) {
throw new TimiException(TimiCode.DATA_EXIST).msgKey("此玩家昵称已被绑定,请使用其他昵称");
}
MinecraftPlayer dbPlayer = new MinecraftPlayer();
dbPlayer.setUserId(player.getUserId());
dbPlayer.setName(player.getName());
super.create(dbPlayer);
}
@Override
public MinecraftPlayer getByName(String name) throws TimiException {
return mapper.selectByName(name);
}
@Override
public List<MinecraftPlayer> listByUserId(Long userId) throws TimiException {
return mapper.listByUserId(userId);
}
@Override
public TokenResponse login(Long playerId, String loginToken) throws TimiException {
Long userId = redis.get(loginToken);
if (userId == null) {
throw new TimiException(TimiCode.RESULT_BAD).msgKey("token.illegal");
}
List<MinecraftPlayer> playerList = listByUserId(userId);
MinecraftPlayer player = null;
for (int i = 0; i < playerList.size(); i++) {
if (playerList.get(i).getId().equals(playerId)) {
player = playerList.get(i);
break;
}
}
if (player == null) {
throw new TimiException(TimiCode.RESULT_BAD).msgKey("token.illegal");
}
player.setLastLoginIP(TimiSpring.getRequestIP());
player.setLastLoginAt(Time.now());
mapper.update(player);
String playerToken = UUID.randomUUID().toString();
long ttl = settingService.getAsInt(SettingKey.FMC_PLAYER_LOGIN_TOKEN_TTL) * Time.D;
redis.set(playerToken, playerId, ttl);
return new TokenResponse(userId, playerToken, Time.now() + ttl);
}
@Override
public TokenResponse genLoginToken(TokenRequest request) throws TimiException {
String reqUser = request.getUser();
User user;
if (Calc.isNumber(reqUser)) {
user = userService.get(Long.valueOf(reqUser));
} else if (reqUser.contains("@")) {
user = userService.getByEmail(reqUser);
} else {
MinecraftPlayer playerByName = getByName(reqUser);
if (playerByName == null) {
throw new TimiException(TimiCode.RESULT_NULL).msgKey("not found player");
}
user = userService.get(playerByName.getUserId());
}
if (user == null) {
throw new TimiException(TimiCode.RESULT_NULL).msgKey("未注册或绑定此玩家昵称,请到 https://%s 进行注册或绑定".formatted(settingService.getAsString(SettingKey.DOMAIN_SPACE)));
}
if (user.isBanning()) {
throw new TimiException(TimiCode.RESULT_BAN).msgKey("账号封禁中");
}
if (userService.isInvalidPassword(user.getPassword(), request.getPassword())) {
throw new TimiException(TimiCode.ARG_BAD).msgKey("密码错误");
}
String token = UUID.randomUUID().toString();
long ttl = settingService.getAsInt(SettingKey.FMC_PLAYER_LOGIN_TOKEN_TTL) * Time.D;
redis.set(token, user.getId(), ttl);
return new TokenResponse(user.getId(), token, Time.now() + ttl);
}
}
@@ -0,0 +1,15 @@
package com.imyeyu.api.modules.minecraft.vo;
import lombok.Data;
/**
* @author 夜雨
* @version 2024-03-29 14:14
*/
@Data
public class LoginRequest {
private Long playerId;
private String token;
}
@@ -0,0 +1,18 @@
package com.imyeyu.api.modules.minecraft.vo;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* @author 夜雨
* @version 2024-03-29 14:14
*/
@Data
public class TokenRequest {
@NotBlank(message = "todo.msg")
private String user;
@NotBlank(message = "todo.msg")
private String password;
}
@@ -0,0 +1,26 @@
package com.imyeyu.api.modules.minecraft.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 令牌返回
*
* @author 夜雨
* @since 2024-03-29 10:13
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TokenResponse {
/** 用户 ID */
private Long userId;
/** 令牌 */
private String token;
/** 过期于 */
private long expiredAt;
}
@@ -0,0 +1,14 @@
package com.imyeyu.api.modules.minecraft.vo.server;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.imyeyu.api.modules.forevermc.bean.ServerStatus;
/**
* @author 夜雨
* @since 2024-08-06 16:36
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ReportRequest extends ServerStatus {
}