@@ -75,11 +75,11 @@ type Killers struct {
7575
7676// Child of Character
7777type 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