Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro-core
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
nanahira
ygopro-core
Commits
7e4dcb52
Commit
7e4dcb52
authored
Jun 17, 2025
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add registry api
parent
ee1548f7
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
265 additions
and
2 deletions
+265
-2
duel.h
duel.h
+4
-1
libduel.cpp
libduel.cpp
+147
-0
ocgapi.cpp
ocgapi.cpp
+100
-1
ocgapi.h
ocgapi.h
+8
-0
scriptlib.h
scriptlib.h
+6
-0
No files found.
duel.h
View file @
7e4dcb52
...
...
@@ -15,6 +15,7 @@
#include <unordered_set>
#include <cstring>
#include <vector>
#include <unordered_map>
class
card
;
class
group
;
...
...
@@ -38,6 +39,8 @@ public:
std
::
unordered_set
<
effect
*>
effects
;
std
::
unordered_set
<
effect
*>
uncopy
;
std
::
unordered_map
<
std
::
string
,
std
::
string
>
registry
;
duel
();
~
duel
();
void
clear
();
...
...
libduel.cpp
View file @
7e4dcb52
...
...
@@ -228,6 +228,147 @@ int32_t scriptlib::duel_get_random_number(lua_State * L) {
lua_pushinteger(L, pduel->get_next_integer(min, max));
return 1;
}
int32_t scriptlib::duel_get_registry_value(lua_State* L) {
check_param_count(L, 1);
duel* pduel = interpreter::get_duel_info(L);
// 对参数 1 调用 tostring
lua_getglobal(L, "tostring");
lua_pushvalue(L, 1);
lua_call(L, 1, 1); // 调用 tostring(key)
const char* key = lua_tostring(L, -1);
if (!key) {
lua_pop(L, 1); // 清理 tostring 返回值
lua_pushnil(L); // 无效 key,返回 nil
return 1;
}
auto it = pduel->registry.find(key);
if (it != pduel->registry.end()) {
lua_pushstring(L, it->second.c_str());
} else {
lua_pushnil(L);
}
lua_remove(L, -2); // 移除 key 的 tostring 结果,保持栈只返回一个结果
return 1;
}
int32_t scriptlib::duel_set_registry_value(lua_State* L) {
check_param_count(L, 2);
duel* pduel = interpreter::get_duel_info(L);
// 对参数 1(key)调用 tostring
lua_getglobal(L, "tostring");
lua_pushvalue(L, 1);
lua_call(L, 1, 1); // 调用 tostring(key)
const char* key = lua_tostring(L, -1); // key 字符串结果在栈顶
if (!key) {
lua_pop(L, 1); // 清理 key tostring 结果
return luaL_error(L, "invalid key for registry");
}
if (lua_isnil(L, 2)) {
// 删除 key
pduel->registry.erase(key);
lua_pop(L, 1); // 清理 key
return 0;
}
// 对参数 2(value)调用 tostring
lua_getglobal(L, "tostring");
lua_pushvalue(L, 2);
lua_call(L, 1, 1); // 调用 tostring(value)
const char* value = lua_tostring(L, -1); // value 字符串在栈顶
if (value) {
pduel->registry[key] = value;
}
lua_pop(L, 2); // 清理 key 和 value 的 tostring 结果
return 0;
}
int32_t scriptlib::duel_get_registry_keys(lua_State* L) {
duel* pduel = interpreter::get_duel_info(L);
if (pduel->registry.empty()) {
lua_pushnil(L);
return 1;
}
int count = 0;
for (const auto& pair : pduel->registry) {
lua_pushstring(L, pair.first.c_str());
++count;
}
return count; // 返回 n 个字符串(key)
}
int32_t scriptlib::duel_get_registry(lua_State* L) {
duel* pduel = interpreter::get_duel_info(L);
lua_newtable(L); // 创建返回表
for (const auto& pair : pduel->registry) {
lua_pushstring(L, pair.first.c_str());
lua_pushstring(L, pair.second.c_str());
lua_settable(L, -3); // table[key] = value
}
return 1; // 返回这个 table
}
int32_t scriptlib::duel_set_registry(lua_State* L) {
check_param_count(L, 1); // 至少要 table 参数
if (!lua_istable(L, 1)) {
return luaL_error(L, "first argument must be a table");
}
bool override = false;
if (lua_gettop(L) >= 2 && lua_isboolean(L, 2)) {
override = lua_toboolean(L, 2);
}
duel* pduel = interpreter::get_duel_info(L);
if (override) {
pduel->registry.clear();
}
// 遍历 Lua 表
lua_pushnil(L); // 初始 key for lua_next
while (lua_next(L, 1)) {
// 栈: [-1]=value, [-2]=key
// 对 key 调用 tostring
lua_getglobal(L, "tostring");
lua_pushvalue(L, -3); // key
lua_call(L, 1, 1); // -> [tostring_key]
const char* kstr = lua_tostring(L, -1);
lua_remove(L, -1); // pop tostring_key
// 对 value 调用 tostring
lua_getglobal(L, "tostring");
lua_pushvalue(L, -2); // value
lua_call(L, 1, 1); // -> [tostring_value]
const char* vstr = lua_tostring(L, -1);
lua_remove(L, -1); // pop tostring_value
if (kstr && vstr) {
pduel->registry[kstr] = vstr;
}
lua_pop(L, 1); // 移除 value,保留 key 以继续迭代
}
return 0;
}
int32_t scriptlib::duel_clear_registry(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L);
pduel->registry.clear();
return 0;
}
int32_t scriptlib::duel_enable_global_flag(lua_State *L) {
check_param_count(L, 1);
...
...
@@ -5105,6 +5246,12 @@ static const struct luaL_Reg duellib[] = {
{ "ResetTimeLimit", scriptlib::duel_reset_time_limit },
{ "SetSummonCancelable", scriptlib::duel_set_summon_cancelable },
{ "GetRandomNumber", scriptlib::duel_get_random_number },
{ "GetRegistryValue", scriptlib::duel_get_registry_value },
{ "SetRegistryValue", scriptlib::duel_set_registry_value },
{ "GetRegistryKeys", scriptlib::duel_get_registry_keys },
{ "SetRegistry", scriptlib::duel_set_registry },
{ "GetRegistry", scriptlib::duel_get_registry },
{ "ClearRegistry", scriptlib::duel_clear_registry },
{ "EnableGlobalFlag", scriptlib::duel_enable_global_flag },
{ "GetLP", scriptlib::duel_get_lp },
...
...
ocgapi.cpp
View file @
7e4dcb52
...
...
@@ -370,3 +370,102 @@ OCGCORE_API void set_responseb(intptr_t pduel, byte* buf) {
OCGCORE_API
int32_t
preload_script
(
intptr_t
pduel
,
const
char
*
script_name
)
{
return
((
duel
*
)
pduel
)
->
lua
->
load_script
(
script_name
);
}
OCGCORE_API
int32_t
get_registry_value
(
intptr_t
pduel
,
const
char
*
key
,
byte
*
out_buf
)
{
if
(
!
pduel
||
!
key
||
!
out_buf
)
return
-
1
;
duel
*
d
=
(
duel
*
)
pduel
;
auto
it
=
d
->
registry
.
find
(
key
);
if
(
it
==
d
->
registry
.
end
())
return
-
1
;
const
std
::
string
&
val
=
it
->
second
;
std
::
memcpy
(
out_buf
,
val
.
c_str
(),
val
.
size
());
return
static_cast
<
int32_t
>
(
val
.
size
());
}
OCGCORE_API
void
set_registry_value
(
intptr_t
pduel
,
const
char
*
key
,
const
char
*
value
)
{
if
(
!
pduel
||
!
key
)
return
;
duel
*
d
=
(
duel
*
)
pduel
;
if
(
value
)
{
d
->
registry
[
key
]
=
value
;
}
else
{
d
->
registry
.
erase
(
key
);
}
}
OCGCORE_API
int32_t
get_registry_keys
(
intptr_t
pduel
,
byte
*
out_buf
)
{
if
(
!
pduel
||
!
out_buf
)
return
-
1
;
duel
*
d
=
(
duel
*
)
pduel
;
byte
*
ptr
=
out_buf
;
for
(
const
auto
&
pair
:
d
->
registry
)
{
const
std
::
string
&
key
=
pair
.
first
;
uint16_t
len
=
static_cast
<
uint16_t
>
(
std
::
min
<
size_t
>
(
key
.
size
(),
0xFFFF
));
// 写入长度(2字节,小端序)
buffer_write
(
ptr
,
len
);
std
::
memcpy
(
ptr
,
key
.
data
(),
len
);
ptr
+=
len
;
}
return
ptr
-
out_buf
;
}
OCGCORE_API
void
clear_registry
(
intptr_t
pduel
)
{
if
(
!
pduel
)
return
;
duel
*
d
=
(
duel
*
)
pduel
;
d
->
registry
.
clear
();
}
OCGCORE_API
int32_t
dump_registry
(
intptr_t
pduel
,
byte
*
out_buf
)
{
if
(
!
pduel
||
!
out_buf
)
return
-
1
;
duel
*
d
=
(
duel
*
)
pduel
;
byte
*
ptr
=
out_buf
;
for
(
const
auto
&
pair
:
d
->
registry
)
{
const
std
::
string
&
key
=
pair
.
first
;
const
std
::
string
&
value
=
pair
.
second
;
uint16_t
key_len
=
static_cast
<
uint16_t
>
(
std
::
min
<
size_t
>
(
key
.
size
(),
0xFFFF
));
uint16_t
val_len
=
static_cast
<
uint16_t
>
(
std
::
min
<
size_t
>
(
value
.
size
(),
0xFFFF
));
// 写入 key_len 和 val_len(每次调用后 ptr 自动推进)
buffer_write
(
ptr
,
key_len
);
buffer_write
(
ptr
,
val_len
);
// 写入 key 内容
std
::
memcpy
(
ptr
,
key
.
data
(),
key_len
);
ptr
+=
key_len
;
// 写入 value 内容
std
::
memcpy
(
ptr
,
value
.
data
(),
val_len
);
ptr
+=
val_len
;
}
return
ptr
-
out_buf
;
// 返回写入的总字节数
}
OCGCORE_API
void
load_registry
(
intptr_t
pduel
,
const
byte
*
in_buf
,
int32_t
in_len
)
{
if
(
!
pduel
||
!
in_buf
||
in_len
<=
0
)
return
;
duel
*
d
=
(
duel
*
)
pduel
;
byte
*
ptr
=
const_cast
<
byte
*>
(
in_buf
);
// buffer_read 要求非 const
byte
*
end
=
ptr
+
in_len
;
while
(
ptr
+
4
<=
end
)
{
// 至少要读取 key_len 和 val_len(2 + 2 字节)
uint16_t
key_len
=
buffer_read
<
uint16_t
>
(
ptr
);
uint16_t
val_len
=
buffer_read
<
uint16_t
>
(
ptr
);
if
(
ptr
+
key_len
+
val_len
>
end
)
{
break
;
// 数据不完整,退出
}
std
::
string
key
(
reinterpret_cast
<
const
char
*>
(
ptr
),
key_len
);
ptr
+=
key_len
;
std
::
string
value
(
reinterpret_cast
<
const
char
*>
(
ptr
),
val_len
);
ptr
+=
val_len
;
d
->
registry
[
std
::
move
(
key
)]
=
std
::
move
(
value
);
}
}
ocgapi.h
View file @
7e4dcb52
...
...
@@ -64,4 +64,12 @@ OCGCORE_API void set_responseb(intptr_t pduel, byte* buf);
OCGCORE_API
int32_t
preload_script
(
intptr_t
pduel
,
const
char
*
script_name
);
OCGCORE_API
byte
*
default_script_reader
(
const
char
*
script_name
,
int
*
len
);
// koishi specific
OCGCORE_API
int32_t
get_registry_value
(
intptr_t
pduel
,
const
char
*
key
,
byte
*
out_buf
);
OCGCORE_API
void
set_registry_value
(
intptr_t
pduel
,
const
char
*
key
,
const
char
*
value
);
OCGCORE_API
int32_t
get_registry_keys
(
intptr_t
pduel
,
byte
*
out_buf
);
OCGCORE_API
void
clear_registry
(
intptr_t
pduel
);
OCGCORE_API
int32_t
dump_registry
(
intptr_t
pduel
,
byte
*
out_buf
);
OCGCORE_API
void
load_registry
(
intptr_t
pduel
,
const
byte
*
in_buf
,
int32_t
in_len
);
#endif
/* OCGAPI_H_ */
scriptlib.h
View file @
7e4dcb52
...
...
@@ -51,6 +51,12 @@ public:
static
int32_t
duel_reset_time_limit
(
lua_State
*
L
);
static
int32_t
duel_set_summon_cancelable
(
lua_State
*
L
);
static
int32_t
duel_get_random_number
(
lua_State
*
L
);
static
int32_t
duel_get_registry_value
(
lua_State
*
L
);
static
int32_t
duel_set_registry_value
(
lua_State
*
L
);
static
int32_t
duel_get_registry_keys
(
lua_State
*
L
);
static
int32_t
duel_set_registry
(
lua_State
*
L
);
static
int32_t
duel_get_registry
(
lua_State
*
L
);
static
int32_t
duel_clear_registry
(
lua_State
*
L
);
//card lib
static
int32_t
card_get_code
(
lua_State
*
L
);
static
int32_t
card_get_origin_code
(
lua_State
*
L
);
...
...
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