Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
W
windbot
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
alstroemeria-silentlove
windbot
Commits
0111d23e
Commit
0111d23e
authored
May 30, 2018
by
Momobako
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
8a7a0f01
d5ee2352
Changes
21
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
3273 additions
and
769 deletions
+3273
-769
Decks/AI_DarkMagician.ydk
Decks/AI_DarkMagician.ydk
+57
-0
Decks/AI_LightswornShaddoldinosour.ydk
Decks/AI_LightswornShaddoldinosour.ydk
+1
-0
Game/AI/AIFunctions.cs
Game/AI/AIFunctions.cs
+50
-3
Game/AI/Decks/ChainBurnExecutor.cs
Game/AI/Decks/ChainBurnExecutor.cs
+868
-685
Game/AI/Decks/DarkMagicianExecutor.cs
Game/AI/Decks/DarkMagicianExecutor.cs
+1948
-0
Game/AI/Decks/LightswornShaddoldinosourExecutor.cs
Game/AI/Decks/LightswornShaddoldinosourExecutor.cs
+1
-1
Game/AI/Decks/SkyStrikerExecutor.cs
Game/AI/Decks/SkyStrikerExecutor.cs
+58
-56
Game/AI/DefaultExecutor.cs
Game/AI/DefaultExecutor.cs
+12
-1
Game/AI/Dialogs.cs
Game/AI/Dialogs.cs
+12
-3
Game/AI/Enums/Floodgate.cs
Game/AI/Enums/Floodgate.cs
+2
-1
Game/AI/Enums/ShouldNotBeTarget.cs
Game/AI/Enums/ShouldNotBeTarget.cs
+2
-1
Game/AI/Executor.cs
Game/AI/Executor.cs
+11
-0
Game/ClientCard.cs
Game/ClientCard.cs
+12
-2
Game/ClientField.cs
Game/ClientField.cs
+94
-0
Game/GameAI.cs
Game/GameAI.cs
+28
-0
Game/GameBehavior.cs
Game/GameBehavior.cs
+90
-14
Game/GameClient.cs
Game/GameClient.cs
+4
-1
Program.cs
Program.cs
+8
-0
WindBot.csproj
WindBot.csproj
+1
-0
WindBotInfo.cs
WindBotInfo.cs
+4
-1
bots.json
bots.json
+10
-0
No files found.
Decks/AI_DarkMagician.ydk
0 → 100644
View file @
0111d23e
#created by ...
#main
46986414
46986414
46986414
30603688
30603688
30603688
71007216
71007216
7084129
7084129
7084129
43722862
43722862
14558127
14558127
14824019
23434538
70117860
1784686
1784686
2314238
23314220
70368879
70368879
89739383
41735184
73616671
47222536
47222536
47222536
67775894
67775894
7922915
7922915
7922915
48680970
48680970
48680970
40605147
40605147
#extra
41721210
41721210
50954680
58074177
90036274
14577226
16691074
22110647
80117527
71384012
71384012
71384012
1482001
!side
Decks/AI_LightswornShaddoldinosour.ydk
View file @
0111d23e
...
...
@@ -15,6 +15,7 @@
80280944
48048590
77723643
77723643
55623480
30328508
30328508
...
...
Game/AI/AIFunctions.cs
View file @
0111d23e
using
System.Collections.Generic
;
using
YGOSharp.OCGWrapper.Enums
;
namespace
WindBot.Game.AI
{
public
class
AIFunctions
...
...
@@ -151,6 +150,25 @@ namespace WindBot.Game.AI
return
bestMonster
;
}
public
ClientCard
GetWorstBotMonster
(
bool
onlyATK
=
false
)
{
int
WorstPower
=
-
1
;
ClientCard
WorstMonster
=
null
;
for
(
int
i
=
0
;
i
<
7
;
++
i
)
{
ClientCard
card
=
Bot
.
MonsterZone
[
i
];
if
(
card
==
null
||
card
.
Data
==
null
)
continue
;
if
(
onlyATK
&&
card
.
IsDefense
())
continue
;
int
newPower
=
card
.
GetDefensePower
();
if
(
newPower
<
WorstPower
)
{
WorstPower
=
newPower
;
WorstMonster
=
card
;
}
}
return
WorstMonster
;
}
public
ClientCard
GetOneEnemyBetterThanValue
(
int
value
,
bool
onlyATK
=
false
,
bool
canBeTarget
=
false
)
{
ClientCard
bestCard
=
null
;
...
...
@@ -250,12 +268,31 @@ namespace WindBot.Game.AI
List
<
ClientCard
>
monsters
=
Enemy
.
GetMonsters
();
// after GetHighestAttackMonster, the left monsters must be face-down.
if
(
monsters
.
Count
>
0
&&
!
onlyFaceup
&&
(!
canBeTarget
||
!
card
.
IsShouldNotBeTarget
())
)
if
(
monsters
.
Count
>
0
&&
!
onlyFaceup
)
return
monsters
[
0
];
return
null
;
}
public
ClientCard
GetWorstEnemyMonster
(
bool
onlyATK
=
false
)
{
int
WorstPower
=
-
1
;
ClientCard
WorstMonster
=
null
;
for
(
int
i
=
0
;
i
<
7
;
++
i
)
{
ClientCard
card
=
Enemy
.
MonsterZone
[
i
];
if
(
card
==
null
||
card
.
Data
==
null
)
continue
;
if
(
onlyATK
&&
card
.
IsDefense
())
continue
;
int
newPower
=
card
.
GetDefensePower
();
if
(
newPower
<
WorstPower
)
{
WorstPower
=
newPower
;
WorstMonster
=
card
;
}
}
return
WorstMonster
;
}
public
ClientCard
GetBestEnemySpell
(
bool
onlyFaceup
=
false
)
{
ClientCard
card
=
GetProblematicEnemySpell
();
...
...
@@ -337,6 +374,16 @@ namespace WindBot.Game.AI
return
count
;
}
public
bool
ChainContainPlayer
(
int
player
)
{
foreach
(
ClientCard
card
in
Duel
.
CurrentChain
)
{
if
(
card
.
Controller
==
player
)
return
true
;
}
return
false
;
}
public
bool
HasChainedTrap
(
int
player
)
{
foreach
(
ClientCard
card
in
Duel
.
CurrentChain
)
...
...
Game/AI/Decks/ChainBurnExecutor.cs
View file @
0111d23e
This diff is collapsed.
Click to expand it.
Game/AI/Decks/DarkMagicianExecutor.cs
0 → 100644
View file @
0111d23e
This diff is collapsed.
Click to expand it.
Game/AI/Decks/LightswornShaddoldinosourExecutor.cs
View file @
0111d23e
...
...
@@ -1052,7 +1052,7 @@ namespace WindBot.Game.AI.Decks
if
(
Card
.
Location
==
CardLocation
.
Grave
)
return
true
;
if
(
Bot
.
LifePoints
<=
1000
)
return
false
;
ClientCard
select
=
AI
.
Utils
.
GetBestEnemy
Monster
();
ClientCard
select
=
AI
.
Utils
.
GetBestEnemy
Card
();
if
(
select
==
null
)
return
false
;
if
(
select
!=
null
)
{
...
...
Game/AI/Decks/SkyStrikerExecutor.cs
View file @
0111d23e
This diff is collapsed.
Click to expand it.
Game/AI/DefaultExecutor.cs
View file @
0111d23e
...
...
@@ -25,7 +25,9 @@ namespace WindBot.Game.AI
public
const
int
DupeFrog
=
46239604
;
public
const
int
MaraudingCaptain
=
2460565
;
public
const
int
EvilswarmExcitonKnight
=
46772449
;
public
const
int
HarpiesFeatherDuster
=
18144506
;
public
const
int
DarkMagicAttack
=
2314238
;
public
const
int
MysticalSpaceTyphoon
=
5318639
;
public
const
int
CosmicCyclone
=
8267140
;
public
const
int
ChickenGame
=
67616300
;
...
...
@@ -39,6 +41,7 @@ namespace WindBot.Game.AI
public
const
int
VampireFr
ä
ulein
=
6039967
;
public
const
int
InjectionFairyLily
=
79575620
;
public
const
int
BlueEyesChaosMAXDragon
=
55410871
;
}
protected
DefaultExecutor
(
GameAI
ai
,
Duel
duel
)
...
...
@@ -469,7 +472,13 @@ namespace WindBot.Game.AI
{
if
(
Card
.
IsFaceup
()
&&
Card
.
IsDefense
()
&&
Card
.
Attack
==
0
)
return
false
;
if
(
Enemy
.
HasInMonstersZone
(
_CardId
.
BlueEyesChaosMAXDragon
)
&&
Card
.
IsAttack
()
&&
(
4000
-
Card
.
Defense
)*
2
>(
4000
-
Card
.
Attack
))
return
false
;
if
(
Enemy
.
HasInMonstersZone
(
_CardId
.
BlueEyesChaosMAXDragon
)
&&
Card
.
IsDefense
()
&&
Card
.
IsFaceup
()
&&
(
4000
-
Card
.
Defense
)
*
2
>
(
4000
-
Card
.
Attack
))
return
true
;
bool
enemyBetter
=
AI
.
Utils
.
IsAllEnemyBetter
(
true
);
if
(
Card
.
IsAttack
()
&&
enemyBetter
)
...
...
@@ -485,7 +494,9 @@ namespace WindBot.Game.AI
protected
bool
DefaultOnBecomeTarget
()
{
if
(
AI
.
Utils
.
IsChainTarget
(
Card
))
return
true
;
if
(
AI
.
Utils
.
ChainContainsCard
(
_CardId
.
EvilswarmExcitonKnight
))
return
true
;
if
(
Enemy
.
HasInSpellZone
(
_CardId
.
HarpiesFeatherDuster
,
true
))
return
true
;
if
(
Enemy
.
HasInSpellZone
(
_CardId
.
DarkMagicAttack
,
true
))
return
true
;
return
false
;
}
/// <summary>
...
...
Game/AI/Dialogs.cs
View file @
0111d23e
...
...
@@ -80,15 +80,15 @@ namespace WindBot.Game.AI
public
void
SendSorry
()
{
InternalSendMessage
(
new
[]
{
"Sorry, an error occurs."
});
InternalSendMessage
Forced
(
new
[]
{
"Sorry, an error occurs."
});
}
public
void
SendDeckSorry
(
string
card
)
{
if
(
card
==
"DECK"
)
InternalSendMessage
(
new
[]
{
"Deck illegal. Please check the database of your YGOPro and WindBot."
});
InternalSendMessage
Forced
(
new
[]
{
"Deck illegal. Please check the database of your YGOPro and WindBot."
});
else
InternalSendMessage
(
_deckerror
,
card
);
InternalSendMessage
Forced
(
_deckerror
,
card
);
}
public
void
SendWelcome
()
...
...
@@ -159,6 +159,15 @@ namespace WindBot.Game.AI
}
private
void
InternalSendMessage
(
IList
<
string
>
array
,
params
object
[]
opts
)
{
if
(!
_game
.
_chat
)
return
;
string
message
=
string
.
Format
(
array
[
Program
.
Rand
.
Next
(
array
.
Count
)],
opts
);
if
(
message
!=
""
)
_game
.
Chat
(
message
);
}
private
void
InternalSendMessageForced
(
IList
<
string
>
array
,
params
object
[]
opts
)
{
string
message
=
string
.
Format
(
array
[
Program
.
Rand
.
Next
(
array
.
Count
)],
opts
);
if
(
message
!=
""
)
...
...
Game/AI/Enums/Floodgate.cs
View file @
0111d23e
...
...
@@ -72,6 +72,7 @@
ElShaddollGrysra
=
48424886
,
ElShaddollWinda
=
94977269
,
UltimateConductorTytanno
=
18940556
,
OvertexCoatls
=
41782653
OvertexCoatls
=
41782653
,
FirePrison
=
269510
}
}
Game/AI/Enums/ShouldNotBeTarget.cs
View file @
0111d23e
...
...
@@ -43,6 +43,7 @@
FlowerCardianLightshower
=
42291297
,
YaziEviloftheYangZing
=
43202238
,
RaidraptorUltimateFalcon
=
86221741
,
DisdainfulBirdofParadise
=
27240101
DisdainfulBirdofParadise
=
27240101
,
DarkestDiabolosLordOfTheLair
=
50383626
}
}
Game/AI/Executor.cs
View file @
0111d23e
...
...
@@ -98,6 +98,11 @@ namespace WindBot.Game.AI
// Some AI need do something on new turn
}
public
virtual
void
OnDraw
(
int
player
)
{
// Some AI need do something on draw
}
public
virtual
IList
<
ClientCard
>
OnSelectCard
(
IList
<
ClientCard
>
cards
,
int
min
,
int
max
,
int
hint
,
bool
cancelable
)
{
// For overriding
...
...
@@ -146,6 +151,12 @@ namespace WindBot.Game.AI
return
null
;
}
public
virtual
IList
<
ClientCard
>
OnCardSorting
(
IList
<
ClientCard
>
cards
)
{
// For overriding
return
null
;
}
public
virtual
bool
OnSelectYesNo
(
int
desc
)
{
return
true
;
...
...
Game/ClientCard.cs
View file @
0111d23e
...
...
@@ -23,7 +23,7 @@ namespace WindBot.Game
public
int
Defense
{
get
;
private
set
;
}
public
int
LScale
{
get
;
private
set
;
}
public
int
RScale
{
get
;
private
set
;
}
public
int
Link
{
get
;
private
set
;
}
public
int
Link
Count
{
get
;
private
set
;
}
public
int
LinkMarker
{
get
;
private
set
;
}
public
int
BaseAttack
{
get
;
private
set
;
}
public
int
BaseDefense
{
get
;
private
set
;
}
...
...
@@ -136,11 +136,21 @@ namespace WindBot.Game
RScale
=
packet
.
ReadInt32
();
if
((
flag
&
(
int
)
Query
.
Link
)
!=
0
)
{
Link
=
packet
.
ReadInt32
();
Link
Count
=
packet
.
ReadInt32
();
LinkMarker
=
packet
.
ReadInt32
();
}
}
public
bool
HasLinkMarker
(
int
dir
)
{
return
((
LinkMarker
&
dir
)
!=
0
);
}
public
bool
HasLinkMarker
(
LinkMarker
dir
)
{
return
((
LinkMarker
&
(
int
)
dir
)
!=
0
);
}
public
bool
HasType
(
CardType
type
)
{
return
((
Type
&
(
int
)
type
)
!=
0
);
...
...
Game/ClientField.cs
View file @
0111d23e
...
...
@@ -71,6 +71,30 @@ namespace WindBot.Game
return
count
;
}
/// <summary>
/// Count Column
/// </summary>
/// <param zone>range of zone 0-4</param>
public
int
GetColumnCount
(
int
zone
,
bool
IncludeExtraMonsterZone
=
true
)
{
int
count
=
0
;
if
(
SpellZone
[
zone
]
!=
null
)
count
++;
if
(
MonsterZone
[
zone
]
!=
null
)
count
++;
if
(
zone
==
1
&&
IncludeExtraMonsterZone
)
{
if
(
MonsterZone
[
5
]
!=
null
)
count
++;
}
if
(
zone
==
3
&&
IncludeExtraMonsterZone
)
{
if
(
MonsterZone
[
6
]
!=
null
)
count
++;
}
return
count
;
}
public
int
GetFieldCount
()
{
...
...
@@ -218,6 +242,76 @@ namespace WindBot.Game
return
HasInCards
(
SpellZone
,
cardId
,
notDisabled
);
}
public
bool
HasInHandOrInSpellZone
(
int
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInSpellZone
(
cardId
);
}
public
bool
HasInHandOrHasInMonstersZone
(
int
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInMonstersZone
(
cardId
);
}
public
bool
HasInHandOrInGraveyard
(
int
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInMonstersZoneOrInGraveyard
(
int
cardId
)
{
return
HasInMonstersZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInSpellZoneOrInGraveyard
(
int
cardId
)
{
return
HasInSpellZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInHandOrInMonstersZoneOrInGraveyard
(
int
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInMonstersZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInHandOrInSpellZoneOrInGraveyard
(
int
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInSpellZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInHandOrInSpellZone
(
IList
<
int
>
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInSpellZone
(
cardId
);
}
public
bool
HasInHandOrHasInMonstersZone
(
IList
<
int
>
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInMonstersZone
(
cardId
);
}
public
bool
HasInHandOrInGraveyard
(
IList
<
int
>
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInMonstersZoneOrInGraveyard
(
IList
<
int
>
cardId
)
{
return
HasInMonstersZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInSpellZoneOrInGraveyard
(
IList
<
int
>
cardId
)
{
return
HasInSpellZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInHandOrInMonstersZoneOrInGraveyard
(
IList
<
int
>
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInMonstersZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
bool
HasInHandOrInSpellZoneOrInGraveyard
(
IList
<
int
>
cardId
)
{
return
HasInHand
(
cardId
)
||
HasInSpellZone
(
cardId
)
||
HasInGraveyard
(
cardId
);
}
public
int
GetRemainingCount
(
int
cardId
,
int
initialCount
)
{
int
remaining
=
initialCount
;
...
...
Game/GameAI.cs
View file @
0111d23e
...
...
@@ -70,6 +70,14 @@ namespace WindBot.Game
return
Executor
.
OnSelectHand
();
}
/// <summary>
/// Called when any player draw card.
/// </summary>
public
void
OnDraw
(
int
player
)
{
Executor
.
OnDraw
(
player
);
}
/// <summary>
/// Called when it's a new turn.
/// </summary>
...
...
@@ -329,6 +337,26 @@ namespace WindBot.Game
return
used
;
}
/// <summary>
/// Called when the AI has to sort cards.
/// </summary>
/// <param name="cards">Cards to sort.</param>
/// <returns>List of sorted cards.</returns>
public
IList
<
ClientCard
>
OnCardSorting
(
IList
<
ClientCard
>
cards
)
{
IList
<
ClientCard
>
result
=
Executor
.
OnCardSorting
(
cards
);
if
(
result
!=
null
)
return
result
;
result
=
new
List
<
ClientCard
>();
// TODO: use selector
for
(
int
i
=
0
;
i
<
cards
.
Count
;
i
++)
{
result
.
Add
(
cards
[
i
]);
}
return
result
;
}
/// <summary>
/// Called when the AI has to choose to activate or not an effect.
/// </summary>
...
...
Game/GameBehavior.cs
View file @
0111d23e
This diff is collapsed.
Click to expand it.
Game/GameClient.cs
View file @
0111d23e
...
...
@@ -14,7 +14,8 @@ namespace WindBot.Game
public
string
Deck
;
public
string
Dialog
;
public
int
Hand
;
public
bool
Debug
;
public
bool
_chat
;
private
string
_serverHost
;
private
int
_serverPort
;
private
short
_proVersion
;
...
...
@@ -29,6 +30,8 @@ namespace WindBot.Game
Deck
=
Info
.
Deck
;
Dialog
=
Info
.
Dialog
;
Hand
=
Info
.
Hand
;
Debug
=
Info
.
Debug
;
_chat
=
Info
.
Chat
;
_serverHost
=
Info
.
Host
;
_serverPort
=
Info
.
Port
;
_roomInfo
=
Info
.
HostInfo
;
...
...
Program.cs
View file @
0111d23e
...
...
@@ -74,6 +74,8 @@ namespace WindBot
Info
.
HostInfo
=
Config
.
GetString
(
"HostInfo"
,
Info
.
HostInfo
);
Info
.
Version
=
Config
.
GetInt
(
"Version"
,
Info
.
Version
);
Info
.
Hand
=
Config
.
GetInt
(
"Hand"
,
Info
.
Hand
);
Info
.
Debug
=
Config
.
GetBool
(
"Debug"
,
Info
.
Debug
);
Info
.
Chat
=
Config
.
GetBool
(
"Chat"
,
Info
.
Chat
);
Run
(
Info
);
}
...
...
@@ -114,6 +116,12 @@ namespace WindBot
string
hand
=
HttpUtility
.
ParseQueryString
(
RawUrl
).
Get
(
"hand"
);
if
(
hand
!=
null
)
Info
.
Hand
=
Int32
.
Parse
(
hand
);
string
debug
=
HttpUtility
.
ParseQueryString
(
RawUrl
).
Get
(
"debug"
);
if
(
debug
!=
null
)
Info
.
Debug
=
bool
.
Parse
(
debug
);
string
chat
=
HttpUtility
.
ParseQueryString
(
RawUrl
).
Get
(
"chat"
);
if
(
chat
!=
null
)
Info
.
Chat
=
bool
.
Parse
(
chat
);
if
(
Info
.
Name
==
null
||
Info
.
Host
==
null
||
port
==
null
)
{
...
...
WindBot.csproj
View file @
0111d23e
...
...
@@ -68,6 +68,7 @@
<Compile
Include=
"Game\AI\DecksManager.cs"
/>
<Compile
Include=
"Game\AI\Decks\BlackwingExecutor.cs"
/>
<Compile
Include=
"Game\AI\Decks\CyberDragonExecutor.cs"
/>
<Compile
Include=
"Game\AI\Decks\DarkMagicianExecutor.cs"
/>
<Compile
Include=
"Game\AI\Decks\SkyStrikerExecutor.cs"
/>
<Compile
Include=
"Game\AI\Decks\MokeyMokeyKingExecutor.cs"
/>
<Compile
Include=
"Game\AI\Decks\MokeyMokeyExecutor.cs"
/>
...
...
WindBotInfo.cs
View file @
0111d23e
...
...
@@ -12,7 +12,8 @@ namespace WindBot
public
string
HostInfo
{
get
;
set
;
}
public
int
Version
{
get
;
set
;
}
public
int
Hand
{
get
;
set
;
}
public
bool
Debug
{
get
;
set
;
}
public
bool
Chat
{
get
;
set
;
}
public
WindBotInfo
()
{
Name
=
"WindBot"
;
...
...
@@ -23,6 +24,8 @@ namespace WindBot
HostInfo
=
""
;
Version
=
0x1343
;
Hand
=
0
;
Debug
=
false
;
Chat
=
true
;
}
}
}
bots.json
View file @
0111d23e
...
...
@@ -120,6 +120,16 @@
"deck"
:
"LightswornShaddoldinosour"
,
"dialog"
:
"kiwi.zh-TW"
},
{
"name"
:
"奇魔果"
,
"deck"
:
"DarkMagician"
,
"dialog"
:
"kiwi.zh-TW"
},
{
"name"
:
"奇魔果"
,
"deck"
:
"DarkMagician"
,
"dialog"
:
"kiwi.zh-TW"
},
{
"name"
:
"燃血鬥士"
,
"deck"
:
"ChainBurn"
,
...
...
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