Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro
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
1
Merge Requests
1
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
ygopro
Commits
3516ba98
Commit
3516ba98
authored
Dec 19, 2017
by
edo9300
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'refs/remotes/origin/new-replay-system'
parents
80ffa24b
38ff205e
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1606 additions
and
1069 deletions
+1606
-1069
gframe/client_card.cpp
gframe/client_card.cpp
+4
-2
gframe/duelclient.cpp
gframe/duelclient.cpp
+101
-63
gframe/duelclient.h
gframe/duelclient.h
+4
-0
gframe/event_handler.cpp
gframe/event_handler.cpp
+2
-2
gframe/game.cpp
gframe/game.cpp
+43
-39
gframe/game.h
gframe/game.h
+4
-1
gframe/menu_handler.cpp
gframe/menu_handler.cpp
+7
-0
gframe/network.h
gframe/network.h
+3
-0
gframe/old_replay_mode.cpp
gframe/old_replay_mode.cpp
+925
-0
gframe/replay.cpp
gframe/replay.cpp
+97
-14
gframe/replay.h
gframe/replay.h
+20
-3
gframe/replay_mode.cpp
gframe/replay_mode.cpp
+98
-814
gframe/replay_mode.h
gframe/replay_mode.h
+7
-2
gframe/single_duel.cpp
gframe/single_duel.cpp
+84
-4
gframe/single_duel.h
gframe/single_duel.h
+4
-0
gframe/single_mode.cpp
gframe/single_mode.cpp
+111
-117
gframe/single_mode.h
gframe/single_mode.h
+3
-4
gframe/tag_duel.cpp
gframe/tag_duel.cpp
+82
-2
gframe/tag_duel.h
gframe/tag_duel.h
+4
-0
ocgcore
ocgcore
+1
-1
strings.conf
strings.conf
+2
-1
No files found.
gframe/client_card.cpp
View file @
3516ba98
...
...
@@ -53,7 +53,8 @@ ClientCard::ClientCard() {
void
ClientCard
::
SetCode
(
int
code
)
{
if
((
location
==
LOCATION_HAND
)
&&
(
this
->
code
!=
(
unsigned
int
)
code
))
{
this
->
code
=
code
;
mainGame
->
dField
.
MoveCard
(
this
,
5
);
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
dField
.
MoveCard
(
this
,
5
);
}
else
this
->
code
=
code
;
}
...
...
@@ -66,7 +67,8 @@ void ClientCard::UpdateInfo(char* buf) {
pdata
=
BufferIO
::
ReadInt32
(
buf
);
if
((
location
==
LOCATION_HAND
)
&&
((
unsigned
int
)
pdata
!=
code
))
{
code
=
pdata
;
mainGame
->
dField
.
MoveCard
(
this
,
5
);
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
dField
.
MoveCard
(
this
,
5
);
}
else
code
=
pdata
;
}
...
...
gframe/duelclient.cpp
View file @
3516ba98
...
...
@@ -26,6 +26,10 @@ u64 DuelClient::select_hint = 0;
wchar_t
DuelClient
::
event_string
[
256
];
mtrandom
DuelClient
::
rnd
;
std
::
vector
<
ReplayPacket
>
DuelClient
::
replay_stream
;
Replay
DuelClient
::
last_replay
;
bool
DuelClient
::
old_replay
=
true
;
bool
DuelClient
::
is_refreshing
=
false
;
int
DuelClient
::
match_kill
=
0
;
std
::
vector
<
HostPacket
>
DuelClient
::
hosts
;
...
...
@@ -693,43 +697,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame
->
btnSideReload
->
setVisible
(
false
);
mainGame
->
wChat
->
setVisible
(
true
);
mainGame
->
device
->
setEventReceiver
(
&
mainGame
->
dField
);
// reset master rule 4 phase button position
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
310
,
855
,
330
));
if
(
mainGame
->
dInfo
.
extraval
&
0x1
)
{
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
290
,
855
,
350
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
310
,
0
,
360
,
20
));
}
else
{
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
}
else
{
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
}
else
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
320
,
0
,
370
,
20
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
}
mainGame
->
SetPhaseButtons
();
if
(
!
mainGame
->
dInfo
.
isTag
)
{
if
(
selftype
>
1
)
{
mainGame
->
dInfo
.
player_type
=
7
;
...
...
@@ -767,6 +735,8 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
}
mainGame
->
gMutex
.
Unlock
();
match_kill
=
0
;
replay_stream
.
clear
();
old_replay
=
true
;
break
;
}
case
STOC_DUEL_END
:
{
...
...
@@ -803,6 +773,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
break
;
}
case
STOC_REPLAY
:
{
if
(
!
old_replay
)
break
;
mainGame
->
gMutex
.
Lock
();
mainGame
->
wPhase
->
setVisible
(
false
);
if
(
mainGame
->
dInfo
.
player_type
<
7
)
...
...
@@ -823,16 +794,28 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame
->
gMutex
.
Unlock
();
mainGame
->
replaySignal
.
Reset
();
mainGame
->
replaySignal
.
Wait
();
if
(
mainGame
->
actionParam
||
!
is_host
)
{
if
(
mainGame
->
saveReplay
||
!
is_host
)
{
char
*
prep
=
pdata
;
Replay
new_replay
;
memcpy
(
&
new_replay
.
pheader
,
prep
,
sizeof
(
ReplayHeader
));
prep
+=
sizeof
(
ReplayHeader
);
memcpy
(
new_replay
.
comp_data
,
prep
,
len
-
sizeof
(
ReplayHeader
)
-
1
);
new_replay
.
comp_size
=
len
-
sizeof
(
ReplayHeader
)
-
1
;
if
(
mainGame
->
actionParam
)
new_replay
.
SaveReplay
(
mainGame
->
ebRSName
->
getText
());
else
new_replay
.
SaveReplay
(
L"_LastReplay"
);
ReplayHeader
pheader
;
memcpy
(
&
pheader
,
prep
,
sizeof
(
ReplayHeader
));
replay_stream
.
push_back
(
ReplayPacket
(
OLD_REPLAY_MODE
,
prep
,
len
-
1
));
if
(
mainGame
->
saveReplay
)
{
last_replay
.
BeginRecord
(
false
);
last_replay
.
WriteHeader
(
pheader
);
last_replay
.
pheader
.
id
=
0x58707279
;
last_replay
.
WriteData
(
mainGame
->
dInfo
.
hostname
,
40
,
false
);
last_replay
.
WriteData
(
mainGame
->
dInfo
.
clientname
,
40
,
false
);
if
(
last_replay
.
pheader
.
flag
&
REPLAY_TAG
)
{
last_replay
.
WriteData
(
mainGame
->
dInfo
.
hostname_tag
,
40
,
false
);
last_replay
.
WriteData
(
mainGame
->
dInfo
.
clientname_tag
,
40
,
false
);
}
last_replay
.
WriteInt32
(
mainGame
->
dInfo
.
duel_field
|
mainGame
->
dInfo
.
extraval
>>
8
);
last_replay
.
WriteStream
(
replay_stream
);
last_replay
.
EndRecord
();
}
if
(
mainGame
->
saveReplay
)
last_replay
.
SaveReplay
(
mainGame
->
ebRSName
->
getText
());
else
last_replay
.
SaveReplay
(
L"_LastReplay"
);
}
break
;
}
...
...
@@ -975,12 +958,56 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame
->
gMutex
.
Unlock
();
break
;
}
case
STOC_NEW_REPLAY
:
{
old_replay
=
false
;
mainGame
->
gMutex
.
Lock
();
mainGame
->
wPhase
->
setVisible
(
false
);
if
(
mainGame
->
dInfo
.
player_type
<
7
)
mainGame
->
btnLeaveGame
->
setVisible
(
false
);
mainGame
->
btnChainIgnore
->
setVisible
(
false
);
mainGame
->
btnChainAlways
->
setVisible
(
false
);
mainGame
->
btnChainWhenAvail
->
setVisible
(
false
);
mainGame
->
btnCancelOrFinish
->
setVisible
(
false
);
time_t
nowtime
=
time
(
NULL
);
struct
tm
*
localedtime
=
localtime
(
&
nowtime
);
char
timebuf
[
40
];
strftime
(
timebuf
,
40
,
"%Y-%m-%d %H-%M-%S"
,
localedtime
);
size_t
size
=
strlen
(
timebuf
)
+
1
;
wchar_t
timetext
[
80
];
mbstowcs
(
timetext
,
timebuf
,
size
);
mainGame
->
ebRSName
->
setText
(
timetext
);
mainGame
->
PopupElement
(
mainGame
->
wReplaySave
);
mainGame
->
gMutex
.
Unlock
();
mainGame
->
replaySignal
.
Reset
();
mainGame
->
replaySignal
.
Wait
();
if
(
mainGame
->
saveReplay
||
!
is_host
)
{
char
*
prep
=
pdata
;
Replay
new_replay
;
memcpy
(
&
new_replay
.
pheader
,
prep
,
sizeof
(
ReplayHeader
));
prep
+=
sizeof
(
ReplayHeader
);
memcpy
(
new_replay
.
comp_data
,
prep
,
len
-
sizeof
(
ReplayHeader
)
-
1
);
new_replay
.
comp_size
=
len
-
sizeof
(
ReplayHeader
)
-
1
;
if
(
mainGame
->
saveReplay
)
new_replay
.
SaveReplay
(
mainGame
->
ebRSName
->
getText
());
else
new_replay
.
SaveReplay
(
L"_LastReplay"
);
}
break
;
}
}
}
int
DuelClient
::
ClientAnalyze
(
char
*
msg
,
unsigned
int
len
)
{
char
*
pbuf
=
msg
;
wchar_t
textBuffer
[
256
];
mainGame
->
dInfo
.
curMsg
=
BufferIO
::
ReadUInt8
(
pbuf
);
if
(
!
mainGame
->
dInfo
.
isReplay
||
mainGame
->
dInfo
.
isOldReplay
)
{
mainGame
->
dInfo
.
curMsg
=
BufferIO
::
ReadUInt8
(
pbuf
);
if
(
mainGame
->
dInfo
.
curMsg
!=
MSG_WAITING
)
{
ReplayPacket
p
;
p
.
message
=
mainGame
->
dInfo
.
curMsg
;
p
.
length
=
len
-
1
;
memcpy
(
p
.
data
,
pbuf
,
p
.
length
);
replay_stream
.
push_back
(
p
);
}
}
mainGame
->
wCmdMenu
->
setVisible
(
false
);
if
(
!
mainGame
->
dInfo
.
isReplay
&&
mainGame
->
dInfo
.
curMsg
!=
MSG_WAITING
&&
mainGame
->
dInfo
.
curMsg
!=
MSG_CARD_SELECTED
)
{
mainGame
->
waitFrame
=
-
1
;
...
...
@@ -1164,15 +1191,17 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
return
true
;
}
case
MSG_START
:
{
mainGame
->
showcardcode
=
11
;
mainGame
->
showcarddif
=
30
;
mainGame
->
showcardp
=
0
;
mainGame
->
showcard
=
101
;
mainGame
->
WaitFrameSignal
(
40
);
mainGame
->
showcard
=
0
;
mainGame
->
gMutex
.
Lock
();
int
playertype
=
BufferIO
::
ReadInt8
(
pbuf
);
mainGame
->
dInfo
.
isFirst
=
(
playertype
&
0xf
)
?
false
:
true
;
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
{
mainGame
->
showcardcode
=
11
;
mainGame
->
showcarddif
=
30
;
mainGame
->
showcardp
=
0
;
mainGame
->
showcard
=
101
;
mainGame
->
WaitFrameSignal
(
40
);
mainGame
->
showcard
=
0
;
mainGame
->
gMutex
.
Lock
();
mainGame
->
dInfo
.
isFirst
=
(
playertype
&
0xf
)
?
false
:
true
;
}
if
(
playertype
&
0xf0
)
mainGame
->
dInfo
.
player_type
=
7
;
if
(
mainGame
->
dInfo
.
isTag
)
{
...
...
@@ -1197,24 +1226,29 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame
->
dField
.
Initial
(
mainGame
->
LocalPlayer
(
1
),
deckc
,
extrac
);
mainGame
->
dInfo
.
turn
=
0
;
mainGame
->
dInfo
.
is_shuffling
=
false
;
mainGame
->
gMutex
.
Unlock
();
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Unlock
();
return
true
;
}
case
MSG_UPDATE_DATA
:
{
int
player
=
mainGame
->
LocalPlayer
(
BufferIO
::
ReadInt8
(
pbuf
));
int
location
=
BufferIO
::
ReadInt8
(
pbuf
);
mainGame
->
gMutex
.
Lock
();
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Lock
();
mainGame
->
dField
.
UpdateFieldCard
(
player
,
location
,
pbuf
);
mainGame
->
gMutex
.
Unlock
();
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Unlock
();
return
true
;
}
case
MSG_UPDATE_CARD
:
{
int
player
=
mainGame
->
LocalPlayer
(
BufferIO
::
ReadInt8
(
pbuf
));
int
loc
=
BufferIO
::
ReadInt8
(
pbuf
);
int
seq
=
BufferIO
::
ReadInt8
(
pbuf
);
mainGame
->
gMutex
.
Lock
();
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Lock
();
mainGame
->
dField
.
UpdateCard
(
player
,
loc
,
seq
,
pbuf
);
mainGame
->
gMutex
.
Unlock
();
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Unlock
();
break
;
}
case
MSG_SELECT_BATTLECMD
:
{
...
...
@@ -3729,11 +3763,13 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
break
;
}
case
MSG_RELOAD_FIELD
:
{
mainGame
->
gMutex
.
Lock
();
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Lock
();
mainGame
->
dField
.
Clear
();
int
field
=
BufferIO
::
ReadInt8
(
pbuf
);
mainGame
->
dInfo
.
duel_field
=
field
&
0xf
;
mainGame
->
dInfo
.
extraval
=
field
>>
4
;
mainGame
->
SetPhaseButtons
();
int
val
=
0
;
for
(
int
i
=
0
;
i
<
2
;
++
i
)
{
int
p
=
mainGame
->
LocalPlayer
(
i
);
...
...
@@ -3848,7 +3884,8 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
myswprintf
(
event_string
,
dataManager
.
GetSysString
(
1609
),
dataManager
.
GetName
(
mainGame
->
dField
.
current_chain
.
code
));
mainGame
->
dField
.
last_chain
=
true
;
}
mainGame
->
gMutex
.
Unlock
();
if
(
!
mainGame
->
dInfo
.
isReplay
||
!
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Unlock
();
break
;
}
}
...
...
@@ -3914,10 +3951,11 @@ void DuelClient::SendResponse() {
break
;
}
}
replay_stream
.
pop_back
();
if
(
mainGame
->
dInfo
.
isSingleMode
)
{
SingleMode
::
SetResponse
(
response_buf
,
response_len
);
mainGame
->
singleSignal
.
Set
();
}
else
{
}
else
if
(
!
mainGame
->
dInfo
.
isReplay
)
{
mainGame
->
dInfo
.
time_player
=
2
;
SendBufferToServer
(
CTOS_RESPONSE
,
response_buf
,
response_len
);
}
...
...
gframe/duelclient.h
View file @
3516ba98
...
...
@@ -13,6 +13,7 @@
#include "data_manager.h"
#include "deck_manager.h"
#include "../ocgcore/mtrandom.h"
#include "replay.h"
namespace
ygo
{
...
...
@@ -45,6 +46,9 @@ public:
static
void
ClientEvent
(
bufferevent
*
bev
,
short
events
,
void
*
ctx
);
static
int
ClientThread
(
void
*
param
);
static
void
HandleSTOCPacketLan
(
char
*
data
,
unsigned
int
len
);
static
std
::
vector
<
ReplayPacket
>
replay_stream
;
static
Replay
last_replay
;
static
bool
old_replay
;
static
int
ClientAnalyze
(
char
*
msg
,
unsigned
int
len
);
static
void
SetResponseI
(
int
respI
);
static
void
SetResponseB
(
void
*
respB
,
unsigned
char
len
);
...
...
gframe/event_handler.cpp
View file @
3516ba98
...
...
@@ -95,13 +95,13 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case
BUTTON_REPLAY_SAVE
:
{
if
(
mainGame
->
ebRSName
->
getText
()[
0
]
==
0
)
break
;
mainGame
->
actionParam
=
1
;
mainGame
->
saveReplay
=
1
;
mainGame
->
HideElement
(
mainGame
->
wReplaySave
);
mainGame
->
replaySignal
.
Set
();
break
;
}
case
BUTTON_REPLAY_CANCEL
:
{
mainGame
->
actionParam
=
0
;
mainGame
->
saveReplay
=
0
;
mainGame
->
HideElement
(
mainGame
->
wReplaySave
);
mainGame
->
replaySignal
.
Set
();
break
;
...
...
gframe/game.cpp
View file @
3516ba98
...
...
@@ -617,6 +617,7 @@ bool Game::Initialize() {
btnReplayCancel
=
env
->
addButton
(
rect
<
s32
>
(
460
,
385
,
570
,
410
),
wReplay
,
BUTTON_CANCEL_REPLAY
,
dataManager
.
GetSysString
(
1347
));
env
->
addStaticText
(
dataManager
.
GetSysString
(
1349
),
rect
<
s32
>
(
360
,
30
,
570
,
50
),
false
,
true
,
wReplay
);
stReplayInfo
=
env
->
addStaticText
(
L""
,
rect
<
s32
>
(
360
,
60
,
570
,
350
),
false
,
true
,
wReplay
);
chkYrp
=
env
->
addCheckBox
(
false
,
recti
(
360
,
250
,
560
,
270
),
wReplay
,
-
1
,
dataManager
.
GetSysString
(
1999
));
env
->
addStaticText
(
dataManager
.
GetSysString
(
1353
),
rect
<
s32
>
(
360
,
275
,
570
,
295
),
false
,
true
,
wReplay
);
ebRepStartTurn
=
env
->
addEditBox
(
L""
,
rect
<
s32
>
(
360
,
300
,
460
,
320
),
true
,
wReplay
,
-
1
);
ebRepStartTurn
->
setTextAlignment
(
irr
::
gui
::
EGUIA_CENTER
,
irr
::
gui
::
EGUIA_CENTER
);
...
...
@@ -1228,7 +1229,7 @@ bool Game::PlayChant(unsigned int code) {
return
false
;
}
void
Game
::
PlaySoundEffect
(
char
*
sound
)
{
if
(
chkEnableSound
->
isChecked
())
{
if
(
chkEnableSound
->
isChecked
()
&&
(
!
dInfo
.
isReplay
||
!
dInfo
.
isReplaySkiping
)
)
{
engineSound
->
play2D
(
sound
);
engineSound
->
setSoundVolume
(
gameConf
.
volume
);
}
...
...
@@ -1563,8 +1564,46 @@ int Game::GetMasterRule(uint32 param, uint32 forbiddentypes, int* truerule) {
}
}
}
void
Game
::
OnResize
()
{
void
Game
::
SetPhaseButtons
()
{
// reset master rule 4 phase button position
wPhase
->
setRelativePosition
(
Resize
(
480
,
310
,
855
,
330
));
if
(
dInfo
.
extraval
&
0x1
)
{
if
(
dInfo
.
duel_field
>=
4
)
{
wPhase
->
setRelativePosition
(
Resize
(
480
,
290
,
855
,
350
));
btnShuffle
->
setRelativePosition
(
Resize
(
0
,
40
,
50
,
60
));
btnDP
->
setRelativePosition
(
Resize
(
0
,
40
,
50
,
60
));
btnSP
->
setRelativePosition
(
Resize
(
0
,
40
,
50
,
60
));
btnM1
->
setRelativePosition
(
Resize
(
160
,
20
,
210
,
40
));
btnBP
->
setRelativePosition
(
Resize
(
160
,
20
,
210
,
40
));
btnM2
->
setRelativePosition
(
Resize
(
160
,
20
,
210
,
40
));
btnEP
->
setRelativePosition
(
Resize
(
310
,
0
,
360
,
20
));
}
else
{
btnShuffle
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnDP
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnSP
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnM1
->
setRelativePosition
(
Resize
(
130
,
0
,
180
,
20
));
btnBP
->
setRelativePosition
(
Resize
(
195
,
0
,
245
,
20
));
btnM2
->
setRelativePosition
(
Resize
(
260
,
0
,
310
,
20
));
btnEP
->
setRelativePosition
(
Resize
(
260
,
0
,
310
,
20
));
}
}
else
{
btnDP
->
setRelativePosition
(
Resize
(
0
,
0
,
50
,
20
));
if
(
dInfo
.
duel_field
>=
4
)
{
btnSP
->
setRelativePosition
(
Resize
(
0
,
0
,
50
,
20
));
btnM1
->
setRelativePosition
(
Resize
(
160
,
0
,
210
,
20
));
btnBP
->
setRelativePosition
(
Resize
(
160
,
0
,
210
,
20
));
btnM2
->
setRelativePosition
(
Resize
(
160
,
0
,
210
,
20
));
}
else
{
btnSP
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnM1
->
setRelativePosition
(
Resize
(
130
,
0
,
180
,
20
));
btnBP
->
setRelativePosition
(
Resize
(
195
,
0
,
245
,
20
));
btnM2
->
setRelativePosition
(
Resize
(
260
,
0
,
310
,
20
));
}
btnEP
->
setRelativePosition
(
Resize
(
320
,
0
,
370
,
20
));
btnShuffle
->
setRelativePosition
(
Resize
(
0
,
0
,
50
,
20
));
}
}
void
Game
::
OnResize
()
{
wMainMenu
->
setRelativePosition
(
ResizeWin
(
370
,
200
,
650
,
415
));
wDeckEdit
->
setRelativePosition
(
Resize
(
309
,
8
,
605
,
130
));
cbDBLFList
->
setRelativePosition
(
Resize
(
80
,
5
,
220
,
30
));
...
...
@@ -1662,42 +1701,7 @@ void Game::OnResize()
btnReplaySwap
->
setRelativePosition
(
Resize
(
5
,
30
,
85
,
50
));
btnReplayExit
->
setRelativePosition
(
Resize
(
5
,
105
,
85
,
125
));
wPhase
->
setRelativePosition
(
Resize
(
480
,
310
,
855
,
330
));
if
(
dInfo
.
extraval
&
0x1
)
{
if
(
dInfo
.
duel_field
>=
4
)
{
wPhase
->
setRelativePosition
(
Resize
(
480
,
290
,
855
,
350
));
btnShuffle
->
setRelativePosition
(
Resize
(
0
,
40
,
50
,
60
));
btnDP
->
setRelativePosition
(
Resize
(
0
,
40
,
50
,
60
));
btnSP
->
setRelativePosition
(
Resize
(
0
,
40
,
50
,
60
));
btnM1
->
setRelativePosition
(
Resize
(
160
,
20
,
210
,
40
));
btnBP
->
setRelativePosition
(
Resize
(
160
,
20
,
210
,
40
));
btnM2
->
setRelativePosition
(
Resize
(
160
,
20
,
210
,
40
));
btnEP
->
setRelativePosition
(
Resize
(
310
,
0
,
360
,
20
));
}
else
{
btnShuffle
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnDP
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnSP
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnM1
->
setRelativePosition
(
Resize
(
130
,
0
,
180
,
20
));
btnBP
->
setRelativePosition
(
Resize
(
195
,
0
,
245
,
20
));
btnM2
->
setRelativePosition
(
Resize
(
260
,
0
,
310
,
20
));
btnEP
->
setRelativePosition
(
Resize
(
260
,
0
,
310
,
20
));
}
}
else
{
btnDP
->
setRelativePosition
(
Resize
(
0
,
0
,
50
,
20
));
if
(
dInfo
.
duel_field
>=
4
)
{
btnSP
->
setRelativePosition
(
Resize
(
0
,
0
,
50
,
20
));
btnM1
->
setRelativePosition
(
Resize
(
160
,
0
,
210
,
20
));
btnBP
->
setRelativePosition
(
Resize
(
160
,
0
,
210
,
20
));
btnM2
->
setRelativePosition
(
Resize
(
160
,
0
,
210
,
20
));
}
else
{
btnSP
->
setRelativePosition
(
Resize
(
65
,
0
,
115
,
20
));
btnM1
->
setRelativePosition
(
Resize
(
130
,
0
,
180
,
20
));
btnBP
->
setRelativePosition
(
Resize
(
195
,
0
,
245
,
20
));
btnM2
->
setRelativePosition
(
Resize
(
260
,
0
,
310
,
20
));
}
btnEP
->
setRelativePosition
(
Resize
(
320
,
0
,
370
,
20
));
btnShuffle
->
setRelativePosition
(
Resize
(
0
,
0
,
50
,
20
));
}
SetPhaseButtons
();
btnSpectatorSwap
->
setRelativePosition
(
Resize
(
205
,
100
,
295
,
135
));
btnChainAlways
->
setRelativePosition
(
Resize
(
205
,
140
,
295
,
175
));
btnChainIgnore
->
setRelativePosition
(
Resize
(
205
,
100
,
295
,
135
));
...
...
gframe/game.h
View file @
3516ba98
...
...
@@ -48,6 +48,7 @@ struct Config {
struct
DuelInfo
{
bool
isStarted
;
bool
isReplay
;
bool
isOldReplay
;
bool
isReplaySkiping
;
bool
isFirst
;
bool
isTag
;
...
...
@@ -134,6 +135,7 @@ public:
const
wchar_t
*
LocalName
(
int
local_player
);
void
UpdateDuelParam
();
int
GetMasterRule
(
uint32
param
,
uint32
forbidden
,
int
*
truerule
=
0
);
void
SetPhaseButtons
();
bool
HasFocus
(
EGUI_ELEMENT_TYPE
type
)
const
{
irr
::
gui
::
IGUIElement
*
focus
=
env
->
getFocus
();
...
...
@@ -170,7 +172,7 @@ public:
unsigned
short
linePattern
;
int
waitFrame
;
int
signalFrame
;
int
actionParam
;
int
saveReplay
;
const
wchar_t
*
showingtext
;
int
showcard
;
int
showcardcode
;
...
...
@@ -309,6 +311,7 @@ public:
irr
::
gui
::
IGUIWindow
*
wReplay
;
irr
::
gui
::
IGUIListBox
*
lstReplayList
;
irr
::
gui
::
IGUIStaticText
*
stReplayInfo
;
irr
::
gui
::
IGUICheckBox
*
chkYrp
;
irr
::
gui
::
IGUIButton
*
btnLoadReplay
;
irr
::
gui
::
IGUIButton
*
btnReplayCancel
;
irr
::
gui
::
IGUIEditBox
*
ebRepStartTurn
;
...
...
gframe/menu_handler.cpp
View file @
3516ba98
...
...
@@ -274,6 +274,8 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if
(
!
ReplayMode
::
cur_replay
.
OpenReplay
(
mainGame
->
lstReplayList
->
getListItem
(
mainGame
->
lstReplayList
->
getSelected
())))
break
;
}
if
(
mainGame
->
chkYrp
->
isChecked
()
&&
!
ReplayMode
::
cur_replay
.
LoadYrp
())
break
;
mainGame
->
imgCard
->
setImage
(
imageManager
.
tCover
[
0
]);
mainGame
->
wCardImg
->
setVisible
(
true
);
mainGame
->
wInfos
->
setVisible
(
true
);
...
...
@@ -393,6 +395,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
repinfo
.
append
(
infobuf
);
mainGame
->
ebRepStartTurn
->
setText
(
L"1"
);
mainGame
->
SetStaticText
(
mainGame
->
stReplayInfo
,
180
,
mainGame
->
guiFont
,
(
wchar_t
*
)
repinfo
.
c_str
());
if
(
ReplayMode
::
cur_replay
.
pheader
.
id
==
0x31707279
)
{
mainGame
->
chkYrp
->
setChecked
(
false
);
mainGame
->
chkYrp
->
setEnabled
(
false
);
}
else
mainGame
->
chkYrp
->
setEnabled
(
true
);
break
;
}
}
...
...
gframe/network.h
View file @
3516ba98
...
...
@@ -215,6 +215,9 @@ public:
#define STOC_HS_PLAYER_CHANGE 0x21
#define STOC_HS_WATCH_CHANGE 0x22
#define STOC_NEW_REPLAY 0x30
#define PLAYERCHANGE_OBSERVE 0x8
#define PLAYERCHANGE_READY 0x9
#define PLAYERCHANGE_NOTREADY 0xa
...
...
gframe/old_replay_mode.cpp
0 → 100644
View file @
3516ba98
#include "replay_mode.h"
#include "duelclient.h"
#include "game.h"
#include "single_mode.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
namespace
ygo
{
bool
ReplayMode
::
ReadReplayResponse
()
{
unsigned
char
resp
[
64
];
bool
result
=
cur_replay
.
ReadNextResponse
(
resp
);
if
(
result
)
set_responseb
(
pduel
,
resp
);
return
result
;
}
int
ReplayMode
::
OldReplayThread
(
void
*
param
)
{
const
ReplayHeader
&
rh
=
cur_replay
.
pheader
;
mainGame
->
dInfo
.
isFirst
=
true
;
mainGame
->
dInfo
.
isTag
=
!!
(
rh
.
flag
&
REPLAY_TAG
);
mainGame
->
dInfo
.
isSingleMode
=
!!
(
rh
.
flag
&
REPLAY_SINGLE_MODE
);
mainGame
->
dInfo
.
lua64
=
true
;
mainGame
->
dInfo
.
tag_player
[
0
]
=
false
;
mainGame
->
dInfo
.
tag_player
[
1
]
=
false
;
if
(
mainGame
->
dInfo
.
isSingleMode
)
{
set_script_reader
((
script_reader
)
SingleMode
::
ScriptReader
);
set_card_reader
((
card_reader
)
DataManager
::
CardReader
);
set_message_handler
((
message_handler
)
MessageHandler
);
}
else
{
set_script_reader
(
default_script_reader
);
set_card_reader
((
card_reader
)
DataManager
::
CardReader
);
set_message_handler
((
message_handler
)
MessageHandler
);
}
if
(
!
StartDuel
())
{
EndDuel
();
return
0
;
}
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplay
=
true
;
mainGame
->
dInfo
.
isOldReplay
=
true
;
mainGame
->
dInfo
.
isReplaySkiping
=
(
skip_turn
>
0
);
char
engineBuffer
[
0x1000
];
is_continuing
=
true
;
skip_step
=
0
;
if
(
mainGame
->
dInfo
.
isSingleMode
)
{
int
len
=
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
if
(
len
>
0
)
is_continuing
=
ReplayAnalyze
(
engineBuffer
,
len
);
}
else
{
ReplayRefreshDeck
(
0
);
ReplayRefreshDeck
(
1
);
ReplayRefreshExtra
(
0
);
ReplayRefreshExtra
(
1
);
}
exit_pending
=
false
;
current_step
=
0
;
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Lock
();
while
(
is_continuing
&&
!
exit_pending
)
{
int
result
=
process
(
pduel
);
int
len
=
result
&
0xffff
;
/*int flag = result >> 16;*/
if
(
len
>
0
)
{
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
is_continuing
=
ReplayAnalyze
(
engineBuffer
,
len
);
if
(
is_restarting
)
{
is_restarting
=
false
;
int
step
=
current_step
-
1
;
if
(
step
<
0
)
step
=
0
;
if
(
mainGame
->
dInfo
.
isSingleMode
)
{
is_continuing
=
true
;
skip_step
=
0
;
int
len
=
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
if
(
len
>
0
)
{
mainGame
->
gMutex
.
Unlock
();
is_continuing
=
ReplayAnalyze
(
engineBuffer
,
len
);
mainGame
->
gMutex
.
Lock
();
}
}
if
(
step
==
0
)
{
Pause
(
true
,
false
);
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
skip_step
=
step
;
current_step
=
0
;
}
}
}
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
{
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
EndDuel
();
return
0
;
}
bool
ReplayMode
::
StartDuel
()
{
const
ReplayHeader
&
rh
=
cur_replay
.
pheader
;
mtrandom
rnd
;
int
seed
=
rh
.
seed
;
rnd
.
reset
(
seed
);
if
(
mainGame
->
dInfo
.
isTag
)
{
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname_tag
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname_tag
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname
);
}
else
{
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname
);
}
pduel
=
create_duel
(
rnd
.
rand
());
int
start_lp
=
cur_replay
.
ReadInt32
();
int
start_hand
=
cur_replay
.
ReadInt32
();
int
draw_count
=
cur_replay
.
ReadInt32
();
int
opt
=
cur_replay
.
ReadInt32
();
int
duel_rule
=
opt
>>
16
;
int
rule
=
opt
>>
16
;
//backwards compatibility with master rule replays
if
(
rule
)
switch
(
rule
)
{
case
1
:
{
opt
|=
MASTER_RULE_1
;
break
;
}
case
2
:
{
opt
|=
MASTER_RULE_2
;
break
;
}
case
3
:
{
opt
|=
MASTER_RULE_3
;
break
;
}
case
4
:
{
opt
|=
MASTER_RULE_4
;
break
;
}
}
//pre mr4 replay compatibility
if
(
opt
&
DUEL_OBSOLETE_RULING
)
{
opt
&=
~
DUEL_OBSOLETE_RULING
;
opt
|=
MASTER_RULE_1
;
}
else
if
(
!
(
opt
&
0xff80
))
opt
|=
MASTER_RULE_3
;
mainGame
->
dInfo
.
duel_field
=
2
;
if
((
opt
&
DUEL_PZONE
)
&&
(
opt
&
DUEL_SEPARATE_PZONE
)
&&
(
opt
&
DUEL_EMZONE
))
mainGame
->
dInfo
.
duel_field
=
5
;
else
if
(
opt
&
DUEL_EMZONE
)
mainGame
->
dInfo
.
duel_field
=
4
;
else
if
(
opt
&
DUEL_PZONE
)
mainGame
->
dInfo
.
duel_field
=
3
;
mainGame
->
dInfo
.
extraval
=
!!
(
opt
&
SPEED_DUEL
);
// reset master rule 4 phase button position
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
310
,
855
,
330
));
if
(
mainGame
->
dInfo
.
extraval
)
{
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
290
,
855
,
350
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
310
,
0
,
360
,
20
));
}
else
{
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
}
else
{
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
}
else
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
320
,
0
,
370
,
20
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
}
set_player_info
(
pduel
,
0
,
start_lp
,
start_hand
,
draw_count
);
set_player_info
(
pduel
,
1
,
start_lp
,
start_hand
,
draw_count
);
mainGame
->
dInfo
.
lp
[
0
]
=
start_lp
;
mainGame
->
dInfo
.
lp
[
1
]
=
start_lp
;
mainGame
->
dInfo
.
startlp
=
start_lp
;
myswprintf
(
mainGame
->
dInfo
.
strLP
[
0
],
L"%d"
,
mainGame
->
dInfo
.
lp
[
0
]);
myswprintf
(
mainGame
->
dInfo
.
strLP
[
1
],
L"%d"
,
mainGame
->
dInfo
.
lp
[
1
]);
mainGame
->
dInfo
.
turn
=
0
;
if
(
!
mainGame
->
dInfo
.
isSingleMode
)
{
if
(
!
(
opt
&
DUEL_TAG_MODE
))
{
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
0
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
}
else
{
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
0
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
LOCATION_DECK
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
LOCATION_EXTRA
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
LOCATION_DECK
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
LOCATION_EXTRA
);
}
}
else
{
char
filename
[
256
];
size_t
slen
=
cur_replay
.
ReadInt16
();
cur_replay
.
ReadData
(
filename
,
slen
);
filename
[
slen
]
=
0
;
if
(
!
preload_script
(
pduel
,
filename
,
slen
))
{
return
false
;
}
}
start_duel
(
pduel
,
opt
);
return
true
;
}
bool
ReplayMode
::
ReplayAnalyze
(
char
*
msg
,
unsigned
int
len
)
{
char
*
pbuf
=
msg
;
int
player
,
count
;
is_restarting
=
false
;
while
(
pbuf
-
msg
<
(
int
)
len
)
{
if
(
is_closing
)
return
false
;
if
(
is_restarting
)
{
//is_restarting = false;
return
true
;
}
if
(
is_swapping
)
{
mainGame
->
gMutex
.
Lock
();
mainGame
->
dField
.
ReplaySwap
();
mainGame
->
gMutex
.
Unlock
();
is_swapping
=
false
;
}
char
*
offset
=
pbuf
;
bool
pauseable
=
true
;
mainGame
->
dInfo
.
curMsg
=
BufferIO
::
ReadUInt8
(
pbuf
);
switch
(
mainGame
->
dInfo
.
curMsg
)
{
case
MSG_RETRY
:
{
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
{
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
mainGame
->
gMutex
.
Lock
();
mainGame
->
stMessage
->
setText
(
L"Error occurs."
);
mainGame
->
PopupElement
(
mainGame
->
wMessage
);
mainGame
->
gMutex
.
Unlock
();
mainGame
->
actionSignal
.
Reset
();
mainGame
->
actionSignal
.
Wait
();
return
false
;
}
case
MSG_HINT
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
10
:
6
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_WIN
:
{
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
{
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
pbuf
+=
2
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
return
false
;
}
case
MSG_SELECT_BATTLECMD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
(
mainGame
->
dInfo
.
lua64
)
?
15
:
11
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
+
2
;
ReplayRefresh
();
return
ReadReplayResponse
();
}
case
MSG_SELECT_IDLECMD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
(
mainGame
->
dInfo
.
lua64
)
?
15
:
11
+
3
;
ReplayRefresh
();
return
ReadReplayResponse
();
}
case
MSG_SELECT_EFFECTYN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
16
:
12
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_YESNO
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
8
:
4
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_OPTION
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
(
mainGame
->
dInfo
.
lua64
)
?
8
:
4
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_CARD
:
case
MSG_SELECT_TRIBUTE
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
3
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_UNSELECT_CARD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
4
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_CHAIN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
10
+
count
*
(
mainGame
->
dInfo
.
lua64
)
?
17
:
13
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_PLACE
:
case
MSG_SELECT_DISFIELD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_POSITION
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_COUNTER
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
4
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
9
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_SUM
:
{
pbuf
++
;
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
6
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
11
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
11
;
return
ReadReplayResponse
();
}
case
MSG_SORT_CARD
:
case
MSG_SORT_CHAIN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
return
ReadReplayResponse
();
}
case
MSG_CONFIRM_DECKTOP
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CONFIRM_EXTRATOP
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CONFIRM_CARDS
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SHUFFLE_DECK
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshDeck
(
player
);
break
;
}
case
MSG_SHUFFLE_HAND
:
{
/*int oplayer = */
BufferIO
::
ReadInt8
(
pbuf
);
int
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SHUFFLE_EXTRA
:
{
/*int oplayer = */
BufferIO
::
ReadInt8
(
pbuf
);
int
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_REFRESH_DECK
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SWAP_GRAVE_DECK
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshGrave
(
player
);
break
;
}
case
MSG_REVERSE_DECK
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshDeck
(
0
);
ReplayRefreshDeck
(
1
);
break
;
}
case
MSG_DECK_TOP
:
{
pbuf
+=
6
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SHUFFLE_SET_CARD
:
{
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_NEW_TURN
:
{
if
(
skip_turn
)
{
skip_turn
--
;
if
(
skip_turn
==
0
)
{
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
}
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_NEW_PHASE
:
{
pbuf
+=
2
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_MOVE
:
{
int
pc
=
pbuf
[
4
];
int
pl
=
pbuf
[
5
];
/*int ps = pbuf[6];*/
/*int pp = pbuf[7];*/
int
cc
=
pbuf
[
8
];
int
cl
=
pbuf
[
9
];
int
cs
=
pbuf
[
10
];
/*int cp = pbuf[11];*/
pbuf
+=
16
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
if
(
cl
&&
!
(
cl
&
0x80
)
&&
(
pl
!=
cl
||
pc
!=
cc
))
ReplayRefreshSingle
(
cc
,
cl
,
cs
);
break
;
}
case
MSG_POS_CHANGE
:
{
pbuf
+=
9
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SET
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SWAP
:
{
pbuf
+=
16
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_FIELD_DISABLED
:
{
pbuf
+=
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SUMMONING
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SUMMONED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_SPSUMMONING
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SPSUMMONED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_FLIPSUMMONING
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_FLIPSUMMONED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_CHAINING
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
20
:
16
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CHAINED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_CHAIN_SOLVING
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_CHAIN_SOLVED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_CHAIN_END
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_CHAIN_NEGATED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CHAIN_DISABLED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CARD_SELECTED
:
case
MSG_RANDOM_SELECTED
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_BECOME_TARGET
:
{
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_DRAW
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_DAMAGE
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_RECOVER
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_EQUIP
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_LPUPDATE
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_UNEQUIP
:
{
pbuf
+=
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_CARD_TARGET
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_CANCEL_TARGET
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_PAY_LPCOST
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ADD_COUNTER
:
{
pbuf
+=
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_REMOVE_COUNTER
:
{
pbuf
+=
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ATTACK
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_BATTLE
:
{
pbuf
+=
26
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_ATTACK_DISABLED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_DAMAGE_STEP_START
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_DAMAGE_STEP_END
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_MISSED_EFFECT
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_TOSS_COIN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_TOSS_DICE
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ROCK_PAPER_SCISSORS
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
return
ReadReplayResponse
();
}
case
MSG_HAND_RES
:
{
pbuf
+=
1
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ANNOUNCE_RACE
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_ANNOUNCE_ATTRIB
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_ANNOUNCE_CARD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
4
;
return
ReadReplayResponse
();
}
case
MSG_ANNOUNCE_NUMBER
:
case
MSG_ANNOUNCE_CARD_FILTER
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
8
:
4
*
count
;
return
ReadReplayResponse
();
}
case
MSG_CARD_HINT
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
13
:
9
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_PLAYER_HINT
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
10
:
6
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_MATCH_KILL
:
{
pbuf
+=
4
;
break
;
}
case
MSG_TAG_SWAP
:
{
player
=
pbuf
[
0
];
pbuf
+=
pbuf
[
2
]
*
4
+
pbuf
[
4
]
*
4
+
9
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshDeck
(
player
);
ReplayRefreshExtra
(
player
);
break
;
}
case
MSG_RELOAD_FIELD
:
{
pbuf
++
;
for
(
int
p
=
0
;
p
<
2
;
++
p
)
{
pbuf
+=
4
;
for
(
int
seq
=
0
;
seq
<
7
;
++
seq
)
{
int
val
=
BufferIO
::
ReadInt8
(
pbuf
);
if
(
val
)
pbuf
+=
2
;
}
for
(
int
seq
=
0
;
seq
<
8
;
++
seq
)
{
int
val
=
BufferIO
::
ReadInt8
(
pbuf
);
if
(
val
)
pbuf
++
;
}
pbuf
+=
6
;
}
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayReload
();
mainGame
->
dField
.
RefreshAllCards
();
break
;
}
case
MSG_AI_NAME
:
{
int
len
=
BufferIO
::
ReadInt16
(
pbuf
);
pbuf
+=
len
+
1
;
break
;
}
case
MSG_SHOW_HINT
:
{
int
len
=
BufferIO
::
ReadInt16
(
pbuf
);
pbuf
+=
len
+
1
;
break
;
}
}
if
(
pauseable
)
{
current_step
++
;
if
(
skip_step
)
{
skip_step
--
;
if
(
skip_step
==
0
)
{
Pause
(
true
,
false
);
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
}
if
(
is_pausing
)
{
is_paused
=
true
;
mainGame
->
actionSignal
.
Reset
();
mainGame
->
actionSignal
.
Wait
();
is_paused
=
false
;
}
}
}
return
true
;
}
void
ReplayMode
::
ReplayRefresh
(
int
flag
)
{
unsigned
char
queryBuffer
[
0x4000
];
/*int len = */
query_field_card
(
pduel
,
0
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshHand
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshGrave
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshDeck
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshExtra
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x4000
];
/*int len = */
query_card
(
pduel
,
player
,
location
,
sequence
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateCard
(
mainGame
->
LocalPlayer
(
player
),
location
,
sequence
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayReload
()
{
unsigned
char
queryBuffer
[
0x4000
];
unsigned
int
flag
=
0xffdfff
;
/*int len = */
query_field_card
(
pduel
,
0
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_REMOVED
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_REMOVED
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_REMOVED
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_REMOVED
,
(
char
*
)
queryBuffer
);
}
int
ReplayMode
::
MessageHandler
(
long
fduel
,
int
type
)
{
if
(
!
enable_log
)
return
0
;
char
msgbuf
[
1024
];
get_log_message
(
fduel
,
(
byte
*
)
msgbuf
);
mainGame
->
AddDebugMsg
(
msgbuf
);
return
0
;
}
}
\ No newline at end of file
gframe/replay.cpp
View file @
3516ba98
#include "replay.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
#include "../ocgcore/field.h"
#include <algorithm>
#include "lzma/LzmaLib.h"
namespace
ygo
{
ReplayPacket
::
ReplayPacket
(
char
*
buf
,
int
len
)
{
message
=
BufferIO
::
ReadInt8
(
buf
);
length
=
len
;
memcpy
(
data
,
buf
,
length
);
}
ReplayPacket
::
ReplayPacket
(
int
msg
,
char
*
buf
,
int
len
)
{
message
=
msg
;
length
=
len
;
memcpy
(
data
,
buf
,
length
);
}
void
ReplayPacket
::
Set
(
int
msg
,
char
*
buf
,
int
len
)
{
message
=
msg
;
length
=
len
;
memcpy
(
data
,
buf
,
length
);
}
Replay
::
Replay
()
{
is_recording
=
false
;
is_replaying
=
false
;
...
...
@@ -16,25 +33,42 @@ Replay::~Replay() {
delete
[]
replay_data
;
delete
[]
comp_data
;
}
void
Replay
::
BeginRecord
()
{
void
Replay
::
BeginRecord
(
bool
write
)
{
#ifdef _WIN32
if
(
is_recording
)
if
(
is_recording
&&
is_writing
)
CloseHandle
(
recording_fp
);
recording_fp
=
CreateFileW
(
L"./replay/_LastReplay.yrp"
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
FILE_FLAG_WRITE_THROUGH
,
NULL
);
if
(
recording_fp
==
INVALID_HANDLE_VALUE
)
return
;
is_writing
=
write
;
if
(
is_writing
)
{
recording_fp
=
CreateFileW
(
L"./replay/_LastReplay.yrpX"
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
FILE_FLAG_WRITE_THROUGH
,
NULL
);
if
(
recording_fp
==
INVALID_HANDLE_VALUE
)
return
;
}
#else
if
(
is_recording
)
if
(
is_recording
&&
is_writing
)
fclose
(
fp
);
fp
=
fopen
(
"./replay/_LastReplay.yrp"
,
"wb"
);
if
(
!
fp
)
return
;
is_writing
=
write
;
if
(
is_writing
)
{
fp
=
fopen
(
"./replay/_LastReplay.yrpX"
,
"wb"
);
if
(
!
fp
)
return
;
}
#endif
pdata
=
replay_data
;
is_recording
=
true
;
}
void
Replay
::
WritePacket
(
ReplayPacket
p
)
{
WriteInt8
(
p
.
message
,
false
);
WriteInt32
(
p
.
length
,
false
);
WriteData
((
char
*
)
p
.
data
,
p
.
length
);
}
void
Replay
::
WriteStream
(
std
::
vector
<
ReplayPacket
>
stream
)
{
if
(
stream
.
size
())
for
(
auto
it
=
stream
.
begin
();
it
!=
stream
.
end
();
it
++
)
WritePacket
((
*
it
));
}
void
Replay
::
WriteHeader
(
ReplayHeader
&
header
)
{
pheader
=
header
;
if
(
!
is_writing
)
return
;
#ifdef _WIN32
DWORD
size
;
WriteFile
(
recording_fp
,
&
header
,
sizeof
(
header
),
&
size
,
NULL
);
...
...
@@ -48,6 +82,7 @@ void Replay::WriteData(const void* data, unsigned int length, bool flush) {
return
;
memcpy
(
pdata
,
data
,
length
);
pdata
+=
length
;
if
(
!
is_writing
)
return
;
#ifdef _WIN32
DWORD
size
;
WriteFile
(
recording_fp
,
data
,
length
,
&
size
,
NULL
);
...
...
@@ -62,6 +97,7 @@ void Replay::WriteInt32(int data, bool flush) {
return
;
*
((
int
*
)(
pdata
))
=
data
;
pdata
+=
4
;
if
(
!
is_writing
)
return
;
#ifdef _WIN32
DWORD
size
;
WriteFile
(
recording_fp
,
&
data
,
sizeof
(
int
),
&
size
,
NULL
);
...
...
@@ -76,6 +112,7 @@ void Replay::WriteInt16(short data, bool flush) {
return
;
*
((
short
*
)(
pdata
))
=
data
;
pdata
+=
2
;
if
(
!
is_writing
)
return
;
#ifdef _WIN32
DWORD
size
;
WriteFile
(
recording_fp
,
&
data
,
sizeof
(
short
),
&
size
,
NULL
);
...
...
@@ -90,6 +127,7 @@ void Replay::WriteInt8(char data, bool flush) {
return
;
*
pdata
=
data
;
pdata
++
;
if
(
!
is_writing
)
return
;
#ifdef _WIN32
DWORD
size
;
WriteFile
(
recording_fp
,
&
data
,
sizeof
(
char
),
&
size
,
NULL
);
...
...
@@ -102,14 +140,16 @@ void Replay::WriteInt8(char data, bool flush) {
void
Replay
::
Flush
()
{
if
(
!
is_recording
)
return
;
if
(
!
is_writing
)
return
;
#ifdef _WIN32
#else
fflush
(
fp
);
#endif
}
void
Replay
::
EndRecord
()
{
void
Replay
::
EndRecord
(
size_t
size
)
{
if
(
!
is_recording
)
return
;
if
(
is_writing
)
#ifdef _WIN32
CloseHandle
(
recording_fp
);
#else
...
...
@@ -118,13 +158,13 @@ void Replay::EndRecord() {
pheader
.
datasize
=
pdata
-
replay_data
;
pheader
.
flag
|=
REPLAY_COMPRESSED
;
size_t
propsize
=
5
;
comp_size
=
0x1000
;
comp_size
=
size
;
LzmaCompress
(
comp_data
,
&
comp_size
,
replay_data
,
pdata
-
replay_data
,
pheader
.
props
,
&
propsize
,
5
,
1
<<
24
,
3
,
0
,
2
,
32
,
1
);
is_recording
=
false
;
}
void
Replay
::
SaveReplay
(
const
wchar_t
*
name
)
{
wchar_t
fname
[
256
];
myswprintf
(
fname
,
L"./replay/%ls.yrp"
,
name
);
myswprintf
(
fname
,
L"./replay/%ls.yrp
X
"
,
name
);
#ifdef WIN32
fp
=
_wfopen
(
fname
,
L"wb"
);
#else
...
...
@@ -161,7 +201,7 @@ bool Replay::OpenReplay(const wchar_t* name) {
return
false
;
fread
(
&
pheader
,
sizeof
(
pheader
),
1
,
fp
);
if
(
pheader
.
flag
&
REPLAY_COMPRESSED
)
{
comp_size
=
fread
(
comp_data
,
1
,
0x
1
000
,
fp
);
comp_size
=
fread
(
comp_data
,
1
,
0x
20
000
,
fp
);
fclose
(
fp
);
replay_size
=
pheader
.
datasize
;
if
(
LzmaUncompress
(
replay_data
,
&
replay_size
,
comp_data
,
&
comp_size
,
pheader
.
props
,
5
)
!=
SZ_OK
)
...
...
@@ -190,7 +230,23 @@ bool Replay::CheckReplay(const wchar_t* name) {
ReplayHeader
rheader
;
fread
(
&
rheader
,
sizeof
(
ReplayHeader
),
1
,
rfp
);
fclose
(
rfp
);
return
rheader
.
id
==
0x31707279
&&
rheader
.
version
>=
0x12d0
;
return
(
rheader
.
id
==
0x31707279
||
rheader
.
id
==
0x58707279
)
&&
rheader
.
version
>=
0x12d0
;
}
bool
Replay
::
ReadNextPacket
(
ReplayPacket
*
packet
)
{
if
(
pdata
-
replay_data
>=
(
int
)
replay_size
)
return
false
;
packet
->
message
=
*
pdata
++
;
packet
->
length
=
ReadInt32
();
ReadData
((
char
*
)
&
packet
->
data
,
packet
->
length
);
return
true
;
}
bool
Replay
::
ReadStream
(
std
::
vector
<
ReplayPacket
>*
stream
)
{
stream
->
clear
();
ReplayPacket
p
;
while
(
ReadNextPacket
(
&
p
))
{
stream
->
push_back
(
p
);
}
return
!!
stream
->
size
();
}
bool
Replay
::
ReadNextResponse
(
unsigned
char
resp
[
64
])
{
if
(
pdata
-
replay_data
>=
(
int
)
replay_size
)
...
...
@@ -238,4 +294,31 @@ void Replay::Rewind() {
pdata
=
replay_data
;
}
bool
Replay
::
LoadYrp
()
{
if
(
pheader
.
flag
&
REPLAY_NEWREPLAY
)
{
pdata
+=
(
4
+
((
pheader
.
flag
&
REPLAY_TAG
)
?
160
:
80
));
ReplayPacket
p
;
while
(
ReadNextPacket
(
&
p
))
if
(
p
.
message
==
OLD_REPLAY_MODE
)
{
char
*
prep
=
(
char
*
)
p
.
data
;
memcpy
(
&
pheader
,
prep
,
sizeof
(
ReplayHeader
));
prep
+=
sizeof
(
ReplayHeader
);
if
(
pheader
.
flag
&
REPLAY_COMPRESSED
)
{
comp_size
=
(
size_t
)(
p
.
length
-
sizeof
(
ReplayHeader
));
replay_size
=
pheader
.
datasize
;
if
(
LzmaUncompress
(
replay_data
,
&
replay_size
,
(
unsigned
char
*
)
prep
,
&
comp_size
,
pheader
.
props
,
5
)
!=
SZ_OK
)
return
false
;
}
else
{
comp_size
=
fread
(
replay_data
,
1
,
0x20000
,
fp
);
fclose
(
fp
);
replay_size
=
comp_size
;
}
pdata
=
replay_data
;
is_replaying
=
true
;
return
true
;
}
}
return
!
(
pheader
.
flag
&
REPLAY_NEWREPLAY
);
}
}
gframe/replay.h
View file @
3516ba98
...
...
@@ -11,6 +11,7 @@ namespace ygo {
#define REPLAY_DECODED 0x4
#define REPLAY_SINGLE_MODE 0x8
#define REPLAY_LUA64 0x10
#define REPLAY_NEWREPLAY 0x20
struct
ReplayHeader
{
unsigned
int
id
;
...
...
@@ -22,29 +23,44 @@ struct ReplayHeader {
unsigned
char
props
[
8
];
};
class
ReplayPacket
{
public:
int
message
;
int
length
;
unsigned
char
data
[
0x2000
];
ReplayPacket
()
{}
ReplayPacket
(
char
*
buf
,
int
len
);
ReplayPacket
(
int
msg
,
char
*
buf
,
int
len
);
void
Set
(
int
msg
,
char
*
buf
,
int
len
);
};
class
Replay
{
public:
Replay
();
~
Replay
();
void
BeginRecord
();
void
BeginRecord
(
bool
write
=
true
);
void
WriteStream
(
std
::
vector
<
ReplayPacket
>
stream
);
void
WritePacket
(
ReplayPacket
p
);
void
WriteHeader
(
ReplayHeader
&
header
);
void
WriteData
(
const
void
*
data
,
unsigned
int
length
,
bool
flush
=
true
);
void
WriteInt32
(
int
data
,
bool
flush
=
true
);
void
WriteInt16
(
short
data
,
bool
flush
=
true
);
void
WriteInt8
(
char
data
,
bool
flush
=
true
);
void
Flush
();
void
EndRecord
();
void
EndRecord
(
size_t
size
=
0x20000
);
void
SaveReplay
(
const
wchar_t
*
name
);
bool
OpenReplay
(
const
wchar_t
*
name
);
static
bool
CheckReplay
(
const
wchar_t
*
name
);
bool
ReadNextPacket
(
ReplayPacket
*
packet
);
bool
ReadStream
(
std
::
vector
<
ReplayPacket
>*
stream
);
bool
ReadNextResponse
(
unsigned
char
resp
[
64
]);
void
ReadName
(
wchar_t
*
data
);
void
ReadHeader
(
ReplayHeader
&
header
);
void
ReadData
(
void
*
data
,
unsigned
int
length
);
int
ReadInt32
();
short
ReadInt16
();
char
ReadInt8
();
void
Rewind
();
bool
LoadYrp
();
FILE
*
fp
;
ReplayHeader
pheader
;
...
...
@@ -57,6 +73,7 @@ public:
size_t
replay_size
;
size_t
comp_size
;
bool
is_recording
;
bool
is_writing
;
bool
is_replaying
;
};
...
...
gframe/replay_mode.cpp
View file @
3516ba98
...
...
@@ -9,12 +9,14 @@
namespace
ygo
{
long
ReplayMode
::
pduel
=
0
;
bool
ReplayMode
::
yrp
=
false
;
Replay
ReplayMode
::
cur_replay
;
std
::
vector
<
ReplayPacket
>
ReplayMode
::
current_stream
;
bool
ReplayMode
::
is_continuing
=
true
;
bool
ReplayMode
::
is_closing
=
false
;
bool
ReplayMode
::
is_pausing
=
false
;
bool
ReplayMode
::
is_paused
=
false
;
bool
ReplayMode
::
is_swaping
=
false
;
bool
ReplayMode
::
is_swap
p
ing
=
false
;
bool
ReplayMode
::
is_restarting
=
false
;
bool
ReplayMode
::
exit_pending
=
false
;
int
ReplayMode
::
skip_turn
=
0
;
...
...
@@ -24,8 +26,12 @@ int ReplayMode::skip_step = 0;
bool
ReplayMode
::
StartReplay
(
int
skipturn
)
{
skip_turn
=
skipturn
;
if
(
skip_turn
<
0
)
skip_turn
=
0
;
Thread
::
NewThread
(
ReplayThread
,
0
);
skip_turn
=
0
;
yrp
=
cur_replay
.
pheader
.
id
==
0x31707279
;
if
(
yrp
)
Thread
::
NewThread
(
OldReplayThread
,
0
);
else
Thread
::
NewThread
(
ReplayThread
,
0
);
return
true
;
}
void
ReplayMode
::
StopReplay
(
bool
is_exiting
)
{
...
...
@@ -39,7 +45,7 @@ void ReplayMode::SwapField() {
if
(
is_paused
)
mainGame
->
dField
.
ReplaySwap
();
else
is_swaping
=
true
;
is_swap
p
ing
=
true
;
}
void
ReplayMode
::
Pause
(
bool
is_pause
,
bool
is_step
)
{
if
(
is_pause
)
...
...
@@ -50,13 +56,6 @@ void ReplayMode::Pause(bool is_pause, bool is_step) {
mainGame
->
actionSignal
.
Set
();
}
}
bool
ReplayMode
::
ReadReplayResponse
()
{
unsigned
char
resp
[
64
];
bool
result
=
cur_replay
.
ReadNextResponse
(
resp
);
if
(
result
)
set_responseb
(
pduel
,
resp
);
return
result
;
}
int
ReplayMode
::
ReplayThread
(
void
*
param
)
{
const
ReplayHeader
&
rh
=
cur_replay
.
pheader
;
mainGame
->
dInfo
.
isFirst
=
true
;
...
...
@@ -65,72 +64,53 @@ int ReplayMode::ReplayThread(void* param) {
mainGame
->
dInfo
.
lua64
=
!!
(
rh
.
flag
&
REPLAY_LUA64
);
mainGame
->
dInfo
.
tag_player
[
0
]
=
false
;
mainGame
->
dInfo
.
tag_player
[
1
]
=
false
;
if
(
mainGame
->
dInfo
.
isSingleMode
)
{
set_script_reader
((
script_reader
)
SingleMode
::
ScriptReader
);
set_card_reader
((
card_reader
)
DataManager
::
CardReader
);
set_message_handler
((
message_handler
)
MessageHandler
);
}
else
{
set_script_reader
(
default_script_reader
);
set_card_reader
((
card_reader
)
DataManager
::
CardReader
);
set_message_handler
((
message_handler
)
MessageHandler
);
if
(
mainGame
->
dInfo
.
isTag
)
{
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname_tag
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname_tag
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname
);
}
if
(
!
StartDuel
())
{
else
{
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname
);
}
int
opt
=
cur_replay
.
ReadInt32
();
mainGame
->
dInfo
.
duel_field
=
opt
&
0xff
;
mainGame
->
dInfo
.
extraval
=
(
opt
>>
8
);
mainGame
->
SetPhaseButtons
();
if
(
!
cur_replay
.
ReadStream
(
&
current_stream
))
{
EndDuel
();
return
0
;
}
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplay
=
true
;
mainGame
->
dInfo
.
turn
=
0
;
mainGame
->
dInfo
.
isReplaySkiping
=
(
skip_turn
>
0
);
char
engineBuffer
[
0x1000
];
is_continuing
=
true
;
skip_step
=
0
;
if
(
mainGame
->
dInfo
.
isSingleMode
)
{
int
len
=
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
if
(
len
>
0
)
is_continuing
=
ReplayAnalyze
(
engineBuffer
,
len
);
}
else
{
ReplayRefreshDeck
(
0
);
ReplayRefreshDeck
(
1
);
ReplayRefreshExtra
(
0
);
ReplayRefreshExtra
(
1
);
}
exit_pending
=
false
;
current_step
=
0
;
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
mainGame
->
gMutex
.
Lock
();
while
(
is_continuing
&&
!
exit_pending
)
{
int
result
=
process
(
pduel
);
int
len
=
result
&
0xffff
;
/*int flag = result >> 16;*/
if
(
len
>
0
)
{
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
is_continuing
=
ReplayAnalyze
(
engineBuffer
,
len
);
if
(
is_restarting
)
{
is_restarting
=
false
;
int
step
=
current_step
-
1
;
if
(
step
<
0
)
step
=
0
;
if
(
mainGame
->
dInfo
.
isSingleMode
)
{
is_continuing
=
true
;
skip_step
=
0
;
int
len
=
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
if
(
len
>
0
)
{
mainGame
->
gMutex
.
Unlock
();
is_continuing
=
ReplayAnalyze
(
engineBuffer
,
len
);
mainGame
->
gMutex
.
Lock
();
}
}
if
(
step
==
0
)
{
Pause
(
true
,
false
);
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
skip_step
=
step
;
current_step
=
0
;
for
(
auto
it
=
current_stream
.
begin
();
is_continuing
&&
!
exit_pending
&&
it
!=
current_stream
.
end
();)
{
is_continuing
=
ReplayAnalyze
((
*
it
));
if
(
is_restarting
)
{
it
=
current_stream
.
begin
();
is_restarting
=
false
;
int
step
=
current_step
-
1
;
if
(
step
<
0
)
step
=
0
;
if
(
step
==
0
)
{
Pause
(
true
,
false
);
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
}
skip_step
=
step
;
current_step
=
0
;
}
else
it
++
;
}
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
{
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
...
...
@@ -140,163 +120,9 @@ int ReplayMode::ReplayThread(void* param) {
EndDuel
();
return
0
;
}
bool
ReplayMode
::
StartDuel
()
{
const
ReplayHeader
&
rh
=
cur_replay
.
pheader
;
mtrandom
rnd
;
int
seed
=
rh
.
seed
;
rnd
.
reset
(
seed
);
if
(
mainGame
->
dInfo
.
isTag
)
{
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname_tag
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname_tag
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname
);
}
else
{
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
hostname
);
cur_replay
.
ReadName
(
mainGame
->
dInfo
.
clientname
);
}
pduel
=
create_duel
(
rnd
.
rand
());
int
start_lp
=
cur_replay
.
ReadInt32
();
int
start_hand
=
cur_replay
.
ReadInt32
();
int
draw_count
=
cur_replay
.
ReadInt32
();
int
opt
=
cur_replay
.
ReadInt32
();
int
duel_rule
=
opt
>>
16
;
int
rule
=
opt
>>
16
;
//backwards compatibility with master rule replays
if
(
rule
)
switch
(
rule
)
{
case
1
:
{
opt
|=
MASTER_RULE_1
;
break
;
}
case
2
:
{
opt
|=
MASTER_RULE_2
;
break
;
}
case
3
:
{
opt
|=
MASTER_RULE_3
;
break
;
}
case
4
:
{
opt
|=
MASTER_RULE_4
;
break
;
}
}
//pre mr4 replay compatibility
if
(
opt
&
DUEL_OBSOLETE_RULING
)
{
opt
&=
~
DUEL_OBSOLETE_RULING
;
opt
|=
MASTER_RULE_1
;
}
else
if
(
!
(
opt
&
0xff80
))
opt
|=
MASTER_RULE_3
;
mainGame
->
dInfo
.
duel_field
=
2
;
if
((
opt
&
DUEL_PZONE
)
&&
(
opt
&
DUEL_SEPARATE_PZONE
)
&&
(
opt
&
DUEL_EMZONE
))
mainGame
->
dInfo
.
duel_field
=
5
;
else
if
(
opt
&
DUEL_EMZONE
)
mainGame
->
dInfo
.
duel_field
=
4
;
else
if
(
opt
&
DUEL_PZONE
)
mainGame
->
dInfo
.
duel_field
=
3
;
mainGame
->
dInfo
.
extraval
=
!!
(
opt
&
SPEED_DUEL
);
// reset master rule 4 phase button position
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
310
,
855
,
330
));
if
(
mainGame
->
dInfo
.
extraval
)
{
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
290
,
855
,
350
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
310
,
0
,
360
,
20
));
}
else
{
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
}
else
{
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
}
else
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
320
,
0
,
370
,
20
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
}
set_player_info
(
pduel
,
0
,
start_lp
,
start_hand
,
draw_count
);
set_player_info
(
pduel
,
1
,
start_lp
,
start_hand
,
draw_count
);
mainGame
->
dInfo
.
lp
[
0
]
=
start_lp
;
mainGame
->
dInfo
.
lp
[
1
]
=
start_lp
;
mainGame
->
dInfo
.
startlp
=
start_lp
;
myswprintf
(
mainGame
->
dInfo
.
strLP
[
0
],
L"%d"
,
mainGame
->
dInfo
.
lp
[
0
]);
myswprintf
(
mainGame
->
dInfo
.
strLP
[
1
],
L"%d"
,
mainGame
->
dInfo
.
lp
[
1
]);
mainGame
->
dInfo
.
turn
=
0
;
if
(
!
mainGame
->
dInfo
.
isSingleMode
)
{
if
(
!
(
opt
&
DUEL_TAG_MODE
))
{
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
0
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
}
else
{
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
0
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
LOCATION_DECK
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
LOCATION_EXTRA
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
LOCATION_DECK
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_tag_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
LOCATION_EXTRA
);
}
}
else
{
char
filename
[
256
];
size_t
slen
=
cur_replay
.
ReadInt16
();
cur_replay
.
ReadData
(
filename
,
slen
);
filename
[
slen
]
=
0
;
if
(
!
preload_script
(
pduel
,
filename
,
slen
))
{
return
false
;
}
}
start_duel
(
pduel
,
opt
);
return
true
;
}
void
ReplayMode
::
EndDuel
()
{
end_duel
(
pduel
);
if
(
yrp
)
end_duel
(
pduel
);
if
(
!
is_closing
)
{
mainGame
->
actionSignal
.
Reset
();
mainGame
->
gMutex
.
Lock
();
...
...
@@ -309,6 +135,7 @@ void ReplayMode::EndDuel() {
mainGame
->
gMutex
.
Lock
();
mainGame
->
dInfo
.
isStarted
=
false
;
mainGame
->
dInfo
.
isReplay
=
false
;
mainGame
->
dInfo
.
isOldReplay
=
false
;
mainGame
->
gMutex
.
Unlock
();
mainGame
->
closeDoneSignal
.
Reset
();
mainGame
->
closeSignal
.
Set
();
...
...
@@ -323,21 +150,21 @@ void ReplayMode::EndDuel() {
}
}
void
ReplayMode
::
Restart
(
bool
refresh
)
{
end_duel
(
pduel
);
if
(
yrp
)
{
end_duel
(
pduel
);
cur_replay
.
Rewind
();
}
mainGame
->
dInfo
.
isStarted
=
false
;
mainGame
->
dInfo
.
turn
=
0
;
mainGame
->
dField
.
Clear
();
//mainGame->device->setEventReceiver(&mainGame->dField);
cur_replay
.
Rewind
();
//mainGame->dInfo.isFirst = true;
mainGame
->
dInfo
.
tag_player
[
0
]
=
false
;
mainGame
->
dInfo
.
tag_player
[
1
]
=
false
;
if
(
!
StartDuel
())
{
if
(
yrp
&&
!
StartDuel
())
{
EndDuel
();
}
if
(
refresh
)
{
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
dInfo
.
isStarted
=
true
;
//mainGame->dInfo.isReplay = true;
}
skip_turn
=
0
;
is_restarting
=
true
;
...
...
@@ -350,26 +177,21 @@ void ReplayMode::Undo() {
mainGame
->
gMutex
.
Lock
();
Pause
(
false
,
false
);
}
bool
ReplayMode
::
ReplayAnalyze
(
char
*
msg
,
unsigned
int
len
)
{
char
*
pbuf
=
msg
;
int
player
,
count
;
bool
ReplayMode
::
ReplayAnalyze
(
ReplayPacket
p
)
{
is_restarting
=
false
;
while
(
pbuf
-
msg
<
(
int
)
len
)
{
while
(
true
)
{
if
(
is_closing
)
return
false
;
if
(
is_restarting
)
{
//is_restarting = false;
return
true
;
}
if
(
is_swaping
)
{
if
(
is_restarting
)
break
;
if
(
is_swapping
)
{
mainGame
->
gMutex
.
Lock
();
mainGame
->
dField
.
ReplaySwap
();
mainGame
->
gMutex
.
Unlock
();
is_swaping
=
false
;
is_swap
p
ing
=
false
;
}
char
*
offset
=
pbuf
;
bool
pauseable
=
true
;
mainGame
->
dInfo
.
curMsg
=
BufferIO
::
ReadUInt8
(
pbuf
)
;
mainGame
->
dInfo
.
curMsg
=
p
.
message
;
switch
(
mainGame
->
dInfo
.
curMsg
)
{
case
MSG_RETRY
:
{
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
{
...
...
@@ -385,188 +207,40 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
mainGame
->
actionSignal
.
Wait
();
return
false
;
}
case
MSG_HINT
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
10
:
6
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_WIN
:
{
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
{
if
(
mainGame
->
dInfo
.
isReplaySkiping
)
{
mainGame
->
dInfo
.
isReplaySkiping
=
false
;
mainGame
->
dField
.
RefreshAllCards
();
mainGame
->
gMutex
.
Unlock
();
}
pbuf
+=
2
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
DuelClient
::
ClientAnalyze
((
char
*
)
p
.
data
,
p
.
length
);
return
false
;
}
case
MSG_SELECT_BATTLECMD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
(
mainGame
->
dInfo
.
lua64
)
?
15
:
11
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
+
2
;
ReplayRefresh
();
return
ReadReplayResponse
();
}
case
MSG_SELECT_IDLECMD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
(
mainGame
->
dInfo
.
lua64
)
?
15
:
11
+
3
;
ReplayRefresh
();
return
ReadReplayResponse
();
}
case
MSG_SELECT_EFFECTYN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
16
:
12
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_YESNO
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
8
:
4
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_OPTION
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
(
mainGame
->
dInfo
.
lua64
)
?
8
:
4
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_CARD
:
case
MSG_SELECT_TRIBUTE
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
3
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_UNSELECT_CARD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
4
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_CHAIN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
10
+
count
*
(
mainGame
->
dInfo
.
lua64
)
?
17
:
13
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_PLACE
:
case
MSG_SELECT_DISFIELD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_POSITION
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_COUNTER
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
4
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
9
;
return
ReadReplayResponse
();
}
case
MSG_SELECT_SUM
:
{
pbuf
++
;
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
6
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
11
;
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
11
;
return
ReadReplayResponse
();
}
case
MSG_SORT_CARD
:
case
MSG_SORT_CHAIN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
return
ReadReplayResponse
();
}
case
MSG_CONFIRM_DECKTOP
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CONFIRM_EXTRATOP
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CONFIRM_CARDS
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SHUFFLE_DECK
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshDeck
(
player
);
break
;
}
case
MSG_SHUFFLE_HAND
:
{
/*int oplayer = */
BufferIO
::
ReadInt8
(
pbuf
);
int
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SHUFFLE_EXTRA
:
{
/*int oplayer = */
BufferIO
::
ReadInt8
(
pbuf
);
int
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_REFRESH_DECK
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SWAP_GRAVE_DECK
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshGrave
(
player
);
break
;
}
case
MSG_REVERSE_DECK
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshDeck
(
0
);
ReplayRefreshDeck
(
1
);
break
;
}
case
MSG_DECK_TOP
:
{
pbuf
+=
6
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SHUFFLE_SET_CARD
:
{
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
case
MSG_START
:
case
MSG_UPDATE_DATA
:
case
MSG_UPDATE_CARD
:
case
MSG_SET
:
case
MSG_SWAP
:
case
MSG_FIELD_DISABLED
:
case
MSG_SUMMONING
:
case
MSG_SPSUMMONING
:
case
MSG_FLIPSUMMONING
:
case
MSG_CHAIN_SOLVING
:
case
MSG_CHAIN_SOLVED
:
case
MSG_CHAIN_END
:
case
MSG_CARD_SELECTED
:
case
MSG_RANDOM_SELECTED
:
case
MSG_EQUIP
:
case
MSG_UNEQUIP
:
case
MSG_CARD_TARGET
:
case
MSG_CANCEL_TARGET
:
case
MSG_BATTLE
:
case
MSG_ATTACK_DISABLED
:
case
MSG_DAMAGE_STEP_START
:
case
MSG_DAMAGE_STEP_END
:
case
MSG_TAG_SWAP
:
case
MSG_RELOAD_FIELD
:
{
pauseable
=
false
;
break
;
}
case
MSG_NEW_TURN
:
{
...
...
@@ -578,335 +252,24 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
mainGame
->
gMutex
.
Unlock
();
}
}
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_NEW_PHASE
:
{
pbuf
+=
2
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_MOVE
:
{
int
pc
=
pbuf
[
4
];
int
pl
=
pbuf
[
5
];
/*int ps = pbuf[6];*/
/*int pp = pbuf[7];*/
int
cc
=
pbuf
[
8
];
int
cl
=
pbuf
[
9
];
int
cs
=
pbuf
[
10
];
/*int cp = pbuf[11];*/
pbuf
+=
16
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
if
(
cl
&&
!
(
cl
&
0x80
)
&&
(
pl
!=
cl
||
pc
!=
cc
))
ReplayRefreshSingle
(
cc
,
cl
,
cs
);
break
;
}
case
MSG_POS_CHANGE
:
{
pbuf
+=
9
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_SET
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SWAP
:
{
pbuf
+=
16
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_FIELD_DISABLED
:
{
pbuf
+=
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SUMMONING
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SUMMONED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_SPSUMMONING
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_SPSUMMONED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_FLIPSUMMONING
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_FLIPSUMMONED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_CHAINING
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
20
:
16
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CHAINED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
break
;
}
case
MSG_CHAIN_SOLVING
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_CHAIN_SOLVED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_CHAIN_END
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_CHAIN_NEGATED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CHAIN_DISABLED
:
{
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_CARD_SELECTED
:
case
MSG_RANDOM_SELECTED
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_BECOME_TARGET
:
{
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_DRAW
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
*
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_DAMAGE
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_RECOVER
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_EQUIP
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_LPUPDATE
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_UNEQUIP
:
{
pbuf
+=
4
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_CARD_TARGET
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_CANCEL_TARGET
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_PAY_LPCOST
:
{
pbuf
+=
5
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ADD_COUNTER
:
{
pbuf
+=
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_REMOVE_COUNTER
:
{
pbuf
+=
7
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ATTACK
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_BATTLE
:
{
pbuf
+=
26
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_ATTACK_DISABLED
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
pauseable
=
false
;
break
;
}
case
MSG_DAMAGE_STEP_START
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_DAMAGE_STEP_END
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefresh
();
pauseable
=
false
;
break
;
}
case
MSG_MISSED_EFFECT
:
{
pbuf
+=
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_TOSS_COIN
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_TOSS_DICE
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
count
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ROCK_PAPER_SCISSORS
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
return
ReadReplayResponse
();
}
case
MSG_HAND_RES
:
{
pbuf
+=
1
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_ANNOUNCE_RACE
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_ANNOUNCE_ATTRIB
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
5
;
return
ReadReplayResponse
();
}
case
MSG_ANNOUNCE_CARD
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
4
;
return
ReadReplayResponse
();
}
case
MSG_ANNOUNCE_NUMBER
:
case
MSG_ANNOUNCE_CARD_FILTER
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
count
=
BufferIO
::
ReadInt8
(
pbuf
);
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
8
:
4
*
count
;
return
ReadReplayResponse
();
}
case
MSG_CARD_HINT
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
13
:
9
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_PLAYER_HINT
:
{
pbuf
+=
(
mainGame
->
dInfo
.
lua64
)
?
10
:
6
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_MATCH_KILL
:
{
pbuf
+=
4
;
break
;
}
case
MSG_TAG_SWAP
:
{
player
=
pbuf
[
0
];
pbuf
+=
pbuf
[
2
]
*
4
+
pbuf
[
4
]
*
4
+
9
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayRefreshDeck
(
player
);
ReplayRefreshExtra
(
player
);
break
;
}
case
MSG_RELOAD_FIELD
:
{
pbuf
++
;
for
(
int
p
=
0
;
p
<
2
;
++
p
)
{
pbuf
+=
4
;
for
(
int
seq
=
0
;
seq
<
7
;
++
seq
)
{
int
val
=
BufferIO
::
ReadInt8
(
pbuf
);
if
(
val
)
pbuf
+=
2
;
}
for
(
int
seq
=
0
;
seq
<
8
;
++
seq
)
{
int
val
=
BufferIO
::
ReadInt8
(
pbuf
);
if
(
val
)
pbuf
++
;
}
pbuf
+=
6
;
}
pbuf
++
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
ReplayReload
();
mainGame
->
dField
.
RefreshAllCards
();
break
;
}
case
MSG_AI_NAME
:
{
char
*
pbuf
=
(
char
*
)
p
.
data
;
char
namebuf
[
128
];
wchar_t
wname
[
128
];
int
len
=
BufferIO
::
ReadInt16
(
pbuf
);
char
*
begin
=
pbuf
;
pbuf
+=
len
+
1
;
break
;
}
case
MSG_SHOW_HINT
:
{
int
len
=
BufferIO
::
ReadInt16
(
pbuf
);
pbuf
+=
len
+
1
;
break
;
memcpy
(
namebuf
,
begin
,
len
+
1
);
BufferIO
::
DecodeUTF8
(
namebuf
,
wname
);
BufferIO
::
CopyWStr
(
wname
,
mainGame
->
dInfo
.
clientname
,
20
);
return
true
;
}
case
OLD_REPLAY_MODE
:
return
true
;
}
DuelClient
::
ClientAnalyze
((
char
*
)
p
.
data
,
p
.
length
);
if
(
pauseable
)
{
current_step
++
;
if
(
skip_step
)
{
...
...
@@ -926,88 +289,9 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
is_paused
=
false
;
}
}
break
;
}
return
true
;
}
void
ReplayMode
::
ReplayRefresh
(
int
flag
)
{
unsigned
char
queryBuffer
[
0x4000
];
/*int len = */
query_field_card
(
pduel
,
0
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshHand
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshGrave
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshDeck
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshExtra
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayRefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x4000
];
/*int len = */
query_card
(
pduel
,
player
,
location
,
sequence
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateCard
(
mainGame
->
LocalPlayer
(
player
),
location
,
sequence
,
(
char
*
)
queryBuffer
);
}
void
ReplayMode
::
ReplayReload
()
{
unsigned
char
queryBuffer
[
0x4000
];
unsigned
int
flag
=
0xffdfff
;
/*int len = */
query_field_card
(
pduel
,
0
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_REMOVED
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_REMOVED
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_REMOVED
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_REMOVED
,
(
char
*
)
queryBuffer
);
}
int
ReplayMode
::
MessageHandler
(
long
fduel
,
int
type
)
{
if
(
!
enable_log
)
return
0
;
char
msgbuf
[
1024
];
get_log_message
(
fduel
,
(
byte
*
)
msgbuf
);
mainGame
->
AddDebugMsg
(
msgbuf
);
return
0
;
}
}
gframe/replay_mode.h
View file @
3516ba98
...
...
@@ -12,12 +12,14 @@ namespace ygo {
class
ReplayMode
{
private:
static
long
pduel
;
static
bool
yrp
;
static
bool
is_continuing
;
static
bool
is_closing
;
static
bool
is_pausing
;
static
bool
is_paused
;
static
bool
is_swaping
;
static
bool
is_swap
p
ing
;
static
bool
is_restarting
;
static
bool
undo
;
static
bool
exit_pending
;
static
int
skip_turn
;
static
int
current_step
;
...
...
@@ -25,6 +27,7 @@ private:
public:
static
Replay
cur_replay
;
static
std
::
vector
<
ReplayPacket
>
ReplayMode
::
current_stream
;
public:
static
bool
StartReplay
(
int
skipturn
);
...
...
@@ -33,12 +36,14 @@ public:
static
void
Pause
(
bool
is_pause
,
bool
is_step
);
static
bool
ReadReplayResponse
();
static
int
ReplayThread
(
void
*
param
);
static
int
OldReplayThread
(
void
*
param
);
static
bool
StartDuel
();
static
void
EndDuel
();
static
void
Restart
(
bool
refresh
);
static
void
Undo
();
static
bool
ReplayAnalyze
(
ReplayPacket
p
);
static
bool
ReplayAnalyze
(
char
*
msg
,
unsigned
int
len
);
static
void
ReplayRefresh
(
int
flag
=
0xf81fff
);
static
void
ReplayRefreshHand
(
int
player
,
int
flag
=
0x781fff
);
static
void
ReplayRefreshGrave
(
int
player
,
int
flag
=
0x181fff
);
...
...
gframe/single_duel.cpp
View file @
3516ba98
...
...
@@ -9,6 +9,8 @@
namespace
ygo
{
std
::
vector
<
ReplayPacket
>
SingleDuel
::
replay_stream
;
SingleDuel
::
SingleDuel
(
bool
is_match
)
{
game_started
=
false
;
match_mode
=
is_match
;
...
...
@@ -187,6 +189,8 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
NetServer
::
ReSendToPlayer
(
players
[
1
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
ReplayPacket
p
((
char
*
)
wbuf
,
3
);
replay_stream
.
push_back
(
p
);
EndDuel
();
NetServer
::
SendPacketToPlayer
(
players
[
0
],
STOC_DUEL_END
);
NetServer
::
ReSendToPlayer
(
players
[
1
]);
...
...
@@ -398,11 +402,19 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rh
.
flag
=
REPLAY_LUA64
;
time_t
seed
=
time
(
0
);
rh
.
seed
=
seed
;
last_replay
.
BeginRecord
();
last_replay
.
BeginRecord
(
false
);
last_replay
.
WriteHeader
(
rh
);
rnd
.
reset
(
seed
);
last_replay
.
WriteData
(
players
[
0
]
->
name
,
40
,
false
);
last_replay
.
WriteData
(
players
[
1
]
->
name
,
40
,
false
);
//records the replay with the new system
new_replay
.
BeginRecord
();
rh
.
id
=
0x58707279
;
rh
.
flag
|=
REPLAY_NEWREPLAY
;
new_replay
.
WriteHeader
(
rh
);
new_replay
.
WriteData
(
players
[
0
]
->
name
,
40
,
false
);
new_replay
.
WriteData
(
players
[
1
]
->
name
,
40
);
replay_stream
.
clear
();
if
(
!
host_info
.
no_shuffle_deck
)
{
for
(
size_t
i
=
pdeck
[
0
].
main
.
size
()
-
1
;
i
>
0
;
--
i
)
{
int
swap
=
rnd
.
real
()
*
(
i
+
1
);
...
...
@@ -427,6 +439,7 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
opt
|=
DUEL_PSEUDO_SHUFFLE
;
if
(
host_info
.
speed
)
opt
|=
SPEED_DUEL
;
new_replay
.
WriteInt32
((
mainGame
->
GetMasterRule
(
opt
,
0
))
|
(
opt
&
SPEED_DUEL
)
<<
8
);
last_replay
.
WriteInt32
(
host_info
.
start_lp
,
false
);
last_replay
.
WriteInt32
(
host_info
.
start_hand
,
false
);
last_replay
.
WriteInt32
(
host_info
.
draw_count
,
false
);
...
...
@@ -518,8 +531,14 @@ void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
else
startbuf
[
1
]
=
0x11
;
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
SendBufferToPlayer
(
*
oit
,
STOC_GAME_MSG
,
startbuf
,
18
);
startbuf
[
1
]
=
0
;
ReplayPacket
p
((
char
*
)
startbuf
,
17
);
replay_stream
.
push_back
(
p
);
PseudoRefreshDeck
(
0
);
PseudoRefreshDeck
(
1
);
RefreshExtra
(
0
);
RefreshExtra
(
1
);
new_replay
.
WriteStream
(
replay_stream
);
start_duel
(
pduel
,
opt
);
Process
();
}
...
...
@@ -594,6 +613,8 @@ void SingleDuel::Surrender(DuelPlayer* dp) {
NetServer
::
ReSendToPlayer
(
players
[
1
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
ReplayPacket
p
((
char
*
)
wbuf
,
3
);
replay_stream
.
push_back
(
p
);
if
(
players
[
player
]
==
pplayer
[
player
])
{
match_result
[
duel_count
++
]
=
1
-
player
;
tp_player
=
player
;
...
...
@@ -609,12 +630,19 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
char
*
offset
,
*
pbufw
,
*
pbuf
=
msgbuffer
;
int
player
,
count
,
type
;
while
(
pbuf
-
msgbuffer
<
(
int
)
len
)
{
replay_stream
.
clear
();
bool
record
=
true
;
ReplayPacket
p
;
offset
=
pbuf
;
unsigned
char
engType
=
BufferIO
::
ReadUInt8
(
pbuf
);
p
.
message
=
engType
;
p
.
length
=
len
-
1
;
memcpy
(
p
.
data
,
pbuf
,
p
.
length
);
switch
(
engType
)
{
case
MSG_RETRY
:
{
WaitforResponse
(
last_response
);
NetServer
::
SendBufferToPlayer
(
players
[
last_response
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
replay_stream
.
push_back
(
p
);
return
1
;
}
case
MSG_HINT
:
{
...
...
@@ -627,6 +655,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
case
3
:
case
5
:
{
NetServer
::
SendBufferToPlayer
(
players
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
record
=
false
;
break
;
}
case
4
:
...
...
@@ -666,6 +695,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
match_result
[
duel_count
++
]
=
1
-
player
;
tp_player
=
player
;
}
replay_stream
.
push_back
(
p
);
EndDuel
();
return
2
;
}
...
...
@@ -872,6 +902,7 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
ReSendToPlayer
(
players
[
1
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
PseudoRefreshDeck
(
player
);
break
;
}
case
MSG_SHUFFLE_HAND
:
{
...
...
@@ -920,6 +951,8 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
ReSendToPlayer
(
players
[
1
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
PseudoRefreshDeck
(
0
);
PseudoRefreshDeck
(
1
);
break
;
}
case
MSG_DECK_TOP
:
{
...
...
@@ -1432,6 +1465,12 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
break
;
}
}
//setting the length again in case of multiple messages in a row,
//when the packet will be written in the replay, the extra data registered previously will be discarded
p
.
length
=
(
pbuf
-
offset
)
-
1
;
if
(
record
)
replay_stream
.
insert
(
replay_stream
.
begin
(),
p
);
new_replay
.
WriteStream
(
replay_stream
);
}
return
0
;
}
...
...
@@ -1453,11 +1492,28 @@ void SingleDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
void
SingleDuel
::
EndDuel
()
{
if
(
!
pduel
)
return
;
last_replay
.
EndRecord
();
last_replay
.
EndRecord
(
0x1000
);
char
replaybuf
[
0x2000
],
*
pbuf
=
replaybuf
;
memcpy
(
pbuf
,
&
last_replay
.
pheader
,
sizeof
(
ReplayHeader
));
pbuf
+=
sizeof
(
ReplayHeader
);
memcpy
(
pbuf
,
last_replay
.
comp_data
,
last_replay
.
comp_size
);
replay_stream
.
push_back
(
ReplayPacket
(
OLD_REPLAY_MODE
,
replaybuf
,
sizeof
(
ReplayHeader
)
+
last_replay
.
comp_size
));
//in case of remaining packets, e.g. MSG_WIN
new_replay
.
WriteStream
(
replay_stream
);
new_replay
.
EndRecord
();
char
nreplaybuf
[
0x2000
],
*
npbuf
=
nreplaybuf
;
memcpy
(
npbuf
,
&
new_replay
.
pheader
,
sizeof
(
ReplayHeader
));
npbuf
+=
sizeof
(
ReplayHeader
);
memcpy
(
npbuf
,
new_replay
.
comp_data
,
new_replay
.
comp_size
);
NetServer
::
SendBufferToPlayer
(
players
[
0
],
STOC_NEW_REPLAY
,
nreplaybuf
,
sizeof
(
ReplayHeader
)
+
new_replay
.
comp_size
);
NetServer
::
ReSendToPlayer
(
players
[
1
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
NetServer
::
SendBufferToPlayer
(
players
[
0
],
STOC_REPLAY
,
replaybuf
,
sizeof
(
ReplayHeader
)
+
last_replay
.
comp_size
);
NetServer
::
ReSendToPlayer
(
players
[
1
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
...
...
@@ -1497,8 +1553,10 @@ void SingleDuel::RefreshMzone(int player, int flag, int use_cache) {
BufferIO
::
WriteInt8
(
qbuf
,
LOCATION_MZONE
);
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_MZONE
,
flag
,
(
unsigned
char
*
)
qbuf
,
use_cache
);
NetServer
::
SendBufferToPlayer
(
players
[
player
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
int
qlen
=
0
;
while
(
qlen
<
len
)
{
while
(
qlen
<
len
)
{
int
clen
=
BufferIO
::
ReadInt32
(
qbuf
);
qlen
+=
clen
;
if
(
clen
==
4
)
...
...
@@ -1519,8 +1577,10 @@ void SingleDuel::RefreshSzone(int player, int flag, int use_cache) {
BufferIO
::
WriteInt8
(
qbuf
,
LOCATION_SZONE
);
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_SZONE
,
flag
,
(
unsigned
char
*
)
qbuf
,
use_cache
);
NetServer
::
SendBufferToPlayer
(
players
[
player
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
int
qlen
=
0
;
while
(
qlen
<
len
)
{
while
(
qlen
<
len
)
{
int
clen
=
BufferIO
::
ReadInt32
(
qbuf
);
qlen
+=
clen
;
if
(
clen
==
4
)
...
...
@@ -1558,6 +1618,8 @@ void SingleDuel::RefreshHand(int player, int flag, int use_cache) {
NetServer
::
SendBufferToPlayer
(
players
[
1
-
player
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
for
(
auto
pit
=
observers
.
begin
();
pit
!=
observers
.
end
();
++
pit
)
NetServer
::
ReSendToPlayer
(
*
pit
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
}
void
SingleDuel
::
RefreshGrave
(
int
player
,
int
flag
,
int
use_cache
)
{
char
query_buffer
[
0x2000
];
...
...
@@ -1570,6 +1632,8 @@ void SingleDuel::RefreshGrave(int player, int flag, int use_cache) {
NetServer
::
ReSendToPlayer
(
players
[
1
]);
for
(
auto
pit
=
observers
.
begin
();
pit
!=
observers
.
end
();
++
pit
)
NetServer
::
ReSendToPlayer
(
*
pit
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
}
void
SingleDuel
::
RefreshExtra
(
int
player
,
int
flag
,
int
use_cache
)
{
char
query_buffer
[
0x2000
];
...
...
@@ -1579,6 +1643,8 @@ void SingleDuel::RefreshExtra(int player, int flag, int use_cache) {
BufferIO
::
WriteInt8
(
qbuf
,
LOCATION_EXTRA
);
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_EXTRA
,
flag
,
(
unsigned
char
*
)
qbuf
,
use_cache
);
NetServer
::
SendBufferToPlayer
(
players
[
player
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
}
void
SingleDuel
::
RefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
)
{
char
query_buffer
[
0x2000
];
...
...
@@ -1589,6 +1655,8 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag)
BufferIO
::
WriteInt8
(
qbuf
,
sequence
);
int
len
=
query_card
(
pduel
,
player
,
location
,
sequence
,
flag
,
(
unsigned
char
*
)
qbuf
,
0
);
NetServer
::
SendBufferToPlayer
(
players
[
player
],
STOC_GAME_MSG
,
query_buffer
,
len
+
4
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
3
);
replay_stream
.
push_back
(
p
);
if
(
location
==
LOCATION_REMOVED
&&
(
qbuf
[
15
]
&
POS_FACEDOWN
))
return
;
if
((
location
&
0x90
)
||
((
location
&
0x2c
)
&&
(
qbuf
[
15
]
&
POS_FACEUP
)))
{
...
...
@@ -1597,6 +1665,16 @@ void SingleDuel::RefreshSingle(int player, int location, int sequence, int flag)
NetServer
::
ReSendToPlayer
(
*
pit
);
}
}
void
SingleDuel
::
PseudoRefreshDeck
(
int
player
,
int
flag
)
{
char
query_buffer
[
0x2000
];
char
*
qbuf
=
query_buffer
;
BufferIO
::
WriteInt8
(
qbuf
,
MSG_UPDATE_DATA
);
BufferIO
::
WriteInt8
(
qbuf
,
player
);
BufferIO
::
WriteInt8
(
qbuf
,
LOCATION_DECK
);
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_DECK
,
flag
,
(
unsigned
char
*
)
qbuf
,
0
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
}
int
SingleDuel
::
MessageHandler
(
long
fduel
,
int
type
)
{
if
(
!
enable_log
)
return
0
;
...
...
@@ -1618,6 +1696,8 @@ void SingleDuel::SingleTimer(evutil_socket_t fd, short events, void* arg) {
NetServer
::
ReSendToPlayer
(
sd
->
players
[
1
]);
for
(
auto
oit
=
sd
->
observers
.
begin
();
oit
!=
sd
->
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
ReplayPacket
p
((
char
*
)
wbuf
,
3
);
sd
->
replay_stream
.
push_back
(
p
);
if
(
sd
->
players
[
player
]
==
sd
->
pplayer
[
player
])
{
sd
->
match_result
[
sd
->
duel_count
++
]
=
1
-
player
;
sd
->
tp_player
=
player
;
...
...
gframe/single_duel.h
View file @
3516ba98
...
...
@@ -40,6 +40,9 @@ public:
static
int
MessageHandler
(
long
fduel
,
int
type
);
static
void
SingleTimer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
);
void
PseudoRefreshDeck
(
int
player
,
int
flag
=
0x181fff
);
static
std
::
vector
<
ReplayPacket
>
replay_stream
;
protected:
DuelPlayer
*
players
[
2
];
...
...
@@ -51,6 +54,7 @@ protected:
unsigned
char
last_response
;
std
::
set
<
DuelPlayer
*>
observers
;
Replay
last_replay
;
Replay
new_replay
;
bool
match_mode
;
int
match_kill
;
bool
game_started
;
...
...
gframe/single_mode.cpp
View file @
3516ba98
...
...
@@ -11,6 +11,8 @@ long SingleMode::pduel = 0;
bool
SingleMode
::
is_closing
=
false
;
bool
SingleMode
::
is_continuing
=
false
;
Replay
SingleMode
::
last_replay
;
Replay
SingleMode
::
new_replay
;
std
::
vector
<
ReplayPacket
>
SingleMode
::
replay_stream
;
static
byte
buffer
[
0x20000
];
...
...
@@ -106,16 +108,21 @@ int SingleMode::SinglePlayThread(void* param) {
char
engineBuffer
[
0x1000
];
is_closing
=
false
;
is_continuing
=
true
;
int
len
=
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
if
(
len
>
0
)
is_continuing
=
SinglePlayAnalyze
(
engineBuffer
,
len
);
last_replay
.
BeginRecord
();
last_replay
.
BeginRecord
(
false
);
last_replay
.
WriteHeader
(
rh
);
//records the replay with the new system
new_replay
.
BeginRecord
();
rh
.
id
=
0x58707279
;
rh
.
flag
|=
REPLAY_NEWREPLAY
;
new_replay
.
WriteHeader
(
rh
);
replay_stream
.
clear
();
unsigned
short
buffer
[
20
];
BufferIO
::
CopyWStr
(
mainGame
->
dInfo
.
hostname
,
buffer
,
20
);
last_replay
.
WriteData
(
buffer
,
40
,
false
);
new_replay
.
WriteData
(
buffer
,
40
,
false
);
BufferIO
::
CopyWStr
(
mainGame
->
dInfo
.
clientname
,
buffer
,
20
);
last_replay
.
WriteData
(
buffer
,
40
,
false
);
new_replay
.
WriteData
(
buffer
,
40
,
false
);
last_replay
.
WriteInt32
(
start_lp
,
false
);
last_replay
.
WriteInt32
(
start_hand
,
false
);
last_replay
.
WriteInt32
(
draw_count
,
false
);
...
...
@@ -123,6 +130,11 @@ int SingleMode::SinglePlayThread(void* param) {
last_replay
.
WriteInt16
(
slen
,
false
);
last_replay
.
WriteData
(
filename
,
slen
,
false
);
last_replay
.
Flush
();
new_replay
.
WriteInt32
((
mainGame
->
GetMasterRule
(
opt
,
0
))
|
(
opt
&
SPEED_DUEL
)
<<
8
);
int
len
=
get_message
(
pduel
,
(
byte
*
)
engineBuffer
);
if
(
len
>
0
){
is_continuing
=
SinglePlayAnalyze
(
engineBuffer
,
len
);
}
start_duel
(
pduel
,
opt
);
while
(
is_continuing
)
{
int
result
=
process
(
pduel
);
...
...
@@ -133,7 +145,15 @@ int SingleMode::SinglePlayThread(void* param) {
is_continuing
=
SinglePlayAnalyze
(
engineBuffer
,
len
);
}
}
last_replay
.
EndRecord
();
last_replay
.
EndRecord
(
0x1000
);
char
replaybuf
[
0x2000
],
*
pbuf
=
replaybuf
;
memcpy
(
pbuf
,
&
last_replay
.
pheader
,
sizeof
(
ReplayHeader
));
pbuf
+=
sizeof
(
ReplayHeader
);
memcpy
(
pbuf
,
last_replay
.
comp_data
,
last_replay
.
comp_size
);
new_replay
.
WritePacket
(
ReplayPacket
(
OLD_REPLAY_MODE
,
replaybuf
,
sizeof
(
ReplayHeader
)
+
last_replay
.
comp_size
));
new_replay
.
EndRecord
();
time_t
nowtime
=
time
(
NULL
);
struct
tm
*
localedtime
=
localtime
(
&
nowtime
);
char
timebuf
[
40
];
...
...
@@ -146,8 +166,8 @@ int SingleMode::SinglePlayThread(void* param) {
mainGame
->
gMutex
.
Unlock
();
mainGame
->
replaySignal
.
Reset
();
mainGame
->
replaySignal
.
Wait
();
if
(
mainGame
->
actionParam
)
last
_replay
.
SaveReplay
(
mainGame
->
ebRSName
->
getText
());
if
(
mainGame
->
saveReplay
)
new
_replay
.
SaveReplay
(
mainGame
->
ebRSName
->
getText
());
end_duel
(
pduel
);
if
(
!
is_closing
)
{
mainGame
->
gMutex
.
Lock
();
...
...
@@ -171,10 +191,16 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
char
*
offset
,
*
pbuf
=
msg
;
int
player
,
count
;
while
(
pbuf
-
msg
<
(
int
)
len
)
{
replay_stream
.
clear
();
bool
record
=
true
;
if
(
is_closing
||
!
is_continuing
)
return
false
;
offset
=
pbuf
;
ReplayPacket
p
;
mainGame
->
dInfo
.
curMsg
=
BufferIO
::
ReadUInt8
(
pbuf
);
p
.
message
=
mainGame
->
dInfo
.
curMsg
;
p
.
length
=
len
-
1
;
memcpy
(
p
.
data
,
pbuf
,
p
.
length
);
switch
(
mainGame
->
dInfo
.
curMsg
)
{
case
MSG_RETRY
:
{
mainGame
->
gMutex
.
Lock
();
...
...
@@ -186,16 +212,19 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
return
false
;
}
case
MSG_HINT
:
{
/*int type = */
BufferIO
::
ReadInt8
(
pbuf
);
int
type
=
BufferIO
::
ReadInt8
(
pbuf
);
int
player
=
BufferIO
::
ReadInt8
(
pbuf
);
/*int data = */
BufferIO
::
ReadInt64
(
pbuf
);
if
(
player
==
0
)
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
if
(
type
>
0
&&
type
<
6
&&
type
!=
4
)
record
=
false
;
break
;
}
case
MSG_WIN
:
{
pbuf
+=
2
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
replay_stream
.
push_back
(
p
);
return
false
;
}
case
MSG_SELECT_BATTLECMD
:
{
...
...
@@ -209,6 +238,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_IDLECMD
:
{
...
...
@@ -230,6 +260,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_EFFECTYN
:
{
...
...
@@ -240,6 +271,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_YESNO
:
{
...
...
@@ -249,6 +281,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_OPTION
:
{
...
...
@@ -259,6 +292,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_CARD
:
...
...
@@ -271,6 +305,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_UNSELECT_CARD
:
{
...
...
@@ -284,6 +319,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_CHAIN
:
{
...
...
@@ -294,6 +330,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_PLACE
:
...
...
@@ -304,6 +341,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_POSITION
:
{
...
...
@@ -313,6 +351,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_COUNTER
:
{
...
...
@@ -324,6 +363,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SELECT_SUM
:
{
...
...
@@ -338,6 +378,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_SORT_CARD
:
...
...
@@ -349,6 +390,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_CONFIRM_DECKTOP
:
{
...
...
@@ -375,7 +417,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
case
MSG_SHUFFLE_DECK
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
SinglePlayRefresh
Deck
(
player
);
SinglePlayRefresh
(
player
,
LOCATION_DECK
,
0x181fff
);
break
;
}
case
MSG_SHUFFLE_HAND
:
{
...
...
@@ -400,13 +442,13 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
case
MSG_SWAP_GRAVE_DECK
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
SinglePlayRefresh
Grave
(
player
);
SinglePlayRefresh
(
player
,
LOCATION_GRAVE
,
0x181fff
);
break
;
}
case
MSG_REVERSE_DECK
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
SinglePlayRefresh
Deck
(
0
);
SinglePlayRefresh
Deck
(
1
);
SinglePlayRefresh
(
0
,
LOCATION_DECK
,
0x181fff
);
SinglePlayRefresh
(
1
,
LOCATION_DECK
,
0x181fff
);
break
;
}
case
MSG_DECK_TOP
:
{
...
...
@@ -521,8 +563,8 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
case
MSG_CHAIN_END
:
{
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
SinglePlayRefresh
();
SinglePlayRefresh
Deck
(
0
);
SinglePlayRefresh
Deck
(
1
);
SinglePlayRefresh
(
0
,
LOCATION_DECK
,
0x181fff
);
SinglePlayRefresh
(
1
,
LOCATION_DECK
,
0x181fff
);
break
;
}
case
MSG_CHAIN_NEGATED
:
{
...
...
@@ -655,6 +697,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_HAND_RES
:
{
...
...
@@ -669,6 +712,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_ANNOUNCE_ATTRIB
:
{
...
...
@@ -678,6 +722,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_ANNOUNCE_CARD
:
{
...
...
@@ -687,6 +732,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_ANNOUNCE_NUMBER
:
...
...
@@ -698,6 +744,7 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame
->
singleSignal
.
Reset
();
mainGame
->
singleSignal
.
Wait
();
}
record
=
false
;
break
;
}
case
MSG_CARD_HINT
:
{
...
...
@@ -714,8 +761,8 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
player
=
pbuf
[
0
];
pbuf
+=
pbuf
[
2
]
*
4
+
pbuf
[
4
]
*
4
+
9
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
SinglePlayRefresh
Deck
(
player
);
SinglePlayRefresh
Extra
(
player
);
SinglePlayRefresh
(
player
,
LOCATION_DECK
,
0x181fff
);
SinglePlayRefresh
(
player
,
LOCATION_EXTRA
,
0x181fff
);
break
;
}
case
MSG_MATCH_KILL
:
{
...
...
@@ -728,43 +775,6 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
int
rule
=
BufferIO
::
ReadInt8
(
pbuf
);
mainGame
->
dInfo
.
duel_field
=
rule
&
0xf
;
mainGame
->
dInfo
.
extraval
=
rule
>>
4
;
// reset master rule 4 phase button position
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
310
,
855
,
330
));
if
(
mainGame
->
dInfo
.
extraval
)
{
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
wPhase
->
setRelativePosition
(
mainGame
->
Resize
(
480
,
290
,
855
,
350
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
40
,
50
,
60
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
20
,
210
,
40
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
310
,
0
,
360
,
20
));
}
else
{
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
}
else
{
mainGame
->
btnDP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
if
(
mainGame
->
dInfo
.
duel_field
>=
4
)
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
160
,
0
,
210
,
20
));
}
else
{
mainGame
->
btnSP
->
setRelativePosition
(
mainGame
->
Resize
(
65
,
0
,
115
,
20
));
mainGame
->
btnM1
->
setRelativePosition
(
mainGame
->
Resize
(
130
,
0
,
180
,
20
));
mainGame
->
btnBP
->
setRelativePosition
(
mainGame
->
Resize
(
195
,
0
,
245
,
20
));
mainGame
->
btnM2
->
setRelativePosition
(
mainGame
->
Resize
(
260
,
0
,
310
,
20
));
}
mainGame
->
btnEP
->
setRelativePosition
(
mainGame
->
Resize
(
320
,
0
,
370
,
20
));
mainGame
->
btnShuffle
->
setRelativePosition
(
mainGame
->
Resize
(
0
,
0
,
50
,
20
));
}
int
val
=
0
;
for
(
int
p
=
0
;
p
<
2
;
++
p
)
{
mainGame
->
dInfo
.
lp
[
p
]
=
BufferIO
::
ReadInt32
(
pbuf
);
...
...
@@ -858,80 +868,64 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
break
;
}
}
//setting the length again in case of multiple messages in a row,
//when the packet will be written in the replay, the extra data registered previously will be discarded
p
.
length
=
(
pbuf
-
offset
)
-
1
;
if
(
record
)
replay_stream
.
insert
(
replay_stream
.
begin
(),
p
);
new_replay
.
WriteStream
(
replay_stream
);
}
return
is_continuing
;
}
void
SingleMode
::
SinglePlayRefresh
(
int
flag
)
{
void
SingleMode
::
SinglePlayRefresh
(
int
player
,
int
location
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
0
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
}
void
SingleMode
::
SinglePlayRefreshHand
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
}
void
SingleMode
::
SinglePlayRefreshGrave
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
}
void
SingleMode
::
SinglePlayRefreshDeck
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
}
void
SingleMode
::
SinglePlayRefreshExtra
(
int
player
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_field_card
(
pduel
,
player
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
char
queryBuffer2
[
0x2000
];
char
*
qbuf
=
queryBuffer2
;
ReplayPacket
p
;
int
len
=
query_field_card
(
pduel
,
player
,
location
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
player
),
location
,
(
char
*
)
queryBuffer
);
BufferIO
::
WriteInt8
(
qbuf
,
player
);
BufferIO
::
WriteInt8
(
qbuf
,
location
);
memcpy
(
qbuf
,
(
char
*
)
queryBuffer
,
len
);
replay_stream
.
push_back
(
ReplayPacket
(
MSG_UPDATE_DATA
,
queryBuffer2
,
len
+
2
));
}
void
SingleMode
::
SinglePlayRefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
)
{
unsigned
char
queryBuffer
[
0x2000
];
/*int len = */
query_card
(
pduel
,
player
,
location
,
sequence
,
flag
,
queryBuffer
,
0
);
char
queryBuffer2
[
0x2000
];
char
*
qbuf
=
queryBuffer2
;
int
len
=
query_card
(
pduel
,
player
,
location
,
sequence
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateCard
(
mainGame
->
LocalPlayer
(
player
),
location
,
sequence
,
(
char
*
)
queryBuffer
);
BufferIO
::
WriteInt8
(
qbuf
,
player
);
BufferIO
::
WriteInt8
(
qbuf
,
location
);
BufferIO
::
WriteInt8
(
qbuf
,
sequence
);
memcpy
(
qbuf
,
(
char
*
)
queryBuffer
,
len
);
ReplayPacket
p
(
MSG_UPDATE_CARD
,
queryBuffer2
,
len
+
3
);
replay_stream
.
push_back
(
p
);
}
void
SingleMode
::
SinglePlayRefresh
(
int
flag
)
{
SinglePlayRefresh
(
0
,
LOCATION_MZONE
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_MZONE
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_SZONE
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_SZONE
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_HAND
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_HAND
,
flag
);
}
void
SingleMode
::
SinglePlayReload
()
{
unsigned
char
queryBuffer
[
0x2000
];
unsigned
int
flag
=
0xffdfff
;
/*int len = */
query_field_card
(
pduel
,
0
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_MZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_MZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_SZONE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_SZONE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_HAND
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_HAND
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_DECK
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_DECK
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_EXTRA
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_EXTRA
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_GRAVE
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_GRAVE
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
0
,
LOCATION_REMOVED
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
0
),
LOCATION_REMOVED
,
(
char
*
)
queryBuffer
);
/*len = */
query_field_card
(
pduel
,
1
,
LOCATION_REMOVED
,
flag
,
queryBuffer
,
0
);
mainGame
->
dField
.
UpdateFieldCard
(
mainGame
->
LocalPlayer
(
1
),
LOCATION_REMOVED
,
(
char
*
)
queryBuffer
);
SinglePlayRefresh
(
0
,
LOCATION_MZONE
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_MZONE
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_SZONE
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_SZONE
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_HAND
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_HAND
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_DECK
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_DECK
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_EXTRA
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_EXTRA
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_GRAVE
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_GRAVE
,
flag
);
SinglePlayRefresh
(
0
,
LOCATION_REMOVED
,
flag
);
SinglePlayRefresh
(
1
,
LOCATION_REMOVED
,
flag
);
}
byte
*
SingleMode
::
ScriptReader
(
const
char
*
script_name
,
int
*
slen
)
{
FILE
*
fp
;
...
...
@@ -960,4 +954,4 @@ int SingleMode::MessageHandler(long fduel, int type) {
return
0
;
}
}
}
\ No newline at end of file
gframe/single_mode.h
View file @
3516ba98
...
...
@@ -18,11 +18,8 @@ public:
static
int
SinglePlayThread
(
void
*
param
);
static
bool
SinglePlayAnalyze
(
char
*
msg
,
unsigned
int
len
);
static
void
SinglePlayRefresh
(
int
player
,
int
location
,
int
flag
=
0xf81fff
);
static
void
SinglePlayRefresh
(
int
flag
=
0xf81fff
);
static
void
SinglePlayRefreshHand
(
int
player
,
int
flag
=
0x781fff
);
static
void
SinglePlayRefreshGrave
(
int
player
,
int
flag
=
0x181fff
);
static
void
SinglePlayRefreshDeck
(
int
player
,
int
flag
=
0x181fff
);
static
void
SinglePlayRefreshExtra
(
int
player
,
int
flag
=
0x181fff
);
static
void
SinglePlayRefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
=
0xf81fff
);
static
void
SinglePlayReload
();
...
...
@@ -31,6 +28,8 @@ public:
protected:
static
Replay
last_replay
;
static
Replay
new_replay
;
static
std
::
vector
<
ReplayPacket
>
replay_stream
;
};
}
...
...
gframe/tag_duel.cpp
View file @
3516ba98
...
...
@@ -9,6 +9,8 @@
namespace
ygo
{
std
::
vector
<
ReplayPacket
>
TagDuel
::
replay_stream
;
TagDuel
::
TagDuel
()
{
game_started
=
false
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
...
...
@@ -355,13 +357,23 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
rh
.
flag
=
REPLAY_TAG
+
REPLAY_LUA64
;
time_t
seed
=
time
(
0
);
rh
.
seed
=
seed
;
last_replay
.
BeginRecord
();
last_replay
.
BeginRecord
(
false
);
last_replay
.
WriteHeader
(
rh
);
rnd
.
reset
(
seed
);
last_replay
.
WriteData
(
players
[
0
]
->
name
,
40
,
false
);
last_replay
.
WriteData
(
players
[
1
]
->
name
,
40
,
false
);
last_replay
.
WriteData
(
players
[
2
]
->
name
,
40
,
false
);
last_replay
.
WriteData
(
players
[
3
]
->
name
,
40
,
false
);
//records the replay with the new system
new_replay
.
BeginRecord
();
rh
.
id
=
0x58707279
;
rh
.
flag
|=
REPLAY_NEWREPLAY
;
new_replay
.
WriteHeader
(
rh
);
new_replay
.
WriteData
(
players
[
0
]
->
name
,
40
,
false
);
new_replay
.
WriteData
(
players
[
1
]
->
name
,
40
,
false
);
new_replay
.
WriteData
(
players
[
2
]
->
name
,
40
,
false
);
new_replay
.
WriteData
(
players
[
3
]
->
name
,
40
);
replay_stream
.
clear
();
if
(
!
host_info
.
no_shuffle_deck
)
{
for
(
size_t
i
=
pdeck
[
0
].
main
.
size
()
-
1
;
i
>
0
;
--
i
)
{
int
swap
=
rnd
.
real
()
*
(
i
+
1
);
...
...
@@ -395,6 +407,7 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if
(
host_info
.
speed
)
opt
|=
SPEED_DUEL
;
opt
|=
DUEL_TAG_MODE
;
new_replay
.
WriteInt32
((
mainGame
->
GetMasterRule
(
opt
,
0
))
|
(
opt
&
SPEED_DUEL
)
<<
8
);
last_replay
.
WriteInt32
(
host_info
.
start_lp
,
false
);
last_replay
.
WriteInt32
(
host_info
.
start_hand
,
false
);
last_replay
.
WriteInt32
(
host_info
.
draw_count
,
false
);
...
...
@@ -519,8 +532,14 @@ void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
else
startbuf
[
1
]
=
0x11
;
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
SendBufferToPlayer
(
*
oit
,
STOC_GAME_MSG
,
startbuf
,
18
);
startbuf
[
1
]
=
0
;
ReplayPacket
p
((
char
*
)
startbuf
,
17
);
replay_stream
.
push_back
(
p
);
PseudoRefreshDeck
(
0
);
PseudoRefreshDeck
(
1
);
RefreshExtra
(
0
);
RefreshExtra
(
1
);
new_replay
.
WriteStream
(
replay_stream
);
start_duel
(
pduel
,
opt
);
Process
();
}
...
...
@@ -558,12 +577,19 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
char
*
offset
,
*
pbufw
,
*
pbuf
=
msgbuffer
;
int
player
,
count
,
type
;
while
(
pbuf
-
msgbuffer
<
(
int
)
len
)
{
replay_stream
.
clear
();
bool
record
=
true
;
ReplayPacket
p
;
offset
=
pbuf
;
unsigned
char
engType
=
BufferIO
::
ReadUInt8
(
pbuf
);
p
.
message
=
engType
;
p
.
length
=
len
-
1
;
memcpy
(
p
.
data
,
pbuf
,
p
.
length
);
switch
(
engType
)
{
case
MSG_RETRY
:
{
WaitforResponse
(
last_response
);
NetServer
::
SendBufferToPlayer
(
cur_player
[
last_response
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
replay_stream
.
push_back
(
p
);
return
1
;
}
case
MSG_HINT
:
{
...
...
@@ -577,6 +603,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
case
5
:
case
10
:
{
NetServer
::
SendBufferToPlayer
(
cur_player
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
record
=
false
;
break
;
}
case
4
:
...
...
@@ -603,6 +630,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
ReSendToPlayer
(
players
[
3
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
replay_stream
.
push_back
(
p
);
EndDuel
();
return
2
;
}
...
...
@@ -817,6 +845,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
ReSendToPlayer
(
players
[
3
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
PseudoRefreshDeck
(
player
);
break
;
}
case
MSG_SHUFFLE_HAND
:
{
...
...
@@ -875,6 +904,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
ReSendToPlayer
(
players
[
3
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
PseudoRefreshDeck
(
0
);
PseudoRefreshDeck
(
1
);
break
;
}
case
MSG_DECK_TOP
:
{
...
...
@@ -1499,6 +1530,7 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
SendBufferToPlayer
(
players
[
p
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
PseudoRefreshDeck
(
player
);
RefreshExtra
(
player
);
RefreshMzone
(
0
,
0x81fff
,
0
);
RefreshMzone
(
1
,
0x81fff
,
0
);
...
...
@@ -1513,6 +1545,12 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
break
;
}
}
//setting the length again in case of multiple messages in a row,
//when the packet will be written in the replay, the extra data registered previously will be discarded
p
.
length
=
(
pbuf
-
offset
)
-
1
;
if
(
record
)
replay_stream
.
insert
(
replay_stream
.
begin
(),
p
);
new_replay
.
WriteStream
(
replay_stream
);
}
return
0
;
}
...
...
@@ -1535,11 +1573,29 @@ void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
void
TagDuel
::
EndDuel
()
{
if
(
!
pduel
)
return
;
last_replay
.
EndRecord
();
last_replay
.
EndRecord
(
0x1000
);
char
replaybuf
[
0x2000
],
*
pbuf
=
replaybuf
;
memcpy
(
pbuf
,
&
last_replay
.
pheader
,
sizeof
(
ReplayHeader
));
pbuf
+=
sizeof
(
ReplayHeader
);
memcpy
(
pbuf
,
last_replay
.
comp_data
,
last_replay
.
comp_size
);
replay_stream
.
push_back
(
ReplayPacket
(
OLD_REPLAY_MODE
,
replaybuf
,
sizeof
(
ReplayHeader
)
+
last_replay
.
comp_size
));
//in case of remaining packets, e.g. MSG_WIN
new_replay
.
WriteStream
(
replay_stream
);
new_replay
.
EndRecord
();
char
nreplaybuf
[
0x2000
],
*
npbuf
=
nreplaybuf
;
memcpy
(
npbuf
,
&
new_replay
.
pheader
,
sizeof
(
ReplayHeader
));
npbuf
+=
sizeof
(
ReplayHeader
);
memcpy
(
npbuf
,
new_replay
.
comp_data
,
new_replay
.
comp_size
);
NetServer
::
SendBufferToPlayer
(
players
[
0
],
STOC_NEW_REPLAY
,
nreplaybuf
,
sizeof
(
ReplayHeader
)
+
new_replay
.
comp_size
);
NetServer
::
ReSendToPlayer
(
players
[
1
]);
NetServer
::
ReSendToPlayer
(
players
[
2
]);
NetServer
::
ReSendToPlayer
(
players
[
3
]);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
NetServer
::
SendBufferToPlayer
(
players
[
0
],
STOC_REPLAY
,
replaybuf
,
sizeof
(
ReplayHeader
)
+
last_replay
.
comp_size
);
NetServer
::
ReSendToPlayer
(
players
[
1
]);
NetServer
::
ReSendToPlayer
(
players
[
2
]);
...
...
@@ -1586,6 +1642,8 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_MZONE
,
flag
,
(
unsigned
char
*
)
qbuf
,
use_cache
);
int
pid
=
(
player
==
0
)
?
0
:
2
;
NetServer
::
SendBufferToPlayer
(
players
[
pid
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
NetServer
::
ReSendToPlayer
(
players
[
pid
+
1
]);
int
qlen
=
0
;
while
(
qlen
<
len
)
{
...
...
@@ -1612,6 +1670,8 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_SZONE
,
flag
,
(
unsigned
char
*
)
qbuf
,
use_cache
);
int
pid
=
(
player
==
0
)
?
0
:
2
;
NetServer
::
SendBufferToPlayer
(
players
[
pid
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
NetServer
::
ReSendToPlayer
(
players
[
pid
+
1
]);
int
qlen
=
0
;
while
(
qlen
<
len
)
{
...
...
@@ -1637,6 +1697,8 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO
::
WriteInt8
(
qbuf
,
LOCATION_HAND
);
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_HAND
,
flag
|
QUERY_IS_PUBLIC
,
(
unsigned
char
*
)
qbuf
,
use_cache
);
NetServer
::
SendBufferToPlayer
(
cur_player
[
player
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
int
qlen
=
0
;
while
(
qlen
<
len
)
{
int
slen
=
BufferIO
::
ReadInt32
(
qbuf
);
...
...
@@ -1670,6 +1732,8 @@ void TagDuel::RefreshGrave(int player, int flag, int use_cache) {
NetServer
::
ReSendToPlayer
(
players
[
3
]);
for
(
auto
pit
=
observers
.
begin
();
pit
!=
observers
.
end
();
++
pit
)
NetServer
::
ReSendToPlayer
(
*
pit
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
}
void
TagDuel
::
RefreshExtra
(
int
player
,
int
flag
,
int
use_cache
)
{
char
query_buffer
[
0x2000
];
...
...
@@ -1679,6 +1743,8 @@ void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
BufferIO
::
WriteInt8
(
qbuf
,
LOCATION_EXTRA
);
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_EXTRA
,
flag
,
(
unsigned
char
*
)
qbuf
,
use_cache
);
NetServer
::
SendBufferToPlayer
(
cur_player
[
player
],
STOC_GAME_MSG
,
query_buffer
,
len
+
3
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
}
void
TagDuel
::
RefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
)
{
char
query_buffer
[
0x2000
];
...
...
@@ -1688,6 +1754,8 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
BufferIO
::
WriteInt8
(
qbuf
,
location
);
BufferIO
::
WriteInt8
(
qbuf
,
sequence
);
int
len
=
query_card
(
pduel
,
player
,
location
,
sequence
,
flag
,
(
unsigned
char
*
)
qbuf
,
0
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
3
);
replay_stream
.
push_back
(
p
);
if
(
location
&
LOCATION_ONFIELD
)
{
int
pid
=
(
player
==
0
)
?
0
:
2
;
NetServer
::
SendBufferToPlayer
(
players
[
pid
],
STOC_GAME_MSG
,
query_buffer
,
len
+
4
);
...
...
@@ -1714,6 +1782,16 @@ void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
}
}
}
void
TagDuel
::
PseudoRefreshDeck
(
int
player
,
int
flag
)
{
char
query_buffer
[
0x2000
];
char
*
qbuf
=
query_buffer
;
BufferIO
::
WriteInt8
(
qbuf
,
MSG_UPDATE_DATA
);
BufferIO
::
WriteInt8
(
qbuf
,
player
);
BufferIO
::
WriteInt8
(
qbuf
,
LOCATION_DECK
);
int
len
=
query_field_card
(
pduel
,
player
,
LOCATION_DECK
,
flag
,
(
unsigned
char
*
)
qbuf
,
0
);
ReplayPacket
p
((
char
*
)
query_buffer
,
len
+
2
);
replay_stream
.
push_back
(
p
);
}
int
TagDuel
::
MessageHandler
(
long
fduel
,
int
type
)
{
if
(
!
enable_log
)
return
0
;
...
...
@@ -1735,6 +1813,8 @@ void TagDuel::TagTimer(evutil_socket_t fd, short events, void* arg) {
NetServer
::
ReSendToPlayer
(
sd
->
players
[
1
]);
NetServer
::
ReSendToPlayer
(
sd
->
players
[
2
]);
NetServer
::
ReSendToPlayer
(
sd
->
players
[
3
]);
ReplayPacket
p
((
char
*
)
wbuf
,
3
);
sd
->
replay_stream
.
push_back
(
p
);
sd
->
EndDuel
();
sd
->
DuelEndProc
();
event_del
(
sd
->
etimer
);
...
...
gframe/tag_duel.h
View file @
3516ba98
...
...
@@ -40,6 +40,9 @@ public:
static
int
MessageHandler
(
long
fduel
,
int
type
);
static
void
TagTimer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
);
void
PseudoRefreshDeck
(
int
player
,
int
flag
=
0x181fff
);
static
std
::
vector
<
ReplayPacket
>
replay_stream
;
protected:
DuelPlayer
*
players
[
4
];
...
...
@@ -52,6 +55,7 @@ protected:
unsigned
char
hand_result
[
2
];
unsigned
char
last_response
;
Replay
last_replay
;
Replay
new_replay
;
bool
game_started
;
unsigned
char
turn_count
;
unsigned
short
time_limit
[
2
];
...
...
ocgcore
@
2a37a9fa
Subproject commit
cbcff83c4001fb4208a530f580ad7ce0ac1fdfb2
Subproject commit
2a37a9fad5e84d06998e16eb530c0c2acdbb4e81
strings.conf
View file @
3516ba98
#The first line is used for comment
#line doesn't start with '!' is also neglected
#called by DataManager::GetSysString(), DataManager::GetDesc()
#system
!
system
1
Normal
Summon
!
system
2
Special
Summon
...
...
@@ -375,6 +375,7 @@
!
system
1353
Start
at
turn
:
!
system
1354
Hide
Set
Names
!
system
1355
Hide
Chain
Buttons
!
system
1356
Old
Replay
Mode
!
system
1360
Previous
!
system
1370
Level
↑
!
system
1371
Attack
↑
...
...
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