Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygo-agent
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
Biluo Shen
ygo-agent
Commits
2d2b1ceb
Commit
2d2b1ceb
authored
Mar 03, 2024
by
sbl1996@126.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add edopro
parent
16fca7eb
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
811 additions
and
495 deletions
+811
-495
repo/packages/e/edopro-core/xmake.lua
repo/packages/e/edopro-core/xmake.lua
+11
-2
scripts/eval.py
scripts/eval.py
+1
-1
ygoai/utils.py
ygoai/utils.py
+5
-4
ygoenv/ygoenv/edopro/edopro.h
ygoenv/ygoenv/edopro/edopro.h
+726
-426
ygoenv/ygoenv/entry.py
ygoenv/ygoenv/entry.py
+6
-0
ygoenv/ygoenv/ygopro/ygopro.h
ygoenv/ygoenv/ygopro/ygopro.h
+62
-62
No files found.
repo/packages/e/edopro-core/xmake.lua
View file @
2d2b1ceb
package
(
"edopro-core"
)
package
(
"edopro-core"
)
set_homepage
(
"https://github.com/edo9300/ygopro-core"
)
--
set_homepage("https://github.com/edo9300/ygopro-core")
set_urls
(
"https://github.com/edo9300/ygopro-core.git"
)
-- set_urls("https://github.com/edo9300/ygopro-core.git")
set_sourcedir
(
path
.
join
(
os
.
scriptdir
(),
"edopro-core"
))
set_policy
(
"package.install_always"
,
true
)
add_deps
(
"lua"
)
add_deps
(
"lua"
)
...
@@ -27,6 +30,12 @@ package("edopro-core")
...
@@ -27,6 +30,12 @@ package("edopro-core")
end
end
end
end
check_and_insert
(
"interpreter.h"
,
12
,
"extern \"
C
\
" {"
)
check_and_insert
(
"interpreter.h"
,
14
,
"}"
)
check_and_insert
(
"interpreter.h"
,
16
,
"extern \"
C
\
" {"
)
check_and_insert
(
"interpreter.h"
,
19
,
"}"
)
local
configs
=
{}
local
configs
=
{}
if
package
:
config
(
"shared"
)
then
if
package
:
config
(
"shared"
)
then
configs
.
kind
=
"shared"
configs
.
kind
=
"shared"
...
...
scripts/eval.py
View file @
2d2b1ceb
...
@@ -99,7 +99,7 @@ if __name__ == "__main__":
...
@@ -99,7 +99,7 @@ if __name__ == "__main__":
args
.
env_threads
=
min
(
args
.
env_threads
or
args
.
num_envs
,
args
.
num_envs
)
args
.
env_threads
=
min
(
args
.
env_threads
or
args
.
num_envs
,
args
.
num_envs
)
args
.
torch_threads
=
args
.
torch_threads
or
int
(
os
.
getenv
(
"OMP_NUM_THREADS"
,
"4"
))
args
.
torch_threads
=
args
.
torch_threads
or
int
(
os
.
getenv
(
"OMP_NUM_THREADS"
,
"4"
))
deck
=
init_ygopro
(
args
.
lang
,
args
.
deck
,
args
.
code_list_file
)
deck
=
init_ygopro
(
args
.
env_id
,
args
.
lang
,
args
.
deck
,
args
.
code_list_file
)
args
.
deck1
=
args
.
deck1
or
deck
args
.
deck1
=
args
.
deck1
or
deck
args
.
deck2
=
args
.
deck2
or
deck
args
.
deck2
=
args
.
deck2
or
deck
...
...
ygoai/utils.py
View file @
2d2b1ceb
import
itertools
from
pathlib
import
Path
from
pathlib
import
Path
from
ygoenv.ygopro
import
init_module
def
load_deck
(
fn
):
def
load_deck
(
fn
):
with
open
(
fn
)
as
f
:
with
open
(
fn
)
as
f
:
...
@@ -24,7 +21,7 @@ _languages = {
...
@@ -24,7 +21,7 @@ _languages = {
"chinese"
:
"zh"
,
"chinese"
:
"zh"
,
}
}
def
init_ygopro
(
lang
,
deck
,
code_list_file
,
preload_tokens
=
False
):
def
init_ygopro
(
env_id
,
lang
,
deck
,
code_list_file
,
preload_tokens
=
False
):
short
=
_languages
[
lang
]
short
=
_languages
[
lang
]
db_path
=
Path
(
get_root_directory
(),
'assets'
,
'locale'
,
short
,
'cards.cdb'
)
db_path
=
Path
(
get_root_directory
(),
'assets'
,
'locale'
,
short
,
'cards.cdb'
)
deck_fp
=
Path
(
deck
)
deck_fp
=
Path
(
deck
)
...
@@ -41,5 +38,9 @@ def init_ygopro(lang, deck, code_list_file, preload_tokens=False):
...
@@ -41,5 +38,9 @@ def init_ygopro(lang, deck, code_list_file, preload_tokens=False):
if
not
token_deck
.
exists
():
if
not
token_deck
.
exists
():
raise
FileNotFoundError
(
f
"Token deck not found: {token_deck}"
)
raise
FileNotFoundError
(
f
"Token deck not found: {token_deck}"
)
decks
[
"_tokens"
]
=
str
(
token_deck
)
decks
[
"_tokens"
]
=
str
(
token_deck
)
if
'YGOPro'
in
env_id
:
from
ygoenv.ygopro
import
init_module
elif
'EDOPro'
in
env_id
:
from
ygoenv.edopro
import
init_module
init_module
(
str
(
db_path
),
code_list_file
,
decks
)
init_module
(
str
(
db_path
),
code_list_file
,
decks
)
return
deck_name
return
deck_name
\ No newline at end of file
ygoenv/ygoenv/edopro/edopro.h
View file @
2d2b1ceb
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
// clang-format off
// clang-format off
#include <algorithm>
#include <algorithm>
#include <cstddef>
#include <cstdio>
#include <cstdio>
#include <numeric>
#include <numeric>
#include <stdexcept>
#include <stdexcept>
...
@@ -745,45 +746,70 @@ inline std::string time_now() {
...
@@ -745,45 +746,70 @@ inline std::string time_now() {
return
std
::
string
(
buffer
);
return
std
::
string
(
buffer
);
}
}
// from
ygopro/gframe/replay.h
// from
Multirole/YGOPro/Replay.cpp
// replay flag
enum
ReplayTypes
#define REPLAY_COMPRESSED 0x1
{
#define REPLAY_TAG 0x2
REPLAY_YRP1
=
0x31707279
,
#define REPLAY_DECODED 0x4
REPLAY_YRPX
=
0x58707279
#define REPLAY_SINGLE_MODE 0x8
};
#define REPLAY_UNIFORM 0x10
// max size
enum
ReplayFlags
#define MAX_REPLAY_SIZE 0x20000
{
REPLAY_COMPRESSED
=
0x1
,
REPLAY_TAG
=
0x2
,
REPLAY_DECODED
=
0x4
,
REPLAY_SINGLE_MODE
=
0x8
,
REPLAY_LUA64
=
0x10
,
REPLAY_NEWREPLAY
=
0x20
,
REPLAY_HAND_TEST
=
0x40
,
REPLAY_DIRECT_SEED
=
0x80
,
REPLAY_64BIT_DUELFLAG
=
0x100
,
REPLAY_EXTENDED_HEADER
=
0x200
,
};
struct
ReplayHeader
{
uint32_t
type
;
// See ReplayTypes.
uint32_t
version
;
// Unused atm, should be set to YGOPro::ClientVersion.
uint32_t
flags
;
// See ReplayFlags.
uint32_t
timestamp
;
// Unix timestamp.
uint32_t
size
;
// Uncompressed size of whatever is after this header.
uint32_t
hash
;
// Unused.
uint8_t
props
[
8U
];
// Used for LZMA compression (check their apis).
ReplayHeader
()
:
type
(
0
),
version
(
0
),
flags
(
0
),
timestamp
(
0
),
size
(
0
),
hash
(
0
),
props
{
0
}
{}
};
struct
ReplayHeader
{
struct
ExtendedReplayHeader
unsigned
int
id
;
{
unsigned
int
version
;
static
constexpr
uint64_t
CURRENT_VERSION
=
1U
;
unsigned
int
flag
;
unsigned
int
seed
;
unsigned
int
datasize
;
unsigned
int
start_time
;
unsigned
char
props
[
8
];
ReplayHeader
()
ReplayHeader
base
;
:
id
(
0
),
version
(
0
),
flag
(
0
),
seed
(
0
),
datasize
(
0
),
start_time
(
0
),
props
{
0
}
{}
uint64_t
version
;
// Version of this extended header.
uint64_t
seed
[
4U
];
// New 256bit seed.
};
};
//
from ygopro/gframe/replay.h
//
end from Multirole/YGOPro/Replay.cpp
using
PlayerId
=
uint8_t
;
using
PlayerId
=
uint8_t
;
using
CardCode
=
uint32_t
;
using
CardCode
=
uint32_t
;
using
CardId
=
uint16_t
;
using
CardId
=
uint16_t
;
struct
loc_info
{
uint8_t
controler
;
uint8_t
location
;
uint32_t
sequence
;
uint32_t
position
;
};
class
Card
{
class
Card
{
friend
class
EDOProEnv
;
friend
class
EDOProEnv
;
protected:
protected:
CardCode
code_
=
0
;
CardCode
code_
=
0
;
uint32_t
alias_
;
uint32_t
alias_
;
uint64_t
setcode_
;
//
uint64_t setcode_;
uint32_t
type_
;
uint32_t
type_
;
uint32_t
level_
;
uint32_t
level_
;
uint32_t
lscale_
;
uint32_t
lscale_
;
...
@@ -809,12 +835,12 @@ protected:
...
@@ -809,12 +835,12 @@ protected:
public:
public:
Card
()
=
default
;
Card
()
=
default
;
Card
(
CardCode
code
,
uint32_t
alias
,
uint
64_t
setcode
,
uint
32_t
type
,
Card
(
CardCode
code
,
uint32_t
alias
,
uint32_t
type
,
uint32_t
level
,
uint32_t
lscale
,
uint32_t
rscale
,
int32_t
attack
,
uint32_t
level
,
uint32_t
lscale
,
uint32_t
rscale
,
int32_t
attack
,
int32_t
defense
,
uint32_t
race
,
uint32_t
attribute
,
uint32_t
link_marker
,
int32_t
defense
,
uint32_t
race
,
uint32_t
attribute
,
uint32_t
link_marker
,
const
std
::
string
&
name
,
const
std
::
string
&
desc
,
const
std
::
string
&
name
,
const
std
::
string
&
desc
,
const
std
::
vector
<
std
::
string
>
&
strings
)
const
std
::
vector
<
std
::
string
>
&
strings
)
:
code_
(
code
),
alias_
(
alias
),
setcode_
(
setcode
),
type_
(
type
),
:
code_
(
code
),
alias_
(
alias
),
type_
(
type
),
level_
(
level
),
lscale_
(
lscale
),
rscale_
(
rscale
),
attack_
(
attack
),
level_
(
level
),
lscale_
(
lscale
),
rscale_
(
rscale
),
attack_
(
attack
),
defense_
(
defense
),
race_
(
race
),
attribute_
(
attribute
),
defense_
(
defense
),
race_
(
race
),
attribute_
(
attribute
),
link_marker_
(
link_marker
),
name_
(
name
),
desc_
(
desc
),
strings_
(
strings
)
{
link_marker_
(
link_marker
),
name_
(
name
),
desc_
(
desc
),
strings_
(
strings
)
{
...
@@ -829,6 +855,13 @@ public:
...
@@ -829,6 +855,13 @@ public:
position_
=
(
location
>>
24
)
&
0xff
;
position_
=
(
location
>>
24
)
&
0xff
;
}
}
void
set_location
(
const
loc_info
&
info
)
{
controler_
=
info
.
controler
;
location_
=
info
.
location
;
sequence_
=
info
.
sequence
;
position_
=
info
.
position
;
}
const
std
::
string
&
name
()
const
{
return
name_
;
}
const
std
::
string
&
name
()
const
{
return
name_
;
}
const
std
::
string
&
desc
()
const
{
return
desc_
;
}
const
std
::
string
&
desc
()
const
{
return
desc_
;
}
const
uint32_t
&
type
()
const
{
return
type_
;
}
const
uint32_t
&
type
()
const
{
return
type_
;
}
...
@@ -884,6 +917,19 @@ public:
...
@@ -884,6 +917,19 @@ public:
}
}
};
};
inline
std
::
string
ls_to_spec
(
const
loc_info
&
info
,
PlayerId
player
)
{
return
ls_to_spec
(
info
.
location
,
info
.
sequence
,
info
.
position
,
player
!=
info
.
controler
);
}
inline
uint32_t
ls_to_spec_code
(
const
loc_info
&
info
,
PlayerId
player
)
{
uint32_t
c
=
player
!=
info
.
controler
?
1
:
0
;
c
|=
(
info
.
location
<<
8
);
c
|=
(
info
.
sequence
<<
16
);
c
|=
(
info
.
position
<<
24
);
return
c
;
}
// TODO: 7% performance loss
// TODO: 7% performance loss
static
std
::
shared_timed_mutex
duel_mtx
;
static
std
::
shared_timed_mutex
duel_mtx
;
...
@@ -897,7 +943,6 @@ inline Card db_query_card(const SQLite::Database &db, CardCode code) {
...
@@ -897,7 +943,6 @@ inline Card db_query_card(const SQLite::Database &db, CardCode code) {
}
}
uint32_t
alias
=
query1
.
getColumn
(
"alias"
);
uint32_t
alias
=
query1
.
getColumn
(
"alias"
);
uint64_t
setcode
=
query1
.
getColumn
(
"setcode"
).
getInt64
();
uint32_t
type
=
query1
.
getColumn
(
"type"
);
uint32_t
type
=
query1
.
getColumn
(
"type"
);
uint32_t
level_
=
query1
.
getColumn
(
"level"
);
uint32_t
level_
=
query1
.
getColumn
(
"level"
);
uint32_t
level
=
level_
&
0xff
;
uint32_t
level
=
level_
&
0xff
;
...
@@ -924,24 +969,32 @@ inline Card db_query_card(const SQLite::Database &db, CardCode code) {
...
@@ -924,24 +969,32 @@ inline Card db_query_card(const SQLite::Database &db, CardCode code) {
std
::
string
str
=
query2
.
getColumn
(
i
);
std
::
string
str
=
query2
.
getColumn
(
i
);
strings
.
push_back
(
str
);
strings
.
push_back
(
str
);
}
}
return
Card
(
code
,
alias
,
setcode
,
type
,
level
,
lscale
,
rscale
,
attack
,
return
Card
(
code
,
alias
,
type
,
level
,
lscale
,
rscale
,
attack
,
defense
,
race
,
attribute
,
link_marker
,
name
,
desc
,
strings
);
defense
,
race
,
attribute
,
link_marker
,
name
,
desc
,
strings
);
}
}
inline
card_d
ata
db_query_card_data
(
const
SQLite
::
Database
&
db
,
CardCode
code
)
{
inline
OCG_CardD
ata
db_query_card_data
(
const
SQLite
::
Database
&
db
,
CardCode
code
)
{
SQLite
::
Statement
query
(
db
,
"SELECT * FROM datas WHERE id=?"
);
SQLite
::
Statement
query
(
db
,
"SELECT * FROM datas WHERE id=?"
);
query
.
bind
(
1
,
code
);
query
.
bind
(
1
,
code
);
query
.
executeStep
();
query
.
executeStep
();
card_d
ata
card
;
OCG_CardD
ata
card
;
card
.
code
=
code
;
card
.
code
=
code
;
card
.
alias
=
query
.
getColumn
(
"alias"
);
card
.
alias
=
query
.
getColumn
(
"alias"
);
uint64_t
setcode
=
query
.
getColumn
(
"setcode"
).
getInt64
();
uint64_t
setcodes_
=
query
.
getColumn
(
"setcode"
).
getInt64
();
card
.
set_setcode
(
setcode
);
std
::
vector
<
uint16_t
>
setcodes
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
uint16_t
setcode
=
(
setcodes_
>>
(
i
*
16
))
&
0xffff
;
if
(
setcode
)
{
setcodes
.
push_back
(
setcode
);
}
}
// memory leak here, but we only use it globally
uint16_t
*
setcodes_p
=
new
uint16_t
[
setcodes
.
size
()];
std
::
copy
(
setcodes
.
begin
(),
setcodes
.
end
(),
setcodes_p
);
card
.
setcodes
=
setcodes_p
;
card
.
type
=
query
.
getColumn
(
"type"
);
card
.
type
=
query
.
getColumn
(
"type"
);
uint32_t
level_
=
query
.
getColumn
(
"level"
);
card
.
level
=
level_
&
0xff
;
card
.
lscale
=
(
level_
>>
24
)
&
0xff
;
card
.
rscale
=
(
level_
>>
16
)
&
0xff
;
card
.
attack
=
query
.
getColumn
(
"atk"
);
card
.
attack
=
query
.
getColumn
(
"atk"
);
card
.
defense
=
query
.
getColumn
(
"def"
);
card
.
defense
=
query
.
getColumn
(
"def"
);
if
(
card
.
type
&
TYPE_LINK
)
{
if
(
card
.
type
&
TYPE_LINK
)
{
...
@@ -950,19 +1003,28 @@ inline card_data db_query_card_data(const SQLite::Database &db, CardCode code) {
...
@@ -950,19 +1003,28 @@ inline card_data db_query_card_data(const SQLite::Database &db, CardCode code) {
}
else
{
}
else
{
card
.
link_marker
=
0
;
card
.
link_marker
=
0
;
}
}
int
level_
=
query
.
getColumn
(
"level"
);
if
(
level_
<
0
)
{
card
.
level
=
-
(
level_
&
0xff
);
}
else
{
card
.
level
=
level_
&
0xff
;
}
card
.
lscale
=
(
level_
>>
24
)
&
0xff
;
card
.
rscale
=
(
level_
>>
16
)
&
0xff
;
card
.
race
=
query
.
getColumn
(
"race"
).
getInt64
();
card
.
race
=
query
.
getColumn
(
"race"
).
getInt64
();
card
.
attribute
=
query
.
getColumn
(
"attribute"
);
card
.
attribute
=
query
.
getColumn
(
"attribute"
);
return
card
;
return
card
;
}
}
struct
card_script
{
struct
card_script
{
byte
*
buf
;
const
char
*
buf
;
int
len
;
int
len
;
};
};
static
ankerl
::
unordered_dense
::
map
<
CardCode
,
Card
>
cards_
;
static
ankerl
::
unordered_dense
::
map
<
CardCode
,
Card
>
cards_
;
static
ankerl
::
unordered_dense
::
map
<
CardCode
,
CardId
>
card_ids_
;
static
ankerl
::
unordered_dense
::
map
<
CardCode
,
CardId
>
card_ids_
;
static
ankerl
::
unordered_dense
::
map
<
CardCode
,
card_d
ata
>
cards_data_
;
static
ankerl
::
unordered_dense
::
map
<
CardCode
,
OCG_CardD
ata
>
cards_data_
;
static
ankerl
::
unordered_dense
::
map
<
std
::
string
,
card_script
>
cards_script_
;
static
ankerl
::
unordered_dense
::
map
<
std
::
string
,
card_script
>
cards_script_
;
static
ankerl
::
unordered_dense
::
map
<
std
::
string
,
std
::
vector
<
CardCode
>>
static
ankerl
::
unordered_dense
::
map
<
std
::
string
,
std
::
vector
<
CardCode
>>
main_decks_
;
main_decks_
;
...
@@ -1037,18 +1099,17 @@ inline void preload_deck(const SQLite::Database &db,
...
@@ -1037,18 +1099,17 @@ inline void preload_deck(const SQLite::Database &db,
}
}
}
}
inline
uint32_t
card_reader_callback
(
CardCode
code
,
card_data
*
card
)
{
inline
void
g_DataReader
(
void
*
payload
,
uint32_t
code
,
OCG_CardData
*
data
)
{
auto
it
=
cards_data_
.
find
(
code
);
auto
it
=
cards_data_
.
find
(
code
);
if
(
it
==
cards_data_
.
end
())
{
if
(
it
==
cards_data_
.
end
())
{
throw
std
::
runtime_error
(
"[
card_reader_callback
] Card not found: "
+
std
::
to_string
(
code
));
throw
std
::
runtime_error
(
"[
g_DataReader
] Card not found: "
+
std
::
to_string
(
code
));
}
}
*
card
=
it
->
second
;
*
data
=
it
->
second
;
return
0
;
}
}
static
std
::
shared_timed_mutex
scripts_mtx
;
static
std
::
shared_timed_mutex
scripts_mtx
;
inline
byte
*
read_card_script
(
const
std
::
string
&
path
,
int
*
lenptr
)
{
inline
const
char
*
read_card_script
(
const
std
::
string
&
path
,
int
*
lenptr
)
{
std
::
ifstream
file
(
path
,
std
::
ios
::
binary
);
std
::
ifstream
file
(
path
,
std
::
ios
::
binary
);
if
(
!
file
)
{
if
(
!
file
)
{
return
nullptr
;
return
nullptr
;
...
@@ -1056,29 +1117,29 @@ inline byte *read_card_script(const std::string &path, int *lenptr) {
...
@@ -1056,29 +1117,29 @@ inline byte *read_card_script(const std::string &path, int *lenptr) {
file
.
seekg
(
0
,
std
::
ios
::
end
);
file
.
seekg
(
0
,
std
::
ios
::
end
);
int
len
=
file
.
tellg
();
int
len
=
file
.
tellg
();
file
.
seekg
(
0
,
std
::
ios
::
beg
);
file
.
seekg
(
0
,
std
::
ios
::
beg
);
byte
*
buf
=
new
byte
[
len
];
const
char
*
buf
=
new
char
[
len
];
file
.
read
((
char
*
)
buf
,
len
);
file
.
read
((
char
*
)
buf
,
len
);
*
lenptr
=
len
;
*
lenptr
=
len
;
return
buf
;
return
buf
;
}
}
inline
byte
*
script_reader_callback
(
const
char
*
name
,
int
*
lenptr
)
{
inline
int
g_ScriptReader
(
void
*
payload
,
OCG_Duel
duel
,
const
char
*
name
)
{
std
::
string
path
(
name
);
std
::
string
path
(
name
);
std
::
shared_lock
<
std
::
shared_timed_mutex
>
lock
(
scripts_mtx
);
std
::
shared_lock
<
std
::
shared_timed_mutex
>
lock
(
scripts_mtx
);
auto
it
=
cards_script_
.
find
(
path
);
auto
it
=
cards_script_
.
find
(
path
);
if
(
it
==
cards_script_
.
end
())
{
if
(
it
==
cards_script_
.
end
())
{
lock
.
unlock
();
lock
.
unlock
();
int
len
;
int
len
;
byte
*
buf
=
read_card_script
(
path
,
&
len
);
const
char
*
buf
=
read_card_script
(
path
,
&
len
);
if
(
buf
==
nullptr
)
{
if
(
buf
==
nullptr
)
{
return
nullptr
;
return
0
;
}
}
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
scripts_mtx
);
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
scripts_mtx
);
cards_script_
[
path
]
=
{
buf
,
len
};
cards_script_
[
path
]
=
{
buf
,
len
};
it
=
cards_script_
.
find
(
path
);
it
=
cards_script_
.
find
(
path
);
}
}
*
lenptr
=
it
->
second
.
len
;
int
len
=
it
->
second
.
len
;
return
it
->
second
.
buf
;
return
len
&&
OCG_LoadScript
(
duel
,
it
->
second
.
buf
,
static_cast
<
uint32_t
>
(
len
),
name
)
;
}
}
static
void
init_module
(
const
std
::
string
&
db_path
,
static
void
init_module
(
const
std
::
string
&
db_path
,
...
@@ -1113,10 +1174,35 @@ static void init_module(const std::string &db_path,
...
@@ -1113,10 +1174,35 @@ static void init_module(const std::string &db_path,
sort_extra_deck
(
deck
);
sort_extra_deck
(
deck
);
}
}
set_card_reader
(
card_reader_callback
);
set_script_reader
(
script_reader_callback
);
}
}
// from edopro/gframe/RNG/SplitMix64.hpp
class
SplitMix64
{
public:
using
ResultType
=
uint64_t
;
using
StateType
=
uint64_t
;
constexpr
SplitMix64
(
StateType
initialState
)
noexcept
:
s
(
initialState
)
{}
ResultType
operator
()()
noexcept
{
uint64_t
z
=
(
s
+=
0x9e3779b97f4a7c15
);
z
=
(
z
^
(
z
>>
30
))
*
0xbf58476d1ce4e5b9
;
z
=
(
z
^
(
z
>>
27
))
*
0x94d049bb133111eb
;
return
z
^
(
z
>>
31
);
}
// NOTE: std::shuffle requires these.
using
result_type
=
ResultType
;
static
constexpr
ResultType
min
()
noexcept
{
return
ResultType
(
0U
);
}
static
constexpr
ResultType
max
()
noexcept
{
return
ResultType
(
~
ResultType
(
0U
));
}
private:
StateType
s
;
};
inline
std
::
string
getline
()
{
inline
std
::
string
getline
()
{
char
*
line
=
nullptr
;
char
*
line
=
nullptr
;
size_t
len
=
0
;
size_t
len
=
0
;
...
@@ -1285,13 +1371,9 @@ inline std::vector<PlayMode> parse_play_modes(const std::string &play_mode) {
...
@@ -1285,13 +1371,9 @@ inline std::vector<PlayMode> parse_play_modes(const std::string &play_mode) {
return
modes
;
return
modes
;
}
}
// rules = 1, Traditional
// rules = 0, Default
// rules = 4, Link
// rules = 5, MR5
constexpr
int32_t
rules_
=
5
;
constexpr
int32_t
duel_options_
=
((
rules_
&
0xFF
)
<<
16
)
+
(
0
&
0xFFFF
);
// from edopro-deskbot/src/client.cpp#L46
constexpr
uint64_t
duel_options_
=
DUEL_MODE_MR5
;
class
EDOProEnv
:
public
Env
<
EDOProEnvSpec
>
{
class
EDOProEnv
:
public
Env
<
EDOProEnvSpec
>
{
protected:
protected:
...
@@ -1313,18 +1395,19 @@ protected:
...
@@ -1313,18 +1395,19 @@ protected:
PlayMode
play_mode_
;
PlayMode
play_mode_
;
bool
verbose_
=
false
;
bool
verbose_
=
false
;
bool
compat_mode_
=
false
;
int
max_episode_steps_
,
elapsed_step_
;
int
max_episode_steps_
,
elapsed_step_
;
PlayerId
ai_player_
;
PlayerId
ai_player_
;
intptr_t
pduel_
;
OCG_Duel
pduel_
;
Player
*
players_
[
2
];
// abstract class must be pointer
Player
*
players_
[
2
];
// abstract class must be pointer
std
::
uniform_int_distribution
<
uint64_t
>
dist_int_
;
std
::
uniform_int_distribution
<
uint64_t
>
dist_int_
;
bool
done_
{
true
};
bool
done_
{
true
};
bool
duel_started_
{
false
};
bool
duel_started_
{
false
};
uint32_t
eng_flag_
{
0
};
int
duel_status_
{
OCG_DUEL_STATUS_CONTINUE
};
PlayerId
winner_
;
PlayerId
winner_
;
uint8_t
win_reason_
;
uint8_t
win_reason_
;
...
@@ -1341,14 +1424,15 @@ protected:
...
@@ -1341,14 +1424,15 @@ protected:
PlayerId
to_play_
;
PlayerId
to_play_
;
std
::
function
<
void
(
int
)
>
callback_
;
std
::
function
<
void
(
int
)
>
callback_
;
byte
data_
[
4096
];
uint8_t
data_
[
4096
];
int
dp_
=
0
;
int
dp_
=
0
;
int
dl_
=
0
;
int
dl_
=
0
;
int
fdl_
=
0
;
byte
query_buf_
[
4096
];
uint8_t
query_buf_
[
4096
];
int
qdp_
=
0
;
int
qdp_
=
0
;
byte
resp_buf_
[
128
];
uint8_t
resp_buf_
[
128
];
using
IdleCardSpec
=
std
::
tuple
<
CardCode
,
std
::
string
,
uint32_t
>
;
using
IdleCardSpec
=
std
::
tuple
<
CardCode
,
std
::
string
,
uint32_t
>
;
...
@@ -1380,8 +1464,6 @@ protected:
...
@@ -1380,8 +1464,6 @@ protected:
// replay
// replay
bool
record_
=
false
;
bool
record_
=
false
;
// uint8_t *replay_data_;
// uint8_t *rdata_;
FILE
*
fp_
=
nullptr
;
FILE
*
fp_
=
nullptr
;
bool
is_recording
=
false
;
bool
is_recording
=
false
;
...
@@ -1399,8 +1481,6 @@ public:
...
@@ -1399,8 +1481,6 @@ public:
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
throw
std
::
runtime_error
(
"record mode must be used with verbose mode and num_envs=1"
);
throw
std
::
runtime_error
(
"record mode must be used with verbose mode and num_envs=1"
);
}
}
// replay_data_ = new uint8_t[MAX_REPLAY_SIZE];
// rdata_ = replay_data_;
}
}
int
max_options
=
spec
.
config
[
"max_options"
_
];
int
max_options
=
spec
.
config
[
"max_options"
_
];
...
@@ -1459,13 +1539,14 @@ public:
...
@@ -1459,13 +1539,14 @@ public:
auto
duel_seed
=
dist_int_
(
gen_
);
auto
duel_seed
=
dist_int_
(
gen_
);
constexpr
uint32_t
init_lp
=
8000
;
constexpr
uint32_t
startcount
=
5
;
constexpr
uint32_t
drawcount
=
1
;
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
pduel_
=
OCG_CreateDuel
(
duel_seed
);
auto
opts
=
YGO_CreateDuel
(
duel_seed
,
init_lp
,
startcount
,
drawcount
);
ulock
.
unlock
();
ulock
.
unlock
();
int
init_lp
=
8000
;
int
startcount
=
5
;
int
drawcount
=
1
;
for
(
PlayerId
i
=
0
;
i
<
2
;
i
++
)
{
for
(
PlayerId
i
=
0
;
i
<
2
;
i
++
)
{
if
(
players_
[
i
]
!=
nullptr
)
{
if
(
players_
[
i
]
!=
nullptr
)
{
delete
players_
[
i
];
delete
players_
[
i
];
...
@@ -1483,7 +1564,6 @@ public:
...
@@ -1483,7 +1564,6 @@ public:
}
else
{
}
else
{
players_
[
i
]
=
new
GreedyAI
(
nickname_
[
i
],
init_lp
,
i
,
verbose_
);
players_
[
i
]
=
new
GreedyAI
(
nickname_
[
i
],
init_lp
,
i
,
verbose_
);
}
}
OCG_SetPlayerInfo
(
pduel_
,
i
,
init_lp
,
startcount
,
drawcount
);
load_deck
(
i
);
load_deck
(
i
);
lp_
[
i
]
=
players_
[
i
]
->
init_lp_
;
lp_
[
i
]
=
players_
[
i
]
->
init_lp_
;
}
}
...
@@ -1513,12 +1593,19 @@ public:
...
@@ -1513,12 +1593,19 @@ public:
is_recording
=
true
;
is_recording
=
true
;
ReplayHeader
rh
;
ReplayHeader
rh
;
rh
.
id
=
0x31707279
;
rh
.
type
=
REPLAY_YRP1
;
rh
.
version
=
0x00001360
;
rh
.
version
=
0x000A0128
;
rh
.
flag
=
REPLAY_UNIFORM
;
rh
.
flags
=
REPLAY_LUA64
|
REPLAY_64BIT_DUELFLAG
|
REPLAY_NEWREPLAY
|
REPLAY_EXTENDED_HEADER
;
rh
.
seed
=
duel_seed
;
rh
.
timestamp
=
(
uint32_t
)
time
(
nullptr
);
rh
.
start_time
=
(
unsigned
int
)
time
(
nullptr
);
fwrite
(
&
rh
,
sizeof
(
rh
),
1
,
fp_
);
ExtendedReplayHeader
erh
;
erh
.
base
=
rh
;
erh
.
version
=
1U
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
erh
.
seed
[
i
]
=
opts
.
seed
[
i
];
}
fwrite
(
&
erh
,
sizeof
(
erh
),
1
,
fp_
);
for
(
PlayerId
i
=
0
;
i
<
2
;
i
++
)
{
for
(
PlayerId
i
=
0
;
i
<
2
;
i
++
)
{
uint16_t
name
[
20
];
uint16_t
name
[
20
];
...
@@ -1530,13 +1617,14 @@ public:
...
@@ -1530,13 +1617,14 @@ public:
}
}
fmt
::
println
(
"name: {}"
,
name_str
);
fmt
::
println
(
"name: {}"
,
name_str
);
str_to_uint16
(
name_str
.
c_str
(),
name
);
str_to_uint16
(
name_str
.
c_str
(),
name
);
ReplayWriteInt32
(
1
);
fwrite
(
name
,
40
,
1
,
fp_
);
fwrite
(
name
,
40
,
1
,
fp_
);
}
}
ReplayWriteInt32
(
init_lp
);
ReplayWriteInt32
(
init_lp
);
ReplayWriteInt32
(
startcount
);
ReplayWriteInt32
(
startcount
);
ReplayWriteInt32
(
drawcount
);
ReplayWriteInt32
(
drawcount
);
ReplayWriteInt
32
(
duel_options_
);
ReplayWriteInt
64
(
opts
.
flags
);
for
(
PlayerId
i
=
0
;
i
<
2
;
i
++
)
{
for
(
PlayerId
i
=
0
;
i
<
2
;
i
++
)
{
auto
&
main_deck
=
i
==
0
?
main_deck0_
:
main_deck1_
;
auto
&
main_deck
=
i
==
0
?
main_deck0_
:
main_deck1_
;
...
@@ -1546,14 +1634,17 @@ public:
...
@@ -1546,14 +1634,17 @@ public:
ReplayWriteInt32
(
code
);
ReplayWriteInt32
(
code
);
}
}
ReplayWriteInt32
(
extra_deck
.
size
());
ReplayWriteInt32
(
extra_deck
.
size
());
for
(
int
j
=
int
(
extra_deck
.
size
())
-
1
;
j
>=
0
;
--
j
)
{
// for (int j = int(extra_deck.size()) - 1; j >= 0; --j) {
for
(
int
j
=
0
;
j
<
extra_deck
.
size
();
++
j
)
{
ReplayWriteInt32
(
extra_deck
[
j
]);
ReplayWriteInt32
(
extra_deck
[
j
]);
}
}
}
}
ReplayWriteInt32
(
0
);
}
}
OCG_StartDuel
(
pduel_
,
duel_options
_
);
YGO_StartDuel
(
pduel
_
);
duel_started_
=
true
;
duel_started_
=
true
;
winner_
=
255
;
winner_
=
255
;
win_reason_
=
255
;
win_reason_
=
255
;
...
@@ -1639,7 +1730,7 @@ public:
...
@@ -1639,7 +1730,7 @@ public:
int
idx
=
action
[
"action"
_
];
int
idx
=
action
[
"action"
_
];
callback_
(
idx
);
callback_
(
idx
);
update_history_actions
(
to_play_
,
idx
);
//
update_history_actions(to_play_, idx);
PlayerId
player
=
to_play_
;
PlayerId
player
=
to_play_
;
...
@@ -1719,7 +1810,7 @@ private:
...
@@ -1719,7 +1810,7 @@ private:
hidden_for_opponent
=
false
;
hidden_for_opponent
=
false
;
}
}
if
(
opponent
&&
hidden_for_opponent
)
{
if
(
opponent
&&
hidden_for_opponent
)
{
auto
n_cards
=
OCG
_QueryFieldCount
(
pduel_
,
player
,
location
);
auto
n_cards
=
YGO
_QueryFieldCount
(
pduel_
,
player
,
location
);
for
(
auto
i
=
0
;
i
<
n_cards
;
i
++
)
{
for
(
auto
i
=
0
;
i
<
n_cards
;
i
++
)
{
f_cards
(
offset
,
2
)
=
location2id
.
at
(
location
);
f_cards
(
offset
,
2
)
=
location2id
.
at
(
location
);
f_cards
(
offset
,
4
)
=
1
;
f_cards
(
offset
,
4
)
=
1
;
...
@@ -2066,75 +2157,120 @@ private:
...
@@ -2066,75 +2157,120 @@ private:
fwrite
(
&
value
,
sizeof
(
value
),
1
,
fp_
);
fwrite
(
&
value
,
sizeof
(
value
),
1
,
fp_
);
}
}
// edopro-core API
void
ReplayWriteInt64
(
uint64_t
value
)
{
intptr_t
OCG_CreateDuel
(
uint32_t
seed
)
{
fwrite
(
&
value
,
sizeof
(
value
),
1
,
fp_
);
std
::
mt19937
rnd
(
seed
);
return
create_duel
(
rnd
());
}
}
void
OCG_SetPlayerInfo
(
intptr_t
pduel
,
int32
playerid
,
int32
lp
,
int32
startcount
,
int32
drawcount
)
{
// edopro-core API
set_player_info
(
pduel
,
playerid
,
lp
,
startcount
,
drawcount
);
OCG_DuelOptions
YGO_CreateDuel
(
uint32_t
seed
,
uint32_t
init_lp
,
uint32_t
startcount
,
uint32_t
drawcount
)
{
SplitMix64
generator
(
seed
);
OCG_DuelOptions
opts
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
opts
.
seed
[
i
]
=
generator
();
}
// from edopro-deskbot/src/client.cpp#L46
opts
.
flags
=
duel_options_
;
opts
.
team1
=
{
init_lp
,
startcount
,
drawcount
};
opts
.
team2
=
{
init_lp
,
startcount
,
drawcount
};
opts
.
cardReader
=
&
g_DataReader
;
opts
.
payload1
=
nullptr
;
opts
.
scriptReader
=
&
g_ScriptReader
;
opts
.
payload2
=
nullptr
;
opts
.
logHandler
=
[](
void
*
/*payload*/
,
const
char
*
/*string*/
,
int
/*type*/
)
{};
opts
.
payload3
=
nullptr
;
opts
.
cardReaderDone
=
[](
void
*
/*payload*/
,
OCG_CardData
*
/*data*/
)
{};
opts
.
payload4
=
nullptr
;
opts
.
enableUnsafeLibraries
=
1
;
int
create_status
=
OCG_CreateDuel
(
&
pduel_
,
opts
);
if
(
create_status
!=
OCG_DUEL_CREATION_SUCCESS
)
{
throw
std
::
runtime_error
(
"Failed to create duel"
);
}
return
opts
;
}
}
void
OCG_NewCard
(
intptr_t
pduel
,
uint32_t
code
,
uint8
owner
,
uint8
playerid
,
uint8
location
,
uint8
sequence
,
uint8
position
)
{
void
YGO_NewCard
(
OCG_Duel
pduel
,
uint32_t
code
,
uint8_t
owner
,
uint8_t
playerid
,
uint8_t
location
,
uint8_t
sequence
,
uint8_t
position
)
{
new_card
(
pduel
,
code
,
owner
,
playerid
,
location
,
sequence
,
position
);
OCG_NewCardInfo
info
;
info
.
team
=
playerid
;
info
.
duelist
=
0
;
info
.
code
=
code
;
info
.
con
=
owner
;
info
.
loc
=
location
;
info
.
seq
=
sequence
;
info
.
pos
=
position
;
OCG_DuelNewCard
(
pduel
,
info
);
}
}
void
OCG_StartDuel
(
intptr_t
pduel
,
int32
options
)
{
void
YGO_StartDuel
(
OCG_Duel
pduel
)
{
start_duel
(
pduel
,
options
);
OCG_StartDuel
(
pduel
);
}
}
void
OCG_EndDuel
(
intptr_t
pduel
)
{
void
YGO_EndDuel
(
OCG_Duel
pduel
)
{
end_d
uel
(
pduel
);
OCG_DestroyD
uel
(
pduel
);
}
}
int32
OCG_GetMessage
(
intptr_t
pduel
,
byte
*
buf
)
{
uint32_t
YGO_GetMessage
(
OCG_Duel
pduel
,
uint8_t
*
buf
)
{
return
get_message
(
pduel
,
buf
);
uint32_t
len
;
auto
buf_
=
OCG_DuelGetMessage
(
pduel_
,
&
len
);
memcpy
(
buf
,
buf_
,
len
);
return
len
;
}
}
uint32_t
OCG_Process
(
intptr_t
pduel
)
{
int
YGO_Process
(
OCG_Duel
pduel
)
{
return
p
rocess
(
pduel
);
return
OCG_DuelP
rocess
(
pduel
);
}
}
int32
OCG_QueryCard
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
,
uint8
sequence
,
int32
query_flag
,
byte
*
buf
,
int32
use_cache
)
{
int32_t
YGO_QueryCard
(
OCG_Duel
pduel
,
uint8_t
playerid
,
uint8_t
location
,
uint8_t
sequence
,
uint32_t
query_flag
,
uint8_t
*
buf
)
{
return
query_card
(
pduel
,
playerid
,
location
,
sequence
,
query_flag
,
buf
,
use_cache
);
// TODO: overlay
OCG_QueryInfo
info
=
{
query_flag
,
playerid
,
location
,
sequence
};
uint32_t
length
;
auto
buf_
=
OCG_DuelQuery
(
pduel
,
&
length
,
info
);
if
(
length
>
0
)
{
memcpy
(
buf
,
buf_
,
length
);
}
return
length
;
}
}
int32
OCG_QueryFieldCount
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
)
{
int32_t
YGO_QueryFieldCount
(
OCG_Duel
pduel
,
uint8_t
playerid
,
uint8_t
location
)
{
return
query_field_count
(
pduel
,
playerid
,
location
);
return
0
;
// return OCG_DuelQueryCount(pduel, playerid, location);
}
}
int32
OCG_QueryFieldCard
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
,
uint32_t
query_flag
,
byte
*
buf
,
int32
use_cache
)
{
int32_t
OCG_QueryFieldCard
(
OCG_Duel
pduel
,
uint8_t
playerid
,
uint8_t
location
,
uint32_t
query_flag
,
uint8_t
*
buf
,
int32_t
use_cache
)
{
return
query_field_card
(
pduel
,
playerid
,
location
,
query_flag
,
buf
,
use_cache
);
return
0
;
// return query_field_card(pduel, playerid, location, query_flag, buf, use_cache);
}
}
void
OCG_SetResponsei
(
intptr_t
pduel
,
int32
value
)
{
void
YGO_SetResponsei
(
OCG_Duel
pduel
,
int32_t
value
)
{
if
(
record_
)
{
if
(
record_
)
{
ReplayWriteInt8
(
4
);
ReplayWriteInt8
(
4
);
ReplayWriteInt32
(
value
);
ReplayWriteInt32
(
value
);
}
}
set_responsei
(
pduel
,
value
);
uint32_t
len
=
sizeof
(
value
);
memcpy
(
resp_buf_
,
&
value
,
len
);
OCG_DuelSetResponse
(
pduel
,
resp_buf_
,
len
);
}
}
void
OCG_SetResponseb
(
intptr_t
pduel
,
byte
*
buf
)
{
void
YGO_SetResponseb
(
OCG_Duel
pduel
,
uint8_t
*
buf
,
uint32_t
len
=
0
)
{
if
(
record_
)
{
if
(
record_
)
{
switch
(
msg_
)
{
if
(
len
==
0
)
{
case
MSG_SORT_CARD
:
// len = buf[0];
ReplayWriteInt8
(
1
);
// ReplayWriteInt8(len);
fwrite
(
buf
,
1
,
1
,
fp_
);
// fwrite(buf + 1, len, 1, fp_);
break
;
fwrite
(
buf
,
len
,
1
,
fp_
);
case
MSG_SELECT_PLACE
:
}
else
{
case
MSG_SELECT_DISFIELD
:
ReplayWriteInt8
(
len
);
ReplayWriteInt8
(
3
);
fwrite
(
buf
,
len
,
1
,
fp_
);
fwrite
(
buf
,
3
,
1
,
fp_
);
break
;
default:
ReplayWriteInt8
(
buf
[
0
]
+
1
);
fwrite
(
buf
,
buf
[
0
]
+
1
,
1
,
fp_
);
break
;
}
}
}
}
set_responseb
(
pduel
,
buf
);
if
(
len
==
0
)
{
len
=
buf
[
0
];
OCG_DuelSetResponse
(
pduel
,
buf
+
1
,
len
);
}
else
{
OCG_DuelSetResponse
(
pduel
,
buf
,
len
);
}
}
}
// edopro-core API
// edopro-core API
...
@@ -2154,10 +2290,10 @@ private:
...
@@ -2154,10 +2290,10 @@ private:
return
;
return
;
}
}
SpecIndex
spec2index
;
//
SpecIndex spec2index;
_set_obs_cards
(
state
[
"obs:cards_"
_
],
spec2index
,
to_play_
);
//
_set_obs_cards(state["obs:cards_"_], spec2index, to_play_);
_set_obs_global
(
state
[
"obs:global_"
_
],
to_play_
);
//
_set_obs_global(state["obs:global_"_], to_play_);
// we can't shuffle because idx must be stable in callback
// we can't shuffle because idx must be stable in callback
if
(
n_options
>
max_options
())
{
if
(
n_options
>
max_options
())
{
...
@@ -2169,10 +2305,11 @@ private:
...
@@ -2169,10 +2305,11 @@ private:
// fmt::println("{} {}", key, val);
// fmt::println("{} {}", key, val);
// }
// }
_set_obs_actions
(
state
[
"obs:actions_"
_
],
spec2index
,
msg_
,
options_
);
//
_set_obs_actions(state["obs:actions_"_], spec2index, msg_, options_);
n_options
=
options_
.
size
();
n_options
=
options_
.
size
();
state
[
"info:num_options"
_
]
=
n_options
;
state
[
"info:num_options"
_
]
=
n_options
;
return
;
// update h_card_ids from state
// update h_card_ids from state
auto
&
h_card_ids
=
to_play_
==
0
?
h_card_ids_0_
:
h_card_ids_1_
;
auto
&
h_card_ids
=
to_play_
==
0
?
h_card_ids_0_
:
h_card_ids_1_
;
...
@@ -2245,32 +2382,31 @@ private:
...
@@ -2245,32 +2382,31 @@ private:
// but since we have shuffled deck, so just add in order
// but since we have shuffled deck, so just add in order
for
(
int
i
=
0
;
i
<
main_deck
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
main_deck
.
size
();
i
++
)
{
OCG_NewCard
(
pduel_
,
main_deck
[
i
],
player
,
player
,
LOCATION_DECK
,
0
,
YGO_NewCard
(
pduel_
,
main_deck
[
i
],
player
,
player
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
POS_FACEDOWN_DEFENSE
);
}
}
// TODO: check this for EDOPro
// add extra deck in reverse order following ygopro
// add extra deck in reverse order following ygopro
for
(
int
i
=
int
(
extra_deck
.
size
())
-
1
;
i
>=
0
;
--
i
)
{
for
(
int
i
=
int
(
extra_deck
.
size
())
-
1
;
i
>=
0
;
--
i
)
{
OCG_NewCard
(
pduel_
,
extra_deck
[
i
],
player
,
player
,
LOCATION_EXTRA
,
0
,
YGO_NewCard
(
pduel_
,
extra_deck
[
i
],
player
,
player
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
POS_FACEDOWN_DEFENSE
);
}
}
}
}
void
next
()
{
void
next
()
{
while
(
duel_started_
)
{
while
(
duel_started_
)
{
if
(
eng_flag_
==
PROCESSOR
_END
)
{
if
(
duel_status_
==
OCG_DUEL_STATUS
_END
)
{
break
;
break
;
}
}
uint32_t
res
=
OCG_Process
(
pduel_
);
dl_
=
res
&
PROCESSOR_BUFFER_LEN
;
eng_flag_
=
res
&
PROCESSOR_FLAG
;
if
(
dl_
==
0
)
{
if
(
dp_
==
fdl_
)
{
continue
;
duel_status_
=
YGO_Process
(
pduel_
);
fdl_
=
YGO_GetMessage
(
pduel_
,
data_
);
if
(
fdl_
==
0
)
{
continue
;
}
dp_
=
0
;
}
}
OCG_GetMessage
(
pduel_
,
data_
);
while
(
dp_
!=
fdl_
)
{
dp_
=
0
;
while
(
dp_
!=
dl_
)
{
handle_message
();
handle_message
();
if
(
options_
.
empty
())
{
if
(
options_
.
empty
())
{
continue
;
continue
;
...
@@ -2313,13 +2449,46 @@ private:
...
@@ -2313,13 +2449,46 @@ private:
return
v
;
return
v
;
}
}
uint32_t
read_u64
()
{
uint32_t
v
=
*
reinterpret_cast
<
uint64_t
*>
(
data_
+
dp_
);
dp_
+=
8
;
return
v
;
}
template
<
typename
T1
,
typename
T2
>
T2
compat_read
()
{
if
(
compat_mode_
)
{
T1
v
=
*
reinterpret_cast
<
T1
*>
(
data_
+
dp_
);
dp_
+=
sizeof
(
T1
);
return
static_cast
<
T2
>
(
v
);
}
T2
v
=
*
reinterpret_cast
<
T2
*>
(
data_
+
dp_
);
dp_
+=
sizeof
(
T2
);
return
v
;
}
uint32_t
q_read_u8
()
{
uint32_t
q_read_u8
()
{
qdp_
+=
6
;
uint8_t
v
=
*
reinterpret_cast
<
uint8_t
*>
(
query_buf_
+
qdp_
);
uint8_t
v
=
*
reinterpret_cast
<
uint8_t
*>
(
query_buf_
+
qdp_
);
qdp_
+=
1
;
qdp_
+=
1
;
return
v
;
return
v
;
}
}
uint32_t
q_read_u16
()
{
qdp_
+=
6
;
uint32_t
v
=
*
reinterpret_cast
<
uint16_t
*>
(
query_buf_
+
qdp_
);
qdp_
+=
2
;
return
v
;
}
uint32_t
q_read_u32
()
{
uint32_t
q_read_u32
()
{
qdp_
+=
6
;
uint32_t
v
=
*
reinterpret_cast
<
uint32_t
*>
(
query_buf_
+
qdp_
);
qdp_
+=
4
;
return
v
;
}
uint32_t
q_read_u32_
()
{
uint32_t
v
=
*
reinterpret_cast
<
uint32_t
*>
(
query_buf_
+
qdp_
);
uint32_t
v
=
*
reinterpret_cast
<
uint32_t
*>
(
query_buf_
+
qdp_
);
qdp_
+=
4
;
qdp_
+=
4
;
return
v
;
return
v
;
...
@@ -2327,34 +2496,29 @@ private:
...
@@ -2327,34 +2496,29 @@ private:
CardCode
get_card_code
(
PlayerId
player
,
uint8_t
loc
,
uint8_t
seq
)
{
CardCode
get_card_code
(
PlayerId
player
,
uint8_t
loc
,
uint8_t
seq
)
{
int32_t
flags
=
QUERY_CODE
;
int32_t
flags
=
QUERY_CODE
;
int32_t
bl
=
OCG_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
,
0
);
int32_t
bl
=
YGO_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
);
qdp_
=
0
;
qdp_
=
0
;
if
(
bl
<=
0
)
{
if
(
bl
<=
0
)
{
throw
std
::
runtime_error
(
"[get_card_code] Invalid card"
);
throw
std
::
runtime_error
(
"[get_card_code] Invalid card"
);
}
}
qdp_
+=
8
;
return
q_read_u32
();
return
q_read_u32
();
}
}
Card
get_card
(
PlayerId
player
,
uint8_t
loc
,
uint8_t
seq
)
{
Card
get_card
(
PlayerId
player
,
uint8_t
loc
,
uint8_t
seq
)
{
int32_t
flags
=
QUERY_CODE
|
QUERY_
ATTACK
|
QUERY_DEFENSE
|
QUERY_POSITION
|
int32_t
flags
=
QUERY_CODE
|
QUERY_
POSITION
|
QUERY_LEVEL
|
QUERY_RANK
|
QUERY_
LEVEL
|
QUERY_RANK
|
QUERY_LSCALE
|
QUERY_RSCALE
|
QUERY_
ATTACK
|
QUERY_DEFENSE
|
QUERY_LSCALE
|
QUERY_RSCALE
|
QUERY_LINK
;
QUERY_LINK
;
int32_t
bl
=
OCG_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
,
0
);
int32_t
bl
=
YGO_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
);
qdp_
=
0
;
qdp_
=
0
;
if
(
bl
<=
0
)
{
if
(
bl
<=
0
)
{
throw
std
::
runtime_error
(
"[get_card] Invalid card (bl <= 0)"
);
throw
std
::
runtime_error
(
"[get_card] Invalid card (bl <= 0)"
);
}
}
uint32_t
f
=
q_read_u32
();
if
(
f
==
LEN_EMPTY
)
{
return
Card
();
}
f
=
q_read_u32
();
CardCode
code
=
q_read_u32
();
CardCode
code
=
q_read_u32
();
Card
c
=
c_get_card
(
code
);
Card
c
=
c_get_card
(
code
);
uint32_t
position
=
q_read_u32
();
uint32_t
position
=
q_read_u32
();
c
.
set_location
(
position
);
c
.
set_location
(
position
);
uint32_t
level
=
q_read_u32
();
uint32_t
level
=
q_read_u32
();
// TODO: check negative level
if
((
level
&
0xff
)
>
0
)
{
if
((
level
&
0xff
)
>
0
)
{
c
.
level_
=
level
&
0xff
;
c
.
level_
=
level
&
0xff
;
}
}
...
@@ -2366,8 +2530,10 @@ private:
...
@@ -2366,8 +2530,10 @@ private:
c
.
defense_
=
q_read_u32
();
c
.
defense_
=
q_read_u32
();
c
.
lscale_
=
q_read_u32
();
c
.
lscale_
=
q_read_u32
();
c
.
rscale_
=
q_read_u32
();
c
.
rscale_
=
q_read_u32
();
uint32_t
link
=
q_read_u32
();
uint32_t
link
=
q_read_u32
();
uint32_t
link_marker
=
q_read_u32
();
uint32_t
link_marker
=
q_read_u32_
();
// TODO: fix this
if
((
link
&
0xff
)
>
0
)
{
if
((
link
&
0xff
)
>
0
)
{
c
.
level_
=
link
&
0xff
;
c
.
level_
=
link
&
0xff
;
}
}
...
@@ -2378,87 +2544,88 @@ private:
...
@@ -2378,87 +2544,88 @@ private:
}
}
std
::
vector
<
Card
>
get_cards_in_location
(
PlayerId
player
,
uint8_t
loc
)
{
std
::
vector
<
Card
>
get_cards_in_location
(
PlayerId
player
,
uint8_t
loc
)
{
int32_t
flags
=
QUERY_CODE
|
QUERY_POSITION
|
QUERY_LEVEL
|
QUERY_RANK
|
return
{};
QUERY_ATTACK
|
QUERY_DEFENSE
|
QUERY_EQUIP_CARD
|
// int32_t flags = QUERY_CODE | QUERY_POSITION | QUERY_LEVEL | QUERY_RANK |
QUERY_OVERLAY_CARD
|
QUERY_COUNTERS
|
QUERY_LSCALE
|
// QUERY_ATTACK | QUERY_DEFENSE | QUERY_EQUIP_CARD |
QUERY_RSCALE
|
QUERY_LINK
;
// QUERY_OVERLAY_CARD | QUERY_COUNTERS | QUERY_LSCALE |
int32_t
bl
=
OCG_QueryFieldCard
(
pduel_
,
player
,
loc
,
flags
,
query_buf_
,
0
);
// QUERY_RSCALE | QUERY_LINK;
qdp_
=
0
;
// int32_t bl = OCG_QueryFieldCard(pduel_, player, loc, flags, query_buf_, 0);
std
::
vector
<
Card
>
cards
;
// qdp_ = 0;
while
(
true
)
{
// std::vector<Card> cards;
if
(
qdp_
>=
bl
)
{
// while (true) {
break
;
// if (qdp_ >= bl) {
}
// break;
uint32_t
f
=
q_read_u32
();
// }
if
(
f
==
LEN_EMPTY
)
{
// uint32_t f = q_read_u32();
continue
;
// if (f == LEN_EMPTY) {
;
// continue;
}
// ;
f
=
q_read_u32
();
// }
CardCode
code
=
q_read_u32
();
// f = q_read_u32();
Card
c
=
c_get_card
(
code
);
// CardCode code = q_read_u32();
// Card c = c_get_card(code);
uint8_t
controller
=
q_read_u8
();
uint8_t
location
=
q_read_u8
();
// uint8_t controller = q_read_u8();
uint8_t
sequence
=
q_read_u8
();
// uint8_t location = q_read_u8();
uint8_t
position
=
q_read_u8
();
// uint8_t sequence = q_read_u8();
c
.
controler_
=
controller
;
// uint8_t position = q_read_u8();
c
.
location_
=
location
;
// c.controler_ = controller;
c
.
sequence_
=
sequence
;
// c.location_ = location;
c
.
position_
=
position
;
// c.sequence_ = sequence;
// c.position_ = position;
uint32_t
level
=
q_read_u32
();
if
((
level
&
0xff
)
>
0
)
{
// uint32_t level = q_read_u32();
c
.
level_
=
level
&
0xff
;
// if ((level & 0xff) > 0) {
}
// c.level_ = level & 0xff;
uint32_t
rank
=
q_read_u32
();
// }
if
((
rank
&
0xff
)
>
0
)
{
// uint32_t rank = q_read_u32();
c
.
level_
=
rank
&
0xff
;
// if ((rank & 0xff) > 0) {
}
// c.level_ = rank & 0xff;
c
.
attack_
=
q_read_u32
();
// }
c
.
defense_
=
q_read_u32
();
// c.attack_ = q_read_u32();
// c.defense_ = q_read_u32();
// TODO: equip_target
if
(
f
&
QUERY_EQUIP_CARD
)
{
// // TODO: equip_target
q_read_u32
();
// if (f & QUERY_EQUIP_CARD) {
}
// q_read_u32();
// }
uint32_t
n_xyz
=
q_read_u32
();
for
(
int
i
=
0
;
i
<
n_xyz
;
++
i
)
{
// uint32_t n_xyz = q_read_u32();
auto
code
=
q_read_u32
();
// for (int i = 0; i < n_xyz; ++i) {
Card
c_
=
c_get_card
(
code
);
// auto code = q_read_u32();
c_
.
controler_
=
controller
;
// Card c_ = c_get_card(code);
c_
.
location_
=
location
|
LOCATION_OVERLAY
;
// c_.controler_ = controller;
c_
.
sequence_
=
sequence
;
// c_.location_ = location | LOCATION_OVERLAY;
c_
.
position_
=
i
;
// c_.sequence_ = sequence;
cards
.
push_back
(
c_
);
// c_.position_ = i;
}
// cards.push_back(c_);
// }
// TODO: counters
uint32_t
n_counters
=
q_read_u32
();
// // TODO: counters
for
(
int
i
=
0
;
i
<
n_counters
;
++
i
)
{
// uint32_t n_counters = q_read_u32();
if
(
i
==
0
)
{
// for (int i = 0; i < n_counters; ++i) {
c
.
counter_
=
q_read_u32
();
// if (i == 0) {
}
// c.counter_ = q_read_u32();
else
{
// }
q_read_u32
();
// else {
}
// q_read_u32();
}
// }
// }
c
.
lscale_
=
q_read_u32
();
c
.
rscale_
=
q_read_u32
();
// c.lscale_ = q_read_u32();
// c.rscale_ = q_read_u32();
uint32_t
link
=
q_read_u32
();
uint32_t
link_marker
=
q_read_u32
();
// uint32_t link = q_read_u32();
if
((
link
&
0xff
)
>
0
)
{
// uint32_t link_marker = q_read_u32();
c
.
level_
=
link
&
0xff
;
// if ((link & 0xff) > 0) {
}
// c.level_ = link & 0xff;
if
(
link_marker
>
0
)
{
// }
c
.
defense_
=
link_marker
;
// if (link_marker > 0) {
}
// c.defense_ = link_marker;
cards
.
push_back
(
c
);
// }
}
// cards.push_back(c);
return
cards
;
// }
// return cards;
}
}
std
::
vector
<
Card
>
read_cardlist
(
bool
extra
=
false
,
bool
extra8
=
false
)
{
std
::
vector
<
Card
>
read_cardlist
(
bool
extra
=
false
,
bool
extra8
=
false
)
{
...
@@ -2483,29 +2650,53 @@ private:
...
@@ -2483,29 +2650,53 @@ private:
return
cards
;
return
cards
;
}
}
std
::
vector
<
IdleCardSpec
>
read_cardlist_spec
(
bool
extra
=
false
,
std
::
vector
<
IdleCardSpec
>
read_cardlist_spec
(
bool
extra8
=
false
)
{
bool
u32_seq
=
true
,
bool
extra
=
false
,
bool
extra8
=
false
)
{
std
::
vector
<
IdleCardSpec
>
card_specs
;
std
::
vector
<
IdleCardSpec
>
card_specs
;
auto
count
=
read_u8
();
// TODO: different with ygopro-core
auto
count
=
compat_read
<
uint8_t
,
uint32_t
>
();
card_specs
.
reserve
(
count
);
card_specs
.
reserve
(
count
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
CardCode
code
=
read_u32
();
CardCode
code
=
read_u32
();
auto
controller
=
read_u8
();
auto
controller
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
// TODO: different with ygopro-core
uint32_t
seq
;
if
(
u32_seq
)
{
seq
=
compat_read
<
uint8_t
,
uint32_t
>
();;
}
else
{
seq
=
read_u8
();
}
uint32_t
data
=
-
1
;
uint32_t
data
=
-
1
;
if
(
extra
)
{
if
(
extra
)
{
if
(
extra8
)
{
data
=
compat_read
<
uint32_t
,
uint64_t
>
();
data
=
read_u8
();
if
(
!
compat_mode_
)
{
}
else
{
// TODO: handle this
data
=
read_u32
();
read_u8
();
}
}
}
}
if
(
extra8
)
{
read_u8
();
}
card_specs
.
push_back
({
code
,
ls_to_spec
(
loc
,
seq
,
0
),
data
});
card_specs
.
push_back
({
code
,
ls_to_spec
(
loc
,
seq
,
0
),
data
});
}
}
return
card_specs
;
return
card_specs
;
}
}
loc_info
read_loc_info
()
{
loc_info
info
;
info
.
controler
=
read_u8
();
info
.
location
=
read_u8
();
if
(
compat_mode_
)
{
info
.
sequence
=
read_u8
();
info
.
position
=
read_u8
();
}
else
{
info
.
sequence
=
read_u32
();
info
.
position
=
read_u32
();
}
return
info
;
}
std
::
string
cardlist_info_for_player
(
const
Card
&
card
,
PlayerId
pl
)
{
std
::
string
cardlist_info_for_player
(
const
Card
&
card
,
PlayerId
pl
)
{
std
::
string
spec
=
card
.
get_spec
(
pl
);
std
::
string
spec
=
card
.
get_spec
(
pl
);
if
(
card
.
location_
==
LOCATION_DECK
)
{
if
(
card
.
location_
==
LOCATION_DECK
)
{
...
@@ -2518,11 +2709,13 @@ private:
...
@@ -2518,11 +2709,13 @@ private:
}
}
void
handle_message
()
{
void
handle_message
()
{
int
l_
=
read_u32
();
dl_
=
dp_
+
l_
;
msg_
=
int
(
data_
[
dp_
++
]);
msg_
=
int
(
data_
[
dp_
++
]);
options_
=
{};
options_
=
{};
if
(
verbose_
)
{
if
(
verbose_
)
{
fmt
::
println
(
"Message {},
length {}, dp {}"
,
msg_to_string
(
msg_
)
,
dl_
,
dp_
);
fmt
::
println
(
"Message {},
full {}, length {}, dp {}"
,
msg_to_string
(
msg_
),
fdl_
,
dl_
,
dp_
);
}
}
if
(
msg_
==
MSG_DRAW
)
{
if
(
msg_
==
MSG_DRAW
)
{
...
@@ -2531,10 +2724,12 @@ private:
...
@@ -2531,10 +2724,12 @@ private:
return
;
return
;
}
}
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
drawed
=
read_u8
();
// TODO: different with ygopro-core
auto
drawed
=
compat_read
<
uint8_t
,
uint32_t
>
();
std
::
vector
<
uint32_t
>
codes
;
std
::
vector
<
uint32_t
>
codes
;
for
(
int
i
=
0
;
i
<
drawed
;
++
i
)
{
for
(
int
i
=
0
;
i
<
drawed
;
++
i
)
{
uint32_t
code
=
read_u32
();
uint32_t
code
=
read_u32
();
dp_
+=
4
;
codes
.
push_back
(
code
&
0x7fffffff
);
codes
.
push_back
(
code
&
0x7fffffff
);
}
}
const
auto
&
pl
=
players_
[
player
];
const
auto
&
pl
=
players_
[
player
];
...
@@ -2569,8 +2764,8 @@ private:
...
@@ -2569,8 +2764,8 @@ private:
return
;
return
;
}
}
CardCode
code
=
read_u32
();
CardCode
code
=
read_u32
();
uint32_t
location
=
read_u32
();
loc_info
location
=
read_loc_info
();
uint32_t
newloc
=
read_u32
();
loc_info
newloc
=
read_loc_info
();
uint32_t
reason
=
read_u32
();
uint32_t
reason
=
read_u32
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
location
);
card
.
set_location
(
location
);
...
@@ -2596,9 +2791,16 @@ private:
...
@@ -2596,9 +2791,16 @@ private:
return
card_visible
?
card
.
name_
:
"Face-down card"
;
return
card_visible
?
card
.
name_
:
"Face-down card"
;
};
};
if
((
reason
&
REASON_DESTROY
)
&&
(
card
.
location_
!=
cnew
.
location_
))
{
if
(
card
.
location_
!=
cnew
.
location_
)
{
pl
->
notify
(
fmt
::
format
(
"Card {} ({}) destroyed."
,
plspec
,
card
.
name_
));
if
(
reason
&
REASON_DESTROY
)
{
op
->
notify
(
fmt
::
format
(
"Card {} ({}) destroyed."
,
opspec
,
card
.
name_
));
pl
->
notify
(
fmt
::
format
(
"Card {} ({}) destroyed."
,
plspec
,
card
.
name_
));
op
->
notify
(
fmt
::
format
(
"Card {} ({}) destroyed."
,
opspec
,
card
.
name_
));
}
else
if
(
cnew
.
location_
==
LOCATION_REMOVED
)
{
pl
->
notify
(
fmt
::
format
(
"Your card {} ({}) was banished."
,
plspec
,
card
.
name_
));
op
->
notify
(
fmt
::
format
(
"{}'s card {} ({}) was banished."
,
pl
->
nickname_
,
opspec
,
getvisiblename
(
op
)));
}
}
else
if
((
card
.
location_
==
cnew
.
location_
)
&&
}
else
if
((
card
.
location_
==
cnew
.
location_
)
&&
(
card
.
location_
&
LOCATION_ONFIELD
))
{
(
card
.
location_
&
LOCATION_ONFIELD
))
{
if
(
card
.
controler_
!=
cnew
.
controler_
)
{
if
(
card
.
controler_
!=
cnew
.
controler_
)
{
...
@@ -2660,12 +2862,6 @@ private:
...
@@ -2660,12 +2862,6 @@ private:
plspec
,
card
.
name_
));
plspec
,
card
.
name_
));
op
->
notify
(
fmt
::
format
(
"{}'s card {} ({}) was sent to the graveyard."
,
op
->
notify
(
fmt
::
format
(
"{}'s card {} ({}) was sent to the graveyard."
,
pl
->
nickname_
,
opspec
,
card
.
name_
));
pl
->
nickname_
,
opspec
,
card
.
name_
));
}
else
if
((
card
.
location_
!=
cnew
.
location_
)
&&
(
cnew
.
location_
==
LOCATION_REMOVED
))
{
pl
->
notify
(
fmt
::
format
(
"Your card {} ({}) was banished."
,
plspec
,
card
.
name_
));
op
->
notify
(
fmt
::
format
(
"{}'s card {} ({}) was banished."
,
pl
->
nickname_
,
opspec
,
getvisiblename
(
op
)));
}
else
if
((
card
.
location_
!=
cnew
.
location_
)
&&
}
else
if
((
card
.
location_
!=
cnew
.
location_
)
&&
(
cnew
.
location_
==
LOCATION_DECK
))
{
(
cnew
.
location_
==
LOCATION_DECK
))
{
pl
->
notify
(
fmt
::
format
(
"Your card {} ({}) returned to your deck."
,
pl
->
notify
(
fmt
::
format
(
"Your card {} ({}) returned to your deck."
,
...
@@ -2685,6 +2881,8 @@ private:
...
@@ -2685,6 +2881,8 @@ private:
pl
->
notify
(
fmt
::
format
(
"Activating {} ({})"
,
plnewspec
,
card
.
name_
));
pl
->
notify
(
fmt
::
format
(
"Activating {} ({})"
,
plnewspec
,
card
.
name_
));
op
->
notify
(
fmt
::
format
(
"{} activating {} ({})"
,
pl
->
nickname_
,
opspec
,
op
->
notify
(
fmt
::
format
(
"{} activating {} ({})"
,
pl
->
nickname_
,
opspec
,
cnew
.
name_
));
cnew
.
name_
));
}
else
{
fmt
::
println
(
"Unknown move reason {}"
,
reason
);
}
}
}
else
if
(
msg_
==
MSG_SWAP
)
{
}
else
if
(
msg_
==
MSG_SWAP
)
{
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
...
@@ -2716,9 +2914,8 @@ private:
...
@@ -2716,9 +2914,8 @@ private:
return
;
return
;
}
}
CardCode
code
=
read_u32
();
CardCode
code
=
read_u32
();
uint32_t
location
=
read_u32
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
location
);
card
.
set_location
(
read_loc_info
()
);
auto
c
=
card
.
controler_
;
auto
c
=
card
.
controler_
;
auto
cpl
=
players_
[
c
];
auto
cpl
=
players_
[
c
];
auto
opl
=
players_
[
1
-
c
];
auto
opl
=
players_
[
1
-
c
];
...
@@ -2732,15 +2929,17 @@ private:
...
@@ -2732,15 +2929,17 @@ private:
dp_
=
dl_
;
dp_
=
dl_
;
return
;
return
;
}
}
auto
c
=
read_u8
();
auto
info
=
read_loc_info
();
auto
loc
=
read_u8
();
auto
c
=
info
.
controler
;
auto
seq
=
read_u8
();
auto
loc
=
info
.
location
;
auto
pos
=
read_u8
();
auto
seq
=
info
.
sequence
;
auto
pos
=
info
.
position
;
Card
card
=
get_card
(
c
,
loc
,
seq
);
Card
card
=
get_card
(
c
,
loc
,
seq
);
c
=
read_u8
();
info
=
read_loc_info
();
loc
=
read_u8
();
c
=
info
.
controler
;
seq
=
read_u8
();
loc
=
info
.
location
;
pos
=
read_u8
();
seq
=
info
.
sequence
;
pos
=
info
.
position
;
Card
target
=
get_card
(
c
,
loc
,
seq
);
Card
target
=
get_card
(
c
,
loc
,
seq
);
for
(
PlayerId
pl
=
0
;
pl
<
2
;
pl
++
)
{
for
(
PlayerId
pl
=
0
;
pl
<
2
;
pl
++
)
{
auto
c
=
cardlist_info_for_player
(
card
,
pl
);
auto
c
=
cardlist_info_for_player
(
card
,
pl
);
...
@@ -2750,7 +2949,8 @@ private:
...
@@ -2750,7 +2949,8 @@ private:
}
else
if
(
msg_
==
MSG_HINT
)
{
}
else
if
(
msg_
==
MSG_HINT
)
{
auto
hint_type
=
read_u8
();
auto
hint_type
=
read_u8
();
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
value
=
read_u32
();
// TODO: different with ygopro-core
auto
value
=
compat_read
<
uint32_t
,
uint64_t
>
();
if
(
hint_type
==
HINT_SELECTMSG
&&
value
==
501
)
{
if
(
hint_type
==
HINT_SELECTMSG
&&
value
==
501
)
{
discard_hand_
=
true
;
discard_hand_
=
true
;
...
@@ -2777,12 +2977,13 @@ private:
...
@@ -2777,12 +2977,13 @@ private:
dp_
=
dl_
;
dp_
=
dl_
;
return
;
return
;
}
}
uint8_t
player
=
read_u8
();
auto
info
=
read_loc_info
();
uint8_t
loc
=
read_u8
();
uint8_t
player
=
info
.
controler
;
uint8_t
seq
=
read_u8
();
uint8_t
loc
=
info
.
location
;
uint8_t
pos
=
read_u8
();
uint8_t
seq
=
info
.
sequence
;
uint8_t
pos
=
info
.
position
;
uint8_t
type
=
read_u8
();
uint8_t
type
=
read_u8
();
uint32_t
value
=
read_u32
();
uint32_t
value
=
compat_read
<
uint32_t
,
uint64_t
>
();
Card
card
=
get_card
(
player
,
loc
,
seq
);
Card
card
=
get_card
(
player
,
loc
,
seq
);
if
(
card
.
code_
==
0
)
{
if
(
card
.
code_
==
0
)
{
return
;
return
;
...
@@ -2851,13 +3052,13 @@ private:
...
@@ -2851,13 +3052,13 @@ private:
return
;
return
;
}
}
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
size
=
read_u8
();
auto
size
=
compat_read
<
uint8_t
,
uint32_t
>
();
std
::
vector
<
Card
>
cards
;
std
::
vector
<
Card
>
cards
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
read_u32
();
read_u32
();
auto
c
=
read_u8
();
auto
c
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
auto
seq
=
compat_read
<
uint8_t
,
uint32_t
>
();
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
}
}
...
@@ -2879,17 +3080,18 @@ private:
...
@@ -2879,17 +3080,18 @@ private:
return
;
return
;
}
}
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
count
=
read_u8
();
auto
count
=
compat_read
<
uint8_t
,
uint32_t
>
();
std
::
vector
<
Card
>
cards
;
std
::
vector
<
Card
>
cards
;
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
auto
c
=
read_u8
();
auto
info
=
read_loc_info
();
auto
loc
=
read_u8
();
auto
c
=
info
.
controler
;
auto
loc
=
info
.
location
;
if
(
loc
&
LOCATION_OVERLAY
)
{
if
(
loc
&
LOCATION_OVERLAY
)
{
throw
std
::
runtime_error
(
"Overlay not supported for random selected"
);
throw
std
::
runtime_error
(
"Overlay not supported for random selected"
);
}
}
auto
seq
=
read_u8
()
;
auto
seq
=
info
.
sequence
;
auto
pos
=
read_u8
()
;
auto
pos
=
info
.
position
;
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
}
}
...
@@ -2912,13 +3114,13 @@ private:
...
@@ -2912,13 +3114,13 @@ private:
}
else
if
(
msg_
==
MSG_CONFIRM_CARDS
)
{
}
else
if
(
msg_
==
MSG_CONFIRM_CARDS
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
size
=
read_u8
();
auto
size
=
compat_read
<
uint8_t
,
uint32_t
>
();
std
::
vector
<
Card
>
cards
;
std
::
vector
<
Card
>
cards
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
read_u32
();
read_u32
();
auto
c
=
read_u8
();
auto
c
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
auto
seq
=
compat_read
<
uint8_t
,
uint32_t
>
();
if
(
verbose_
)
{
if
(
verbose_
)
{
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
}
}
...
@@ -2954,18 +3156,17 @@ private:
...
@@ -2954,18 +3156,17 @@ private:
// TODO: implement action
// TODO: implement action
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
dp_
=
dl_
;
dp_
=
dl_
;
resp_buf_
[
0
]
=
255
;
YGO_SetResponsei
(
pduel_
,
-
1
);
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
return
;
return
;
}
}
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
size
=
read_u8
();
auto
size
=
compat_read
<
uint8_t
,
uint32_t
>
();
std
::
vector
<
Card
>
cards
;
std
::
vector
<
Card
>
cards
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
read_u32
();
read_u32
();
auto
c
=
read_u8
();
auto
c
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
seq
=
read_u8
();
auto
seq
=
compat_read
<
uint8_t
,
uint32_t
>
();
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
}
}
auto
pl
=
players_
[
player
];
auto
pl
=
players_
[
player
];
...
@@ -2977,8 +3178,7 @@ private:
...
@@ -2977,8 +3178,7 @@ private:
}
}
fmt
::
println
(
"sort card action not implemented"
);
fmt
::
println
(
"sort card action not implemented"
);
resp_buf_
[
0
]
=
255
;
YGO_SetResponsei
(
pduel_
,
-
1
);
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
// // generate all permutations
// // generate all permutations
// std::vector<int> perm(size);
// std::vector<int> perm(size);
...
@@ -2998,7 +3198,7 @@ private:
...
@@ -2998,7 +3198,7 @@ private:
// const auto &option = options_[idx];
// const auto &option = options_[idx];
// if (option == "c") {
// if (option == "c") {
// resp_buf_[0] = 255;
// resp_buf_[0] = 255;
//
OCG
_SetResponseb(pduel_, resp_buf_);
//
YGO
_SetResponseb(pduel_, resp_buf_);
// return;
// return;
// }
// }
// std::istringstream iss(option);
// std::istringstream iss(option);
...
@@ -3008,7 +3208,7 @@ private:
...
@@ -3008,7 +3208,7 @@ private:
// resp_buf_[i] = uint8_t(x);
// resp_buf_[i] = uint8_t(x);
// i++;
// i++;
// }
// }
//
OCG
_SetResponseb(pduel_, resp_buf_);
//
YGO
_SetResponseb(pduel_, resp_buf_);
// };
// };
}
else
if
(
msg_
==
MSG_ADD_COUNTER
)
{
}
else
if
(
msg_
==
MSG_ADD_COUNTER
)
{
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
...
@@ -3104,7 +3304,7 @@ private:
...
@@ -3104,7 +3304,7 @@ private:
}
}
CardCode
code
=
read_u32
();
CardCode
code
=
read_u32
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
read_
u32
());
card
.
set_location
(
read_
loc_info
());
const
auto
&
nickname
=
players_
[
card
.
controler_
]
->
nickname_
;
const
auto
&
nickname
=
players_
[
card
.
controler_
]
->
nickname_
;
for
(
auto
pl
:
players_
)
{
for
(
auto
pl
:
players_
)
{
pl
->
notify
(
nickname
+
" summoning "
+
card
.
name_
+
" ("
+
pl
->
notify
(
nickname
+
" summoning "
+
card
.
name_
+
" ("
+
...
@@ -3123,9 +3323,9 @@ private:
...
@@ -3123,9 +3323,9 @@ private:
}
}
auto
code
=
read_u32
();
auto
code
=
read_u32
();
auto
loc
ation
=
read_u32
();
auto
loc
_info
=
read_loc_info
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
loc
ation
);
card
.
set_location
(
loc
_info
);
auto
cpl
=
players_
[
card
.
controler_
];
auto
cpl
=
players_
[
card
.
controler_
];
for
(
PlayerId
pl
=
0
;
pl
<
2
;
pl
++
)
{
for
(
PlayerId
pl
=
0
;
pl
<
2
;
pl
++
)
{
...
@@ -3221,16 +3421,16 @@ private:
...
@@ -3221,16 +3421,16 @@ private:
dp_
=
dl_
;
dp_
=
dl_
;
return
;
return
;
}
}
auto
attacker
=
read_
u32
();
auto
attacker
=
read_
loc_info
();
PlayerId
ac
=
attacker
&
0xff
;
PlayerId
ac
=
attacker
.
controler
;
auto
aloc
=
(
attacker
>>
8
)
&
0xff
;
auto
aloc
=
attacker
.
location
;
auto
aseq
=
(
attacker
>>
16
)
&
0xff
;
auto
aseq
=
attacker
.
sequence
;
auto
apos
=
(
attacker
>>
24
)
&
0xff
;
auto
apos
=
attacker
.
position
;
auto
target
=
read_
u32
();
auto
target
=
read_
loc_info
();
PlayerId
tc
=
target
&
0xff
;
PlayerId
tc
=
target
.
controler
;
auto
tloc
=
(
target
>>
8
)
&
0xff
;
auto
tloc
=
target
.
location
;
auto
tseq
=
(
target
>>
16
)
&
0xff
;
auto
tseq
=
target
.
sequence
;
auto
tpos
=
(
target
>>
24
)
&
0xff
;
auto
tpos
=
target
.
position
;
if
((
ac
==
0
)
&&
(
aloc
==
0
)
&&
(
aseq
==
0
)
&&
(
apos
==
0
))
{
if
((
ac
==
0
)
&&
(
aloc
==
0
)
&&
(
aseq
==
0
)
&&
(
apos
==
0
))
{
return
;
return
;
...
@@ -3277,23 +3477,23 @@ private:
...
@@ -3277,23 +3477,23 @@ private:
dp_
=
dl_
;
dp_
=
dl_
;
return
;
return
;
}
}
auto
attacker
=
read_
u32
();
auto
attacker
=
read_
loc_info
();
auto
aa
=
read_u32
();
auto
aa
=
read_u32
();
auto
ad
=
read_u32
();
auto
ad
=
read_u32
();
auto
bd0
=
read_u8
();
auto
bd0
=
read_u8
();
auto
target
=
read_
u32
();
auto
target
=
read_
loc_info
();
auto
da
=
read_u32
();
auto
da
=
read_u32
();
auto
dd
=
read_u32
();
auto
dd
=
read_u32
();
auto
bd1
=
read_u8
();
auto
bd1
=
read_u8
();
auto
ac
=
attacker
&
0xff
;
auto
ac
=
attacker
.
controler
;
auto
aloc
=
(
attacker
>>
8
)
&
0xff
;
auto
aloc
=
attacker
.
location
;
auto
aseq
=
(
attacker
>>
16
)
&
0xff
;
auto
aseq
=
attacker
.
sequence
;
auto
tc
=
target
&
0xff
;
auto
tc
=
target
.
controler
;
auto
tloc
=
(
target
>>
8
)
&
0xff
;
auto
tloc
=
target
.
location
;
auto
tseq
=
(
target
>>
16
)
&
0xff
;
auto
tseq
=
target
.
sequence
;
auto
tpos
=
(
target
>>
24
)
&
0xff
;
auto
tpos
=
target
.
position
;
Card
acard
=
get_card
(
ac
,
aloc
,
aseq
);
Card
acard
=
get_card
(
ac
,
aloc
,
aseq
);
Card
tcard
;
Card
tcard
;
...
@@ -3338,8 +3538,8 @@ private:
...
@@ -3338,8 +3538,8 @@ private:
throw
std
::
runtime_error
(
"Retry"
);
throw
std
::
runtime_error
(
"Retry"
);
}
else
if
(
msg_
==
MSG_SELECT_BATTLECMD
)
{
}
else
if
(
msg_
==
MSG_SELECT_BATTLECMD
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
activatable
=
read_cardlist_spec
(
true
);
auto
activatable
=
read_cardlist_spec
(
true
,
true
);
auto
attackable
=
read_cardlist_spec
(
tru
e
,
true
);
auto
attackable
=
read_cardlist_spec
(
false
,
fals
e
,
true
);
bool
to_m2
=
read_u8
();
bool
to_m2
=
read_u8
();
bool
to_ep
=
read_u8
();
bool
to_ep
=
read_u8
();
...
@@ -3391,14 +3591,14 @@ private:
...
@@ -3391,14 +3591,14 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
,
n_activatables
,
n_attackables
,
to_ep
,
to_m2
](
int
idx
)
{
callback_
=
[
this
,
n_activatables
,
n_attackables
,
to_ep
,
to_m2
](
int
idx
)
{
if
(
idx
<
n_activatables
)
{
if
(
idx
<
n_activatables
)
{
OCG
_SetResponsei
(
pduel_
,
idx
<<
16
);
YGO
_SetResponsei
(
pduel_
,
idx
<<
16
);
}
else
if
(
idx
<
(
n_activatables
+
n_attackables
))
{
}
else
if
(
idx
<
(
n_activatables
+
n_attackables
))
{
idx
=
idx
-
n_activatables
;
idx
=
idx
-
n_activatables
;
OCG
_SetResponsei
(
pduel_
,
(
idx
<<
16
)
+
1
);
YGO
_SetResponsei
(
pduel_
,
(
idx
<<
16
)
+
1
);
}
else
if
((
options_
[
idx
]
==
"e"
)
&&
to_ep
)
{
}
else
if
((
options_
[
idx
]
==
"e"
)
&&
to_ep
)
{
OCG
_SetResponsei
(
pduel_
,
3
);
YGO
_SetResponsei
(
pduel_
,
3
);
}
else
if
((
options_
[
idx
]
==
"m"
)
&&
to_m2
)
{
}
else
if
((
options_
[
idx
]
==
"m"
)
&&
to_m2
)
{
OCG
_SetResponsei
(
pduel_
,
2
);
YGO
_SetResponsei
(
pduel_
,
2
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option"
);
throw
std
::
runtime_error
(
"Invalid option"
);
}
}
...
@@ -3407,9 +3607,9 @@ private:
...
@@ -3407,9 +3607,9 @@ private:
auto
player
=
read_u8
();
auto
player
=
read_u8
();
bool
finishable
=
read_u8
();
bool
finishable
=
read_u8
();
bool
cancelable
=
read_u8
();
bool
cancelable
=
read_u8
();
auto
min
=
read_u8
();
auto
min
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
max
=
read_u8
();
auto
max
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
select_size
=
read_u8
();
auto
select_size
=
compat_read
<
uint8_t
,
uint32_t
>
();
std
::
vector
<
std
::
string
>
select_specs
;
std
::
vector
<
std
::
string
>
select_specs
;
select_specs
.
reserve
(
select_size
);
select_specs
.
reserve
(
select_size
);
...
@@ -3417,9 +3617,9 @@ private:
...
@@ -3417,9 +3617,9 @@ private:
std
::
vector
<
Card
>
cards
;
std
::
vector
<
Card
>
cards
;
for
(
int
i
=
0
;
i
<
select_size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
select_size
;
++
i
)
{
auto
code
=
read_u32
();
auto
code
=
read_u32
();
auto
loc
=
read_u32
();
auto
loc
_info
=
read_loc_info
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
loc
);
card
.
set_location
(
loc
_info
);
cards
.
push_back
(
card
);
cards
.
push_back
(
card
);
}
}
auto
pl
=
players_
[
player
];
auto
pl
=
players_
[
player
];
...
@@ -3433,19 +3633,20 @@ private:
...
@@ -3433,19 +3633,20 @@ private:
}
else
{
}
else
{
for
(
int
i
=
0
;
i
<
select_size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
select_size
;
++
i
)
{
dp_
+=
4
;
dp_
+=
4
;
auto
controller
=
read_u8
();
auto
loc_info
=
read_loc_info
();
auto
loc
=
read_u8
();
auto
spec
=
ls_to_spec
(
loc_info
,
player
);
auto
seq
=
read_u8
();
auto
pos
=
read_u8
();
auto
spec
=
ls_to_spec
(
loc
,
seq
,
pos
,
controller
!=
player
);
select_specs
.
push_back
(
spec
);
select_specs
.
push_back
(
spec
);
}
}
}
}
auto
unselect_size
=
read_u8
();
auto
unselect_size
=
compat_read
<
uint8_t
,
uint32_t
>
();
// unselect not allowed (no regrets!)
// unselect not allowed (no regrets!)
dp_
+=
8
*
unselect_size
;
if
(
compat_mode_
)
{
dp_
+=
8
*
unselect_size
;
}
else
{
dp_
+=
14
*
unselect_size
;
}
for
(
int
j
=
0
;
j
<
select_specs
.
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
select_specs
.
size
();
++
j
)
{
options_
.
push_back
(
select_specs
[
j
]);
options_
.
push_back
(
select_specs
[
j
]);
...
@@ -3458,22 +3659,35 @@ private:
...
@@ -3458,22 +3659,35 @@ private:
// cancelable and finishable not needed
// cancelable and finishable not needed
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
if
(
compat_mode_
)
{
if
(
options_
[
idx
]
==
"f"
)
{
callback_
=
[
this
](
int
idx
)
{
OCG_SetResponsei
(
pduel_
,
-
1
);
if
(
options_
[
idx
]
==
"f"
)
{
}
else
{
YGO_SetResponsei
(
pduel_
,
-
1
);
resp_buf_
[
0
]
=
1
;
}
else
{
resp_buf_
[
1
]
=
idx
;
resp_buf_
[
0
]
=
1
;
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
resp_buf_
[
1
]
=
idx
;
}
YGO_SetResponseb
(
pduel_
,
resp_buf_
);
};
}
};
}
else
{
callback_
=
[
this
](
int
idx
)
{
if
(
options_
[
idx
]
==
"f"
)
{
YGO_SetResponsei
(
pduel_
,
-
1
);
}
else
{
uint32_t
ret
=
1
;
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
uint32_t
v
=
idx
;
memcpy
(
resp_buf_
+
4
,
&
v
,
sizeof
(
v
));
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
8
);
}
};
}
}
else
if
(
msg_
==
MSG_SELECT_CARD
)
{
}
else
if
(
msg_
==
MSG_SELECT_CARD
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
bool
cancelable
=
read_u8
();
bool
cancelable
=
read_u8
();
auto
min
=
read_u8
();
auto
min
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
max
=
read_u8
();
auto
max
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
size
=
read_u8
();
auto
size
=
compat_read
<
uint8_t
,
uint32_t
>
();
std
::
vector
<
std
::
string
>
specs
;
std
::
vector
<
std
::
string
>
specs
;
specs
.
reserve
(
size
);
specs
.
reserve
(
size
);
...
@@ -3481,9 +3695,8 @@ private:
...
@@ -3481,9 +3695,8 @@ private:
std
::
vector
<
Card
>
cards
;
std
::
vector
<
Card
>
cards
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
auto
code
=
read_u32
();
auto
code
=
read_u32
();
auto
loc
=
read_u32
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
loc
);
card
.
set_location
(
read_loc_info
()
);
cards
.
push_back
(
card
);
cards
.
push_back
(
card
);
}
}
auto
pl
=
players_
[
player
];
auto
pl
=
players_
[
player
];
...
@@ -3501,11 +3714,8 @@ private:
...
@@ -3501,11 +3714,8 @@ private:
}
else
{
}
else
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
dp_
+=
4
;
dp_
+=
4
;
auto
controller
=
read_u8
();
loc_info
info
=
read_loc_info
();
auto
loc
=
read_u8
();
auto
spec
=
ls_to_spec
(
info
,
player
);
auto
seq
=
read_u8
();
auto
pos
=
read_u8
();
auto
spec
=
ls_to_spec
(
loc
,
seq
,
pos
,
controller
!=
player
);
specs
.
push_back
(
spec
);
specs
.
push_back
(
spec
);
}
}
}
}
...
@@ -3520,7 +3730,7 @@ private:
...
@@ -3520,7 +3730,7 @@ private:
for
(
int
i
=
0
;
i
<
min
;
++
i
)
{
for
(
int
i
=
0
;
i
<
min
;
++
i
)
{
resp_buf_
[
i
+
1
]
=
comb
[
i
];
resp_buf_
[
i
+
1
]
=
comb
[
i
];
}
}
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
discard_hand_
=
false
;
discard_hand_
=
false
;
return
;
return
;
}
}
...
@@ -3540,7 +3750,7 @@ private:
...
@@ -3540,7 +3750,7 @@ private:
spec_
.
config
[
"max_multi_select"
_
]));
spec_
.
config
[
"max_multi_select"
_
]));
}
}
max
=
std
::
min
(
max
,
uint
8
_t
(
spec_
.
config
[
"max_multi_select"
_
]));
max
=
std
::
min
(
max
,
uint
32
_t
(
spec_
.
config
[
"max_multi_select"
_
]));
std
::
vector
<
std
::
vector
<
int
>>
combs
;
std
::
vector
<
std
::
vector
<
int
>>
combs
;
for
(
int
i
=
min
;
i
<=
max
;
++
i
)
{
for
(
int
i
=
min
;
i
<=
max
;
++
i
)
{
...
@@ -3558,20 +3768,34 @@ private:
...
@@ -3558,20 +3768,34 @@ private:
}
}
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
,
combs
](
int
idx
)
{
if
(
compat_mode_
)
{
const
auto
&
comb
=
combs
[
idx
];
callback_
=
[
this
,
combs
](
int
idx
)
{
resp_buf_
[
0
]
=
comb
.
size
();
const
auto
&
comb
=
combs
[
idx
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
resp_buf_
[
0
]
=
comb
.
size
();
resp_buf_
[
i
+
1
]
=
comb
[
i
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
}
resp_buf_
[
i
+
1
]
=
comb
[
i
];
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
}
};
YGO_SetResponseb
(
pduel_
,
resp_buf_
);
};
}
else
{
callback_
=
[
this
,
combs
](
int
idx
)
{
int32_t
ret
=
3
;
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
uint8_t
v
=
0
;
const
auto
&
comb
=
combs
[
idx
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
v
|=
(
1
<<
comb
[
i
]);
}
memcpy
(
resp_buf_
+
4
,
&
v
,
sizeof
(
v
));
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
5
);
};
}
}
else
if
(
msg_
==
MSG_SELECT_TRIBUTE
)
{
}
else
if
(
msg_
==
MSG_SELECT_TRIBUTE
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
bool
cancelable
=
read_u8
();
bool
cancelable
=
read_u8
();
auto
min
=
read_u8
();
auto
min
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
max
=
read_u8
();
auto
max
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
size
=
read_u8
();
auto
size
=
compat_read
<
uint8_t
,
uint32_t
>
();
if
(
max
>
3
)
{
if
(
max
>
3
)
{
throw
std
::
runtime_error
(
"Max > 3 not implemented for select tribute"
);
throw
std
::
runtime_error
(
"Max > 3 not implemented for select tribute"
);
...
@@ -3587,7 +3811,7 @@ private:
...
@@ -3587,7 +3811,7 @@ private:
auto
code
=
read_u32
();
auto
code
=
read_u32
();
auto
controller
=
read_u8
();
auto
controller
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
auto
seq
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
release_param
=
read_u8
();
auto
release_param
=
read_u8
();
Card
card
=
get_card
(
controller
,
loc
,
seq
);
Card
card
=
get_card
(
controller
,
loc
,
seq
);
cards
.
push_back
(
card
);
cards
.
push_back
(
card
);
...
@@ -3607,7 +3831,7 @@ private:
...
@@ -3607,7 +3831,7 @@ private:
dp_
+=
4
;
dp_
+=
4
;
auto
controller
=
read_u8
();
auto
controller
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
auto
seq
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
release_param
=
read_u8
();
auto
release_param
=
read_u8
();
auto
spec
=
ls_to_spec
(
loc
,
seq
,
0
,
controller
!=
player
);
auto
spec
=
ls_to_spec
(
loc
,
seq
,
0
,
controller
!=
player
);
...
@@ -3644,21 +3868,42 @@ private:
...
@@ -3644,21 +3868,42 @@ private:
}
}
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
,
combs
](
int
idx
)
{
if
(
compat_mode_
)
{
const
auto
&
comb
=
combs
[
idx
];
callback_
=
[
this
,
combs
](
int
idx
)
{
resp_buf_
[
0
]
=
comb
.
size
();
const
auto
&
comb
=
combs
[
idx
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
resp_buf_
[
0
]
=
comb
.
size
();
resp_buf_
[
i
+
1
]
=
comb
[
i
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
}
resp_buf_
[
i
+
1
]
=
comb
[
i
];
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
}
};
YGO_SetResponseb
(
pduel_
,
resp_buf_
);
};
}
else
{
callback_
=
[
this
,
combs
](
int
idx
)
{
int32_t
ret
=
3
;
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
uint8_t
v
=
0
;
const
auto
&
comb
=
combs
[
idx
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
v
|=
(
1
<<
comb
[
i
]);
}
memcpy
(
resp_buf_
+
4
,
&
v
,
sizeof
(
v
));
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
5
);
};
}
}
else
if
(
msg_
==
MSG_SELECT_SUM
)
{
}
else
if
(
msg_
==
MSG_SELECT_SUM
)
{
auto
mode
=
read_u8
();
uint8_t
mode
;
auto
player
=
read_u8
();
uint8_t
player
;
if
(
compat_mode_
)
{
mode
=
read_u8
();
player
=
read_u8
();
}
else
{
player
=
read_u8
();
mode
=
read_u8
();
}
auto
val
=
read_u32
();
auto
val
=
read_u32
();
int
min
=
read_u8
();
int
min
=
compat_read
<
uint8_t
,
uint32_t
>
();
int
max
=
read_u8
();
int
max
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
must_select_size
=
read_u8
();
auto
must_select_size
=
compat_read
<
uint8_t
,
uint32_t
>
();
if
(
mode
==
0
)
{
if
(
mode
==
0
)
{
if
(
must_select_size
!=
1
)
{
if
(
must_select_size
!=
1
)
{
...
@@ -3687,7 +3932,13 @@ private:
...
@@ -3687,7 +3932,13 @@ private:
auto
code
=
read_u32
();
auto
code
=
read_u32
();
auto
controller
=
read_u8
();
auto
controller
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
uint32_t
seq
;
if
(
compat_mode_
)
{
seq
=
read_u8
();
}
else
{
seq
=
read_u32
();
dp_
+=
4
;
}
auto
param
=
read_u32
();
auto
param
=
read_u32
();
Card
card
=
get_card
(
controller
,
loc
,
seq
);
Card
card
=
get_card
(
controller
,
loc
,
seq
);
must_select
.
push_back
(
card
);
must_select
.
push_back
(
card
);
...
@@ -3708,7 +3959,13 @@ private:
...
@@ -3708,7 +3959,13 @@ private:
dp_
+=
4
;
dp_
+=
4
;
auto
controller
=
read_u8
();
auto
controller
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
uint32_t
seq
;
if
(
compat_mode_
)
{
seq
=
read_u8
();
}
else
{
seq
=
read_u32
();
dp_
+=
4
;
}
auto
param
=
read_u32
();
auto
param
=
read_u32
();
auto
spec
=
ls_to_spec
(
loc
,
seq
,
0
,
controller
!=
player
);
auto
spec
=
ls_to_spec
(
loc
,
seq
,
0
,
controller
!=
player
);
...
@@ -3718,7 +3975,7 @@ private:
...
@@ -3718,7 +3975,7 @@ private:
expected
=
int
(
val
)
-
(
must_select_params
[
0
]
&
0xff
);
expected
=
int
(
val
)
-
(
must_select_params
[
0
]
&
0xff
);
}
}
uint8_t
select_size
=
read_u8
();
uint8_t
select_size
=
compat_read
<
uint8_t
,
uint32_t
>
();
select_params
.
reserve
(
select_size
);
select_params
.
reserve
(
select_size
);
select_specs
.
reserve
(
select_size
);
select_specs
.
reserve
(
select_size
);
...
@@ -3729,7 +3986,13 @@ private:
...
@@ -3729,7 +3986,13 @@ private:
auto
code
=
read_u32
();
auto
code
=
read_u32
();
auto
controller
=
read_u8
();
auto
controller
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
uint32_t
seq
;
if
(
compat_mode_
)
{
seq
=
read_u8
();
}
else
{
seq
=
read_u32
();
dp_
+=
4
;
}
auto
param
=
read_u32
();
auto
param
=
read_u32
();
Card
card
=
get_card
(
controller
,
loc
,
seq
);
Card
card
=
get_card
(
controller
,
loc
,
seq
);
select
.
push_back
(
card
);
select
.
push_back
(
card
);
...
@@ -3746,7 +4009,13 @@ private:
...
@@ -3746,7 +4009,13 @@ private:
dp_
+=
4
;
dp_
+=
4
;
auto
controller
=
read_u8
();
auto
controller
=
read_u8
();
auto
loc
=
read_u8
();
auto
loc
=
read_u8
();
auto
seq
=
read_u8
();
uint32_t
seq
;
if
(
compat_mode_
)
{
seq
=
read_u8
();
}
else
{
seq
=
read_u32
();
dp_
+=
4
;
}
auto
param
=
read_u32
();
auto
param
=
read_u32
();
auto
spec
=
ls_to_spec
(
loc
,
seq
,
0
,
controller
!=
player
);
auto
spec
=
ls_to_spec
(
loc
,
seq
,
0
,
controller
!=
player
);
...
@@ -3784,24 +4053,51 @@ private:
...
@@ -3784,24 +4053,51 @@ private:
}
}
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
,
combs
,
must_select_size
](
int
idx
)
{
if
(
compat_mode_
)
{
const
auto
&
comb
=
combs
[
idx
];
callback_
=
[
this
,
combs
,
must_select_size
](
int
idx
)
{
resp_buf_
[
0
]
=
must_select_size
+
comb
.
size
();
const
auto
&
comb
=
combs
[
idx
];
for
(
int
i
=
0
;
i
<
must_select_size
;
++
i
)
{
resp_buf_
[
0
]
=
must_select_size
+
comb
.
size
();
resp_buf_
[
i
+
1
]
=
0
;
for
(
int
i
=
0
;
i
<
must_select_size
;
++
i
)
{
}
resp_buf_
[
i
+
1
]
=
0
;
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
}
resp_buf_
[
i
+
must_select_size
+
1
]
=
comb
[
i
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
}
resp_buf_
[
i
+
must_select_size
+
1
]
=
comb
[
i
];
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
}
};
YGO_SetResponseb
(
pduel_
,
resp_buf_
);
};
}
else
{
callback_
=
[
this
,
combs
,
must_select_size
](
int
idx
)
{
int32_t
ret
=
3
;
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
uint8_t
v
=
0
;
const
auto
&
comb
=
combs
[
idx
];
// TODO: support more than 8 cards
if
(
must_select_size
+
comb
.
size
()
>
8
)
{
throw
std
::
runtime_error
(
"must_select_size + comb.size() > 8"
);
}
// for (int i = 0; i < must_select_size; ++i) {
// v |= (1 << i);
// }
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
v
|=
(
1
<<
(
comb
[
i
]));
}
memcpy
(
resp_buf_
+
4
,
&
v
,
sizeof
(
v
));
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
5
);
};
}
}
else
if
(
msg_
==
MSG_SELECT_CHAIN
)
{
}
else
if
(
msg_
==
MSG_SELECT_CHAIN
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
size
=
read_u8
();
uint32_t
size
;
if
(
compat_mode_
)
{
size
=
read_u8
();
}
auto
spe_count
=
read_u8
();
auto
spe_count
=
read_u8
();
bool
forced
=
read_u8
();
bool
forced
=
read_u8
();
dp_
+=
8
;
dp_
+=
8
;
if
(
!
compat_mode_
)
{
size
=
read_u32
();
}
// auto hint_timing = read_u32();
// auto hint_timing = read_u32();
// auto other_timing = read_u32();
// auto other_timing = read_u32();
...
@@ -3809,12 +4105,15 @@ private:
...
@@ -3809,12 +4105,15 @@ private:
std
::
vector
<
uint32_t
>
descs
;
std
::
vector
<
uint32_t
>
descs
;
std
::
vector
<
uint32_t
>
spec_codes
;
std
::
vector
<
uint32_t
>
spec_codes
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
auto
et
=
read_u8
();
uint8_t
flag
;
if
(
compat_mode_
)
{
flag
=
read_u8
();
}
CardCode
code
=
read_u32
();
CardCode
code
=
read_u32
();
auto
loc_info
=
read_loc_info
();
if
(
verbose_
)
{
if
(
verbose_
)
{
uint32_t
loc
=
read_u32
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
loc
);
card
.
set_location
(
loc
_info
);
cards
.
push_back
(
card
);
cards
.
push_back
(
card
);
spec_codes
.
push_back
(
card
.
get_spec_code
(
player
));
spec_codes
.
push_back
(
card
.
get_spec_code
(
player
));
}
else
{
}
else
{
...
@@ -3822,10 +4121,14 @@ private:
...
@@ -3822,10 +4121,14 @@ private:
uint8_t
loc
=
read_u8
();
uint8_t
loc
=
read_u8
();
uint8_t
seq
=
read_u8
();
uint8_t
seq
=
read_u8
();
uint8_t
pos
=
read_u8
();
uint8_t
pos
=
read_u8
();
spec_codes
.
push_back
(
ls_to_spec_code
(
loc
,
seq
,
pos
,
c
!=
player
));
spec_codes
.
push_back
(
ls_to_spec_code
(
loc_info
,
player
));
}
}
uint32_t
desc
=
read_u32
();
uint32_t
desc
=
compat_read
<
uint32_t
,
uint64_t
>
();
descs
.
push_back
(
desc
);
descs
.
push_back
(
desc
);
if
(
!
compat_mode_
)
{
flag
=
read_u8
();
}
}
}
if
((
size
==
0
)
&&
(
spe_count
==
0
))
{
if
((
size
==
0
)
&&
(
spe_count
==
0
))
{
...
@@ -3833,7 +4136,7 @@ private:
...
@@ -3833,7 +4136,7 @@ private:
// if (verbose_) {
// if (verbose_) {
// fmt::println("keep processing");
// fmt::println("keep processing");
// }
// }
OCG
_SetResponsei
(
pduel_
,
-
1
);
YGO
_SetResponsei
(
pduel_
,
-
1
);
return
;
return
;
}
}
...
@@ -3898,10 +4201,10 @@ private:
...
@@ -3898,10 +4201,10 @@ private:
callback_
=
[
this
,
forced
](
int
idx
)
{
callback_
=
[
this
,
forced
](
int
idx
)
{
const
auto
&
option
=
options_
[
idx
];
const
auto
&
option
=
options_
[
idx
];
if
((
option
==
"c"
)
&&
(
!
forced
))
{
if
((
option
==
"c"
)
&&
(
!
forced
))
{
OCG
_SetResponsei
(
pduel_
,
-
1
);
YGO
_SetResponsei
(
pduel_
,
-
1
);
return
;
return
;
}
}
OCG
_SetResponsei
(
pduel_
,
idx
);
YGO
_SetResponsei
(
pduel_
,
idx
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_YESNO
)
{
}
else
if
(
msg_
==
MSG_SELECT_YESNO
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -3932,9 +4235,9 @@ private:
...
@@ -3932,9 +4235,9 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
if
(
idx
==
0
)
{
if
(
idx
==
0
)
{
OCG
_SetResponsei
(
pduel_
,
1
);
YGO
_SetResponsei
(
pduel_
,
1
);
}
else
if
(
idx
==
1
)
{
}
else
if
(
idx
==
1
)
{
OCG
_SetResponsei
(
pduel_
,
0
);
YGO
_SetResponsei
(
pduel_
,
0
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option"
);
throw
std
::
runtime_error
(
"Invalid option"
);
}
}
...
@@ -3945,10 +4248,10 @@ private:
...
@@ -3945,10 +4248,10 @@ private:
std
::
string
spec
;
std
::
string
spec
;
if
(
verbose_
)
{
if
(
verbose_
)
{
CardCode
code
=
read_u32
();
CardCode
code
=
read_u32
();
uint32_t
loc
=
read_u32
();
auto
loc_info
=
read_loc_info
();
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
loc
);
card
.
set_location
(
loc
_info
);
auto
desc
=
read_u32
();
auto
desc
=
compat_read
<
uint32_t
,
uint64_t
>
();
auto
pl
=
players_
[
player
];
auto
pl
=
players_
[
player
];
spec
=
card
.
get_spec
(
player
);
spec
=
card
.
get_spec
(
player
);
auto
name
=
card
.
name_
;
auto
name
=
card
.
name_
;
...
@@ -3995,20 +4298,17 @@ private:
...
@@ -3995,20 +4298,17 @@ private:
pl
->
notify
(
"Please enter y or n."
);
pl
->
notify
(
"Please enter y or n."
);
}
else
{
}
else
{
dp_
+=
4
;
dp_
+=
4
;
auto
c
=
read_u8
();
auto
loc_info
=
read_loc_info
();
auto
loc
=
read_u8
();
compat_read
<
uint32_t
,
uint64_t
>
();
auto
seq
=
read_u8
();
spec
=
ls_to_spec
(
loc_info
,
player
);
auto
pos
=
read_u8
();
dp_
+=
4
;
spec
=
ls_to_spec
(
loc
,
seq
,
pos
,
c
!=
player
);
}
}
options_
=
{
"y "
+
spec
,
"n "
+
spec
};
options_
=
{
"y "
+
spec
,
"n "
+
spec
};
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
if
(
idx
==
0
)
{
if
(
idx
==
0
)
{
OCG
_SetResponsei
(
pduel_
,
1
);
YGO
_SetResponsei
(
pduel_
,
1
);
}
else
if
(
idx
==
1
)
{
}
else
if
(
idx
==
1
)
{
OCG
_SetResponsei
(
pduel_
,
0
);
YGO
_SetResponsei
(
pduel_
,
0
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option"
);
throw
std
::
runtime_error
(
"Invalid option"
);
}
}
...
@@ -4048,16 +4348,16 @@ private:
...
@@ -4048,16 +4348,16 @@ private:
"."
);
"."
);
}
}
OCG
_SetResponsei
(
pduel_
,
idx
);
YGO
_SetResponsei
(
pduel_
,
idx
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_IDLECMD
)
{
}
else
if
(
msg_
==
MSG_SELECT_IDLECMD
)
{
int32_t
player
=
read_u8
();
int32_t
player
=
read_u8
();
auto
summonable_
=
read_cardlist_spec
();
auto
summonable_
=
read_cardlist_spec
();
auto
spsummon_
=
read_cardlist_spec
();
auto
spsummon_
=
read_cardlist_spec
();
auto
repos_
=
read_cardlist_spec
();
auto
repos_
=
read_cardlist_spec
(
false
);
auto
idle_mset_
=
read_cardlist_spec
();
auto
idle_mset_
=
read_cardlist_spec
();
auto
idle_set_
=
read_cardlist_spec
();
auto
idle_set_
=
read_cardlist_spec
();
auto
idle_activate_
=
read_cardlist_spec
(
true
);
auto
idle_activate_
=
read_cardlist_spec
(
true
,
true
);
bool
to_bp_
=
read_u8
();
bool
to_bp_
=
read_u8
();
bool
to_ep_
=
read_u8
();
bool
to_ep_
=
read_u8
();
read_u8
();
// can_shuffle
read_u8
();
// can_shuffle
...
@@ -4162,29 +4462,29 @@ private:
...
@@ -4162,29 +4462,29 @@ private:
const
auto
&
option
=
options_
[
idx
];
const
auto
&
option
=
options_
[
idx
];
char
cmd
=
option
[
0
];
char
cmd
=
option
[
0
];
if
(
cmd
==
'b'
)
{
if
(
cmd
==
'b'
)
{
OCG
_SetResponsei
(
pduel_
,
6
);
YGO
_SetResponsei
(
pduel_
,
6
);
}
else
if
(
cmd
==
'e'
)
{
}
else
if
(
cmd
==
'e'
)
{
OCG
_SetResponsei
(
pduel_
,
7
);
YGO
_SetResponsei
(
pduel_
,
7
);
}
else
{
}
else
{
auto
spec
=
option
.
substr
(
2
);
auto
spec
=
option
.
substr
(
2
);
if
(
cmd
==
's'
)
{
if
(
cmd
==
's'
)
{
uint32_t
idx_
=
idx
;
uint32_t
idx_
=
idx
;
OCG
_SetResponsei
(
pduel_
,
idx_
<<
16
);
YGO
_SetResponsei
(
pduel_
,
idx_
<<
16
);
}
else
if
(
cmd
==
'c'
)
{
}
else
if
(
cmd
==
'c'
)
{
uint32_t
idx_
=
idx
-
spsummon_offset
;
uint32_t
idx_
=
idx
-
spsummon_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
1
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
1
);
}
else
if
(
cmd
==
'r'
)
{
}
else
if
(
cmd
==
'r'
)
{
uint32_t
idx_
=
idx
-
repos_offset
;
uint32_t
idx_
=
idx
-
repos_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
2
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
2
);
}
else
if
(
cmd
==
'm'
)
{
}
else
if
(
cmd
==
'm'
)
{
uint32_t
idx_
=
idx
-
mset_offset
;
uint32_t
idx_
=
idx
-
mset_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
3
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
3
);
}
else
if
(
cmd
==
't'
)
{
}
else
if
(
cmd
==
't'
)
{
uint32_t
idx_
=
idx
-
set_offset
;
uint32_t
idx_
=
idx
-
set_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
4
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
4
);
}
else
if
(
cmd
==
'v'
)
{
}
else
if
(
cmd
==
'v'
)
{
uint32_t
idx_
=
idx
-
activate_offset
;
uint32_t
idx_
=
idx
-
activate_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
5
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
5
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option: "
+
option
);
throw
std
::
runtime_error
(
"Invalid option: "
+
option
);
}
}
...
@@ -4224,7 +4524,7 @@ private:
...
@@ -4224,7 +4524,7 @@ private:
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
2
]
=
seq
;
resp_buf_
[
2
]
=
seq
;
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
3
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_DISFIELD
)
{
}
else
if
(
msg_
==
MSG_SELECT_DISFIELD
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -4260,7 +4560,7 @@ private:
...
@@ -4260,7 +4560,7 @@ private:
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
2
]
=
seq
;
resp_buf_
[
2
]
=
seq
;
OCG_SetResponseb
(
pduel_
,
resp_buf_
);
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
3
);
};
};
}
else
if
(
msg_
==
MSG_ANNOUNCE_NUMBER
)
{
}
else
if
(
msg_
==
MSG_ANNOUNCE_NUMBER
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -4289,7 +4589,7 @@ private:
...
@@ -4289,7 +4589,7 @@ private:
}
}
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
OCG
_SetResponsei
(
pduel_
,
idx
);
YGO
_SetResponsei
(
pduel_
,
idx
);
};
};
}
else
if
(
msg_
==
MSG_ANNOUNCE_ATTRIB
)
{
}
else
if
(
msg_
==
MSG_ANNOUNCE_ATTRIB
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -4341,7 +4641,7 @@ private:
...
@@ -4341,7 +4641,7 @@ private:
resp
|=
1
<<
(
option
[
i
]
-
'1'
);
resp
|=
1
<<
(
option
[
i
]
-
'1'
);
i
+=
2
;
i
+=
2
;
}
}
OCG
_SetResponsei
(
pduel_
,
resp
);
YGO
_SetResponsei
(
pduel_
,
resp
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_POSITION
)
{
}
else
if
(
msg_
==
MSG_SELECT_POSITION
)
{
...
@@ -4373,7 +4673,7 @@ private:
...
@@ -4373,7 +4673,7 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
uint8_t
pos
=
options_
[
idx
][
0
]
-
'1'
;
uint8_t
pos
=
options_
[
idx
][
0
]
-
'1'
;
OCG
_SetResponsei
(
pduel_
,
1
<<
pos
);
YGO
_SetResponsei
(
pduel_
,
1
<<
pos
);
};
};
}
else
{
}
else
{
show_deck
(
0
);
show_deck
(
0
);
...
@@ -4409,7 +4709,7 @@ private:
...
@@ -4409,7 +4709,7 @@ private:
win_reason_
=
reason
;
win_reason_
=
reason
;
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
OCG
_EndDuel
(
pduel_
);
YGO
_EndDuel
(
pduel_
);
ulock
.
unlock
();
ulock
.
unlock
();
duel_started_
=
false
;
duel_started_
=
false
;
...
...
ygoenv/ygoenv/entry.py
View file @
2d2b1ceb
...
@@ -19,6 +19,12 @@ except ImportError:
...
@@ -19,6 +19,12 @@ except ImportError:
pass
pass
try
:
import
ygoenv.edopro.registration
# noqa: F401
except
ImportError
:
pass
try
:
try
:
import
ygoenv.dummy.registration
# noqa: F401
import
ygoenv.dummy.registration
# noqa: F401
except
ImportError
:
except
ImportError
:
...
...
ygoenv/ygoenv/ygopro/ygopro.h
View file @
2d2b1ceb
...
@@ -1460,7 +1460,7 @@ public:
...
@@ -1460,7 +1460,7 @@ public:
auto
duel_seed
=
dist_int_
(
gen_
);
auto
duel_seed
=
dist_int_
(
gen_
);
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
pduel_
=
OCG
_CreateDuel
(
duel_seed
);
YGO
_CreateDuel
(
duel_seed
);
ulock
.
unlock
();
ulock
.
unlock
();
int
init_lp
=
8000
;
int
init_lp
=
8000
;
...
@@ -1483,7 +1483,7 @@ public:
...
@@ -1483,7 +1483,7 @@ public:
}
else
{
}
else
{
players_
[
i
]
=
new
GreedyAI
(
nickname_
[
i
],
init_lp
,
i
,
verbose_
);
players_
[
i
]
=
new
GreedyAI
(
nickname_
[
i
],
init_lp
,
i
,
verbose_
);
}
}
OCG
_SetPlayerInfo
(
pduel_
,
i
,
init_lp
,
startcount
,
drawcount
);
YGO
_SetPlayerInfo
(
pduel_
,
i
,
init_lp
,
startcount
,
drawcount
);
load_deck
(
i
);
load_deck
(
i
);
lp_
[
i
]
=
players_
[
i
]
->
init_lp_
;
lp_
[
i
]
=
players_
[
i
]
->
init_lp_
;
}
}
...
@@ -1553,7 +1553,7 @@ public:
...
@@ -1553,7 +1553,7 @@ public:
}
}
OCG
_StartDuel
(
pduel_
,
duel_options_
);
YGO
_StartDuel
(
pduel_
,
duel_options_
);
duel_started_
=
true
;
duel_started_
=
true
;
winner_
=
255
;
winner_
=
255
;
win_reason_
=
255
;
win_reason_
=
255
;
...
@@ -1719,7 +1719,7 @@ private:
...
@@ -1719,7 +1719,7 @@ private:
hidden_for_opponent
=
false
;
hidden_for_opponent
=
false
;
}
}
if
(
opponent
&&
hidden_for_opponent
)
{
if
(
opponent
&&
hidden_for_opponent
)
{
auto
n_cards
=
OCG
_QueryFieldCount
(
pduel_
,
player
,
location
);
auto
n_cards
=
YGO
_QueryFieldCount
(
pduel_
,
player
,
location
);
for
(
auto
i
=
0
;
i
<
n_cards
;
i
++
)
{
for
(
auto
i
=
0
;
i
<
n_cards
;
i
++
)
{
f_cards
(
offset
,
2
)
=
location2id
.
at
(
location
);
f_cards
(
offset
,
2
)
=
location2id
.
at
(
location
);
f_cards
(
offset
,
4
)
=
1
;
f_cards
(
offset
,
4
)
=
1
;
...
@@ -2067,48 +2067,48 @@ private:
...
@@ -2067,48 +2067,48 @@ private:
}
}
// ygopro-core API
// ygopro-core API
intptr_t
OCG
_CreateDuel
(
uint32_t
seed
)
{
void
YGO
_CreateDuel
(
uint32_t
seed
)
{
std
::
mt19937
rnd
(
seed
);
std
::
mt19937
rnd
(
seed
);
return
create_duel
(
rnd
());
pduel_
=
create_duel
(
rnd
());
}
}
void
OCG
_SetPlayerInfo
(
intptr_t
pduel
,
int32
playerid
,
int32
lp
,
int32
startcount
,
int32
drawcount
)
{
void
YGO
_SetPlayerInfo
(
intptr_t
pduel
,
int32
playerid
,
int32
lp
,
int32
startcount
,
int32
drawcount
)
{
set_player_info
(
pduel
,
playerid
,
lp
,
startcount
,
drawcount
);
set_player_info
(
pduel
,
playerid
,
lp
,
startcount
,
drawcount
);
}
}
void
OCG
_NewCard
(
intptr_t
pduel
,
uint32
code
,
uint8
owner
,
uint8
playerid
,
uint8
location
,
uint8
sequence
,
uint8
position
)
{
void
YGO
_NewCard
(
intptr_t
pduel
,
uint32
code
,
uint8
owner
,
uint8
playerid
,
uint8
location
,
uint8
sequence
,
uint8
position
)
{
new_card
(
pduel
,
code
,
owner
,
playerid
,
location
,
sequence
,
position
);
new_card
(
pduel
,
code
,
owner
,
playerid
,
location
,
sequence
,
position
);
}
}
void
OCG
_StartDuel
(
intptr_t
pduel
,
int32
options
)
{
void
YGO
_StartDuel
(
intptr_t
pduel
,
int32
options
)
{
start_duel
(
pduel
,
options
);
start_duel
(
pduel
,
options
);
}
}
void
OCG
_EndDuel
(
intptr_t
pduel
)
{
void
YGO
_EndDuel
(
intptr_t
pduel
)
{
end_duel
(
pduel
);
end_duel
(
pduel
);
}
}
int32
OCG
_GetMessage
(
intptr_t
pduel
,
byte
*
buf
)
{
int32
YGO
_GetMessage
(
intptr_t
pduel
,
byte
*
buf
)
{
return
get_message
(
pduel
,
buf
);
return
get_message
(
pduel
,
buf
);
}
}
uint32
OCG
_Process
(
intptr_t
pduel
)
{
uint32
YGO
_Process
(
intptr_t
pduel
)
{
return
process
(
pduel
);
return
process
(
pduel
);
}
}
int32
OCG_QueryCard
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
,
uint8
sequence
,
int32
query_flag
,
byte
*
buf
,
int32
use_cache
)
{
int32
YGO_QueryCard
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
,
uint8
sequence
,
int32
query_flag
,
byte
*
buf
)
{
return
query_card
(
pduel
,
playerid
,
location
,
sequence
,
query_flag
,
buf
,
use_cache
);
return
query_card
(
pduel
,
playerid
,
location
,
sequence
,
query_flag
,
buf
,
0
);
}
}
int32
OCG
_QueryFieldCount
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
)
{
int32
YGO
_QueryFieldCount
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
)
{
return
query_field_count
(
pduel
,
playerid
,
location
);
return
query_field_count
(
pduel
,
playerid
,
location
);
}
}
int32
OCG_QueryFieldCard
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
,
uint32
query_flag
,
byte
*
buf
,
int32
use_cache
)
{
int32
YGO_QueryFieldCard
(
intptr_t
pduel
,
uint8
playerid
,
uint8
location
,
uint32
query_flag
,
byte
*
buf
)
{
return
query_field_card
(
pduel
,
playerid
,
location
,
query_flag
,
buf
,
use_cache
);
return
query_field_card
(
pduel
,
playerid
,
location
,
query_flag
,
buf
,
0
);
}
}
void
OCG
_SetResponsei
(
intptr_t
pduel
,
int32
value
)
{
void
YGO
_SetResponsei
(
intptr_t
pduel
,
int32
value
)
{
if
(
record_
)
{
if
(
record_
)
{
ReplayWriteInt8
(
4
);
ReplayWriteInt8
(
4
);
ReplayWriteInt32
(
value
);
ReplayWriteInt32
(
value
);
...
@@ -2116,7 +2116,7 @@ private:
...
@@ -2116,7 +2116,7 @@ private:
set_responsei
(
pduel
,
value
);
set_responsei
(
pduel
,
value
);
}
}
void
OCG
_SetResponseb
(
intptr_t
pduel
,
byte
*
buf
)
{
void
YGO
_SetResponseb
(
intptr_t
pduel
,
byte
*
buf
)
{
if
(
record_
)
{
if
(
record_
)
{
switch
(
msg_
)
{
switch
(
msg_
)
{
case
MSG_SORT_CARD
:
case
MSG_SORT_CARD
:
...
@@ -2245,13 +2245,13 @@ private:
...
@@ -2245,13 +2245,13 @@ private:
// but since we have shuffled deck, so just add in order
// but since we have shuffled deck, so just add in order
for
(
int
i
=
0
;
i
<
main_deck
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
main_deck
.
size
();
i
++
)
{
OCG
_NewCard
(
pduel_
,
main_deck
[
i
],
player
,
player
,
LOCATION_DECK
,
0
,
YGO
_NewCard
(
pduel_
,
main_deck
[
i
],
player
,
player
,
LOCATION_DECK
,
0
,
POS_FACEDOWN_DEFENSE
);
POS_FACEDOWN_DEFENSE
);
}
}
// add extra deck in reverse order following ygopro
// add extra deck in reverse order following ygopro
for
(
int
i
=
int
(
extra_deck
.
size
())
-
1
;
i
>=
0
;
--
i
)
{
for
(
int
i
=
int
(
extra_deck
.
size
())
-
1
;
i
>=
0
;
--
i
)
{
OCG
_NewCard
(
pduel_
,
extra_deck
[
i
],
player
,
player
,
LOCATION_EXTRA
,
0
,
YGO
_NewCard
(
pduel_
,
extra_deck
[
i
],
player
,
player
,
LOCATION_EXTRA
,
0
,
POS_FACEDOWN_DEFENSE
);
POS_FACEDOWN_DEFENSE
);
}
}
}
}
...
@@ -2261,14 +2261,14 @@ private:
...
@@ -2261,14 +2261,14 @@ private:
if
(
eng_flag_
==
PROCESSOR_END
)
{
if
(
eng_flag_
==
PROCESSOR_END
)
{
break
;
break
;
}
}
uint32_t
res
=
OCG
_Process
(
pduel_
);
uint32_t
res
=
YGO
_Process
(
pduel_
);
dl_
=
res
&
PROCESSOR_BUFFER_LEN
;
dl_
=
res
&
PROCESSOR_BUFFER_LEN
;
eng_flag_
=
res
&
PROCESSOR_FLAG
;
eng_flag_
=
res
&
PROCESSOR_FLAG
;
if
(
dl_
==
0
)
{
if
(
dl_
==
0
)
{
continue
;
continue
;
}
}
OCG
_GetMessage
(
pduel_
,
data_
);
YGO
_GetMessage
(
pduel_
,
data_
);
dp_
=
0
;
dp_
=
0
;
while
(
dp_
!=
dl_
)
{
while
(
dp_
!=
dl_
)
{
handle_message
();
handle_message
();
...
@@ -2327,7 +2327,7 @@ private:
...
@@ -2327,7 +2327,7 @@ private:
CardCode
get_card_code
(
PlayerId
player
,
uint8_t
loc
,
uint8_t
seq
)
{
CardCode
get_card_code
(
PlayerId
player
,
uint8_t
loc
,
uint8_t
seq
)
{
int32_t
flags
=
QUERY_CODE
;
int32_t
flags
=
QUERY_CODE
;
int32_t
bl
=
OCG_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
,
0
);
int32_t
bl
=
YGO_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
);
qdp_
=
0
;
qdp_
=
0
;
if
(
bl
<=
0
)
{
if
(
bl
<=
0
)
{
throw
std
::
runtime_error
(
"[get_card_code] Invalid card"
);
throw
std
::
runtime_error
(
"[get_card_code] Invalid card"
);
...
@@ -2340,7 +2340,7 @@ private:
...
@@ -2340,7 +2340,7 @@ private:
int32_t
flags
=
QUERY_CODE
|
QUERY_ATTACK
|
QUERY_DEFENSE
|
QUERY_POSITION
|
int32_t
flags
=
QUERY_CODE
|
QUERY_ATTACK
|
QUERY_DEFENSE
|
QUERY_POSITION
|
QUERY_LEVEL
|
QUERY_RANK
|
QUERY_LSCALE
|
QUERY_RSCALE
|
QUERY_LEVEL
|
QUERY_RANK
|
QUERY_LSCALE
|
QUERY_RSCALE
|
QUERY_LINK
;
QUERY_LINK
;
int32_t
bl
=
OCG_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
,
0
);
int32_t
bl
=
YGO_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
);
qdp_
=
0
;
qdp_
=
0
;
if
(
bl
<=
0
)
{
if
(
bl
<=
0
)
{
throw
std
::
runtime_error
(
"[get_card] Invalid card (bl <= 0)"
);
throw
std
::
runtime_error
(
"[get_card] Invalid card (bl <= 0)"
);
...
@@ -2382,7 +2382,7 @@ private:
...
@@ -2382,7 +2382,7 @@ private:
QUERY_ATTACK
|
QUERY_DEFENSE
|
QUERY_EQUIP_CARD
|
QUERY_ATTACK
|
QUERY_DEFENSE
|
QUERY_EQUIP_CARD
|
QUERY_OVERLAY_CARD
|
QUERY_COUNTERS
|
QUERY_LSCALE
|
QUERY_OVERLAY_CARD
|
QUERY_COUNTERS
|
QUERY_LSCALE
|
QUERY_RSCALE
|
QUERY_LINK
;
QUERY_RSCALE
|
QUERY_LINK
;
int32_t
bl
=
OCG_QueryFieldCard
(
pduel_
,
player
,
loc
,
flags
,
query_buf_
,
0
);
int32_t
bl
=
YGO_QueryFieldCard
(
pduel_
,
player
,
loc
,
flags
,
query_buf_
);
qdp_
=
0
;
qdp_
=
0
;
std
::
vector
<
Card
>
cards
;
std
::
vector
<
Card
>
cards
;
while
(
true
)
{
while
(
true
)
{
...
@@ -2955,7 +2955,7 @@ private:
...
@@ -2955,7 +2955,7 @@ private:
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
dp_
=
dl_
;
dp_
=
dl_
;
resp_buf_
[
0
]
=
255
;
resp_buf_
[
0
]
=
255
;
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
return
;
return
;
}
}
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -2978,7 +2978,7 @@ private:
...
@@ -2978,7 +2978,7 @@ private:
fmt
::
println
(
"sort card action not implemented"
);
fmt
::
println
(
"sort card action not implemented"
);
resp_buf_
[
0
]
=
255
;
resp_buf_
[
0
]
=
255
;
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
// // generate all permutations
// // generate all permutations
// std::vector<int> perm(size);
// std::vector<int> perm(size);
...
@@ -2998,7 +2998,7 @@ private:
...
@@ -2998,7 +2998,7 @@ private:
// const auto &option = options_[idx];
// const auto &option = options_[idx];
// if (option == "c") {
// if (option == "c") {
// resp_buf_[0] = 255;
// resp_buf_[0] = 255;
//
OCG
_SetResponseb(pduel_, resp_buf_);
//
YGO
_SetResponseb(pduel_, resp_buf_);
// return;
// return;
// }
// }
// std::istringstream iss(option);
// std::istringstream iss(option);
...
@@ -3008,7 +3008,7 @@ private:
...
@@ -3008,7 +3008,7 @@ private:
// resp_buf_[i] = uint8_t(x);
// resp_buf_[i] = uint8_t(x);
// i++;
// i++;
// }
// }
//
OCG
_SetResponseb(pduel_, resp_buf_);
//
YGO
_SetResponseb(pduel_, resp_buf_);
// };
// };
}
else
if
(
msg_
==
MSG_ADD_COUNTER
)
{
}
else
if
(
msg_
==
MSG_ADD_COUNTER
)
{
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
...
@@ -3391,14 +3391,14 @@ private:
...
@@ -3391,14 +3391,14 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
,
n_activatables
,
n_attackables
,
to_ep
,
to_m2
](
int
idx
)
{
callback_
=
[
this
,
n_activatables
,
n_attackables
,
to_ep
,
to_m2
](
int
idx
)
{
if
(
idx
<
n_activatables
)
{
if
(
idx
<
n_activatables
)
{
OCG
_SetResponsei
(
pduel_
,
idx
<<
16
);
YGO
_SetResponsei
(
pduel_
,
idx
<<
16
);
}
else
if
(
idx
<
(
n_activatables
+
n_attackables
))
{
}
else
if
(
idx
<
(
n_activatables
+
n_attackables
))
{
idx
=
idx
-
n_activatables
;
idx
=
idx
-
n_activatables
;
OCG
_SetResponsei
(
pduel_
,
(
idx
<<
16
)
+
1
);
YGO
_SetResponsei
(
pduel_
,
(
idx
<<
16
)
+
1
);
}
else
if
((
options_
[
idx
]
==
"e"
)
&&
to_ep
)
{
}
else
if
((
options_
[
idx
]
==
"e"
)
&&
to_ep
)
{
OCG
_SetResponsei
(
pduel_
,
3
);
YGO
_SetResponsei
(
pduel_
,
3
);
}
else
if
((
options_
[
idx
]
==
"m"
)
&&
to_m2
)
{
}
else
if
((
options_
[
idx
]
==
"m"
)
&&
to_m2
)
{
OCG
_SetResponsei
(
pduel_
,
2
);
YGO
_SetResponsei
(
pduel_
,
2
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option"
);
throw
std
::
runtime_error
(
"Invalid option"
);
}
}
...
@@ -3460,11 +3460,11 @@ private:
...
@@ -3460,11 +3460,11 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
if
(
options_
[
idx
]
==
"f"
)
{
if
(
options_
[
idx
]
==
"f"
)
{
OCG
_SetResponsei
(
pduel_
,
-
1
);
YGO
_SetResponsei
(
pduel_
,
-
1
);
}
else
{
}
else
{
resp_buf_
[
0
]
=
1
;
resp_buf_
[
0
]
=
1
;
resp_buf_
[
1
]
=
idx
;
resp_buf_
[
1
]
=
idx
;
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
}
}
};
};
...
@@ -3520,7 +3520,7 @@ private:
...
@@ -3520,7 +3520,7 @@ private:
for
(
int
i
=
0
;
i
<
min
;
++
i
)
{
for
(
int
i
=
0
;
i
<
min
;
++
i
)
{
resp_buf_
[
i
+
1
]
=
comb
[
i
];
resp_buf_
[
i
+
1
]
=
comb
[
i
];
}
}
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
discard_hand_
=
false
;
discard_hand_
=
false
;
return
;
return
;
}
}
...
@@ -3564,7 +3564,7 @@ private:
...
@@ -3564,7 +3564,7 @@ private:
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
resp_buf_
[
i
+
1
]
=
comb
[
i
];
resp_buf_
[
i
+
1
]
=
comb
[
i
];
}
}
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_TRIBUTE
)
{
}
else
if
(
msg_
==
MSG_SELECT_TRIBUTE
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -3650,7 +3650,7 @@ private:
...
@@ -3650,7 +3650,7 @@ private:
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
resp_buf_
[
i
+
1
]
=
comb
[
i
];
resp_buf_
[
i
+
1
]
=
comb
[
i
];
}
}
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_SUM
)
{
}
else
if
(
msg_
==
MSG_SELECT_SUM
)
{
auto
mode
=
read_u8
();
auto
mode
=
read_u8
();
...
@@ -3793,7 +3793,7 @@ private:
...
@@ -3793,7 +3793,7 @@ private:
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
resp_buf_
[
i
+
must_select_size
+
1
]
=
comb
[
i
];
resp_buf_
[
i
+
must_select_size
+
1
]
=
comb
[
i
];
}
}
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_CHAIN
)
{
}
else
if
(
msg_
==
MSG_SELECT_CHAIN
)
{
...
@@ -3833,7 +3833,7 @@ private:
...
@@ -3833,7 +3833,7 @@ private:
// if (verbose_) {
// if (verbose_) {
// fmt::println("keep processing");
// fmt::println("keep processing");
// }
// }
OCG
_SetResponsei
(
pduel_
,
-
1
);
YGO
_SetResponsei
(
pduel_
,
-
1
);
return
;
return
;
}
}
...
@@ -3898,10 +3898,10 @@ private:
...
@@ -3898,10 +3898,10 @@ private:
callback_
=
[
this
,
forced
](
int
idx
)
{
callback_
=
[
this
,
forced
](
int
idx
)
{
const
auto
&
option
=
options_
[
idx
];
const
auto
&
option
=
options_
[
idx
];
if
((
option
==
"c"
)
&&
(
!
forced
))
{
if
((
option
==
"c"
)
&&
(
!
forced
))
{
OCG
_SetResponsei
(
pduel_
,
-
1
);
YGO
_SetResponsei
(
pduel_
,
-
1
);
return
;
return
;
}
}
OCG
_SetResponsei
(
pduel_
,
idx
);
YGO
_SetResponsei
(
pduel_
,
idx
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_YESNO
)
{
}
else
if
(
msg_
==
MSG_SELECT_YESNO
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -3932,9 +3932,9 @@ private:
...
@@ -3932,9 +3932,9 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
if
(
idx
==
0
)
{
if
(
idx
==
0
)
{
OCG
_SetResponsei
(
pduel_
,
1
);
YGO
_SetResponsei
(
pduel_
,
1
);
}
else
if
(
idx
==
1
)
{
}
else
if
(
idx
==
1
)
{
OCG
_SetResponsei
(
pduel_
,
0
);
YGO
_SetResponsei
(
pduel_
,
0
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option"
);
throw
std
::
runtime_error
(
"Invalid option"
);
}
}
...
@@ -4006,9 +4006,9 @@ private:
...
@@ -4006,9 +4006,9 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
if
(
idx
==
0
)
{
if
(
idx
==
0
)
{
OCG
_SetResponsei
(
pduel_
,
1
);
YGO
_SetResponsei
(
pduel_
,
1
);
}
else
if
(
idx
==
1
)
{
}
else
if
(
idx
==
1
)
{
OCG
_SetResponsei
(
pduel_
,
0
);
YGO
_SetResponsei
(
pduel_
,
0
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option"
);
throw
std
::
runtime_error
(
"Invalid option"
);
}
}
...
@@ -4048,7 +4048,7 @@ private:
...
@@ -4048,7 +4048,7 @@ private:
"."
);
"."
);
}
}
OCG
_SetResponsei
(
pduel_
,
idx
);
YGO
_SetResponsei
(
pduel_
,
idx
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_IDLECMD
)
{
}
else
if
(
msg_
==
MSG_SELECT_IDLECMD
)
{
int32_t
player
=
read_u8
();
int32_t
player
=
read_u8
();
...
@@ -4162,29 +4162,29 @@ private:
...
@@ -4162,29 +4162,29 @@ private:
const
auto
&
option
=
options_
[
idx
];
const
auto
&
option
=
options_
[
idx
];
char
cmd
=
option
[
0
];
char
cmd
=
option
[
0
];
if
(
cmd
==
'b'
)
{
if
(
cmd
==
'b'
)
{
OCG
_SetResponsei
(
pduel_
,
6
);
YGO
_SetResponsei
(
pduel_
,
6
);
}
else
if
(
cmd
==
'e'
)
{
}
else
if
(
cmd
==
'e'
)
{
OCG
_SetResponsei
(
pduel_
,
7
);
YGO
_SetResponsei
(
pduel_
,
7
);
}
else
{
}
else
{
auto
spec
=
option
.
substr
(
2
);
auto
spec
=
option
.
substr
(
2
);
if
(
cmd
==
's'
)
{
if
(
cmd
==
's'
)
{
uint32_t
idx_
=
idx
;
uint32_t
idx_
=
idx
;
OCG
_SetResponsei
(
pduel_
,
idx_
<<
16
);
YGO
_SetResponsei
(
pduel_
,
idx_
<<
16
);
}
else
if
(
cmd
==
'c'
)
{
}
else
if
(
cmd
==
'c'
)
{
uint32_t
idx_
=
idx
-
spsummon_offset
;
uint32_t
idx_
=
idx
-
spsummon_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
1
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
1
);
}
else
if
(
cmd
==
'r'
)
{
}
else
if
(
cmd
==
'r'
)
{
uint32_t
idx_
=
idx
-
repos_offset
;
uint32_t
idx_
=
idx
-
repos_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
2
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
2
);
}
else
if
(
cmd
==
'm'
)
{
}
else
if
(
cmd
==
'm'
)
{
uint32_t
idx_
=
idx
-
mset_offset
;
uint32_t
idx_
=
idx
-
mset_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
3
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
3
);
}
else
if
(
cmd
==
't'
)
{
}
else
if
(
cmd
==
't'
)
{
uint32_t
idx_
=
idx
-
set_offset
;
uint32_t
idx_
=
idx
-
set_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
4
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
4
);
}
else
if
(
cmd
==
'v'
)
{
}
else
if
(
cmd
==
'v'
)
{
uint32_t
idx_
=
idx
-
activate_offset
;
uint32_t
idx_
=
idx
-
activate_offset
;
OCG
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
5
);
YGO
_SetResponsei
(
pduel_
,
(
idx_
<<
16
)
+
5
);
}
else
{
}
else
{
throw
std
::
runtime_error
(
"Invalid option: "
+
option
);
throw
std
::
runtime_error
(
"Invalid option: "
+
option
);
}
}
...
@@ -4224,7 +4224,7 @@ private:
...
@@ -4224,7 +4224,7 @@ private:
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
2
]
=
seq
;
resp_buf_
[
2
]
=
seq
;
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_DISFIELD
)
{
}
else
if
(
msg_
==
MSG_SELECT_DISFIELD
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -4260,7 +4260,7 @@ private:
...
@@ -4260,7 +4260,7 @@ private:
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
0
]
=
plr
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
1
]
=
loc
;
resp_buf_
[
2
]
=
seq
;
resp_buf_
[
2
]
=
seq
;
OCG
_SetResponseb
(
pduel_
,
resp_buf_
);
YGO
_SetResponseb
(
pduel_
,
resp_buf_
);
};
};
}
else
if
(
msg_
==
MSG_ANNOUNCE_NUMBER
)
{
}
else
if
(
msg_
==
MSG_ANNOUNCE_NUMBER
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -4289,7 +4289,7 @@ private:
...
@@ -4289,7 +4289,7 @@ private:
}
}
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
OCG
_SetResponsei
(
pduel_
,
idx
);
YGO
_SetResponsei
(
pduel_
,
idx
);
};
};
}
else
if
(
msg_
==
MSG_ANNOUNCE_ATTRIB
)
{
}
else
if
(
msg_
==
MSG_ANNOUNCE_ATTRIB
)
{
auto
player
=
read_u8
();
auto
player
=
read_u8
();
...
@@ -4341,7 +4341,7 @@ private:
...
@@ -4341,7 +4341,7 @@ private:
resp
|=
1
<<
(
option
[
i
]
-
'1'
);
resp
|=
1
<<
(
option
[
i
]
-
'1'
);
i
+=
2
;
i
+=
2
;
}
}
OCG
_SetResponsei
(
pduel_
,
resp
);
YGO
_SetResponsei
(
pduel_
,
resp
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_POSITION
)
{
}
else
if
(
msg_
==
MSG_SELECT_POSITION
)
{
...
@@ -4373,7 +4373,7 @@ private:
...
@@ -4373,7 +4373,7 @@ private:
to_play_
=
player
;
to_play_
=
player
;
callback_
=
[
this
](
int
idx
)
{
callback_
=
[
this
](
int
idx
)
{
uint8_t
pos
=
options_
[
idx
][
0
]
-
'1'
;
uint8_t
pos
=
options_
[
idx
][
0
]
-
'1'
;
OCG
_SetResponsei
(
pduel_
,
1
<<
pos
);
YGO
_SetResponsei
(
pduel_
,
1
<<
pos
);
};
};
}
else
{
}
else
{
show_deck
(
0
);
show_deck
(
0
);
...
@@ -4409,7 +4409,7 @@ private:
...
@@ -4409,7 +4409,7 @@ private:
win_reason_
=
reason
;
win_reason_
=
reason
;
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
std
::
unique_lock
<
std
::
shared_timed_mutex
>
ulock
(
duel_mtx
);
OCG
_EndDuel
(
pduel_
);
YGO
_EndDuel
(
pduel_
);
ulock
.
unlock
();
ulock
.
unlock
();
duel_started_
=
false
;
duel_started_
=
false
;
...
...
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