Skip to content

Commit 086f483

Browse files
authored
fix: character-death parsing when only being assisted (#454)
1 parent 9df2bd7 commit 086f483

File tree

3 files changed

+1290
-104
lines changed

3 files changed

+1290
-104
lines changed

src/TibiaCharactersCharacter.go

Lines changed: 128 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ type Killers struct {
7575

7676
// Child of Character
7777
type Deaths struct {
78-
Time string `json:"time"` // The timestamp when the death occurred.
79-
Level int `json:"level"` // The level when the death occurred.
80-
Killers []Killers `json:"killers"` // List of killers involved.
81-
Assists []Killers `json:"assists"` // List of assists involved.
82-
Reason string `json:"reason"` // The plain text reason of death.
78+
Time string `json:"time"` // The timestamp when the death occurred.
79+
Level int `json:"level,omitempty"` // The level when the death occurred.
80+
Killers []Killers `json:"killers"` // List of killers involved.
81+
Assists []Killers `json:"assists"` // List of assists involved.
82+
Reason string `json:"reason"` // The plain text reason of death.
8383
}
8484

8585
// Child of Character
@@ -383,9 +383,9 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
383383
return false
384384
}
385385

386-
// Removing line breaks
386+
// Removing line breaks and sanitizing string
387387
CharacterListHTML = TibiaDataHTMLRemoveLinebreaks(CharacterListHTML)
388-
CharacterListHTML = strings.ReplaceAll(CharacterListHTML, ".<br/>Assisted by", ". Assisted by")
388+
CharacterListHTML = strings.ReplaceAll(strings.ReplaceAll(CharacterListHTML, "<br/>", " "), " ", " ")
389389
CharacterListHTML = TibiaDataSanitizeStrings(CharacterListHTML)
390390

391391
dataNoTags := RemoveHtmlTag(CharacterListHTML)
@@ -404,6 +404,7 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
404404
initCestIndexer = `CEST`
405405
levelIndexer = `at Level `
406406
killersIndexer = `by `
407+
assistedIndexer = `Assisted by `
407408
)
408409

409410
var initIndexer string
@@ -444,6 +445,11 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
444445

445446
level := TibiaDataStringToInteger(dataNoTags[levelIdx:endLevelIdx])
446447

448+
// if kill is with assist only (and level is set to 25), then we reset level
449+
if reasonStart == assistedIndexer && level == 25 {
450+
level = 0
451+
}
452+
447453
killersIdx := strings.Index(
448454
CharacterListHTML, killersIndexer,
449455
) + len(killersIndexer)
@@ -453,10 +459,17 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
453459

454460
rawListofKillers := CharacterListHTML[killersIdx:endKillersIdx]
455461

456-
// if kill is with assist..
457-
if strings.Contains(dataNoTags, ". Assisted by ") {
458-
TmpListOfDeath := strings.Split(CharacterListHTML, ". Assisted by ")
459-
rawListofKillers = TmpListOfDeath[0][killersIdx:]
462+
// A death with assist (or with assist only)
463+
if strings.Contains(dataNoTags, assistedIndexer) {
464+
TmpListOfDeath := strings.Split(CharacterListHTML, assistedIndexer)
465+
466+
// get a list of killers
467+
if reasonStart != assistedIndexer {
468+
rawListofKillers = TmpListOfDeath[0][killersIdx:]
469+
rawListofKillers = strings.TrimSpace(strings.TrimSuffix(rawListofKillers, "."))
470+
} else {
471+
rawListofKillers = ""
472+
}
460473
TmpAssist := TmpListOfDeath[1]
461474

462475
// get a list of killers
@@ -473,120 +486,128 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
473486

474487
for i := range ListOfAssists {
475488
name, isPlayer, isTraded, theSummon := TibiaDataParseKiller(ListOfAssists[i])
476-
DeathAssists = append(DeathAssists, Killers{
477-
Name: strings.TrimSuffix(strings.TrimSuffix(name, ".</td>"), "."),
478-
Player: isPlayer,
479-
Traded: isTraded,
480-
Summon: theSummon,
481-
})
489+
if name != "" { // Ensure we don't append empty names
490+
DeathAssists = append(DeathAssists, Killers{
491+
Name: name,
492+
Player: isPlayer,
493+
Traded: isTraded,
494+
Summon: theSummon,
495+
})
496+
}
482497
}
483498
}
484499

485-
// get a list of killers
486-
ListOfKillers := strings.Split(rawListofKillers, ", ")
500+
// A death with killers
501+
if rawListofKillers != "" {
487502

488-
const andStr = " and "
489-
lastItem := ListOfKillers[len(ListOfKillers)-1]
490-
lastAndIdx := strings.LastIndex(lastItem, andStr)
503+
// get a list of killers
504+
ListOfKillers := strings.Split(rawListofKillers, ", ")
491505

492-
if lastAndIdx > -1 {
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-
}
506+
const andStr = " and "
507+
lastItem := ListOfKillers[len(ListOfKillers)-1]
508+
lastAndIdx := strings.LastIndex(lastItem, andStr)
532509

533-
if strings.Contains(str, "of") && !containsCreaturesWithOf(str) {
534-
// this is a summon
535-
buffer.WriteByte(cur)
536-
continue
537-
}
510+
if lastAndIdx > -1 {
511+
if !strings.Contains(lastItem, "<a href=") {
512+
ListOfKillers[len(ListOfKillers)-1] = lastItem[:lastAndIdx]
513+
ListOfKillers = append(ListOfKillers, lastItem[lastAndIdx+len(andStr):])
514+
} else {
515+
ListOfKillers = ListOfKillers[:len(ListOfKillers)-1]
516+
517+
const (
518+
nonTag = iota // outside of a tag
519+
openAnchorTag // inside a <a>
520+
closeAchorTag // inside a </a>
521+
)
522+
523+
var (
524+
buffer bytes.Buffer
525+
state = nonTag
526+
)
527+
buffer.Grow(200) // arbitrary number to avoid allocations
528+
529+
for i := range lastItem {
530+
cur := lastItem[i]
531+
switch state {
532+
case nonTag:
533+
if cur == '<' {
534+
switch lastItem[i+1] {
535+
case '/':
536+
state = closeAchorTag
537+
default:
538+
state = openAnchorTag
539+
if buffer.Len() > 0 {
540+
str := buffer.String()
541+
542+
str = strings.TrimPrefix(str, " and ")
543+
str = strings.TrimSuffix(str, " and ")
544+
545+
if str == "" {
546+
buffer.Reset()
547+
buffer.WriteByte(cur)
548+
continue
549+
}
550+
551+
if strings.Contains(str, "of") && !containsCreaturesWithOf(str) {
552+
// this is a summon
553+
buffer.WriteByte(cur)
554+
continue
555+
}
538556

539-
buffer.Reset()
540-
ListOfKillers = append(ListOfKillers, str)
557+
buffer.Reset()
558+
ListOfKillers = append(ListOfKillers, str)
559+
}
541560
}
542561
}
562+
buffer.WriteByte(cur)
563+
case openAnchorTag:
564+
if cur == '>' {
565+
state = nonTag
566+
}
567+
buffer.WriteByte(cur)
568+
case closeAchorTag:
569+
buffer.WriteByte(cur)
570+
if cur == '>' {
571+
str := buffer.String()
572+
573+
str = strings.TrimPrefix(str, " and ")
574+
str = strings.TrimSuffix(str, " and ")
575+
576+
ListOfKillers = append(ListOfKillers, str)
577+
buffer.Reset()
578+
state = nonTag
579+
}
543580
}
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()
581+
}
582+
583+
if buffer.Len() > 0 {
584+
str := buffer.String()
585+
buffer.Reset()
554586

555-
str = strings.TrimPrefix(str, " and ")
556-
str = strings.TrimSuffix(str, " and ")
587+
str = strings.TrimPrefix(str, " and ")
588+
str = strings.TrimSuffix(str, " and ")
557589

590+
if str != "" {
558591
ListOfKillers = append(ListOfKillers, str)
559-
buffer.Reset()
560-
state = nonTag
561592
}
562593
}
563594
}
595+
}
564596

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-
}
597+
// loop through all killers and append to result
598+
for i := range ListOfKillers {
599+
name, isPlayer, isTraded, theSummon := TibiaDataParseKiller(ListOfKillers[i])
600+
if name != "" { // Ensure we don't append empty names
601+
DeathKillers = append(DeathKillers, Killers{
602+
Name: name,
603+
Player: isPlayer,
604+
Traded: isTraded,
605+
Summon: theSummon,
606+
})
575607
}
576608
}
577609
}
578610

579-
// loop through all killers and append to result
580-
for i := range ListOfKillers {
581-
name, isPlayer, isTraded, theSummon := TibiaDataParseKiller(ListOfKillers[i])
582-
DeathKillers = append(DeathKillers, Killers{
583-
Name: strings.TrimSuffix(strings.TrimSuffix(name, ".</td>"), "."),
584-
Player: isPlayer,
585-
Traded: isTraded,
586-
Summon: theSummon,
587-
})
588-
}
589-
590611
// append deadentry to death list
591612
DeathsData = append(DeathsData, Deaths{
592613
Time: time,
@@ -756,6 +777,9 @@ func TibiaDataParseKiller(data string) (string, bool, bool, string) {
756777
data = RemoveHtmlTag(data)
757778
}
758779

780+
// remove htlm, spaces and dots from data-string
781+
data = strings.TrimSpace(strings.TrimSuffix(strings.TrimSuffix(data, "</td>"), "."))
782+
759783
// get summon information
760784
if strings.HasPrefix(data, "a ") || strings.HasPrefix(data, "an ") {
761785
if containsCreaturesWithOf(data) {

0 commit comments

Comments
 (0)