Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/main/java/ru/scarletredman/gd2spring/config/TestConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import ru.scarletredman.gd2spring.model.Level;
import ru.scarletredman.gd2spring.model.User;
import ru.scarletredman.gd2spring.model.UserComment;
import ru.scarletredman.gd2spring.service.LevelService;
import ru.scarletredman.gd2spring.service.MessageService;
import ru.scarletredman.gd2spring.service.UserCommentService;
import ru.scarletredman.gd2spring.service.UserService;

@Profile("test")
@Configuration
@RequiredArgsConstructor
public class TestConfig {

private final UserService userService;
private final UserCommentService userCommentService;
private final LevelService levelService;
private final MessageService messageService;

@Autowired
void createTestUser(boolean debugMode) {
Expand All @@ -42,6 +46,12 @@ void createTestUser(boolean debugMode) {

var level = createTestLevel(user, "Test level");
levelService.uploadLevel(level);

var user2 = userService.findUserById(2).get();
for (int i = 0; i < 30; i++) {
messageService.sendMessage(user, user2, "Sent " + i, "Hello my dear friend, Test2!");
messageService.sendMessage(user2, user, "Received " + i, "Hello my dear friend, Test!");
}
}

Level createTestLevel(User owner, String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ GetLevelsResponse getLevels(
@RequestParam(name = "song", required = false, defaultValue = "0") int song,
@RequestParam(name = "customSong", required = false, defaultValue = "0") int customSong) {

var levels = levelService.getLevels(new LevelListPage.Filters(
"", null, null, 0, false, false, false, false, false, false, false, false, 0, 0, 0));
var filters = new LevelListPage.Filters(
levelName, null, null, page, false, false, false, false, false, false, false, false, 0, 0, 0);

var levels = levelService.getLevels(filters);
return responseLogger.result(new GetLevelsResponse(levels));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package ru.scarletredman.gd2spring.controller;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.binary.Base64;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ru.scarletredman.gd2spring.controller.annotation.GeometryDashAPI;
import ru.scarletredman.gd2spring.controller.response.GetMessagesResponse;
import ru.scarletredman.gd2spring.controller.response.MessageResponse;
import ru.scarletredman.gd2spring.controller.response.RemoveMessageResponse;
import ru.scarletredman.gd2spring.controller.response.UploadMessageResponse;
import ru.scarletredman.gd2spring.security.annotation.GDAuthorizedOnly;
import ru.scarletredman.gd2spring.service.MessageService;
import ru.scarletredman.gd2spring.service.UserService;
import ru.scarletredman.gd2spring.util.ResponseLogger;

@GeometryDashAPI
@RestController
@RequiredArgsConstructor
public class MessageController {

private final MessageService messageService;
private final UserService userService;
private final ResponseLogger responseLogger;

@GDAuthorizedOnly
@PostMapping("/getGJMessages20.php")
GetMessagesResponse messages(
@RequestParam(name = "page") int page,
@RequestParam(name = "total") long total,
@RequestParam(name = "getSent", required = false, defaultValue = "0") int isSent) {

if (page < 0) return responseLogger.result(GetMessagesResponse.error());

var user = UserService.getCurrentUserFromSecurityContextHolder();
var sent = isSent == 1;
var messages = messageService.getMessages(user, isSent == 1, page, 10);

return responseLogger.result(
new GetMessagesResponse(messages.messages(), sent, messages.total(), messages.page()));
}

@GDAuthorizedOnly
@PostMapping("/downloadGJMessage20.php")
MessageResponse download(
@RequestParam(name = "messageID") long messageId, @RequestParam(name = "isSender") int isSender) {

var user = UserService.getCurrentUserFromSecurityContextHolder();
var message = messageService.getMessageById(messageId);

if (message.isEmpty()) {
return responseLogger.result(MessageResponse.error());
}
var sender = isSender == 1;
var msg = message.get();

if ((sender && !Objects.equals(msg.getSender().getId(), user.getId()))
|| (!sender && !Objects.equals(msg.getReceiver().getId(), user.getId()))) {
return responseLogger.result(MessageResponse.error());
}

return responseLogger.result(new MessageResponse(msg, sender));
}

@GDAuthorizedOnly
@PostMapping("/uploadGJMessage20.php")
UploadMessageResponse upload(
@RequestParam(name = "toAccountID") long receiverUserId,
@RequestParam(name = "subject") String subject,
@RequestParam(name = "body") String body) {

var user = UserService.getCurrentUserFromSecurityContextHolder();
var receiver = userService.findUserById(receiverUserId);

if (receiver.isEmpty()) {
return responseLogger.result(UploadMessageResponse.error());
}

var decodedSubject = new String(Base64.decodeBase64(subject), StandardCharsets.UTF_8).replace('\0', ' ');
var decodedText = new String(Base64.decodeBase64(body), StandardCharsets.UTF_8).replace('\0', ' ');

messageService.sendMessage(user, receiver.get(), decodedSubject, decodedText);
return responseLogger.result(UploadMessageResponse.success());
}

@GDAuthorizedOnly
@PostMapping("/deleteGJMessages20.php")
RemoveMessageResponse delete(
@RequestParam(name = "messageID", defaultValue = "-1", required = false) long messageId,
@RequestParam(name = "messages", defaultValue = "", required = false) String messagesList) {

var user = UserService.getCurrentUserFromSecurityContextHolder();
if (messageId == -1 && messagesList.isEmpty()) return responseLogger.result(RemoveMessageResponse.success());

try {
if (messageId > 0) {
var message = messageService.getMessageById(messageId);
message.ifPresent(msg -> messageService.deleteMessage(user, msg));
}

if (!messagesList.isEmpty()) {
var ids = Arrays.stream(messagesList.split(","))
.map(num -> {
try {
return Long.parseLong(num);
} catch (NumberFormatException ex) {
return -1L;
}
})
.filter(num -> num != -1)
.toList();

messageService.deleteMessagesById(user, ids);
}
} catch (AccessDeniedException ex) {
return responseLogger.result(RemoveMessageResponse.error());
}

return responseLogger.result(RemoveMessageResponse.success());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package ru.scarletredman.gd2spring.controller.response;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.nio.charset.StandardCharsets;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.apache.commons.codec.binary.Base64;
import ru.scarletredman.gd2spring.controller.response.json.ResponseSerializer;
import ru.scarletredman.gd2spring.model.Message;
import ru.scarletredman.gd2spring.util.JoinResponseUtil;
import ru.scarletredman.gd2spring.util.TimeFormatUtil;

@Getter
@Setter
@JsonSerialize(using = ResponseSerializer.class)
public final class GetMessagesResponse implements ResponseSerializer.Response {

private long messagesCount;
private long offset;
private final List<MessageResponse> messages = new LinkedList<>();
private final boolean error;

private GetMessagesResponse() {
error = true;
}

public GetMessagesResponse(List<Message> messages, boolean sent, long messagesCount, long offset) {
this.messagesCount = messagesCount;
this.offset = offset;
init(messages, sent);
error = false;
}

public static GetMessagesResponse error() {
return new GetMessagesResponse();
}

private void init(List<Message> messages, boolean sent) {
this.messages.addAll(messages.stream()
.map(message -> new MessageResponse(message, sent))
.toList());
}

@Override
public String getResponse() {
if (error) return "-1";
if (messages.isEmpty()) return "-2";

var msgList = String.join(
"|", messages.stream().map(MessageResponse::getResponse).toList());
return msgList + "#" + messagesCount + ":" + (offset * 10) + ":10";
}

public static class MessageResponse implements ResponseSerializer.Response {

private final Map<MessageResponse.Key, Object> elements = new EnumMap<>(MessageResponse.Key.class);

public MessageResponse(Message message, boolean isSender) {
init(message, isSender);
}

private void init(Message message, boolean isSender) {
var target = isSender ? message.getReceiver() : message.getSender();
var targetId = target.getId();

elements.put(MessageResponse.Key.MESSAGE_ID, message.getId());
elements.put(MessageResponse.Key.TARGET_USER_ID1, targetId);
elements.put(MessageResponse.Key.TARGET_USER_ID2, targetId);
setSubject(message.getSubject());
elements.put(Key.TARGET_USERNAME, target.getUsername());
elements.put(Key.UPLOAD_TIME, TimeFormatUtil.formatBetween(message.getTime()));
elements.put(Key.IS_NEW, message.isNew() ? 1 : 0);
elements.put(Key.IS_SENDER, isSender ? 1 : 0);
}

public void setSubject(String subject) {
elements.put(Key.SUBJECT, Base64.encodeBase64String(subject.getBytes(StandardCharsets.UTF_8)));
}

@Override
public String getResponse() {
return JoinResponseUtil.join(elements, ":");
}

@Getter
@RequiredArgsConstructor
public enum Key implements JoinResponseUtil.Key {
MESSAGE_ID("1"),
TARGET_USER_ID1("2"),
TARGET_USER_ID2("3"),
SUBJECT("4"),
TARGET_USERNAME("6"),
UPLOAD_TIME("7"),
IS_NEW("8"),
IS_SENDER("9"),
;

private final String code;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package ru.scarletredman.gd2spring.controller.response;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.nio.charset.StandardCharsets;
import java.util.EnumMap;
import java.util.Map;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.apache.commons.codec.binary.Base64;
import ru.scarletredman.gd2spring.controller.response.json.ResponseSerializer;
import ru.scarletredman.gd2spring.model.Message;
import ru.scarletredman.gd2spring.util.JoinResponseUtil;
import ru.scarletredman.gd2spring.util.TimeFormatUtil;

@Getter
@Setter
@JsonSerialize(using = ResponseSerializer.class)
public final class MessageResponse implements ResponseSerializer.Response {

private final Map<Key, Object> elements = new EnumMap<>(Key.class);
private final boolean error;

private MessageResponse() {
error = true;
}

public MessageResponse(Message message, boolean isSender) {
init(message, isSender);
error = false;
}

public static MessageResponse error() {
return new MessageResponse();
}

private void init(Message message, boolean isSender) {
var target = isSender ? message.getReceiver() : message.getSender();
var targetId = target.getId();

elements.put(Key.MESSAGE_ID, message.getId());
elements.put(Key.TARGET_USER_ID1, targetId);
elements.put(Key.TARGET_USER_ID2, targetId);
setSubject(message.getSubject());
setText(message.getText());
elements.put(Key.TARGET_USERNAME, target.getUsername());
elements.put(Key.UPLOAD_TIME, TimeFormatUtil.formatBetween(message.getTime()));
elements.put(Key.IS_SENDER, isSender ? 1 : 0);
elements.put(Key.IS_NEW, message.isNew() ? 1 : 0);
}

public void setSubject(String subject) {
elements.put(Key.SUBJECT, Base64.encodeBase64String(subject.getBytes(StandardCharsets.UTF_8)));
}

public void setText(String message) {
elements.put(Key.BODY, Base64.encodeBase64String(message.getBytes(StandardCharsets.UTF_8)));
}

@Override
public String getResponse() {
if (error) return "-1";
return JoinResponseUtil.join(elements, ":");
}

@Getter
@RequiredArgsConstructor
public enum Key implements JoinResponseUtil.Key {
MESSAGE_ID("1"),
TARGET_USER_ID1("2"),
TARGET_USER_ID2("3"),
SUBJECT("4"),
BODY("5"),
TARGET_USERNAME("6"),
UPLOAD_TIME("7"),
IS_NEW("8"),
IS_SENDER("9"),
;

private final String code;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.scarletredman.gd2spring.controller.response;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import ru.scarletredman.gd2spring.controller.response.json.ResponseSerializer;

@JsonSerialize(using = ResponseSerializer.class)
public final class RemoveMessageResponse implements ResponseSerializer.Response {

private final boolean error;

private RemoveMessageResponse(boolean error) {
this.error = error;
}

public static RemoveMessageResponse success() {
return new RemoveMessageResponse(false);
}

public static RemoveMessageResponse error() {
return new RemoveMessageResponse(true);
}

@Override
public String getResponse() {
return error ? "-1" : "1";
}
}
Loading