Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
srvpro2
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
srvpro2
Commits
ab194281
Commit
ab194281
authored
Feb 20, 2026
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
send previous duels to post watch
parent
70f2b880
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
171 additions
and
147 deletions
+171
-147
src/feats/cloud-replay/cloud-replay-service.ts
src/feats/cloud-replay/cloud-replay-service.ts
+22
-133
src/feats/cloud-replay/duel-record.entity.ts
src/feats/cloud-replay/duel-record.entity.ts
+75
-0
src/room/duel-record.ts
src/room/duel-record.ts
+57
-1
src/room/room.ts
src/room/room.ts
+17
-13
No files found.
src/feats/cloud-replay/cloud-replay-service.ts
View file @
ab194281
import
YGOProDeck
from
'
ygopro-deck-encode
'
;
import
{
import
{
ChatColor
,
ChatColor
,
HostInfo
,
HostInfo
,
NetPlayerType
,
YGOProMsgResponseBase
,
YGOProMsgWin
,
YGOProStocDuelEnd
,
YGOProStocDuelEnd
,
YGOProStocDuelStart
,
YGOProStocDuelStart
,
YGOProStocGameMsg
,
YGOProStocGameMsg
,
...
@@ -20,10 +16,6 @@ import { MenuEntry, MenuManager } from '../menu-manager';
...
@@ -20,10 +16,6 @@ import { MenuEntry, MenuManager } from '../menu-manager';
import
{
DuelRecordEntity
}
from
'
./duel-record.entity
'
;
import
{
DuelRecordEntity
}
from
'
./duel-record.entity
'
;
import
{
DuelRecordPlayer
}
from
'
./duel-record-player.entity
'
;
import
{
DuelRecordPlayer
}
from
'
./duel-record-player.entity
'
;
import
{
import
{
decodeDeckBase64
,
decodeMessagesBase64
,
decodeResponsesBase64
,
decodeSeedBase64
,
encodeCurrentDeckBase64
,
encodeCurrentDeckBase64
,
encodeDeckBase64
,
encodeDeckBase64
,
encodeIngameDeckBase64
,
encodeIngameDeckBase64
,
...
@@ -395,25 +387,25 @@ export class CloudReplayService {
...
@@ -395,25 +387,25 @@ export class CloudReplayService {
viewMode
:
ReplayWatchViewMode
=
'
default
'
,
viewMode
:
ReplayWatchViewMode
=
'
default
'
,
)
{
)
{
try
{
try
{
const
duelRecord
=
replay
.
toDuelRecord
();
await
client
.
sendChat
(
await
client
.
sendChat
(
`#{cloud_replay_playing} R#
${
replay
.
id
}
`
,
`#{cloud_replay_playing} R#
${
replay
.
id
}
`
,
ChatColor
.
BABYBLUE
,
ChatColor
.
BABYBLUE
,
);
);
await
client
.
send
(
this
.
createJoinGamePacket
(
replay
));
await
client
.
send
(
this
.
createJoinGamePacket
(
replay
));
await
this
.
sendReplayPlayers
(
client
,
replay
);
await
this
.
sendReplayPlayers
(
client
,
duelRecord
);
await
client
.
send
(
new
YGOProStocDuelStart
());
await
client
.
send
(
new
YGOProStocDuelStart
());
const
gameMessages
=
this
.
resolveReplayVisibleMessages
(
const
gameMessages
=
this
.
resolveReplayVisibleMessages
(
replay
.
messages
,
duelRecord
,
viewMode
,
viewMode
,
);
);
for
(
const
msg
of
gameMessages
)
{
for
(
const
msg
of
gameMessages
)
{
await
client
.
send
(
msg
);
await
client
.
send
(
msg
);
}
}
await
this
.
sendReplayWinMsg
(
client
,
replay
);
if
(
withYrp
)
{
if
(
withYrp
)
{
await
client
.
send
(
this
.
createReplayPacket
(
replay
));
await
client
.
send
(
this
.
createReplayPacket
(
replay
.
hostInfo
,
duelRecord
));
}
}
await
client
.
send
(
new
YGOProStocDuelEnd
());
await
client
.
send
(
new
YGOProStocDuelEnd
());
...
@@ -432,84 +424,16 @@ export class CloudReplayService {
...
@@ -432,84 +424,16 @@ export class CloudReplayService {
}
}
private
resolveReplayVisibleMessages
(
private
resolveReplayVisibleMessages
(
messagesBase64
:
string
,
duelRecord
:
DuelRecord
,
viewMode
:
ReplayWatchViewMode
=
'
default
'
,
viewMode
:
ReplayWatchViewMode
=
'
default
'
,
)
{
)
{
const
visiblePackets
=
decodeMessagesBase64
(
messagesBase64
).
filter
(
return
duelRecord
.
toObserverPlayback
(
(
packet
)
=>
{
viewMode
===
'
default
'
const
msg
=
packet
.
msg
;
?
(
msg
)
=>
msg
if
(
!
msg
)
{
:
viewMode
===
'
observer
'
return
false
;
?
(
msg
)
=>
msg
.
observerView
()
}
:
(
msg
)
=>
msg
.
playerView
(
viewMode
===
'
player0
'
?
0
:
1
),
if
(
msg
instanceof
YGOProMsgResponseBase
)
{
return
false
;
}
if
(
msg
instanceof
YGOProMsgWin
)
{
return
false
;
}
return
msg
.
getSendTargets
().
includes
(
NetPlayerType
.
OBSERVER
);
},
);
if
(
viewMode
===
'
default
'
)
{
return
visiblePackets
;
}
return
visiblePackets
.
map
((
packet
)
=>
{
const
sourceMsg
=
packet
.
msg
;
let
mappedMsg
=
sourceMsg
;
if
(
viewMode
===
'
player0
'
)
{
mappedMsg
=
sourceMsg
.
playerView
(
0
);
}
else
if
(
viewMode
===
'
player1
'
)
{
mappedMsg
=
sourceMsg
.
playerView
(
1
);
}
else
if
(
viewMode
===
'
observer
'
)
{
mappedMsg
=
sourceMsg
.
observerView
();
}
return
new
YGOProStocGameMsg
().
fromPartial
({
msg
:
mappedMsg
,
});
});
}
private
async
sendReplayWinMsg
(
client
:
Client
,
replay
:
DuelRecordEntity
)
{
const
player
=
this
.
resolveReplayWinPlayer
(
replay
);
if
(
player
==
null
)
{
return
;
}
await
client
.
send
(
new
YGOProStocGameMsg
().
fromPartial
({
msg
:
new
YGOProMsgWin
().
fromPartial
({
player
,
type
:
replay
.
winReason
,
}),
}),
);
}
private
resolveReplayWinPlayer
(
replay
:
DuelRecordEntity
)
{
const
winnerPlayer
=
replay
.
players
.
find
((
player
)
=>
player
.
winner
);
if
(
!
winnerPlayer
)
{
return
0x2
;
// PLAYER_NONE
}
const
winnerDuelPos
=
this
.
resolveDuelPosBySeat
(
winnerPlayer
.
pos
,
replay
.
hostInfo
,
);
);
const
swapped
=
this
.
resolveReplaySwappedByIsFirst
(
replay
);
return
swapped
?
1
-
winnerDuelPos
:
winnerDuelPos
;
}
private
resolveDuelPosBySeat
(
pos
:
number
,
hostInfo
:
HostInfo
)
{
const
teamOffsetBit
=
this
.
isTagMode
(
hostInfo
)
?
1
:
0
;
return
(
pos
&
(
0x1
<<
teamOffsetBit
))
>>>
teamOffsetBit
;
}
private
resolveReplaySwappedByIsFirst
(
replay
:
DuelRecordEntity
)
{
const
pos0Player
=
replay
.
players
.
find
((
player
)
=>
player
.
pos
===
0
);
return
!
pos0Player
?.
isFirst
;
}
}
private
async
downloadReplayYrp
(
private
async
downloadReplayYrp
(
...
@@ -518,11 +442,12 @@ export class CloudReplayService {
...
@@ -518,11 +442,12 @@ export class CloudReplayService {
withJoinGame
=
false
,
withJoinGame
=
false
,
)
{
)
{
try
{
try
{
const
duelRecord
=
replay
.
toDuelRecord
();
if
(
withJoinGame
)
{
if
(
withJoinGame
)
{
await
client
.
send
(
this
.
createJoinGamePacket
(
replay
));
await
client
.
send
(
this
.
createJoinGamePacket
(
replay
));
}
}
await
client
.
send
(
new
YGOProStocDuelStart
());
await
client
.
send
(
new
YGOProStocDuelStart
());
await
client
.
send
(
this
.
createReplayPacket
(
replay
));
await
client
.
send
(
this
.
createReplayPacket
(
replay
.
hostInfo
,
duelRecord
));
await
client
.
send
(
new
YGOProStocDuelEnd
());
await
client
.
send
(
new
YGOProStocDuelEnd
());
client
.
disconnect
();
client
.
disconnect
();
}
catch
(
error
)
{
}
catch
(
error
)
{
...
@@ -538,11 +463,11 @@ export class CloudReplayService {
...
@@ -538,11 +463,11 @@ export class CloudReplayService {
}
}
}
}
private
async
sendReplayPlayers
(
client
:
Client
,
replay
:
DuelRecordEntity
)
{
private
async
sendReplayPlayers
(
client
:
Client
,
duelRecord
:
DuelRecord
)
{
const
seatCount
=
this
.
resolveSeatCount
(
replay
.
hostInfo
)
;
const
seatCount
=
duelRecord
.
players
.
length
;
const
sortedPlayers
=
[...
replay
.
players
].
sort
((
a
,
b
)
=>
a
.
pos
-
b
.
pos
)
;
const
sortedPlayers
=
[...
duelRecord
.
players
]
;
for
(
let
pos
=
0
;
pos
<
seatCount
;
pos
+=
1
)
{
for
(
let
pos
=
0
;
pos
<
seatCount
;
pos
+=
1
)
{
const
player
=
sortedPlayers
.
find
((
entry
)
=>
entry
.
pos
===
pos
)
;
const
player
=
sortedPlayers
[
pos
]
;
await
client
.
send
(
await
client
.
send
(
new
YGOProStocHsPlayerEnter
().
fromPartial
({
new
YGOProStocHsPlayerEnter
().
fromPartial
({
pos
,
pos
,
...
@@ -567,18 +492,18 @@ export class CloudReplayService {
...
@@ -567,18 +492,18 @@ export class CloudReplayService {
};
};
}
}
private
createReplayPacket
(
replay
:
DuelRecordEntity
)
{
private
createReplayPacket
(
hostInfo
:
HostInfo
,
duelRecord
:
DuelRecord
)
{
const
duelRecord
=
this
.
restoreDuelRecord
(
replay
);
return
new
YGOProStocReplay
().
fromPartial
({
return
new
YGOProStocReplay
().
fromPartial
({
replay
:
duelRecord
.
toYrp
({
replay
:
duelRecord
.
toYrp
({
hostinfo
:
replay
.
hostInfo
as
any
,
hostinfo
:
hostInfo
as
any
,
isTag
:
this
.
isTagMode
(
replay
.
hostInfo
),
isTag
:
this
.
isTagMode
(
hostInfo
),
}),
}),
});
});
}
}
buildReplayYrpPayload
(
replay
:
DuelRecordEntity
)
{
buildReplayYrpPayload
(
replay
:
DuelRecordEntity
)
{
return
this
.
createReplayPacket
(
replay
).
replay
.
toYrp
();
const
duelRecord
=
replay
.
toDuelRecord
();
return
this
.
createReplayPacket
(
replay
.
hostInfo
,
duelRecord
).
replay
.
toYrp
();
}
}
async
getReplayYrpPayloadById
(
replayId
:
number
)
{
async
getReplayYrpPayloadById
(
replayId
:
number
)
{
...
@@ -589,38 +514,6 @@ export class CloudReplayService {
...
@@ -589,38 +514,6 @@ export class CloudReplayService {
return
this
.
buildReplayYrpPayload
(
replay
);
return
this
.
buildReplayYrpPayload
(
replay
);
}
}
private
restoreDuelRecord
(
replay
:
DuelRecordEntity
)
{
const
wasSwapped
=
this
.
resolveReplaySwappedByIsFirst
(
replay
);
const
seatCount
=
this
.
resolveSeatCount
(
replay
.
hostInfo
);
const
players
=
Array
.
from
({
length
:
seatCount
},
()
=>
({
name
:
''
,
deck
:
new
YGOProDeck
(),
}));
const
sortedPlayers
=
[...
replay
.
players
].
sort
((
a
,
b
)
=>
a
.
pos
-
b
.
pos
);
for
(
const
player
of
sortedPlayers
)
{
const
deckBuffer
=
player
.
ingameDeckBuffer
||
player
.
currentDeckBuffer
;
const
mainc
=
player
.
ingameDeckMainc
??
player
.
currentDeckMainc
??
0
;
if
(
player
.
pos
<
0
||
player
.
pos
>=
seatCount
)
{
continue
;
}
players
[
player
.
pos
]
=
{
name
:
player
.
name
,
deck
:
decodeDeckBase64
(
deckBuffer
,
mainc
),
};
}
const
duelRecord
=
new
DuelRecord
(
decodeSeedBase64
(
replay
.
seed
),
players
,
wasSwapped
,
);
duelRecord
.
startTime
=
replay
.
startTime
;
duelRecord
.
endTime
=
replay
.
endTime
;
duelRecord
.
responses
=
decodeResponsesBase64
(
replay
.
responses
);
return
duelRecord
;
}
private
async
getReplayPage
(
client
:
Client
):
Promise
<
ReplayPage
>
{
private
async
getReplayPage
(
client
:
Client
):
Promise
<
ReplayPage
>
{
const
cursor
=
this
.
getReplayCursor
(
client
);
const
cursor
=
this
.
getReplayCursor
(
client
);
const
firstPage
=
this
.
isFirstReplayPage
(
client
);
const
firstPage
=
this
.
isFirstReplayPage
(
client
);
...
@@ -826,10 +719,6 @@ export class CloudReplayService {
...
@@ -826,10 +719,6 @@ export class CloudReplayService {
return
(
hostInfo
.
mode
&
0x2
)
!==
0
;
return
(
hostInfo
.
mode
&
0x2
)
!==
0
;
}
}
private
resolveSeatCount
(
hostInfo
:
HostInfo
)
{
return
this
.
isTagMode
(
hostInfo
)
?
4
:
2
;
}
private
parseDirectReplayPass
(
pass
:
string
):
DirectReplayPass
|
undefined
{
private
parseDirectReplayPass
(
pass
:
string
):
DirectReplayPass
|
undefined
{
if
(
pass
.
startsWith
(
'
W0#
'
))
{
if
(
pass
.
startsWith
(
'
W0#
'
))
{
return
{
return
{
...
...
src/feats/cloud-replay/duel-record.entity.ts
View file @
ab194281
import
{
HostInfo
}
from
'
ygopro-msg-encode
'
;
import
{
HostInfo
}
from
'
ygopro-msg-encode
'
;
import
YGOProDeck
from
'
ygopro-deck-encode
'
;
import
{
import
{
Column
,
Column
,
Entity
,
Entity
,
...
@@ -8,7 +9,14 @@ import {
...
@@ -8,7 +9,14 @@ import {
PrimaryColumn
,
PrimaryColumn
,
}
from
'
typeorm
'
;
}
from
'
typeorm
'
;
import
{
BaseTimeEntity
,
BigintTransformer
}
from
'
../../utility
'
;
import
{
BaseTimeEntity
,
BigintTransformer
}
from
'
../../utility
'
;
import
{
DuelRecord
}
from
'
../../room
'
;
import
{
DuelRecordPlayer
}
from
'
./duel-record-player.entity
'
;
import
{
DuelRecordPlayer
}
from
'
./duel-record-player.entity
'
;
import
{
decodeDeckBase64
,
decodeMessagesBase64
,
decodeResponsesBase64
,
decodeSeedBase64
,
}
from
'
./utility
'
;
@
Entity
(
'
duel_record
'
)
@
Entity
(
'
duel_record
'
)
export
class
DuelRecordEntity
extends
BaseTimeEntity
{
export
class
DuelRecordEntity
extends
BaseTimeEntity
{
...
@@ -78,4 +86,71 @@ export class DuelRecordEntity extends BaseTimeEntity {
...
@@ -78,4 +86,71 @@ export class DuelRecordEntity extends BaseTimeEntity {
cascade
:
true
,
cascade
:
true
,
})
})
players
!
:
DuelRecordPlayer
[];
players
!
:
DuelRecordPlayer
[];
toDuelRecord
()
{
const
seatCount
=
this
.
resolveSeatCount
();
const
players
=
Array
.
from
({
length
:
seatCount
},
()
=>
({
name
:
''
,
deck
:
new
YGOProDeck
(),
}));
const
sortedPlayers
=
[...(
this
.
players
||
[])].
sort
(
(
a
,
b
)
=>
a
.
pos
-
b
.
pos
,
);
for
(
const
player
of
sortedPlayers
)
{
const
deckBuffer
=
player
.
ingameDeckBuffer
||
player
.
currentDeckBuffer
;
const
mainc
=
player
.
ingameDeckMainc
??
player
.
currentDeckMainc
??
0
;
if
(
player
.
pos
<
0
||
player
.
pos
>=
seatCount
)
{
continue
;
}
players
[
player
.
pos
]
=
{
name
:
player
.
name
,
deck
:
decodeDeckBase64
(
deckBuffer
,
mainc
),
};
}
const
duelRecord
=
new
DuelRecord
(
decodeSeedBase64
(
this
.
seed
),
players
,
this
.
resolveSwappedByIsFirst
(),
);
duelRecord
.
startTime
=
this
.
startTime
;
duelRecord
.
endTime
=
this
.
endTime
;
duelRecord
.
winPosition
=
this
.
resolveWinPosition
();
duelRecord
.
winReason
=
this
.
winReason
;
duelRecord
.
messages
=
decodeMessagesBase64
(
this
.
messages
).
map
(
(
packet
)
=>
packet
.
msg
,
);
duelRecord
.
responses
=
decodeResponsesBase64
(
this
.
responses
);
return
duelRecord
;
}
private
resolveWinPosition
()
{
const
winnerPlayer
=
(
this
.
players
||
[]).
find
((
player
)
=>
player
.
winner
);
if
(
!
winnerPlayer
)
{
return
undefined
;
}
return
this
.
resolveDuelPosBySeat
(
winnerPlayer
.
pos
);
}
private
resolveSwappedByIsFirst
()
{
const
pos0Player
=
(
this
.
players
||
[]).
find
((
player
)
=>
player
.
pos
===
0
);
if
(
!
pos0Player
)
{
return
false
;
}
return
!
pos0Player
.
isFirst
;
}
private
resolveDuelPosBySeat
(
pos
:
number
)
{
const
teamOffsetBit
=
this
.
isTagMode
()
?
1
:
0
;
return
(
pos
&
(
0x1
<<
teamOffsetBit
))
>>>
teamOffsetBit
;
}
private
isTagMode
()
{
return
(
this
.
hostInfo
.
mode
&
0x2
)
!==
0
;
}
private
resolveSeatCount
()
{
return
this
.
isTagMode
()
?
4
:
2
;
}
}
}
src/room/duel-record.ts
View file @
ab194281
import
YGOProDeck
from
'
ygopro-deck-encode
'
;
import
YGOProDeck
from
'
ygopro-deck-encode
'
;
import
{
YGOProYrp
,
ReplayHeader
}
from
'
ygopro-yrp-encode
'
;
import
{
YGOProYrp
,
ReplayHeader
}
from
'
ygopro-yrp-encode
'
;
import
{
Room
}
from
'
./room
'
;
import
{
Room
}
from
'
./room
'
;
import
{
YGOProMsgBase
}
from
'
ygopro-msg-encode
'
;
import
{
NetPlayerType
,
YGOProMsgBase
,
YGOProMsgResponseBase
,
YGOProMsgWin
,
YGOProStocGameMsg
,
}
from
'
ygopro-msg-encode
'
;
import
{
calculateDuelOptions
}
from
'
../utility/calculate-duel-options
'
;
import
{
calculateDuelOptions
}
from
'
../utility/calculate-duel-options
'
;
// Constants from ygopro
// Constants from ygopro
...
@@ -20,6 +26,7 @@ export class DuelRecord {
...
@@ -20,6 +26,7 @@ export class DuelRecord {
startTime
=
new
Date
();
startTime
=
new
Date
();
endTime
?:
Date
;
endTime
?:
Date
;
winPosition
?:
number
;
winPosition
?:
number
;
winReason
?:
number
;
responses
:
Buffer
[]
=
[];
responses
:
Buffer
[]
=
[];
messages
:
YGOProMsgBase
[]
=
[];
messages
:
YGOProMsgBase
[]
=
[];
...
@@ -106,4 +113,53 @@ export class DuelRecord {
...
@@ -106,4 +113,53 @@ export class DuelRecord {
return
yrp
;
return
yrp
;
}
}
*
toObserverPlayback
(
cb
:
(
msg
:
YGOProMsgBase
)
=>
YGOProMsgBase
|
undefined
=
(
msg
)
=>
msg
,
):
Generator
<
YGOProStocGameMsg
,
void
,
unknown
>
{
let
recordedWinMsg
:
YGOProMsgWin
|
undefined
;
for
(
const
message
of
this
.
messages
)
{
if
(
message
instanceof
YGOProMsgResponseBase
)
{
continue
;
}
if
(
message
instanceof
YGOProMsgWin
)
{
if
(
!
recordedWinMsg
)
{
recordedWinMsg
=
message
;
}
continue
;
}
if
(
!
message
.
getSendTargets
().
includes
(
NetPlayerType
.
OBSERVER
))
{
continue
;
}
const
mappedMsg
=
cb
(
message
);
if
(
!
mappedMsg
)
{
continue
;
}
yield
new
YGOProStocGameMsg
().
fromPartial
({
msg
:
mappedMsg
,
});
}
const
winMsg
=
this
.
resolveObserverWinMsg
()
||
recordedWinMsg
;
if
(
winMsg
)
{
yield
new
YGOProStocGameMsg
().
fromPartial
({
msg
:
winMsg
,
});
}
}
private
resolveObserverWinMsg
()
{
if
(
(
this
.
winPosition
!==
0
&&
this
.
winPosition
!==
1
)
||
typeof
this
.
winReason
!==
'
number
'
)
{
return
undefined
;
}
const
player
=
this
.
isSwapped
?
1
-
this
.
winPosition
:
this
.
winPosition
;
return
new
YGOProMsgWin
().
fromPartial
({
player
,
type
:
this
.
winReason
,
});
}
}
}
src/room/room.ts
View file @
ab194281
...
@@ -352,9 +352,20 @@ export class Room {
...
@@ -352,9 +352,20 @@ export class Room {
private
async
sendPostWatchMessages
(
client
:
Client
)
{
private
async
sendPostWatchMessages
(
client
:
Client
)
{
await
client
.
send
(
new
YGOProStocDuelStart
());
await
client
.
send
(
new
YGOProStocDuelStart
());
const
previousDuels
=
this
.
duelRecords
.
slice
(
0
,
-
1
);
if
(
previousDuels
.
length
)
{
for
(
const
duelRecord
of
previousDuels
)
{
for
(
const
message
of
duelRecord
.
toObserverPlayback
((
msg
)
=>
msg
.
observerView
(),
))
{
await
client
.
send
(
message
);
}
}
}
// 在 SelectHand / SelectTp 阶段发送 DeckCount
// 在 SelectHand / SelectTp 阶段发送 DeckCount
// Siding 阶段不发 DeckCount
// Siding 阶段不发 DeckCount
if
(
else
if
(
this
.
duelStage
===
DuelStage
.
Finger
||
this
.
duelStage
===
DuelStage
.
Finger
||
this
.
duelStage
===
DuelStage
.
FirstGo
this
.
duelStage
===
DuelStage
.
FirstGo
)
{
)
{
...
@@ -365,18 +376,10 @@ export class Room {
...
@@ -365,18 +376,10 @@ export class Room {
await
client
.
send
(
new
YGOProStocWaitingSide
());
await
client
.
send
(
new
YGOProStocWaitingSide
());
}
else
if
(
this
.
duelStage
===
DuelStage
.
Dueling
)
{
}
else
if
(
this
.
duelStage
===
DuelStage
.
Dueling
)
{
// Dueling 阶段不发 DeckCount,直接发送观战消息
// Dueling 阶段不发 DeckCount,直接发送观战消息
const
observerMessages
=
for
(
const
message
of
this
.
lastDuelRecord
?.
toObserverPlayback
((
msg
)
=>
this
.
lastDuelRecord
?.
messages
.
filter
(
msg
.
observerView
(),
(
msg
)
=>
)
||
[])
{
!
(
msg
instanceof
YGOProMsgResponseBase
)
&&
await
client
.
send
(
message
);
msg
.
getSendTargets
().
includes
(
NetPlayerType
.
OBSERVER
),
)
||
[];
for
(
const
message
of
observerMessages
)
{
await
client
.
send
(
new
YGOProStocGameMsg
().
fromPartial
({
msg
:
message
.
observerView
(),
}),
);
}
}
}
}
}
}
...
@@ -545,6 +548,7 @@ export class Room {
...
@@ -545,6 +548,7 @@ export class Room {
const
lastDuelRecord
=
this
.
lastDuelRecord
;
const
lastDuelRecord
=
this
.
lastDuelRecord
;
if
(
lastDuelRecord
&&
this
.
duelStage
===
DuelStage
.
Dueling
)
{
if
(
lastDuelRecord
&&
this
.
duelStage
===
DuelStage
.
Dueling
)
{
lastDuelRecord
.
winPosition
=
duelPos
;
lastDuelRecord
.
winPosition
=
duelPos
;
lastDuelRecord
.
winReason
=
winMsg
.
type
;
lastDuelRecord
.
endTime
=
new
Date
();
lastDuelRecord
.
endTime
=
new
Date
();
}
}
if
(
typeof
forceWinMatch
===
'
number
'
)
{
if
(
typeof
forceWinMatch
===
'
number
'
)
{
...
...
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