Skip to content

RTUStudio/DonationAPI

Repository files navigation

DonationAPI

실시간 후원 플랫폼 통합 API for Minecraft.

Version Java Bukkit License


다운로드 프레임워크


목차


지원 플랫폼

플랫폼 구분 연동 방식 지원 기능
치지직 (CHZZK) 공식 OpenAPI OAuth + WebSocket 치즈(후원)
숲 (SOOP) 공식 OpenAPI OAuth + Binary WebSocket 별풍선
씨미 (CIME) 공식 OpenAPI OAuth + WebSocket 빔(후원)
SSAPI 통합 Socket.io 기반 통합 중계 치지직 + 숲 통합
투네이션 (Toonation) 비공식 페이로드 토큰 + WebSocket 일반 후원
유튜브 (YouTube) 비공식 라이브챗 폴링 슈퍼챗

요구사항

항목 최소 버전
Minecraft 1.20.1+ (Paper/Folia)
Java 21
RSFramework 4.7.17+

설치

  1. 최신 릴리즈에서 DonationAPI-1.6.1.jar를 다운로드합니다.
  2. 서버의 plugins/ 폴더에 JAR 파일을 배치합니다.
  3. 서버를 시작하면 기본 설정 파일이 자동 생성됩니다.
  4. plugins/DonationAPI/Config/Services/ 하위의 플랫폼별 설정 파일을 편집합니다.
  5. /후원API reload 또는 서버 재시작으로 설정을 적용합니다.

설정

플랫폼별 어플리케이션 생성

OAuth 기반 플랫폼(치지직, 숲, 씨미)을 사용하려면, 먼저 각 플랫폼의 개발자 사이트에서 어플리케이션을 생성하고 Client IDClient Secret을 발급받아야 합니다.

플랫폼 개발자 포털 비고
치지직 (CHZZK) https://developers.chzzk.naver.com/application 네이버 로그인 필요
숲 (SOOP) https://developers.sooplive.com/?szWork=myinfo SOOP 계정 필요
씨미 (CIME) https://developers.ci.me/applications 씨미 계정 필요

Redirect URI 설정: 어플리케이션 생성 시 Redirect URI(콜백 주소)를 설정해야 합니다. 설정 파일의 base-uri 값을 기준으로 자동 생성되며, 기본값은 http://localhost:3663 입니다. 외부 접속이 필요한 경우 포트포워딩 후 공인 IP 또는 도메인으로 변경하세요.

구성 파일 구조

플러그인을 처음 실행하면 아래와 같은 설정 파일이 자동 생성됩니다.

plugins/DonationAPI/Config/
├── Global.yml            # 전역 설정 (후원 알림 등)
└── Services/
    ├── CHZZK.yml          # 치지직 설정
    ├── SOOP.yml           # 숲 설정
    ├── CIME.yml           # 씨미 설정
    ├── SSAPI.yml          # SSAPI 설정
    ├── Toonation.yml      # 투네이션 설정
    └── YouTube.yml        # 유튜브 설정

치지직 (CHZZK) 설정

사전 준비: 치지직 개발자 포털에서 어플리케이션을 생성하고 Client IDClient Secret을 발급받으세요.

plugins/DonationAPI/Config/Services/CHZZK.yml:

# 서비스 활성화 여부
enabled: true
# 브랜드 색상 (HEX)
color: "#00FFA3"
# 클라이언트 ID (개발자 포털에서 발급)
client-id: "00000000-0000-0000-0000-000000000000"
# 클라이언트 시크릿 (개발자 포털에서 발급)
client-secret: "secret"
# OAuth 콜백을 받을 접속용 주소
base-uri: "http://localhost:3663"
# 내장 HTTP 서버 바인드 호스트
host: "0.0.0.0"
# 내장 HTTP 서버 바인드 포트
port: 3663
# 라이브 상태 확인 주기 (ms)
live-check-interval: 15000
# 소켓 옵션
socket:
  # 소켓 연결 타임아웃 (ms)
  timeout: 3000
  keepalive:
    # 서버-클라이언트 간 keepalive(ping) 사용 여부
    enabled: false
    # keepalive 주기 (ms)
    interval: 60000
  reconnection:
    # 자동 재연결 활성화 여부
    enabled: false
    # 재연결 최초 지연 (ms)
    delay: 1000
    # 재연결 최대 지연 (ms)
    max-delay: 3000

설정 방법:

  1. 개발자 포털에서 발급받은 값을 client-id, client-secret에 입력
  2. Redirect URI에 {base-uri}/auth/chzzk/callback 형태로 등록 (ex: http://localhost:3663/auth/chzzk/callback)
  3. 외부 접속 시 base-uri를 공인 IP/도메인으로 변경하고 port에 맞게 포트포워딩 설정
  4. 인게임에서 /후원API 치지직 연동 명령어로 OAuth 인증 진행

숲 (SOOP) 설정

사전 준비: 숲 개발자 포털에서 어플리케이션을 생성하고 Client IDClient Secret을 발급받으세요.

plugins/DonationAPI/Config/Services/SOOP.yml:

# 서비스 활성화 여부
enabled: true
# 브랜드 색상 (HEX)
color: "#0050FF"
# 클라이언트 ID (개발자 포털에서 발급)
client-id: "00000000000000000000000000000000"
# 클라이언트 시크릿 (개발자 포털에서 발급)
client-secret: "secret"
# OAuth 콜백을 받을 접속용 주소
base-uri: "http://localhost:3663"
# 내장 HTTP 서버 바인드 호스트
host: "0.0.0.0"
# 내장 HTTP 서버 바인드 포트
port: 3663
# 라이브 상태 확인 주기 (ms)
live-check-interval: 30000
# 소켓 옵션
socket:
  # 소켓 연결 타임아웃 (ms)
  timeout: 3000
  keepalive:
    # 서버-클라이언트 간 keepalive(ping) 사용 여부
    enabled: true
    # keepalive 주기 (ms)
    interval: 60000
  reconnection:
    # 자동 재연결 활성화 여부
    enabled: true
    # 재연결 최초 지연 (ms)
    delay: 1000
    # 재연결 최대 지연 (ms)
    max-delay: 30000

설정 방법:

  1. 개발자 포털에서 발급받은 값을 client-id, client-secret에 입력
  2. Redirect URI에 {base-uri}/auth/soop/callback 형태로 등록 (ex: http://localhost:3663/auth/soop/callback)
  3. 외부 접속 시 base-uri를 공인 IP/도메인으로 변경하고 port에 맞게 포트포워딩 설정
  4. 인게임에서 /후원API 숲 연동 명령어로 OAuth 인증 진행

씨미 (CIME) 설정

사전 준비: 씨미 개발자 포털에서 어플리케이션을 생성하고 Client IDClient Secret을 발급받으세요.

plugins/DonationAPI/Config/Services/CIME.yml:

# 서비스 활성화 여부
enabled: true
# 브랜드 색상 (HEX)
color: "#8A2BE2"
# 클라이언트 ID (개발자 포털에서 발급)
client-id: "00000000-0000-0000-0000-000000000000"
# 클라이언트 시크릿 (개발자 포털에서 발급)
client-secret: "secret"
# OAuth 콜백을 받을 접속용 주소
base-uri: "http://localhost:3663"
# 내장 HTTP 서버 바인드 호스트
host: "0.0.0.0"
# 내장 HTTP 서버 바인드 포트
port: 3663
# 라이브 상태 확인 주기 (ms)
live-check-interval: 30000
# 소켓 옵션
socket:
  # 소켓 연결 타임아웃 (ms)
  timeout: 3000
  keepalive:
    # 서버-클라이언트 간 keepalive(ping) 사용 여부
    # (씨미 API 10분 유휴 타임아웃 방지)
    enabled: true
    # keepalive 주기 (ms)
    interval: 60000
  reconnection:
    # 자동 재연결 활성화 여부
    enabled: true
    # 재연결 최초 지연 (ms)
    delay: 1000
    # 재연결 최대 지연 (ms)
    max-delay: 30000

설정 방법:

  1. 개발자 포털에서 발급받은 값을 client-id, client-secret에 입력
  2. Redirect URI에 {base-uri}/auth/cime/callback 형태로 등록 (ex: http://localhost:3663/auth/cime/callback)
  3. 외부 접속 시 base-uri를 공인 IP/도메인으로 변경하고 port에 맞게 포트포워딩 설정
  4. 인게임에서 /후원API 씨미 연동 명령어로 OAuth 인증 진행

참고: 씨미 WebSocket은 10분간 데이터가 없으면 유휴 타임아웃으로 연결이 끊길 수 있습니다.
keepalive.enabled: true를 유지하는 것을 강력히 권장합니다.


SSAPI 설정

SSAPI는 스트리머 지원 API 통합 중계 서비스로, 별도의 OAuth 과정 없이 API 키 하나로 치지직과 숲 후원을 동시에 수신할 수 있습니다.

plugins/DonationAPI/Config/Services/SSAPI.yml:

# 서비스 활성화 여부
enabled: true
# 브랜드 색상 (HEX)
color: "#FFFFFF"
# SSAPI API 키
api-key: ""
# 로그인 재시도 간격 (ms)
login-retry-delay: 1000
# 소켓 옵션
socket:
  # 소켓 연결 타임아웃 (ms)
  timeout: 3000
  keepalive:
    enabled: true
    interval: 60000
  reconnection:
    enabled: true
    delay: 1000
    max-delay: 3000

설정 방법:

  1. SSAPI 사이트에서 API 키를 발급받아 api-key에 입력
  2. 인게임에서 /후원API SSAPI(치지직) 연동 <ID> 또는 /후원API SSAPI(숲) 연동 <ID> 명령어로 연동

투네이션 (Toonation) 설정

투네이션은 비공식 연동으로, 알림 위젯 페이지에서 발급하는 페이로드 토큰을 사용합니다.

plugins/DonationAPI/Config/Services/Toonation.yml:

# 서비스 활성화 여부
enabled: true
# 브랜드 색상 (HEX)
color: "#00C7ED"
# 소켓 옵션
socket:
  # 소켓 연결 타임아웃 (ms)
  timeout: 3000
  keepalive:
    enabled: false
    interval: 60000
  reconnection:
    enabled: true
    delay: 1000
    max-delay: 30000

설정 방법:

  1. 투네이션 알림 위젯 페이지에서 페이로드 토큰을 복사
  2. 인게임에서 /후원API 투네이션 연동 <토큰> 명령어로 연동

토큰 획득 방법: 투네이션 대시보드 → 위젯 → 알림 위젯 → 임의 알림 위젯을 선택하고 주소(URL)의 payload 파라미터 값이 토큰입니다.


유튜브 (YouTube) 설정

유튜브는 비공식 연동으로, 별도의 인증 없이 채널 ID만으로 라이브 슈퍼챗을 수신합니다.

plugins/DonationAPI/Config/Services/YouTube.yml:

# 서비스 활성화 여부
enabled: true
# 브랜드 색상 (HEX)
color: "#FF0000"
# 유튜브 라이브챗 폴링 간격 (ms)
polling-interval-ms: 5000
# 라이브 상태 확인 주기 (ms)
live-check-interval: 60000

설정 방법:

  1. 유튜브 채널의 채널 ID를 확인 (채널 URL의 @handle 또는 UC... 형태의 ID)
  2. 인게임에서 /후원API 유튜브 연동 <채널ID> 명령어로 연동

참고: 유튜브 연동은 라이브 방송 중에만 슈퍼챗을 수신합니다. 폴링 방식이므로 실시간성이 다소 떨어질 수 있습니다.


전역 설정 (Global)

plugins/DonationAPI/Config/Global.yml:

# 후원 알림 설정 (서버 전체 브로드캐스트)
donation-notify: false

명령어

기본 명령어: /donationapi (별칭: /후원API)

플랫폼 연동

명령어 설명
/후원API 치지직 연동 치지직 OAuth 인증 링크 생성
/후원API 숲 연동 숲 OAuth 인증 링크 생성
/후원API 씨미 연동 씨미 OAuth 인증 링크 생성
/후원API 투네이션 연동 <토큰> 투네이션 위젯 토큰으로 연동
/후원API 유튜브 연동 <채널ID> 유튜브 채널 연동
/후원API SSAPI(치지직) 연동 <ID> SSAPI 치지직 통합 연동
/후원API SSAPI(숲) 연동 <ID> SSAPI 숲 통합 연동
/후원API [플랫폼] 연동해제 해당 플랫폼의 연결 해제

관리

명령어 설명
/후원API 이벤트 <닉네임> <금액> [메시지] 테스트용 후원 이벤트 발생
/후원API reload 설정 및 서비스 전체 재로드

모든 명령어는 OP 권한이 필요합니다.

PlaceholderAPI 연동

PlaceholderAPI가 설치되면 자동으로 Placeholder가 등록됩니다.

연결 상태

Placeholder 설명
%donationapi_chzzk% 치지직 연결 상태
%donationapi_soop% 숲 연결 상태
%donationapi_cime% 씨미 연결 상태
%donationapi_toonation% 투네이션 연결 상태
%donationapi_youtube% 유튜브 연결 상태
%donationapi_ssapi_chzzk% SSAPI 치지직 연결 상태
%donationapi_ssapi_soop% SSAPI 숲 연결 상태

참고: 연결 상태는 테스트 후원 또는 실제 후원이 최소 1회 이상 인식되어야 true로 표시됩니다.

라이브 상태

Placeholder 설명
%donationapi_live_[플랫폼]% 방송 중 여부 (true/false)
%donationapi_title_[플랫폼]% 방송 제목
%donationapi_viewers_[플랫폼]% 시청자 수
%donationapi_url_[플랫폼]% 방송 채널 URL

[플랫폼]에는 chzzk, soop, cime, youtube를 사용할 수 있습니다.


개발자 가이드

DonationEvent 수신

모든 플랫폼의 후원은 Bukkit의 DonationEvent로 통합됩니다.

import kr.rtustudio.donation.bukkit.event.DonationEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class DonationListener implements Listener {

    @EventHandler
    public void onDonation(DonationEvent event) {
        String nickname = event.getNickname();
        int amount      = event.getAmount();     // 플랫폼 단위 수량
        int price       = event.getPrice();      // 원 환산 금액
        String unit     = event.getUnit();       // 단위명 (치즈, 개 등)
        String message  = event.getMessage();

        if (event.getPlayer() != null) {
            event.getPlayer().sendMessage(
                String.format("§e%s§f님이 §d%,d§f%s를 후원! §7%s",
                              nickname, amount, unit, message)
            );
        }
    }
}

DonationEvent 메서드:

메서드 반환 타입 설명
getPlayer() @Nullable Player 후원 대상 플레이어
getDonation() Donation 통합 후원 데이터
getService() Services 서비스 유형 (CHZZK, SOOP 등)
getPlatform() Platform 실제 플랫폼
getNickname() String 후원자 닉네임
getAmount() int 후원 수량 (플랫폼 단위)
getPrice() int 원 환산 금액
getUnit() String 단위명
getMessage() String 후원 메시지
isCancelled() boolean 이벤트 취소 여부

Donation 객체

Donation은 불변 record로 정의됩니다.

public record Donation(
    @Nullable UUID uniqueId,     // 후원 대상 플레이어 UUID
    Services service,            // 서비스 유형
    Platform platform,           // 실제 플랫폼
    DonationType type,           // CHAT 또는 VIDEO
    String streamer,             // 스트리머 식별자
    String donator,              // 후원자 식별자
    String nickname,             // 후원자 닉네임 (기본: "익명의 후원자")
    String message,              // 후원 메시지
    int amount                   // 후원 수량
) {
    public String unit()  { return platform.unit(); }
    public int    price() { return amount * platform.rate(); }
}

플랫폼별 단위 및 환산:

플랫폼 단위 환산(rate) 예시
치지직 치즈 ×1 1,000치즈 → 1,000원
×100 5개 → 500원
씨미 ×1 1,000빔 → 1,000원
투네이션 캐시 ×1 5,000캐시 → 5,000원
유튜브 ×1 1,000원 → 1,000원

Services vs Platform:

Services는 연동 서비스를 나타내고, Platform은 후원이 발생한 실제 플랫폼을 나타냅니다. 예를 들어 SSAPI 서비스는 치지직과 숲 두 플랫폼을 모두 지원합니다.

Services 지원 Platform
CHZZK CHZZK
SOOP SOOP
CIME CIME
SSAPI CHZZK, SOOP
Toonation TOONATION
YOUTUBE YOUTUBE

라이브 상태 확인

LiveStatusManager를 통해 연결된 스트리머의 방송 상태를 조회할 수 있습니다.

LiveStatusManager manager = BukkitDonationAPI.getInstance().getLiveStatusManager();
LiveStatus status = manager.getLiveStatus(Services.CHZZK, player.getUniqueId());

if (status != null && status.live()) {
    player.sendMessage(
        String.format("방송 중: %s (시청자 %,d명)", status.title(), status.viewerCount())
    );
}

LiveStatus 필드:

필드 타입 설명
live() boolean 방송 중 여부
title() @Nullable String 방송 제목
viewerCount() int 시청자 수
channelUrl() String 채널 URL
updatedAt() long 캐시 갱신 시각 (epoch ms)

라이브 상태는 플랫폼별 설정의 liveCheckInterval에 지정된 주기로 자동 폴링됩니다.

Skript 애드온 연동

DonationAPI는 자체적으로 Skript 연동을 지원하므로, 애드온 없이 플러그인 환경에서 직접 스크립트로 후원 이벤트를 감지할 수 있습니다.

이벤트 구문:

on donation:
    if player is set:
        send "&e&l[후원] &f%donation nickname%님이 &d%donation amount%%donation unit%&f를 후원했습니다!" to player
    broadcast "&7메시지: %donation message%"
    broadcast "&7플랫폼: %donation platform%"

지원 수식어(Expression):

구문 반환 타입 설명
event-player 또는 player Player 이벤트를 연동한 대상 플레이어
donation message String 후원 메시지
donation amount Number 후원 수량 (플랫폼 기준 단위)
donation price Number 원(KRW) 환산 금액
donation unit String 단위명 (치즈, 개, 캐시 등)
donation nickname String 후원자 닉네임
donation donator String 후원자 고유 식별자
donation streamer String 후원 대상 스트리머 / 방송국
donation platform String 결제 플랫폼 (CHZZK, SOOP 등)

아키텍처

모듈 구조

DonationAPI/
├── Services/                    # 프레임워크 독립 코어 서비스 (순수 Java)
│   ├── Common/                  # 통합 모델 (Donation, Platform, AsyncExecutor)
│   ├── CHZZK/                   # 치지직 — OpenAPI + WebSocket
│   ├── SOOP/                    # 숲 — OpenAPI + Binary WebSocket
│   ├── CIME/                    # 씨미 — OpenAPI + WebSocket
│   ├── SSAPI/                   # SSAPI — Socket.io 통합 중계
│   ├── Toonation/               # 투네이션 — WebSocket
│   └── YouTube/                 # 유튜브 — 라이브챗 폴링
│
└── Platform/                    # 프레임워크 종속 어댑터
    ├── Common/                  # 플랫폼 공통 API (DonationAPI 레지스트리)
    └── Bukkit/                  # Bukkit 통합 계층
        ├── command/             #   명령어 처리
        ├── configuration/       #   GlobalConfig + 플랫폼별 Config
        ├── event/               #   DonationEvent
        ├── handler/             #   PlayerJoinQuit 리스너
        ├── integration/         #   PlaceholderAPI 연동
        ├── manager/             #   DonationManager, LiveStatusManager
        └── platform/            #   ServiceBuilder, PlatformRegistry

핵심 계층

  • BukkitDonationAPI — RSPlugin 메인 클래스. 서비스 생명주기와 설정 관리를 담당합니다.
  • PlatformRegistryDonationPlatform 인스턴스를 관리하며 플레이어 연결/해제 상태를 추적합니다.
  • DonationAPIService 인스턴스 레지스트리. 등록된 서비스의 시작/종료를 관리합니다.
  • ServiceBuilder — 서비스 생성, 핸들러 연결, 플랫폼 등록을 선언적으로 처리하는 빌더입니다.
  • ServiceHandler<R> — 후원(donation), 성공(success), 실패(failure), 알림(messenger) 콜백을 묶는 record입니다.
  • AsyncExecutor — Java 21 Virtual Thread 기반 공유 Executor. 모든 I/O 비동기 작업에 사용됩니다.

ServiceBuilder 패턴

새 후원 플랫폼을 추가할 때 ServiceBuilder로 서비스 등록을 선언적으로 처리합니다.

register(ServiceBuilder.builder()
    .config(ChzzkConfig.class)          // 설정 클래스
    .data(ChzzkPlayer.class)            // 플레이어 데이터 타입
    .factory(ChzzkService::new)         // 서비스 팩토리
    .reconnect((service, data) ->       // 재연결 콜백 (선택)
        service.reconnect(data.uuid(), data))
    .build(this)
);

빌더 흐름:

  1. builder() → 공통 빌더 생성
  2. .config(Class) → 설정 클래스 바인딩
  3. .data(Class) → 데이터 타입 바인딩 → TypedBuilder 전환
  4. .factory(ServiceFactory) → 서비스 팩토리 설정
  5. .reconnect(ReconnectFunction) → 재연결 로직 설정 (선택)
  6. .build(plugin)ServiceBuilder<D, S> 완성

빌드

# 빌드 (테스트 포함)
./gradlew build

# 빌드 (테스트 제외)
./gradlew build -x test

빌드 결과물: build/libs/DonationAPI-1.6.1.jar

라이선스

이 프로젝트는 GNU General Public License v3.0 하에 배포됩니다.


Made with ❤️ by RTU Studio

About

치지직, 숲, 씨미, 투네이션, 유튜브 등 6개 후원 플랫폼을 하나의 통합 API로 관리하는 Bukkit/Paper 플러그인입니다.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages