Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
srvpro
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
3
Merge Requests
3
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
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
MyCard
srvpro
Commits
c3c66c53
Commit
c3c66c53
authored
May 07, 2020
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add recover from replay
parent
e592353c
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
869 additions
and
99 deletions
+869
-99
Replay.coffee
Replay.coffee
+196
-0
Replay.js
Replay.js
+293
-0
data/default_config.json
data/default_config.json
+2
-1
data/i18n.json
data/i18n.json
+8
-0
ygopro-server.coffee
ygopro-server.coffee
+162
-44
ygopro-server.js
ygopro-server.js
+208
-54
No files found.
Replay.coffee
0 → 100644
View file @
c3c66c53
lzma
=
require
'lzma'
fs
=
require
'fs'
# Deck = require './Deck.js'
class
replayHeader
@
replayCompressedFlag
=
0x1
@
replayTagFlag
=
0x2
@
replayDecodedFlag
=
0x4
constructor
:
->
@
id
=
0
@
version
=
0
@
flag
=
0
@
seed
=
0
@
dataSizeRaw
=
[]
@
hash
=
0
@
props
=
[]
getDataSize
:
->
@
dataSizeRaw
[
0
]
+
@
dataSizeRaw
[
1
]
*
0x100
+
@
dataSizeRaw
[
2
]
*
0x10000
+
@
dataSizeRaw
[
3
]
*
0x1000000
getIsTag
:
->
@
flag
&
replayHeader
.
replayTagFlag
>
0
getIsCompressed
:
->
@
flag
&
replayHeader
.
replayCompressedFlag
>
0
getLzmaHeader
:
->
bytes
=
[].
concat
(
@
props
[
0
..
4
],
@
dataSizeRaw
,
[
0
,
0
,
0
,
0
])
Buffer
.
from
(
bytes
)
Object
.
defineProperty
replayHeader
.
prototype
,
'dataSize'
,
get
:
@
getDataSize
Object
.
defineProperty
replayHeader
.
prototype
,
'isTag'
,
get
:
@
getIsTag
Object
.
defineProperty
replayHeader
.
prototype
,
'isCompressed'
,
get
:
@
getIsCompressed
class
ReplayReader
constructor
:
(
buffer
)
->
@
pointer
=
0
@
buffer
=
buffer
readByte
:
->
answer
=
@
buffer
.
readUInt8
(
@
pointer
)
@
pointer
+=
1
answer
readByteArray
:
(
length
)
->
answer
=
[]
answer
.
push
@
readByte
()
for
i
in
[
1
..
length
]
answer
readInt8
:
->
answer
=
@
buffer
.
readInt8
(
@
pointer
)
@
pointer
+=
1
answer
readUInt8
:
->
answer
=
@
buffer
.
readUInt8
(
@
pointer
)
@
pointer
+=
1
answer
readInt16
:
->
answer
=
@
buffer
.
readInt16LE
@
pointer
@
pointer
+=
2
answer
readInt32
:
->
answer
=
@
buffer
.
readInt32LE
@
pointer
@
pointer
+=
4
answer
readAll
:
->
answer
=
@
buffer
.
slice
(
@
pointer
)
# @pointer = 0
answer
readString
:
(
length
)
->
if
@
pointer
+
length
>
@
buffer
.
length
return
null
full
=
@
buffer
.
slice
(
@
pointer
,
@
pointer
+
length
).
toString
(
'utf-16le'
)
answer
=
full
.
split
(
"
\u0000
"
)[
0
]
@
pointer
+=
length
answer
readRaw
:
(
length
)
->
if
@
pointer
+
length
>
@
buffer
.
length
return
null
answer
=
@
buffer
.
slice
(
@
pointer
,
@
pointer
+
length
)
@
pointer
+=
length
answer
class
Replay
constructor
:
->
@
header
=
null
@
hostName
=
""
@
clientName
=
""
@
startLp
=
0
@
startHand
=
0
@
drawCount
=
0
@
opt
=
0
@
hostDeck
=
null
@
clientDeck
=
null
@
tagHostName
=
null
@
tagClientName
=
null
@
tagHostDeck
=
null
@
tagClientDeck
=
null
@
responses
=
null
getDecks
:
->
if
@
isTag
[
@
hostDeck
,
@
clientDeck
,
@
tagHostDeck
,
@
tagClientDeck
]
else
[
@
hostDeck
,
@
clientDeck
]
getIsTag
:
->
@
header
==
null
?
false
:
@
header
.
isTag
@
fromFile
:
(
filePath
)
->
Replay
.
fromBuffer
fs
.
readFileSync
filePath
@
fromBuffer
:
(
buffer
)
->
reader
=
new
ReplayReader
buffer
header
=
Replay
.
readHeader
reader
lzmaBuffer
=
Buffer
.
concat
[
header
.
getLzmaHeader
(),
reader
.
readAll
()]
if
header
.
isCompressed
decompressed
=
lzmaBuffer
else
decompressed
=
Buffer
.
from
lzma
.
decompress
lzmaBuffer
reader
=
new
ReplayReader
decompressed
replay
=
Replay
.
readReplay
header
,
reader
replay
@
readHeader
:
(
reader
)
->
header
=
new
replayHeader
()
header
.
id
=
reader
.
readInt32
()
header
.
version
=
reader
.
readInt32
()
header
.
flag
=
reader
.
readInt32
()
header
.
seed
=
reader
.
readInt32
()
header
.
dataSizeRaw
=
reader
.
readByteArray
4
header
.
hash
=
reader
.
readInt32
()
header
.
props
=
reader
.
readByteArray
8
header
@
readReplay
:
(
header
,
reader
)
->
replay
=
new
Replay
()
replay
.
header
=
header
replay
.
hostName
=
reader
.
readString
(
40
)
replay
.
tagHostName
=
reader
.
readString
(
40
)
if
header
.
isTag
replay
.
tagClientName
=
reader
.
readString
(
40
)
if
header
.
isTag
replay
.
clientName
=
reader
.
readString
(
40
)
replay
.
startLp
=
reader
.
readInt32
()
replay
.
startHand
=
reader
.
readInt32
()
replay
.
drawCount
=
reader
.
readInt32
()
replay
.
opt
=
reader
.
readInt32
()
replay
.
hostDeck
=
Replay
.
readDeck
reader
replay
.
tagHostDeck
=
Replay
.
readDeck
reader
if
header
.
isTag
replay
.
tagClientDeck
=
Replay
.
readDeck
reader
if
header
.
isTag
replay
.
clientDeck
=
Replay
.
readDeck
reader
replay
.
responses
=
Replay
.
readResponses
reader
replay
@
readDeck
:
(
reader
)
->
deck
=
{}
deck
.
main
=
Replay
.
readDeckPack
reader
deck
.
ex
=
Replay
.
readDeckPack
reader
deck
@
readDeckPack
:
(
reader
)
->
length
=
reader
.
readInt32
()
answer
=
[]
answer
.
push
reader
.
readInt32
()
for
i
in
[
1
..
length
]
answer
@
readResponses
:
(
reader
)
->
answer
=
[]
while
true
try
length
=
reader
.
readUInt8
()
if
length
>
64
length
=
64
single
=
reader
.
readRaw
(
length
)
if
!
single
break
answer
.
push
(
single
)
catch
break
answer
Object
.
defineProperty
replayHeader
.
prototype
,
'decks'
,
get
:
@
getDecks
Object
.
defineProperty
replayHeader
.
prototype
,
'isTag'
,
get
:
@
getIsTag
module
.
exports
=
Replay
Replay.js
0 → 100644
View file @
c3c66c53
// Generated by CoffeeScript 2.5.1
(
function
()
{
var
Replay
,
ReplayReader
,
fs
,
lzma
,
replayHeader
;
lzma
=
require
(
'
lzma
'
);
fs
=
require
(
'
fs
'
);
replayHeader
=
(
function
()
{
// Deck = require './Deck.js'
class
replayHeader
{
constructor
()
{
this
.
id
=
0
;
this
.
version
=
0
;
this
.
flag
=
0
;
this
.
seed
=
0
;
this
.
dataSizeRaw
=
[];
this
.
hash
=
0
;
this
.
props
=
[];
}
getDataSize
()
{
return
this
.
dataSizeRaw
[
0
]
+
this
.
dataSizeRaw
[
1
]
*
0x100
+
this
.
dataSizeRaw
[
2
]
*
0x10000
+
this
.
dataSizeRaw
[
3
]
*
0x1000000
;
}
getIsTag
()
{
return
this
.
flag
&
replayHeader
.
replayTagFlag
>
0
;
}
getIsCompressed
()
{
return
this
.
flag
&
replayHeader
.
replayCompressedFlag
>
0
;
}
getLzmaHeader
()
{
var
bytes
;
bytes
=
[].
concat
(
this
.
props
.
slice
(
0
,
5
),
this
.
dataSizeRaw
,
[
0
,
0
,
0
,
0
]);
return
Buffer
.
from
(
bytes
);
}
};
replayHeader
.
replayCompressedFlag
=
0x1
;
replayHeader
.
replayTagFlag
=
0x2
;
replayHeader
.
replayDecodedFlag
=
0x4
;
Object
.
defineProperty
(
replayHeader
.
prototype
,
'
dataSize
'
,
{
get
:
replayHeader
.
getDataSize
});
Object
.
defineProperty
(
replayHeader
.
prototype
,
'
isTag
'
,
{
get
:
replayHeader
.
getIsTag
});
Object
.
defineProperty
(
replayHeader
.
prototype
,
'
isCompressed
'
,
{
get
:
replayHeader
.
getIsCompressed
});
return
replayHeader
;
}).
call
(
this
);
ReplayReader
=
class
ReplayReader
{
constructor
(
buffer
)
{
this
.
pointer
=
0
;
this
.
buffer
=
buffer
;
}
readByte
()
{
var
answer
;
answer
=
this
.
buffer
.
readUInt8
(
this
.
pointer
);
this
.
pointer
+=
1
;
return
answer
;
}
readByteArray
(
length
)
{
var
answer
,
i
,
j
,
ref
;
answer
=
[];
for
(
i
=
j
=
1
,
ref
=
length
;
(
1
<=
ref
?
j
<=
ref
:
j
>=
ref
);
i
=
1
<=
ref
?
++
j
:
--
j
)
{
answer
.
push
(
this
.
readByte
());
}
return
answer
;
}
readInt8
()
{
var
answer
;
answer
=
this
.
buffer
.
readInt8
(
this
.
pointer
);
this
.
pointer
+=
1
;
return
answer
;
}
readUInt8
()
{
var
answer
;
answer
=
this
.
buffer
.
readUInt8
(
this
.
pointer
);
this
.
pointer
+=
1
;
return
answer
;
}
readInt16
()
{
var
answer
;
answer
=
this
.
buffer
.
readInt16LE
(
this
.
pointer
);
this
.
pointer
+=
2
;
return
answer
;
}
readInt32
()
{
var
answer
;
answer
=
this
.
buffer
.
readInt32LE
(
this
.
pointer
);
this
.
pointer
+=
4
;
return
answer
;
}
readAll
()
{
var
answer
;
answer
=
this
.
buffer
.
slice
(
this
.
pointer
);
// @pointer = 0
return
answer
;
}
readString
(
length
)
{
var
answer
,
full
;
if
(
this
.
pointer
+
length
>
this
.
buffer
.
length
)
{
return
null
;
}
full
=
this
.
buffer
.
slice
(
this
.
pointer
,
this
.
pointer
+
length
).
toString
(
'
utf-16le
'
);
answer
=
full
.
split
(
"
\
u0000
"
)[
0
];
this
.
pointer
+=
length
;
return
answer
;
}
readRaw
(
length
)
{
var
answer
;
if
(
this
.
pointer
+
length
>
this
.
buffer
.
length
)
{
return
null
;
}
answer
=
this
.
buffer
.
slice
(
this
.
pointer
,
this
.
pointer
+
length
);
this
.
pointer
+=
length
;
return
answer
;
}
};
Replay
=
(
function
()
{
class
Replay
{
constructor
()
{
this
.
header
=
null
;
this
.
hostName
=
""
;
this
.
clientName
=
""
;
this
.
startLp
=
0
;
this
.
startHand
=
0
;
this
.
drawCount
=
0
;
this
.
opt
=
0
;
this
.
hostDeck
=
null
;
this
.
clientDeck
=
null
;
this
.
tagHostName
=
null
;
this
.
tagClientName
=
null
;
this
.
tagHostDeck
=
null
;
this
.
tagClientDeck
=
null
;
this
.
responses
=
null
;
}
getDecks
()
{
if
(
this
.
isTag
)
{
return
[
this
.
hostDeck
,
this
.
clientDeck
,
this
.
tagHostDeck
,
this
.
tagClientDeck
];
}
else
{
return
[
this
.
hostDeck
,
this
.
clientDeck
];
}
}
getIsTag
()
{
var
ref
;
return
(
ref
=
this
.
header
===
null
)
!=
null
?
ref
:
{
false
:
this
.
header
.
isTag
};
}
static
fromFile
(
filePath
)
{
return
Replay
.
fromBuffer
(
fs
.
readFileSync
(
filePath
));
}
static
fromBuffer
(
buffer
)
{
var
decompressed
,
header
,
lzmaBuffer
,
reader
,
replay
;
reader
=
new
ReplayReader
(
buffer
);
header
=
Replay
.
readHeader
(
reader
);
lzmaBuffer
=
Buffer
.
concat
([
header
.
getLzmaHeader
(),
reader
.
readAll
()]);
if
(
header
.
isCompressed
)
{
decompressed
=
lzmaBuffer
;
}
else
{
decompressed
=
Buffer
.
from
(
lzma
.
decompress
(
lzmaBuffer
));
}
reader
=
new
ReplayReader
(
decompressed
);
replay
=
Replay
.
readReplay
(
header
,
reader
);
return
replay
;
}
static
readHeader
(
reader
)
{
var
header
;
header
=
new
replayHeader
();
header
.
id
=
reader
.
readInt32
();
header
.
version
=
reader
.
readInt32
();
header
.
flag
=
reader
.
readInt32
();
header
.
seed
=
reader
.
readInt32
();
header
.
dataSizeRaw
=
reader
.
readByteArray
(
4
);
header
.
hash
=
reader
.
readInt32
();
header
.
props
=
reader
.
readByteArray
(
8
);
return
header
;
}
static
readReplay
(
header
,
reader
)
{
var
replay
;
replay
=
new
Replay
();
replay
.
header
=
header
;
replay
.
hostName
=
reader
.
readString
(
40
);
if
(
header
.
isTag
)
{
replay
.
tagHostName
=
reader
.
readString
(
40
);
}
if
(
header
.
isTag
)
{
replay
.
tagClientName
=
reader
.
readString
(
40
);
}
replay
.
clientName
=
reader
.
readString
(
40
);
replay
.
startLp
=
reader
.
readInt32
();
replay
.
startHand
=
reader
.
readInt32
();
replay
.
drawCount
=
reader
.
readInt32
();
replay
.
opt
=
reader
.
readInt32
();
replay
.
hostDeck
=
Replay
.
readDeck
(
reader
);
if
(
header
.
isTag
)
{
replay
.
tagHostDeck
=
Replay
.
readDeck
(
reader
);
}
if
(
header
.
isTag
)
{
replay
.
tagClientDeck
=
Replay
.
readDeck
(
reader
);
}
replay
.
clientDeck
=
Replay
.
readDeck
(
reader
);
replay
.
responses
=
Replay
.
readResponses
(
reader
);
return
replay
;
}
static
readDeck
(
reader
)
{
var
deck
;
deck
=
{};
deck
.
main
=
Replay
.
readDeckPack
(
reader
);
deck
.
ex
=
Replay
.
readDeckPack
(
reader
);
return
deck
;
}
static
readDeckPack
(
reader
)
{
var
answer
,
i
,
j
,
length
,
ref
;
length
=
reader
.
readInt32
();
answer
=
[];
for
(
i
=
j
=
1
,
ref
=
length
;
(
1
<=
ref
?
j
<=
ref
:
j
>=
ref
);
i
=
1
<=
ref
?
++
j
:
--
j
)
{
answer
.
push
(
reader
.
readInt32
());
}
return
answer
;
}
static
readResponses
(
reader
)
{
var
answer
,
length
,
single
;
answer
=
[];
while
(
true
)
{
try
{
length
=
reader
.
readUInt8
();
if
(
length
>
64
)
{
length
=
64
;
}
single
=
reader
.
readRaw
(
length
);
if
(
!
single
)
{
break
;
}
answer
.
push
(
single
);
}
catch
(
error
)
{
break
;
}
}
return
answer
;
}
};
Object
.
defineProperty
(
replayHeader
.
prototype
,
'
decks
'
,
{
get
:
Replay
.
getDecks
});
Object
.
defineProperty
(
replayHeader
.
prototype
,
'
isTag
'
,
{
get
:
Replay
.
getIsTag
});
return
Replay
;
}).
call
(
this
);
module
.
exports
=
Replay
;
}).
call
(
this
);
data/default_config.json
View file @
c3c66c53
...
@@ -168,7 +168,8 @@
...
@@ -168,7 +168,8 @@
"replay_safe"
:
true
,
"replay_safe"
:
true
,
"replay_path"
:
"./replays/"
,
"replay_path"
:
"./replays/"
,
"replay_archive_tool"
:
"7z"
,
"replay_archive_tool"
:
"7z"
,
"block_replay_to_player"
:
true
,
"block_replay_to_player"
:
false
,
"enable_recover"
:
true
,
"show_ip"
:
false
,
"show_ip"
:
false
,
"show_info"
:
true
,
"show_info"
:
true
,
"log_save_path"
:
"./config/"
,
"log_save_path"
:
"./config/"
,
...
...
data/i18n.json
View file @
c3c66c53
...
@@ -30,6 +30,9 @@
...
@@ -30,6 +30,9 @@
"cloud_replay_error"
:
"Replay opening failed."
,
"cloud_replay_error"
:
"Replay opening failed."
,
"cloud_replay_playing"
:
"Accessing cloud replay"
,
"cloud_replay_playing"
:
"Accessing cloud replay"
,
"cloud_replay_hint"
:
"These are the recent saved replay codes, please enter the replay code at the password column to access it."
,
"cloud_replay_hint"
:
"These are the recent saved replay codes, please enter the replay code at the password column to access it."
,
"recover_replay_hint"
:
"These are the recent duels, please enter the code RC[ID]%[TURN]#[ROOMNAME] at the password column to recover the duel."
,
"recover_hint"
:
"You entered a recover room. Please be ready with your deck on that duel."
,
"recover_start_hint"
:
"Started recovering..."
,
"blank_room_name"
:
"Blank room name is unallowed, please fill in something."
,
"blank_room_name"
:
"Blank room name is unallowed, please fill in something."
,
"loading_user_info"
:
"Loading user info..."
,
"loading_user_info"
:
"Loading user info..."
,
"invalid_password_length"
:
"Password invalid (Invalid Length)"
,
"invalid_password_length"
:
"Password invalid (Invalid Length)"
,
...
@@ -342,6 +345,11 @@
...
@@ -342,6 +345,11 @@
"cloud_replay_error"
:
"播放录像出错"
,
"cloud_replay_error"
:
"播放录像出错"
,
"cloud_replay_playing"
:
"正在观看云录像"
,
"cloud_replay_playing"
:
"正在观看云录像"
,
"cloud_replay_hint"
:
"以下是您近期的云录像,密码处输入 R#录像编号 即可观看"
,
"cloud_replay_hint"
:
"以下是您近期的云录像,密码处输入 R#录像编号 即可观看"
,
"recover_replay_hint"
:
"以下是您近期进行的决斗,密码处输入 RC决斗编号%回合数#房间号 即可创建复盘房间"
,
"recover_hint"
:
"你进入了一个复盘房间,请使用复盘局的卡组准备。"
,
"recover_start_hint"
:
"开始复盘..."
,
"recover_success"
:
"复盘成功。请耐心等待跳到当前回合。"
,
"recover_fail"
:
"复盘失败。"
,
"blank_room_name"
:
"房间名不能为空,请在主机密码处填写房间名"
,
"blank_room_name"
:
"房间名不能为空,请在主机密码处填写房间名"
,
"loading_user_info"
:
"正在读取用户信息..."
,
"loading_user_info"
:
"正在读取用户信息..."
,
"invalid_password_length"
:
"主机密码不正确 (Invalid Length)"
,
"invalid_password_length"
:
"主机密码不正确 (Invalid Length)"
,
...
...
ygopro-server.coffee
View file @
c3c66c53
...
@@ -314,6 +314,9 @@ if settings.modules.windbot.enabled
...
@@ -314,6 +314,9 @@ if settings.modules.windbot.enabled
if
settings
.
modules
.
heartbeat_detection
.
enabled
if
settings
.
modules
.
heartbeat_detection
.
enabled
long_resolve_cards
=
global
.
long_resolve_cards
=
loadJSON
(
'./data/long_resolve_cards.json'
)
long_resolve_cards
=
global
.
long_resolve_cards
=
loadJSON
(
'./data/long_resolve_cards.json'
)
if
settings
.
modules
.
tournament_mode
.
enable_recover
ReplayParser
=
global
.
ReplayParser
=
require
"./Replay.js"
# 组件
# 组件
ygopro
=
global
.
ygopro
=
require
'./ygopro.js'
ygopro
=
global
.
ygopro
=
require
'./ygopro.js'
roomlist
=
global
.
roomlist
=
require
'./roomlist.js'
if
settings
.
modules
.
http
.
websocket_roomlist
roomlist
=
global
.
roomlist
=
require
'./roomlist.js'
if
settings
.
modules
.
http
.
websocket_roomlist
...
@@ -524,15 +527,8 @@ ROOM_kick = (name, callback)->
...
@@ -524,15 +527,8 @@ ROOM_kick = (name, callback)->
done
()
done
()
return
return
found
=
true
found
=
true
if
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
room
.
termiate
()
room
.
scores
[
room
.
dueling_players
[
0
].
name_vpass
]
=
0
room
.
scores
[
room
.
dueling_players
[
1
].
name_vpass
]
=
0
room
.
kicked
=
true
room
.
send_replays
()
room
.
process
.
kill
()
room
.
delete
()
done
()
done
()
return
,
(
err
)
->
,
(
err
)
->
callback
(
null
,
found
)
callback
(
null
,
found
)
return
return
...
@@ -817,6 +813,8 @@ CLIENT_import_data = global.CLIENT_import_data = (client, old_client, room) ->
...
@@ -817,6 +813,8 @@ CLIENT_import_data = global.CLIENT_import_data = (client, old_client, room) ->
room
.
waiting_for_player2
=
client
room
.
waiting_for_player2
=
client
if
room
.
selecting_tp
==
old_client
if
room
.
selecting_tp
==
old_client
room
.
selecting_tp
=
client
room
.
selecting_tp
=
client
if
room
.
determine_firstgo
==
old_client
room
.
determine_firstgo
=
client
for
key
in
import_datas
for
key
in
import_datas
client
[
key
]
=
old_client
[
key
]
client
[
key
]
=
old_client
[
key
]
old_client
.
had_new_reconnection
=
true
old_client
.
had_new_reconnection
=
true
...
@@ -1178,6 +1176,21 @@ class Room
...
@@ -1178,6 +1176,21 @@ class Room
else
else
@
hostinfo
.
auto_death
=
40
@
hostinfo
.
auto_death
=
40
if
settings
.
modules
.
tournament_mode
.
enable_recover
and
(
param
=
rule
.
match
/(^|,|,)(RC|RECOVER)(\d*)%(\d*)(,|,|$)/
)
@
recovered
=
true
@
recovering
=
true
@
recover_from_turn
=
parseInt
(
param
[
4
])
duel_log_id
=
parseInt
(
param
[
3
])
@
recover_duel_log
=
_
.
find
(
duel_log
.
duel_log
,
(
duel
)
->
return
duel
.
id
==
duel_log_id
and
duel
.
roommode
!=
2
)
if
!
@
recover_duel_log
||
!
fs
.
existsSync
(
settings
.
modules
.
tournament_mode
.
replay_path
+
@
recover_duel_log
.
replay_filename
)
@
error
=
"${cloud_replay_no}"
return
@
recover_replay
=
ReplayParser
.
fromFile
(
settings
.
modules
.
tournament_mode
.
replay_path
+
@
recover_duel_log
.
replay_filename
)
@
recover_buffers
=
[[],
[],
[],
[]]
@
welcome
=
"${recover_hint}"
@
hostinfo
.
replay_mode
=
0
# 0x1: Save the replays in file. 0x2: Block the replays to observers.
@
hostinfo
.
replay_mode
=
0
# 0x1: Save the replays in file. 0x2: Block the replays to observers.
if
settings
.
modules
.
tournament_mode
.
enabled
if
settings
.
modules
.
tournament_mode
.
enabled
...
@@ -1189,6 +1202,9 @@ class Room
...
@@ -1189,6 +1202,9 @@ class Room
(
if
@
hostinfo
.
no_check_deck
then
'T'
else
'F'
),
(
if
@
hostinfo
.
no_shuffle_deck
then
'T'
else
'F'
),
(
if
@
hostinfo
.
no_check_deck
then
'T'
else
'F'
),
(
if
@
hostinfo
.
no_shuffle_deck
then
'T'
else
'F'
),
@
hostinfo
.
start_lp
,
@
hostinfo
.
start_hand
,
@
hostinfo
.
draw_count
,
@
hostinfo
.
time_limit
,
@
hostinfo
.
replay_mode
]
@
hostinfo
.
start_lp
,
@
hostinfo
.
start_hand
,
@
hostinfo
.
draw_count
,
@
hostinfo
.
time_limit
,
@
hostinfo
.
replay_mode
]
if
@
recovered
param
.
push
(
@
recover_replay
.
header
.
seed
)
try
try
@
process
=
spawn
'./ygopro'
,
param
,
{
cwd
:
'ygopro'
}
@
process
=
spawn
'./ygopro'
,
param
,
{
cwd
:
'ygopro'
}
@
process_pid
=
@
process
.
pid
@
process_pid
=
@
process
.
pid
...
@@ -1542,6 +1558,26 @@ class Room
...
@@ -1542,6 +1558,26 @@ class Room
@
death
=
0
@
death
=
0
ygopro
.
stoc_send_chat_to_room
(
this
,
"${death_cancel}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
ygopro
.
stoc_send_chat_to_room
(
this
,
"${death_cancel}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
return
true
return
true
termiate
:
->
if
@
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
@
scores
[
@
dueling_players
[
0
].
name_vpass
]
=
0
@
scores
[
@
dueling_players
[
1
].
name_vpass
]
=
0
@
kicked
=
true
@
send_replays
()
@
process
.
kill
()
@
delete
()
finish_recover
:
(
fail
)
->
if
fail
ygopro
.
stoc_send_chat_to_room
(
this
,
"${recover_fail}"
,
ygopro
.
constants
.
COLORS
.
RED
)
@
termiate
()
else
ygopro
.
stoc_send_chat_to_room
(
this
,
"${recover_success}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
@
recovering
=
false
for
player
in
@
get_playing_player
()
for
buffer
in
@
recover_buffers
[
player
.
pos
]
ygopro
.
stoc_send
(
player
,
"GAME_MSG"
,
buffer
)
# 网络连接
# 网络连接
net
.
createServer
(
client
)
->
net
.
createServer
(
client
)
->
...
@@ -1694,7 +1730,7 @@ net.createServer (client) ->
...
@@ -1694,7 +1730,7 @@ net.createServer (client) ->
break
break
else
else
if
ctos_buffer
.
length
>=
2
+
ctos_message_length
if
ctos_buffer
.
length
>=
2
+
ctos_message_length
#console.log "CTOS", ygopro.constants.CTOS[ctos_proto]
#console.log
client.pos,
"CTOS", ygopro.constants.CTOS[ctos_proto]
cancel
=
false
cancel
=
false
if
settings
.
modules
.
reconnect
.
enabled
and
client
.
pre_reconnecting
and
ygopro
.
constants
.
CTOS
[
ctos_proto
]
!=
'UPDATE_DECK'
if
settings
.
modules
.
reconnect
.
enabled
and
client
.
pre_reconnecting
and
ygopro
.
constants
.
CTOS
[
ctos_proto
]
!=
'UPDATE_DECK'
cancel
=
true
cancel
=
true
...
@@ -1780,7 +1816,7 @@ net.createServer (client) ->
...
@@ -1780,7 +1816,7 @@ net.createServer (client) ->
break
break
else
else
if
stoc_buffer
.
length
>=
2
+
stoc_message_length
if
stoc_buffer
.
length
>=
2
+
stoc_message_length
#console.log "STOC", ygopro.constants.STOC[stoc_proto]
#console.log
client.pos,
"STOC", ygopro.constants.STOC[stoc_proto]
cancel
=
false
cancel
=
false
b
=
stoc_buffer
.
slice
(
3
,
stoc_message_length
-
1
+
3
)
b
=
stoc_buffer
.
slice
(
3
,
stoc_message_length
-
1
+
3
)
info
=
null
info
=
null
...
@@ -1933,6 +1969,29 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server, datas)->
...
@@ -1933,6 +1969,29 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server, datas)->
CLIENT_kick
(
client
)
CLIENT_kick
(
client
)
return
),
500
return
),
500
else
if
info
.
pass
.
toUpperCase
()
==
"RC"
and
settings
.
modules
.
tournament_mode
.
enable_recover
ygopro
.
stoc_send_chat
(
client
,
"${recover_replay_hint}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
available_logs
=
duel_log
.
duel_log
.
filter
((
duel
)
->
return
duel
.
roommode
!=
2
and
_
.
any
(
duel
.
players
,
(
player
)
->
return
player
.
real_name
==
client
.
name_vpass
)
).
slice
(
0
,
8
)
_
.
each
(
available_logs
,
(
duel
)
->
player_names
=
duel
.
players
[
0
].
real_name
+
(
if
duel
.
players
[
2
]
then
"+"
+
duel
.
players
[
2
].
real_name
else
""
)
+
" VS "
+
(
if
duel
.
players
[
1
]
then
duel
.
players
[
1
].
real_name
else
"AI"
)
+
(
if
duel
.
players
[
3
]
then
"+"
+
duel
.
players
[
3
].
real_name
else
""
)
ygopro
.
stoc_send_chat
(
client
,
"<
#{
duel
.
id
}
>
#{
player_names
}
#{
duel
.
time
}
"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
)
# 强行等待异步执行完毕_(:з」∠)_
setTimeout
(()
->
ygopro
.
stoc_send
client
,
'ERROR_MSG'
,{
msg
:
1
code
:
9
}
CLIENT_kick
(
client
)
return
),
500
else
if
info
.
pass
[
0
...
2
].
toUpperCase
()
==
"R#"
and
settings
.
modules
.
cloud_replay
.
enabled
else
if
info
.
pass
[
0
...
2
].
toUpperCase
()
==
"R#"
and
settings
.
modules
.
cloud_replay
.
enabled
replay_id
=
info
.
pass
.
split
(
"#"
)[
1
]
replay_id
=
info
.
pass
.
split
(
"#"
)[
1
]
if
(
replay_id
>
0
and
replay_id
<=
9
)
if
(
replay_id
>
0
and
replay_id
<=
9
)
...
@@ -2461,6 +2520,10 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
...
@@ -2461,6 +2520,10 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
room
=
ROOM_all
[
client
.
rid
]
room
=
ROOM_all
[
client
.
rid
]
return
unless
room
and
!
client
.
reconnecting
return
unless
room
and
!
client
.
reconnecting
msg
=
buffer
.
readInt8
(
0
)
msg
=
buffer
.
readInt8
(
0
)
#console.log client.pos, "MSG", ygopro.constants.MSG[msg]
if
ygopro
.
constants
.
MSG
[
msg
]
==
'RETRY'
and
room
.
recovering
room
.
finish_recover
(
true
)
return
true
if
settings
.
modules
.
retry_handle
.
enabled
if
settings
.
modules
.
retry_handle
.
enabled
if
ygopro
.
constants
.
MSG
[
msg
]
==
'RETRY'
if
ygopro
.
constants
.
MSG
[
msg
]
==
'RETRY'
if
!
client
.
retry_count
?
if
!
client
.
retry_count
?
...
@@ -2492,8 +2555,14 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
...
@@ -2492,8 +2555,14 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
# log.info(client.name, client.last_game_msg_title)
# log.info(client.name, client.last_game_msg_title)
if
(
msg
>=
10
and
msg
<
30
)
or
msg
==
132
or
(
msg
>=
140
and
msg
<=
144
)
#SELECT和ANNOUNCE开头的消息
if
(
msg
>=
10
and
msg
<
30
)
or
msg
==
132
or
(
msg
>=
140
and
msg
<=
144
)
#SELECT和ANNOUNCE开头的消息
room
.
waiting_for_player
=
client
if
room
.
recovering
room
.
last_active_time
=
moment
()
ygopro
.
ctos_send
(
server
,
'RESPONSE'
,
room
.
recover_replay
.
responses
.
splice
(
0
,
1
)[
0
])
if
!
room
.
recover_replay
.
responses
.
length
room
.
finish_recover
()
return
true
else
room
.
waiting_for_player
=
client
room
.
last_active_time
=
moment
()
#log.info("#{ygopro.constants.MSG[msg]}等待#{room.waiting_for_player.name}")
#log.info("#{ygopro.constants.MSG[msg]}等待#{room.waiting_for_player.name}")
#log.info 'MSG', ygopro.constants.MSG[msg]
#log.info 'MSG', ygopro.constants.MSG[msg]
...
@@ -2511,6 +2580,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
...
@@ -2511,6 +2580,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
ygopro
.
stoc_send_chat_to_room
(
room
,
"${death_start_final}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
ygopro
.
stoc_send_chat_to_room
(
room
,
"${death_start_final}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
else
else
ygopro
.
stoc_send_chat_to_room
(
room
,
"${death_start_extra}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
ygopro
.
stoc_send_chat_to_room
(
room
,
"${death_start_extra}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
if
room
.
recovering
ygopro
.
stoc_send_chat_to_room
(
room
,
"${recover_start_hint}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
if
client
.
is_first
and
(
room
.
hostinfo
.
mode
!=
2
or
client
.
pos
==
0
or
client
.
pos
==
2
)
if
client
.
is_first
and
(
room
.
hostinfo
.
mode
!=
2
or
client
.
pos
==
0
or
client
.
pos
==
2
)
room
.
first_list
.
push
(
client
.
name_vpass
)
room
.
first_list
.
push
(
client
.
name_vpass
)
if
settings
.
modules
.
retry_handle
.
enabled
if
settings
.
modules
.
retry_handle
.
enabled
...
@@ -2527,6 +2598,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
...
@@ -2527,6 +2598,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
if
ygopro
.
constants
.
MSG
[
msg
]
==
'NEW_TURN'
if
ygopro
.
constants
.
MSG
[
msg
]
==
'NEW_TURN'
if
client
.
pos
==
0
if
client
.
pos
==
0
room
.
turn
++
room
.
turn
++
if
room
.
recovering
and
room
.
recover_from_turn
<=
room
.
turn
room
.
finish_recover
()
if
room
.
death
and
room
.
death
!=
-
2
if
room
.
death
and
room
.
death
!=
-
2
if
room
.
turn
>=
room
.
death
if
room
.
turn
>=
room
.
death
oppo_pos
=
if
room
.
hostinfo
.
mode
==
2
then
2
else
1
oppo_pos
=
if
room
.
hostinfo
.
mode
==
2
then
2
else
1
...
@@ -2572,6 +2645,9 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
...
@@ -2572,6 +2645,9 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
ygopro
.
stoc_send_chat_to_room
(
room
,
"${death_remain_final}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
ygopro
.
stoc_send_chat_to_room
(
room
,
"${death_remain_final}"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
)
if
ygopro
.
constants
.
MSG
[
msg
]
==
'WIN'
and
client
.
pos
==
0
if
ygopro
.
constants
.
MSG
[
msg
]
==
'WIN'
and
client
.
pos
==
0
if
room
.
recovering
room
.
finish_recover
(
true
)
return
true
pos
=
buffer
.
readUInt8
(
1
)
pos
=
buffer
.
readUInt8
(
1
)
pos
=
1
-
pos
unless
client
.
is_first
or
pos
==
2
or
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
pos
=
1
-
pos
unless
client
.
is_first
or
pos
==
2
or
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
pos
=
pos
*
2
if
pos
>=
0
and
room
.
hostinfo
.
mode
==
2
pos
=
pos
*
2
if
pos
>=
0
and
room
.
hostinfo
.
mode
==
2
...
@@ -2712,7 +2788,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
...
@@ -2712,7 +2788,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
delete
room
.
long_resolve_chain
delete
room
.
long_resolve_chain
#登场台词
#登场台词
if
settings
.
modules
.
dialogues
.
enabled
if
settings
.
modules
.
dialogues
.
enabled
and
!
room
.
recovering
if
ygopro
.
constants
.
MSG
[
msg
]
==
'SUMMONING'
or
ygopro
.
constants
.
MSG
[
msg
]
==
'SPSUMMONING'
or
ygopro
.
constants
.
MSG
[
msg
]
==
'CHAINING'
if
ygopro
.
constants
.
MSG
[
msg
]
==
'SUMMONING'
or
ygopro
.
constants
.
MSG
[
msg
]
==
'SPSUMMONING'
or
ygopro
.
constants
.
MSG
[
msg
]
==
'CHAINING'
card
=
buffer
.
readUInt32LE
(
1
)
card
=
buffer
.
readUInt32LE
(
1
)
trigger_location
=
buffer
.
readUInt8
(
6
)
trigger_location
=
buffer
.
readUInt8
(
6
)
...
@@ -2726,6 +2802,12 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
...
@@ -2726,6 +2802,12 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
client
.
ready_trap
=
!!
(
loc
&
0x8
)
and
!!
(
ppos
&
0xa
)
and
!!
(
cpos
&
0x5
)
client
.
ready_trap
=
!!
(
loc
&
0x8
)
and
!!
(
ppos
&
0xa
)
and
!!
(
cpos
&
0x5
)
else
if
ygopro
.
constants
.
MSG
[
msg
]
!=
'UPDATE_CARD'
and
ygopro
.
constants
.
MSG
[
msg
]
!=
'WAITING'
else
if
ygopro
.
constants
.
MSG
[
msg
]
!=
'UPDATE_CARD'
and
ygopro
.
constants
.
MSG
[
msg
]
!=
'WAITING'
client
.
ready_trap
=
false
client
.
ready_trap
=
false
if
room
.
recovering
and
client
.
pos
<
4
if
ygopro
.
constants
.
MSG
[
msg
]
!=
'WAITING'
room
.
recover_buffers
[
client
.
pos
].
push
(
buffer
)
return
true
return
false
return
false
#房间管理
#房间管理
...
@@ -3227,13 +3309,25 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)->
...
@@ -3227,13 +3309,25 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)->
CLIENT_kick
(
room
.
dueling_players
[
oppo_pos
-
win_pos
])
CLIENT_kick
(
room
.
dueling_players
[
oppo_pos
-
win_pos
])
CLIENT_kick
(
room
.
dueling_players
[
oppo_pos
-
win_pos
+
1
])
if
room
.
hostinfo
.
mode
==
2
CLIENT_kick
(
room
.
dueling_players
[
oppo_pos
-
win_pos
+
1
])
if
room
.
hostinfo
.
mode
==
2
return
true
return
true
struct
=
ygopro
.
structs
[
"deck"
]
struct
.
_setBuff
(
buffer
)
if
room
.
random_type
or
room
.
arena
if
room
.
random_type
or
room
.
arena
if
client
.
pos
==
0
if
client
.
pos
==
0
room
.
waiting_for_player
=
room
.
waiting_for_player2
room
.
waiting_for_player
=
room
.
waiting_for_player2
room
.
last_active_time
=
moment
()
room
.
last_active_time
=
moment
()
if
room
.
duel_stage
==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
and
room
.
recovering
recover_player_data
=
_
.
find
(
room
.
recover_duel_log
.
players
,
(
player
)
->
return
player
.
real_name
==
client
.
name_vpass
)
if
recover_player_data
and
_
.
isEqual
(
buffer
,
Buffer
.
from
(
recover_player_data
.
deckbuf
,
"base64"
))
if
recover_player_data
.
is_first
room
.
determine_firstgo
=
client
else
struct
.
set
(
"mainc"
,
1
)
struct
.
set
(
"sidec"
,
1
)
struct
.
set
(
"deckbuf"
,
[
4392470
,
4392470
])
ygopro
.
stoc_send_chat
(
client
,
"${deck_incorrect_reconnect}"
,
ygopro
.
constants
.
COLORS
.
RED
)
else
if
room
.
duel_stage
==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
and
room
.
hostinfo
.
mode
==
1
and
settings
.
modules
.
tournament_mode
.
enabled
and
settings
.
modules
.
tournament_mode
.
deck_check
and
fs
.
readdirSync
(
settings
.
modules
.
tournament_mode
.
deck_path
).
length
else
if
room
.
duel_stage
==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
and
room
.
hostinfo
.
mode
==
1
and
settings
.
modules
.
tournament_mode
.
enabled
and
settings
.
modules
.
tournament_mode
.
deck_check
and
fs
.
readdirSync
(
settings
.
modules
.
tournament_mode
.
deck_path
).
length
struct
=
ygopro
.
structs
[
"deck"
]
struct
.
_setBuff
(
buffer
)
struct
.
set
(
"mainc"
,
1
)
struct
.
set
(
"mainc"
,
1
)
struct
.
set
(
"sidec"
,
1
)
struct
.
set
(
"sidec"
,
1
)
struct
.
set
(
"deckbuf"
,
[
4392470
,
4392470
])
struct
.
set
(
"deckbuf"
,
[
4392470
,
4392470
])
...
@@ -3279,13 +3373,6 @@ ygopro.ctos_follow 'RESPONSE', false, (buffer, info, client, server, datas)->
...
@@ -3279,13 +3373,6 @@ ygopro.ctos_follow 'RESPONSE', false, (buffer, info, client, server, datas)->
ygopro
.
stoc_follow
'TIME_LIMIT'
,
true
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
ygopro
.
stoc_follow
'TIME_LIMIT'
,
true
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
room
=
ROOM_all
[
client
.
rid
]
room
=
ROOM_all
[
client
.
rid
]
return
unless
room
return
unless
room
if
settings
.
modules
.
reconnect
.
enabled
if
client
.
closed
ygopro
.
ctos_send
(
server
,
'TIME_CONFIRM'
)
return
true
else
client
.
time_confirm_required
=
true
return
unless
settings
.
modules
.
heartbeat_detection
.
enabled
and
room
.
duel_stage
==
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
and
!
room
.
windbot
check
=
false
check
=
false
if
room
.
hostinfo
.
mode
!=
2
if
room
.
hostinfo
.
mode
!=
2
check
=
(
client
.
is_first
and
info
.
player
==
0
)
or
(
!
client
.
is_first
and
info
.
player
==
1
)
check
=
(
client
.
is_first
and
info
.
player
==
0
)
or
(
!
client
.
is_first
and
info
.
player
==
1
)
...
@@ -3308,6 +3395,17 @@ ygopro.stoc_follow 'TIME_LIMIT', true, (buffer, info, client, server, datas)->
...
@@ -3308,6 +3395,17 @@ ygopro.stoc_follow 'TIME_LIMIT', true, (buffer, info, client, server, datas)->
cur_players
[
0
]
=
cur_players
[
0
]
+
2
cur_players
[
0
]
=
cur_players
[
0
]
+
2
cur_players
[
1
]
=
cur_players
[
1
]
-
2
cur_players
[
1
]
=
cur_players
[
1
]
-
2
check
=
client
.
pos
==
cur_players
[
info
.
player
]
check
=
client
.
pos
==
cur_players
[
info
.
player
]
if
room
.
recovering
if
check
ygopro
.
ctos_send
(
server
,
'TIME_CONFIRM'
)
return
true
if
settings
.
modules
.
reconnect
.
enabled
if
client
.
closed
ygopro
.
ctos_send
(
server
,
'TIME_CONFIRM'
)
return
true
else
client
.
time_confirm_required
=
true
return
unless
settings
.
modules
.
heartbeat_detection
.
enabled
and
room
.
duel_stage
==
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
and
!
room
.
windbot
if
check
if
check
CLIENT_heartbeat_register
(
client
,
false
)
CLIENT_heartbeat_register
(
client
,
false
)
return
false
return
false
...
@@ -3315,6 +3413,8 @@ ygopro.stoc_follow 'TIME_LIMIT', true, (buffer, info, client, server, datas)->
...
@@ -3315,6 +3413,8 @@ ygopro.stoc_follow 'TIME_LIMIT', true, (buffer, info, client, server, datas)->
ygopro
.
ctos_follow
'TIME_CONFIRM'
,
false
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
ygopro
.
ctos_follow
'TIME_CONFIRM'
,
false
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
room
=
ROOM_all
[
client
.
rid
]
room
=
ROOM_all
[
client
.
rid
]
return
unless
room
return
unless
room
if
room
.
recovered
room
.
recovered
=
false
if
settings
.
modules
.
reconnect
.
enabled
if
settings
.
modules
.
reconnect
.
enabled
if
client
.
waiting_for_last
if
client
.
waiting_for_last
client
.
waiting_for_last
=
false
client
.
waiting_for_last
=
false
...
@@ -3333,10 +3433,10 @@ ygopro.ctos_follow 'HAND_RESULT', false, (buffer, info, client, server, datas)->
...
@@ -3333,10 +3433,10 @@ ygopro.ctos_follow 'HAND_RESULT', false, (buffer, info, client, server, datas)->
room
=
ROOM_all
[
client
.
rid
]
room
=
ROOM_all
[
client
.
rid
]
return
unless
room
return
unless
room
client
.
selected_preduel
=
true
client
.
selected_preduel
=
true
return
unless
room
.
random_type
or
room
.
arena
if
room
.
random_type
or
room
.
arena
if
client
.
pos
==
0
if
client
.
pos
==
0
room
.
waiting_for_player
=
room
.
waiting_for_player2
room
.
waiting_for_player
=
room
.
waiting_for_player2
room
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
's'
)
room
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
's'
)
return
return
ygopro
.
ctos_follow
'TP_RESULT'
,
false
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
ygopro
.
ctos_follow
'TP_RESULT'
,
false
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
...
@@ -3374,30 +3474,47 @@ ygopro.stoc_follow 'CHAT', true, (buffer, info, client, server, datas)->
...
@@ -3374,30 +3474,47 @@ ygopro.stoc_follow 'CHAT', true, (buffer, info, client, server, datas)->
return
true
return
true
return
return
ygopro
.
stoc_follow
'SELECT_HAND'
,
fals
e
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
ygopro
.
stoc_follow
'SELECT_HAND'
,
tru
e
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
room
=
ROOM_all
[
client
.
rid
]
room
=
ROOM_all
[
client
.
rid
]
return
unless
room
return
false
unless
room
client
.
selected_preduel
=
false
if
client
.
pos
==
0
if
client
.
pos
==
0
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FINGER
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FINGER
return
unless
room
.
random_type
or
room
.
arena
if
room
.
random_type
or
room
.
arena
if
client
.
pos
==
0
if
client
.
pos
==
0
room
.
waiting_for_player
=
client
room
.
waiting_for_player
=
client
else
room
.
waiting_for_player2
=
client
room
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
's'
)
if
room
.
determine_firstgo
ygopro
.
ctos_send
(
server
,
"HAND_RESULT"
,
{
res
:
if
client
.
pos
==
0
then
2
else
1
})
return
true
else
else
room
.
waiting_for_player2
=
client
client
.
selected_preduel
=
false
room
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
's'
)
return
false
return
ygopro
.
stoc_follow
'
SELECT_TP'
,
fals
e
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
ygopro
.
stoc_follow
'
HAND_RESULT'
,
tru
e
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
room
=
ROOM_all
[
client
.
rid
]
room
=
ROOM_all
[
client
.
rid
]
return
unless
room
return
false
unless
room
client
.
selected_preduel
=
false
return
room
.
determine_firstgo
ygopro
.
stoc_follow
'SELECT_TP'
,
true
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
room
=
ROOM_all
[
client
.
rid
]
return
false
unless
room
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FIRSTGO
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FIRSTGO
room
.
selecting_tp
=
client
if
room
.
random_type
or
room
.
arena
if
room
.
random_type
or
room
.
arena
room
.
waiting_for_player
=
client
room
.
waiting_for_player
=
client
room
.
last_active_time
=
moment
()
room
.
last_active_time
=
moment
()
return
if
room
.
determine_firstgo
ygopro
.
ctos_send
(
server
,
"TP_RESULT"
,
{
res
:
if
room
.
determine_firstgo
==
client
then
1
else
0
})
return
true
else
client
.
selected_preduel
=
false
room
.
selecting_tp
=
client
return
false
ygopro
.
stoc_follow
'CHANGE_SIDE'
,
false
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
ygopro
.
stoc_follow
'CHANGE_SIDE'
,
false
,
(
buffer
,
info
,
client
,
server
,
datas
)
->
room
=
ROOM_all
[
client
.
rid
]
room
=
ROOM_all
[
client
.
rid
]
...
@@ -3475,9 +3592,10 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)->
...
@@ -3475,9 +3592,10 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)->
replay_filename
:
replay_filename
,
replay_filename
:
replay_filename
,
roommode
:
room
.
hostinfo
.
mode
,
roommode
:
room
.
hostinfo
.
mode
,
players
:
(
for
player
in
room
.
dueling_players
players
:
(
for
player
in
room
.
dueling_players
real_name
:
player
.
name
,
real_name
:
player
.
name
_vpass
,
deckbuf
:
player
.
deckbuf
.
toString
(
"base64"
),
deckbuf
:
player
.
start_
deckbuf
.
toString
(
"base64"
),
pos
:
player
.
pos
pos
:
player
.
pos
is_first
:
player
.
is_first
name
:
player
.
name
+
(
if
settings
.
modules
.
tournament_mode
.
show_ip
and
!
player
.
is_local
then
(
" (IP: "
+
player
.
ip
.
slice
(
7
)
+
")"
)
else
""
)
+
(
if
settings
.
modules
.
tournament_mode
.
show_info
and
not
(
room
.
hostinfo
.
mode
==
2
and
player
.
pos
%
2
>
0
)
then
(
" (Score:"
+
room
.
scores
[
player
.
name_vpass
]
+
" LP:"
+
(
if
player
.
lp
?
then
player
.
lp
else
room
.
hostinfo
.
start_lp
)
+
(
if
room
.
hostinfo
.
mode
!=
2
then
(
" Cards:"
+
(
if
player
.
card_count
?
then
player
.
card_count
else
room
.
hostinfo
.
start_hand
))
else
""
)
+
")"
)
else
""
),
name
:
player
.
name
+
(
if
settings
.
modules
.
tournament_mode
.
show_ip
and
!
player
.
is_local
then
(
" (IP: "
+
player
.
ip
.
slice
(
7
)
+
")"
)
else
""
)
+
(
if
settings
.
modules
.
tournament_mode
.
show_info
and
not
(
room
.
hostinfo
.
mode
==
2
and
player
.
pos
%
2
>
0
)
then
(
" (Score:"
+
room
.
scores
[
player
.
name_vpass
]
+
" LP:"
+
(
if
player
.
lp
?
then
player
.
lp
else
room
.
hostinfo
.
start_lp
)
+
(
if
room
.
hostinfo
.
mode
!=
2
then
(
" Cards:"
+
(
if
player
.
card_count
?
then
player
.
card_count
else
room
.
hostinfo
.
start_hand
))
else
""
)
+
")"
)
else
""
),
winner
:
player
.
pos
==
room
.
winner
winner
:
player
.
pos
==
room
.
winner
)
)
...
@@ -3496,7 +3614,7 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)->
...
@@ -3496,7 +3614,7 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)->
if
settings
.
modules
.
random_duel
.
enabled
if
settings
.
modules
.
random_duel
.
enabled
setInterval
()
->
setInterval
()
->
_async
.
each
(
ROOM_all
,
(
room
,
done
)
->
_async
.
each
(
ROOM_all
,
(
room
,
done
)
->
if
!
(
room
and
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
and
room
.
random_type
and
room
.
last_active_time
and
room
.
waiting_for_player
and
room
.
get_disconnected_count
()
==
0
and
(
!
settings
.
modules
.
side_timeout
or
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
))
if
!
(
room
and
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
and
room
.
random_type
and
room
.
last_active_time
and
room
.
waiting_for_player
and
room
.
get_disconnected_count
()
==
0
and
(
!
settings
.
modules
.
side_timeout
or
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
)
and
!
room
.
recovered
)
done
()
done
()
return
return
time_passed
=
Math
.
floor
((
moment
()
-
room
.
last_active_time
)
/
1000
)
time_passed
=
Math
.
floor
((
moment
()
-
room
.
last_active_time
)
/
1000
)
...
@@ -3521,7 +3639,7 @@ if settings.modules.random_duel.enabled
...
@@ -3521,7 +3639,7 @@ if settings.modules.random_duel.enabled
if
settings
.
modules
.
mycard
.
enabled
if
settings
.
modules
.
mycard
.
enabled
setInterval
()
->
setInterval
()
->
_async
.
each
(
ROOM_all
,
(
room
,
done
)
->
_async
.
each
(
ROOM_all
,
(
room
,
done
)
->
if
not
(
room
and
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
and
room
.
arena
and
room
.
last_active_time
and
room
.
waiting_for_player
and
room
.
get_disconnected_count
()
==
0
and
(
!
settings
.
modules
.
side_timeout
or
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
))
if
not
(
room
and
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
and
room
.
arena
and
room
.
last_active_time
and
room
.
waiting_for_player
and
room
.
get_disconnected_count
()
==
0
and
(
!
settings
.
modules
.
side_timeout
or
room
.
duel_stage
!=
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
)
and
!
room
.
recovered
)
done
()
done
()
return
return
time_passed
=
Math
.
floor
((
moment
()
-
room
.
last_active_time
)
/
1000
)
time_passed
=
Math
.
floor
((
moment
()
-
room
.
last_active_time
)
/
1000
)
...
...
ygopro-server.js
View file @
c3c66c53
// Generated by CoffeeScript 2.5.1
// Generated by CoffeeScript 2.5.1
(
function
()
{
(
function
()
{
// 标准库
// 标准库
var
CLIENT_get_authorize_key
,
CLIENT_get_kick_reconnect_target
,
CLIENT_heartbeat_register
,
CLIENT_heartbeat_unregister
,
CLIENT_import_data
,
CLIENT_is_able_to_kick_reconnect
,
CLIENT_is_able_to_reconnect
,
CLIENT_is_banned_by_mc
,
CLIENT_is_player
,
CLIENT_kick
,
CLIENT_kick_reconnect
,
CLIENT_pre_reconnect
,
CLIENT_reconnect
,
CLIENT_reconnect_register
,
CLIENT_reconnect_unregister
,
CLIENT_send_pre_reconnect_info
,
CLIENT_send_reconnect_info
,
CLIENT_send_replays
,
Cloud_replay_ids
,
ROOM_all
,
ROOM_bad_ip
,
ROOM_ban_player
,
ROOM_clear_disconnect
,
ROOM_connected_ip
,
ROOM_find_by_name
,
ROOM_find_by_pid
,
ROOM_find_by_port
,
ROOM_find_by_title
,
ROOM_find_or_create_ai
,
ROOM_find_or_create_by_name
,
ROOM_find_or_create_random
,
ROOM_kick
,
ROOM_player_flee
,
ROOM_player_get_score
,
ROOM_player_lose
,
ROOM_player_win
,
ROOM_players_banned
,
ROOM_players_oppentlist
,
ROOM_players_scores
,
ROOM_unwelcome
,
ROOM_validate
,
ResolveData
,
Room
,
SERVER_clear_disconnect
,
SERVER_kick
,
SOCKET_flush_data
,
_
,
_async
,
addCallback
,
auth
,
badwords
,
ban_user
,
bunyan
,
challonge
,
challonge_cache
,
challonge_module_name
,
challonge_queue_callbacks
,
chat_color
,
config
,
cppversion
,
crypto
,
date
,
deck_name_match
,
default_config
,
default_data
,
dialogues
,
disconnect_list
,
dns
,
duel_log
,
e
,
exec
,
execFile
,
fs
,
geoip
,
get_callback
,
get_memory_usage
,
http
,
http_server
,
https
,
https_server
,
import_datas
,
imported
,
is_requesting
,
j
,
l
,
len
,
len1
,
len2
,
lflists
,
list
,
loadJSON
,
load_dialogues
,
load_tips
,
log
,
long_resolve_cards
,
m
,
memory_usage
,
merge
,
moment
,
net
,
oldbadwords
,
oldconfig
,
olddialogues
,
oldduellog
,
oldtips
,
options
,
os
,
path
,
pgClient
,
pg_client
,
pg_query
,
plugin_filename
,
plugin_list
,
plugin_path
,
real_windbot_server_ip
,
redis
,
redisdb
,
ref
,
ref1
,
refresh_challonge_cache
,
release_disconnect
,
report_to_big_brother
,
request
,
requestListener
,
roomlist
,
setting_change
,
setting_save
,
settings
,
spawn
,
spawnSync
,
spawn_windbot
,
tips
,
url
,
users_cache
,
util
,
wait_room_start
,
wait_room_start_arena
,
windbot_looplimit
,
windbot_process
,
windbots
,
ygopro
,
zlib
;
var
CLIENT_get_authorize_key
,
CLIENT_get_kick_reconnect_target
,
CLIENT_heartbeat_register
,
CLIENT_heartbeat_unregister
,
CLIENT_import_data
,
CLIENT_is_able_to_kick_reconnect
,
CLIENT_is_able_to_reconnect
,
CLIENT_is_banned_by_mc
,
CLIENT_is_player
,
CLIENT_kick
,
CLIENT_kick_reconnect
,
CLIENT_pre_reconnect
,
CLIENT_reconnect
,
CLIENT_reconnect_register
,
CLIENT_reconnect_unregister
,
CLIENT_send_pre_reconnect_info
,
CLIENT_send_reconnect_info
,
CLIENT_send_replays
,
Cloud_replay_ids
,
ROOM_all
,
ROOM_bad_ip
,
ROOM_ban_player
,
ROOM_clear_disconnect
,
ROOM_connected_ip
,
ROOM_find_by_name
,
ROOM_find_by_pid
,
ROOM_find_by_port
,
ROOM_find_by_title
,
ROOM_find_or_create_ai
,
ROOM_find_or_create_by_name
,
ROOM_find_or_create_random
,
ROOM_kick
,
ROOM_player_flee
,
ROOM_player_get_score
,
ROOM_player_lose
,
ROOM_player_win
,
ROOM_players_banned
,
ROOM_players_oppentlist
,
ROOM_players_scores
,
ROOM_unwelcome
,
ROOM_validate
,
Re
playParser
,
Re
solveData
,
Room
,
SERVER_clear_disconnect
,
SERVER_kick
,
SOCKET_flush_data
,
_
,
_async
,
addCallback
,
auth
,
badwords
,
ban_user
,
bunyan
,
challonge
,
challonge_cache
,
challonge_module_name
,
challonge_queue_callbacks
,
chat_color
,
config
,
cppversion
,
crypto
,
date
,
deck_name_match
,
default_config
,
default_data
,
dialogues
,
disconnect_list
,
dns
,
duel_log
,
e
,
exec
,
execFile
,
fs
,
geoip
,
get_callback
,
get_memory_usage
,
http
,
http_server
,
https
,
https_server
,
import_datas
,
imported
,
is_requesting
,
j
,
l
,
len
,
len1
,
len2
,
lflists
,
list
,
loadJSON
,
load_dialogues
,
load_tips
,
log
,
long_resolve_cards
,
m
,
memory_usage
,
merge
,
moment
,
net
,
oldbadwords
,
oldconfig
,
olddialogues
,
oldduellog
,
oldtips
,
options
,
os
,
path
,
pgClient
,
pg_client
,
pg_query
,
plugin_filename
,
plugin_list
,
plugin_path
,
real_windbot_server_ip
,
redis
,
redisdb
,
ref
,
ref1
,
refresh_challonge_cache
,
release_disconnect
,
report_to_big_brother
,
request
,
requestListener
,
roomlist
,
setting_change
,
setting_save
,
settings
,
spawn
,
spawnSync
,
spawn_windbot
,
tips
,
url
,
users_cache
,
util
,
wait_room_start
,
wait_room_start_arena
,
windbot_looplimit
,
windbot_process
,
windbots
,
ygopro
,
zlib
;
net
=
require
(
'
net
'
);
net
=
require
(
'
net
'
);
...
@@ -403,6 +403,10 @@
...
@@ -403,6 +403,10 @@
long_resolve_cards
=
global
.
long_resolve_cards
=
loadJSON
(
'
./data/long_resolve_cards.json
'
);
long_resolve_cards
=
global
.
long_resolve_cards
=
loadJSON
(
'
./data/long_resolve_cards.json
'
);
}
}
if
(
settings
.
modules
.
tournament_mode
.
enable_recover
)
{
ReplayParser
=
global
.
ReplayParser
=
require
(
"
./Replay.js
"
);
}
// 组件
// 组件
ygopro
=
global
.
ygopro
=
require
(
'
./ygopro.js
'
);
ygopro
=
global
.
ygopro
=
require
(
'
./ygopro.js
'
);
...
@@ -686,15 +690,8 @@
...
@@ -686,15 +690,8 @@
return
;
return
;
}
}
found
=
true
;
found
=
true
;
if
(
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
)
{
room
.
termiate
();
room
.
scores
[
room
.
dueling_players
[
0
].
name_vpass
]
=
0
;
return
done
();
room
.
scores
[
room
.
dueling_players
[
1
].
name_vpass
]
=
0
;
}
room
.
kicked
=
true
;
room
.
send_replays
();
room
.
process
.
kill
();
room
.
delete
();
done
();
},
function
(
err
)
{
},
function
(
err
)
{
callback
(
null
,
found
);
callback
(
null
,
found
);
});
});
...
@@ -1094,6 +1091,9 @@
...
@@ -1094,6 +1091,9 @@
if
(
room
.
selecting_tp
===
old_client
)
{
if
(
room
.
selecting_tp
===
old_client
)
{
room
.
selecting_tp
=
client
;
room
.
selecting_tp
=
client
;
}
}
if
(
room
.
determine_firstgo
===
old_client
)
{
room
.
determine_firstgo
=
client
;
}
for
(
n
=
0
,
len3
=
import_datas
.
length
;
n
<
len3
;
n
++
)
{
for
(
n
=
0
,
len3
=
import_datas
.
length
;
n
<
len3
;
n
++
)
{
key
=
import_datas
[
n
];
key
=
import_datas
[
n
];
client
[
key
]
=
old_client
[
key
];
client
[
key
]
=
old_client
[
key
];
...
@@ -1407,7 +1407,7 @@
...
@@ -1407,7 +1407,7 @@
Room
=
class
Room
{
Room
=
class
Room
{
constructor
(
name
,
hostinfo
)
{
constructor
(
name
,
hostinfo
)
{
var
death_time
,
draw_count
,
duel_rule
,
lflist
,
param
,
rule
,
start_hand
,
start_lp
,
time_limit
;
var
death_time
,
draw_count
,
duel_
log_id
,
duel_
rule
,
lflist
,
param
,
rule
,
start_hand
,
start_lp
,
time_limit
;
this
.
hostinfo
=
hostinfo
;
this
.
hostinfo
=
hostinfo
;
this
.
name
=
name
;
this
.
name
=
name
;
//@alive = true
//@alive = true
...
@@ -1558,6 +1558,22 @@
...
@@ -1558,6 +1558,22 @@
this
.
hostinfo
.
auto_death
=
40
;
this
.
hostinfo
.
auto_death
=
40
;
}
}
}
}
if
(
settings
.
modules
.
tournament_mode
.
enable_recover
&&
(
param
=
rule
.
match
(
/
(
^|,|,
)(
RC|RECOVER
)(\d
*
)
%
(\d
*
)(
,|,|$
)
/
)))
{
this
.
recovered
=
true
;
this
.
recovering
=
true
;
this
.
recover_from_turn
=
parseInt
(
param
[
4
]);
duel_log_id
=
parseInt
(
param
[
3
]);
this
.
recover_duel_log
=
_
.
find
(
duel_log
.
duel_log
,
function
(
duel
)
{
return
duel
.
id
===
duel_log_id
&&
duel
.
roommode
!==
2
;
});
if
(
!
this
.
recover_duel_log
||
!
fs
.
existsSync
(
settings
.
modules
.
tournament_mode
.
replay_path
+
this
.
recover_duel_log
.
replay_filename
))
{
this
.
error
=
"
${cloud_replay_no}
"
;
return
;
}
this
.
recover_replay
=
ReplayParser
.
fromFile
(
settings
.
modules
.
tournament_mode
.
replay_path
+
this
.
recover_duel_log
.
replay_filename
);
this
.
recover_buffers
=
[[],
[],
[],
[]];
this
.
welcome
=
"
${recover_hint}
"
;
}
}
}
this
.
hostinfo
.
replay_mode
=
0
;
// 0x1: Save the replays in file. 0x2: Block the replays to observers.
this
.
hostinfo
.
replay_mode
=
0
;
// 0x1: Save the replays in file. 0x2: Block the replays to observers.
if
(
settings
.
modules
.
tournament_mode
.
enabled
)
{
if
(
settings
.
modules
.
tournament_mode
.
enabled
)
{
...
@@ -1567,6 +1583,9 @@
...
@@ -1567,6 +1583,9 @@
this
.
hostinfo
.
replay_mode
|=
0x2
;
this
.
hostinfo
.
replay_mode
|=
0x2
;
}
}
param
=
[
0
,
this
.
hostinfo
.
lflist
,
this
.
hostinfo
.
rule
,
this
.
hostinfo
.
mode
,
this
.
hostinfo
.
duel_rule
,
(
this
.
hostinfo
.
no_check_deck
?
'
T
'
:
'
F
'
),
(
this
.
hostinfo
.
no_shuffle_deck
?
'
T
'
:
'
F
'
),
this
.
hostinfo
.
start_lp
,
this
.
hostinfo
.
start_hand
,
this
.
hostinfo
.
draw_count
,
this
.
hostinfo
.
time_limit
,
this
.
hostinfo
.
replay_mode
];
param
=
[
0
,
this
.
hostinfo
.
lflist
,
this
.
hostinfo
.
rule
,
this
.
hostinfo
.
mode
,
this
.
hostinfo
.
duel_rule
,
(
this
.
hostinfo
.
no_check_deck
?
'
T
'
:
'
F
'
),
(
this
.
hostinfo
.
no_shuffle_deck
?
'
T
'
:
'
F
'
),
this
.
hostinfo
.
start_lp
,
this
.
hostinfo
.
start_hand
,
this
.
hostinfo
.
draw_count
,
this
.
hostinfo
.
time_limit
,
this
.
hostinfo
.
replay_mode
];
if
(
this
.
recovered
)
{
param
.
push
(
this
.
recover_replay
.
header
.
seed
);
}
try
{
try
{
this
.
process
=
spawn
(
'
./ygopro
'
,
param
,
{
this
.
process
=
spawn
(
'
./ygopro
'
,
param
,
{
cwd
:
'
ygopro
'
cwd
:
'
ygopro
'
...
@@ -2086,6 +2105,44 @@
...
@@ -2086,6 +2105,44 @@
return
true
;
return
true
;
}
}
termiate
()
{
if
(
this
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
)
{
this
.
scores
[
this
.
dueling_players
[
0
].
name_vpass
]
=
0
;
this
.
scores
[
this
.
dueling_players
[
1
].
name_vpass
]
=
0
;
}
this
.
kicked
=
true
;
this
.
send_replays
();
this
.
process
.
kill
();
return
this
.
delete
();
}
finish_recover
(
fail
)
{
var
buffer
,
len2
,
m
,
player
,
ref2
,
results
;
if
(
fail
)
{
ygopro
.
stoc_send_chat_to_room
(
this
,
"
${recover_fail}
"
,
ygopro
.
constants
.
COLORS
.
RED
);
return
this
.
termiate
();
}
else
{
ygopro
.
stoc_send_chat_to_room
(
this
,
"
${recover_success}
"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
);
this
.
recovering
=
false
;
ref2
=
this
.
get_playing_player
();
results
=
[];
for
(
m
=
0
,
len2
=
ref2
.
length
;
m
<
len2
;
m
++
)
{
player
=
ref2
[
m
];
results
.
push
((
function
()
{
var
len3
,
n
,
ref3
,
results1
;
ref3
=
this
.
recover_buffers
[
player
.
pos
];
results1
=
[];
for
(
n
=
0
,
len3
=
ref3
.
length
;
n
<
len3
;
n
++
)
{
buffer
=
ref3
[
n
];
results1
.
push
(
ygopro
.
stoc_send
(
player
,
"
GAME_MSG
"
,
buffer
));
}
return
results1
;
}).
call
(
this
));
}
return
results
;
}
}
};
};
// 网络连接
// 网络连接
...
@@ -2263,7 +2320,7 @@
...
@@ -2263,7 +2320,7 @@
}
}
}
else
{
}
else
{
if
(
ctos_buffer
.
length
>=
2
+
ctos_message_length
)
{
if
(
ctos_buffer
.
length
>=
2
+
ctos_message_length
)
{
//console.log "CTOS", ygopro.constants.CTOS[ctos_proto]
//console.log
client.pos,
"CTOS", ygopro.constants.CTOS[ctos_proto]
cancel
=
false
;
cancel
=
false
;
if
(
settings
.
modules
.
reconnect
.
enabled
&&
client
.
pre_reconnecting
&&
ygopro
.
constants
.
CTOS
[
ctos_proto
]
!==
'
UPDATE_DECK
'
)
{
if
(
settings
.
modules
.
reconnect
.
enabled
&&
client
.
pre_reconnecting
&&
ygopro
.
constants
.
CTOS
[
ctos_proto
]
!==
'
UPDATE_DECK
'
)
{
cancel
=
true
;
cancel
=
true
;
...
@@ -2383,7 +2440,7 @@
...
@@ -2383,7 +2440,7 @@
}
}
}
else
{
}
else
{
if
(
stoc_buffer
.
length
>=
2
+
stoc_message_length
)
{
if
(
stoc_buffer
.
length
>=
2
+
stoc_message_length
)
{
//console.log "STOC", ygopro.constants.STOC[stoc_proto]
//console.log
client.pos,
"STOC", ygopro.constants.STOC[stoc_proto]
cancel
=
false
;
cancel
=
false
;
b
=
stoc_buffer
.
slice
(
3
,
stoc_message_length
-
1
+
3
);
b
=
stoc_buffer
.
slice
(
3
,
stoc_message_length
-
1
+
3
);
info
=
null
;
info
=
null
;
...
@@ -2539,7 +2596,7 @@
...
@@ -2539,7 +2596,7 @@
});
});
ygopro
.
ctos_follow
(
'
JOIN_GAME
'
,
false
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
ygopro
.
ctos_follow
(
'
JOIN_GAME
'
,
false
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
var
check_buffer_indentity
,
create_room_with_action
,
len2
,
len3
,
m
,
n
,
name
,
pre_room
,
ref2
,
ref3
,
replay_id
,
room
;
var
available_logs
,
check_buffer_indentity
,
create_room_with_action
,
len2
,
len3
,
m
,
n
,
name
,
pre_room
,
ref2
,
ref3
,
replay_id
,
room
;
//log.info info
//log.info info
info
.
pass
=
info
.
pass
.
trim
();
info
.
pass
=
info
.
pass
.
trim
();
client
.
pass
=
info
.
pass
;
client
.
pass
=
info
.
pass
;
...
@@ -2573,6 +2630,26 @@
...
@@ -2573,6 +2630,26 @@
});
});
CLIENT_kick
(
client
);
CLIENT_kick
(
client
);
}),
500
);
}),
500
);
}
else
if
(
info
.
pass
.
toUpperCase
()
===
"
RC
"
&&
settings
.
modules
.
tournament_mode
.
enable_recover
)
{
ygopro
.
stoc_send_chat
(
client
,
"
${recover_replay_hint}
"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
);
available_logs
=
duel_log
.
duel_log
.
filter
(
function
(
duel
)
{
return
duel
.
roommode
!==
2
&&
_
.
any
(
duel
.
players
,
function
(
player
)
{
return
player
.
real_name
===
client
.
name_vpass
;
});
}).
slice
(
0
,
8
);
_
.
each
(
available_logs
,
function
(
duel
)
{
var
player_names
;
player_names
=
duel
.
players
[
0
].
real_name
+
(
duel
.
players
[
2
]
?
"
+
"
+
duel
.
players
[
2
].
real_name
:
""
)
+
"
VS
"
+
(
duel
.
players
[
1
]
?
duel
.
players
[
1
].
real_name
:
"
AI
"
)
+
(
duel
.
players
[
3
]
?
"
+
"
+
duel
.
players
[
3
].
real_name
:
""
);
return
ygopro
.
stoc_send_chat
(
client
,
`<
${
duel
.
id
}
>
${
player_names
}
${
duel
.
time
}
`
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
);
});
// 强行等待异步执行完毕_(:з」∠)_
setTimeout
((
function
()
{
ygopro
.
stoc_send
(
client
,
'
ERROR_MSG
'
,
{
msg
:
1
,
code
:
9
});
CLIENT_kick
(
client
);
}),
500
);
}
else
if
(
info
.
pass
.
slice
(
0
,
2
).
toUpperCase
()
===
"
R#
"
&&
settings
.
modules
.
cloud_replay
.
enabled
)
{
}
else
if
(
info
.
pass
.
slice
(
0
,
2
).
toUpperCase
()
===
"
R#
"
&&
settings
.
modules
.
cloud_replay
.
enabled
)
{
replay_id
=
info
.
pass
.
split
(
"
#
"
)[
1
];
replay_id
=
info
.
pass
.
split
(
"
#
"
)[
1
];
if
(
replay_id
>
0
&&
replay_id
<=
9
)
{
if
(
replay_id
>
0
&&
replay_id
<=
9
)
{
...
@@ -3201,6 +3278,11 @@
...
@@ -3201,6 +3278,11 @@
return
;
return
;
}
}
msg
=
buffer
.
readInt8
(
0
);
msg
=
buffer
.
readInt8
(
0
);
//console.log client.pos, "MSG", ygopro.constants.MSG[msg]
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
RETRY
'
&&
room
.
recovering
)
{
room
.
finish_recover
(
true
);
return
true
;
}
if
(
settings
.
modules
.
retry_handle
.
enabled
)
{
if
(
settings
.
modules
.
retry_handle
.
enabled
)
{
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
RETRY
'
)
{
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
RETRY
'
)
{
if
(
client
.
retry_count
==
null
)
{
if
(
client
.
retry_count
==
null
)
{
...
@@ -3238,8 +3320,16 @@
...
@@ -3238,8 +3320,16 @@
}
}
// log.info(client.name, client.last_game_msg_title)
// log.info(client.name, client.last_game_msg_title)
if
((
msg
>=
10
&&
msg
<
30
)
||
msg
===
132
||
(
msg
>=
140
&&
msg
<=
144
))
{
//SELECT和ANNOUNCE开头的消息
if
((
msg
>=
10
&&
msg
<
30
)
||
msg
===
132
||
(
msg
>=
140
&&
msg
<=
144
))
{
//SELECT和ANNOUNCE开头的消息
room
.
waiting_for_player
=
client
;
if
(
room
.
recovering
)
{
room
.
last_active_time
=
moment
();
ygopro
.
ctos_send
(
server
,
'
RESPONSE
'
,
room
.
recover_replay
.
responses
.
splice
(
0
,
1
)[
0
]);
if
(
!
room
.
recover_replay
.
responses
.
length
)
{
room
.
finish_recover
();
}
return
true
;
}
else
{
room
.
waiting_for_player
=
client
;
room
.
last_active_time
=
moment
();
}
}
}
//log.info("#{ygopro.constants.MSG[msg]}等待#{room.waiting_for_player.name}")
//log.info("#{ygopro.constants.MSG[msg]}等待#{room.waiting_for_player.name}")
...
@@ -3262,6 +3352,9 @@
...
@@ -3262,6 +3352,9 @@
ygopro
.
stoc_send_chat_to_room
(
room
,
"
${death_start_extra}
"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
);
ygopro
.
stoc_send_chat_to_room
(
room
,
"
${death_start_extra}
"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
);
}
}
}
}
if
(
room
.
recovering
)
{
ygopro
.
stoc_send_chat_to_room
(
room
,
"
${recover_start_hint}
"
,
ygopro
.
constants
.
COLORS
.
BABYBLUE
);
}
}
}
if
(
client
.
is_first
&&
(
room
.
hostinfo
.
mode
!==
2
||
client
.
pos
===
0
||
client
.
pos
===
2
))
{
if
(
client
.
is_first
&&
(
room
.
hostinfo
.
mode
!==
2
||
client
.
pos
===
0
||
client
.
pos
===
2
))
{
room
.
first_list
.
push
(
client
.
name_vpass
);
room
.
first_list
.
push
(
client
.
name_vpass
);
...
@@ -3281,6 +3374,9 @@
...
@@ -3281,6 +3374,9 @@
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
NEW_TURN
'
)
{
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
NEW_TURN
'
)
{
if
(
client
.
pos
===
0
)
{
if
(
client
.
pos
===
0
)
{
room
.
turn
++
;
room
.
turn
++
;
if
(
room
.
recovering
&&
room
.
recover_from_turn
<=
room
.
turn
)
{
room
.
finish_recover
();
}
if
(
room
.
death
&&
room
.
death
!==
-
2
)
{
if
(
room
.
death
&&
room
.
death
!==
-
2
)
{
if
(
room
.
turn
>=
room
.
death
)
{
if
(
room
.
turn
>=
room
.
death
)
{
oppo_pos
=
room
.
hostinfo
.
mode
===
2
?
2
:
1
;
oppo_pos
=
room
.
hostinfo
.
mode
===
2
?
2
:
1
;
...
@@ -3335,6 +3431,10 @@
...
@@ -3335,6 +3431,10 @@
}
}
}
}
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
WIN
'
&&
client
.
pos
===
0
)
{
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
WIN
'
&&
client
.
pos
===
0
)
{
if
(
room
.
recovering
)
{
room
.
finish_recover
(
true
);
return
true
;
}
pos
=
buffer
.
readUInt8
(
1
);
pos
=
buffer
.
readUInt8
(
1
);
if
(
!
(
client
.
is_first
||
pos
===
2
||
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
))
{
if
(
!
(
client
.
is_first
||
pos
===
2
||
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
))
{
pos
=
1
-
pos
;
pos
=
1
-
pos
;
...
@@ -3536,7 +3636,7 @@
...
@@ -3536,7 +3636,7 @@
}
}
}
}
//登场台词
//登场台词
if
(
settings
.
modules
.
dialogues
.
enabled
)
{
if
(
settings
.
modules
.
dialogues
.
enabled
&&
!
room
.
recovering
)
{
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
SUMMONING
'
||
ygopro
.
constants
.
MSG
[
msg
]
===
'
SPSUMMONING
'
||
ygopro
.
constants
.
MSG
[
msg
]
===
'
CHAINING
'
)
{
if
(
ygopro
.
constants
.
MSG
[
msg
]
===
'
SUMMONING
'
||
ygopro
.
constants
.
MSG
[
msg
]
===
'
SPSUMMONING
'
||
ygopro
.
constants
.
MSG
[
msg
]
===
'
CHAINING
'
)
{
card
=
buffer
.
readUInt32LE
(
1
);
card
=
buffer
.
readUInt32LE
(
1
);
trigger_location
=
buffer
.
readUInt8
(
6
);
trigger_location
=
buffer
.
readUInt8
(
6
);
...
@@ -3557,6 +3657,12 @@
...
@@ -3557,6 +3657,12 @@
client
.
ready_trap
=
false
;
client
.
ready_trap
=
false
;
}
}
}
}
if
(
room
.
recovering
&&
client
.
pos
<
4
)
{
if
(
ygopro
.
constants
.
MSG
[
msg
]
!==
'
WAITING
'
)
{
room
.
recover_buffers
[
client
.
pos
].
push
(
buffer
);
}
return
true
;
}
return
false
;
return
false
;
});
});
...
@@ -4230,7 +4336,7 @@
...
@@ -4230,7 +4336,7 @@
});
});
ygopro
.
ctos_follow
(
'
UPDATE_DECK
'
,
true
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
ygopro
.
ctos_follow
(
'
UPDATE_DECK
'
,
true
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
var
buff_main
,
buff_side
,
card
,
current_deck
,
deck
,
deck_array
,
deck_main
,
deck_side
,
deck_text
,
deckbuf
,
decks
,
found_deck
,
i
,
len2
,
len3
,
line
,
m
,
n
,
oppo_pos
,
room
,
struct
,
win_pos
;
var
buff_main
,
buff_side
,
card
,
current_deck
,
deck
,
deck_array
,
deck_main
,
deck_side
,
deck_text
,
deckbuf
,
decks
,
found_deck
,
i
,
len2
,
len3
,
line
,
m
,
n
,
oppo_pos
,
r
ecover_player_data
,
r
oom
,
struct
,
win_pos
;
if
(
settings
.
modules
.
reconnect
.
enabled
&&
client
.
pre_reconnecting
)
{
if
(
settings
.
modules
.
reconnect
.
enabled
&&
client
.
pre_reconnecting
)
{
if
(
!
CLIENT_is_able_to_reconnect
(
client
)
&&
!
CLIENT_is_able_to_kick_reconnect
(
client
))
{
if
(
!
CLIENT_is_able_to_reconnect
(
client
)
&&
!
CLIENT_is_able_to_kick_reconnect
(
client
))
{
ygopro
.
stoc_send_chat
(
client
,
"
${reconnect_failed}
"
,
ygopro
.
constants
.
COLORS
.
RED
);
ygopro
.
stoc_send_chat
(
client
,
"
${reconnect_failed}
"
,
ygopro
.
constants
.
COLORS
.
RED
);
...
@@ -4300,14 +4406,29 @@
...
@@ -4300,14 +4406,29 @@
}
}
return
true
;
return
true
;
}
}
struct
=
ygopro
.
structs
[
"
deck
"
];
struct
.
_setBuff
(
buffer
);
if
(
room
.
random_type
||
room
.
arena
)
{
if
(
room
.
random_type
||
room
.
arena
)
{
if
(
client
.
pos
===
0
)
{
if
(
client
.
pos
===
0
)
{
room
.
waiting_for_player
=
room
.
waiting_for_player2
;
room
.
waiting_for_player
=
room
.
waiting_for_player2
;
}
}
room
.
last_active_time
=
moment
();
room
.
last_active_time
=
moment
();
}
if
(
room
.
duel_stage
===
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
&&
room
.
recovering
)
{
recover_player_data
=
_
.
find
(
room
.
recover_duel_log
.
players
,
function
(
player
)
{
return
player
.
real_name
===
client
.
name_vpass
;
});
if
(
recover_player_data
&&
_
.
isEqual
(
buffer
,
Buffer
.
from
(
recover_player_data
.
deckbuf
,
"
base64
"
)))
{
if
(
recover_player_data
.
is_first
)
{
room
.
determine_firstgo
=
client
;
}
}
else
{
struct
.
set
(
"
mainc
"
,
1
);
struct
.
set
(
"
sidec
"
,
1
);
struct
.
set
(
"
deckbuf
"
,
[
4392470
,
4392470
]);
ygopro
.
stoc_send_chat
(
client
,
"
${deck_incorrect_reconnect}
"
,
ygopro
.
constants
.
COLORS
.
RED
);
}
}
else
if
(
room
.
duel_stage
===
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
&&
room
.
hostinfo
.
mode
===
1
&&
settings
.
modules
.
tournament_mode
.
enabled
&&
settings
.
modules
.
tournament_mode
.
deck_check
&&
fs
.
readdirSync
(
settings
.
modules
.
tournament_mode
.
deck_path
).
length
)
{
}
else
if
(
room
.
duel_stage
===
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
&&
room
.
hostinfo
.
mode
===
1
&&
settings
.
modules
.
tournament_mode
.
enabled
&&
settings
.
modules
.
tournament_mode
.
deck_check
&&
fs
.
readdirSync
(
settings
.
modules
.
tournament_mode
.
deck_path
).
length
)
{
struct
=
ygopro
.
structs
[
"
deck
"
];
struct
.
_setBuff
(
buffer
);
struct
.
set
(
"
mainc
"
,
1
);
struct
.
set
(
"
mainc
"
,
1
);
struct
.
set
(
"
sidec
"
,
1
);
struct
.
set
(
"
sidec
"
,
1
);
struct
.
set
(
"
deckbuf
"
,
[
4392470
,
4392470
]);
struct
.
set
(
"
deckbuf
"
,
[
4392470
,
4392470
]);
...
@@ -4373,17 +4494,6 @@
...
@@ -4373,17 +4494,6 @@
if
(
!
room
)
{
if
(
!
room
)
{
return
;
return
;
}
}
if
(
settings
.
modules
.
reconnect
.
enabled
)
{
if
(
client
.
closed
)
{
ygopro
.
ctos_send
(
server
,
'
TIME_CONFIRM
'
);
return
true
;
}
else
{
client
.
time_confirm_required
=
true
;
}
}
if
(
!
(
settings
.
modules
.
heartbeat_detection
.
enabled
&&
room
.
duel_stage
===
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
&&
!
room
.
windbot
))
{
return
;
}
check
=
false
;
check
=
false
;
if
(
room
.
hostinfo
.
mode
!==
2
)
{
if
(
room
.
hostinfo
.
mode
!==
2
)
{
check
=
(
client
.
is_first
&&
info
.
player
===
0
)
||
(
!
client
.
is_first
&&
info
.
player
===
1
);
check
=
(
client
.
is_first
&&
info
.
player
===
0
)
||
(
!
client
.
is_first
&&
info
.
player
===
1
);
...
@@ -4412,6 +4522,23 @@
...
@@ -4412,6 +4522,23 @@
}
}
check
=
client
.
pos
===
cur_players
[
info
.
player
];
check
=
client
.
pos
===
cur_players
[
info
.
player
];
}
}
if
(
room
.
recovering
)
{
if
(
check
)
{
ygopro
.
ctos_send
(
server
,
'
TIME_CONFIRM
'
);
}
return
true
;
}
if
(
settings
.
modules
.
reconnect
.
enabled
)
{
if
(
client
.
closed
)
{
ygopro
.
ctos_send
(
server
,
'
TIME_CONFIRM
'
);
return
true
;
}
else
{
client
.
time_confirm_required
=
true
;
}
}
if
(
!
(
settings
.
modules
.
heartbeat_detection
.
enabled
&&
room
.
duel_stage
===
ygopro
.
constants
.
DUEL_STAGE
.
DUELING
&&
!
room
.
windbot
))
{
return
;
}
if
(
check
)
{
if
(
check
)
{
CLIENT_heartbeat_register
(
client
,
false
);
CLIENT_heartbeat_register
(
client
,
false
);
}
}
...
@@ -4424,6 +4551,9 @@
...
@@ -4424,6 +4551,9 @@
if
(
!
room
)
{
if
(
!
room
)
{
return
;
return
;
}
}
if
(
room
.
recovered
)
{
room
.
recovered
=
false
;
}
if
(
settings
.
modules
.
reconnect
.
enabled
)
{
if
(
settings
.
modules
.
reconnect
.
enabled
)
{
if
(
client
.
waiting_for_last
)
{
if
(
client
.
waiting_for_last
)
{
client
.
waiting_for_last
=
false
;
client
.
waiting_for_last
=
false
;
...
@@ -4450,13 +4580,12 @@
...
@@ -4450,13 +4580,12 @@
return
;
return
;
}
}
client
.
selected_preduel
=
true
;
client
.
selected_preduel
=
true
;
if
(
!
(
room
.
random_type
||
room
.
arena
)
)
{
if
(
room
.
random_type
||
room
.
arena
)
{
return
;
if
(
client
.
pos
===
0
)
{
}
room
.
waiting_for_player
=
room
.
waiting_for_player2
;
if
(
client
.
pos
===
0
)
{
}
room
.
waiting_for_player
=
room
.
waiting_for_player2
;
room
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
'
s
'
)
;
}
}
room
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
'
s
'
);
});
});
ygopro
.
ctos_follow
(
'
TP_RESULT
'
,
false
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
ygopro
.
ctos_follow
(
'
TP_RESULT
'
,
false
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
...
@@ -4512,40 +4641,64 @@
...
@@ -4512,40 +4641,64 @@
}
}
});
});
ygopro
.
stoc_follow
(
'
SELECT_HAND
'
,
fals
e
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
ygopro
.
stoc_follow
(
'
SELECT_HAND
'
,
tru
e
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
var
room
;
var
room
;
room
=
ROOM_all
[
client
.
rid
];
room
=
ROOM_all
[
client
.
rid
];
if
(
!
room
)
{
if
(
!
room
)
{
return
;
return
false
;
}
}
client
.
selected_preduel
=
false
;
if
(
client
.
pos
===
0
)
{
if
(
client
.
pos
===
0
)
{
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FINGER
;
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FINGER
;
}
}
if
(
!
(
room
.
random_type
||
room
.
arena
))
{
if
(
room
.
random_type
||
room
.
arena
)
{
return
;
if
(
client
.
pos
===
0
)
{
room
.
waiting_for_player
=
client
;
}
else
{
room
.
waiting_for_player2
=
client
;
}
room
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
'
s
'
);
}
}
if
(
client
.
pos
===
0
)
{
if
(
room
.
determine_firstgo
)
{
room
.
waiting_for_player
=
client
;
ygopro
.
ctos_send
(
server
,
"
HAND_RESULT
"
,
{
res
:
client
.
pos
===
0
?
2
:
1
});
return
true
;
}
else
{
}
else
{
room
.
waiting_for_player2
=
client
;
client
.
selected_preduel
=
false
;
}
}
r
oom
.
last_active_time
=
moment
().
subtract
(
settings
.
modules
.
random_duel
.
hang_timeout
-
19
,
'
s
'
)
;
r
eturn
false
;
});
});
ygopro
.
stoc_follow
(
'
SELECT_TP
'
,
fals
e
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
ygopro
.
stoc_follow
(
'
HAND_RESULT
'
,
tru
e
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
var
room
;
var
room
;
room
=
ROOM_all
[
client
.
rid
];
room
=
ROOM_all
[
client
.
rid
];
if
(
!
room
)
{
if
(
!
room
)
{
return
;
return
false
;
}
return
room
.
determine_firstgo
;
});
ygopro
.
stoc_follow
(
'
SELECT_TP
'
,
true
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
var
room
;
room
=
ROOM_all
[
client
.
rid
];
if
(
!
room
)
{
return
false
;
}
}
client
.
selected_preduel
=
false
;
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FIRSTGO
;
room
.
duel_stage
=
ygopro
.
constants
.
DUEL_STAGE
.
FIRSTGO
;
room
.
selecting_tp
=
client
;
if
(
room
.
random_type
||
room
.
arena
)
{
if
(
room
.
random_type
||
room
.
arena
)
{
room
.
waiting_for_player
=
client
;
room
.
waiting_for_player
=
client
;
room
.
last_active_time
=
moment
();
room
.
last_active_time
=
moment
();
}
}
if
(
room
.
determine_firstgo
)
{
ygopro
.
ctos_send
(
server
,
"
TP_RESULT
"
,
{
res
:
room
.
determine_firstgo
===
client
?
1
:
0
});
return
true
;
}
else
{
client
.
selected_preduel
=
false
;
room
.
selecting_tp
=
client
;
}
return
false
;
});
});
ygopro
.
stoc_follow
(
'
CHANGE_SIDE
'
,
false
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
ygopro
.
stoc_follow
(
'
CHANGE_SIDE
'
,
false
,
function
(
buffer
,
info
,
client
,
server
,
datas
)
{
...
@@ -4653,9 +4806,10 @@
...
@@ -4653,9 +4806,10 @@
for
(
o
=
0
,
len4
=
ref4
.
length
;
o
<
len4
;
o
++
)
{
for
(
o
=
0
,
len4
=
ref4
.
length
;
o
<
len4
;
o
++
)
{
player
=
ref4
[
o
];
player
=
ref4
[
o
];
results
.
push
({
results
.
push
({
real_name
:
player
.
name
,
real_name
:
player
.
name
_vpass
,
deckbuf
:
player
.
deckbuf
.
toString
(
"
base64
"
),
deckbuf
:
player
.
start_
deckbuf
.
toString
(
"
base64
"
),
pos
:
player
.
pos
,
pos
:
player
.
pos
,
is_first
:
player
.
is_first
,
name
:
player
.
name
+
(
settings
.
modules
.
tournament_mode
.
show_ip
&&
!
player
.
is_local
?
"
(IP:
"
+
player
.
ip
.
slice
(
7
)
+
"
)
"
:
""
)
+
(
settings
.
modules
.
tournament_mode
.
show_info
&&
!
(
room
.
hostinfo
.
mode
===
2
&&
player
.
pos
%
2
>
0
)
?
"
(Score:
"
+
room
.
scores
[
player
.
name_vpass
]
+
"
LP:
"
+
(
player
.
lp
!=
null
?
player
.
lp
:
room
.
hostinfo
.
start_lp
)
+
(
room
.
hostinfo
.
mode
!==
2
?
"
Cards:
"
+
(
player
.
card_count
!=
null
?
player
.
card_count
:
room
.
hostinfo
.
start_hand
)
:
""
)
+
"
)
"
:
""
),
name
:
player
.
name
+
(
settings
.
modules
.
tournament_mode
.
show_ip
&&
!
player
.
is_local
?
"
(IP:
"
+
player
.
ip
.
slice
(
7
)
+
"
)
"
:
""
)
+
(
settings
.
modules
.
tournament_mode
.
show_info
&&
!
(
room
.
hostinfo
.
mode
===
2
&&
player
.
pos
%
2
>
0
)
?
"
(Score:
"
+
room
.
scores
[
player
.
name_vpass
]
+
"
LP:
"
+
(
player
.
lp
!=
null
?
player
.
lp
:
room
.
hostinfo
.
start_lp
)
+
(
room
.
hostinfo
.
mode
!==
2
?
"
Cards:
"
+
(
player
.
card_count
!=
null
?
player
.
card_count
:
room
.
hostinfo
.
start_hand
)
:
""
)
+
"
)
"
:
""
),
winner
:
player
.
pos
===
room
.
winner
winner
:
player
.
pos
===
room
.
winner
});
});
...
@@ -4684,7 +4838,7 @@
...
@@ -4684,7 +4838,7 @@
setInterval
(
function
()
{
setInterval
(
function
()
{
_async
.
each
(
ROOM_all
,
function
(
room
,
done
)
{
_async
.
each
(
ROOM_all
,
function
(
room
,
done
)
{
var
time_passed
;
var
time_passed
;
if
(
!
(
room
&&
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
&&
room
.
random_type
&&
room
.
last_active_time
&&
room
.
waiting_for_player
&&
room
.
get_disconnected_count
()
===
0
&&
(
!
settings
.
modules
.
side_timeout
||
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
)))
{
if
(
!
(
room
&&
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
&&
room
.
random_type
&&
room
.
last_active_time
&&
room
.
waiting_for_player
&&
room
.
get_disconnected_count
()
===
0
&&
(
!
settings
.
modules
.
side_timeout
||
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
)
&&
!
room
.
recovered
))
{
done
();
done
();
return
;
return
;
}
}
...
@@ -4711,7 +4865,7 @@
...
@@ -4711,7 +4865,7 @@
setInterval
(
function
()
{
setInterval
(
function
()
{
_async
.
each
(
ROOM_all
,
function
(
room
,
done
)
{
_async
.
each
(
ROOM_all
,
function
(
room
,
done
)
{
var
time_passed
;
var
time_passed
;
if
(
!
(
room
&&
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
&&
room
.
arena
&&
room
.
last_active_time
&&
room
.
waiting_for_player
&&
room
.
get_disconnected_count
()
===
0
&&
(
!
settings
.
modules
.
side_timeout
||
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
)))
{
if
(
!
(
room
&&
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
BEGIN
&&
room
.
arena
&&
room
.
last_active_time
&&
room
.
waiting_for_player
&&
room
.
get_disconnected_count
()
===
0
&&
(
!
settings
.
modules
.
side_timeout
||
room
.
duel_stage
!==
ygopro
.
constants
.
DUEL_STAGE
.
SIDING
)
&&
!
room
.
recovered
))
{
done
();
done
();
return
;
return
;
}
}
...
...
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