Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
YGOMobile-Cn-Ko-En
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
fallenstardust
YGOMobile-Cn-Ko-En
Commits
c8ad16eb
Commit
c8ad16eb
authored
Dec 10, 2025
by
fallenstardust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
读取genesys禁卡文件
parent
f82b00e7
Pipeline
#41930
failed with stages
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
249 additions
and
17 deletions
+249
-17
Classes/gframe/deck_con.cpp
Classes/gframe/deck_con.cpp
+84
-7
Classes/gframe/deck_manager.cpp
Classes/gframe/deck_manager.cpp
+134
-9
Classes/gframe/deck_manager.h
Classes/gframe/deck_manager.h
+2
-0
Classes/gframe/drawing.cpp
Classes/gframe/drawing.cpp
+27
-1
Classes/gframe/image_manager.cpp
Classes/gframe/image_manager.cpp
+1
-0
Classes/gframe/image_manager.h
Classes/gframe/image_manager.h
+1
-0
mobile/assets/data/textures/lim_credit.png
mobile/assets/data/textures/lim_credit.png
+0
-0
No files found.
Classes/gframe/deck_con.cpp
View file @
c8ad16eb
...
...
@@ -1857,24 +1857,101 @@ void DeckBuilder::pop_side(int seq) {
is_modified
=
true
;
GetHoveredCard
();
}
/**
* @brief 检查指定卡片在当前卡组中是否超过限制数量,并处理信用点数消耗逻辑。
*
* 此函数用于判断一张卡片(由 pointer 指定)能否被加入当前卡组,
* 包括常规禁卡表卡片的数量限制以及GeneSys存在的“信用点”数量限制。
*
* @param pointer 指向卡片信息的指针,包含卡片ID及别名等数据。
* @return 如果该卡片可以合法地加入卡组(未超出数量限制、信用点足够),则返回 true;否则返回 false。
*/
bool
DeckBuilder
::
check_limit
(
code_pointer
pointer
)
{
// 获取实际用于限制检查的卡片编码:如果存在别名则使用别名,否则使用原ID
auto
limitcode
=
pointer
->
second
.
alias
?
pointer
->
second
.
alias
:
pointer
->
first
;
// 默认每张卡最多允许3张
int
limit
=
3
;
// 查找此卡片是否有自定义的数量限制
auto
flit
=
filterList
->
content
.
find
(
limitcode
);
if
(
flit
!=
filterList
->
content
.
end
())
limit
=
flit
->
second
;
for
(
auto
&
card
:
deckManager
.
current_deck
.
main
)
{
if
(
card
->
first
==
limitcode
||
card
->
second
.
alias
==
limitcode
)
// 记录已使用的各类信用点数
std
::
unordered_map
<
std
::
wstring
,
uint32_t
>
credit_used
;
// Lambda 函数:尝试消费某张卡所需的信用点数,若超限则返回false
auto
spend_credit
=
[
&
](
uint32_t
code
)
{
// 查找该卡所需信用点配置
auto
code_credit_it
=
filterList
->
credits
.
find
(
code
);
if
(
code_credit_it
==
filterList
->
credits
.
end
())
return
true
;
// 若无信用要求,默认通过
auto
code_credit
=
code_credit_it
->
second
;
auto
valid
=
true
;
// 遍历所有需要扣除的信用类型与数值
for
(
auto
&
credit_it
:
code_credit
)
{
auto
key
=
credit_it
.
first
;
auto
credit_limit_it
=
filterList
->
credit_limits
.
find
(
key
);
if
(
credit_limit_it
==
filterList
->
credit_limits
.
end
())
continue
;
// 若没有设定上限,则跳过
auto
credit_limit
=
credit_limit_it
->
second
;
// 初始化该信用类型的已用量
if
(
credit_used
.
find
(
key
)
==
credit_used
.
end
())
credit_used
[
key
]
=
0
;
// 判断是否会超出信用上限
auto
credit_after
=
credit_used
[
key
]
+
credit_it
.
second
;
if
(
credit_after
>
credit_limit
)
valid
=
false
;
// 更新已用信用量
credit_used
[
key
]
=
credit_after
;
}
return
valid
;
};
// Lambda 函数:处理单张卡的计数和信用检查
auto
handle_card
=
[
&
](
ygo
::
code_pointer
&
card
)
{
// 如果是目标卡,则减少其剩余可放数量
if
(
card
->
first
==
limitcode
||
card
->
second
.
alias
==
limitcode
)
{
limit
--
;
if
(
limit
<=
0
)
return
false
;
// 已达最大数量限制
}
// 获取真实卡号并尝试扣减信用点
auto
code
=
card
->
second
.
alias
?
card
->
second
.
alias
:
card
->
first
;
spend_credit
(
code
);
return
true
;
};
// 遍历主卡组中的所有卡片进行检查
for
(
auto
&
card
:
deckManager
.
current_deck
.
main
)
{
if
(
!
handle_card
(
card
))
return
false
;
}
// 遍历额外卡组中的所有卡片进行检查
for
(
auto
&
card
:
deckManager
.
current_deck
.
extra
)
{
if
(
card
->
first
==
limitcode
||
card
->
second
.
alias
==
limitcode
)
limit
--
;
if
(
!
handle_card
(
card
)
)
return
false
;
}
// 遍历副卡组中的所有卡片进行检查
for
(
auto
&
card
:
deckManager
.
current_deck
.
side
)
{
if
(
card
->
first
==
limitcode
||
card
->
second
.
alias
==
limitcode
)
limit
--
;
if
(
!
handle_card
(
card
)
)
return
false
;
}
return
limit
>
0
;
// 最后尝试为当前要插入的卡扣除一次信用点数
return
spend_credit
(
limitcode
);
}
}
Classes/gframe/deck_manager.cpp
View file @
c8ad16eb
...
...
@@ -7,6 +7,7 @@ namespace ygo {
DeckManager
deckManager
;
std
::
vector
<
std
::
wstring
>
DeckManager
::
deckComments
;
void
DeckManager
::
LoadLFListSingle
(
const
char
*
path
)
{
auto
cur
=
_lfList
.
rend
();
FILE
*
fp
=
myfopen
(
path
,
"r"
);
...
...
@@ -29,24 +30,70 @@ void DeckManager::LoadLFListSingle(const char* path) {
}
if
(
cur
==
_lfList
.
rend
())
continue
;
if
(
linebuf
[
0
]
==
'$'
)
{
char
*
keyPos
=
linebuf
+
1
;
keyPos
+=
std
::
strspn
(
keyPos
,
"
\t
"
);
auto
keyLen
=
std
::
strcspn
(
keyPos
,
"
\t\r\n
"
);
if
(
!
keyLen
)
continue
;
char
keybuf
[
256
];
if
(
keyLen
>=
sizeof
keybuf
)
keyLen
=
sizeof
keybuf
-
1
;
std
::
memcpy
(
keybuf
,
keyPos
,
keyLen
);
keybuf
[
keyLen
]
=
0
;
keyPos
+=
keyLen
;
keyPos
+=
std
::
strspn
(
keyPos
,
"
\t
"
);
errno
=
0
;
char
*
valuePos
=
keyPos
;
auto
limitValue
=
std
::
strtoul
(
keyPos
,
&
keyPos
,
10
);
if
(
errno
||
valuePos
==
keyPos
)
continue
;
BufferIO
::
DecodeUTF8
(
keybuf
,
strBuffer
);
cur
->
credit_limits
[
strBuffer
]
=
static_cast
<
uint32_t
>
(
limitValue
);
continue
;
}
char
*
pos
=
linebuf
;
errno
=
0
;
char
*
codePos
=
pos
;
auto
result
=
std
::
strtoul
(
pos
,
&
pos
,
10
);
if
(
errno
||
result
>
UINT32_MAX
)
if
(
errno
||
result
>
UINT32_MAX
||
codePos
==
pos
)
continue
;
if
(
pos
==
linebuf
||
*
pos
!=
'
'
)
if
(
*
pos
!=
' '
&&
*
pos
!=
'\t
'
)
continue
;
pos
+=
std
::
strspn
(
pos
,
"
\t
"
);
uint32_t
code
=
static_cast
<
uint32_t
>
(
result
);
if
(
*
pos
==
'$'
)
{
++
pos
;
pos
+=
std
::
strspn
(
pos
,
"
\t
"
);
auto
creditKeyLen
=
std
::
strcspn
(
pos
,
"
\t\r\n
"
);
if
(
!
creditKeyLen
)
continue
;
char
keybuf
[
256
];
if
(
creditKeyLen
>=
sizeof
keybuf
)
creditKeyLen
=
sizeof
keybuf
-
1
;
std
::
memcpy
(
keybuf
,
pos
,
creditKeyLen
);
keybuf
[
creditKeyLen
]
=
0
;
pos
+=
creditKeyLen
;
pos
+=
std
::
strspn
(
pos
,
"
\t
"
);
errno
=
0
;
char
*
creditValuePos
=
pos
;
auto
creditValue
=
std
::
strtoul
(
pos
,
&
pos
,
10
);
if
(
errno
||
creditValuePos
==
pos
)
continue
;
BufferIO
::
DecodeUTF8
(
keybuf
,
strBuffer
);
cur
->
credits
[
code
][
strBuffer
]
=
static_cast
<
uint32_t
>
(
creditValue
);
continue
;
}
errno
=
0
;
char
*
countPos
=
pos
;
int
count
=
std
::
strtol
(
pos
,
&
pos
,
10
);
if
(
errno
)
if
(
errno
||
countPos
==
pos
)
continue
;
if
(
count
<
0
||
count
>
2
)
if
(
count
<
0
||
count
>
2
)
continue
;
cur
->
content
[
code
]
=
count
;
cur
->
hash
=
cur
->
hash
^
((
code
<<
18
)
|
(
code
>>
14
))
^
((
code
<<
(
27
+
count
))
|
(
code
>>
(
5
-
count
)));
}
std
::
fclose
(
fp
);
}
}
void
DeckManager
::
LoadLFListSingle
(
irr
::
io
::
IReadFile
*
reader
)
{
...
...
@@ -96,22 +143,70 @@ void DeckManager::LoadLFListSingle(irr::io::IReadFile* reader) {
}
if
(
cur
==
_lfList
.
rend
())
continue
;
if
(
linebuf
[
0
]
==
'$'
)
{
char
*
keyPos
=
linebuf
+
1
;
keyPos
+=
std
::
strspn
(
keyPos
,
"
\t
"
);
auto
keyLen
=
std
::
strcspn
(
keyPos
,
"
\t\r\n
"
);
if
(
!
keyLen
)
continue
;
char
keybuf
[
256
];
if
(
keyLen
>=
sizeof
keybuf
)
keyLen
=
sizeof
keybuf
-
1
;
std
::
memcpy
(
keybuf
,
keyPos
,
keyLen
);
keybuf
[
keyLen
]
=
0
;
keyPos
+=
keyLen
;
keyPos
+=
std
::
strspn
(
keyPos
,
"
\t
"
);
errno
=
0
;
char
*
valuePos
=
keyPos
;
auto
limitValue
=
std
::
strtoul
(
keyPos
,
&
keyPos
,
10
);
if
(
errno
||
valuePos
==
keyPos
)
continue
;
BufferIO
::
DecodeUTF8
(
keybuf
,
strBuffer
);
cur
->
credit_limits
[
strBuffer
]
=
static_cast
<
uint32_t
>
(
limitValue
);
continue
;
}
char
*
pos
=
linebuf
;
errno
=
0
;
char
*
codePos
=
pos
;
auto
result
=
std
::
strtoul
(
pos
,
&
pos
,
10
);
if
(
errno
||
result
>
UINT32_MAX
)
if
(
errno
||
result
>
UINT32_MAX
||
codePos
==
pos
)
continue
;
if
(
pos
==
linebuf
||
*
pos
!=
'
'
)
if
(
*
pos
!=
' '
&&
*
pos
!=
'\t
'
)
continue
;
pos
+=
std
::
strspn
(
pos
,
"
\t
"
);
uint32_t
code
=
static_cast
<
uint32_t
>
(
result
);
if
(
*
pos
==
'$'
)
{
++
pos
;
pos
+=
std
::
strspn
(
pos
,
"
\t
"
);
auto
creditKeyLen
=
std
::
strcspn
(
pos
,
"
\t\r\n
"
);
if
(
!
creditKeyLen
)
continue
;
char
keybuf
[
256
];
if
(
creditKeyLen
>=
sizeof
keybuf
)
creditKeyLen
=
sizeof
keybuf
-
1
;
std
::
memcpy
(
keybuf
,
pos
,
creditKeyLen
);
keybuf
[
creditKeyLen
]
=
0
;
pos
+=
creditKeyLen
;
pos
+=
std
::
strspn
(
pos
,
"
\t
"
);
errno
=
0
;
char
*
creditValuePos
=
pos
;
auto
creditValue
=
std
::
strtoul
(
pos
,
&
pos
,
10
);
if
(
errno
||
creditValuePos
==
pos
)
continue
;
BufferIO
::
DecodeUTF8
(
keybuf
,
strBuffer
);
cur
->
credits
[
code
][
strBuffer
]
=
static_cast
<
uint32_t
>
(
creditValue
);
continue
;
}
errno
=
0
;
char
*
countPos
=
pos
;
int
count
=
std
::
strtol
(
pos
,
&
pos
,
10
);
if
(
errno
)
if
(
errno
||
countPos
==
pos
)
continue
;
if
(
count
<
0
||
count
>
2
)
if
(
count
<
0
||
count
>
2
)
continue
;
cur
->
content
[
code
]
=
count
;
cur
->
hash
=
cur
->
hash
^
((
code
<<
18
)
|
(
code
>>
14
))
^
((
code
<<
(
27
+
count
))
|
(
code
>>
(
5
-
count
)));
}
}
void
DeckManager
::
LoadLFList
(
irr
::
android
::
InitOptions
*
options
)
{
...
...
@@ -161,6 +256,27 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
if
(
!
lflist
)
return
0
;
auto
&
list
=
lflist
->
content
;
std
::
unordered_map
<
std
::
wstring
,
uint32_t
>
credit_used
;
auto
spend_credit
=
[
&
](
uint32_t
code
)
{
auto
code_credit_it
=
lflist
->
credits
.
find
(
code
);
if
(
code_credit_it
==
lflist
->
credits
.
end
())
return
(
uint32_t
)
0
;
auto
code_credit
=
code_credit_it
->
second
;
for
(
auto
&
credit_it
:
code_credit
)
{
auto
key
=
credit_it
.
first
;
auto
credit_limit_it
=
lflist
->
credit_limits
.
find
(
key
);
if
(
credit_limit_it
==
lflist
->
credit_limits
.
end
())
continue
;
auto
credit_limit
=
credit_limit_it
->
second
;
if
(
credit_used
.
find
(
key
)
==
credit_used
.
end
())
credit_used
[
key
]
=
0
;
auto
credit_after
=
credit_used
[
key
]
+
credit_it
.
second
;
if
(
credit_after
>
credit_limit
)
return
(
DECKERROR_LFLIST
<<
28
)
|
code
;
credit_used
[
key
]
=
credit_after
;
}
return
(
uint32_t
)
0
;
};
const
unsigned
int
rule_map
[
6
]
=
{
AVAIL_OCG
,
AVAIL_TCG
,
AVAIL_SC
,
AVAIL_CUSTOM
,
AVAIL_OCGTCG
,
0
};
unsigned
int
avail
=
0
;
if
(
rule
>=
0
&&
rule
<
(
int
)(
sizeof
rule_map
/
sizeof
rule_map
[
0
]))
...
...
@@ -179,6 +295,9 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
auto
it
=
list
.
find
(
code
);
if
(
it
!=
list
.
end
()
&&
dc
>
it
->
second
)
return
(
DECKERROR_LFLIST
<<
28
)
|
cit
->
first
;
auto
spend_credit_error
=
spend_credit
(
code
);
if
(
spend_credit_error
)
return
spend_credit_error
;
}
for
(
auto
&
cit
:
deck
.
extra
)
{
auto
gameruleDeckError
=
checkAvail
(
cit
->
second
.
ot
,
avail
);
...
...
@@ -194,6 +313,9 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
auto
it
=
list
.
find
(
code
);
if
(
it
!=
list
.
end
()
&&
dc
>
it
->
second
)
return
(
DECKERROR_LFLIST
<<
28
)
|
cit
->
first
;
auto
spend_credit_error
=
spend_credit
(
code
);
if
(
spend_credit_error
)
return
spend_credit_error
;
}
for
(
auto
&
cit
:
deck
.
side
)
{
auto
gameruleDeckError
=
checkAvail
(
cit
->
second
.
ot
,
avail
);
...
...
@@ -209,6 +331,9 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
auto
it
=
list
.
find
(
code
);
if
(
it
!=
list
.
end
()
&&
dc
>
it
->
second
)
return
(
DECKERROR_LFLIST
<<
28
)
|
cit
->
first
;
auto
spend_credit_error
=
spend_credit
(
code
);
if
(
spend_credit_error
)
return
spend_credit_error
;
}
return
0
;
}
...
...
Classes/gframe/deck_manager.h
View file @
c8ad16eb
...
...
@@ -28,6 +28,8 @@ struct LFList {
unsigned
int
hash
{};
std
::
wstring
listName
;
std
::
unordered_map
<
uint32_t
,
int
>
content
;
std
::
unordered_map
<
std
::
wstring
,
uint32_t
>
credit_limits
;
std
::
unordered_map
<
uint32_t
,
std
::
unordered_map
<
std
::
wstring
,
uint32_t
>>
credits
;
};
struct
Deck
{
std
::
vector
<
code_pointer
>
main
;
...
...
Classes/gframe/drawing.cpp
View file @
c8ad16eb
...
...
@@ -1537,7 +1537,33 @@ void Game::DrawThumb(code_pointer cp, irr::core::vector2di pos, const LFList* lf
break
;
}
}
auto
lfcredit
=
lflist
->
credits
.
find
(
lcode
);
auto
current_limitloc
=
limitloc
;
auto
credit_max_display
=
CARD_THUMB_WIDTH
/
20
;
auto
next_limitloc
=
[
&
]()
{
auto
this_limitloc
=
current_limitloc
;
auto
width
=
current_limitloc
.
getWidth
();
current_limitloc
.
UpperLeftCorner
.
X
+=
width
;
current_limitloc
.
LowerRightCorner
.
X
+=
width
;
--
credit_max_display
;
return
this_limitloc
;
};
if
(
lfcredit
!=
lflist
->
credits
.
end
())
{
for
(
auto
&
credit_entry
:
lfcredit
->
second
)
{
if
(
credit_max_display
<=
0
)
break
;
auto
value
=
credit_entry
.
second
;
if
(
value
>
0
&&
value
<=
100
)
{
auto
cvalue
=
value
-
1
;
// 1-100 => 0-99
// pick the first and second digit
auto
digit1
=
cvalue
/
10
;
auto
digit2
=
cvalue
%
10
;
auto
credit_texture_offset_x
=
digit2
*
64
;
auto
credit_texture_offset_y
=
digit1
*
64
;
driver
->
draw2DImage
(
imageManager
.
tLimCredit
,
next_limitloc
(),
irr
::
core
::
recti
(
credit_texture_offset_x
,
credit_texture_offset_y
,
credit_texture_offset_x
+
64
,
credit_texture_offset_y
+
64
),
0
,
0
,
true
);
}
}
}
// 判断是否需要显示可用性相关图标
bool
showAvail
=
false
;
bool
showNotAvail
=
false
;
...
...
Classes/gframe/image_manager.cpp
View file @
c8ad16eb
...
...
@@ -35,6 +35,7 @@ bool ImageManager::Initial(const path dir) {
tTarget
=
driver
->
getTexture
((
dir
+
path
(
"/textures/target.png"
)).
c_str
());
tChainTarget
=
driver
->
getTexture
((
dir
+
path
(
"/textures/chaintarget.png"
)).
c_str
());
tLim
=
driver
->
getTexture
((
dir
+
path
(
"/textures/lim.png"
)).
c_str
());
tLimCredit
=
driver
->
getTexture
((
dir
+
path
(
"/textures/limCredit.png"
)).
c_str
());
tOT
=
driver
->
getTexture
((
dir
+
path
(
"/textures/ot.png"
)).
c_str
());
tHand
[
0
]
=
driver
->
getTexture
((
dir
+
path
(
"/textures/f1.jpg"
)).
c_str
());
tHand
[
1
]
=
driver
->
getTexture
((
dir
+
path
(
"/textures/f2.jpg"
)).
c_str
());
...
...
Classes/gframe/image_manager.h
View file @
c8ad16eb
...
...
@@ -47,6 +47,7 @@ public:
irr
::
video
::
ITexture
*
tTarget
;
irr
::
video
::
ITexture
*
tChainTarget
;
irr
::
video
::
ITexture
*
tLim
;
irr
::
video
::
ITexture
*
tLimCredit
;
irr
::
video
::
ITexture
*
tOT
;
irr
::
video
::
ITexture
*
tHand
[
3
];
irr
::
video
::
ITexture
*
tBackGround
;
...
...
mobile/assets/data/textures/lim_credit.png
0 → 100644
View file @
c8ad16eb
87.9 KB
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