fix: 시작 시 플레이어 접속 확인 + RCON 호환
- check_player() 추가: 30초 대기하며 플레이어 접속 안내 - game.players[1] 사용으로 RCON 호환 - 미접속 시 명확한 에러 메시지
This commit is contained in:
51
main.py
51
main.py
@@ -1,8 +1,13 @@
|
|||||||
"""
|
"""
|
||||||
main.py — 순수 AI 플레이 버전
|
main.py — 순수 AI 플레이 버전
|
||||||
|
|
||||||
치트 없이 실제 게임 메커닉으로 플레이.
|
치트 없이 실제 게임 메커니즘으로 플레이.
|
||||||
걷기/채굴/제작에 실제 시간이 걸리므로 ACTION_DELAY를 줄임.
|
걷기/채굴/제작에 실제 시간이 걸리므로 ACTION_DELAY를 설정.
|
||||||
|
|
||||||
|
핵심 변경:
|
||||||
|
- 시작 시 플레이어 접속 여부 확인
|
||||||
|
- game.player → game.players[1] (RCON 호환)
|
||||||
|
- JSON 파싱 실패 시 재시도 (ai_planner 내부)
|
||||||
"""
|
"""
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
@@ -16,20 +21,54 @@ from action_executor import ActionExecutor
|
|||||||
RCON_HOST = os.getenv("FACTORIO_HOST", "127.0.0.1")
|
RCON_HOST = os.getenv("FACTORIO_HOST", "127.0.0.1")
|
||||||
RCON_PORT = int(os.getenv("FACTORIO_PORT", "25575"))
|
RCON_PORT = int(os.getenv("FACTORIO_PORT", "25575"))
|
||||||
RCON_PASSWORD = os.getenv("FACTORIO_PASSWORD", "factorio_ai")
|
RCON_PASSWORD = os.getenv("FACTORIO_PASSWORD", "factorio_ai")
|
||||||
ACTION_DELAY = 0.2 # 행동 자체에 시간이 걸리므로 간격 짧게
|
ACTION_DELAY = 0.2
|
||||||
LOG_FILE = "agent_log.jsonl"
|
LOG_FILE = "agent_log.jsonl"
|
||||||
|
|
||||||
# 건물 N개 이상이면 압축 모드로 전환
|
# 건물 N개 이상이면 압축 모드로 전환
|
||||||
COMPRESS_THRESHOLD = 50
|
COMPRESS_THRESHOLD = 50
|
||||||
|
|
||||||
|
|
||||||
|
def check_player(rcon: FactorioRCON) -> bool:
|
||||||
|
"""서버에 접속한 플레이어가 있는지 확인하고 안내"""
|
||||||
|
print("\n[초기화] 플레이어 접속 확인 중...")
|
||||||
|
|
||||||
|
for attempt in range(30): # 최대 30초 대기
|
||||||
|
result = rcon.check_player()
|
||||||
|
if result:
|
||||||
|
info = rcon.lua("""
|
||||||
|
local p = game.players[1]
|
||||||
|
if p then
|
||||||
|
rcon.print(p.name .. " @ " .. string.format("%.0f, %.0f", p.position.x, p.position.y))
|
||||||
|
end
|
||||||
|
""")
|
||||||
|
print(f"[초기화] ✅ 플레이어 발견: {info}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
if attempt == 0:
|
||||||
|
print("[초기화] ⚠️ 접속한 플레이어가 없습니다!")
|
||||||
|
print("[초기화] 팩토리오 클라이언트로 이 서버에 접속하세요.")
|
||||||
|
print(f"[초기화] 서버 주소: {RCON_HOST}")
|
||||||
|
print(f"[초기화] 대기 중... (최대 30초)")
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("[오류] 30초 내에 플레이어가 접속하지 않았습니다.")
|
||||||
|
print("[오류] 팩토리오 클라이언트로 서버에 접속한 후 다시 실행하세요.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
print(" 팩토리오 순수 AI 에이전트 (치트 없음)")
|
print(" 팩토리오 순수 AI 에이전트 (치트 없음)")
|
||||||
print(" - 실제 걷기 / 실제 채굴 / 실제 제작 / 건설 거리 제한")
|
print(" - 실제 걷기 / 실제 채굴 / 실제 제작 / 건설 거리 제한")
|
||||||
|
print(" - RCON 호환: game.players[1] 사용")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
|
|
||||||
with FactorioRCON(RCON_HOST, RCON_PORT, RCON_PASSWORD) as rcon:
|
with FactorioRCON(RCON_HOST, RCON_PORT, RCON_PASSWORD) as rcon:
|
||||||
|
# ── 플레이어 접속 확인 ──
|
||||||
|
if not check_player(rcon):
|
||||||
|
return
|
||||||
|
|
||||||
reader = StateReader(rcon)
|
reader = StateReader(rcon)
|
||||||
compressor = ContextCompressor(rcon)
|
compressor = ContextCompressor(rcon)
|
||||||
planner = AIPlanner()
|
planner = AIPlanner()
|
||||||
@@ -45,7 +84,7 @@ def run():
|
|||||||
print(f"\n{'='*50}")
|
print(f"\n{'='*50}")
|
||||||
print(f"[재계획] 총 {total_actions}개 실행 완료")
|
print(f"[재계획] 총 {total_actions}개 실행 완료")
|
||||||
|
|
||||||
# ── 압축 레벨 자동 선택 ──────────────────────
|
# ── 압축 레벨 자동 선택 ──
|
||||||
if entity_count < COMPRESS_THRESHOLD:
|
if entity_count < COMPRESS_THRESHOLD:
|
||||||
print("[상태] 초반 모드 — 상세 상태 수집")
|
print("[상태] 초반 모드 — 상세 상태 수집")
|
||||||
state = reader.get_full_state()
|
state = reader.get_full_state()
|
||||||
@@ -64,14 +103,14 @@ def run():
|
|||||||
global_info = compressor._get_global_summary()
|
global_info = compressor._get_global_summary()
|
||||||
entity_count = global_info.get("total_entities", entity_count)
|
entity_count = global_info.get("total_entities", entity_count)
|
||||||
|
|
||||||
# ── AI 계획 ──────────────────────────────────
|
# ── AI 계획 ──
|
||||||
queue = planner.decide(summary)
|
queue = planner.decide(summary)
|
||||||
if not queue:
|
if not queue:
|
||||||
print("[경고] AI가 행동 반환 안 함. 10초 후 재시도")
|
print("[경고] AI가 행동 반환 안 함. 10초 후 재시도")
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ── 행동 실행 ─────────────────────────────────────
|
# ── 행동 실행 ──
|
||||||
action = queue.pop(0)
|
action = queue.pop(0)
|
||||||
total_actions += 1
|
total_actions += 1
|
||||||
act = action.get("action", "")
|
act = action.get("action", "")
|
||||||
|
|||||||
Reference in New Issue
Block a user