rename com.imyeyu.server to com.imyeyu.api
This commit is contained in:
@@ -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 {
|
||||
}
|
||||
+51
@@ -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;
|
||||
}
|
||||
+62
@@ -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);
|
||||
}
|
||||
}
|
||||
+25
@@ -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();
|
||||
}
|
||||
}
|
||||
+151
@@ -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 {
|
||||
}
|
||||
Reference in New Issue
Block a user