asta-PastaClient icon

PastaClient

Shitter추가, 나간사람 조회 등등

Last updated 2 weeks ago
Total downloads 86
Total rating 0 
Categories Tweaks & Quality Of Life
Dependency string asta-PastaClient-0.0.4
Dependants 0 other packages depend on this package

This mod requires the following mods to function

BepInEx-BepInExPack-5.4.2100 icon
BepInEx-BepInExPack

BepInEx pack for Mono Unity games. Preconfigured and ready to use.

Preferred version: 5.4.2100
AinaVT-LethalConfig-1.4.6 icon
AinaVT-LethalConfig

Provides an in-game config menu for players to edit their configs, and an API for other mods to use and customize their entries.

Preferred version: 1.4.6

README

Pasta Client 개발 문서

이 문서는 Lethal Company용 모드 Pasta Client의 현재 개발 진행 상황, 내부 구조, 각 기능의 처리 방식, 디자인 패턴, 코드 스타일 가이드 등을 정리해 다른 개발자가 프로젝트를 이어받아도 무리 없이 진행할 수 있도록 작성되었습니다.


🚀 빠른 시작 (사용자용)

설치 방법

  1. Thunderstore에서 Pasta Client 모드 다운로드
  2. BepInEx 폴더에 설치
  3. 게임 실행

사용 방법

명령어

  • :st - Shitter 추가/확인 UI 열기
  • :who - 최근 나간 플레이어 목록 확인

주요 기능

  1. Shitter 추가

    • :st 명령어 입력
    • 현재 방 플레이어 또는 최근 나간 플레이어 선택
    • 이유 입력 (최대 500자)
    • "추가 요청" 버튼 클릭
    • 서버로 투표가 전송됨
  2. 최근 나간 플레이어 확인

    • :who 명령어 입력
    • 최근 나간 플레이어 목록 확인
    • Steam 프로필 열기 가능
  3. 킥당했을 때

    • 킥당하면 자동으로 킥 UI 표시
    • 킥당한 시점의 방 플레이어 목록 확인 가능
    • Steam 프로필 열기 가능

서버 설정

서버를 사용하려면:

  1. server.py 실행:

    python server.py
    
  2. 설정에서 서버 URL 변경 (기본값: https://shitter.asta.rs):

    • 게임 내 Config 메뉴 또는
    • BepInEx/config/dev523.pasta.client.cfg 파일 수정

📌 1. 현재 진행 상황

✅ 구현 완료

  • ✅ 기본 프로젝트 구조 (BepInEx Plugin + Harmony Patch + LethalConfig 연동)
  • ✅ 설정(Enable/Disable) 및 Config 시스템 구현
  • ✅ Shitter 데이터 구조 및 저장 시스템
  • ✅ UI Framework IMGUI 기반 구현
  • ✅ 명령어 시스템(:st, :who) 구현
  • ✅ 네트워크 RPC 시스템 (Unity Netcode)
  • Steam ID 기반 플레이어 추적 시스템
  • 서버 통신 (HTTP 요청)
  • 플레이어 이름 가져오기 (Steam API + 게임 내 이름)
  • 최근 나간 플레이어 추적 시스템
  • 킥 UI 및 킥 감지 시스템
  • 자동 킥 기능 (투표 수 기준)
  • Steam 프로필 열기 기능
  • 플레이어 목록 수집 및 표시
  • 기본 이름 필터링 ("Player #1" 등)
  • 텍스트 입력 중 인게임 입력 차단
  • UI 투명 버그 수정

🚧 구현 중 / 개선 필요

  • Shitter DB 파일 저장 기능 (현재 메모리 기반)
  • 서버와의 동기화 개선
  • UI 성능 최적화

❗ 향후 작업

  • UI uGUI/UIToolkit 전환 (IMGUI 유지보수 어려움)
  • 에러 핸들링 및 로깅 체계 확립
  • 서버 보안 강화

📁 2. 폴더/파일 구조

PastaClient/
│
├── Plugin.cs                 # 메인 엔트리포인트
├── ConfigManager.cs          # 설정 관리 (BepInEx Config)
├── PastaClient.csproj        # 프로젝트 파일
│
├── Network/
│   └── PastaNetwork.cs       # Unity Netcode 네트워크 처리
│                              # - 플레이어 입장/퇴장 감지
│                              # - RPC (ServerRpc, ClientRpc)
│                              # - 플레이어 목록 전송
│
├── Systems/
│   ├── ShitterDatabase.cs    # Shitter 데이터 저장소
│   ├── RecentLeaveTracker.cs # 최근 나간 플레이어 추적
│   └── KickTracker.cs        # 킥당했을 때 플레이어 목록 저장
│
├── Utils/
│   ├── ServerClient.cs       # 외부 서버와 HTTP 통신
│   ├── SteamIDHelper.cs      # Unity Netcode clientId → Steam ID 변환
│   ├── SteamNameFetcher.cs   # Steam 프로필에서 이름 가져오기
│   ├── UIHelper.cs           # IMGUI 관리 및 커서 제어
│   ├── UIStyle.cs            # UI 스타일 정의
│   ├── ShitterUI.cs          # Shitter 추가/확인 UI
│   ├── RecentUI.cs           # 최근 나간 플레이어 UI
│   └── KickUI.cs             # 킥 UI
│
├── Patches/
│   ├── ChatPatch.cs          # 채팅 명령어 처리
│   └── PlayerPatches.cs      # 플레이어 입력 패치 (UI 열려있을 때 입력 차단)
│
└── server.py                 # Python Flask 서버 (Shitter 투표 저장)

🧩 3. 내부 설계 개요

(1) 전체 플로우 요약

명령어 입력 (:st, :who)
    ↓
UI 표시 (ShitterUI, RecentUI, KickUI)
    ↓
플레이어 선택 + 이유 입력
    ↓
서버로 HTTP 요청 전송 (ServerClient)
    ↓
로컬 DB 업데이트 (ShitterDatabase)
    ↓
Unity Netcode RPC로 동기화 (PastaNetwork)
    ↓
자동 킥 판단 (투표 수 ≥ 임계값)

(2) 플레이어 입장/퇴장 감지 플로우

플레이어 입장/퇴장 감지 (PastaNetwork)
    ↓
Steam ID 변환 (SteamIDHelper)
    ↓
플레이어 이름 캐싱 (SteamNameFetcher)
    ↓
RecentLeaveTracker에 추가 (퇴장 시)
    ↓
서버에 플레이어 목록 전송 (클라이언트 접속 시)

🗂 4. 주요 시스템 설명

4.1 Shitter Database

  • 목적: 문제 플레이어(Shitter)의 투표 기록 저장
  • 구조: Dictionary<ulong, ShitterInfo>
    • Key: Steam ID
    • Value: ShitterInfo (Steam ID + 투표자 목록 및 이유)

ShitterInfo 구조:

public class ShitterInfo
{
    public ulong SteamId;
    public Dictionary<ulong, string> Reasons; // 투표자 Steam ID → 이유
}

저장 방식:

  • 로컬: 메모리 기반 Dictionary
  • 서버: HTTP POST 요청으로 외부 서버에 저장
  • 동기화: Unity Netcode RPC로 게임 내 클라이언트 간 동기화

4.2 Recent Leave Tracker

  • 목적: 최근 나간 플레이어 목록 관리
  • 최대 저장 개수: 5명
  • 기능:
    • 플레이어 퇴장 시 자동 추가
    • 플레이어 이름 비동기 로딩 (Steam API)
    • 이름 캐싱

RecentPlayerInfo 구조:

public class RecentPlayerInfo
{
    public ulong ClientId;      // Steam ID
    public string PlayerName;   // 플레이어 이름
    public bool IsNameLoading;  // 이름 로딩 중 여부
}

4.3 Kick Tracker

  • 목적: 킥당했을 때 방에 있던 플레이어 목록 저장
  • 사용: 킥 UI에서 킥한 사람 확인용
  • 저장 시점:
    • 플레이어 퇴장 시 (현재 플레이어 목록 스냅샷)
    • 클라이언트 접속 시 (서버에서 플레이어 목록 수신)

4.4 Steam ID Helper

  • 목적: Unity Netcode의 clientId를 실제 Steam ID로 변환
  • 변환 방법:
    1. 캐시 확인
    2. PlayerControllerB에서 Reflection으로 Steam ID 필드 찾기
    3. NetworkObject.OwnerClientId 확인
    4. clientId가 Steam ID 형식인지 확인 (7656119로 시작)
    5. 실패 시 clientId 반환 (fallback)

4.5 Steam Name Fetcher

  • 목적: Steam ID로부터 플레이어 이름 가져오기
  • 우선순위:
    1. 게임 내 이름 (PlayerControllerB.playerUsername, name 필드)
    2. 캐시된 이름
    3. Steam 프로필 HTML 파싱 (비동기)
  • 캐싱: 가져온 이름은 메모리에 캐시

4.6 Server Client

  • 목적: 외부 서버와 HTTP 통신
  • 기능:
    • POST /api/shitter/vote - Shitter 투표 전송
    • GET /api/shitter/info/<target_id> - Shitter 정보 조회
    • GET /api/shitter/list - 모든 Shitter 목록
  • 구현: Unity UnityWebRequest 사용

4.7 Commands

:st

  • 기능: Shitter 추가/확인 UI 열기
  • 표시 내용:
    • 현재 방 플레이어 목록
    • 최근 나간 플레이어 목록
    • 이유 입력 필드
    • 추가 요청 버튼

:who

  • 기능: 최근 나간 플레이어 목록 UI 열기
  • 표시 내용:
    • 최근 나간 플레이어 목록 (최대 5명)
    • 각 플레이어의 Steam 프로필 열기 버튼

4.8 자동 킥 시스템

  • 조건:
    1. 플레이어 입장 감지
    2. ShitterDatabase에 해당 플레이어 존재
    3. 투표 수 ≥ ConfigManager.VoteKickThreshold (기본값: 2)
    4. ConfigManager.EnableAutoKick = true
  • 동작: 호스트가 NetworkManager.Singleton.DisconnectClient() 호출

4.9 킥 UI

  • 트리거: 로컬 클라이언트가 킥당했을 때 자동 표시
  • 표시 내용:
    • 킥당한 시점의 방 플레이어 목록
    • 각 플레이어의 Steam 프로필 열기 버튼
  • 목적: 킥한 사람 확인

🎨 5. 디자인 패턴

✔ Singleton Pattern

  • PastaNetwork.Instance - NetworkBehaviour 싱글톤
  • UIHelper.Instance - UI 관리 싱글톤 (MonoBehaviour)

✔ Observer Pattern

  • 플레이어 입장/퇴장 이벤트 구독 (NetworkManager.OnClientConnectedCallback, OnClientDisconnectCallback)
  • 백업 폴링 방식 (MonitorPlayerChanges 코루틴)

✔ Factory Pattern

  • SteamNameFetcher - 이름 가져오기 전략 패턴 (게임 → 캐시 → Steam API)

✔ MVC-like 구조

  • Model: ShitterDatabase, RecentLeaveTracker, KickTracker
  • View: ShitterUI, RecentUI, KickUI
  • Controller: PastaNetwork, ChatPatch

🛠 6. 코딩 컨벤션

네이밍 규칙

  • 클래스: PascalCase
  • 메서드: PascalCase
  • 변수: camelCase
  • 상수: ALL_CAPS
  • private 필드: _camelCase

파일 규칙

  • 기능별 폴더 분리 (Network/, Systems/, Utils/, Patches/)
  • 한 파일에는 한 클래스 원칙
  • UI는 Utils/ 폴더에 위치

주석 규칙

  • 메서드 상단에 XML 문서 주석 (/// <summary>)
  • 중요한 로직은 인라인 주석
  • 한글 주석 허용

🔧 7. 네트워크 통신 구조

Unity Netcode RPC

ServerRpc

  • AddShitterServerRpc(ulong targetId, string reason, ulong senderId)
    • 클라이언트 → 서버: Shitter 투표 요청
    • 서버에서 ShitterDatabase 업데이트
    • 모든 클라이언트에 UpdateShitterClientsClientRpc 브로드캐스트

ClientRpc

  • UpdateShitterClientsClientRpc(ulong id)

    • 서버 → 클라이언트: Shitter DB 업데이트 알림
    • UI 갱신
  • SendPlayerListClientRpc(ulong[] playerIds)

    • 서버 → 특정 클라이언트: 방 플레이어 목록 전송
    • 클라이언트 접속 시 한 번 전송

HTTP 서버 통신

엔드포인트

  • POST /api/shitter/vote - Shitter 투표 추가

    {
      "targetId": "76561198000000000",
      "senderId": "76561198000000001",
      "reason": "팀킬",
      "timestamp": 1234567890
    }
    
  • GET /api/shitter/info/<target_id> - Shitter 정보 조회

  • GET /api/shitter/list - 모든 Shitter 목록

  • GET /health - 서버 상태 확인


🖥 8. UI 구조

UI 시스템

  • 프레임워크: Unity IMGUI
  • 관리: UIHelper - UI 등록/해제 및 커서 제어
  • 스타일: UIStyle - 통일된 UI 스타일 정의

UI 윈도우

  1. ShitterUI (Window ID: 987654)

    • 현재 방 플레이어 목록
    • 최근 나간 플레이어 목록
    • 이유 입력 필드
    • 추가 요청 버튼
  2. RecentUI (Window ID: 987655)

    • 최근 나간 플레이어 목록
    • Steam 프로필 열기 버튼
  3. KickUI (Window ID: 987656)

    • 킥당한 시점의 방 플레이어 목록
    • Steam 프로필 열기 버튼

커서 관리

  • UI가 열려있을 때: Cursor.visible = true, Cursor.lockState = CursorLockMode.None
  • UI가 닫혔을 때: 게임이 커서 상태 관리 (강제 변경하지 않음)

입력 차단

  • UI가 열려있을 때: 마우스 입력 (Mouse X, Mouse Y) 차단
  • 텍스트 입력 필드 포커스 시: 모든 입력 차단 (ESC 제외)

🔐 9. 보안 고려사항

클라이언트/서버 구분

  • Shitter DB 변경: 서버에서만 가능 (ServerRpc)
  • ConnectedClients 접근: 서버에서만 가능 (클라이언트 접근 시 예외 처리)
  • 플레이어 정보 수집: 클라이언트는 PlayerControllerB 직접 탐색

데이터 검증

  • 자기 자신에게 투표 불가 (targetId == senderId 체크)
  • Steam ID 형식 검증 (7656119로 시작하는 큰 숫자)
  • 기본 이름 필터링 ("Player #1" 등 제외)

🐛 10. 알려진 이슈 및 해결 방법

이슈 1: 플레이어 목록이 표시되지 않음

  • 원인: 클라이언트에서 ConnectedClients 접근 시도
  • 해결: PlayerControllerB 직접 탐색 + KickTracker 병합

이슈 2: UI가 투명해짐

  • 원인: 텍스처가 매 프레임 재생성
  • 해결: 텍스처 캐싱 시스템 구현

이슈 3: 접속 전 플레이어가 표시되지 않음

  • 원인: 초기 플레이어 수집 타이밍 문제
  • 해결: 여러 번 시도하는 초기 수집 로직 + 서버에서 플레이어 목록 전송

🔮 11. 향후 개선 방향

단기

  • [ ] Shitter DB 파일 저장 (JSON)
  • [ ] 서버 데이터와 로컬 DB 동기화
  • [ ] UI 성능 최적화

중기

  • [ ] UI uGUI/UIToolkit 전환
  • [ ] 에러 핸들링 및 로깅 체계 확립
  • [ ] 서버 보안 강화 (인증 등)

장기

  • [ ] 웹 대시보드 (Shitter 목록 조회)
  • [ ] 모드 간 호환성 검사 시스템
  • [ ] 통계 시스템 (가장 많은 투표 받은 플레이어 등)

📞 12. 개발자 정보

주요 클래스 의존성

Plugin
  ├── ConfigManager
  ├── PastaNetwork (NetworkBehaviour)
  │     ├── ServerClient
  │     ├── SteamNameFetcher
  │     ├── ShitterDatabase
  │     ├── RecentLeaveTracker
  │     └── KickTracker
  ├── ChatPatch (Harmony)
  │     └── ShitterUI, RecentUI
  └── PlayerPatches (Harmony)
        └── UIHelper

핵심 컴포넌트

  • PastaNetwork: 네트워크 이벤트 처리 및 RPC 관리
  • SteamIDHelper: clientId ↔ Steam ID 변환
  • SteamNameFetcher: 플레이어 이름 가져오기 (비동기)
  • ServerClient: 외부 서버 통신
  • UIHelper: UI 관리 및 커서 제어

📚 13. 사용 예시

Shitter 추가하기

// 클라이언트에서 호출
PastaNetwork.RequestAddShitter(steamId, "팀킬");

// 내부 처리:
// 1. ServerClient.SendShitterVote() - HTTP 서버에 요청
// 2. ShitterDatabase.AddVote() - 로컬 DB 업데이트
// 3. AddShitterServerRpc() - Unity Netcode 동기화 (서버인 경우)

플레이어 이름 가져오기

// 비동기로 이름 가져오기
SteamNameFetcher.FetchPlayerNameFromGameOrSteam(steamId, (sid, name) =>
{
    Debug.Log($"플레이어 {sid}의 이름: {name}");
});

// 캐시에서 이름 가져오기 (동기)
string cachedName = SteamNameFetcher.GetCachedName(steamId);

Steam ID 변환

// Unity Netcode clientId를 Steam ID로 변환
ulong steamId = SteamIDHelper.GetSteamID(clientId);

// 역변환 (필요시)
ulong clientId = SteamIDHelper.GetClientID(steamId);

🛡 14. 서버 설정 및 실행

서버 실행

# Python Flask 서버 실행
python server.py

# 서버는 기본적으로 http://localhost:8000 에서 실행됩니다

서버 API 문서

POST /api/shitter/vote

Shitter 투표 추가

Request:

{
  "targetId": "76561198000000000",
  "senderId": "76561198000000001",
  "reason": "팀킬",
  "timestamp": 1234567890
}

Response:

{
  "success": true,
  "message": "Vote added successfully",
  "data": {
    "targetId": "76561198000000000",
    "voteCount": 3
  }
}

GET /api/shitter/info/<target_id>

Shitter 정보 조회

Response:

{
  "success": true,
  "data": {
    "steamId": "76561198000000000",
    "voteCount": 3,
    "votes": {
      "76561198000000001": {
        "reason": "팀킬",
        "timestamp": 1234567890
      }
    }
  }
}

📝 15. 변경 이력

최근 업데이트

  • ✅ Steam ID 기반 플레이어 추적 시스템 구현
  • ✅ 서버 통신 (HTTP) 구현
  • ✅ 플레이어 이름 가져오기 (Steam API) 구현
  • ✅ 킥 UI 및 킥 감지 시스템 구현
  • ✅ 접속 전 플레이어 목록 수집 개선
  • ✅ 기본 이름 필터링 ("Player #1" 등) 구현
  • ✅ 텍스트 입력 중 인게임 입력 차단
  • ✅ UI 투명 버그 수정

gpt한태 써달라했는데 개잘써주네 ㄹㅇ