BeamNG.Earth
BeamNG.drive용 1:1 비율 실시간 지구, 실제 고도·위성 이미지·부동 원점·보조 서버에서 LOD 스트리밍
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
사이버보안 실태평가 문제를 방탈출 형식으로 풀어보는 모바일 웹 게임입니다. 관리자 기능을 사용할 때는 별도 터미널에서 API 서버도 실행합니다. Node.js 22 이상을 권장합니다. 생성한 비밀번호 해시는 .env.server의 ADMIN_PASSWORD_HASH에 넣습니다. 관리자 비밀번호, 세션 비밀키, Supabase service_role 키는 서버 전용 값이며 VITE_ 접두사를 붙이거나 저장소에 커밋하면 안 됩니다. 관리자 화면은 /admin에서 확인할 수 있습니다. 로그인 정보는 브라우저 코드가 아니라 API 서버에서 검증하며, 성공한 세션은 JavaScript로 읽을 수 없는 HttpOnly 쿠키에 저장됩니다. 문제·기관·배포· 응시 조정·순위·상품 관리 요청은 동일 출처 확인과 CSRF 토큰 검사를 통과한 경우에만 서버가 처리합니다. 운영 환경에서는 웹앱과 /api를 같은 HTTPS 도메인으로 연결하는 리버스 프록시 구성을 권장합니다.README 전문 보기 ↗
사이버보안 실태평가 문제를 방탈출 형식으로 풀어보는 모바일 웹 게임입니다.
pnpm install
pnpm dev
관리자 기능을 사용할 때는 별도 터미널에서 API 서버도 실행합니다. Node.js 22 이상을 권장합니다.
cp .env.server.example .env.server
ADMIN_PASSWORD='12자 이상의 관리자 비밀번호' pnpm server:hash-password
pnpm server
생성한 비밀번호 해시는 .env.server의 ADMIN_PASSWORD_HASH에 넣습니다. 관리자 비밀번호,
세션 비밀키, Supabase service_role 키는 서버 전용 값이며 VITE_ 접두사를 붙이거나
저장소에 커밋하면 안 됩니다.
pnpm check
관리자 화면은 /admin에서 확인할 수 있습니다. 로그인 정보는 브라우저 코드가 아니라 API 서버에서
검증하며, 성공한 세션은 JavaScript로 읽을 수 없는 HttpOnly 쿠키에 저장됩니다. 문제·기관·배포·
응시 조정·순위·상품 관리 요청은 동일 출처 확인과 CSRF 토큰 검사를 통과한 경우에만 서버가
처리합니다. 운영 환경에서는 웹앱과 /api를 같은 HTTPS 도메인으로 연결하는 리버스 프록시 구성을
권장합니다.
로컬 UI와 흐름을 확인할 때만 .env.local에서 VITE_ADMIN_DEMO_MODE=true, .env.server에서
ALLOW_LOCAL_DATA=true를 사용할 수 있습니다. 운영 환경에서는 로컬 데이터 모드가 강제로
차단되며 Supabase 프로젝트 연결이 필요합니다.
cp .env.example .env.local
supabase/migrations 안의 SQL을 파일명 순서대로 실행합니다..env.server에 SUPABASE_URL과 SUPABASE_SERVICE_ROLE_KEY를 설정합니다.NODE_ENV=production, ALLOW_LOCAL_DATA=false, 충분히 긴 무작위 SESSION_SECRET으로 서버를
실행합니다./api를 API 서버로 프록시하고 HTTPS를 적용합니다.마지막 마이그레이션은 기존 브라우저 관리자 쓰기 정책을 제거합니다. service_role 키는 모든 RLS를
우회할 수 있으므로 반드시 API 서버의 비밀 저장소에서만 관리해야 합니다.
문제 가져오기는 문제지 1부 + 해답지 1부를 한 세트로 받습니다. 두 파일은 각각 PDF, HWP,
HWPX 중 하나를 선택할 수 있으므로 문제지 PDF + 해답지 HWP 조합도 가능합니다. 원문은 같은
세트 식별자로 private Storage 버킷에 저장되며, 문항 번호가 일치하는 문제와 정답만 결합합니다.
번호를 연결하지 못하거나 정답이 보기 범위를 벗어나면 임의로 보정하지 않고 등록 대상에서 제외합니다.
문서 추출은 브라우저가 아닌 관리자 API 서버에서 수행합니다. PDF는 PDF.js로 페이지 좌표를 기준으로
읽기 순서를 복원하고, HWP/HWPX는 @mdgate/hwp로 구조를 읽습니다. PDF의 텍스트가 없거나 문제·
정답 구조 인식률이 낮으면 CLOVA_OCR_INVOKE_URL과 CLOVA_OCR_SECRET이 설정된 경우 CLOVA
OCR의 한국어·표 추출로 자동 재처리합니다. 두 값은 Render 같은 API 서버의 비밀 환경변수에만
등록하고 Vercel이나 VITE_ 변수에 넣지 않습니다.
구형 바이너리 HWP의 복잡한 표와 배치까지 원본과 동일하게 처리해야 하는 운영 환경에는 한컴 Hwp
SDK 같은 정식 문서 필터가 필요합니다. 문제 번호가 정확히 일치한 문항만 자동 선택하며, 번호 대신
문서 순서로 연결한 결과와 낮은 신뢰도 결과는 경고와 함께 관리자가 직접 선택하도록 남깁니다. 자동
추출 결과는 즉시 공개되지 않고 항상 초안으로 저장되므로 관리자가 문제·보기·정답·해설을 확인한
뒤 공개해야 합니다.
게임은 Supabase가 연결된 운영 환경에서 공개 상태 문제를 번호순으로 30개 불러옵니다. 공개
문제가 30개보다 적거나 조회에 실패하면 정적 문제로 조용히 대체하지 않고 시작을 막아, 화면에
보이는 문제와 서버가 검증하는 정답이 달라지는 상황을 방지합니다. Supabase가 없는 로컬 게임
개발 환경에서만 기존 src/data/questions.ts를 사용합니다.
관리자는 /admin/institutions에서 기관을 등록하고 배포 링크를 생성할 수 있습니다. 배포 링크로
접속한 참여자는 요원명과 부서명, 기관에서 안내한 고유 참여 코드를 입력합니다. 참여 코드는 원문
대신 해시로 저장되며, 같은 배포와 참여 코드 조합에는 응시 기록이 하나만 생성됩니다. 요원명과
부서명은 응시 현황, 순위, CSV 운영 자료에 함께 표시됩니다. 정보보안 등급은 사전 선택이나 별도
진단 없이 게임을 완료한 뒤 서버에서 검증한 정답률로 결정합니다. 60% 미만은 초급, 60% 이상은
중급, 80% 이상은 고급이며 기본 점수는 모든 참가자에게 동일하게 적용합니다.
운영 전에는 문제 관리 화면의 기존 게임 문제 동기화를 실행해 공개 문제 30개를 DB에 등록해야
합니다. 참여 코드는 기관에서 사람마다 다르게 발급해야 단일 응시 제한을 정확히 적용할 수 있습니다.
게임 중 참가자 순위표는 live_leaderboard_entries의 공개 가능한 최소 정보만 Supabase Realtime로
구독합니다. 점수가 바뀌면 참가자 화면이 자동으로 새 순위를 가져오며, 연결이 잠시 끊긴 경우에도
10초 간격 재조회로 복구합니다. 모바일에서는 순위 패널을 펼친 동안에만 실시간 연결을 유지합니다.
전체 및 초급·중급·고급별 순위를 볼 수 있습니다. 아직 게임을 완료하지 않은 참가자의 등급은
평가 중으로 표시됩니다.
/admin/rankings에서도 배포별 완료 순위를 확인할 수 있습니다. 순위는 클라이언트 화면의 점수가
아니라 서버에 처음 기록된 답안을 기준으로 계산하며, 아래 순서를 차례로 적용합니다.
관리자는 현재 1위를 수상자로 확정하고 1위 선정 → 수상자 안내 → 지급 완료 상태와 메모를
기록할 수 있습니다. 운영 자료는 배포별 CSV로 내려받을 수 있습니다. 무효 처리된 응시 기록은
순위에서 자동 제외됩니다.
실시간 순위 기능을 배포하려면 202609090002_result_security_grade.sql까지 적용해야 합니다.
실제 행사 전 부하 시험 절차는 docs/REALTIME_LOAD_TEST.md에 정리되어 있습니다.
src/screens: 화면 단위 컴포넌트src/components: 여러 화면에서 재사용할 수 있는 UIsrc/game: 게임 규칙, 설정, 질문 파싱 로직src/data: 보안 문제 데이터src/admin: 관리자 데이터 모델, 문서 추출, 저장소 접근 로직server: 관리자 인증, 세션, 권한 검사, 관리자 데이터 APIsupabase/migrations: 운영 데이터베이스 스키마와 서버 전용 권한public: 앱에서 실제 사용하는 이미지와 아이콘