182 lines
7.5 KiB
Markdown
182 lines
7.5 KiB
Markdown
# Genesis_GameServer
|
|
|
|
유니티 게임(Genesis) 서버 + 개인 포트폴리오 사이트.
|
|
|
|
하나의 ASP.NET Core 프로세스가 두 가지를 함께 서빙합니다.
|
|
|
|
| 경로 | 내용 |
|
|
|---|---|
|
|
| `/myGame/*` | 유니티 게임 클라이언트가 쓰는 기존 API (변경 없음) |
|
|
| `/api/portfolio/*` | 포트폴리오 REST API |
|
|
| `/` 그 밖의 모든 경로 | 포트폴리오 웹사이트 (정적 SPA) |
|
|
|
|
---
|
|
|
|
## 1. 처음 실행하기
|
|
|
|
### 관리자 비밀번호부터 바꾸세요
|
|
|
|
`GameServer/appsettings.json` 의 `Portfolio.AdminPassword` 가 `CHANGE_ME` 로 되어 있으면
|
|
**로그인 자체가 막혀 있습니다**(503). 원하는 비밀번호로 바꾸고 서버를 다시 시작하세요.
|
|
|
|
```json
|
|
"Portfolio": {
|
|
"AdminPassword": "여기에-원하는-비밀번호",
|
|
"SiteTitle": "사이트 이름",
|
|
"SiteTagline": "한 줄 소개",
|
|
"MaxUploadBytes": 10485760
|
|
}
|
|
```
|
|
|
|
> `SiteTitle` · `SiteTagline` 은 지금 어느 코드도 읽지 않습니다.
|
|
> 화면에 나오는 이름과 문구는 `GameServer/wwwroot/index.html` 에 직접 들어 있습니다.
|
|
|
|
파일에 비밀번호를 두고 싶지 않다면 환경변수가 우선합니다.
|
|
|
|
```bash
|
|
# Windows (PowerShell)
|
|
$env:Portfolio__AdminPassword = "비밀번호"
|
|
# Linux / macOS
|
|
export Portfolio__AdminPassword="비밀번호"
|
|
```
|
|
|
|
### 실행
|
|
|
|
```bash
|
|
dotnet run --project GameServer/GameServer.csproj
|
|
```
|
|
|
|
브라우저에서 `http://localhost:5281` 을 열면 포트폴리오가 뜹니다.
|
|
우측 상단 **관리자** 버튼 → 비밀번호 입력 → 글을 쓸 수 있습니다.
|
|
|
|
> 이 프로젝트는 `net9.0` 을 대상으로 합니다. .NET 9 런타임이 없고 상위 버전만 있다면
|
|
> `DOTNET_ROLL_FORWARD=LatestMajor` 를 주고 실행하거나, .NET 9 런타임을 설치하세요.
|
|
|
|
---
|
|
|
|
## 2. 데이터베이스
|
|
|
|
포트폴리오 테이블은 **서버가 시작할 때 자동으로 만들어집니다**
|
|
(`Data/PortfolioSchemaInitializer.cs`, `CREATE TABLE IF NOT EXISTS`).
|
|
따로 마이그레이션을 돌릴 필요가 없습니다.
|
|
|
|
- `tb_portfolio_category` — 카테고리 (처음 한 번 `게임 / 개발 / 아트 / 기록` 4개가 시드됩니다)
|
|
- `tb_portfolio_post` — 게시물
|
|
- `tb_portfolio_post_image` — 게시물 이미지
|
|
|
|
수동으로 만들고 싶다면 `GameServer/sql/portfolio_schema.sql` 을 쓰세요.
|
|
DB 연결이 실패해도 **게임 서버 부팅은 막지 않습니다**(로그만 남기고 넘어갑니다).
|
|
|
|
---
|
|
|
|
## 3. 화면
|
|
|
|
| 주소 | 화면 |
|
|
|---|---|
|
|
| `#/` | 작업 인덱스 (히어로 + 카테고리 필터 + 번호 매긴 목록) |
|
|
| `#/?cat=game` | 카테고리로 걸러진 목록 |
|
|
| `#/post/12` | 게시물 상세 (마크다운 본문 + 이미지 갤러리 + 라이트박스) |
|
|
| `#/about` | 소개 |
|
|
| `#/admin` | 관리자 로그인 / 대시보드 |
|
|
| `#/admin/new` | 새 글 |
|
|
| `#/admin/edit/12` | 글 수정 |
|
|
| `#/admin/categories` | 카테고리 관리 |
|
|
|
|
### 글쓰기
|
|
|
|
본문은 **마크다운**입니다. 왼쪽에 쓰면 오른쪽에 바로 미리보기가 나옵니다.
|
|
|
|
이미지는 세 가지 방법으로 올립니다.
|
|
|
|
1. 이미지 영역을 **클릭**해서 파일 고르기
|
|
2. 파일을 **끌어다 놓기**
|
|
3. 클립보드에서 **Ctrl+V** 로 붙여넣기
|
|
|
|
올린 이미지마다 세 개의 버튼이 있습니다.
|
|
|
|
- **대표** — 목록에서 커서를 따라 뜨는 썸네일과 상세 표지로 지정
|
|
- **본문삽입** — 커서 위치에 `` 를 끼워 넣기
|
|
- **삭제** — 목록에서 빼기 (이번에 올린 파일이면 서버에서도 지웁니다)
|
|
|
|
저장하지 않고 페이지를 벗어나려 하면 경고가 뜹니다.
|
|
|
|
### 화면 구성
|
|
|
|
목록은 카드 그리드가 아니라 **작품집 목차(인덱스)** 형태입니다.
|
|
번호 → 제목 → 요약 → 카테고리 · 날짜 순으로 한 줄씩 늘어놓고,
|
|
행에 마우스를 올리면 행이 살짝 밀려 들어오면서 대표 이미지가 커서 옆에 떠오릅니다
|
|
(마우스가 있는 기기에서만. 터치 기기에서는 뜨지 않습니다).
|
|
|
|
배경 장식은 쓰지 않습니다. 위계는 글자 크기 대비와 얇은 괘선으로 만들고,
|
|
색은 카테고리 강조색으로만 들어옵니다. 한글은 산세리프, 숫자·라벨은 모노스페이스입니다.
|
|
|
|
카테고리 색은 `#/admin/categories` 에서 바꿀 수 있고, 그 색이 목록·상세·관리자 화면에
|
|
그대로 반영됩니다.
|
|
|
|
### 샘플 글 지우기
|
|
|
|
화면이 어떻게 보이는지 확인할 수 있도록 제목이 `[샘플]` 로 시작하는 글 5건을
|
|
자리표시 이미지와 함께 넣어 두었습니다. **직접 쓴 글이 아니니 지우고 시작하세요.**
|
|
|
|
`#/admin` 에서 로그인한 뒤 각 줄의 **삭제** 를 누르면 됩니다.
|
|
글을 지워도 업로드된 자리표시 이미지 파일은 남으므로, 함께 비우려면
|
|
`GameServer/wwwroot/uploads/` 아래 폴더를 통째로 지우면 됩니다
|
|
(`.gitkeep` 은 남겨 두세요).
|
|
|
|
### 소개 화면 내용 바꾸기
|
|
|
|
`GameServer/wwwroot/js/views/about.js` 의 `ABOUT_MD` 상수 하나만 고치면 됩니다.
|
|
빌드가 필요 없고 새로고침하면 바로 반영됩니다.
|
|
|
|
---
|
|
|
|
## 4. 구조
|
|
|
|
```
|
|
GameServer/
|
|
├─ Controllers/
|
|
│ ├─ CharacterController.cs 게임 API (기존)
|
|
│ ├─ UserController.cs 게임 API (기존)
|
|
│ └─ Portfolio/
|
|
│ ├─ PortfolioAuthController.cs 로그인 · 로그아웃 · 상태
|
|
│ ├─ PortfolioCategoryController.cs 카테고리 CRUD
|
|
│ ├─ PortfolioPostController.cs 게시물 CRUD
|
|
│ └─ PortfolioUploadController.cs 이미지 업로드 · 삭제
|
|
├─ Models/Portfolio/ 모델 + DTO
|
|
├─ Services/PortfolioAdminAuth.cs 관리자 비밀번호 검증
|
|
├─ Data/PortfolioSchemaInitializer.cs 테이블 자동 생성 + 시드
|
|
├─ sql/portfolio_schema.sql 참고용 DDL
|
|
└─ wwwroot/ 포트폴리오 사이트 (빌드 단계 없음)
|
|
├─ index.html
|
|
├─ css/style.css 디자인 시스템 한 파일
|
|
├─ js/
|
|
│ ├─ app.js 진입점 · 라우트 표
|
|
│ ├─ router.js 해시 라우터
|
|
│ ├─ api.js REST 래퍼
|
|
│ ├─ ui.js 토스트 · 모달 · 헬퍼
|
|
│ ├─ markdown.js 자체 제작 마크다운 렌더러
|
|
│ └─ views/ home · post · about · admin
|
|
└─ uploads/ 업로드된 이미지 (git 에서 제외됨)
|
|
```
|
|
|
|
프론트엔드에 **빌드 단계가 없습니다**. npm 도, 번들러도, 외부 CDN 요청도 없습니다.
|
|
배포는 그대로 `dotnet publish` 하나로 끝납니다.
|
|
|
|
---
|
|
|
|
## 5. 보안 메모
|
|
|
|
- 조회는 누구나, **작성 · 수정 · 삭제는 로그인한 관리자만** 가능합니다 (쿠키 세션).
|
|
- 로그인은 IP별 **5분에 8회**로 제한됩니다.
|
|
- 업로드는 확장자뿐 아니라 **매직 바이트**까지 검사합니다. 파일명은 서버가 GUID 로 새로 짓습니다.
|
|
- 이미지 삭제는 경로를 절대경로로 해석해 **`uploads` 폴더 밖이면 거부**합니다.
|
|
- 마크다운은 **먼저 escape 한 뒤 HTML 을 조립**하므로 본문에 넣은 태그가 실행되지 않습니다.
|
|
링크는 `http` · `https` · `mailto` 와 사이트 내부 경로만 허용합니다.
|
|
|
|
### 아직 남은 것
|
|
|
|
`appsettings.json` 에 **DB 비밀번호가 평문으로 들어 있고 git 에 커밋돼 있습니다.**
|
|
이 저장소를 공개할 계획이 있다면 연결 문자열을 환경변수
|
|
(`ConnectionStrings__DefaultConnection`)나 사용자 비밀로 옮기고,
|
|
노출된 DB 비밀번호를 교체하는 것을 권합니다.
|