Add nickname retrieval support: implemented NicknameMapper for database queries, updated ChatService to return player names with optional nicknames, and extended /chat/player/{uuid}/name API endpoint.
This commit is contained in:
parent
f9f05dcc88
commit
8931bdc30d
|
|
@ -2,6 +2,7 @@ package com.alttd.altitudeweb.controllers.chat;
|
||||||
|
|
||||||
import com.alttd.altitudeweb.api.ChatApi;
|
import com.alttd.altitudeweb.api.ChatApi;
|
||||||
import com.alttd.altitudeweb.model.ChatMessageDto;
|
import com.alttd.altitudeweb.model.ChatMessageDto;
|
||||||
|
import com.alttd.altitudeweb.model.PlayerNameDto;
|
||||||
import com.alttd.altitudeweb.model.ServerStateDto;
|
import com.alttd.altitudeweb.model.ServerStateDto;
|
||||||
import com.alttd.altitudeweb.services.chat.ChatService;
|
import com.alttd.altitudeweb.services.chat.ChatService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
@ -11,6 +12,7 @@ import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
|
|
@ -31,4 +33,11 @@ public class ChatController implements ChatApi {
|
||||||
//TODO [Stijn] [2026-07-18]: Implement handling server state updates (push to listeners)
|
//TODO [Stijn] [2026-07-18]: Implement handling server state updates (push to listeners)
|
||||||
throw new UnsupportedOperationException("Not implemented");
|
throw new UnsupportedOperationException("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<PlayerNameDto> getName(UUID uuid) {
|
||||||
|
return chatService.getPlayerName(uuid)
|
||||||
|
.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,10 @@ import com.alttd.altitudeweb.controllers.chat.ChatMessageMapper;
|
||||||
import com.alttd.altitudeweb.controllers.chat.ChatMessageType;
|
import com.alttd.altitudeweb.controllers.chat.ChatMessageType;
|
||||||
import com.alttd.altitudeweb.database.Databases;
|
import com.alttd.altitudeweb.database.Databases;
|
||||||
import com.alttd.altitudeweb.database.chat.ChatLogMapper;
|
import com.alttd.altitudeweb.database.chat.ChatLogMapper;
|
||||||
|
import com.alttd.altitudeweb.database.chat.NicknameMapper;
|
||||||
|
import com.alttd.altitudeweb.database.luckperms.UUIDUsernameMapper;
|
||||||
import com.alttd.altitudeweb.model.PermissionClaimDto;
|
import com.alttd.altitudeweb.model.PermissionClaimDto;
|
||||||
|
import com.alttd.altitudeweb.model.PlayerNameDto;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.EventPublisher;
|
import com.alttd.altitudeweb.services.chat.event_publisher.EventPublisher;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.EventUser;
|
import com.alttd.altitudeweb.services.chat.event_publisher.EventUser;
|
||||||
import com.alttd.altitudeweb.setup.Connection;
|
import com.alttd.altitudeweb.setup.Connection;
|
||||||
|
|
@ -142,4 +145,22 @@ public class ChatService {
|
||||||
return chatMessages.tailMap(instant, false).values().stream().toList();
|
return chatMessages.tailMap(instant, false).values().stream().toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<PlayerNameDto> getPlayerName(UUID uuid) {
|
||||||
|
String username = Connection.getConnection(Databases.LUCK_PERMS)
|
||||||
|
.runQueryWithResult(sqlSession -> sqlSession.getMapper(UUIDUsernameMapper.class).getUsernameFromUUID(uuid.toString()));
|
||||||
|
|
||||||
|
if (username == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<String> nickname = Connection.getConnection(Databases.CHAT)
|
||||||
|
.runQueryWithResult(sqlSession -> sqlSession.getMapper(NicknameMapper.class).getNicknameFromUUID(uuid.toString()));
|
||||||
|
|
||||||
|
PlayerNameDto playerNameDto = new PlayerNameDto();
|
||||||
|
playerNameDto.setName(username);
|
||||||
|
playerNameDto.setNickname(nickname.orElse(null));
|
||||||
|
|
||||||
|
return Optional.of(playerNameDto);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class ChatServiceTest {
|
||||||
verify(eventPublisher).sendToUsers(anyString(), captor.capture());
|
verify(eventPublisher).sendToUsers(anyString(), captor.capture());
|
||||||
|
|
||||||
MessageForUser messageForUser = captor.getValue();
|
MessageForUser messageForUser = captor.getValue();
|
||||||
EventUser user = new EventUser(UUID.randomUUID(), List.of());
|
EventUser user = new EventUser(UUID.randomUUID(), List.of(), null);
|
||||||
String result = messageForUser.get(user);
|
String result = messageForUser.get(user);
|
||||||
|
|
||||||
assertTrue(result.contains("hello"));
|
assertTrue(result.contains("hello"));
|
||||||
|
|
@ -73,10 +73,10 @@ class ChatServiceTest {
|
||||||
|
|
||||||
MessageForUser messageForUser = captor.getValue();
|
MessageForUser messageForUser = captor.getValue();
|
||||||
|
|
||||||
EventUser regularUser = new EventUser(UUID.randomUUID(), List.of());
|
EventUser regularUser = new EventUser(UUID.randomUUID(), List.of(), null);
|
||||||
assertFalse(messageForUser.get(regularUser).contains("staff chat"), "Regular user should not see GAC message");
|
assertFalse(messageForUser.get(regularUser).contains("staff chat"), "Regular user should not see GAC message");
|
||||||
|
|
||||||
EventUser modUser = new EventUser(UUID.randomUUID(), List.of(PermissionClaimDto.MOD.getValue()));
|
EventUser modUser = new EventUser(UUID.randomUUID(), List.of(PermissionClaimDto.MOD.getValue()), null);
|
||||||
assertTrue(messageForUser.get(modUser).contains("staff chat"), "MOD should see GAC message");
|
assertTrue(messageForUser.get(modUser).contains("staff chat"), "MOD should see GAC message");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,9 +101,9 @@ class ChatServiceTest {
|
||||||
|
|
||||||
MessageForUser messageForUser = captor.getValue();
|
MessageForUser messageForUser = captor.getValue();
|
||||||
|
|
||||||
EventUser sender = new EventUser(senderUuid, List.of());
|
EventUser sender = new EventUser(senderUuid, List.of(), null);
|
||||||
EventUser receiver = new EventUser(receiverUuid, List.of());
|
EventUser receiver = new EventUser(receiverUuid, List.of(), null);
|
||||||
EventUser other = new EventUser(UUID.randomUUID(), List.of());
|
EventUser other = new EventUser(UUID.randomUUID(), List.of(), null);
|
||||||
|
|
||||||
assertTrue(messageForUser.get(sender).contains("private message"), "Sender should see their own message");
|
assertTrue(messageForUser.get(sender).contains("private message"), "Sender should see their own message");
|
||||||
assertTrue(messageForUser.get(receiver).contains("private message"), "Receiver should see the message");
|
assertTrue(messageForUser.get(receiver).contains("private message"), "Receiver should see the message");
|
||||||
|
|
@ -127,7 +127,7 @@ class ChatServiceTest {
|
||||||
verify(eventPublisher).sendToUsers(anyString(), captor.capture());
|
verify(eventPublisher).sendToUsers(anyString(), captor.capture());
|
||||||
|
|
||||||
MessageForUser messageForUser = captor.getValue();
|
MessageForUser messageForUser = captor.getValue();
|
||||||
EventUser user = new EventUser(UUID.randomUUID(), List.of());
|
EventUser user = new EventUser(UUID.randomUUID(), List.of(), null);
|
||||||
assertTrue(messageForUser.get(user).contains("global hello"));
|
assertTrue(messageForUser.get(user).contains("global hello"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,8 +148,8 @@ class ChatServiceTest {
|
||||||
verify(eventPublisher).sendToUsers(anyString(), captor.capture());
|
verify(eventPublisher).sendToUsers(anyString(), captor.capture());
|
||||||
|
|
||||||
MessageForUser messageForUser = captor.getValue();
|
MessageForUser messageForUser = captor.getValue();
|
||||||
EventUser regularUser = new EventUser(UUID.randomUUID(), List.of());
|
EventUser regularUser = new EventUser(UUID.randomUUID(), List.of(), null);
|
||||||
EventUser headModUser = new EventUser(UUID.randomUUID(), List.of(PermissionClaimDto.HEAD_MOD.getValue()));
|
EventUser headModUser = new EventUser(UUID.randomUUID(), List.of(PermissionClaimDto.HEAD_MOD.getValue()), null);
|
||||||
|
|
||||||
assertFalse(messageForUser.get(regularUser).contains("blocked message"));
|
assertFalse(messageForUser.get(regularUser).contains("blocked message"));
|
||||||
assertTrue(messageForUser.get(headModUser).contains("blocked message"));
|
assertTrue(messageForUser.get(headModUser).contains("blocked message"));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.alttd.altitudeweb.database.chat;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface NicknameMapper {
|
||||||
|
@Select("""
|
||||||
|
SELECT nickname
|
||||||
|
FROM nicknames
|
||||||
|
WHERE uuid = #{uuid}
|
||||||
|
""")
|
||||||
|
Optional<String> getNicknameFromUUID(@Param("uuid") String uuid);
|
||||||
|
}
|
||||||
|
|
@ -144,6 +144,26 @@ public class Connection {
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> T runQueryWithResult(QueryFunction<T> function) {
|
||||||
|
if (sqlSessionFactory == null) {
|
||||||
|
sqlSessionFactory = createSqlSessionFactory(settings, addMappers);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (SqlSession session = sqlSessionFactory.openSession()) {
|
||||||
|
T result = function.apply(session);
|
||||||
|
session.commit();
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to run query", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface QueryFunction<T> {
|
||||||
|
T apply(SqlSession session);
|
||||||
|
}
|
||||||
|
|
||||||
private SqlSessionFactory createSqlSessionFactory(DatabaseSettings settings, AddMappers addMappers) {
|
private SqlSessionFactory createSqlSessionFactory(DatabaseSettings settings, AddMappers addMappers) {
|
||||||
try {
|
try {
|
||||||
Configuration configuration = getConfiguration(settings);
|
Configuration configuration = getConfiguration(settings);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.alttd.altitudeweb.setup;
|
||||||
|
|
||||||
import com.alttd.altitudeweb.database.Databases;
|
import com.alttd.altitudeweb.database.Databases;
|
||||||
import com.alttd.altitudeweb.database.chat.ChatLogMapper;
|
import com.alttd.altitudeweb.database.chat.ChatLogMapper;
|
||||||
|
import com.alttd.altitudeweb.database.chat.NicknameMapper;
|
||||||
import com.alttd.altitudeweb.database.votingplugin.VotingPluginUsersMapper;
|
import com.alttd.altitudeweb.database.votingplugin.VotingPluginUsersMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
@ -12,6 +13,7 @@ public class InitializeChat {
|
||||||
log.info("Initializing Chat");
|
log.info("Initializing Chat");
|
||||||
Connection.getConnection(Databases.CHAT, (configuration) -> {
|
Connection.getConnection(Databases.CHAT, (configuration) -> {
|
||||||
configuration.addMapper(ChatLogMapper.class);
|
configuration.addMapper(ChatLogMapper.class);
|
||||||
|
configuration.addMapper(NicknameMapper.class);
|
||||||
}).join();
|
}).join();
|
||||||
log.debug("Initialized Chat");
|
log.debug("Initialized Chat");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,40 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
"202":
|
"202":
|
||||||
description: Accepted
|
description: Accepted
|
||||||
|
|
||||||
|
/chat/player/{uuid}/name:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- chat
|
||||||
|
summary: Gets the name, and nickname of the player associated with that uuid
|
||||||
|
operationId: getName
|
||||||
|
parameters:
|
||||||
|
- name: uuid
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The player's name and nickname
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/PlayerName"
|
||||||
|
"404":
|
||||||
|
description: Player not found
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
|
PlayerName:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
nickname:
|
||||||
|
type: string
|
||||||
User:
|
User:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user