public class MongoDB {
// MongoDB 클라이언트 인스턴스
private static MongoClient db;
// MongoDatabase 참조
@Getter
private static MongoDatabase RPGSharp;
// 설정 파일에서 사용할 키 이름들
private static final String HOST_CONFIG_NAME = "database.host";
private static final String PORT_CONFIG_NAME = "database.port";
private static final String DATABASE_CONFIG_NAME = "database.database";
// MongoDB URI 형식 문자열
private static final String MONGODB_URI_FORMAT = "mongodb://%s:%d";
// 설정 파일 이름
private static final String CONFIG_FILE_NAME = "config.yml";
/**
* config.yml 파일에서 설정을 읽어와 MongoDB 데이터베이스에 연결합니다.
* 설정 파일이 존재하지 않으면 기본 값으로 설정 파일을 생성합니다.
*/
public static void connect() {
// 플러그인의 데이터 폴더에서 설정 파일을 가져옵니다.
File configFile = new File(RankingPlugin_Bungee.getInstance().getDataFolder(), CONFIG_FILE_NAME);
// 설정 파일이 존재하지 않으면 기본 설정 파일을 생성합니다.
if (!configFile.exists()) {
createDefaultConfig(configFile, RankingPlugin_Bungee.getInstance());
}
Configuration config;
try {
// 파일에서 설정을 로드합니다.
config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
} catch (IOException e) {
// 설정 로드 실패 시 오류 메시지를 출력합니다.
ErrorView.MONGODB_LOAD_FAILED.print(e.getMessage());
return;
}
// 설정에서 호스트, 포트, 데이터베이스 이름을 가져옵니다.
String host = config.getString(HOST_CONFIG_NAME);
int port = config.getInt(PORT_CONFIG_NAME);
String database = config.getString(DATABASE_CONFIG_NAME);
// MongoDB 클라이언트를 생성하고 데이터베이스에 연결합니다.
db = MongoClients.create(String.format(MONGODB_URI_FORMAT, host, port));
RPGSharp = db.getDatabase(database);
// MongoDB 연결 성공 로그를 출력합니다.
OutView.MONGODB_CONNECTED.log();
}
.... disconnect, createDefaultConfig 메소드 등등
}
public class LevelRanking {
// 레벨 랭킹 배열 및 변경 사항 배열
@Getter
private static List<LevelRankDTO> levelRankingArr;
@Getter
private static List<RankDiff> levelRankingDiffArr;
@Getter
private static String lastModifiedAt;
// 레벨 정렬 기준 (레벨 내림차순, 경험치 내림차순)
@Getter
private static final Document LEVEL_SORT_CRITERIA = new Document("level", -1).append("exp", -1);
/**
* 레벨 랭킹 배열을 업데이트합니다.
* MongoDB에서 데이터를 가져와 정렬 후 배열에 저장합니다.
*
* @param readCount 읽어올 문서 수
*/
private static void updateLevelRankingArr(int readCount) {
MongoDB.connect();
levelRankingArr = new ArrayList<>();
// MongoDB에서 RPGPlayer 컬렉션의 문서를 조회하고 정렬하여 가져오는 커서를 생성합니다.
MongoCursor<Document> cursor = MongoDB.getRPGSharp().getCollection("RPGPlayer").find()
// projection: 가져올 필드를 지정합니다. nickname, level, exp 필드만 결과에 포함됩니다.
.projection(new Document("nickname", 1).append("level", 1).append("exp", 1))
// sort: 결과를 level 필드를 기준으로 내림차순(-1), 그 다음 exp 필드를 기준으로 내림차순(-1)으로 정렬합니다.
.sort(LEVEL_SORT_CRITERIA)
// limit: 결과의 최대 개수를 readCount로 제한합니다.
.limit(readCount)
// iterator: 위의 조건으로 MongoDB 쿼리를 실행하고 결과를 순회(iterate)할 수 있는 커서를 반환합니다.
.iterator();
int i = 1;
while (cursor.hasNext()) {
Document document = cursor.next();
String nickname = document.getString("nickname");
int level = document.getInteger("level");
double exp = document.getDouble("exp");
if (i > 1) {
// level, exp 둘다 같은 경우 공동 순위로 처리
if (levelRankingArr.get(levelRankingArr.size() - 1).getLevel() == level
&& levelRankingArr.get(levelRankingArr.size() - 1).getExp() == exp) {
levelRankingArr.add(new LevelRankDTO(i - 1, nickname, level, exp));
i++;
continue;
}
}
levelRankingArr.add(new LevelRankDTO(i++, nickname, level, exp));
}
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
lastModifiedAt = sdf.format(new Date());
MongoDB.disconnect();
}
....
}
public class Broadcast {
public static final String BUNGEE_CHANNEL = "BungeeCord";
public static final String RANKING_CHANNEL = "Ranking";
public static void send(String channel, String message) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Forward");
out.writeUTF("ALL");
out.writeUTF(channel);
out.writeUTF(message);
for (ServerInfo server : ProxyServer.getInstance().getServers().values()) {
server.sendData(BUNGEE_CHANNEL, out.toByteArray());
}
}
}
"Forward", "ALL" 옵션을 써줘야 번지 서버에서 모든 버킷 서버로 메세지가 날아갑니다.