diff --git a/CHANGELOG.md b/CHANGELOG.md
index cdb03ab4..5ffadd74 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
# Changelog
+## [4.3.5] - 2025-03-09
+
+## Changed
+
+- bump golang.org/x/text from 0.22.0 to 0.23.0 ([#457](https://github.com/TibiaData/tibiadata-api-go/pull/457) by [dependabot](https://github.com/dependabot))
+
+## Fixed
+
+- character-death parsing when only being assisted ([#454](https://github.com/TibiaData/tibiadata-api-go/pull/454) by [tobiasehlert](https://github.com/tobiasehlert))
+- improve character death parsing and removing creature prefix ([#456](https://github.com/TibiaData/tibiadata-api-go/pull/456) by [tobiasehlert](https://github.com/tobiasehlert))
+
## [4.3.4] - 2025-02-26
### Changed
@@ -588,6 +599,7 @@ Head over to [tibiadata.com](https://tibiadata.com/2022/03/tibiadata-api-v3-rele
Initial commit
+[4.3.5]: https://github.com/tibiadata/tibiadata-api-go/compare/v4.3.4...v4.3.5
[4.3.4]: https://github.com/tibiadata/tibiadata-api-go/compare/v4.3.3...v4.3.4
[4.3.3]: https://github.com/tibiadata/tibiadata-api-go/compare/v4.3.2...v4.3.3
[4.3.2]: https://github.com/tibiadata/tibiadata-api-go/compare/v4.3.1...v4.3.2
diff --git a/go.mod b/go.mod
index b6e67615..209a1354 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
github.com/go-resty/resty/v2 v2.16.5
github.com/mantyr/go-charset v0.0.0-20160510214718-44d054d82c4a
github.com/stretchr/testify v1.10.0
- golang.org/x/text v0.22.0
+ golang.org/x/text v0.23.0
)
require (
diff --git a/go.sum b/go.sum
index 1d647570..79810275 100644
--- a/go.sum
+++ b/go.sum
@@ -139,8 +139,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
-golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/src/TibiaCharactersCharacter.go b/src/TibiaCharactersCharacter.go
index c9231aa4..984d19ef 100644
--- a/src/TibiaCharactersCharacter.go
+++ b/src/TibiaCharactersCharacter.go
@@ -7,6 +7,8 @@ import (
"net/http"
"reflect"
"strings"
+ "unicode"
+ "unicode/utf8"
"github.com/PuerkitoBio/goquery"
"github.com/TibiaData/tibiadata-api-go/src/validation"
@@ -75,11 +77,11 @@ type Killers struct {
// Child of Character
type Deaths struct {
- Time string `json:"time"` // The timestamp when the death occurred.
- Level int `json:"level"` // The level when the death occurred.
- Killers []Killers `json:"killers"` // List of killers involved.
- Assists []Killers `json:"assists"` // List of assists involved.
- Reason string `json:"reason"` // The plain text reason of death.
+ Time string `json:"time"` // The timestamp when the death occurred.
+ Level int `json:"level,omitempty"` // The level when the death occurred.
+ Killers []Killers `json:"killers"` // List of killers involved.
+ Assists []Killers `json:"assists"` // List of assists involved.
+ Reason string `json:"reason"` // The plain text reason of death.
}
// Child of Character
@@ -383,9 +385,9 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
return false
}
- // Removing line breaks
+ // Removing line breaks and sanitizing string
CharacterListHTML = TibiaDataHTMLRemoveLinebreaks(CharacterListHTML)
- CharacterListHTML = strings.ReplaceAll(CharacterListHTML, ". Assisted by", ". Assisted by")
+ CharacterListHTML = strings.ReplaceAll(strings.ReplaceAll(CharacterListHTML, " ", " "), " ", " ")
CharacterListHTML = TibiaDataSanitizeStrings(CharacterListHTML)
dataNoTags := RemoveHtmlTag(CharacterListHTML)
@@ -404,6 +406,7 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
initCestIndexer = `CEST`
levelIndexer = `at Level `
killersIndexer = `by `
+ assistedIndexer = `Assisted by `
)
var initIndexer string
@@ -444,6 +447,11 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
level := TibiaDataStringToInteger(dataNoTags[levelIdx:endLevelIdx])
+ // if kill is with assist only (and level is set to 25), then we reset level
+ if reasonStart == assistedIndexer && level == 25 {
+ level = 0
+ }
+
killersIdx := strings.Index(
CharacterListHTML, killersIndexer,
) + len(killersIndexer)
@@ -453,10 +461,17 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
rawListofKillers := CharacterListHTML[killersIdx:endKillersIdx]
- // if kill is with assist..
- if strings.Contains(dataNoTags, ". Assisted by ") {
- TmpListOfDeath := strings.Split(CharacterListHTML, ". Assisted by ")
- rawListofKillers = TmpListOfDeath[0][killersIdx:]
+ // A death with assist (or with assist only)
+ if strings.Contains(dataNoTags, assistedIndexer) {
+ TmpListOfDeath := strings.Split(CharacterListHTML, assistedIndexer)
+
+ // get a list of killers
+ if reasonStart != assistedIndexer {
+ rawListofKillers = TmpListOfDeath[0][killersIdx:]
+ rawListofKillers = strings.TrimSpace(strings.TrimSuffix(rawListofKillers, "."))
+ } else {
+ rawListofKillers = ""
+ }
TmpAssist := TmpListOfDeath[1]
// get a list of killers
@@ -473,118 +488,133 @@ func TibiaCharactersCharacterImpl(BoxContentHTML string, url string) (CharacterR
for i := range ListOfAssists {
name, isPlayer, isTraded, theSummon := TibiaDataParseKiller(ListOfAssists[i])
- DeathAssists = append(DeathAssists, Killers{
- Name: strings.TrimSuffix(strings.TrimSuffix(name, "."), "."),
- Player: isPlayer,
- Traded: isTraded,
- Summon: theSummon,
- })
+ if name != "" { // Ensure we don't append empty names
+ DeathAssists = append(DeathAssists, Killers{
+ Name: name,
+ Player: isPlayer,
+ Traded: isTraded,
+ Summon: theSummon,
+ })
+ }
}
}
- // get a list of killers
- ListOfKillers := strings.Split(rawListofKillers, ", ")
+ // A death with killers
+ if rawListofKillers != "" {
- const andStr = " and "
- lastItem := ListOfKillers[len(ListOfKillers)-1]
- lastAndIdx := strings.LastIndex(lastItem, andStr)
+ // get a list of killers
+ ListOfKillers := strings.Split(rawListofKillers, ", ")
- if lastAndIdx > -1 {
- if !strings.Contains(lastItem, " -1 {
+ if !strings.Contains(lastItem, " ' {
- state = nonTag
- }
- buffer.WriteByte(cur)
- case closeAchorTag:
- buffer.WriteByte(cur)
- if cur == '>' {
- str := buffer.String()
+ buffer.WriteByte(cur)
- str = strings.TrimPrefix(str, " and ")
- str = strings.TrimSuffix(str, " and ")
+ if cur == ')' {
+ str := buffer.String()
- ListOfKillers = append(ListOfKillers, str)
- buffer.Reset()
- state = nonTag
+ buffer.Reset()
+ ListOfKillers = append(ListOfKillers, str)
+ }
+ case openAnchorTag:
+ if cur == '>' {
+ state = nonTag
+ }
+ buffer.WriteByte(cur)
+ case closeAchorTag:
+ buffer.WriteByte(cur)
+ if cur == '>' {
+ str := buffer.String()
+
+ str = strings.TrimPrefix(str, " and ")
+ str = strings.TrimSuffix(str, " and ")
+
+ ListOfKillers = append(ListOfKillers, str)
+ buffer.Reset()
+ state = nonTag
+ }
}
}
- }
- if buffer.Len() > 0 {
- str := buffer.String()
- buffer.Reset()
+ if buffer.Len() > 0 {
+ str := buffer.String()
+ buffer.Reset()
- str = strings.TrimPrefix(str, " and ")
- str = strings.TrimSuffix(str, " and ")
+ str = strings.TrimPrefix(str, " and ")
+ str = strings.TrimSuffix(str, " and ")
- if str != "" {
- ListOfKillers = append(ListOfKillers, str)
+ if str != "" {
+ ListOfKillers = append(ListOfKillers, str)
+ }
}
}
}
- }
- // loop through all killers and append to result
- for i := range ListOfKillers {
- name, isPlayer, isTraded, theSummon := TibiaDataParseKiller(ListOfKillers[i])
- DeathKillers = append(DeathKillers, Killers{
- Name: strings.TrimSuffix(strings.TrimSuffix(name, "."), "."),
- Player: isPlayer,
- Traded: isTraded,
- Summon: theSummon,
- })
+ // loop through all killers and append to result
+ for i := range ListOfKillers {
+ name, isPlayer, isTraded, theSummon := TibiaDataParseKiller(ListOfKillers[i])
+ if name != "" { // Ensure we don't append empty names
+ DeathKillers = append(DeathKillers, Killers{
+ Name: name,
+ Player: isPlayer,
+ Traded: isTraded,
+ Summon: theSummon,
+ })
+ }
+ }
}
// append deadentry to death list
@@ -756,16 +786,19 @@ func TibiaDataParseKiller(data string) (string, bool, bool, string) {
data = RemoveHtmlTag(data)
}
+ // remove htlm, spaces, dots and prefixes from data-string
+ data = strings.TrimSpace(strings.TrimSuffix(strings.TrimSuffix(data, ""), "."))
+ data = strings.TrimPrefix(strings.TrimPrefix(strings.TrimPrefix(data, "and "), "a "), "an ")
+
+ firstRune, _ := utf8.DecodeRuneInString(data)
// get summon information
- if strings.HasPrefix(data, "a ") || strings.HasPrefix(data, "an ") {
- if containsCreaturesWithOf(data) {
- // this is not a summon, since it is a creature with a of in the middle
- } else {
- ofIdx := strings.Index(data, "of")
- if ofIdx != -1 {
- theSummon = data[:ofIdx-1]
- data = data[ofIdx+3:]
- }
+ if containsCreaturesWithOf(data) {
+ // this is not a summon, since it is a creature with a of in the middle
+ } else if unicode.IsLower(firstRune) {
+ ofIdx := strings.Index(data, "of")
+ if ofIdx != -1 {
+ theSummon = data[:ofIdx-1]
+ data = data[ofIdx+3:]
}
}
@@ -852,9 +885,9 @@ func containsCreaturesWithOf(str string) bool {
"pillar of summoning",
"priestess of the wild sun",
"rage of mazoran",
+ "reflection of a mage",
"reflection of mawhawk",
"reflection of obujos",
- "reflection of a mage",
"retainer of baeloc",
"scorn of the emperor",
"servant of tentugly",
diff --git a/src/TibiaCharactersCharacter_test.go b/src/TibiaCharactersCharacter_test.go
index b502ed73..7c8c004f 100644
--- a/src/TibiaCharactersCharacter_test.go
+++ b/src/TibiaCharactersCharacter_test.go
@@ -198,11 +198,11 @@ func TestNumber4(t *testing.T) {
creatureWithOfDeath := characterJson.Character.Deaths[16]
assert.Equal(2, len(creatureWithOfDeath.Killers))
assert.Equal(260, creatureWithOfDeath.Level)
- assert.Equal("an undead elite gladiator", creatureWithOfDeath.Killers[0].Name)
+ assert.Equal("undead elite gladiator", creatureWithOfDeath.Killers[0].Name)
assert.False(creatureWithOfDeath.Killers[0].Player)
assert.False(creatureWithOfDeath.Killers[0].Traded)
assert.Empty(creatureWithOfDeath.Killers[0].Summon)
- assert.Equal("a priestess of the wild sun", creatureWithOfDeath.Killers[1].Name)
+ assert.Equal("priestess of the wild sun", creatureWithOfDeath.Killers[1].Name)
tradedInDeath := characterJson.Character.Deaths[18]
assert.Equal(3, len(tradedInDeath.Assists))
@@ -216,7 +216,7 @@ func TestNumber4(t *testing.T) {
assert.Equal(5, len(longDeath.Assists))
assert.Equal(231, longDeath.Level)
assert.Equal("Adam No Hands", longDeath.Assists[4].Name)
- assert.Equal("a paladin familiar", longDeath.Assists[4].Summon)
+ assert.Equal("paladin familiar", longDeath.Assists[4].Summon)
assert.True(longDeath.Assists[4].Traded)
deaths := characterJson.Character.Deaths
@@ -319,7 +319,7 @@ func TestNumber4(t *testing.T) {
{
Assists: []Killers{},
Killers: []Killers{
- {Name: "an ice golem", Player: false, Traded: false, Summon: ""},
+ {Name: "ice golem", Player: false, Traded: false, Summon: ""},
},
Level: 266,
Reason: "Died at Level 266 by an ice golem.",
@@ -402,7 +402,7 @@ func TestNumber4(t *testing.T) {
{
Assists: []Killers{},
Killers: []Killers{
- {Name: "a gazer spectre", Player: false, Traded: false, Summon: ""},
+ {Name: "gazer spectre", Player: false, Traded: false, Summon: ""},
},
Level: 264,
Reason: "Died at Level 264 by a gazer spectre.",
@@ -557,7 +557,7 @@ func TestNumber4(t *testing.T) {
{Name: "Kanj iro", Player: true, Traded: false, Summon: ""},
},
Killers: []Killers{
- {Name: "an unstable spark", Player: false, Traded: false, Summon: ""},
+ {Name: "unstable spark", Player: false, Traded: false, Summon: ""},
},
Level: 267,
Reason: "Died at Level 267 by an unstable spark. Assisted by Jack Kevorkian, Mapius Akuno and Kanj iro.",
@@ -569,7 +569,7 @@ func TestNumber4(t *testing.T) {
{Name: "Niki Salamanca", Player: true, Traded: false, Summon: ""},
},
Killers: []Killers{
- {Name: "a dawnfire asura", Player: false, Traded: false, Summon: ""},
+ {Name: "dawnfire asura", Player: false, Traded: false, Summon: ""},
},
Level: 261,
Reason: "Died at Level 261 by a dawnfire asura. Assisted by Samorbum and Niki Salamanca.",
@@ -643,8 +643,8 @@ func TestNumber4(t *testing.T) {
{
Assists: []Killers{},
Killers: []Killers{
- {Name: "an undead elite gladiator", Player: false, Traded: false, Summon: ""},
- {Name: "a priestess of the wild sun", Player: false, Traded: false, Summon: ""},
+ {Name: "undead elite gladiator", Player: false, Traded: false, Summon: ""},
+ {Name: "priestess of the wild sun", Player: false, Traded: false, Summon: ""},
},
Level: 260,
Reason: "Died at Level 260 by an undead elite gladiator and a priestess of the wild sun.",
@@ -686,7 +686,7 @@ func TestNumber4(t *testing.T) {
{Name: "Adam No Hands", Player: true, Traded: true, Summon: ""},
},
Killers: []Killers{
- {Name: "a midnight asura", Player: false, Traded: false, Summon: ""},
+ {Name: "midnight asura", Player: false, Traded: false, Summon: ""},
},
Level: 261,
Reason: "Died at Level 261 by a midnight asura. Assisted by Peninsula Boi, Vithrann and Adam No Hands (traded).",
@@ -698,7 +698,7 @@ func TestNumber4(t *testing.T) {
{Name: "Adam No Hands", Player: true, Traded: true, Summon: ""},
},
Killers: []Killers{
- {Name: "a midnight asura", Player: false, Traded: false, Summon: ""},
+ {Name: "midnight asura", Player: false, Traded: false, Summon: ""},
},
Level: 262,
Reason: "Died at Level 262 by a midnight asura. Assisted by Peninsula Boi and Adam No Hands (traded).",
@@ -820,7 +820,7 @@ func TestNumber4(t *testing.T) {
{Name: "Utanii Herh", Player: true, Traded: false, Summon: ""},
{Name: "King Peruvian", Player: true, Traded: false, Summon: ""},
{Name: "Raven Kyle", Player: true, Traded: false, Summon: ""},
- {Name: "a true dawnfire asura", Player: false, Traded: false, Summon: ""},
+ {Name: "true dawnfire asura", Player: false, Traded: false, Summon: ""},
},
Level: 262,
Reason: "Killed at Level 262 by Utanii Herh, King Peruvian, Raven Kyle and a true dawnfire asura.",
@@ -1815,7 +1815,7 @@ func TestNumber4(t *testing.T) {
{Name: "Psycovzky", Player: true, Traded: false, Summon: ""},
{Name: "Tacos Ardera", Player: true, Traded: false, Summon: ""},
{Name: "Street Runner", Player: true, Traded: false, Summon: ""},
- {Name: "Slobansky", Player: true, Traded: false, Summon: "a sorcerer familiar"},
+ {Name: "Slobansky", Player: true, Traded: false, Summon: "sorcerer familiar"},
},
Level: 237,
Reason: "Slain at Level 237 by Nevin kyle, Dont Kill Marta, Rein is Here, Arthur Heartless, Psycovzky, Tacos Ardera, Street Runner and a sorcerer familiar of Slobansky.",
@@ -2270,7 +2270,7 @@ func TestNumber4(t *testing.T) {
{Name: "Spyt Ponzi", Player: true, Traded: false, Summon: ""},
{Name: "Contatinho Ekbomba", Player: true, Traded: false, Summon: ""},
{Name: "Rondero Miguel", Player: true, Traded: false, Summon: ""},
- {Name: "an adult goanna", Player: false, Traded: false, Summon: ""},
+ {Name: "adult goanna", Player: false, Traded: false, Summon: ""},
},
Level: 225,
Reason: "Slain at Level 225 by Nevin kyle, Jungle Rubi Dominante, Negaum ardera defender, Chapo Kyle, Rondero Zaka (traded), Spyt Ponzi, Contatinho Ekbomba, Rondero Miguel and an adult goanna. Assisted by Schalama Rei Delas, Samorbum and Ell Rugalzawer.",
@@ -2339,7 +2339,7 @@ func TestNumber4(t *testing.T) {
Assists: []Killers{},
Killers: []Killers{
{Name: "Kaelsia Menardord", Player: true, Traded: false, Summon: ""},
- {Name: "a skeleton elite warrior", Player: false, Traded: false, Summon: ""},
+ {Name: "skeleton elite warrior", Player: false, Traded: false, Summon: ""},
},
Level: 228,
Reason: "Killed at Level 228 by Kaelsia Menardord and a skeleton elite warrior.",
@@ -2352,7 +2352,7 @@ func TestNumber4(t *testing.T) {
{Name: "Netozawer", Player: true, Traded: false, Summon: ""},
},
Killers: []Killers{
- {Name: "a priestess of the wild sun", Player: false, Traded: false, Summon: ""},
+ {Name: "priestess of the wild sun", Player: false, Traded: false, Summon: ""},
},
Level: 229,
Reason: "Died at Level 229 by a priestess of the wild sun. Assisted by Mma Axel Mendoza, Caladan Bane and Netozawer.",
@@ -2712,7 +2712,7 @@ func TestNumber4(t *testing.T) {
{Name: "Mapius Akuno", Player: true, Traded: false, Summon: ""},
{Name: "Don Ballusse", Player: true, Traded: false, Summon: ""},
{Name: "Netozawer", Player: true, Traded: false, Summon: ""},
- {Name: "Adam No Hands", Player: true, Traded: true, Summon: "a paladin familiar"},
+ {Name: "Adam No Hands", Player: true, Traded: true, Summon: "paladin familiar"},
},
Killers: []Killers{
{Name: "Nevin kyle", Player: true, Traded: false, Summon: ""},
@@ -3389,6 +3389,614 @@ func TestNumber13(t *testing.T) {
}
}
+func TestNumber14(t *testing.T) {
+ file, err := static.TestFiles.Open("testdata/characters/Nannorka.html")
+ if err != nil {
+ t.Fatalf("file opening error: %s", err)
+ }
+ defer file.Close()
+
+ data, err := io.ReadAll(file)
+ if err != nil {
+ t.Fatalf("File reading error: %s", err)
+ }
+
+ characterJson, err := TibiaCharactersCharacterImpl(string(data), "")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ assert := assert.New(t)
+ character := characterJson.Character.CharacterInfo
+
+ assert.Equal("Nannorka", character.Name)
+ assert.False(characterJson.Character.DeathsTruncated)
+
+ // validate death data
+ assert.Equal(35, len(characterJson.Character.Deaths))
+ deaths := characterJson.Character.Deaths
+
+ for idx, tc := range []struct {
+ Assists []Killers
+ Killers []Killers
+ Level int
+ Reason string
+ Time string
+ }{
+ {
+ Assists: []Killers{
+ {Name: "Miquudalajarab", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Miquudalajarab.",
+ Time: "2025-02-27T16:20:06Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Satashi Xuuu", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 791,
+ Reason: "Killed at Level 791 by Satashi Xuuu.",
+ Time: "2025-02-27T03:46:47Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Basilicata", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Basilicata.",
+ Time: "2025-02-25T14:11:42Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Tainerd Ruero", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Tainerd Ruero.",
+ Time: "2025-02-15T10:35:03Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Miquudalajarab", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Miquudalajarab.",
+ Time: "2025-02-15T09:45:37Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Basilicata", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Basilicata.",
+ Time: "2025-02-14T16:56:53Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Satashi Xuuu", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 826,
+ Reason: "Killed at Level 826 by Satashi Xuuu.",
+ Time: "2025-02-14T14:56:33Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Miquudalajarab", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Miquudalajarab.",
+ Time: "2025-02-14T13:24:43Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Miquudalajarab", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Miquudalajarab.",
+ Time: "2025-02-14T08:19:51Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Miquudalajarab", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Miquudalajarab.",
+ Time: "2025-02-12T19:38:28Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Tikozera To Calmo", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Tikozera To Calmo.",
+ Time: "2025-02-12T17:37:04Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Basilicata", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Basilicata.",
+ Time: "2025-02-12T17:02:27Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Du nken", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Du nken.",
+ Time: "2025-02-12T16:56:42Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Satashi Xuuu", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 878,
+ Reason: "Killed at Level 878 by Satashi Xuuu.",
+ Time: "2025-02-11T20:00:44Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Basilicata", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Basilicata.",
+ Time: "2025-02-11T16:21:46Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Whiskin", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Whiskin.",
+ Time: "2025-02-11T16:18:28Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Fjunkes", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Fjunkes.",
+ Time: "2025-02-11T16:16:29Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Fjunkes", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Fjunkes.",
+ Time: "2025-02-10T14:57:44Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Whiskin", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Whiskin.",
+ Time: "2025-02-10T14:55:03Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Kaos Mest", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Kaos Mest.",
+ Time: "2025-02-09T12:13:57Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Whiskin", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Whiskin.",
+ Time: "2025-02-09T10:26:48Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Miquudalajarab", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Miquudalajarab.",
+ Time: "2025-02-09T10:09:39Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Guzik Szef", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Guzik Szef.",
+ Time: "2025-02-09T10:06:43Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Whiskin", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Whiskin.",
+ Time: "2025-02-08T18:06:49Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Shensz Khalifa", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Shensz Khalifa.",
+ Time: "2025-02-08T09:19:19Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Taiimo", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Taiimo.",
+ Time: "2025-02-07T17:13:05Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Shensz Khalifa", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Shensz Khalifa.",
+ Time: "2025-02-06T17:51:50Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Miquudalajarab", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Miquudalajarab.",
+ Time: "2025-02-06T17:50:03Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Taiimo", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Taiimo.",
+ Time: "2025-02-06T17:15:54Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Sephea", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 1007,
+ Reason: "Killed at Level 1007 by Sephea.",
+ Time: "2025-02-05T17:03:08Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Satashi Xuuu", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 1016,
+ Reason: "Killed at Level 1016 by Satashi Xuuu.",
+ Time: "2025-02-04T03:42:41Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Rodmago Aesir", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Rodmago Aesir.",
+ Time: "2025-02-03T16:14:53Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Zain Malek", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Zain Malek.",
+ Time: "2025-02-02T10:19:05Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Itzz Xed", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 1042,
+ Reason: "Killed at Level 1042 by Itzz Xed.",
+ Time: "2025-02-02T10:17:25Z",
+ },
+ {
+ Assists: []Killers{
+ {Name: "Rauxzin", Player: true, Traded: false, Summon: ""},
+ },
+ Killers: []Killers{},
+ Reason: "Assisted by Rauxzin.",
+ Time: "2025-02-02T10:11:07Z",
+ },
+ } {
+ assert.True(
+ reflect.DeepEqual(deaths[idx].Assists, tc.Assists),
+ "Wrong assists\nidx: %d\nwant: %#v\n\ngot: %#v",
+ idx, tc.Assists, deaths[idx].Assists,
+ )
+ assert.True(
+ reflect.DeepEqual(deaths[idx].Killers, tc.Killers),
+ "Wrong killers\nidx: %d\nwant: %#v\n\ngot: %#v",
+ idx, tc.Killers, deaths[idx].Killers,
+ )
+ assert.Equal(
+ deaths[idx].Level, tc.Level,
+ "Wrong Level\nidx: %d\nwant: %d\n\ngot: %d",
+ idx, tc.Level, deaths[idx].Level,
+ )
+ assert.Equal(
+ deaths[idx].Reason, tc.Reason,
+ "Wrong Reason\nidx: %d\nwant: %s\n\ngot: %s",
+ idx, tc.Reason, deaths[idx].Reason,
+ )
+ assert.Equal(
+ tc.Time, deaths[idx].Time,
+ "Wrong Time\nidx: %d\nwant: %s\n\ngot: %s",
+ idx, tc.Time, deaths[idx].Time,
+ )
+ }
+}
+
+func TestNumber15(t *testing.T) {
+ file, err := static.TestFiles.Open("testdata/characters/Sir Dumbas.html")
+ if err != nil {
+ t.Fatalf("file opening error: %s", err)
+ }
+ defer file.Close()
+
+ data, err := io.ReadAll(file)
+ if err != nil {
+ t.Fatalf("File reading error: %s", err)
+ }
+
+ characterJson, err := TibiaCharactersCharacterImpl(string(data), "")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ assert := assert.New(t)
+ character := characterJson.Character.CharacterInfo
+
+ assert.Equal("Sir Dumbas", character.Name)
+ assert.False(characterJson.Character.DeathsTruncated)
+
+ // validate death data
+ assert.Equal(3, len(characterJson.Character.Deaths))
+ deaths := characterJson.Character.Deaths
+
+ for idx, tc := range []struct {
+ Assists []Killers
+ Killers []Killers
+ Level int
+ Reason string
+ Time string
+ }{
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Corruption Toxic", Player: true, Traded: false, Summon: "fire elemental"},
+ },
+ Level: 43,
+ Reason: "Killed at Level 43 by fire elemental of Corruption Toxic.",
+ Time: "2025-02-02T23:08:13Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "cave rat", Player: false, Traded: false, Summon: ""},
+ },
+ Level: 44,
+ Reason: "Died at Level 44 by cave rat.",
+ Time: "2025-02-02T22:47:32Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "cave rat", Player: false, Traded: false, Summon: ""},
+ },
+ Level: 45,
+ Reason: "Died at Level 45 by cave rat.",
+ Time: "2025-02-02T22:46:11Z",
+ },
+ } {
+ assert.True(
+ reflect.DeepEqual(deaths[idx].Assists, tc.Assists),
+ "Wrong assists\nidx: %d\nwant: %#v\n\ngot: %#v",
+ idx, tc.Assists, deaths[idx].Assists,
+ )
+ assert.True(
+ reflect.DeepEqual(deaths[idx].Killers, tc.Killers),
+ "Wrong killers\nidx: %d\nwant: %#v\n\ngot: %#v",
+ idx, tc.Killers, deaths[idx].Killers,
+ )
+ assert.Equal(
+ deaths[idx].Level, tc.Level,
+ "Wrong Level\nidx: %d\nwant: %d\n\ngot: %d",
+ idx, tc.Level, deaths[idx].Level,
+ )
+ assert.Equal(
+ deaths[idx].Reason, tc.Reason,
+ "Wrong Reason\nidx: %d\nwant: %s\n\ngot: %s",
+ idx, tc.Reason, deaths[idx].Reason,
+ )
+ assert.Equal(
+ tc.Time, deaths[idx].Time,
+ "Wrong Time\nidx: %d\nwant: %s\n\ngot: %s",
+ idx, tc.Time, deaths[idx].Time,
+ )
+ }
+}
+
+func TestNumber16(t *testing.T) {
+ file, err := static.TestFiles.Open("testdata/characters/Sergiozk.html")
+ if err != nil {
+ t.Fatalf("file opening error: %s", err)
+ }
+ defer file.Close()
+
+ data, err := io.ReadAll(file)
+ if err != nil {
+ t.Fatalf("File reading error: %s", err)
+ }
+
+ characterJson, err := TibiaCharactersCharacterImpl(string(data), "")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ assert := assert.New(t)
+ character := characterJson.Character.CharacterInfo
+
+ assert.Equal("Sergiozk", character.Name)
+ assert.False(characterJson.Character.DeathsTruncated)
+
+ // validate death data
+ assert.Equal(6, len(characterJson.Character.Deaths))
+ deaths := characterJson.Character.Deaths
+
+ for idx, tc := range []struct {
+ Assists []Killers
+ Killers []Killers
+ Level int
+ Reason string
+ Time string
+ }{
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Phelip On Danera", Player: true, Traded: false, Summon: ""},
+ {Name: "fire elemental", Player: false, Traded: false, Summon: ""},
+ },
+ Level: 597,
+ Reason: "Killed at Level 597 by Phelip On Danera and fire elemental.",
+ Time: "2024-03-17T04:47:32Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Phelip On Danera", Player: true, Traded: false, Summon: ""},
+ {Name: "Indio Pedibrek", Player: true, Traded: false, Summon: ""},
+ {Name: "Guillera", Player: true, Traded: false, Summon: ""},
+ {Name: "Sago Dashzik", Player: true, Traded: false, Summon: ""},
+ {Name: "Spectrum on Ferobra", Player: true, Traded: false, Summon: ""},
+ {Name: "Hawker Destroyer", Player: true, Traded: false, Summon: ""},
+ {Name: "Lenuzera Dushow", Player: true, Traded: false, Summon: ""},
+ {Name: "Migurina", Player: true, Traded: false, Summon: ""},
+ {Name: "Zofia Bosak", Player: true, Traded: false, Summon: ""},
+ {Name: "Lekinho Destroyer", Player: true, Traded: false, Summon: ""},
+ {Name: "Sergiozk", Player: true, Traded: false, Summon: ""},
+ {Name: "Zeqs", Player: true, Traded: false, Summon: ""},
+ {Name: "Durantezika", Player: true, Traded: false, Summon: ""},
+ {Name: "Maxionz", Player: true, Traded: true, Summon: ""},
+ {Name: "Axmc", Player: true, Traded: false, Summon: ""},
+ {Name: "Luan Chriistiian", Player: true, Traded: true, Summon: ""},
+ {Name: "Utv", Player: true, Traded: false, Summon: ""},
+ {Name: "Duzym", Player: true, Traded: false, Summon: ""},
+ {Name: "Wizz Gigi", Player: true, Traded: false, Summon: ""},
+ {Name: "Kan Zinho", Player: true, Traded: false, Summon: ""},
+ {Name: "Yuyo", Player: true, Traded: false, Summon: ""},
+ {Name: "skeleton elite warrior", Player: false, Traded: false, Summon: ""},
+ },
+ Level: 597,
+ Reason: "Annihilated at Level 597 by Phelip On Danera, Indio Pedibrek, Guillera, Sago Dashzik, Spectrum on Ferobra, Hawker Destroyer, Lenuzera Dushow, Migurina, Zofia Bosak, Lekinho Destroyer, Sergiozk, Zeqs, Durantezika, Maxionz (traded), Axmc, Luan Chriistiian (traded), Utv, Duzym, Wizz Gigi, Kan Zinho, Yuyo and skeleton elite warrior.",
+ Time: "2024-03-17T04:32:23Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Phelip On Danera", Player: true, Traded: false, Summon: ""},
+ {Name: "Indio Pedibrek", Player: true, Traded: false, Summon: ""},
+ {Name: "Guillera", Player: true, Traded: false, Summon: ""},
+ {Name: "Sago Dashzik", Player: true, Traded: false, Summon: ""},
+ {Name: "Hawker Destroyer", Player: true, Traded: false, Summon: ""},
+ {Name: "Lenuzera Dushow", Player: true, Traded: false, Summon: ""},
+ {Name: "Zofia Bosak", Player: true, Traded: false, Summon: ""},
+ {Name: "Zeh da Mannga", Player: true, Traded: false, Summon: ""},
+ {Name: "Maxionz", Player: true, Traded: true, Summon: ""},
+ {Name: "Luan Chriistiian", Player: true, Traded: true, Summon: ""},
+ {Name: "Utv", Player: true, Traded: false, Summon: ""},
+ {Name: "Wizz Gigi", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 597,
+ Reason: "Crushed at Level 597 by Phelip On Danera, Indio Pedibrek, Guillera, Sago Dashzik, Hawker Destroyer, Lenuzera Dushow, Zofia Bosak, Zeh da Mannga, Maxionz (traded), Luan Chriistiian (traded), Utv and Wizz Gigi.",
+ Time: "2024-03-17T04:26:44Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Moon Warlock", Player: true, Traded: false, Summon: ""},
+ {Name: "Manglu", Player: true, Traded: false, Summon: ""},
+ {Name: "Dudodix", Player: true, Traded: false, Summon: ""},
+ {Name: "Luchador", Player: true, Traded: false, Summon: ""},
+ {Name: "King Madara", Player: true, Traded: false, Summon: ""},
+ {Name: "Masstterpali", Player: true, Traded: false, Summon: ""},
+ {Name: "Gilbas Concursado", Player: true, Traded: false, Summon: ""},
+ {Name: "Cafezinhum", Player: true, Traded: false, Summon: ""},
+ {Name: "Antipuush", Player: true, Traded: false, Summon: ""},
+ },
+ Level: 597,
+ Reason: "Slain at Level 597 by Moon Warlock, Manglu, Dudodix, Luchador, King Madara, Masstterpali, Gilbas Concursado, Cafezinhum and Antipuush.",
+ Time: "2024-03-15T13:02:38Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "crazed summer rearguard", Player: false, Traded: false, Summon: ""},
+ },
+ Level: 598,
+ Reason: "Died at Level 598 by crazed summer rearguard.",
+ Time: "2024-03-11T06:21:25Z",
+ },
+ {
+ Assists: []Killers{},
+ Killers: []Killers{
+ {Name: "Irynn", Player: true, Traded: false, Summon: ""},
+ {Name: "Indio Pedibrek", Player: true, Traded: false, Summon: ""},
+ {Name: "Tenoriio Rex", Player: true, Traded: false, Summon: ""},
+ {Name: "Pitucola", Player: true, Traded: false, Summon: ""},
+ {Name: "Lekinho Destroyer", Player: true, Traded: false, Summon: ""},
+ {Name: "Sergiozk", Player: true, Traded: false, Summon: ""},
+ {Name: "Aperninha de grilo", Player: true, Traded: false, Summon: ""},
+ {Name: "Bino Pally Rox", Player: true, Traded: false, Summon: ""},
+ {Name: "Experience Hunter", Player: true, Traded: false, Summon: ""},
+ {Name: "Lohana Darkside", Player: true, Traded: false, Summon: ""},
+ {Name: "Flavzk", Player: true, Traded: true, Summon: ""},
+ {Name: "Fllockyy", Player: true, Traded: false, Summon: "paladin familiar"},
+ },
+ Level: 597,
+ Reason: "Crushed at Level 597 by Irynn, Indio Pedibrek, Tenoriio Rex, Pitucola, Lekinho Destroyer, Sergiozk, Aperninha de grilo, Bino Pally Rox, Experience Hunter, Lohana Darkside, Flavzk (traded) and paladin familiar of Fllockyy.",
+ Time: "2024-03-10T14:49:27Z",
+ },
+ } {
+ assert.True(
+ reflect.DeepEqual(deaths[idx].Assists, tc.Assists),
+ "Wrong assists\nidx: %d\nwant: %#v\n\ngot: %#v",
+ idx, tc.Assists, deaths[idx].Assists,
+ )
+ assert.True(
+ reflect.DeepEqual(deaths[idx].Killers, tc.Killers),
+ "Wrong killers\nidx: %d\nwant: %#v\n\ngot: %#v",
+ idx, tc.Killers, deaths[idx].Killers,
+ )
+ assert.Equal(
+ deaths[idx].Level, tc.Level,
+ "Wrong Level\nidx: %d\nwant: %d\n\ngot: %d",
+ idx, tc.Level, deaths[idx].Level,
+ )
+ assert.Equal(
+ deaths[idx].Reason, tc.Reason,
+ "Wrong Reason\nidx: %d\nwant: %s\n\ngot: %s",
+ idx, tc.Reason, deaths[idx].Reason,
+ )
+ assert.Equal(
+ tc.Time, deaths[idx].Time,
+ "Wrong Time\nidx: %d\nwant: %s\n\ngot: %s",
+ idx, tc.Time, deaths[idx].Time,
+ )
+ }
+}
+
func BenchmarkNumber1(b *testing.B) {
file, err := static.TestFiles.Open("testdata/characters/Darkside Rafa.html")
if err != nil {
diff --git a/src/static/testdata/characters/Nannorka.html b/src/static/testdata/characters/Nannorka.html
new file mode 100644
index 00000000..f13c98c9
--- /dev/null
+++ b/src/static/testdata/characters/Nannorka.html
@@ -0,0 +1,813 @@
+
+
+
+
+ Tibia - Free Multiplayer Online Role Playing Game - Community
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
NO - internet explorer
+
NEW - internet explorer
+
OLD - internet explorer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Name: Nannorka
Title: None (26 titles unlocked) Sex: male Vocation: Royal Paladin Level: 778 Achievement Points: 401 World: Retalia Former World: Obscubra Residence: Kazordoon Guild Membership: Main of the Retro Delusion Last Login: Mar 03 2025, 18:05:32 CET Account Status: Premium Account
There are no account badges set to be displayed for this character.
There are no achievements set to be displayed for this character.
Feb 27 2025, 17:20:06 CET Assisted by Miquudalajarab . Feb 27 2025, 04:46:47 CET Killed at Level 791 by Satashi Xuuu . Feb 25 2025, 15:11:42 CET Assisted by Basilicata . Feb 15 2025, 11:35:03 CET Assisted by Tainerd Ruero . Feb 15 2025, 10:45:37 CET Assisted by Miquudalajarab . Feb 14 2025, 17:56:53 CET Assisted by Basilicata . Feb 14 2025, 15:56:33 CET Killed at Level 826 by Satashi Xuuu . Feb 14 2025, 14:24:43 CET Assisted by Miquudalajarab . Feb 14 2025, 09:19:51 CET Assisted by Miquudalajarab . Feb 12 2025, 20:38:28 CET Assisted by Miquudalajarab . Feb 12 2025, 18:37:04 CET Assisted by Tikozera To Calmo . Feb 12 2025, 18:02:27 CET Assisted by Basilicata . Feb 12 2025, 17:56:42 CET Assisted by Du nken . Feb 11 2025, 21:00:44 CET Killed at Level 878 by Satashi Xuuu . Feb 11 2025, 17:21:46 CET Assisted by Basilicata . Feb 11 2025, 17:18:28 CET Assisted by Whiskin . Feb 11 2025, 17:16:29 CET Assisted by Fjunkes . Feb 10 2025, 15:57:44 CET Assisted by Fjunkes . Feb 10 2025, 15:55:03 CET Assisted by Whiskin . Feb 09 2025, 13:13:57 CET Assisted by Kaos Mest . Feb 09 2025, 11:26:48 CET Assisted by Whiskin . Feb 09 2025, 11:09:39 CET Assisted by Miquudalajarab . Feb 09 2025, 11:06:43 CET Assisted by Guzik Szef . Feb 08 2025, 19:06:49 CET Assisted by Whiskin . Feb 08 2025, 10:19:19 CET Assisted by Shensz Khalifa . Feb 07 2025, 18:13:05 CET Assisted by Taiimo . Feb 06 2025, 18:51:50 CET Assisted by Shensz Khalifa . Feb 06 2025, 18:50:03 CET Assisted by Miquudalajarab . Feb 06 2025, 18:15:54 CET Assisted by Taiimo . Feb 05 2025, 18:03:08 CET Killed at Level 1007 by Sephea . Feb 04 2025, 04:42:41 CET Killed at Level 1016 by Satashi Xuuu . Feb 03 2025, 17:14:53 CET Assisted by Rodmago Aesir . Feb 02 2025, 11:19:05 CET Assisted by Zain Malek . Feb 02 2025, 11:17:25 CET Killed at Level 1042 by Itzz Xed . Feb 02 2025, 11:11:07 CET Assisted by Rauxzin .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/static/testdata/characters/Sergiozk.html b/src/static/testdata/characters/Sergiozk.html
new file mode 100644
index 00000000..84db7b3c
--- /dev/null
+++ b/src/static/testdata/characters/Sergiozk.html
@@ -0,0 +1,779 @@
+
+
+
+
+Tibia - Free Multiplayer Online Role Playing Game - Community
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
NO - internet explorer
+
NEW - internet explorer
+
OLD - internet explorer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Name: Sergiozk
Title: Time Traveller (21 titles unlocked) Sex: male Vocation: Elder Druid Level: 601 Achievement Points: 370 World: Havera Former World: Ferobra Residence: Thais Last Login: Apr 09 2024, 05:10:18 CEST Account Status: Premium Account
There are no achievements set to be displayed for this character.
Mar 17 2024, 05:47:32 CET Killed at Level 597 by Phelip On Danera and fire elemental. Mar 17 2024, 05:32:23 CET Annihilated at Level 597 by Phelip On Danera , Indio Pedibrek , Guillera , Sago Dashzik , Spectrum on Ferobra , Hawker Destroyer , Lenuzera Dushow , Migurina , Zofia Bosak , Lekinho Destroyer , Sergiozk , Zeqs , Durantezika , Maxionz (traded), Axmc , Luan Chriistiian (traded), Utv , Duzym , Wizz Gigi , Kan Zinho , Yuyo and skeleton elite warrior. Mar 17 2024, 05:26:44 CET Crushed at Level 597 by Phelip On Danera , Indio Pedibrek , Guillera , Sago Dashzik , Hawker Destroyer , Lenuzera Dushow , Zofia Bosak , Zeh da Mannga , Maxionz (traded), Luan Chriistiian (traded), Utv and Wizz Gigi . Mar 15 2024, 14:02:38 CET Slain at Level 597 by Moon Warlock , Manglu , Dudodix , Luchador , King Madara , Masstterpali , Gilbas Concursado , Cafezinhum and Antipuush . Mar 11 2024, 07:21:25 CET Died at Level 598 by crazed summer rearguard. Mar 10 2024, 15:49:27 CET Crushed at Level 597 by Irynn , Indio Pedibrek , Tenoriio Rex , Pitucola , Lekinho Destroyer , Sergiozk , Aperninha de grilo , Bino Pally Rox , Experience Hunter , Lohana Darkside , Flavzk (traded) and paladin familiar of Fllockyy .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Our website makes use of cookies (sadly not the delicious, crumbly ones) and similar technologies. If you accept them, we share information with our partners for social media, advertising and analysis.
Please let us know which cookies we can use.
+
diff --git a/src/static/testdata/characters/Sir Dumbas.html b/src/static/testdata/characters/Sir Dumbas.html
new file mode 100644
index 00000000..8bfdb7ca
--- /dev/null
+++ b/src/static/testdata/characters/Sir Dumbas.html
@@ -0,0 +1,813 @@
+
+
+
+
+ Tibia - Free Multiplayer Online Role Playing Game - Community
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
NO - internet explorer
+
NEW - internet explorer
+
OLD - internet explorer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Name: Sir Dumbas
Title: None (3 titles unlocked) Sex: male Vocation: Master Sorcerer Level: 50 Achievement Points: 5 World: Quidera Residence: Port Hope Guild Membership: Warloyal of the Loyalty Last Login: Mar 01 2025, 23:21:26 CET Comment: TB4c9a6ac59b68fef40734cffc3b507ed7 Account Status: Premium Account
There are no achievements set to be displayed for this character.
Feb 03 2025, 00:08:13 CET Killed at Level 43 by fire elemental of Corruption Toxic . Feb 02 2025, 23:47:32 CET Died at Level 44 by cave rat. Feb 02 2025, 23:46:11 CET Died at Level 45 by cave rat.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy