Skip to content

Commit 6e543bf

Browse files
StopDragonclaude
andcommitted
fix: 레벨 인식 정확도 개선 및 0강 판매 방지
- filterMyMessages 유저 필터링 강화: 다른 유저 메시지 혼입 차단 (예: 권혁진의 [+12] 레벨이 내 결과에 섞이는 문제) - 파괴 시 새 검 이름 추출 패턴 추가 (destroySwordNamePattern) → pendingZeroSword 정상 설정 → 0강 판매 시도 제거 - EnhanceToTarget 파괴 처리 개선: 파괴 전용 패턴 우선 사용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b38c8ea commit 6e543bf

File tree

3 files changed

+38
-16
lines changed

3 files changed

+38
-16
lines changed

internal/game/engine.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,21 +1420,22 @@ func (e *Engine) waitForResponseInternal(maxWait time.Duration, raw bool) string
14201420
}
14211421

14221422
// filterMyMessages 내 메시지만 필터링 (가장 최근 @이름 섹션만)
1423+
// 다른 유저의 강화 결과가 섞이는 것을 방지
1424+
// 예: "플레이봇 @권혁진 〖💦강화 유지💦〗" + "[+12] 검이름" 이 내 결과에 혼입되는 문제 차단
14231425
func (e *Engine) filterMyMessages(text string) string {
14241426
if e.sessionProfile == nil || e.sessionProfile.Name == "" {
14251427
return text // 프로필 없으면 전체 반환
14261428
}
14271429

1428-
myName := e.sessionProfile.Name
1430+
myName := e.sessionProfile.Name // "@행복사랑평화" 형식
14291431
lines := strings.Split(text, "\n")
14301432

14311433
// 가장 마지막 내 메시지 섹션의 시작점 찾기
1434+
// "플레이봇 @내이름" 패턴 (게임봇이 나에게 보낸 결과)
14321435
lastMyIndex := -1
14331436
for i, line := range lines {
1434-
if strings.Contains(line, "@") {
1435-
if strings.Contains(line, myName) {
1436-
lastMyIndex = i // 마지막 내 섹션 시작점 갱신
1437-
}
1437+
if strings.Contains(line, myName) {
1438+
lastMyIndex = i // 마지막 내 섹션 시작점 갱신
14381439
}
14391440
}
14401441

@@ -1448,12 +1449,11 @@ func (e *Engine) filterMyMessages(text string) string {
14481449
for i := lastMyIndex; i < len(lines); i++ {
14491450
line := lines[i]
14501451

1451-
// 다른 사람의 섹션이 시작되면 중단
1452-
if i > lastMyIndex && strings.Contains(line, "@") {
1453-
trimmed := strings.TrimSpace(line)
1454-
if strings.HasPrefix(trimmed, "@") && !strings.Contains(line, myName) {
1455-
break
1456-
}
1452+
// 다른 유저의 게임 메시지가 시작되면 중단
1453+
// @가 포함되어 있지만 내 이름(@myName)이 없는 줄 = 다른 유저의 영역
1454+
// 예: "12:21 플레이봇 @권혁진 〖결과〗" 또는 "12:21 권혁진 @플레이봇 강화"
1455+
if i > lastMyIndex && strings.Contains(line, "@") && !strings.Contains(line, myName) {
1456+
break
14571457
}
14581458

14591459
result = append(result, line)

internal/game/helpers.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,18 @@ func (e *Engine) EnhanceToTarget(itemName string, startLevel int) EnhanceResult
123123
if state.LastResult == "destroy" {
124124
result := EnhanceResult{FinalLevel: currentLevel, Success: false, Destroyed: true}
125125

126-
// 파괴 시 새 검 정보 추출 (판매 결과와 동일한 패턴 사용)
127-
saleResult := ExtractSaleResult(text)
128-
if saleResult != nil && saleResult.NewSwordName != "" {
129-
result.NewSwordName = saleResult.NewSwordName
130-
result.NewSwordType = DetermineItemType(saleResult.NewSwordName)
126+
// 파괴 시 새 검 정보 추출
127+
// 1순위: 파괴 전용 패턴 "『[+0] 낡은 검』 지급되었습니다"
128+
if name, _, found := ExtractDestroyNewSword(text); found {
129+
result.NewSwordName = name
130+
result.NewSwordType = DetermineItemType(name)
131+
} else {
132+
// 2순위: 판매 패턴 fallback "새로운 검 획득: [+0] 낡은 검"
133+
saleResult := ExtractSaleResult(text)
134+
if saleResult != nil && saleResult.NewSwordName != "" {
135+
result.NewSwordName = saleResult.NewSwordName
136+
result.NewSwordType = DetermineItemType(saleResult.NewSwordName)
137+
}
131138
}
132139

133140
return result

internal/game/parser.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ var (
7373
trashPattern = regexp.MustCompile(`(?:낡은|일반|노말|커먼|쓰레기)`)
7474
farmPattern = regexp.MustCompile(`(?:획득|얻었|드랍|뽑기)`)
7575

76+
// 파괴 시 새 검 지급 패턴: "『[+0] 낡은 검』 지급되었습니다"
77+
destroyNewSwordPattern = regexp.MustCompile(`지급되었습니다`)
78+
destroySwordNamePattern = regexp.MustCompile(`『\[\+?(\d+)\]\s*([^』]+)』\s*지급`)
79+
7680
// 판매 관련 패턴
7781
cantSellPattern = regexp.MustCompile(`(?:판매할 수 없|가치가 없|팔 수 없)`)
7882
newSwordPattern = regexp.MustCompile(`새로운 검.*획득|검.*획득`)
@@ -378,6 +382,17 @@ func ExtractSaleResult(text string) *SaleResult {
378382
return result
379383
}
380384

385+
// ExtractDestroyNewSword 파괴 시 지급된 새 검 정보 추출
386+
// 형식: "『[+0] 낡은 검』 지급되었습니다" → (name="낡은 검", level=0, found=true)
387+
func ExtractDestroyNewSword(text string) (string, int, bool) {
388+
if match := destroySwordNamePattern.FindStringSubmatch(text); len(match) >= 3 {
389+
level, _ := strconv.Atoi(match[1])
390+
name := strings.TrimSpace(match[2])
391+
return name, level, true
392+
}
393+
return "", 0, false
394+
}
395+
381396
// DetermineItemType 아이템 이름으로 타입 결정 (v3 로직)
382397
// - 몽둥이, 망치, 검, 칼로 끝나면 → "normal" (일반)
383398
// - 그 외 전부 → "special" (특수: 칫솔, 우산, 단소, 젓가락, 광선검, 슬리퍼 등)

0 commit comments

Comments
 (0)