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
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
YGOPRO-520DIY
ygopro
Commits
f23cbe45
Commit
f23cbe45
authored
May 09, 2012
by
argon.sun
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:Fluorohydride/ygopro
parents
6f9ffc19
2b1b5e62
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
266 additions
and
78 deletions
+266
-78
gframe/drawing.cpp
gframe/drawing.cpp
+11
-4
gframe/duelclient.cpp
gframe/duelclient.cpp
+108
-1
gframe/game.cpp
gframe/game.cpp
+1
-0
gframe/netserver.cpp
gframe/netserver.cpp
+5
-1
gframe/network.h
gframe/network.h
+4
-4
gframe/replay_mode.cpp
gframe/replay_mode.cpp
+50
-15
gframe/single_duel.cpp
gframe/single_duel.cpp
+7
-3
gframe/tag_duel.cpp
gframe/tag_duel.cpp
+32
-5
gframe/tag_duel.h
gframe/tag_duel.h
+1
-1
ocgcore/field.cpp
ocgcore/field.cpp
+9
-0
ocgcore/operations.cpp
ocgcore/operations.cpp
+1
-1
script/c25123082.lua
script/c25123082.lua
+3
-3
script/c25924653.lua
script/c25924653.lua
+2
-2
script/c27068117.lua
script/c27068117.lua
+2
-1
script/c33302407.lua
script/c33302407.lua
+2
-2
script/c33900648.lua
script/c33900648.lua
+8
-8
script/c51589188.lua
script/c51589188.lua
+1
-1
script/c51790181.lua
script/c51790181.lua
+0
-8
script/c52628687.lua
script/c52628687.lua
+14
-13
script/c63676256.lua
script/c63676256.lua
+4
-4
script/c99004752.lua
script/c99004752.lua
+1
-1
No files found.
gframe/drawing.cpp
View file @
f23cbe45
...
...
@@ -326,10 +326,17 @@ void Game::DrawMisc() {
numFont
->
draw
(
dInfo
.
strLP
[
1
],
recti
(
691
,
11
,
990
,
30
),
0xff000000
,
true
,
false
,
0
);
numFont
->
draw
(
dInfo
.
strLP
[
1
],
recti
(
691
,
12
,
992
,
30
),
0xffffff00
,
true
,
false
,
0
);
textFont
->
draw
(
dInfo
.
hostname
,
recti
(
335
,
31
,
629
,
50
),
0xffffffff
,
false
,
false
,
0
);
auto
cld
=
textFont
->
getDimension
(
dInfo
.
clientname
);
textFont
->
draw
(
dInfo
.
clientname
,
recti
(
986
-
cld
.
Width
,
31
,
986
,
50
),
0xffffffff
,
false
,
false
,
0
);
if
(
!
dInfo
.
is_tag
||
!
dInfo
.
tag_player
[
0
])
textFont
->
draw
(
dInfo
.
hostname
,
recti
(
335
,
31
,
629
,
50
),
0xffffffff
,
false
,
false
,
0
);
else
textFont
->
draw
(
dInfo
.
hostname_tag
,
recti
(
335
,
31
,
629
,
50
),
0xffffffff
,
false
,
false
,
0
);
if
(
!
dInfo
.
is_tag
||
!
dInfo
.
tag_player
[
1
])
{
auto
cld
=
textFont
->
getDimension
(
dInfo
.
clientname
);
textFont
->
draw
(
dInfo
.
clientname
,
recti
(
986
-
cld
.
Width
,
31
,
986
,
50
),
0xffffffff
,
false
,
false
,
0
);
}
else
{
auto
cld
=
textFont
->
getDimension
(
dInfo
.
clientname_tag
);
textFont
->
draw
(
dInfo
.
clientname_tag
,
recti
(
986
-
cld
.
Width
,
31
,
986
,
50
),
0xffffffff
,
false
,
false
,
0
);
}
driver
->
draw2DRectangle
(
recti
(
632
,
10
,
688
,
30
),
0x00000000
,
0x00000000
,
0xffffffff
,
0xffffffff
);
driver
->
draw2DRectangle
(
recti
(
632
,
30
,
688
,
50
),
0xffffffff
,
0xffffffff
,
0x00000000
,
0x00000000
);
lpcFont
->
draw
(
dataManager
.
GetNumString
(
dInfo
.
turn
),
recti
(
635
,
5
,
685
,
40
),
0x80000000
,
true
,
false
,
0
);
...
...
gframe/duelclient.cpp
View file @
f23cbe45
...
...
@@ -600,7 +600,11 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
if
(
pos
>
3
)
break
;
mainGame
->
gMutex
.
Lock
();
if
(
state
==
PLAYERCHANGE_READY
)
{
if
(
state
<
8
)
{
mainGame
->
stHostPrepDuelist
[
state
]
->
setText
(
mainGame
->
stHostPrepDuelist
[
pos
]
->
getText
());
mainGame
->
stHostPrepDuelist
[
pos
]
->
setText
(
L""
);
mainGame
->
chkHostPrepReady
[
pos
]
->
setChecked
(
false
);
}
else
if
(
state
==
PLAYERCHANGE_READY
)
{
mainGame
->
chkHostPrepReady
[
pos
]
->
setChecked
(
true
);
}
else
if
(
state
==
PLAYERCHANGE_NOTREADY
)
{
mainGame
->
chkHostPrepReady
[
pos
]
->
setChecked
(
false
);
...
...
@@ -2566,6 +2570,109 @@ int DuelClient::ClientAnalyze(char* msg, unsigned int len) {
}
return
true
;
}
case
MSG_TAG_SWAP
:
{
int
player
=
mainGame
->
LocalPlayer
(
BufferIO
::
ReadInt8
(
pbuf
));
int
mcount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
ecount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
hcount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
topcode
=
BufferIO
::
ReadInt32
(
pbuf
);
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
deck
[
player
].
size
();
++
i
)
mainGame
->
dField
.
deck
[
player
][
i
]
->
code
=
0
;
for
(
auto
cit
=
mainGame
->
dField
.
deck
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
deck
[
player
].
end
();
++
cit
)
{
if
(
player
==
0
)
(
*
cit
)
->
dPos
.
Y
=
1.0
f
;
else
(
*
cit
)
->
dPos
.
Y
=
-
1.0
f
;
(
*
cit
)
->
dRot
=
irr
::
core
::
vector3df
(
0
,
0
,
0
);
(
*
cit
)
->
is_moving
=
true
;
(
*
cit
)
->
aniFrame
=
5
;
}
for
(
auto
cit
=
mainGame
->
dField
.
hand
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
hand
[
player
].
end
();
++
cit
)
{
if
(
player
==
0
)
(
*
cit
)
->
dPos
.
Y
=
1.0
f
;
else
(
*
cit
)
->
dPos
.
Y
=
-
1.0
f
;
(
*
cit
)
->
dRot
=
irr
::
core
::
vector3df
(
0
,
0
,
0
);
(
*
cit
)
->
is_moving
=
true
;
(
*
cit
)
->
aniFrame
=
5
;
}
for
(
auto
cit
=
mainGame
->
dField
.
extra
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
extra
[
player
].
end
();
++
cit
)
{
if
(
player
==
0
)
(
*
cit
)
->
dPos
.
Y
=
1.0
f
;
else
(
*
cit
)
->
dPos
.
Y
=
-
1.0
f
;
(
*
cit
)
->
dRot
=
irr
::
core
::
vector3df
(
0
,
0
,
0
);
(
*
cit
)
->
is_moving
=
true
;
(
*
cit
)
->
aniFrame
=
5
;
}
mainGame
->
WaitFrameSignal
(
5
);
//
mainGame
->
gMutex
.
Lock
();
if
(
mainGame
->
dField
.
deck
[
player
].
size
()
>
mcount
)
{
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
deck
[
player
].
size
()
-
mcount
;
++
i
)
{
ClientCard
*
ccard
=
*
mainGame
->
dField
.
deck
[
player
].
rbegin
();
mainGame
->
dField
.
deck
[
player
].
pop_back
();
delete
ccard
;
}
}
else
{
for
(
int
i
=
0
;
i
<
mcount
-
mainGame
->
dField
.
deck
[
player
].
size
();
++
i
)
{
ClientCard
*
ccard
=
new
ClientCard
();
ccard
->
controler
=
player
;
ccard
->
location
=
LOCATION_DECK
;
ccard
->
sequence
=
mainGame
->
dField
.
deck
[
player
].
size
()
-
1
;
mainGame
->
dField
.
deck
[
player
].
push_back
(
ccard
);
}
}
if
(
mainGame
->
dField
.
hand
[
player
].
size
()
>
mcount
)
{
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
hand
[
player
].
size
()
-
mcount
;
++
i
)
{
ClientCard
*
ccard
=
*
mainGame
->
dField
.
hand
[
player
].
rbegin
();
mainGame
->
dField
.
hand
[
player
].
pop_back
();
delete
ccard
;
}
}
else
{
for
(
int
i
=
0
;
i
<
mcount
-
mainGame
->
dField
.
hand
[
player
].
size
();
++
i
)
{
ClientCard
*
ccard
=
new
ClientCard
();
ccard
->
controler
=
player
;
ccard
->
location
=
LOCATION_HAND
;
ccard
->
sequence
=
mainGame
->
dField
.
hand
[
player
].
size
()
-
1
;
mainGame
->
dField
.
hand
[
player
].
push_back
(
ccard
);
}
}
if
(
mainGame
->
dField
.
extra
[
player
].
size
()
>
mcount
)
{
for
(
int
i
=
0
;
i
<
mainGame
->
dField
.
extra
[
player
].
size
()
-
mcount
;
++
i
)
{
ClientCard
*
ccard
=
*
mainGame
->
dField
.
extra
[
player
].
rbegin
();
mainGame
->
dField
.
extra
[
player
].
pop_back
();
delete
ccard
;
}
}
else
{
for
(
int
i
=
0
;
i
<
mcount
-
mainGame
->
dField
.
extra
[
player
].
size
();
++
i
)
{
ClientCard
*
ccard
=
new
ClientCard
();
ccard
->
controler
=
player
;
ccard
->
location
=
LOCATION_EXTRA
;
ccard
->
sequence
=
mainGame
->
dField
.
extra
[
player
].
size
()
-
1
;
mainGame
->
dField
.
extra
[
player
].
push_back
(
ccard
);
}
}
mainGame
->
gMutex
.
Unlock
();
//
for
(
auto
cit
=
mainGame
->
dField
.
deck
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
deck
[
player
].
end
();
++
cit
)
{
ClientCard
*
pcard
=
*
cit
;
mainGame
->
dField
.
GetCardLocation
(
pcard
,
&
pcard
->
curPos
,
&
pcard
->
curRot
);
if
(
player
==
0
)
pcard
->
curPos
.
Y
+=
5.0
f
;
else
pcard
->
curPos
.
Y
-=
5.0
f
;
mainGame
->
dField
.
MoveCard
(
*
cit
,
5
);
}
for
(
auto
cit
=
mainGame
->
dField
.
hand
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
hand
[
player
].
end
();
++
cit
)
{
ClientCard
*
pcard
=
*
cit
;
mainGame
->
dField
.
GetCardLocation
(
pcard
,
&
pcard
->
curPos
,
&
pcard
->
curRot
);
if
(
player
==
0
)
pcard
->
curPos
.
Y
+=
5.0
f
;
else
pcard
->
curPos
.
Y
-=
5.0
f
;
mainGame
->
dField
.
MoveCard
(
*
cit
,
5
);
}
for
(
auto
cit
=
mainGame
->
dField
.
extra
[
player
].
begin
();
cit
!=
mainGame
->
dField
.
extra
[
player
].
end
();
++
cit
)
{
ClientCard
*
pcard
=
*
cit
;
mainGame
->
dField
.
GetCardLocation
(
pcard
,
&
pcard
->
curPos
,
&
pcard
->
curRot
);
if
(
player
==
0
)
pcard
->
curPos
.
Y
+=
5.0
f
;
else
pcard
->
curPos
.
Y
-=
5.0
f
;
mainGame
->
dField
.
MoveCard
(
*
cit
,
5
);
}
mainGame
->
WaitFrameSignal
(
5
);
break
;
}
}
return
true
;
}
...
...
gframe/game.cpp
View file @
f23cbe45
...
...
@@ -110,6 +110,7 @@ bool Game::Initialize() {
cbMatchMode
=
env
->
addComboBox
(
rect
<
s32
>
(
140
,
85
,
300
,
110
),
wCreateHost
);
cbMatchMode
->
addItem
(
dataManager
.
GetSysString
(
1244
));
cbMatchMode
->
addItem
(
dataManager
.
GetSysString
(
1245
));
cbMatchMode
->
addItem
(
dataManager
.
GetSysString
(
1246
));
env
->
addStaticText
(
dataManager
.
GetSysString
(
1237
),
rect
<
s32
>
(
20
,
120
,
320
,
140
),
false
,
false
,
wCreateHost
);
myswprintf
(
strbuf
,
L"%d"
,
180
);
ebTimeLimit
=
env
->
addEditBox
(
strbuf
,
rect
<
s32
>
(
140
,
115
,
220
,
140
),
true
,
wCreateHost
);
...
...
gframe/netserver.cpp
View file @
f23cbe45
#include "netserver.h"
#include "single_duel.h"
#include "tag_duel.h"
namespace
ygo
{
std
::
unordered_map
<
bufferevent
*
,
DuelPlayer
>
NetServer
::
users
;
...
...
@@ -228,10 +229,13 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
}
else
if
(
pkt
->
info
.
mode
==
MODE_MATCH
)
{
duel_mode
=
new
SingleDuel
(
true
);
duel_mode
->
etimer
=
event_new
(
net_evbase
,
0
,
EV_TIMEOUT
|
EV_PERSIST
,
SingleDuel
::
SingleTimer
,
duel_mode
);
}
else
if
(
pkt
->
info
.
mode
==
MODE_TAG
)
{
duel_mode
=
new
TagDuel
();
duel_mode
->
etimer
=
event_new
(
net_evbase
,
0
,
EV_TIMEOUT
|
EV_PERSIST
,
TagDuel
::
TagTimer
,
duel_mode
);
}
if
(
pkt
->
info
.
rule
>
3
)
pkt
->
info
.
rule
=
0
;
if
(
pkt
->
info
.
mode
>
1
)
if
(
pkt
->
info
.
mode
>
2
)
pkt
->
info
.
mode
=
0
;
unsigned
int
hash
=
1
;
for
(
auto
lfit
=
deckManager
.
_lfList
.
begin
();
lfit
!=
deckManager
.
_lfList
.
end
();
++
lfit
)
{
...
...
gframe/network.h
View file @
f23cbe45
...
...
@@ -197,10 +197,10 @@ public:
#define STOC_HS_PLAYER_CHANGE 0x21
#define STOC_HS_WATCH_CHANGE 0x22
#define PLAYERCHANGE_
READY 0x1
#define PLAYERCHANGE_
NOTREADY 0x2
#define PLAYERCHANGE_
LEAVE 0x3
#define PLAYERCHANGE_
OBSERVE 0x4
#define PLAYERCHANGE_
OBSERVE 0x8
#define PLAYERCHANGE_
READY 0x9
#define PLAYERCHANGE_
NOTREADY 0xa
#define PLAYERCHANGE_
LEAVE 0xb
#define ERRMSG_JOINERROR 0x1
#define ERRMSG_DECKERROR 0x2
...
...
gframe/replay_mode.cpp
View file @
f23cbe45
#include "replay_mode.h"
#include "duelclient.h"
#include "game.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
...
...
@@ -72,20 +73,49 @@ int ReplayMode::ReplayThread(void* param) {
myswprintf
(
mainGame
->
dInfo
.
strLP
[
1
],
L"%d"
,
mainGame
->
dInfo
.
lp
[
1
]);
mainGame
->
dInfo
.
turn
=
0
;
mainGame
->
dInfo
.
strTurn
[
0
]
=
0
;
int
main
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
main
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_DECK
,
0
,
0
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
0
);
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
,
0
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
0
);
mainGame
->
dField
.
Initial
(
1
,
main
,
extra
);
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
,
0
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
0
);
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
,
0
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
0
);
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
,
0
);
int
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
0
,
0
,
LOCATION_EXTRA
,
0
,
0
);
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
,
0
);
extra
=
cur_replay
.
ReadInt32
();
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
new_card
(
pduel
,
cur_replay
.
ReadInt32
(),
1
,
1
,
LOCATION_EXTRA
,
0
,
0
);
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
);
}
start_duel
(
pduel
,
opt
);
mainGame
->
dInfo
.
isStarted
=
true
;
mainGame
->
dInfo
.
isReplay
=
true
;
...
...
@@ -565,6 +595,11 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
case
MSG_TAG_SWAP
:
{
pbuf
+=
pbuf
[
4
]
*
4
+
8
;
DuelClient
::
ClientAnalyze
(
offset
,
pbuf
-
offset
);
break
;
}
}
if
(
pauseable
&&
is_pausing
)
{
is_paused
=
true
;
...
...
@@ -614,7 +649,7 @@ int ReplayMode::MessageHandler(long fduel, int type) {
wchar_t
wbuf
[
1024
];
BufferIO
::
DecodeUTF8
(
msgbuf
,
wbuf
);
mainGame
->
AddChatMsg
(
wbuf
,
9
);
}
else
if
(
enable_log
==
2
){
}
else
if
(
enable_log
==
2
)
{
FILE
*
fp
=
fopen
(
"error.log"
,
"at"
);
if
(
!
fp
)
return
0
;
...
...
gframe/single_duel.cpp
View file @
f23cbe45
...
...
@@ -1081,8 +1081,12 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
pbufw
=
pbuf
;
pbuf
+=
count
*
4
;
NetServer
::
SendBufferToPlayer
(
players
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
BufferIO
::
WriteInt32
(
pbufw
,
0
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
(
pbufw
[
i
]
&
0x80000000
))
BufferIO
::
WriteInt32
(
pbufw
,
0
);
else
pbufw
+=
4
;
}
NetServer
::
SendBufferToPlayer
(
players
[
1
-
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
...
...
@@ -1437,7 +1441,7 @@ int SingleDuel::MessageHandler(long fduel, int type) {
wchar_t
wbuf
[
1024
];
BufferIO
::
DecodeUTF8
(
msgbuf
,
wbuf
);
mainGame
->
AddChatMsg
(
wbuf
,
9
);
}
else
if
(
enable_log
==
2
){
}
else
if
(
enable_log
==
2
)
{
FILE
*
fp
=
fopen
(
"error.log"
,
"at"
);
if
(
!
fp
)
return
0
;
...
...
gframe/tag_duel.cpp
View file @
f23cbe45
...
...
@@ -191,13 +191,12 @@ void TagDuel::ToDuelist(DuelPlayer* dp) {
for
(
auto
pit
=
observers
.
begin
();
pit
!=
observers
.
end
();
++
pit
)
NetServer
::
SendPacketToPlayer
(
*
pit
,
STOC_HS_PLAYER_CHANGE
,
scpc
);
STOC_TypeChange
sctc
;
sctc
.
type
=
(
dp
==
host_player
?
0x10
:
0
)
|
dp
->
type
;
sctc
.
type
=
(
dp
==
host_player
?
0x10
:
0
)
|
dptype
;
NetServer
::
SendPacketToPlayer
(
dp
,
STOC_TYPE_CHANGE
,
sctc
);
players
[
dptype
]
=
dp
;
players
[
dp
->
type
]
=
0
;
dp
->
type
=
dptype
;
}
}
void
TagDuel
::
ToObserver
(
DuelPlayer
*
dp
)
{
if
(
dp
->
type
>
3
)
...
...
@@ -448,6 +447,8 @@ 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
);
RefreshExtra
(
0
);
RefreshExtra
(
1
);
start_duel
(
pduel
,
opt
);
Process
();
}
...
...
@@ -1090,8 +1091,12 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
pbufw
=
pbuf
;
pbuf
+=
count
*
4
;
NetServer
::
SendBufferToPlayer
(
cur_player
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
BufferIO
::
WriteInt32
(
pbufw
,
0
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
(
pbufw
[
i
]
&
0x80000000
))
BufferIO
::
WriteInt32
(
pbufw
,
0
);
else
pbufw
+=
4
;
}
for
(
int
i
=
0
;
i
<
4
;
++
i
)
if
(
players
[
i
]
!=
cur_player
[
player
])
NetServer
::
SendBufferToPlayer
(
players
[
i
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
...
...
@@ -1318,6 +1323,28 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer
::
ReSendToPlayer
(
*
oit
);
break
;
}
case
MSG_TAG_SWAP
:
{
player
=
BufferIO
::
ReadInt8
(
pbuf
);
int
mcount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
ecount
=
BufferIO
::
ReadInt8
(
pbuf
);
int
hcount
=
BufferIO
::
ReadInt8
(
pbuf
);
pbufw
=
pbuf
+
4
;
pbuf
+=
hcount
*
4
+
4
;
NetServer
::
SendBufferToPlayer
(
cur_player
[
player
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
int
i
=
0
;
i
<
hcount
;
++
i
)
{
if
(
!
(
pbufw
[
i
]
&
0x80000000
))
BufferIO
::
WriteInt32
(
pbufw
,
0
);
else
pbufw
+=
4
;
}
for
(
int
i
=
0
;
i
<
4
;
++
i
)
if
(
players
[
i
]
!=
cur_player
[
player
])
NetServer
::
SendBufferToPlayer
(
players
[
i
],
STOC_GAME_MSG
,
offset
,
pbuf
-
offset
);
for
(
auto
oit
=
observers
.
begin
();
oit
!=
observers
.
end
();
++
oit
)
NetServer
::
ReSendToPlayer
(
*
oit
);
RefreshExtra
(
player
);
break
;
}
}
}
return
0
;
...
...
@@ -1510,7 +1537,7 @@ int TagDuel::MessageHandler(long fduel, int type) {
}
return
0
;
}
void
TagDuel
::
Single
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
)
{
void
TagDuel
::
Tag
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
)
{
TagDuel
*
sd
=
static_cast
<
TagDuel
*>
(
arg
);
sd
->
time_elapsed
++
;
if
(
sd
->
time_elapsed
>=
sd
->
time_limit
[
sd
->
last_response
])
{
...
...
gframe/tag_duel.h
View file @
f23cbe45
...
...
@@ -39,7 +39,7 @@ public:
void
RefreshSingle
(
int
player
,
int
location
,
int
sequence
,
int
flag
=
0x181fff
);
static
int
MessageHandler
(
long
fduel
,
int
type
);
static
void
Single
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
);
static
void
Tag
Timer
(
evutil_socket_t
fd
,
short
events
,
void
*
arg
);
protected:
DuelPlayer
*
players
[
4
];
...
...
ocgcore/field.cpp
View file @
f23cbe45
...
...
@@ -585,6 +585,15 @@ void field::tag_swap(uint8 playerid) {
}
pduel
->
write_buffer8
(
MSG_TAG_SWAP
);
pduel
->
write_buffer8
(
playerid
);
pduel
->
write_buffer8
(
player
[
playerid
].
list_main
.
size
());
pduel
->
write_buffer8
(
player
[
playerid
].
list_extra
.
size
());
pduel
->
write_buffer8
(
player
[
playerid
].
list_hand
.
size
());
if
(
core
.
deck_reversed
)
pduel
->
write_buffer32
((
*
player
[
playerid
].
list_main
.
rbegin
())
->
data
.
code
);
else
pduel
->
write_buffer32
(
0
);
for
(
auto
cit
=
player
[
playerid
].
list_hand
.
begin
();
cit
!=
player
[
playerid
].
list_hand
.
end
();
++
cit
)
pduel
->
write_buffer32
((
*
cit
)
->
data
.
code
|
((
*
cit
)
->
is_status
(
STATUS_IS_PUBLIC
)
?
0x80000000
:
0
));
}
void
field
::
add_effect
(
effect
*
peffect
,
uint8
owner_player
)
{
if
(
!
peffect
->
handler
)
{
...
...
ocgcore/operations.cpp
View file @
f23cbe45
...
...
@@ -352,7 +352,7 @@ int32 field::draw(uint16 step, effect* reason_effect, uint32 reason, uint8 reaso
pduel
->
write_buffer8
(
playerid
);
pduel
->
write_buffer8
(
drawed
);
for
(
uint32
i
=
0
;
i
<
drawed
;
++
i
)
pduel
->
write_buffer32
(
cv
[
i
]
->
data
.
code
);
pduel
->
write_buffer32
(
cv
[
i
]
->
data
.
code
|
(
cv
[
i
]
->
is_status
(
STATUS_IS_PUBLIC
)
?
0x80000000
:
0
)
);
if
(
core
.
deck_reversed
&&
(
public_count
<
drawed
))
{
pduel
->
write_buffer8
(
MSG_CONFIRM_CARDS
);
pduel
->
write_buffer8
(
1
-
playerid
);
...
...
script/c25123082.lua
View file @
f23cbe45
...
...
@@ -26,7 +26,7 @@ function c25123082.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
end
function
c25123082
.
activate
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
Duel
.
GetFirstTarget
()
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
then
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
and
not
tc
:
IsImmuneToEffect
(
e
)
then
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_UPDATE_ATTACK
)
...
...
@@ -38,7 +38,7 @@ function c25123082.activate(e,tp,eg,ep,ev,re,r,rp)
e2
:
SetCategory
(
CATEGORY_TOHAND
+
CATEGORY_SEARCH
)
e2
:
SetType
(
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_TRIGGER_O
)
e2
:
SetCode
(
EVENT_BATTLE_DESTROYING
)
e2
:
SetLabel
Object
(
tc
)
e2
:
SetLabel
(
tc
:
GetFieldID
()
)
e2
:
SetCondition
(
c25123082
.
shcon
)
e2
:
SetTarget
(
c25123082
.
shtg
)
e2
:
SetOperation
(
c25123082
.
shop
)
...
...
@@ -47,7 +47,7 @@ function c25123082.activate(e,tp,eg,ep,ev,re,r,rp)
end
end
function
c25123082
.
shcon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
return
eg
:
IsContains
(
e
:
GetLabelObject
()
)
return
eg
:
GetFirst
():
GetFieldID
()
==
e
:
GetLabel
(
)
end
function
c25123082
.
shfilter
(
c
)
return
c
:
IsSetCard
(
0x106e
)
and
c
:
IsType
(
TYPE_SPELL
)
and
c
:
IsAbleToHand
()
...
...
script/c25924653.lua
View file @
f23cbe45
...
...
@@ -51,7 +51,7 @@ function c25924653.spgop(e,tp,eg,ep,ev,re,r,rp)
if
tc
and
tc
:
IsRelateToEffect
(
e
)
and
Duel
.
SpecialSummon
(
tc
,
104
,
tp
,
tp
,
false
,
false
,
POS_FACEUP
)
>
0
and
c
:
IsFaceup
()
and
c
:
IsRelateToEffect
(
e
)
then
c
:
SetCardTarget
(
tc
)
tc
:
RegisterFlagEffect
(
2592465
3
,
RESET_EVENT
+
0x13e0000
,
0
,
1
)
tc
:
RegisterFlagEffect
(
2592465
4
,
RESET_EVENT
+
0x13e0000
,
0
,
1
)
local
e1
=
Effect
.
CreateEffect
(
c
)
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetProperty
(
EFFECT_FLAG_OWNER_RELATE
)
...
...
@@ -71,7 +71,7 @@ function c25924653.discon(e)
return
e
:
GetOwner
():
IsHasCardTarget
(
e
:
GetHandler
())
end
function
c25924653
.
disop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
if
re
:
GetHandler
():
GetFlagEffect
(
2592465
3
)
~=
0
then
if
re
:
GetHandler
():
GetFlagEffect
(
2592465
4
)
~=
0
then
Duel
.
NegateEffect
(
ev
)
end
end
...
...
script/c27068117.lua
View file @
f23cbe45
...
...
@@ -14,7 +14,8 @@ function c27068117.filter(c)
end
function
c27068117
.
target
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
chkc
)
if
chkc
then
return
chkc
:
IsLocation
(
LOCATION_MZONE
)
and
c27068117
.
filter
(
chkc
)
end
if
chk
==
0
then
return
Duel
.
IsExistingTarget
(
c27068117
.
filter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
1
,
nil
)
end
if
chk
==
0
then
return
not
e
:
GetHandler
():
IsLocation
(
LOCATION_GRAVE
)
and
Duel
.
IsExistingTarget
(
c27068117
.
filter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
1
,
nil
)
end
Duel
.
Hint
(
HINT_SELECTMSG
,
tp
,
HINTMSG_TARGET
)
Duel
.
SelectTarget
(
tp
,
c27068117
.
filter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
1
,
1
,
nil
)
end
...
...
script/c33302407.lua
View file @
f23cbe45
...
...
@@ -25,13 +25,13 @@ function c33302407.filter(c)
return
c
:
IsSetCard
(
0x25
)
and
c
:
IsType
(
TYPE_MONSTER
)
end
function
c33302407
.
distg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
GRAV
E
,
0
,
nil
)
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
MZON
E
,
0
,
nil
)
if
chk
==
0
then
return
ct
>
0
and
Duel
.
IsPlayerCanDiscardDeck
(
1
-
tp
,
0
)
end
Duel
.
SetOperationInfo
(
0
,
CATEGORY_DECKDES
,
nil
,
0
,
1
-
tp
,
ct
)
end
function
c33302407
.
disop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
if
not
e
:
GetHandler
():
IsRelateToEffect
(
e
)
then
return
end
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
GRAV
E
,
0
,
nil
)
local
ct
=
Duel
.
GetMatchingGroupCount
(
c33302407
.
filter
,
tp
,
LOCATION_
MZON
E
,
0
,
nil
)
if
ct
>
0
then
Duel
.
DiscardDeck
(
1
-
tp
,
ct
,
REASON_EFFECT
)
end
...
...
script/c33900648.lua
View file @
f23cbe45
...
...
@@ -6,14 +6,14 @@ function c33900648.initial_effect(c)
e1
:
SetCode
(
EVENT_FREE_CHAIN
)
c
:
RegisterEffect
(
e1
)
--maintain
--
local e2=Effect.CreateEffect(c)
--
e2:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_CONTINUOUS)
--
e2:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
-- e2:SetCode(EVENT_PHASE+PHASE_STANDBY
)
--
e2:SetRange(LOCATION_SZONE)
--
e2:SetCountLimit(1)
--
e2:SetOperation(c33900648.mtop)
--
c:RegisterEffect(e2)
local
e2
=
Effect
.
CreateEffect
(
c
)
e2
:
SetType
(
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_CONTINUOUS
)
e2
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
+
EFFECT_FLAG_UNCOPYABLE
)
e2
:
SetCode
(
EVENT_PHASE
+
PHASE_END
)
e2
:
SetRange
(
LOCATION_SZONE
)
e2
:
SetCountLimit
(
1
)
e2
:
SetOperation
(
c33900648
.
mtop
)
c
:
RegisterEffect
(
e2
)
--adjust
local
e3
=
Effect
.
CreateEffect
(
c
)
e3
:
SetType
(
EFFECT_TYPE_FIELD
+
EFFECT_TYPE_CONTINUOUS
)
...
...
script/c51589188.lua
View file @
f23cbe45
...
...
@@ -26,7 +26,7 @@ function c51589188.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
end
function
c51589188
.
activate
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
Duel
.
GetFirstTarget
()
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
then
if
tc
:
IsRelateToEffect
(
e
)
and
tc
:
IsFaceup
()
and
not
tc
:
IsImmuneToEffect
(
e
)
then
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_UPDATE_ATTACK
)
...
...
script/c51790181.lua
View file @
f23cbe45
...
...
@@ -13,14 +13,6 @@ function c51790181.initial_effect(c)
end
function
c51790181
.
cost
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
if
chk
==
0
then
return
Duel
.
GetFlagEffect
(
tp
,
51790181
)
==
0
end
--oath effects
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_FIELD
)
e1
:
SetProperty
(
EFFECT_FLAG_PLAYER_TARGET
+
EFFECT_FLAG_OATH
)
e1
:
SetCode
(
EFFECT_CANNOT_SPECIAL_SUMMON
)
e1
:
SetReset
(
RESET_PHASE
+
PHASE_END
)
e1
:
SetTargetRange
(
1
,
0
)
Duel
.
RegisterEffect
(
e1
,
tp
)
Duel
.
RegisterFlagEffect
(
tp
,
51790181
,
RESET_PHASE
+
PHASE_END
,
EFFECT_FLAG_OATH
,
1
)
end
function
c51790181
.
target
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
,
chkc
)
...
...
script/c52628687.lua
View file @
f23cbe45
...
...
@@ -52,22 +52,23 @@ function c52628687.operation(e,tp,eg,ep,ev,re,r,rp)
local
c
=
e
:
GetHandler
()
local
tc
=
Duel
.
GetFirstTarget
()
if
c
:
IsRelateToEffect
(
e
)
and
tc
:
IsRelateToEffect
(
e
)
and
Duel
.
SpecialSummon
(
tc
,
0
,
tp
,
tp
,
false
,
false
,
POS_FACEUP_ATTACK
)
~=
0
then
Duel
.
Equip
(
tp
,
c
,
tc
)
--Add Equip limit
local
e1
=
Effect
.
CreateEffect
(
tc
)
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_EQUIP_LIMIT
)
e1
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
)
and
Duel
.
SpecialSummonStep
(
tc
,
0
,
tp
,
tp
,
false
,
false
,
POS_FACEUP_ATTACK
)
then
--levelup
local
e1
=
Effect
.
CreateEffect
(
c
)
e1
:
SetType
(
EFFECT_TYPE_EQUIP
)
e1
:
SetCode
(
EFFECT_UPDATE_LEVEL
)
e1
:
SetValue
(
e
:
GetLabel
())
e1
:
SetReset
(
RESET_EVENT
+
0x1fe0000
)
e1
:
SetValue
(
c52628687
.
eqlimit
)
c
:
RegisterEffect
(
e1
)
--levelup
local
e2
=
Effect
.
CreateEffect
(
c
)
e2
:
SetType
(
EFFECT_TYPE_EQUIP
)
e2
:
SetCode
(
EFFECT_UPDATE_LEVEL
)
e2
:
SetValue
(
e
:
GetLabel
())
Duel
.
SpecialSummonComplete
()
Duel
.
Equip
(
tp
,
c
,
tc
)
--Add Equip limit
local
e2
=
Effect
.
CreateEffect
(
tc
)
e2
:
SetType
(
EFFECT_TYPE_SINGLE
)
e2
:
SetCode
(
EFFECT_EQUIP_LIMIT
)
e2
:
SetProperty
(
EFFECT_FLAG_CANNOT_DISABLE
)
e2
:
SetReset
(
RESET_EVENT
+
0x1fe0000
)
e2
:
SetValue
(
c52628687
.
eqlimit
)
c
:
RegisterEffect
(
e2
)
end
end
script/c63676256.lua
View file @
f23cbe45
...
...
@@ -99,18 +99,18 @@ end
function
c63676256
.
descon
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
return
e
:
GetHandler
():
IsStatus
(
STATUS_UNION
)
and
eg
:
GetCount
()
==
1
and
eg
:
GetFirst
()
==
e
:
GetHandler
():
GetEquipTarget
()
end
function
c63676256
.
dfilter
(
c
,
att
)
return
c
:
IsFaceup
()
and
c
:
Is
Attribute
(
att
)
and
c
:
IsDestructable
()
function
c63676256
.
dfilter
(
c
,
rac
)
return
c
:
IsFaceup
()
and
c
:
Is
Race
(
rac
)
and
c
:
IsDestructable
()
end
function
c63676256
.
destg
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
,
chk
)
if
chk
==
0
then
return
true
end
local
tc
=
eg
:
GetFirst
():
GetBattleTarget
()
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Attribut
e
())
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Rac
e
())
Duel
.
SetOperationInfo
(
0
,
CATEGORY_DESTROY
,
desg
,
desg
:
GetCount
(),
0
,
0
)
end
function
c63676256
.
desop
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
if
not
e
:
GetHandler
():
IsRelateToEffect
(
e
)
then
return
end
local
tc
=
eg
:
GetFirst
():
GetBattleTarget
()
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Attribut
e
())
local
desg
=
Duel
.
GetMatchingGroup
(
c63676256
.
dfilter
,
tp
,
LOCATION_MZONE
,
LOCATION_MZONE
,
nil
,
tc
:
Get
Rac
e
())
Duel
.
Destroy
(
desg
,
REASON_EFFECT
)
end
script/c99004752.lua
View file @
f23cbe45
...
...
@@ -24,7 +24,7 @@ function c99004752.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
end
function
c99004752
.
activate
(
e
,
tp
,
eg
,
ep
,
ev
,
re
,
r
,
rp
)
local
tc
=
Duel
.
GetFirstTarget
()
if
tc
:
IsFaceup
()
and
tc
:
IsRelateToEffect
(
e
)
then
if
tc
:
IsFaceup
()
and
tc
:
IsRelateToEffect
(
e
)
and
not
tc
:
IsImmuneToEffect
(
e
)
then
local
e1
=
Effect
.
CreateEffect
(
e
:
GetHandler
())
e1
:
SetType
(
EFFECT_TYPE_SINGLE
)
e1
:
SetCode
(
EFFECT_SET_ATTACK_FINAL
)
...
...
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