Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
K
koishi-plugin-ygotournament
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
3rdeye
koishi-plugin-ygotournament
Commits
a470da9c
Commit
a470da9c
authored
Nov 03, 2021
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
finish
parent
3cc4eb3f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
288 additions
and
40 deletions
+288
-40
package-lock.json
package-lock.json
+64
-8
package.json
package.json
+3
-0
src/config.ts
src/config.ts
+28
-3
src/def/challonge.ts
src/def/challonge.ts
+5
-1
src/def/selection.ts
src/def/selection.ts
+20
-0
src/plugin.ts
src/plugin.ts
+164
-28
webpack.config.js
webpack.config.js
+4
-0
No files found.
package-lock.json
View file @
a470da9c
...
@@ -17,17 +17,20 @@
...
@@ -17,17 +17,20 @@
"@aws-sdk/util-format-url"
:
"^3.38.0"
,
"@aws-sdk/util-format-url"
:
"^3.38.0"
,
"class-transformer"
:
"^0.4.0"
,
"class-transformer"
:
"^0.4.0"
,
"koishi-utils-schemagen"
:
"^1.1.9"
,
"koishi-utils-schemagen"
:
"^1.1.9"
,
"moment"
:
"^2.29.1"
,
"source-map-support"
:
"^0.5.20"
"source-map-support"
:
"^0.5.20"
},
},
"devDependencies"
:
{
"devDependencies"
:
{
"@types/node"
:
"^16.11.6"
,
"@types/node"
:
"^16.11.6"
,
"@typescript-eslint/eslint-plugin"
:
"^4.33.0"
,
"@typescript-eslint/eslint-plugin"
:
"^4.33.0"
,
"@typescript-eslint/parser"
:
"^4.33.0"
,
"@typescript-eslint/parser"
:
"^4.33.0"
,
"axios"
:
"^0.24.0"
,
"eslint"
:
"^7.32.0"
,
"eslint"
:
"^7.32.0"
,
"eslint-config-prettier"
:
"^8.3.0"
,
"eslint-config-prettier"
:
"^8.3.0"
,
"eslint-plugin-prettier"
:
"^3.4.1"
,
"eslint-plugin-prettier"
:
"^3.4.1"
,
"koishi"
:
"^4.0.0-alpha.12"
,
"koishi"
:
"^4.0.0-alpha.12"
,
"prettier"
:
"^2.4.1"
,
"prettier"
:
"^2.4.1"
,
"proxy-agent"
:
"^5.0.0"
,
"raw-loader"
:
"^4.0.2"
,
"raw-loader"
:
"^4.0.2"
,
"ts-loader"
:
"^9.2.6"
,
"ts-loader"
:
"^9.2.6"
,
"typescript"
:
"^4.4.4"
,
"typescript"
:
"^4.4.4"
,
...
@@ -2140,6 +2143,15 @@
...
@@ -2140,6 +2143,15 @@
"websocket-stream"
:
"^5.5.2"
"websocket-stream"
:
"^5.5.2"
}
}
},
},
"node_modules/aws-crt/node_modules/axios"
:
{
"version"
:
"0.21.4"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.21.4.tgz"
,
"integrity"
:
"sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg=="
,
"peer"
:
true
,
"dependencies"
:
{
"follow-redirects"
:
"^1.14.0"
}
},
"node_modules/aws-sign2"
:
{
"node_modules/aws-sign2"
:
{
"version"
:
"0.7.0"
,
"version"
:
"0.7.0"
,
"resolved"
:
"https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz"
,
...
@@ -2156,11 +2168,12 @@
...
@@ -2156,11 +2168,12 @@
"peer"
:
true
"peer"
:
true
},
},
"node_modules/axios"
:
{
"node_modules/axios"
:
{
"version"
:
"0.21.4"
,
"version"
:
"0.24.0"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.21.4.tgz"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.24.0.tgz"
,
"integrity"
:
"sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg=="
,
"integrity"
:
"sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA=="
,
"dev"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"follow-redirects"
:
"^1.14.
0
"
"follow-redirects"
:
"^1.14.
4
"
}
}
},
},
"node_modules/balanced-match"
:
{
"node_modules/balanced-match"
:
{
...
@@ -4771,6 +4784,14 @@
...
@@ -4771,6 +4784,14 @@
"reflect-metadata"
:
"^0.1.13"
"reflect-metadata"
:
"^0.1.13"
}
}
},
},
"node_modules/koishi/node_modules/axios"
:
{
"version"
:
"0.21.4"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.21.4.tgz"
,
"integrity"
:
"sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg=="
,
"dependencies"
:
{
"follow-redirects"
:
"^1.14.0"
}
},
"node_modules/lcid"
:
{
"node_modules/lcid"
:
{
"version"
:
"1.0.0"
,
"version"
:
"1.0.0"
,
"resolved"
:
"https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz"
,
...
@@ -5044,6 +5065,14 @@
...
@@ -5044,6 +5065,14 @@
"node"
:
">=10"
"node"
:
">=10"
}
}
},
},
"node_modules/moment"
:
{
"version"
:
"2.29.1"
,
"resolved"
:
"https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
,
"integrity"
:
"sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
,
"engines"
:
{
"node"
:
"*"
}
},
"node_modules/mqtt"
:
{
"node_modules/mqtt"
:
{
"version"
:
"4.2.8"
,
"version"
:
"4.2.8"
,
"resolved"
:
"https://registry.npmjs.org/mqtt/-/mqtt-4.2.8.tgz"
,
"resolved"
:
"https://registry.npmjs.org/mqtt/-/mqtt-4.2.8.tgz"
,
...
@@ -8892,6 +8921,17 @@
...
@@ -8892,6 +8921,17 @@
"mqtt"
:
"^4.2.8"
,
"mqtt"
:
"^4.2.8"
,
"tar"
:
"^6.1.11"
,
"tar"
:
"^6.1.11"
,
"websocket-stream"
:
"^5.5.2"
"websocket-stream"
:
"^5.5.2"
},
"dependencies"
:
{
"axios"
:
{
"version"
:
"0.21.4"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.21.4.tgz"
,
"integrity"
:
"sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg=="
,
"peer"
:
true
,
"requires"
:
{
"follow-redirects"
:
"^1.14.0"
}
}
}
}
},
},
"aws-sign2"
:
{
"aws-sign2"
:
{
...
@@ -8907,11 +8947,12 @@
...
@@ -8907,11 +8947,12 @@
"peer"
:
true
"peer"
:
true
},
},
"axios"
:
{
"axios"
:
{
"version"
:
"0.21.4"
,
"version"
:
"0.24.0"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.21.4.tgz"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.24.0.tgz"
,
"integrity"
:
"sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg=="
,
"integrity"
:
"sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA=="
,
"dev"
:
true
,
"requires"
:
{
"requires"
:
{
"follow-redirects"
:
"^1.14.
0
"
"follow-redirects"
:
"^1.14.
4
"
}
}
},
},
"balanced-match"
:
{
"balanced-match"
:
{
...
@@ -10870,6 +10911,16 @@
...
@@ -10870,6 +10911,16 @@
"parseurl"
:
"^1.3.3"
,
"parseurl"
:
"^1.3.3"
,
"path-to-regexp"
:
"^6.2.0"
,
"path-to-regexp"
:
"^6.2.0"
,
"proxy-agent"
:
"^5.0.0"
"proxy-agent"
:
"^5.0.0"
},
"dependencies"
:
{
"axios"
:
{
"version"
:
"0.21.4"
,
"resolved"
:
"https://registry.npmjs.org/axios/-/axios-0.21.4.tgz"
,
"integrity"
:
"sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg=="
,
"requires"
:
{
"follow-redirects"
:
"^1.14.0"
}
}
}
}
},
},
"koishi-utils-schemagen"
:
{
"koishi-utils-schemagen"
:
{
...
@@ -11099,6 +11150,11 @@
...
@@ -11099,6 +11150,11 @@
"integrity"
:
"sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
,
"integrity"
:
"sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
,
"peer"
:
true
"peer"
:
true
},
},
"moment"
:
{
"version"
:
"2.29.1"
,
"resolved"
:
"https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
,
"integrity"
:
"sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"mqtt"
:
{
"mqtt"
:
{
"version"
:
"4.2.8"
,
"version"
:
"4.2.8"
,
"resolved"
:
"https://registry.npmjs.org/mqtt/-/mqtt-4.2.8.tgz"
,
"resolved"
:
"https://registry.npmjs.org/mqtt/-/mqtt-4.2.8.tgz"
,
...
...
package.json
View file @
a470da9c
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
"
@aws-sdk/util-format-url
"
:
"
^3.38.0
"
,
"
@aws-sdk/util-format-url
"
:
"
^3.38.0
"
,
"
class-transformer
"
:
"
^0.4.0
"
,
"
class-transformer
"
:
"
^0.4.0
"
,
"
koishi-utils-schemagen
"
:
"
^1.1.9
"
,
"
koishi-utils-schemagen
"
:
"
^1.1.9
"
,
"
moment
"
:
"
^2.29.1
"
,
"
source-map-support
"
:
"
^0.5.20
"
"
source-map-support
"
:
"
^0.5.20
"
},
},
"peerDependencies"
:
{
"peerDependencies"
:
{
...
@@ -45,11 +46,13 @@
...
@@ -45,11 +46,13 @@
"
@types/node
"
:
"
^16.11.6
"
,
"
@types/node
"
:
"
^16.11.6
"
,
"
@typescript-eslint/eslint-plugin
"
:
"
^4.33.0
"
,
"
@typescript-eslint/eslint-plugin
"
:
"
^4.33.0
"
,
"
@typescript-eslint/parser
"
:
"
^4.33.0
"
,
"
@typescript-eslint/parser
"
:
"
^4.33.0
"
,
"
axios
"
:
"
^0.24.0
"
,
"
eslint
"
:
"
^7.32.0
"
,
"
eslint
"
:
"
^7.32.0
"
,
"
eslint-config-prettier
"
:
"
^8.3.0
"
,
"
eslint-config-prettier
"
:
"
^8.3.0
"
,
"
eslint-plugin-prettier
"
:
"
^3.4.1
"
,
"
eslint-plugin-prettier
"
:
"
^3.4.1
"
,
"
koishi
"
:
"
^4.0.0-alpha.12
"
,
"
koishi
"
:
"
^4.0.0-alpha.12
"
,
"
prettier
"
:
"
^2.4.1
"
,
"
prettier
"
:
"
^2.4.1
"
,
"
proxy-agent
"
:
"
^5.0.0
"
,
"
raw-loader
"
:
"
^4.0.2
"
,
"
raw-loader
"
:
"
^4.0.2
"
,
"
ts-loader
"
:
"
^9.2.6
"
,
"
ts-loader
"
:
"
^9.2.6
"
,
"
typescript
"
:
"
^4.4.4
"
,
"
typescript
"
:
"
^4.4.4
"
,
...
...
src/config.ts
View file @
a470da9c
...
@@ -11,13 +11,11 @@ import { Context, Schema } from 'koishi';
...
@@ -11,13 +11,11 @@ import { Context, Schema } from 'koishi';
import
{
import
{
GetObjectCommand
,
GetObjectCommand
,
ListObjectsCommand
,
ListObjectsCommand
,
S3
,
S3Client
,
S3Client
,
S3ClientConfig
,
S3ClientConfig
,
}
from
'
@aws-sdk/client-s3
'
;
}
from
'
@aws-sdk/client-s3
'
;
import
{
Tournament
}
from
'
./def/challonge
'
;
import
{
Type
}
from
'
class-transformer
'
;
import
{
SRVProRoomInfo
}
from
'
./def/srvpro
'
;
import
{
SRVProRoomInfo
}
from
'
./def/srvpro
'
;
import
{
Selection
}
from
'
./def/selection
'
;
const
credentialsSchema
:
Schema
<
Credentials
>
=
Schema
.
object
(
const
credentialsSchema
:
Schema
<
Credentials
>
=
Schema
.
object
(
{
{
...
@@ -106,6 +104,16 @@ export class TournamentConfig {
...
@@ -106,6 +104,16 @@ export class TournamentConfig {
})
})
challongeCacheTTL
:
number
;
challongeCacheTTL
:
number
;
@
DefineSchema
({
desc
:
'
Challonge URL 前缀
'
,
default
:
'
https://api.challonge.com/v1/tournaments/
'
,
})
challongeUrlPrefix
:
string
;
getChallongeUrl
()
{
return
`
${
this
.
challongeUrlPrefix
}${
this
.
challongeTournamentId
}
`
;
}
async
fetchRooms
(
ctx
:
Context
)
{
async
fetchRooms
(
ctx
:
Context
)
{
return
ctx
.
http
.
get
<
Partial
<
SRVProRoomInfo
>>
(
return
ctx
.
http
.
get
<
Partial
<
SRVProRoomInfo
>>
(
`
${
this
.
endpoint
}
/api/getrooms`
,
`
${
this
.
endpoint
}
/api/getrooms`
,
...
@@ -115,9 +123,25 @@ export class TournamentConfig {
...
@@ -115,9 +123,25 @@ export class TournamentConfig {
},
},
);
);
}
}
async
kickRoom
(
ctx
:
Context
,
search
:
string
)
{
return
ctx
.
http
.
get
(
`
${
this
.
endpoint
}
/api/message`
,
{
username
:
this
.
username
,
pass
:
this
.
password
,
kick
:
search
,
});
}
}
}
export
class
YGOTournamentPluginConfig
{
export
class
YGOTournamentPluginConfig
{
@
DefineSchema
({
type
:
'
object
'
,
allowUnknown
:
true
,
desc
:
'
裁判接口作用域
'
,
required
:
true
,
})
judgeSelection
:
Selection
;
@
DefineSchema
()
@
DefineSchema
()
tournament
:
TournamentConfig
;
tournament
:
TournamentConfig
;
...
@@ -134,6 +158,7 @@ export class YGOTournamentPluginConfig {
...
@@ -134,6 +158,7 @@ export class YGOTournamentPluginConfig {
}
}
export
interface
YGOTournamentPluginConfigLike
{
export
interface
YGOTournamentPluginConfigLike
{
judgeSelection
:
Selection
;
tournament
?:
Partial
<
TournamentConfig
>
;
tournament
?:
Partial
<
TournamentConfig
>
;
deckFetch
?:
Partial
<
DeckFetchConfig
>
;
deckFetch
?:
Partial
<
DeckFetchConfig
>
;
}
}
src/def/challonge.ts
View file @
a470da9c
...
@@ -35,7 +35,7 @@ export class MatchWrapper {
...
@@ -35,7 +35,7 @@ export class MatchWrapper {
isClean
()
{
isClean
()
{
return
(
return
(
this
.
match
.
state
!==
'
complete
'
&&
this
.
match
.
state
!==
'
complete
'
&&
(
this
.
match
.
scores_csv
?.
length
&&
0
)
<
3
(
this
.
match
.
scores_csv
?.
length
||
0
)
<
3
);
);
}
}
getPlayerIds
()
{
getPlayerIds
()
{
...
@@ -91,6 +91,10 @@ export class ParticipantWrapper {
...
@@ -91,6 +91,10 @@ export class ParticipantWrapper {
}
}
return
{
userId
:
matching
[
1
],
userName
:
matching
[
2
]
};
return
{
userId
:
matching
[
1
],
userName
:
matching
[
2
]
};
}
}
getDisplayName
()
{
return
`
${
this
.
participant
.
name
}
(
${
this
.
participant
.
id
}
)`
;
}
}
}
export
class
Tournament
{
export
class
Tournament
{
...
...
src/def/selection.ts
0 → 100644
View file @
a470da9c
import
{
MaybeArray
}
from
'
koishi
'
;
const
selectors
=
[
'
user
'
,
'
guild
'
,
'
channel
'
,
'
self
'
,
'
private
'
,
'
platform
'
,
]
as
const
;
type
SelectorType
=
typeof
selectors
[
number
];
type
SelectorValue
=
boolean
|
MaybeArray
<
string
|
number
>
;
type
BaseSelection
=
{
[
K
in
SelectorType
as
`$
${
K
}
`
]?:
SelectorValue
};
export
interface
Selection
extends
BaseSelection
{
$and
?:
Selection
[];
$or
?:
Selection
[];
$not
?:
Selection
;
}
src/plugin.ts
View file @
a470da9c
import
'
source-map-support/register
'
;
import
'
source-map-support/register
'
;
import
{
Context
,
Schema
}
from
'
koishi
'
;
import
{
Context
,
Schema
,
Quester
}
from
'
koishi
'
;
import
{
import
{
YGOTournamentPluginConfig
,
YGOTournamentPluginConfig
,
YGOTournamentPluginConfigLike
,
YGOTournamentPluginConfigLike
,
...
@@ -10,12 +10,21 @@ import { Tournament, TournamentWrapper } from './def/challonge';
...
@@ -10,12 +10,21 @@ import { Tournament, TournamentWrapper } from './def/challonge';
import
{
S3Client
}
from
'
@aws-sdk/client-s3
'
;
import
{
S3Client
}
from
'
@aws-sdk/client-s3
'
;
import
{
getSignedUrl
}
from
'
./presign
'
;
import
{
getSignedUrl
}
from
'
./presign
'
;
import
{
Room
,
SRVProRoomInfo
}
from
'
./def/srvpro
'
;
import
{
Room
,
SRVProRoomInfo
}
from
'
./def/srvpro
'
;
import
moment
from
'
moment
'
;
import
axios
,
{
AxiosRequestConfig
}
from
'
axios
'
;
import
ProxyAgent
from
'
proxy-agent
'
;
export
interface
FromAndToTimeUnix
{
fromTime
:
number
;
toTime
:
number
;
}
declare
module
'
koishi
'
{
declare
module
'
koishi
'
{
// eslint-disable-next-line @typescript-eslint/no-namespace
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace
Cache
{
namespace
Cache
{
interface
Tables
{
interface
Tables
{
challongeData
:
any
;
challongeData
:
any
;
lateDeclarationTime
:
FromAndToTimeUnix
;
}
}
}
}
}
}
...
@@ -55,7 +64,7 @@ export class YGOTournamentPlugin {
...
@@ -55,7 +64,7 @@ export class YGOTournamentPlugin {
return
cached
;
return
cached
;
}
}
const
plain
=
await
this
.
ctx
.
http
.
get
(
const
plain
=
await
this
.
ctx
.
http
.
get
(
`
https://api.challonge.com/v1/tournaments/
${
this
.
config
.
tournament
.
challongeTournamentId
}
.json`
,
`
${
this
.
config
.
tournament
.
getChallongeUrl
()
}
.json`
,
{
{
api_key
:
this
.
config
.
tournament
.
challongeKey
,
api_key
:
this
.
config
.
tournament
.
challongeKey
,
include_participants
:
1
,
include_participants
:
1
,
...
@@ -69,7 +78,6 @@ export class YGOTournamentPlugin {
...
@@ -69,7 +78,6 @@ export class YGOTournamentPlugin {
private
async
onUserQuit
(
userId
:
string
)
{
private
async
onUserQuit
(
userId
:
string
)
{
const
tournament
=
await
this
.
fetchChallongeData
();
const
tournament
=
await
this
.
fetchChallongeData
();
const
{
matches
}
=
tournament
.
tournament
;
const
participant
=
tournament
.
getParticipantFromId
(
userId
);
const
participant
=
tournament
.
getParticipantFromId
(
userId
);
if
(
!
participant
)
{
if
(
!
participant
)
{
return
'
未找到您的参赛信息。
'
;
return
'
未找到您的参赛信息。
'
;
...
@@ -77,7 +85,7 @@ export class YGOTournamentPlugin {
...
@@ -77,7 +85,7 @@ export class YGOTournamentPlugin {
// const participantName = participant.getNameMatching().userName;
// const participantName = participant.getNameMatching().userName;
this
.
ctx
this
.
ctx
.
logger
(
'
challonge
'
)
.
logger
(
'
challonge
'
)
.
info
(
`Player
${
participant
.
participant
.
name
}
requested for quit.`
);
.
info
(
`Player
${
participant
.
getDisplayName
()
}
requested for quit.`
);
const
currentMatch
=
tournament
.
getCurrentMatchFromId
(
const
currentMatch
=
tournament
.
getCurrentMatchFromId
(
participant
.
participant
.
id
,
participant
.
participant
.
id
,
);
);
...
@@ -86,19 +94,21 @@ export class YGOTournamentPlugin {
...
@@ -86,19 +94,21 @@ export class YGOTournamentPlugin {
participant
.
participant
.
id
===
currentMatch
.
match
.
player2_id
participant
.
participant
.
id
===
currentMatch
.
match
.
player2_id
?
'
2--1
'
?
'
2--1
'
:
'
-1-2
'
;
:
'
-1-2
'
;
const
winner_id
=
currentMatch
.
getPlayerIds
()
.
find
((
id
)
=>
id
!==
participant
.
participant
.
id
);
this
.
ctx
this
.
ctx
.
logger
(
'
challonge
'
)
.
logger
(
'
challonge
'
)
.
info
(
.
info
(
`Cleaning remaining match for player
${
participant
.
participant
.
name
}
.`
,
`Cleaning remaining match for player
${
participant
.
getDisplayName
()
}
.`
,
);
);
await
this
.
ctx
.
http
.
put
(
await
this
.
ctx
.
http
.
put
(
`https://api.challonge.com/v1/tournaments/
${
this
.
config
.
tournament
.
challongeTournamentId
}
/matches/
${
currentMatch
.
match
.
id
}
.json`
,
`
${
this
.
config
.
tournament
.
getChallongeUrl
()}
/matches/
${
currentMatch
.
match
.
id
}
.json`
,
{
{
api_key
:
this
.
config
.
tournament
.
challongeKey
,
api_key
:
this
.
config
.
tournament
.
challongeKey
,
scores_csv
,
match
:
{
scores_csv
,
winner_id
},
winner_id
:
currentMatch
.
getPlayerIds
()
.
find
((
id
)
=>
id
!==
participant
.
participant
.
id
),
},
},
);
);
this
.
ctx
this
.
ctx
...
@@ -107,23 +117,33 @@ export class YGOTournamentPlugin {
...
@@ -107,23 +117,33 @@ export class YGOTournamentPlugin {
`Cleaned remaining match for player
${
participant
.
participant
.
name
}
.`
,
`Cleaned remaining match for player
${
participant
.
participant
.
name
}
.`
,
);
);
await
this
.
ctx
.
http
.
delete
(
await
this
.
ctx
.
http
.
delete
(
`https://api.challonge.com/v1/tournaments/
${
`
${
this
.
config
.
tournament
.
getChallongeUrl
()}
/participants/
${
this
.
config
.
tournament
.
challongeTournamentId
}
/participants/
${
participant
.
participant
.
id
participant
.
participant
.
id
}
.json?api_key=
${
encodeURIComponent
(
}
.json`
,
this
.
config
.
tournament
.
challongeKey
,
{
)}
`
,
api_key
:
this
.
config
.
tournament
.
challongeKey
,
},
);
);
this
.
ctx
this
.
ctx
.
logger
(
'
challonge
'
)
.
logger
(
'
challonge
'
)
.
info
(
`Player
${
participant
.
participant
.
name
}
quit
ted.`
);
.
info
(
`Player
${
participant
.
getDisplayName
()}
qui
ted.`
);
await
this
.
deleteChallongeCache
();
await
this
.
deleteChallongeCache
();
return
'
退赛成功。
'
;
return
'
退赛成功。
'
;
}
}
}
}
private
async
onUserDeclareLate
(
userId
:
string
)
{
private
async
onUserDeclareLate
(
userId
:
string
)
{
const
timeUnix
=
await
this
.
ctx
.
cache
.
get
(
'
lateDeclarationTime
'
,
'
current
'
);
this
.
ctx
.
logger
(
'
test
'
).
warn
(
JSON
.
stringify
(
timeUnix
));
if
(
!
timeUnix
||
!
moment
().
isBetween
(
moment
.
unix
(
timeUnix
.
fromTime
),
moment
.
unix
(
timeUnix
.
toTime
),
)
)
{
return
'
现在不是允许迟到杀的时间。
'
;
}
const
tournament
=
await
this
.
fetchChallongeData
();
const
tournament
=
await
this
.
fetchChallongeData
();
const
participant
=
tournament
.
getParticipantFromId
(
userId
);
const
participant
=
tournament
.
getParticipantFromId
(
userId
);
if
(
!
participant
)
{
if
(
!
participant
)
{
...
@@ -157,27 +177,39 @@ export class YGOTournamentPlugin {
...
@@ -157,27 +177,39 @@ export class YGOTournamentPlugin {
participant
.
participant
.
id
===
currentMatch
.
match
.
player1_id
participant
.
participant
.
id
===
currentMatch
.
match
.
player1_id
?
'
2--1
'
?
'
2--1
'
:
'
-1-2
'
;
:
'
-1-2
'
;
const
rivalId
=
currentMatch
.
getPlayerIds
()
.
find
((
id
)
=>
id
!==
participant
.
participant
.
id
);
const
rival
=
tournament
.
tournament
.
participants
.
find
(
(
p
)
=>
p
.
participant
.
id
===
rivalId
,
);
this
.
ctx
this
.
ctx
.
logger
(
'
challonge
'
)
.
logger
(
'
challonge
'
)
.
info
(
.
info
(
`Player
${
participant
.
participant
.
name
}
requested for a late declaration
.`
,
`Player
${
participant
.
getDisplayName
()}
requested for a late declaration against
${
rival
?.
getDisplayName
()}
.
`,
);
);
const result = await this.ctx.http.put(
const result = await this.ctx.http.put(
`https://api.challonge.com/v1/tournaments/
${
this
.
config
.
tournament
.
challongeTournamentId
}
/matches/
${
currentMatch
.
match
.
id
}
.json`
,
`
$
{
this
.
config
.
tournament
.
getChallongeUrl
()}
/matches/
$
{
currentMatch
.
match
.
id
}.
json
`,
{
{
api_key: this.config.tournament.challongeKey,
api_key: this.config.tournament.challongeKey,
scores_csv
,
match: { scores_csv, winner_id: participant.participant.id },
winner_id
:
participant
.
participant
.
id
,
},
},
);
);
this.ctx
this.ctx
.logger('challonge')
.logger('challonge')
.info(
.info(
`Result of late declaration for player
${
`
Player
$
{
participant
.
getDisplayName
()}
declared
late
against
$
{
rival
?.
getDisplayName
()}.
`,
participant
.
participant
.
name
}
:
${
JSON
.
stringify
(
result
)}
`
,
);
);
await
this
.
deleteChallongeCache
();
await Promise.all([
this.deleteChallongeCache(),
...roomsWithPlayer.map((r) =>
this.config.tournament.kickRoom(this.ctx, r.roomid),
),
]);
return '迟到杀成功。';
return '迟到杀成功。';
}
}
...
@@ -220,13 +252,117 @@ export class YGOTournamentPlugin {
...
@@ -220,13 +252,117 @@ export class YGOTournamentPlugin {
});
});
}
}
// WTF fix for missing ctx.http.delete
private
workaroundQuester
(
quester
:
Quester
)
{
const
config
=
quester
.
config
;
const
options
:
AxiosRequestConfig
=
{
timeout
:
config
.
timeout
,
headers
:
config
.
headers
,
};
if
(
config
.
proxyAgent
)
{
const
agent
=
new
ProxyAgent
(
config
.
proxyAgent
);
options
.
httpAgent
=
agent
;
options
.
httpsAgent
=
agent
;
}
quester
.
delete
=
async
(
url
,
params
,
headers
)
=>
{
const
{
data
}
=
await
axios
.
delete
(
url
,
{
...
options
,
...
config
,
params
,
headers
:
{
...
options
.
headers
,
...
headers
,
},
});
return
data
;
};
}
initializeTournament
()
{
initializeTournament
()
{
if
(
!
this
.
config
.
isTournamentEnabled
())
{
if
(
!
this
.
config
.
isTournamentEnabled
())
{
return
;
return
;
}
}
this
.
ctx
.
cache
.
table
(
'
challongeData
'
,
{
this
.
workaroundQuester
(
this
.
ctx
.
http
);
maxAge
:
this
.
config
.
tournament
.
challongeCacheTTL
,
this
.
ctx
.
cache
.
table
(
'
lateDeclarationTime
'
,
{
maxAge
:
3600
*
1000
});
});
this
.
ctx
.
command
(
'
tournament/late
'
,
'
迟到杀
'
)
.
shortcut
(
'
迟到杀
'
)
.
usage
(
'
迟到杀需要选手在房间内,且只有1人才可以迟到杀。
'
)
.
action
(
async
({
session
})
=>
{
try
{
return
await
this
.
onUserDeclareLate
(
session
.
userId
);
}
catch
(
e
)
{
this
.
ctx
.
logger
(
'
challonge
'
)
.
error
(
`Failed to quit user
${
session
.
userId
}
:
${
e
.
toString
()}
`
);
return
'
迟到杀出现了一些问题,请与技术人员联系。
'
;
}
});
this
.
ctx
.
command
(
'
tournament/quit
'
,
'
退赛
'
)
.
shortcut
(
'
退赛
'
)
.
usage
(
'
退赛需要慎重,会取消后续的比赛资格。
'
)
.
action
(
async
({
session
})
=>
{
await
session
.
send
(
'
确定要退赛吗?输入 yes 以确认。
'
);
const
reply
=
await
session
.
prompt
();
if
(
reply
!==
'
yes
'
)
{
return
'
退赛被取消,接下来要继续努力哦。
'
;
}
try
{
return
await
this
.
onUserQuit
(
session
.
userId
);
}
catch
(
e
)
{
this
.
ctx
.
logger
(
'
challonge
'
)
.
error
(
`Failed to quit user
${
session
.
userId
}
:
${
e
.
toString
()}
`
);
return
'
退赛出现了一些问题,请与技术人员联系。
'
;
}
});
const
judgeCommand
=
this
.
ctx
.
select
(
this
.
config
.
judgeSelection
)
.
command
(
'
tournament/judge
'
,
'
裁判操作
'
)
.
usage
(
'
需要有裁判权限才能执行这些操作。
'
);
judgeCommand
.
subcommand
(
'
.enablelate
'
,
'
开启迟到杀
'
)
.
usage
(
'
允许选手使用指令来进行迟到杀。
'
)
.
option
(
'
delay
'
,
'
-d <time:posint> 在指定分钟后开启迟到杀。
'
,
{
fallback
:
0
,
})
.
option
(
'
duration
'
,
'
-t <time:posint> 迟到杀允许的分钟数。
'
,
{
fallback
:
30
,
})
.
action
(
async
({
session
,
options
})
=>
{
const
fromTime
=
moment
().
add
(
options
.
delay
,
'
minutes
'
);
const
toTime
=
fromTime
.
clone
().
add
(
options
.
duration
,
'
minutes
'
);
await
this
.
ctx
.
cache
.
set
(
'
lateDeclarationTime
'
,
'
current
'
,
{
fromTime
:
fromTime
.
unix
(),
toTime
:
toTime
.
unix
(),
},
(
options
.
delay
+
options
.
duration
)
*
60000
,
);
return
`设置成功。将允许在
${
fromTime
.
format
(
'
HH:mm:ss
'
,
)}
至
${
toTime
.
format
(
'
HH:mm:ss
'
)}
期间允许迟到杀。`
;
});
judgeCommand
.
subcommand
(
'
.disablelate
'
,
'
关闭迟到杀
'
)
.
usage
(
'
不再允许选手进行迟到杀操作。
'
)
.
action
(
async
()
=>
{
await
this
.
ctx
.
cache
.
del
(
'
lateDeclarationTime
'
,
'
current
'
);
return
'
设置成功。选手不再允许进行迟到杀操作。
'
;
});
judgeCommand
.
subcommand
(
'
.refresh
'
,
'
清理 Challonge 缓存
'
)
.
action
(
async
()
=>
{
await
this
.
ctx
.
cache
.
del
(
'
challongeData
'
,
this
.
config
.
tournament
.
challongeTournamentId
,
);
return
'
清理缓存成功。
'
;
});
}
}
name
=
'
ygotournament-main
'
;
name
=
'
ygotournament-main
'
;
...
...
webpack.config.js
View file @
a470da9c
...
@@ -29,6 +29,8 @@ module.exports = {
...
@@ -29,6 +29,8 @@ module.exports = {
},
},
externals
:
{
externals
:
{
koishi
:
'
koishi
'
,
koishi
:
'
koishi
'
,
'
proxy-agent
'
:
'
proxy-agent
'
,
axios
:
'
axios
'
,
...(
packAll
...(
packAll
?
{}
?
{}
:
{
:
{
...
@@ -37,8 +39,10 @@ module.exports = {
...
@@ -37,8 +39,10 @@ module.exports = {
'
@aws-sdk/protocol-http
'
:
'
@aws-sdk/protocol-http
'
,
'
@aws-sdk/protocol-http
'
:
'
@aws-sdk/protocol-http
'
,
'
@aws-sdk/smithy-client
'
:
'
@aws-sdk/smithy-client
'
,
'
@aws-sdk/smithy-client
'
:
'
@aws-sdk/smithy-client
'
,
'
@aws-sdk/util-format-url
'
:
'
@aws-sdk/util-format-url
'
,
'
@aws-sdk/util-format-url
'
:
'
@aws-sdk/util-format-url
'
,
'
@aws-sdk/types
'
:
'
@aws-sdk/types
'
,
'
koishi-utils-schemagen
'
:
'
koishi-utils-schemagen
'
,
'
koishi-utils-schemagen
'
:
'
koishi-utils-schemagen
'
,
'
class-transformer
'
:
'
class-transformer
'
,
'
class-transformer
'
:
'
class-transformer
'
,
moment
:
'
moment
'
,
}),
}),
},
},
};
};
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