Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
T
tx3-bang-reader
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
tx3-bang-reader
Commits
d1bc3354
Commit
d1bc3354
authored
Jul 01, 2020
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
playerlist
parent
14a74aae
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
221 additions
and
105 deletions
+221
-105
src/fetcher.ts
src/fetcher.ts
+1
-1
src/playerlist.ts
src/playerlist.ts
+54
-0
src/user.ts
src/user.ts
+18
-104
src/utility.ts
src/utility.ts
+148
-0
No files found.
src/fetcher.ts
View file @
d1bc3354
...
...
@@ -10,7 +10,7 @@ class Tx3Fetcher {
responseType
:
"
document
"
})).
data
;
const
parsedContent
=
parseHTML
(
content
);
return
new
User
(
id
,
content
);
return
new
User
(
id
,
content
,
null
);
/*} catch(e) {
console.error(`Errored fetching role data from ${id}: ${e.toString()}`);
return null;
...
...
src/playerlist.ts
0 → 100644
View file @
d1bc3354
import
HTML
from
"
posthtml-parser
"
;
import
_
,
{
first
}
from
"
underscore
"
;
import
{
getDepthOfTree
,
getNumber
,
findNodeIndex
,
findNodeIndexByAttribute
,
findNodeIndexByContent
,
findNodeIndexByTag
,
findAllNodeIndex
,
getContinuousData
,
getContinuousNodes
,
getString
}
from
"
./utility
"
;
export
interface
PlayerRow
{
url
:
string
;
rank
:
number
;
name
:
string
;
category
:
string
;
serverArea
:
string
;
server
:
string
;
level
:
number
;
region
:
string
;
score
:
number
;
equip
:
number
;
totalScore
:
number
;
}
function
getPlayerRowFromTree
(
tree
:
HTML
.
Tree
):
PlayerRow
{
const
nodes
=
getContinuousNodes
(
tree
,
[
1
],
0
,
2
,
10
);
return
{
url
:
(
nodes
[
1
]
as
HTML
.
NodeTag
).
attrs
.
href
as
string
,
rank
:
getNumber
(
nodes
[
0
]),
name
:
getString
(
nodes
[
1
]),
serverArea
:
getString
(
nodes
[
2
]),
server
:
getString
(
nodes
[
3
]),
level
:
getNumber
(
nodes
[
4
]),
category
:
getString
(
nodes
[
5
]),
region
:
getString
(
nodes
[
6
]),
score
:
getNumber
(
nodes
[
7
]),
equip
:
getNumber
(
nodes
[
8
]),
totalScore
:
getNumber
(
nodes
[
9
])
}
}
export
class
PlayerList
{
rows
:
PlayerRow
[];
private
parseRows
(
content
:
string
)
{
this
.
rows
=
[];
const
parsedContent
=
HTML
(
content
);
const
tablePos
=
findNodeIndexByTag
(
parsedContent
,
"
table
"
,
[]);
const
tableTree
=
getDepthOfTree
(
parsedContent
,
tablePos
);
const
playerPoses
=
findAllNodeIndex
(
tableTree
,
(
node
)
=>
{
return
typeof
(
node
)
!==
"
string
"
&&
node
.
tag
===
"
tr
"
&&
node
.
attrs
.
class
!==
"
trTop2
"
;
},
[]);
this
.
rows
=
playerPoses
.
map
(
pos
=>
{
const
tree
=
getDepthOfTree
(
tableTree
,
pos
);
return
getPlayerRowFromTree
(
tree
);
})
}
constructor
(
content
:
string
)
{
this
.
parseRows
(
content
);
}
}
src/user.ts
View file @
d1bc3354
import
HTML
from
"
posthtml-parser
"
;
import
_
,
{
first
}
from
"
underscore
"
;
import
{
getDepthOfTree
,
getNumber
,
findNodeIndex
,
findNodeIndexByAttribute
,
findNodeIndexByContent
,
findNodeIndexByTag
,
getContinuousNumber
}
from
"
./utility
"
;
function
getDepthOfTree
(
tree
:
HTML
.
Tree
,
indexList
:
number
[]):
HTML
.
Tree
{
if
(
indexList
.
length
)
{
const
_indexList
=
_
.
clone
(
indexList
);
const
index
=
_indexList
.
splice
(
0
,
1
)[
0
];
const
node
=
tree
[
index
];
if
(
typeof
(
node
)
===
"
string
"
||
!
node
.
content
)
{
return
[
node
];
}
return
getDepthOfTree
(
node
.
content
,
_indexList
);
}
else
{
return
tree
;
}
}
function
findNodeIndex
(
baseTree
:
HTML
.
Tree
,
condition
:
(
node
:
HTML
.
Node
)
=>
boolean
,
offset
:
number
[]):
number
[]
{
let
queue
=
[
offset
];
while
(
queue
.
length
)
{
const
indexList
=
queue
.
splice
(
0
,
1
)[
0
];
const
tree
=
getDepthOfTree
(
baseTree
,
indexList
);
for
(
let
i
=
0
;
i
<
tree
.
length
;
++
i
)
{
const
node
=
tree
[
i
];
const
newList
=
indexList
.
concat
([
i
]);
if
(
condition
(
node
))
{
//console.log(newList);
return
newList
;
}
else
if
(
typeof
(
node
)
!==
"
string
"
)
{
queue
.
push
(
newList
);
}
}
}
return
null
;
}
function
findNodeIndexByContent
(
baseTree
:
HTML
.
Tree
,
label
:
string
,
offset
:
number
[]):
number
[]
{
return
findNodeIndex
(
baseTree
,
(
node
)
=>
{
return
node
===
label
;
},
offset
);
}
function
findNodeIndexByAttribute
(
baseTree
:
HTML
.
Tree
,
key
:
string
,
value
:
string
,
offset
:
number
[]):
number
[]
{
return
findNodeIndex
(
baseTree
,
(
node
)
=>
{
return
typeof
(
node
)
!==
"
string
"
&&
node
.
attrs
&&
node
.
attrs
[
key
]
===
value
;
},
offset
);
}
function
findNodeIndexByTag
(
baseTree
:
HTML
.
Tree
,
tag
:
string
,
offset
:
number
[]):
number
[]
{
return
findNodeIndex
(
baseTree
,
(
node
)
=>
{
return
typeof
(
node
)
!==
"
string
"
&&
node
.
tag
===
tag
;
},
offset
);
}
const
chineseCapitalNumbers
=
[
"
零
"
,
"
壹
"
,
"
贰
"
,
"
叁
"
,
"
肆
"
,
"
伍
"
,
"
陆
"
,
"
柒
"
,
"
捌
"
,
"
玖
"
]
function
getNumber
(
node
:
HTML
.
Node
)
{
let
numberStr
:
string
;
if
(
typeof
(
node
)
===
"
string
"
)
{
numberStr
=
node
;
}
else
{
const
subTree
=
node
.
content
;
if
(
!
subTree
)
{
return
null
;
}
numberStr
=
subTree
[
0
]
as
string
;
}
numberStr
=
numberStr
.
trim
();
let
stringMatch
:
RegExpMatchArray
;
if
(
numberStr
===
"
没有上榜
"
)
{
return
null
;
}
else
if
(
stringMatch
=
numberStr
.
match
(
/^
([
天地
])
魂$/
))
{
return
stringMatch
[
1
]
===
"
天
"
?
2
:
1
;
}
else
if
(
stringMatch
=
numberStr
.
match
(
/^
(
.+
)
天
(
.+
)
境界$/
))
{
return
(
_
.
findIndex
(
chineseCapitalNumbers
,
(
m
)
=>
m
===
stringMatch
[
1
])
<<
8
)
|
_
.
findIndex
(
chineseCapitalNumbers
,
(
m
)
=>
m
===
stringMatch
[
2
]);
}
else
if
(
stringMatch
=
numberStr
.
match
(
/^
(\d
+
)
-
(\d
+
)
$/
))
{
const
minValue
=
parseInt
(
stringMatch
[
1
]);
const
maxValue
=
parseInt
(
stringMatch
[
2
]);
return
(
minValue
<<
16
)
|
maxValue
;
}
else
{
return
parseInt
(
numberStr
);
}
}
interface
AttackAttribute
{
export
interface
AttackAttribute
{
'
攻力
'
:
number
,
//大攻取前2字节int16,小攻取后2字节int16,法力也是这样
'
命中
'
:
number
,
'
法力
'
:
number
,
...
...
@@ -91,7 +12,7 @@ interface AttackAttribute {
'
附加伤害
'
:
number
}
interface
DefenseAttribute
{
export
interface
DefenseAttribute
{
'
防御
'
:
number
,
'
回避
'
:
number
,
'
法防
'
:
number
,
...
...
@@ -100,7 +21,7 @@ interface DefenseAttribute {
'
知彼
'
:
number
}
interface
SpecialAttribute
{
export
interface
SpecialAttribute
{
'
身法
'
:
number
,
'
坚韧
'
:
number
,
'
定力
'
:
number
,
...
...
@@ -110,12 +31,13 @@ interface SpecialAttribute {
'
铁壁
'
:
number
}
interface
AdvancedAttribute
{
'
追电
'
:
number
,
'
骤雨
'
:
number
,
'
疾语
'
:
number
,
'
明思
'
:
number
,
'
扰心
'
:
number
,
'
人祸
'
:
number
}
export
interface
AdvancedAttribute
{
'
追电
'
:
number
,
'
骤雨
'
:
number
,
'
疾语
'
:
number
,
'
明思
'
:
number
,
'
扰心
'
:
number
,
'
人祸
'
:
number
}
export
class
User
{
id
:
string
;
content
:
HTML
.
Tree
;
name
:
string
;
region
:
string
;
category
:
string
;
serverArea
:
string
;
server
:
string
;
...
...
@@ -145,17 +67,8 @@ export class User {
specialAttributes
:
SpecialAttribute
;
advancedAttributes
:
AdvancedAttribute
;
yhz
:
string
[];
getContinuousData
(
_pos
:
number
[],
moveOffset
:
number
,
step
:
number
,
dataCount
:
number
):
number
[]
{
const
pos
=
_
.
clone
(
_pos
);
const
datas
:
number
[]
=
[];
for
(
let
i
=
0
;
i
<
dataCount
;
++
i
)
{
const
node
=
getDepthOfTree
(
this
.
content
,
pos
)[
0
];
datas
.
push
(
getNumber
(
node
))
pos
[
pos
.
length
-
(
moveOffset
+
1
)]
+=
step
;
}
return
datas
;
}
parseMetadata
()
{
private
parseMetadata
()
{
let
namePos
=
findNodeIndexByAttribute
(
this
.
content
,
"
class
"
,
"
sTitle
"
,
[]);
this
.
name
=
getDepthOfTree
(
this
.
content
,
namePos
.
concat
([
0
]))[
0
]
as
string
;
namePos
[
namePos
.
length
-
1
]
+=
2
;
...
...
@@ -168,11 +81,11 @@ export class User {
levelPos
[
levelPos
.
length
-
1
]
++
;
this
.
level
=
getNumber
(
getDepthOfTree
(
this
.
content
,
levelPos
)[
0
]);
}
parseEquipmentData
()
{
p
rivate
p
arseEquipmentData
()
{
let
ValuePos
=
findNodeIndexByContent
(
this
.
content
,
"
装备评价:
"
,
[]);
ValuePos
.
pop
();
ValuePos
[
ValuePos
.
length
-
1
]
++
;
let
datas
=
this
.
getContinuousData
(
ValuePos
,
1
,
2
,
4
);
let
datas
=
getContinuousNumber
(
this
.
content
,
ValuePos
,
1
,
2
,
4
);
this
.
equipValue
=
datas
[
0
];
this
.
equipRank
=
datas
[
1
];
this
.
equipLocalRank
=
datas
[
2
];
...
...
@@ -181,7 +94,7 @@ export class User {
ValuePos
=
findNodeIndexByContent
(
this
.
content
,
"
人物修为:
"
,
[]);
ValuePos
.
pop
();
ValuePos
[
ValuePos
.
length
-
1
]
++
;
datas
=
this
.
getContinuousData
(
ValuePos
,
1
,
2
,
8
);
datas
=
getContinuousNumber
(
this
.
content
,
ValuePos
,
1
,
2
,
8
);
this
.
scoreValue
=
datas
[
0
];
this
.
scoreRank
=
datas
[
1
];
this
.
scoreLocalRank
=
datas
[
2
];
...
...
@@ -191,7 +104,7 @@ export class User {
this
.
qhLevel
=
datas
[
6
];
this
.
tlPoints
=
datas
[
7
];
}
parseAttributeTable
(
_pos
:
number
[]):
any
{
p
rivate
p
arseAttributeTable
(
_pos
:
number
[]):
any
{
const
ret
=
{};
const
pos
=
_
.
clone
(
_pos
);
const
tree
=
getDepthOfTree
(
this
.
content
,
pos
);
...
...
@@ -204,11 +117,11 @@ export class User {
}
return
ret
;
}
parseBasicAttributes
()
{
p
rivate
p
arseBasicAttributes
()
{
let
ValuePos
=
findNodeIndexByContent
(
this
.
content
,
"
命
"
,
[]);
ValuePos
.
pop
();
ValuePos
[
ValuePos
.
length
-
1
]
+=
2
;
const
datas
=
this
.
getContinuousData
(
ValuePos
,
0
,
4
,
8
);
const
datas
=
getContinuousNumber
(
this
.
content
,
ValuePos
,
0
,
4
,
8
);
this
.
hp
=
datas
[
0
];
this
.
mp
=
datas
[
1
];
this
.
li
=
datas
[
2
];
...
...
@@ -229,7 +142,7 @@ export class User {
ValuePos
[
ValuePos
.
length
-
1
]
+=
2
;
this
.
advancedAttributes
=
this
.
parseAttributeTable
(
ValuePos
)
as
AdvancedAttribute
;
}
parseYHZ
()
{
p
rivate
p
arseYHZ
()
{
let
ValuePos
=
findNodeIndexByAttribute
(
this
.
content
,
"
id
"
,
"
tableYHZ
"
,
[]);
ValuePos
.
push
(
1
);
const
tree
=
getDepthOfTree
(
this
.
content
,
ValuePos
);
...
...
@@ -239,14 +152,15 @@ export class User {
this
.
yhz
.
push
(
node
.
content
[
0
]
as
string
);
}
}
parse
()
{
p
rivate
p
arse
()
{
this
.
parseMetadata
();
this
.
parseEquipmentData
();
this
.
parseBasicAttributes
();
this
.
parseYHZ
();
}
constructor
(
id
:
string
,
content
:
string
)
{
constructor
(
id
:
string
,
content
:
string
,
region
:
string
)
{
this
.
id
=
id
;
this
.
region
=
region
;
this
.
content
=
HTML
(
content
);
this
.
parse
();
this
.
content
=
null
;
...
...
src/utility.ts
0 → 100644
View file @
d1bc3354
import
HTML
from
"
posthtml-parser
"
;
import
_
from
"
underscore
"
;
export
function
getDepthOfTree
(
tree
:
HTML
.
Tree
,
indexList
:
number
[]):
HTML
.
Tree
{
if
(
indexList
.
length
)
{
const
_indexList
=
_
.
clone
(
indexList
);
const
index
=
_indexList
.
splice
(
0
,
1
)[
0
];
const
node
=
tree
[
index
];
if
(
typeof
(
node
)
===
"
string
"
||
!
node
.
content
)
{
return
[
node
];
}
return
getDepthOfTree
(
node
.
content
,
_indexList
);
}
else
{
return
tree
;
}
}
export
function
findNodeIndex
(
baseTree
:
HTML
.
Tree
,
condition
:
(
node
:
HTML
.
Node
)
=>
boolean
,
offset
:
number
[]):
number
[]
{
const
queue
=
[
offset
];
while
(
queue
.
length
)
{
const
indexList
=
queue
.
splice
(
0
,
1
)[
0
];
const
tree
=
getDepthOfTree
(
baseTree
,
indexList
);
for
(
let
i
=
0
;
i
<
tree
.
length
;
++
i
)
{
const
node
=
tree
[
i
];
const
newList
=
indexList
.
concat
([
i
]);
if
(
condition
(
node
))
{
return
newList
;
}
else
if
(
typeof
(
node
)
!==
"
string
"
)
{
queue
.
push
(
newList
);
}
}
}
return
null
;
}
export
function
findAllNodeIndex
(
baseTree
:
HTML
.
Tree
,
condition
:
(
node
:
HTML
.
Node
)
=>
boolean
,
offset
:
number
[]):
number
[][]
{
const
queue
=
[
offset
];
const
res
:
number
[][]
=
[];
while
(
queue
.
length
)
{
const
indexList
=
queue
.
splice
(
0
,
1
)[
0
];
const
tree
=
getDepthOfTree
(
baseTree
,
indexList
);
for
(
let
i
=
0
;
i
<
tree
.
length
;
++
i
)
{
const
node
=
tree
[
i
];
const
newList
=
indexList
.
concat
([
i
]);
if
(
condition
(
node
))
{
//console.log(newList);
res
.
push
(
newList
);
}
else
if
(
typeof
(
node
)
!==
"
string
"
)
{
queue
.
push
(
newList
);
}
}
}
return
res
;
}
export
function
findNodeIndexByContent
(
baseTree
:
HTML
.
Tree
,
label
:
string
,
offset
:
number
[]):
number
[]
{
return
findNodeIndex
(
baseTree
,
(
node
)
=>
{
return
node
===
label
;
},
offset
);
}
export
function
findNodeIndexByAttribute
(
baseTree
:
HTML
.
Tree
,
key
:
string
,
value
:
string
,
offset
:
number
[]):
number
[]
{
return
findNodeIndex
(
baseTree
,
(
node
)
=>
{
return
typeof
(
node
)
!==
"
string
"
&&
node
.
attrs
&&
node
.
attrs
[
key
]
===
value
;
},
offset
);
}
export
function
findNodeIndexByTag
(
baseTree
:
HTML
.
Tree
,
tag
:
string
,
offset
:
number
[]):
number
[]
{
return
findNodeIndex
(
baseTree
,
(
node
)
=>
{
return
typeof
(
node
)
!==
"
string
"
&&
node
.
tag
===
tag
;
},
offset
);
}
export
function
findAllNodeIndexByContent
(
baseTree
:
HTML
.
Tree
,
label
:
string
,
offset
:
number
[]):
number
[][]
{
return
findAllNodeIndex
(
baseTree
,
(
node
)
=>
{
return
node
===
label
;
},
offset
);
}
export
function
findAllNodeIndexByAttribute
(
baseTree
:
HTML
.
Tree
,
key
:
string
,
value
:
string
,
offset
:
number
[]):
number
[][]
{
return
findAllNodeIndex
(
baseTree
,
(
node
)
=>
{
return
typeof
(
node
)
!==
"
string
"
&&
node
.
attrs
&&
node
.
attrs
[
key
]
===
value
;
},
offset
);
}
export
function
findAllNodeIndexByTag
(
baseTree
:
HTML
.
Tree
,
tag
:
string
,
offset
:
number
[]):
number
[][]
{
return
findAllNodeIndex
(
baseTree
,
(
node
)
=>
{
return
typeof
(
node
)
!==
"
string
"
&&
node
.
tag
===
tag
;
},
offset
);
}
const
chineseCapitalNumbers
=
[
"
零
"
,
"
壹
"
,
"
贰
"
,
"
叁
"
,
"
肆
"
,
"
伍
"
,
"
陆
"
,
"
柒
"
,
"
捌
"
,
"
玖
"
]
export
function
getString
(
node
:
HTML
.
Node
)
{
let
resultStr
:
string
;
if
(
typeof
(
node
)
===
"
string
"
)
{
resultStr
=
node
;
}
else
{
const
subTree
=
node
.
content
;
if
(
!
subTree
)
{
return
null
;
}
const
subNode
=
subTree
[
0
];
if
(
typeof
(
subNode
)
===
"
string
"
)
{
resultStr
=
subTree
[
0
]
as
string
;
}
else
{
resultStr
=
getString
(
subTree
[
0
])
as
string
;
}
}
resultStr
=
resultStr
.
trim
();
return
resultStr
;
}
export
function
getNumber
(
node
:
HTML
.
Node
)
{
const
numberStr
=
getString
(
node
);
let
stringMatch
:
RegExpMatchArray
;
if
(
numberStr
===
"
没有上榜
"
)
{
return
null
;
}
else
if
(
stringMatch
=
numberStr
.
match
(
/^
([
天地
])
魂$/
))
{
return
stringMatch
[
1
]
===
"
天
"
?
2
:
1
;
}
else
if
(
stringMatch
=
numberStr
.
match
(
/^
(
.+
)
天
(
.+
)
境界$/
))
{
return
(
_
.
findIndex
(
chineseCapitalNumbers
,
(
m
)
=>
m
===
stringMatch
[
1
])
<<
8
)
|
_
.
findIndex
(
chineseCapitalNumbers
,
(
m
)
=>
m
===
stringMatch
[
2
]);
}
else
if
(
stringMatch
=
numberStr
.
match
(
/^
(\d
+
)
-
(\d
+
)
$/
))
{
const
minValue
=
parseInt
(
stringMatch
[
1
]);
const
maxValue
=
parseInt
(
stringMatch
[
2
]);
return
(
minValue
<<
16
)
|
maxValue
;
}
else
{
return
parseInt
(
numberStr
);
}
}
export
function
getContinuousNodes
(
tree
:
HTML
.
Tree
,
_pos
:
number
[],
moveOffset
:
number
,
step
:
number
,
dataCount
:
number
):
HTML
.
Node
[]
{
const
pos
=
_
.
clone
(
_pos
);
const
datas
:
HTML
.
Node
[]
=
[];
for
(
let
i
=
0
;
i
<
dataCount
;
++
i
)
{
const
node
=
getDepthOfTree
(
tree
,
pos
)[
0
];
datas
.
push
(
node
);
pos
[
pos
.
length
-
(
moveOffset
+
1
)]
+=
step
;
}
return
datas
;
}
export
function
getContinuousData
(
tree
:
HTML
.
Tree
,
_pos
:
number
[],
moveOffset
:
number
,
step
:
number
,
dataCount
:
number
):
string
[]
{
return
getContinuousNodes
(
tree
,
_pos
,
moveOffset
,
step
,
dataCount
).
map
(
getString
);
}
export
function
getContinuousNumber
(
tree
:
HTML
.
Tree
,
_pos
:
number
[],
moveOffset
:
number
,
step
:
number
,
dataCount
:
number
):
number
[]
{
return
getContinuousNodes
(
tree
,
_pos
,
moveOffset
,
step
,
dataCount
).
map
(
getNumber
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment