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
+
+ +
+
+
+ +
+
+ Monster Pedestal Box
Boosted CreatureBoosted Boss
+ +
+
+
+
+
Contentbox headline +
+
+
+
Character Information
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


Account Badges
There are no account badges set to be displayed for this character.


Account Achievements
There are no achievements set to be displayed for this character.


Character Deaths
Feb 27 2025, 17:20:06 CETAssisted by Miquudalajarab.
Feb 27 2025, 04:46:47 CETKilled at Level 791 by Satashi Xuuu.
Feb 25 2025, 15:11:42 CETAssisted by Basilicata.
Feb 15 2025, 11:35:03 CETAssisted by Tainerd Ruero.
Feb 15 2025, 10:45:37 CETAssisted by Miquudalajarab.
Feb 14 2025, 17:56:53 CETAssisted by Basilicata.
Feb 14 2025, 15:56:33 CETKilled at Level 826 by Satashi Xuuu.
Feb 14 2025, 14:24:43 CETAssisted by Miquudalajarab.
Feb 14 2025, 09:19:51 CETAssisted by Miquudalajarab.
Feb 12 2025, 20:38:28 CETAssisted by Miquudalajarab.
Feb 12 2025, 18:37:04 CETAssisted by Tikozera To Calmo.
Feb 12 2025, 18:02:27 CETAssisted by Basilicata.
Feb 12 2025, 17:56:42 CETAssisted by Du nken.
Feb 11 2025, 21:00:44 CETKilled at Level 878 by Satashi Xuuu.
Feb 11 2025, 17:21:46 CETAssisted by Basilicata.
Feb 11 2025, 17:18:28 CETAssisted by Whiskin.
Feb 11 2025, 17:16:29 CETAssisted by Fjunkes.
Feb 10 2025, 15:57:44 CETAssisted by Fjunkes.
Feb 10 2025, 15:55:03 CETAssisted by Whiskin.
Feb 09 2025, 13:13:57 CETAssisted by Kaos Mest.
Feb 09 2025, 11:26:48 CETAssisted by Whiskin.
Feb 09 2025, 11:09:39 CETAssisted by Miquudalajarab.
Feb 09 2025, 11:06:43 CETAssisted by Guzik Szef.
Feb 08 2025, 19:06:49 CETAssisted by Whiskin.
Feb 08 2025, 10:19:19 CETAssisted by Shensz Khalifa.
Feb 07 2025, 18:13:05 CETAssisted by Taiimo.
Feb 06 2025, 18:51:50 CETAssisted by Shensz Khalifa.
Feb 06 2025, 18:50:03 CETAssisted by Miquudalajarab.
Feb 06 2025, 18:15:54 CETAssisted by Taiimo.
Feb 05 2025, 18:03:08 CETKilled at Level 1007 by Sephea.
Feb 04 2025, 04:42:41 CETKilled at Level 1016 by Satashi Xuuu.
Feb 03 2025, 17:14:53 CETAssisted by Rodmago Aesir.
Feb 02 2025, 11:19:05 CETAssisted by Zain Malek.
Feb 02 2025, 11:17:25 CETKilled at Level 1042 by Itzz Xed.
Feb 02 2025, 11:11:07 CETAssisted by Rauxzin.


Search Character
Character Name:
+
+
+
+
+
+
+ +
+
+
+

Trade Tibia Coins!

+
+ +
+
+ +
+ + +
+
+ + +
+
+ +
+ +
+
+
+
+ +

+ 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
+
+
+
+
+ +
+
+Monster Pedestal Box
Boosted CreatureBoosted Boss
+
+
+
+
+
Contentbox headline +
+
+
+
Character Information
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


Account Achievements
There are no achievements set to be displayed for this character.


Character Deaths
Mar 17 2024, 05:47:32 CETKilled at Level 597 by Phelip On Danera and fire elemental.
Mar 17 2024, 05:32:23 CETAnnihilated 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 CETCrushed 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 CETSlain at Level 597 by Moon Warlock, Manglu, Dudodix, Luchador, King Madara, Masstterpali, Gilbas Concursado, Cafezinhum and Antipuush.
Mar 11 2024, 07:21:25 CETDied at Level 598 by crazed summer rearguard.
Mar 10 2024, 15:49:27 CETCrushed 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.


Search Character
Character Name:
+
+
+
+
+
+
+ +
+
+
+

Buy Epic Decoration!

+
+
+ +
+ +
+
+
+
+ +
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.
Manage Cookies

Necessary

These cookies are required in order for our website to function (e.g. logging in). If you set your browser to block or alert you about these cookies, some parts of the website might not work.

Targeting and Advertising

Advertisers and other content providers that may appear on our website may also use cookies that are not sent by us. Such advertisements or content may use cookies to help track and target the interests of users of the website to present customised and personalised advertisements or other messages that the user might find interesting. We also use these cookies and so-called Tracking Pixels of our partners to measure and improve the effectiveness of marketing campaigns. (Facebook Tracking Pixel)

Social Media

These cookies enable the website to provide enhanced functionality and personalisation. They may be set by third-party providers (like social networks or streaming platforms) whose services we use on the website. If you do not allow these cookies, some or all of these services may not function properly. (Twitter, YouTube, Facebook)


+ 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
+
+ +
+
+
+ +
+
+ Monster Pedestal Box
Boosted CreatureBoosted Boss
+ +
+
+
+
+
Contentbox headline +
+
+
+
Character Information
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


Account Achievements
There are no achievements set to be displayed for this character.


Character Deaths
Feb 03 2025, 00:08:13 CETKilled at Level 43 by fire elemental of Corruption Toxic.
Feb 02 2025, 23:47:32 CETDied at Level 44 by cave rat.
Feb 02 2025, 23:46:11 CETDied at Level 45 by cave rat.


Search Character
Character Name:
+
+
+
+
+
+
+ +
+
+
+

Use XP Boosts!

+
+ +
+
+ +
+ + +
+
+ + +
+
+ +
+ +
+
+
+
+ +

+ 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