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
92898eae
Commit
92898eae
authored
Mar 05, 2024
by
sbl1996@126.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add edopro
parent
2d2b1ceb
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
371 additions
and
213 deletions
+371
-213
ygoenv/ygoenv/edopro/edopro.h
ygoenv/ygoenv/edopro/edopro.h
+359
-203
ygoenv/ygoenv/ygopro/ygopro.h
ygoenv/ygoenv/ygopro/ygopro.h
+12
-10
No files found.
ygoenv/ygoenv/edopro/edopro.h
View file @
92898eae
...
@@ -83,42 +83,55 @@ combinations_with_weight(const std::vector<int> &weights, int r) {
...
@@ -83,42 +83,55 @@ combinations_with_weight(const std::vector<int> &weights, int r) {
}
}
inline
bool
sum_to2
(
const
std
::
vector
<
std
::
vector
<
int
>>
&
w
,
inline
bool
sum_to2
(
const
std
::
vector
<
std
::
vector
<
int
>>
&
w
,
const
std
::
vector
<
int
>
ind
,
int
i
,
int
r
)
{
const
std
::
vector
<
int
>
ind
,
int
i
,
int
r
,
bool
max
=
false
)
{
if
(
r
<=
0
)
{
if
(
r
<=
0
)
{
return
false
;
if
(
max
)
{
return
true
;
}
else
{
return
false
;
}
}
}
int
n
=
ind
.
size
();
int
n
=
ind
.
size
();
const
auto
&
w_
=
w
[
ind
[
i
]];
const
auto
&
w_
=
w
[
ind
[
i
]];
if
(
i
==
n
-
1
)
{
if
(
i
==
n
-
1
)
{
if
(
w_
.
size
()
==
1
)
{
if
(
w_
.
size
()
==
1
)
{
return
w_
[
0
]
==
r
;
if
(
max
)
{
return
w_
[
0
]
>=
r
;
}
else
{
return
w_
[
0
]
==
r
;
}
}
else
{
}
else
{
return
w_
[
0
]
==
r
||
w_
[
1
]
==
r
;
if
(
max
)
{
return
w_
[
0
]
>=
r
||
w_
[
1
]
>=
r
;
}
else
{
return
w_
[
0
]
==
r
||
w_
[
1
]
==
r
;
}
}
}
}
}
if
(
w_
.
size
()
==
1
)
{
if
(
w_
.
size
()
==
1
)
{
return
sum_to2
(
w
,
ind
,
i
+
1
,
r
-
w_
[
0
]);
return
sum_to2
(
w
,
ind
,
i
+
1
,
r
-
w_
[
0
]
,
max
);
}
else
{
}
else
{
return
sum_to2
(
w
,
ind
,
i
+
1
,
r
-
w_
[
0
])
||
return
sum_to2
(
w
,
ind
,
i
+
1
,
r
-
w_
[
0
]
,
max
)
||
sum_to2
(
w
,
ind
,
i
+
1
,
r
-
w_
[
1
]);
sum_to2
(
w
,
ind
,
i
+
1
,
r
-
w_
[
1
]
,
max
);
}
}
}
}
inline
bool
sum_to2
(
const
std
::
vector
<
std
::
vector
<
int
>>
&
w
,
inline
bool
sum_to2
(
const
std
::
vector
<
std
::
vector
<
int
>>
&
w
,
const
std
::
vector
<
int
>
ind
,
int
r
)
{
const
std
::
vector
<
int
>
ind
,
int
r
,
bool
max
=
false
)
{
return
sum_to2
(
w
,
ind
,
0
,
r
);
return
sum_to2
(
w
,
ind
,
0
,
r
,
max
);
}
}
inline
std
::
vector
<
std
::
vector
<
int
>>
inline
std
::
vector
<
std
::
vector
<
int
>>
combinations_with_weight2
(
const
std
::
vector
<
std
::
vector
<
int
>>
&
weights
,
combinations_with_weight2
(
const
std
::
vector
<
std
::
vector
<
int
>>
&
weights
,
int
r
)
{
int
r
,
bool
max
=
false
)
{
int
n
=
weights
.
size
();
int
n
=
weights
.
size
();
std
::
vector
<
std
::
vector
<
int
>>
results
;
std
::
vector
<
std
::
vector
<
int
>>
results
;
for
(
int
k
=
1
;
k
<=
n
;
k
++
)
{
for
(
int
k
=
1
;
k
<=
n
;
k
++
)
{
std
::
vector
<
std
::
vector
<
int
>>
combs
=
combinations
(
n
,
k
);
std
::
vector
<
std
::
vector
<
int
>>
combs
=
combinations
(
n
,
k
);
for
(
const
auto
&
comb
:
combs
)
{
for
(
const
auto
&
comb
:
combs
)
{
if
(
sum_to2
(
weights
,
comb
,
r
))
{
if
(
sum_to2
(
weights
,
comb
,
r
,
max
))
{
results
.
push_back
(
comb
);
results
.
push_back
(
comb
);
}
}
}
}
...
@@ -309,7 +322,7 @@ static const ankerl::unordered_dense::map<int, std::string> system_strings = {
...
@@ -309,7 +322,7 @@ static const ankerl::unordered_dense::map<int, std::string> system_strings = {
{
1622
,
"[%ls] Missed timing"
}
{
1622
,
"[%ls] Missed timing"
}
};
};
static
std
::
string
get_system_string
(
in
t
desc
)
{
static
std
::
string
get_system_string
(
uint32_
t
desc
)
{
auto
it
=
system_strings
.
find
(
desc
);
auto
it
=
system_strings
.
find
(
desc
);
if
(
it
!=
system_strings
.
end
())
{
if
(
it
!=
system_strings
.
end
())
{
return
it
->
second
;
return
it
->
second
;
...
@@ -862,6 +875,7 @@ public:
...
@@ -862,6 +875,7 @@ public:
position_
=
info
.
position
;
position_
=
info
.
position
;
}
}
const
CardCode
&
code
()
const
{
return
code_
;
}
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_
;
}
...
@@ -933,11 +947,14 @@ inline uint32_t ls_to_spec_code(const loc_info &info, PlayerId player) {
...
@@ -933,11 +947,14 @@ inline uint32_t ls_to_spec_code(const loc_info &info, PlayerId player) {
// TODO: 7% performance loss
// TODO: 7% performance loss
static
std
::
shared_timed_mutex
duel_mtx
;
static
std
::
shared_timed_mutex
duel_mtx
;
inline
Card
db_query_card
(
const
SQLite
::
Database
&
db
,
CardCode
code
)
{
inline
Card
db_query_card
(
const
SQLite
::
Database
&
db
,
CardCode
code
,
bool
may_absent
=
false
)
{
SQLite
::
Statement
query1
(
db
,
"SELECT * FROM datas WHERE id=?"
);
SQLite
::
Statement
query1
(
db
,
"SELECT * FROM datas WHERE id=?"
);
query1
.
bind
(
1
,
code
);
query1
.
bind
(
1
,
code
);
bool
found
=
query1
.
executeStep
();
bool
found
=
query1
.
executeStep
();
if
(
!
found
)
{
if
(
!
found
)
{
if
(
may_absent
)
{
return
Card
();
}
std
::
string
msg
=
"[db_query_card] Card not found: "
+
std
::
to_string
(
code
);
std
::
string
msg
=
"[db_query_card] Card not found: "
+
std
::
to_string
(
code
);
throw
std
::
runtime_error
(
msg
);
throw
std
::
runtime_error
(
msg
);
}
}
...
@@ -973,7 +990,8 @@ inline Card db_query_card(const SQLite::Database &db, CardCode code) {
...
@@ -973,7 +990,8 @@ inline Card db_query_card(const SQLite::Database &db, CardCode code) {
defense
,
race
,
attribute
,
link_marker
,
name
,
desc
,
strings
);
defense
,
race
,
attribute
,
link_marker
,
name
,
desc
,
strings
);
}
}
inline
OCG_CardData
db_query_card_data
(
const
SQLite
::
Database
&
db
,
CardCode
code
)
{
inline
OCG_CardData
db_query_card_data
(
const
SQLite
::
Database
&
db
,
CardCode
code
,
bool
may_absent
=
false
)
{
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
();
...
@@ -989,10 +1007,17 @@ inline OCG_CardData db_query_card_data(const SQLite::Database &db, CardCode code
...
@@ -989,10 +1007,17 @@ inline OCG_CardData db_query_card_data(const SQLite::Database &db, CardCode code
setcodes
.
push_back
(
setcode
);
setcodes
.
push_back
(
setcode
);
}
}
}
}
// memory leak here, but we only use it globally
if
(
setcodes
.
size
())
{
uint16_t
*
setcodes_p
=
new
uint16_t
[
setcodes
.
size
()];
setcodes
.
push_back
(
0
);
std
::
copy
(
setcodes
.
begin
(),
setcodes
.
end
(),
setcodes_p
);
// memory leak here, but we only use it globally
card
.
setcodes
=
setcodes_p
;
uint16_t
*
setcodes_p
=
new
uint16_t
[
setcodes
.
size
()];
for
(
int
i
=
0
;
i
<
setcodes
.
size
();
i
++
)
{
setcodes_p
[
i
]
=
setcodes
[
i
];
}
card
.
setcodes
=
setcodes_p
;
}
else
{
card
.
setcodes
=
nullptr
;
}
card
.
type
=
query
.
getColumn
(
"type"
);
card
.
type
=
query
.
getColumn
(
"type"
);
card
.
attack
=
query
.
getColumn
(
"atk"
);
card
.
attack
=
query
.
getColumn
(
"atk"
);
...
@@ -1081,11 +1106,17 @@ inline void sort_extra_deck(std::vector<CardCode> &deck) {
...
@@ -1081,11 +1106,17 @@ inline void sort_extra_deck(std::vector<CardCode> &deck) {
}
}
inline
void
preload_deck
(
const
SQLite
::
Database
&
db
,
inline
void
preload_deck
(
const
SQLite
::
Database
&
db
,
const
std
::
vector
<
CardCode
>
&
deck
)
{
const
std
::
vector
<
CardCode
>
&
deck
,
bool
may_absent
=
false
)
{
for
(
const
auto
&
code
:
deck
)
{
for
(
const
auto
&
code
:
deck
)
{
auto
it
=
cards_
.
find
(
code
);
auto
it
=
cards_
.
find
(
code
);
if
(
it
==
cards_
.
end
())
{
if
(
it
==
cards_
.
end
())
{
cards_
[
code
]
=
db_query_card
(
db
,
code
);
auto
card
=
db_query_card
(
db
,
code
,
may_absent
);
if
((
card
.
code
()
==
0
)
&&
may_absent
)
{
fmt
::
println
(
"[preload_deck] Card not found: {}"
,
code
);
continue
;
}
cards_
[
code
]
=
card
;
if
(
card_ids_
.
find
(
code
)
==
card_ids_
.
end
())
{
if
(
card_ids_
.
find
(
code
)
==
card_ids_
.
end
())
{
throw
std
::
runtime_error
(
"Card not found in code list: "
+
throw
std
::
runtime_error
(
"Card not found in code list: "
+
std
::
to_string
(
code
));
std
::
to_string
(
code
));
...
@@ -1094,7 +1125,7 @@ inline void preload_deck(const SQLite::Database &db,
...
@@ -1094,7 +1125,7 @@ inline void preload_deck(const SQLite::Database &db,
auto
it2
=
cards_data_
.
find
(
code
);
auto
it2
=
cards_data_
.
find
(
code
);
if
(
it2
==
cards_data_
.
end
())
{
if
(
it2
==
cards_data_
.
end
())
{
cards_data_
[
code
]
=
db_query_card_data
(
db
,
code
);
cards_data_
[
code
]
=
db_query_card_data
(
db
,
code
,
may_absent
);
}
}
}
}
}
}
...
@@ -1110,8 +1141,12 @@ inline void g_DataReader(void* payload, uint32_t code, OCG_CardData* data) {
...
@@ -1110,8 +1141,12 @@ inline void g_DataReader(void* payload, uint32_t code, OCG_CardData* data) {
static
std
::
shared_timed_mutex
scripts_mtx
;
static
std
::
shared_timed_mutex
scripts_mtx
;
inline
const
char
*
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
);
// edopro_script/c*.lua copied from ProjectIgnis/script/official
auto
full_path
=
"edopro_script/"
+
path
;
std
::
ifstream
file
(
full_path
,
std
::
ios
::
binary
);
if
(
!
file
)
{
if
(
!
file
)
{
fmt
::
print
(
"Unable to open script file: {}
\n
"
,
full_path
);
*
lenptr
=
0
;
return
nullptr
;
return
nullptr
;
}
}
file
.
seekg
(
0
,
std
::
ios
::
end
);
file
.
seekg
(
0
,
std
::
ios
::
end
);
...
@@ -1131,15 +1166,20 @@ inline int g_ScriptReader(void* payload, OCG_Duel duel, const char* name) {
...
@@ -1131,15 +1166,20 @@ inline int g_ScriptReader(void* payload, OCG_Duel duel, const char* name) {
lock
.
unlock
();
lock
.
unlock
();
int
len
;
int
len
;
const
char
*
buf
=
read_card_script
(
path
,
&
len
);
const
char
*
buf
=
read_card_script
(
path
,
&
len
);
if
(
buf
==
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
);
}
}
int
len
=
it
->
second
.
len
;
int
len
=
it
->
second
.
len
;
return
len
&&
OCG_LoadScript
(
duel
,
it
->
second
.
buf
,
static_cast
<
uint32_t
>
(
len
),
name
);
auto
res
=
len
&&
OCG_LoadScript
(
duel
,
it
->
second
.
buf
,
static_cast
<
uint32_t
>
(
len
),
name
);
// if (!res) {
// fmt::print("Failed to load script: {}\n", path);
// }
return
res
;
}
void
g_LogHandler
(
void
*
payload
,
const
char
*
string
,
int
type
)
{
fmt
::
println
(
"[LOG] type: {}, string: {}"
,
type
,
string
);
}
}
static
void
init_module
(
const
std
::
string
&
db_path
,
static
void
init_module
(
const
std
::
string
&
db_path
,
...
@@ -1167,7 +1207,7 @@ static void init_module(const std::string &db_path,
...
@@ -1167,7 +1207,7 @@ static void init_module(const std::string &db_path,
preload_deck
(
db
,
main_deck
);
preload_deck
(
db
,
main_deck
);
preload_deck
(
db
,
extra_deck
);
preload_deck
(
db
,
extra_deck
);
preload_deck
(
db
,
side_deck
);
preload_deck
(
db
,
side_deck
,
true
);
}
}
for
(
auto
&
[
name
,
deck
]
:
extra_decks_
)
{
for
(
auto
&
[
name
,
deck
]
:
extra_decks_
)
{
...
@@ -1429,7 +1469,7 @@ protected:
...
@@ -1429,7 +1469,7 @@ protected:
int
dl_
=
0
;
int
dl_
=
0
;
int
fdl_
=
0
;
int
fdl_
=
0
;
uint8_t
query_buf_
[
4096
];
uint8_t
query_buf_
[
16384
];
int
qdp_
=
0
;
int
qdp_
=
0
;
uint8_t
resp_buf_
[
128
];
uint8_t
resp_buf_
[
128
];
...
@@ -1634,8 +1674,8 @@ public:
...
@@ -1634,8 +1674,8 @@ 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
)
{
//
for (int j = 0; j < extra_deck.size(); ++j) {
ReplayWriteInt32
(
extra_deck
[
j
]);
ReplayWriteInt32
(
extra_deck
[
j
]);
}
}
}
}
...
@@ -2177,7 +2217,8 @@ private:
...
@@ -2177,7 +2217,8 @@ private:
opts
.
scriptReader
=
&
g_ScriptReader
;
opts
.
scriptReader
=
&
g_ScriptReader
;
opts
.
payload2
=
nullptr
;
opts
.
payload2
=
nullptr
;
opts
.
logHandler
=
[](
void
*
/*payload*/
,
const
char
*
/*string*/
,
int
/*type*/
)
{};
// opts.logHandler = [](void* /*payload*/, const char* /*string*/, int /*type*/) {};
opts
.
logHandler
=
&
g_LogHandler
;
opts
.
payload3
=
nullptr
;
opts
.
payload3
=
nullptr
;
opts
.
cardReaderDone
=
[](
void
*
/*payload*/
,
OCG_CardData
*
/*data*/
)
{};
opts
.
cardReaderDone
=
[](
void
*
/*payload*/
,
OCG_CardData
*
/*data*/
)
{};
...
@@ -2188,6 +2229,8 @@ private:
...
@@ -2188,6 +2229,8 @@ private:
if
(
create_status
!=
OCG_DUEL_CREATION_SUCCESS
)
{
if
(
create_status
!=
OCG_DUEL_CREATION_SUCCESS
)
{
throw
std
::
runtime_error
(
"Failed to create duel"
);
throw
std
::
runtime_error
(
"Failed to create duel"
);
}
}
g_ScriptReader
(
nullptr
,
pduel_
,
"constant.lua"
);
g_ScriptReader
(
nullptr
,
pduel_
,
"utility.lua"
);
return
opts
;
return
opts
;
}
}
...
@@ -2213,7 +2256,7 @@ private:
...
@@ -2213,7 +2256,7 @@ private:
uint32_t
YGO_GetMessage
(
OCG_Duel
pduel
,
uint8_t
*
buf
)
{
uint32_t
YGO_GetMessage
(
OCG_Duel
pduel
,
uint8_t
*
buf
)
{
uint32_t
len
;
uint32_t
len
;
auto
buf_
=
OCG_DuelGetMessage
(
pduel
_
,
&
len
);
auto
buf_
=
OCG_DuelGetMessage
(
pduel
,
&
len
);
memcpy
(
buf
,
buf_
,
len
);
memcpy
(
buf
,
buf_
,
len
);
return
len
;
return
len
;
}
}
...
@@ -2226,7 +2269,7 @@ private:
...
@@ -2226,7 +2269,7 @@ private:
// TODO: overlay
// TODO: overlay
OCG_QueryInfo
info
=
{
query_flag
,
playerid
,
location
,
sequence
};
OCG_QueryInfo
info
=
{
query_flag
,
playerid
,
location
,
sequence
};
uint32_t
length
;
uint32_t
length
;
auto
buf_
=
OCG_DuelQuery
(
pduel
,
&
length
,
info
);
auto
buf_
=
static_cast
<
uint8_t
*>
(
OCG_DuelQuery
(
pduel
,
&
length
,
info
)
);
if
(
length
>
0
)
{
if
(
length
>
0
)
{
memcpy
(
buf
,
buf_
,
length
);
memcpy
(
buf
,
buf_
,
length
);
}
}
...
@@ -2234,13 +2277,18 @@ private:
...
@@ -2234,13 +2277,18 @@ private:
}
}
int32_t
YGO_QueryFieldCount
(
OCG_Duel
pduel
,
uint8_t
playerid
,
uint8_t
location
)
{
int32_t
YGO_QueryFieldCount
(
OCG_Duel
pduel
,
uint8_t
playerid
,
uint8_t
location
)
{
return
0
;
return
OCG_DuelQueryCount
(
pduel
,
playerid
,
location
);
// return OCG_DuelQueryCount(pduel, playerid, location);
}
}
int32_t
OCG_QueryFieldCard
(
OCG_Duel
pduel
,
uint8_t
playerid
,
uint8_t
location
,
uint32_t
query_flag
,
uint8_t
*
buf
,
int32_t
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
0
;
// TODO: overlay
// return query_field_card(pduel, playerid, location, query_flag, buf, use_cache);
OCG_QueryInfo
info
=
{
query_flag
,
playerid
,
location
};
uint32_t
length
;
auto
buf_
=
static_cast
<
uint8_t
*>
(
OCG_DuelQueryLocation
(
pduel
,
&
length
,
info
));
if
(
length
>
0
)
{
memcpy
(
buf
,
buf_
,
length
);
}
return
length
;
}
}
void
YGO_SetResponsei
(
OCG_Duel
pduel
,
int32_t
value
)
{
void
YGO_SetResponsei
(
OCG_Duel
pduel
,
int32_t
value
)
{
...
@@ -2290,10 +2338,10 @@ private:
...
@@ -2290,10 +2338,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
())
{
...
@@ -2305,11 +2353,10 @@ private:
...
@@ -2305,11 +2353,10 @@ 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_
;
...
@@ -2474,6 +2521,12 @@ private:
...
@@ -2474,6 +2521,12 @@ private:
return
v
;
return
v
;
}
}
uint32_t
q_read_u16_
()
{
uint32_t
v
=
*
reinterpret_cast
<
uint16_t
*>
(
query_buf_
+
qdp_
);
qdp_
+=
2
;
return
v
;
}
uint32_t
q_read_u16
()
{
uint32_t
q_read_u16
()
{
qdp_
+=
6
;
qdp_
+=
6
;
uint32_t
v
=
*
reinterpret_cast
<
uint16_t
*>
(
query_buf_
+
qdp_
);
uint32_t
v
=
*
reinterpret_cast
<
uint16_t
*>
(
query_buf_
+
qdp_
);
...
@@ -2511,12 +2564,16 @@ private:
...
@@ -2511,12 +2564,16 @@ private:
int32_t
bl
=
YGO_QueryCard
(
pduel_
,
player
,
loc
,
seq
,
flags
,
query_buf_
);
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)"
);
std
::
string
err
=
fmt
::
format
(
"Player: {}, loc: {}, seq: {}, length: {}"
,
player
,
loc
,
seq
,
bl
);
throw
std
::
runtime_error
(
"[get_card] Invalid card "
+
err
);
}
}
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
.
controler_
=
player
;
c
.
location_
=
loc
;
c
.
sequence_
=
seq
;
c
.
position_
=
position
;
uint32_t
level
=
q_read_u32
();
uint32_t
level
=
q_read_u32
();
// TODO: check negative level
// TODO: check negative level
if
((
level
&
0xff
)
>
0
)
{
if
((
level
&
0xff
)
>
0
)
{
...
@@ -2544,88 +2601,94 @@ private:
...
@@ -2544,88 +2601,94 @@ 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
)
{
return
{};
int32_t
flags
=
QUERY_CODE
|
QUERY_POSITION
|
QUERY_LEVEL
|
QUERY_RANK
|
// int32_t flags = QUERY_CODE | QUERY_POSITION | QUERY_LEVEL | QUERY_RANK |
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 = OCG_QueryFieldCard(pduel_, player, loc, flags, query_buf_, 0);
// qdp_ = 0;
// fmt::println("player: {}, loc: {}, bl {}", player, location2str.at(loc), bl);
// std::vector<Card> cards;
// print byte by byte
// while (true) {
// for (int i = 0; i < bl; ++i) {
// if (qdp_ >= bl) {
// fmt::print("{:02x} ", query_buf_[i]);
// break;
// }
// uint32_t f = q_read_u32();
// if (f == LEN_EMPTY) {
// continue;
// ;
// }
// f = q_read_u32();
// 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 sequence = q_read_u8();
// uint8_t position = q_read_u8();
// c.controler_ = controller;
// c.location_ = location;
// c.sequence_ = sequence;
// c.position_ = position;
// uint32_t level = q_read_u32();
// if ((level & 0xff) > 0) {
// c.level_ = level & 0xff;
// }
// uint32_t rank = q_read_u32();
// if ((rank & 0xff) > 0) {
// c.level_ = rank & 0xff;
// }
// c.attack_ = q_read_u32();
// c.defense_ = q_read_u32();
// // TODO: equip_target
// if (f & QUERY_EQUIP_CARD) {
// q_read_u32();
// }
// uint32_t n_xyz = q_read_u32();
// for (int i = 0; i < n_xyz; ++i) {
// auto code = q_read_u32();
// Card c_ = c_get_card(code);
// c_.controler_ = controller;
// c_.location_ = location | LOCATION_OVERLAY;
// c_.sequence_ = sequence;
// c_.position_ = i;
// cards.push_back(c_);
// }
// // TODO: counters
// uint32_t n_counters = q_read_u32();
// for (int i = 0; i < n_counters; ++i) {
// if (i == 0) {
// c.counter_ = q_read_u32();
// }
// else {
// 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();
// if ((link & 0xff) > 0) {
// c.level_ = link & 0xff;
// }
// if (link_marker > 0) {
// c.defense_ = link_marker;
// }
// cards.push_back(c);
// }
// }
// return cards;
// fmt::print("\n");
qdp_
=
4
;
std
::
vector
<
Card
>
cards
;
while
(
true
)
{
if
(
qdp_
>=
bl
||
bl
-
qdp_
<
136
)
{
break
;
}
uint16_t
v
=
q_read_u16_
();
while
(
v
==
0
)
{
v
=
q_read_u16_
();
}
qdp_
+=
4
;
CardCode
code
=
q_read_u32_
();
Card
c
=
c_get_card
(
code
);
uint32_t
position
=
q_read_u32
();
c
.
controler_
=
player
;
c
.
location_
=
loc
;
// TODO: fix this
uint32_t
sequence
=
0
;
c
.
sequence_
=
sequence
;
c
.
position_
=
position
;
uint32_t
level
=
q_read_u32
();
// TODO: check negative level
if
((
level
&
0xff
)
>
0
)
{
c
.
level_
=
level
&
0xff
;
}
uint32_t
rank
=
q_read_u32
();
if
((
rank
&
0xff
)
>
0
)
{
c
.
level_
=
rank
&
0xff
;
}
c
.
attack_
=
q_read_u32
();
c
.
defense_
=
q_read_u32
();
// TODO: equip_target
qdp_
+=
16
;
uint32_t
n_xyz
=
q_read_u32
();
for
(
int
i
=
0
;
i
<
n_xyz
;
++
i
)
{
auto
code
=
q_read_u32_
();
Card
c_
=
c_get_card
(
code
);
c_
.
controler_
=
player
;
c_
.
location_
=
loc
|
LOCATION_OVERLAY
;
c_
.
sequence_
=
sequence
;
c_
.
position_
=
i
;
cards
.
push_back
(
c_
);
}
// TODO: counters
uint32_t
n_counters
=
q_read_u32
();
for
(
int
i
=
0
;
i
<
n_counters
;
++
i
)
{
if
(
i
==
0
)
{
c
.
counter_
=
q_read_u32_
();
}
else
{
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_
();
if
((
link
&
0xff
)
>
0
)
{
c
.
level_
=
link
&
0xff
;
}
if
(
link_marker
>
0
)
{
c
.
defense_
=
link_marker
;
}
qdp_
+=
6
;
cards
.
push_back
(
c
);
}
return
cards
;
}
}
std
::
vector
<
Card
>
read_cardlist
(
bool
extra
=
false
,
bool
extra8
=
false
)
{
std
::
vector
<
Card
>
read_cardlist
(
bool
extra
=
false
,
bool
extra8
=
false
)
{
...
@@ -2716,6 +2779,11 @@ private:
...
@@ -2716,6 +2779,11 @@ private:
if
(
verbose_
)
{
if
(
verbose_
)
{
fmt
::
println
(
"Message {}, full {}, length {}, dp {}"
,
msg_to_string
(
msg_
),
fdl_
,
dl_
,
dp_
);
fmt
::
println
(
"Message {}, full {}, length {}, dp {}"
,
msg_to_string
(
msg_
),
fdl_
,
dl_
,
dp_
);
// print byte by byte
for
(
int
i
=
dp_
;
i
<
dl_
;
++
i
)
{
fmt
::
print
(
"{:02x} "
,
data_
[
i
]);
}
fmt
::
print
(
"
\n
"
);
}
}
if
(
msg_
==
MSG_DRAW
)
{
if
(
msg_
==
MSG_DRAW
)
{
...
@@ -2890,9 +2958,9 @@ private:
...
@@ -2890,9 +2958,9 @@ private:
return
;
return
;
}
}
CardCode
code1
=
read_u32
();
CardCode
code1
=
read_u32
();
uint32_t
loc1
=
read_u32
();
auto
loc1
=
read_loc_info
();
CardCode
code2
=
read_u32
();
CardCode
code2
=
read_u32
();
uint32_t
loc2
=
read_u32
();
auto
loc2
=
read_loc_info
();
Card
cards
[
2
];
Card
cards
[
2
];
cards
[
0
]
=
c_get_card
(
code1
);
cards
[
0
]
=
c_get_card
(
code1
);
cards
[
1
]
=
c_get_card
(
code2
);
cards
[
1
]
=
c_get_card
(
code2
);
...
@@ -2946,10 +3014,19 @@ private:
...
@@ -2946,10 +3014,19 @@ private:
auto
t
=
cardlist_info_for_player
(
target
,
pl
);
auto
t
=
cardlist_info_for_player
(
target
,
pl
);
players_
[
pl
]
->
notify
(
fmt
::
format
(
"{} equipped to {}."
,
c
,
t
));
players_
[
pl
]
->
notify
(
fmt
::
format
(
"{} equipped to {}."
,
c
,
t
));
}
}
}
else
if
(
msg_
==
MSG_PLAYER_HINT
)
{
if
(
!
verbose_
)
{
dp_
=
dl_
;
return
;
}
auto
player
=
read_u8
();
auto
hint_type
=
read_u8
();
auto
value
=
compat_read
<
uint32_t
,
uint64_t
>
();
// TODO: handle this
return
;
}
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
();
// TODO: different with ygopro-core
auto
value
=
compat_read
<
uint32_t
,
uint64_t
>
();
auto
value
=
compat_read
<
uint32_t
,
uint64_t
>
();
if
(
hint_type
==
HINT_SELECTMSG
&&
value
==
501
)
{
if
(
hint_type
==
HINT_SELECTMSG
&&
value
==
501
)
{
...
@@ -3026,25 +3103,42 @@ private:
...
@@ -3026,25 +3103,42 @@ private:
") changed from "
+
prevpos_str
+
" to "
+
pos_str
+
"."
);
") changed from "
+
prevpos_str
+
" to "
+
pos_str
+
"."
);
op
->
notify
(
"The position of card "
+
opspec
+
" ("
+
card
.
name_
+
op
->
notify
(
"The position of card "
+
opspec
+
" ("
+
card
.
name_
+
") changed from "
+
prevpos_str
+
" to "
+
pos_str
+
"."
);
") changed from "
+
prevpos_str
+
" to "
+
pos_str
+
"."
);
}
else
if
(
msg_
==
MSG_BECOME_TARGET
)
{
}
else
if
(
msg_
==
MSG_BECOME_TARGET
||
msg_
==
MSG_CARD_SELECTED
)
{
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
dp_
=
dl_
;
dp_
=
dl_
;
return
;
return
;
}
}
auto
u
=
read_u8
();
auto
count
=
compat_read
<
uint8_t
,
uint32_t
>
();
uint32_t
target
=
read_u32
();
std
::
vector
<
Card
>
cards
;
uint8_t
tc
=
target
&
0xff
;
cards
.
reserve
(
count
);
uint8_t
tl
=
(
target
>>
8
)
&
0xff
;
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
uint8_t
tseq
=
(
target
>>
16
)
&
0xff
;
auto
info
=
read_loc_info
();
Card
card
=
get_card
(
tc
,
tl
,
tseq
);
auto
c
=
info
.
controler
;
auto
loc
=
info
.
location
;
auto
seq
=
info
.
sequence
;
cards
.
push_back
(
get_card
(
c
,
loc
,
seq
));
}
auto
name
=
players_
[
chaining_player_
]
->
nickname_
;
auto
name
=
players_
[
chaining_player_
]
->
nickname_
;
for
(
PlayerId
pl
=
0
;
pl
<
2
;
pl
++
)
{
for
(
PlayerId
pl
=
0
;
pl
<
2
;
pl
++
)
{
auto
spec
=
card
.
get_spec
(
pl
);
std
::
string
str
=
name
;
auto
tcname
=
card
.
name_
;
if
(
msg_
==
MSG_BECOME_TARGET
)
{
if
((
card
.
controler_
!=
pl
)
&&
(
card
.
position_
&
POS_FACEDOWN
))
{
str
+=
" targets "
;
tcname
=
position_to_string
(
card
.
position_
)
+
" card"
;
}
else
{
str
+=
" selects "
;
}
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
auto
card
=
cards
[
i
];
auto
spec
=
card
.
get_spec
(
pl
);
auto
tcname
=
card
.
name_
;
if
((
card
.
controler_
!=
pl
)
&&
(
card
.
position_
&
POS_FACEDOWN
))
{
tcname
=
position_to_string
(
card
.
position_
)
+
" card"
;
}
str
+=
spec
+
" ("
+
tcname
+
")"
;
if
(
i
<
count
-
1
)
{
str
+=
", "
;
}
}
}
players_
[
pl
]
->
notify
(
name
+
" targets "
+
spec
+
" ("
+
tcname
+
")"
);
players_
[
pl
]
->
notify
(
str
);
}
}
}
else
if
(
msg_
==
MSG_CONFIRM_DECKTOP
)
{
}
else
if
(
msg_
==
MSG_CONFIRM_DECKTOP
)
{
if
(
!
verbose_
)
{
if
(
!
verbose_
)
{
...
@@ -3340,17 +3434,19 @@ private:
...
@@ -3340,17 +3434,19 @@ 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
(
PlayerId
p
=
0
;
p
<
2
;
p
++
)
{
auto
pl
=
players_
[
p
];
auto
pos
=
card
.
get_position
();
auto
pos
=
card
.
get_position
();
auto
atk
=
std
::
to_string
(
card
.
attack_
);
auto
atk
=
std
::
to_string
(
card
.
attack_
);
auto
def
=
std
::
to_string
(
card
.
defense_
);
auto
def
=
std
::
to_string
(
card
.
defense_
);
std
::
string
name
=
p
==
card
.
controler_
?
"You"
:
nickname
;
if
(
card
.
type_
&
TYPE_LINK
)
{
if
(
card
.
type_
&
TYPE_LINK
)
{
pl
->
notify
(
n
ickn
ame
+
" special summoning "
+
card
.
name_
+
" ("
+
pl
->
notify
(
name
+
" special summoning "
+
card
.
name_
+
" ("
+
atk
+
") in "
+
pos
+
" position."
);
atk
+
") in "
+
pos
+
" position."
);
}
else
{
}
else
{
pl
->
notify
(
n
ickn
ame
+
" special summoning "
+
card
.
name_
+
" ("
+
pl
->
notify
(
name
+
" special summoning "
+
card
.
name_
+
" ("
+
atk
+
"/"
+
def
+
") in "
+
pos
+
" position."
);
atk
+
"/"
+
def
+
") in "
+
pos
+
" position."
);
}
}
}
}
...
@@ -3374,12 +3470,12 @@ private:
...
@@ -3374,12 +3470,12 @@ 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
());
auto
tc
=
read_u8
();
auto
tc
=
read_u8
();
auto
tl
=
read_u8
();
auto
tl
=
read_u8
();
auto
ts
=
read_u8
();
auto
ts
=
compat_read
<
uint8_t
,
uint32_t
>
();
uint32_t
desc
=
read_u32
();
uint32_t
desc
=
compat_read
<
uint32_t
,
uint64_t
>
();
auto
cs
=
read_u8
();
auto
cs
=
compat_read
<
uint8_t
,
uint32_t
>
();
auto
c
=
card
.
controler_
;
auto
c
=
card
.
controler_
;
PlayerId
o
=
1
-
c
;
PlayerId
o
=
1
-
c
;
chaining_player_
=
c
;
chaining_player_
=
c
;
...
@@ -3551,7 +3647,7 @@ private:
...
@@ -3551,7 +3647,7 @@ private:
options_
.
push_back
(
"v "
+
spec
);
options_
.
push_back
(
"v "
+
spec
);
if
(
verbose_
)
{
if
(
verbose_
)
{
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
c
=
get_card
(
to_play_
,
loc
,
seq
);
auto
c
=
get_card
(
player
,
loc
,
seq
);
pl
->
notify
(
"v "
+
spec
+
": activate "
+
c
.
name_
+
" ("
+
pl
->
notify
(
"v "
+
spec
+
": activate "
+
c
.
name_
+
" ("
+
std
::
to_string
(
c
.
attack_
)
+
"/"
+
std
::
to_string
(
c
.
attack_
)
+
"/"
+
std
::
to_string
(
c
.
defense_
)
+
")"
);
std
::
to_string
(
c
.
defense_
)
+
")"
);
...
@@ -3561,7 +3657,7 @@ private:
...
@@ -3561,7 +3657,7 @@ private:
options_
.
push_back
(
"a "
+
spec
);
options_
.
push_back
(
"a "
+
spec
);
if
(
verbose_
)
{
if
(
verbose_
)
{
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
c
=
get_card
(
to_play_
,
loc
,
seq
);
auto
c
=
get_card
(
player
,
loc
,
seq
);
if
(
c
.
type_
&
TYPE_LINK
)
{
if
(
c
.
type_
&
TYPE_LINK
)
{
pl
->
notify
(
"a "
+
spec
+
": "
+
c
.
name_
+
" ("
+
pl
->
notify
(
"a "
+
spec
+
": "
+
c
.
name_
+
" ("
+
std
::
to_string
(
c
.
attack_
)
+
") attack"
);
std
::
to_string
(
c
.
attack_
)
+
") attack"
);
...
@@ -3779,15 +3875,32 @@ private:
...
@@ -3779,15 +3875,32 @@ private:
};
};
}
else
{
}
else
{
callback_
=
[
this
,
combs
](
int
idx
)
{
callback_
=
[
this
,
combs
](
int
idx
)
{
int32_t
ret
=
3
;
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
uint8_t
v
=
0
;
const
auto
&
comb
=
combs
[
idx
];
const
auto
&
comb
=
combs
[
idx
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
uint32_t
maxseq
=
0
;
v
|=
(
1
<<
comb
[
i
]);
uint32_t
size
=
comb
.
size
();
for
(
auto
&
c
:
comb
)
{
maxseq
=
std
::
max
(
maxseq
,
static_cast
<
uint32_t
>
(
c
));
}
auto
ret
=
GetSuitableReturn
(
maxseq
,
size
);
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
if
(
ret
==
3
)
{
uint8_t
v
=
0
;
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
(
ret
==
2
)
{
memcpy
(
resp_buf_
+
4
,
&
size
,
sizeof
(
size
));
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
uint8_t
v
=
comb
[
i
];
memcpy
(
resp_buf_
+
8
+
i
,
&
v
,
sizeof
(
v
));
}
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
8
+
size
);
}
else
{
auto
err
=
fmt
::
format
(
"Invalid return value: {}"
,
ret
);
throw
std
::
runtime_error
(
err
);
}
}
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
)
{
...
@@ -3879,15 +3992,32 @@ private:
...
@@ -3879,15 +3992,32 @@ private:
};
};
}
else
{
}
else
{
callback_
=
[
this
,
combs
](
int
idx
)
{
callback_
=
[
this
,
combs
](
int
idx
)
{
int32_t
ret
=
3
;
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
uint8_t
v
=
0
;
const
auto
&
comb
=
combs
[
idx
];
const
auto
&
comb
=
combs
[
idx
];
for
(
int
i
=
0
;
i
<
comb
.
size
();
++
i
)
{
uint32_t
maxseq
=
0
;
v
|=
(
1
<<
comb
[
i
]);
uint32_t
size
=
comb
.
size
();
for
(
auto
&
c
:
comb
)
{
maxseq
=
std
::
max
(
maxseq
,
static_cast
<
uint32_t
>
(
c
));
}
auto
ret
=
GetSuitableReturn
(
maxseq
,
size
);
memcpy
(
resp_buf_
,
&
ret
,
sizeof
(
ret
));
if
(
ret
==
3
)
{
uint8_t
v
=
0
;
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
(
ret
==
2
)
{
memcpy
(
resp_buf_
+
4
,
&
size
,
sizeof
(
size
));
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
uint8_t
v
=
comb
[
i
];
memcpy
(
resp_buf_
+
8
+
i
,
&
v
,
sizeof
(
v
));
}
YGO_SetResponseb
(
pduel_
,
resp_buf_
,
8
+
size
);
}
else
{
auto
err
=
fmt
::
format
(
"Invalid return value: {}"
,
ret
);
throw
std
::
runtime_error
(
err
);
}
}
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
)
{
...
@@ -3912,8 +4042,13 @@ private:
...
@@ -3912,8 +4042,13 @@ private:
" not implemented for MSG_SELECT_SUM"
);
" not implemented for MSG_SELECT_SUM"
);
}
}
}
else
{
}
else
{
throw
std
::
runtime_error
(
"mode: "
+
std
::
to_string
(
mode
)
+
if
(
min
!=
0
||
max
!=
0
||
must_select_size
!=
0
)
{
" not implemented for MSG_SELECT_SUM"
);
std
::
string
err
=
fmt
::
format
(
"min: {}, max: {}, must select size: {} not implemented for "
"MSG_SELECT_SUM, mode: {}"
,
min
,
max
,
must_select_size
,
mode
);
throw
std
::
runtime_error
(
err
);
}
}
}
std
::
vector
<
int
>
must_select_params
;
std
::
vector
<
int
>
must_select_params
;
...
@@ -3924,7 +4059,7 @@ private:
...
@@ -3924,7 +4059,7 @@ private:
must_select_params
.
reserve
(
must_select_size
);
must_select_params
.
reserve
(
must_select_size
);
must_select_specs
.
reserve
(
must_select_size
);
must_select_specs
.
reserve
(
must_select_size
);
int
expected
;
int
expected
=
val
;
if
(
verbose_
)
{
if
(
verbose_
)
{
std
::
vector
<
Card
>
must_select
;
std
::
vector
<
Card
>
must_select
;
must_select
.
reserve
(
must_select_size
);
must_select
.
reserve
(
must_select_size
);
...
@@ -3944,15 +4079,17 @@ private:
...
@@ -3944,15 +4079,17 @@ private:
must_select
.
push_back
(
card
);
must_select
.
push_back
(
card
);
must_select_params
.
push_back
(
param
);
must_select_params
.
push_back
(
param
);
}
}
expected
=
int
(
val
)
-
(
must_select_params
[
0
]
&
0xff
);
if
(
must_select_size
>
0
)
{
expected
-=
must_select_params
[
0
]
&
0xff
;
}
auto
pl
=
players_
[
player
];
auto
pl
=
players_
[
player
];
pl
->
notify
(
"Select cards with a total value of "
+
pl
->
notify
(
"Select cards with a total value of "
+
std
::
to_string
(
expected
)
+
", seperated by spaces."
);
std
::
to_string
(
expected
)
+
", seperated by spaces."
);
for
(
const
auto
&
card
:
must_select
)
{
for
(
const
auto
&
card
:
must_select
)
{
auto
spec
=
card
.
get_spec
(
player
);
auto
spec
=
card
.
get_spec
(
player
);
must_select_specs
.
push_back
(
spec
);
must_select_specs
.
push_back
(
spec
);
pl
->
notify
(
card
.
name_
+
" ("
+
spec
+
pl
->
notify
(
card
.
name_
+
" ("
+
spec
+
") must be selected, automatically selected."
);
") must be selected, automatically selected."
);
}
}
}
else
{
}
else
{
for
(
int
i
=
0
;
i
<
must_select_size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
must_select_size
;
++
i
)
{
...
@@ -3972,7 +4109,9 @@ private:
...
@@ -3972,7 +4109,9 @@ private:
must_select_specs
.
push_back
(
spec
);
must_select_specs
.
push_back
(
spec
);
must_select_params
.
push_back
(
param
);
must_select_params
.
push_back
(
param
);
}
}
expected
=
int
(
val
)
-
(
must_select_params
[
0
]
&
0xff
);
if
(
must_select_size
>
0
)
{
expected
-=
must_select_params
[
0
]
&
0xff
;
}
}
}
uint8_t
select_size
=
compat_read
<
uint8_t
,
uint32_t
>
();
uint8_t
select_size
=
compat_read
<
uint8_t
,
uint32_t
>
();
...
@@ -4039,13 +4178,14 @@ private:
...
@@ -4039,13 +4178,14 @@ private:
}
}
std
::
vector
<
std
::
vector
<
int
>>
combs
=
std
::
vector
<
std
::
vector
<
int
>>
combs
=
combinations_with_weight2
(
card_levels
,
expected
);
combinations_with_weight2
(
card_levels
,
expected
,
true
);
for
(
const
auto
&
comb
:
combs
)
{
for
(
const
auto
&
comb
:
combs
)
{
std
::
string
option
=
""
;
std
::
string
option
=
""
;
for
(
int
j
=
0
;
j
<
min
;
++
j
)
{
int
size
=
comb
.
size
();
for
(
int
j
=
0
;
j
<
size
;
++
j
)
{
option
+=
select_specs
[
comb
[
j
]];
option
+=
select_specs
[
comb
[
j
]];
if
(
j
<
min
-
1
)
{
if
(
j
<
size
-
1
)
{
option
+=
" "
;
option
+=
" "
;
}
}
}
}
...
@@ -4117,10 +4257,6 @@ private:
...
@@ -4117,10 +4257,6 @@ private:
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
{
PlayerId
c
=
read_u8
();
uint8_t
loc
=
read_u8
();
uint8_t
seq
=
read_u8
();
uint8_t
pos
=
read_u8
();
spec_codes
.
push_back
(
spec_codes
.
push_back
(
ls_to_spec_code
(
loc_info
,
player
));
ls_to_spec_code
(
loc_info
,
player
));
}
}
...
@@ -4210,26 +4346,27 @@ private:
...
@@ -4210,26 +4346,27 @@ private:
auto
player
=
read_u8
();
auto
player
=
read_u8
();
if
(
verbose_
)
{
if
(
verbose_
)
{
auto
desc
=
read_u32
();
auto
desc
=
compat_read
<
uint32_t
,
uint64_t
>
();
auto
pl
=
players_
[
player
];
auto
pl
=
players_
[
player
];
std
::
string
opt
;
std
::
string
opt
;
if
(
desc
>
10000
)
{
// if (desc > 10000) {
auto
code
=
desc
>>
4
;
// auto code = desc >> 4;
auto
card
=
c_get_card
(
code
);
// auto card = c_get_card(code);
auto
opt_idx
=
desc
&
0xf
;
// auto opt_idx = desc & 0xf;
if
(
opt_idx
<
card
.
strings_
.
size
())
{
// if (opt_idx < card.strings_.size()) {
opt
=
card
.
strings_
[
opt_idx
];
// opt = card.strings_[opt_idx];
}
// }
if
(
opt
.
empty
())
{
// if (opt.empty()) {
opt
=
"Unknown question from "
+
card
.
name_
+
". Yes or no?"
;
// opt = "Unknown question from " + card.name_ + ". Yes or no?";
}
// }
}
else
{
// } else {
opt
=
get_system_string
(
desc
);
// opt = get_system_string(desc);
}
// }
opt
=
"TODO: MSG_SELECT_YESNO desc"
;
pl
->
notify
(
opt
);
pl
->
notify
(
opt
);
pl
->
notify
(
"Please enter y or n."
);
pl
->
notify
(
"Please enter y or n."
);
}
else
{
}
else
{
dp_
+=
4
;
compat_read
<
uint32_t
,
uint64_t
>
()
;
}
}
options_
=
{
"y"
,
"n"
};
options_
=
{
"y"
,
"n"
};
to_play_
=
player
;
to_play_
=
player
;
...
@@ -4320,21 +4457,22 @@ private:
...
@@ -4320,21 +4457,22 @@ private:
auto
pl
=
players_
[
player
];
auto
pl
=
players_
[
player
];
pl
->
notify
(
"Select an option:"
);
pl
->
notify
(
"Select an option:"
);
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
auto
opt
=
read_u32
();
auto
opt
=
compat_read
<
uint32_t
,
uint64_t
>
();
std
::
string
s
;
std
::
string
s
;
if
(
opt
>
10000
)
{
// if (opt > 10000) {
CardCode
code
=
opt
>>
4
;
// CardCode code = opt >> 4;
s
=
c_get_card
(
code
).
strings_
[
opt
&
0xf
];
// s = c_get_card(code).strings_[opt & 0xf];
}
else
{
// } else {
s
=
get_system_string
(
opt
);
// s = get_system_string(opt);
}
// }
s
=
"TODO: MSG_SELECT_OPTION desc"
;
std
::
string
option
=
std
::
to_string
(
i
+
1
);
std
::
string
option
=
std
::
to_string
(
i
+
1
);
options_
.
push_back
(
option
);
options_
.
push_back
(
option
);
pl
->
notify
(
option
+
": "
+
s
);
pl
->
notify
(
option
+
": "
+
s
);
}
}
}
else
{
}
else
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
dp_
+=
4
;
compat_read
<
uint32_t
,
uint64_t
>
()
;
options_
.
push_back
(
std
::
to_string
(
i
+
1
));
options_
.
push_back
(
std
::
to_string
(
i
+
1
));
}
}
}
}
...
@@ -4567,7 +4705,7 @@ private:
...
@@ -4567,7 +4705,7 @@ private:
int
count
=
read_u8
();
int
count
=
read_u8
();
std
::
vector
<
int
>
numbers
;
std
::
vector
<
int
>
numbers
;
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
int
number
=
read_u32
();
int
number
=
compat_read
<
uint32_t
,
uint64_t
>
();
if
(
number
<=
0
||
number
>
12
)
{
if
(
number
<=
0
||
number
>
12
)
{
throw
std
::
runtime_error
(
"Number "
+
std
::
to_string
(
number
)
+
throw
std
::
runtime_error
(
"Number "
+
std
::
to_string
(
number
)
+
" not implemented for announce number"
);
" not implemented for announce number"
);
...
@@ -4680,8 +4818,26 @@ private:
...
@@ -4680,8 +4818,26 @@ private:
show_deck
(
1
);
show_deck
(
1
);
throw
std
::
runtime_error
(
throw
std
::
runtime_error
(
fmt
::
format
(
"Unknown message {}, length {}, dp {}"
,
fmt
::
format
(
"Unknown message {}, length {}, dp {}"
,
msg_to_string
(
msg_
),
dl_
,
dp_
));
msg_
,
dl_
,
dp_
));
}
}
int
GetSuitableReturn
(
uint32_t
maxseq
,
uint32_t
size
)
{
using
nl8
=
std
::
numeric_limits
<
uint8_t
>
;
using
nl16
=
std
::
numeric_limits
<
uint16_t
>
;
using
nl32
=
std
::
numeric_limits
<
uint32_t
>
;
if
(
maxseq
<
nl8
::
max
())
{
if
(
maxseq
>=
size
*
nl8
::
digits
)
return
2
;
}
else
if
(
maxseq
<
nl16
::
max
())
{
if
(
maxseq
>=
size
*
nl16
::
digits
)
return
1
;
}
else
if
(
maxseq
<
nl32
::
max
())
{
if
(
maxseq
>=
size
*
nl32
::
digits
)
return
0
;
}
}
return
3
;
}
}
void
_damage
(
uint8_t
player
,
uint32_t
amount
)
{
void
_damage
(
uint8_t
player
,
uint32_t
amount
)
{
...
...
ygoenv/ygoenv/ygopro/ygopro.h
View file @
92898eae
...
@@ -1051,6 +1051,7 @@ static std::shared_timed_mutex scripts_mtx;
...
@@ -1051,6 +1051,7 @@ static std::shared_timed_mutex scripts_mtx;
inline
byte
*
read_card_script
(
const
std
::
string
&
path
,
int
*
lenptr
)
{
inline
byte
*
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
)
{
*
lenptr
=
0
;
return
nullptr
;
return
nullptr
;
}
}
file
.
seekg
(
0
,
std
::
ios
::
end
);
file
.
seekg
(
0
,
std
::
ios
::
end
);
...
@@ -1070,9 +1071,6 @@ inline byte *script_reader_callback(const char *name, int *lenptr) {
...
@@ -1070,9 +1071,6 @@ inline byte *script_reader_callback(const char *name, int *lenptr) {
lock
.
unlock
();
lock
.
unlock
();
int
len
;
int
len
;
byte
*
buf
=
read_card_script
(
path
,
&
len
);
byte
*
buf
=
read_card_script
(
path
,
&
len
);
if
(
buf
==
nullptr
)
{
return
nullptr
;
}
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
);
...
@@ -3142,15 +3140,17 @@ private:
...
@@ -3142,15 +3140,17 @@ private:
Card
card
=
c_get_card
(
code
);
Card
card
=
c_get_card
(
code
);
card
.
set_location
(
read_u32
());
card
.
set_location
(
read_u32
());
const
auto
&
nickname
=
players_
[
card
.
controler_
]
->
nickname_
;
const
auto
&
nickname
=
players_
[
card
.
controler_
]
->
nickname_
;
for
(
auto
pl
:
players_
)
{
for
(
PlayerId
p
=
0
;
p
<
2
;
p
++
)
{
auto
pl
=
players_
[
p
];
auto
pos
=
card
.
get_position
();
auto
pos
=
card
.
get_position
();
auto
atk
=
std
::
to_string
(
card
.
attack_
);
auto
atk
=
std
::
to_string
(
card
.
attack_
);
auto
def
=
std
::
to_string
(
card
.
defense_
);
auto
def
=
std
::
to_string
(
card
.
defense_
);
std
::
string
name
=
p
==
card
.
controler_
?
"You"
:
nickname
;
if
(
card
.
type_
&
TYPE_LINK
)
{
if
(
card
.
type_
&
TYPE_LINK
)
{
pl
->
notify
(
n
ickn
ame
+
" special summoning "
+
card
.
name_
+
" ("
+
pl
->
notify
(
name
+
" special summoning "
+
card
.
name_
+
" ("
+
atk
+
") in "
+
pos
+
" position."
);
atk
+
") in "
+
pos
+
" position."
);
}
else
{
}
else
{
pl
->
notify
(
n
ickn
ame
+
" special summoning "
+
card
.
name_
+
" ("
+
pl
->
notify
(
name
+
" special summoning "
+
card
.
name_
+
" ("
+
atk
+
"/"
+
def
+
") in "
+
pos
+
" position."
);
atk
+
"/"
+
def
+
") in "
+
pos
+
" position."
);
}
}
}
}
...
@@ -3351,7 +3351,7 @@ private:
...
@@ -3351,7 +3351,7 @@ private:
options_
.
push_back
(
"v "
+
spec
);
options_
.
push_back
(
"v "
+
spec
);
if
(
verbose_
)
{
if
(
verbose_
)
{
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
c
=
get_card
(
to_play_
,
loc
,
seq
);
auto
c
=
get_card
(
player
,
loc
,
seq
);
pl
->
notify
(
"v "
+
spec
+
": activate "
+
c
.
name_
+
" ("
+
pl
->
notify
(
"v "
+
spec
+
": activate "
+
c
.
name_
+
" ("
+
std
::
to_string
(
c
.
attack_
)
+
"/"
+
std
::
to_string
(
c
.
attack_
)
+
"/"
+
std
::
to_string
(
c
.
defense_
)
+
")"
);
std
::
to_string
(
c
.
defense_
)
+
")"
);
...
@@ -3361,7 +3361,7 @@ private:
...
@@ -3361,7 +3361,7 @@ private:
options_
.
push_back
(
"a "
+
spec
);
options_
.
push_back
(
"a "
+
spec
);
if
(
verbose_
)
{
if
(
verbose_
)
{
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
[
loc
,
seq
,
pos
]
=
spec_to_ls
(
spec
);
auto
c
=
get_card
(
to_play_
,
loc
,
seq
);
auto
c
=
get_card
(
player
,
loc
,
seq
);
if
(
c
.
type_
&
TYPE_LINK
)
{
if
(
c
.
type_
&
TYPE_LINK
)
{
pl
->
notify
(
"a "
+
spec
+
": "
+
c
.
name_
+
" ("
+
pl
->
notify
(
"a "
+
spec
+
": "
+
c
.
name_
+
" ("
+
std
::
to_string
(
c
.
attack_
)
+
") attack"
);
std
::
to_string
(
c
.
attack_
)
+
") attack"
);
...
@@ -3653,6 +3653,7 @@ private:
...
@@ -3653,6 +3653,7 @@ private:
YGO_SetResponseb
(
pduel_
,
resp_buf_
);
YGO_SetResponseb
(
pduel_
,
resp_buf_
);
};
};
}
else
if
(
msg_
==
MSG_SELECT_SUM
)
{
}
else
if
(
msg_
==
MSG_SELECT_SUM
)
{
// ritual summoning mode 1 (max)
auto
mode
=
read_u8
();
auto
mode
=
read_u8
();
auto
player
=
read_u8
();
auto
player
=
read_u8
();
auto
val
=
read_u32
();
auto
val
=
read_u32
();
...
@@ -3774,9 +3775,10 @@ private:
...
@@ -3774,9 +3775,10 @@ private:
for
(
const
auto
&
comb
:
combs
)
{
for
(
const
auto
&
comb
:
combs
)
{
std
::
string
option
=
""
;
std
::
string
option
=
""
;
for
(
int
j
=
0
;
j
<
min
;
++
j
)
{
int
size
=
comb
.
size
();
for
(
int
j
=
0
;
j
<
size
;
++
j
)
{
option
+=
select_specs
[
comb
[
j
]];
option
+=
select_specs
[
comb
[
j
]];
if
(
j
<
min
-
1
)
{
if
(
j
<
size
-
1
)
{
option
+=
" "
;
option
+=
" "
;
}
}
}
}
...
...
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