Skip to content

Commit 1e7d6b7

Browse files
authored
fix character killer parser by rewrite of death parsing logic (#338)
1 parent ec2e9ea commit 1e7d6b7

File tree

3 files changed

+975
-2
lines changed

3 files changed

+975
-2
lines changed

src/TibiaCharactersCharacter.go

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"bytes"
45
"fmt"
56
"log"
67
"net/http"
@@ -489,8 +490,90 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string) (CharacterResponse, err
489490
lastAndIdx := strings.LastIndex(lastItem, andStr)
490491

491492
if lastAndIdx > -1 {
492-
ListOfKillers[len(ListOfKillers)-1] = lastItem[:lastAndIdx]
493-
ListOfKillers = append(ListOfKillers, lastItem[lastAndIdx+len(andStr):])
493+
if !strings.Contains(lastItem, "<a href=") {
494+
ListOfKillers[len(ListOfKillers)-1] = lastItem[:lastAndIdx]
495+
ListOfKillers = append(ListOfKillers, lastItem[lastAndIdx+len(andStr):])
496+
} else {
497+
ListOfKillers = ListOfKillers[:len(ListOfKillers)-1]
498+
499+
const (
500+
nonTag = iota // outside of a tag
501+
openAnchorTag // inside a <a>
502+
closeAchorTag // inside a </a>
503+
)
504+
505+
var (
506+
buffer bytes.Buffer
507+
state = nonTag
508+
)
509+
buffer.Grow(200) // arbitrary number to avoid allocations
510+
511+
for i := range lastItem {
512+
cur := lastItem[i]
513+
switch state {
514+
case nonTag:
515+
if cur == '<' {
516+
switch lastItem[i+1] {
517+
case '/':
518+
state = closeAchorTag
519+
default:
520+
state = openAnchorTag
521+
if buffer.Len() > 0 {
522+
str := buffer.String()
523+
524+
str = strings.TrimPrefix(str, " and ")
525+
str = strings.TrimSuffix(str, " and ")
526+
527+
if str == "" {
528+
buffer.Reset()
529+
buffer.WriteByte(cur)
530+
continue
531+
}
532+
533+
if strings.Contains(str, "of") && !containsCreaturesWithOf(str) {
534+
// this is a summon
535+
buffer.WriteByte(cur)
536+
continue
537+
}
538+
539+
buffer.Reset()
540+
ListOfKillers = append(ListOfKillers, str)
541+
}
542+
}
543+
}
544+
buffer.WriteByte(cur)
545+
case openAnchorTag:
546+
if cur == '>' {
547+
state = nonTag
548+
}
549+
buffer.WriteByte(cur)
550+
case closeAchorTag:
551+
buffer.WriteByte(cur)
552+
if cur == '>' {
553+
str := buffer.String()
554+
555+
str = strings.TrimPrefix(str, " and ")
556+
str = strings.TrimSuffix(str, " and ")
557+
558+
ListOfKillers = append(ListOfKillers, str)
559+
buffer.Reset()
560+
state = nonTag
561+
}
562+
}
563+
}
564+
565+
if buffer.Len() > 0 {
566+
str := buffer.String()
567+
buffer.Reset()
568+
569+
str = strings.TrimPrefix(str, " and ")
570+
str = strings.TrimSuffix(str, " and ")
571+
572+
if str != "" {
573+
ListOfKillers = append(ListOfKillers, str)
574+
}
575+
}
576+
}
494577
}
495578

496579
// loop through all killers and append to result

src/TibiaCharactersCharacter_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,6 +3298,94 @@ func TestNumber12(t *testing.T) {
32983298
assert.Equal(55, len(characterJson.Character.Deaths))
32993299
}
33003300

3301+
func TestNumber13(t *testing.T) {
3302+
file, err := static.TestFiles.Open("testdata/characters/Ninth Dimension.html")
3303+
if err != nil {
3304+
t.Fatalf("file opening error: %s", err)
3305+
}
3306+
defer file.Close()
3307+
3308+
data, err := io.ReadAll(file)
3309+
if err != nil {
3310+
t.Fatalf("File reading error: %s", err)
3311+
}
3312+
3313+
characterJson, err := TibiaCharactersCharacterImpl(string(data))
3314+
if err != nil {
3315+
t.Fatal(err)
3316+
}
3317+
3318+
assert := assert.New(t)
3319+
character := characterJson.Character.CharacterInfo
3320+
3321+
assert.Equal("Ninth Dimension", character.Name)
3322+
assert.False(characterJson.Character.DeathsTruncated)
3323+
3324+
// validate death data
3325+
assert.Equal(1, len(characterJson.Character.Deaths))
3326+
deaths := characterJson.Character.Deaths
3327+
3328+
for idx, tc := range []struct {
3329+
Assists []Killers
3330+
Killers []Killers
3331+
Level int
3332+
Reason string
3333+
Time string
3334+
}{
3335+
{
3336+
Assists: []Killers{
3337+
{Name: "Dark Assa", Player: true, Traded: false, Summon: ""},
3338+
},
3339+
Killers: []Killers{
3340+
{Name: "Pess Joeru", Player: true, Traded: false, Summon: ""},
3341+
{Name: "Curly Da Goonx", Player: true, Traded: false, Summon: ""},
3342+
{Name: "Setarehh", Player: true, Traded: false, Summon: ""},
3343+
{Name: "Skkrimz", Player: true, Traded: false, Summon: ""},
3344+
{Name: "Luna Mors", Player: true, Traded: false, Summon: ""},
3345+
{Name: "Micklo", Player: true, Traded: false, Summon: ""},
3346+
{Name: "Kate Morningstar", Player: true, Traded: false, Summon: ""},
3347+
{Name: "Avatar Avatar", Player: true, Traded: false, Summon: ""},
3348+
{Name: "San Bernardino Hoodrat", Player: true, Traded: false, Summon: ""},
3349+
{Name: "Mighty Nitro", Player: true, Traded: false, Summon: ""},
3350+
{Name: "Aiakosz", Player: true, Traded: false, Summon: ""},
3351+
{Name: "Sithaadoz", Player: true, Traded: false, Summon: ""},
3352+
{Name: "Compa Ache", Player: true, Traded: false, Summon: ""},
3353+
{Name: "Cave Stormer", Player: true, Traded: false, Summon: ""},
3354+
{Name: "Doppler and Bankrupt", Player: true, Traded: false, Summon: ""},
3355+
},
3356+
Level: 544,
3357+
Reason: "Eliminated at Level 544 by Pess Joeru, Curly Da Goonx, Setarehh, Skkrimz, Luna Mors, Micklo, Kate Morningstar, Avatar Avatar, San Bernardino Hoodrat, Mighty Nitro, Aiakosz, Sithaadoz, Compa Ache, Cave Stormer and Doppler and Bankrupt. Assisted by Dark Assa.",
3358+
Time: "2024-03-12T21:02:33Z",
3359+
},
3360+
} {
3361+
assert.True(
3362+
reflect.DeepEqual(deaths[idx].Assists, tc.Assists),
3363+
"Wrong assists\nidx: %d\nwant: %#v\n\ngot: %#v",
3364+
idx, tc.Assists, deaths[idx].Assists,
3365+
)
3366+
assert.True(
3367+
reflect.DeepEqual(deaths[idx].Killers, tc.Killers),
3368+
"Wrong killers\nidx: %d\nwant: %#v\n\ngot: %#v",
3369+
idx, tc.Killers, deaths[idx].Killers,
3370+
)
3371+
assert.Equal(
3372+
deaths[idx].Level, tc.Level,
3373+
"Wrong Level\nidx: %d\nwant: %d\n\ngot: %d",
3374+
idx, tc.Level, deaths[idx].Level,
3375+
)
3376+
assert.Equal(
3377+
deaths[idx].Reason, tc.Reason,
3378+
"Wrong Reason\nidx: %d\nwant: %s\n\ngot: %s",
3379+
idx, tc.Reason, deaths[idx].Reason,
3380+
)
3381+
assert.Equal(
3382+
tc.Time, deaths[idx].Time,
3383+
"Wrong Time\nidx: %d\nwant: %s\n\ngot: %s",
3384+
idx, tc.Time, deaths[idx].Time,
3385+
)
3386+
}
3387+
}
3388+
33013389
func BenchmarkNumber1(b *testing.B) {
33023390
file, err := static.TestFiles.Open("testdata/characters/Darkside Rafa.html")
33033391
if err != nil {

0 commit comments

Comments
 (0)