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
5689558d
Commit
5689558d
authored
Jul 28, 2025
by
fallenstardust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update gframe
parent
9d143828
Changes
23
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1139 additions
and
1347 deletions
+1139
-1347
Classes/gframe/bufferio.h
Classes/gframe/bufferio.h
+61
-166
Classes/gframe/client_card.cpp
Classes/gframe/client_card.cpp
+34
-34
Classes/gframe/client_field.cpp
Classes/gframe/client_field.cpp
+15
-8
Classes/gframe/data_manager.cpp
Classes/gframe/data_manager.cpp
+64
-80
Classes/gframe/data_manager.h
Classes/gframe/data_manager.h
+45
-21
Classes/gframe/deck_con.cpp
Classes/gframe/deck_con.cpp
+12
-12
Classes/gframe/deck_manager.cpp
Classes/gframe/deck_manager.cpp
+13
-6
Classes/gframe/deck_manager.h
Classes/gframe/deck_manager.h
+5
-2
Classes/gframe/drawing.cpp
Classes/gframe/drawing.cpp
+1
-1
Classes/gframe/duelclient.cpp
Classes/gframe/duelclient.cpp
+423
-422
Classes/gframe/duelclient.h
Classes/gframe/duelclient.h
+7
-6
Classes/gframe/game.cpp
Classes/gframe/game.cpp
+3
-6
Classes/gframe/menu_handler.cpp
Classes/gframe/menu_handler.cpp
+5
-5
Classes/gframe/netserver.cpp
Classes/gframe/netserver.cpp
+5
-4
Classes/gframe/netserver.h
Classes/gframe/netserver.h
+8
-7
Classes/gframe/network.h
Classes/gframe/network.h
+1
-2
Classes/gframe/replay.cpp
Classes/gframe/replay.cpp
+2
-27
Classes/gframe/replay.h
Classes/gframe/replay.h
+4
-2
Classes/gframe/replay_mode.cpp
Classes/gframe/replay_mode.cpp
+63
-63
Classes/gframe/single_duel.cpp
Classes/gframe/single_duel.cpp
+118
-118
Classes/gframe/single_mode.cpp
Classes/gframe/single_mode.cpp
+68
-68
Classes/gframe/tag_duel.cpp
Classes/gframe/tag_duel.cpp
+121
-121
libcore/android/bufferio_android.h
libcore/android/bufferio_android.h
+61
-166
No files found.
Classes/gframe/bufferio.h
View file @
5689558d
...
...
@@ -2,31 +2,52 @@
#define BUFFERIO_H
#include <cstdint>
#include <cstring>
#include <cwchar>
#include "../ocgcore/buffer.h"
class
BufferIO
{
public:
static
int
ReadInt32
(
unsigned
char
*&
p
)
{
return
buffer_read
<
int32_t
>
(
p
);
template
<
typename
T
>
static
T
Read
(
unsigned
char
*&
p
)
{
T
ret
{};
std
::
memcpy
(
&
ret
,
p
,
sizeof
(
T
));
p
+=
sizeof
(
T
);
return
ret
;
}
template
<
typename
T
>
static
void
Write
(
unsigned
char
*&
p
,
T
value
)
{
std
::
memcpy
(
p
,
&
value
,
sizeof
(
T
));
p
+=
sizeof
(
T
);
}
// for compatibility
[[
deprecated
]]
static
int32_t
ReadInt32
(
unsigned
char
*&
p
)
{
return
Read
<
int32_t
>
(
p
);
}
[[
deprecated
]]
static
short
ReadInt16
(
unsigned
char
*&
p
)
{
return
buffer_r
ead
<
int16_t
>
(
p
);
return
R
ead
<
int16_t
>
(
p
);
}
[[
deprecated
]]
static
char
ReadInt8
(
unsigned
char
*&
p
)
{
return
buffer_r
ead
<
char
>
(
p
);
return
R
ead
<
char
>
(
p
);
}
[[
deprecated
]]
static
unsigned
char
ReadUInt8
(
unsigned
char
*&
p
)
{
return
buffer_r
ead
<
unsigned
char
>
(
p
);
return
R
ead
<
unsigned
char
>
(
p
);
}
static
void
WriteInt32
(
unsigned
char
*&
p
,
int
val
)
{
buffer_write
<
int32_t
>
(
p
,
val
);
[[
deprecated
]]
static
void
WriteInt32
(
unsigned
char
*&
p
,
int32_t
val
)
{
Write
<
int32_t
>
(
p
,
val
);
}
[[
deprecated
]]
static
void
WriteInt16
(
unsigned
char
*&
p
,
short
val
)
{
buffer_w
rite
<
int16_t
>
(
p
,
val
);
W
rite
<
int16_t
>
(
p
,
val
);
}
[[
deprecated
]]
static
void
WriteInt8
(
unsigned
char
*&
p
,
char
val
)
{
buffer_w
rite
<
char
>
(
p
,
val
);
W
rite
<
char
>
(
p
,
val
);
}
/**
* @brief Copy a C-style string to another C-style string.
...
...
@@ -61,64 +82,18 @@ public:
return
CopyWStr
(
src
,
dst
,
N
);
}
template
<
size_t
N
>
static
void
CopyString
(
const
char
*
src
,
char
(
&
dst
)[
N
])
{
std
::
strncpy
(
dst
,
src
,
N
-
1
);
dst
[
N
-
1
]
=
0
;
static
void
CopyString
(
const
char
*
src
,
char
(
&
dst
)[
N
],
size_t
len
=
N
-
1
)
{
if
(
len
>=
N
)
len
=
N
-
1
;
std
::
strncpy
(
dst
,
src
,
len
);
dst
[
len
]
=
0
;
}
template
<
size_t
N
>
static
void
CopyWideString
(
const
wchar_t
*
src
,
wchar_t
(
&
dst
)[
N
])
{
std
::
wcsncpy
(
dst
,
src
,
N
-
1
);
dst
[
N
-
1
]
=
0
;
}
template
<
typename
T
>
static
bool
CheckUTF8Byte
(
const
T
*
str
,
int
len
)
{
for
(
int
i
=
1
;
i
<
len
;
++
i
)
{
if
((
str
[
i
]
&
0xc0U
)
!=
0x80U
)
return
false
;
}
return
true
;
}
static
unsigned
int
ConvertUTF8
(
const
char
*&
p
)
{
unsigned
int
cur
=
0
;
if
((
p
[
0
]
&
0x80U
)
==
0
)
{
cur
=
p
[
0
]
&
0xffU
;
p
++
;
}
else
if
((
p
[
0
]
&
0xe0U
)
==
0xc0U
)
{
if
(
!
CheckUTF8Byte
(
p
,
2
))
{
p
++
;
return
UINT32_MAX
;
}
cur
=
((
p
[
0
]
&
0x1fU
)
<<
6
)
|
(
p
[
1
]
&
0x3fU
);
p
+=
2
;
if
(
cur
<
0x80U
)
return
UINT32_MAX
;
}
else
if
((
p
[
0
]
&
0xf0U
)
==
0xe0U
)
{
if
(
!
CheckUTF8Byte
(
p
,
3
))
{
p
++
;
return
UINT32_MAX
;
}
cur
=
((
p
[
0
]
&
0xfU
)
<<
12
)
|
((
p
[
1
]
&
0x3fU
)
<<
6
)
|
(
p
[
2
]
&
0x3fU
);
p
+=
3
;
if
(
cur
<
0x800U
)
return
UINT32_MAX
;
}
else
if
((
p
[
0
]
&
0xf8U
)
==
0xf0U
)
{
if
(
!
CheckUTF8Byte
(
p
,
4
))
{
p
++
;
return
UINT32_MAX
;
}
cur
=
((
p
[
0
]
&
0x7U
)
<<
18
)
|
((
p
[
1
]
&
0x3fU
)
<<
12
)
|
((
p
[
2
]
&
0x3fU
)
<<
6
)
|
(
p
[
3
]
&
0x3fU
);
p
+=
4
;
if
(
cur
<
0x10000U
)
return
UINT32_MAX
;
}
else
{
p
++
;
return
UINT32_MAX
;
}
return
cur
;
static
void
CopyWideString
(
const
wchar_t
*
src
,
wchar_t
(
&
dst
)[
N
],
size_t
len
=
N
-
1
)
{
if
(
len
>=
N
)
len
=
N
-
1
;
std
::
wcsncpy
(
dst
,
src
,
len
);
dst
[
len
]
=
0
;
}
static
bool
IsHighSurrogate
(
unsigned
int
c
)
{
return
(
c
>=
0xd800U
&&
c
<=
0xdbffU
);
...
...
@@ -137,111 +112,31 @@ public:
}
// UTF-16/UTF-32 to UTF-8
// return: string length
static
int
EncodeUTF8String
(
const
wchar_t
*
wsrc
,
char
*
str
,
int
size
)
{
auto
pw
=
wsrc
;
auto
pstr
=
str
;
while
(
*
pw
!=
0
)
{
unsigned
cur
=
0
;
int
codepoint_size
=
0
;
if
(
sizeof
(
wchar_t
)
==
2
)
{
if
(
IsHighSurrogate
(
pw
[
0
]))
{
if
(
pw
[
1
]
==
0
)
break
;
if
(
IsLowSurrogate
(
pw
[
1
]))
{
cur
=
((
pw
[
0
]
&
0x3ffU
)
<<
10
)
|
(
pw
[
1
]
&
0x3ffU
);
cur
+=
0x10000
;
pw
+=
2
;
}
else
{
pw
++
;
continue
;
}
}
else
if
(
IsLowSurrogate
(
pw
[
0
]))
{
pw
++
;
continue
;
}
else
{
cur
=
*
pw
;
pw
++
;
}
}
else
{
cur
=
*
pw
;
pw
++
;
}
if
(
!
IsUnicodeChar
(
cur
))
continue
;
if
(
cur
<
0x80U
)
codepoint_size
=
1
;
else
if
(
cur
<
0x800U
)
codepoint_size
=
2
;
else
if
(
cur
<
0x10000U
)
codepoint_size
=
3
;
else
codepoint_size
=
4
;
if
((
int
)(
pstr
-
str
)
+
codepoint_size
>
size
-
1
)
break
;
switch
(
codepoint_size
)
{
case
1
:
*
pstr
=
(
char
)
cur
;
break
;
case
2
:
pstr
[
0
]
=
((
cur
>>
6
)
&
0x1f
)
|
0xc0
;
pstr
[
1
]
=
(
cur
&
0x3f
)
|
0x80
;
break
;
case
3
:
pstr
[
0
]
=
((
cur
>>
12
)
&
0xf
)
|
0xe0
;
pstr
[
1
]
=
((
cur
>>
6
)
&
0x3f
)
|
0x80
;
pstr
[
2
]
=
(
cur
&
0x3f
)
|
0x80
;
break
;
case
4
:
pstr
[
0
]
=
((
cur
>>
18
)
&
0x7
)
|
0xf0
;
pstr
[
1
]
=
((
cur
>>
12
)
&
0x3f
)
|
0x80
;
pstr
[
2
]
=
((
cur
>>
6
)
&
0x3f
)
|
0x80
;
pstr
[
3
]
=
(
cur
&
0x3f
)
|
0x80
;
break
;
default:
break
;
}
pstr
+=
codepoint_size
;
static
int
EncodeUTF8String
(
const
wchar_t
*
wsrc
,
char
*
str
,
size_t
len
)
{
if
(
len
==
0
)
{
str
[
0
]
=
0
;
return
0
;
}
*
pstr
=
0
;
return
(
int
)(
pstr
-
str
);
std
::
mbstate_t
state
{};
size_t
result_len
=
std
::
wcsrtombs
(
str
,
&
wsrc
,
len
-
1
,
&
state
);
if
(
result_len
==
static_cast
<
size_t
>
(
-
1
))
result_len
=
0
;
str
[
result_len
]
=
0
;
return
static_cast
<
int
>
(
result_len
);
}
// UTF-8 to UTF-16/UTF-32
// return: string length
static
int
DecodeUTF8String
(
const
char
*
src
,
wchar_t
*
wstr
,
int
size
)
{
const
char
*
p
=
src
;
wchar_t
*
wp
=
wstr
;
while
(
*
p
!=
0
)
{
unsigned
int
cur
=
ConvertUTF8
(
p
);
int
codepoint_size
=
0
;
if
(
!
IsUnicodeChar
(
cur
))
continue
;
if
(
cur
>=
0x10000
)
{
if
(
sizeof
(
wchar_t
)
==
2
)
codepoint_size
=
2
;
else
codepoint_size
=
1
;
}
else
codepoint_size
=
1
;
if
((
int
)(
wp
-
wstr
)
+
codepoint_size
>
size
-
1
)
break
;
if
(
codepoint_size
==
1
)
{
wp
[
0
]
=
cur
;
wp
++
;
}
else
{
cur
-=
0x10000U
;
wp
[
0
]
=
(
cur
>>
10
)
|
0xd800
;
wp
[
1
]
=
(
cur
&
0x3ff
)
|
0xdc00
;
wp
+=
2
;
}
static
int
DecodeUTF8String
(
const
char
*
src
,
wchar_t
*
wstr
,
size_t
len
)
{
if
(
len
==
0
)
{
wstr
[
0
]
=
0
;
return
0
;
}
*
wp
=
0
;
return
wp
-
wstr
;
std
::
mbstate_t
state
{};
size_t
result_len
=
std
::
mbsrtowcs
(
wstr
,
&
src
,
len
-
1
,
&
state
);
if
(
result_len
==
static_cast
<
size_t
>
(
-
1
))
result_len
=
0
;
wstr
[
result_len
]
=
0
;
return
static_cast
<
int
>
(
result_len
);
}
template
<
size_t
N
>
static
int
EncodeUTF8
(
const
wchar_t
*
src
,
char
(
&
dst
)[
N
])
{
...
...
Classes/gframe/client_card.cpp
View file @
5689558d
...
...
@@ -39,13 +39,13 @@ void ClientCard::SetCode(unsigned int x) {
code
=
x
;
}
void
ClientCard
::
UpdateInfo
(
unsigned
char
*
buf
)
{
int
flag
=
BufferIO
::
Read
Int32
(
buf
);
int
flag
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
==
0
)
{
ClearData
();
return
;
}
if
(
flag
&
QUERY_CODE
)
{
int
pdata
=
BufferIO
::
Read
Int32
(
buf
);
int
pdata
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
!
pdata
)
ClearData
();
if
((
location
==
LOCATION_HAND
)
&&
((
unsigned
int
)
pdata
!=
code
))
{
...
...
@@ -55,7 +55,7 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
code
=
pdata
;
}
if
(
flag
&
QUERY_POSITION
)
{
int
pdata
=
(
BufferIO
::
Read
Int32
(
buf
)
>>
24
)
&
0xff
;
int
pdata
=
(
BufferIO
::
Read
<
int32_t
>
(
buf
)
>>
24
)
&
0xff
;
if
((
location
&
(
LOCATION_EXTRA
|
LOCATION_REMOVED
))
&&
pdata
!=
position
)
{
position
=
pdata
;
mainGame
->
dField
.
MoveCard
(
this
,
1
);
...
...
@@ -63,29 +63,29 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
position
=
pdata
;
}
if
(
flag
&
QUERY_ALIAS
)
alias
=
BufferIO
::
Read
Int32
(
buf
);
alias
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_TYPE
)
type
=
BufferIO
::
Read
Int32
(
buf
);
type
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_LEVEL
)
{
int
pdata
=
BufferIO
::
Read
Int32
(
buf
);
int
pdata
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
level
!=
(
unsigned
int
)
pdata
)
{
level
=
pdata
;
myswprintf
(
lvstring
,
L"L%d"
,
level
);
}
}
if
(
flag
&
QUERY_RANK
)
{
int
pdata
=
BufferIO
::
Read
Int32
(
buf
);
int
pdata
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
pdata
&&
rank
!=
(
unsigned
int
)
pdata
)
{
rank
=
pdata
;
myswprintf
(
lvstring
,
L"R%d"
,
rank
);
}
}
if
(
flag
&
QUERY_ATTRIBUTE
)
attribute
=
BufferIO
::
Read
Int32
(
buf
);
attribute
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_RACE
)
race
=
BufferIO
::
Read
Int32
(
buf
);
race
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_ATTACK
)
{
attack
=
BufferIO
::
Read
Int32
(
buf
);
attack
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
attack
<
0
)
{
atkstring
[
0
]
=
'?'
;
atkstring
[
1
]
=
0
;
...
...
@@ -93,7 +93,7 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
myswprintf
(
atkstring
,
L"%d"
,
attack
);
}
if
(
flag
&
QUERY_DEFENSE
)
{
defense
=
BufferIO
::
Read
Int32
(
buf
);
defense
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
type
&
TYPE_LINK
)
{
defstring
[
0
]
=
'-'
;
defstring
[
1
]
=
0
;
...
...
@@ -104,18 +104,18 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
myswprintf
(
defstring
,
L"%d"
,
defense
);
}
if
(
flag
&
QUERY_BASE_ATTACK
)
base_attack
=
BufferIO
::
Read
Int32
(
buf
);
base_attack
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_BASE_DEFENSE
)
base_defense
=
BufferIO
::
Read
Int32
(
buf
);
base_defense
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_REASON
)
reason
=
BufferIO
::
Read
Int32
(
buf
);
reason
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_REASON_CARD
)
buf
+=
4
;
if
(
flag
&
QUERY_EQUIP_CARD
)
{
int
c
=
BufferIO
::
Read
UInt8
(
buf
);
unsigned
int
l
=
BufferIO
::
Read
UInt8
(
buf
);
int
s
=
BufferIO
::
Read
UInt8
(
buf
);
BufferIO
::
Read
UInt8
(
buf
);
int
c
=
BufferIO
::
Read
<
uint8_t
>
(
buf
);
unsigned
int
l
=
BufferIO
::
Read
<
uint8_t
>
(
buf
);
int
s
=
BufferIO
::
Read
<
uint8_t
>
(
buf
);
BufferIO
::
Read
<
uint8_t
>
(
buf
);
ClientCard
*
ecard
=
mainGame
->
dField
.
GetCard
(
mainGame
->
LocalPlayer
(
c
),
l
,
s
);
if
(
ecard
)
{
equipTarget
=
ecard
;
...
...
@@ -123,12 +123,12 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
}
}
if
(
flag
&
QUERY_TARGET_CARD
)
{
int
count
=
BufferIO
::
Read
Int32
(
buf
);
int
count
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
int
c
=
BufferIO
::
Read
UInt8
(
buf
);
unsigned
int
l
=
BufferIO
::
Read
UInt8
(
buf
);
int
s
=
BufferIO
::
Read
UInt8
(
buf
);
BufferIO
::
Read
UInt8
(
buf
);
int
c
=
BufferIO
::
Read
<
uint8_t
>
(
buf
);
unsigned
int
l
=
BufferIO
::
Read
<
uint8_t
>
(
buf
);
int
s
=
BufferIO
::
Read
<
uint8_t
>
(
buf
);
BufferIO
::
Read
<
uint8_t
>
(
buf
);
ClientCard
*
tcard
=
mainGame
->
dField
.
GetCard
(
mainGame
->
LocalPlayer
(
c
),
l
,
s
);
if
(
tcard
)
{
cardTarget
.
insert
(
tcard
);
...
...
@@ -137,38 +137,38 @@ void ClientCard::UpdateInfo(unsigned char* buf) {
}
}
if
(
flag
&
QUERY_OVERLAY_CARD
)
{
int
count
=
BufferIO
::
Read
Int32
(
buf
);
int
count
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
overlayed
[
i
]
->
SetCode
(
BufferIO
::
Read
Int32
(
buf
));
overlayed
[
i
]
->
SetCode
(
BufferIO
::
Read
<
int32_t
>
(
buf
));
}
}
if
(
flag
&
QUERY_COUNTERS
)
{
int
count
=
BufferIO
::
Read
Int32
(
buf
);
int
count
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
int
ctype
=
BufferIO
::
Read
Int16
(
buf
);
int
ccount
=
BufferIO
::
Read
Int16
(
buf
);
int
ctype
=
BufferIO
::
Read
<
uint16_t
>
(
buf
);
int
ccount
=
BufferIO
::
Read
<
uint16_t
>
(
buf
);
counters
[
ctype
]
=
ccount
;
}
}
if
(
flag
&
QUERY_OWNER
)
owner
=
BufferIO
::
Read
Int32
(
buf
);
owner
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_STATUS
)
status
=
BufferIO
::
Read
Int32
(
buf
);
status
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
flag
&
QUERY_LSCALE
)
{
lscale
=
BufferIO
::
Read
Int32
(
buf
);
lscale
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
myswprintf
(
lscstring
,
L"%d"
,
lscale
);
}
if
(
flag
&
QUERY_RSCALE
)
{
rscale
=
BufferIO
::
Read
Int32
(
buf
);
rscale
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
myswprintf
(
rscstring
,
L"%d"
,
rscale
);
}
if
(
flag
&
QUERY_LINK
)
{
int
pdata
=
BufferIO
::
Read
Int32
(
buf
);
int
pdata
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
link
!=
(
unsigned
int
)
pdata
)
{
link
=
pdata
;
}
myswprintf
(
linkstring
,
L"L
\x2013
%d"
,
link
);
pdata
=
BufferIO
::
Read
Int32
(
buf
);
pdata
=
BufferIO
::
Read
<
int32_t
>
(
buf
);
if
(
link_marker
!=
(
unsigned
int
)
pdata
)
{
link_marker
=
pdata
;
}
...
...
Classes/gframe/client_field.cpp
View file @
5689558d
...
...
@@ -332,7 +332,7 @@ ClientCard* ClientField::RemoveCard(int controler, int location, int sequence) {
}
void
ClientField
::
UpdateCard
(
int
controler
,
int
location
,
int
sequence
,
unsigned
char
*
data
)
{
ClientCard
*
pcard
=
GetCard
(
controler
,
location
,
sequence
);
int
len
=
BufferIO
::
Read
Int32
(
data
);
int
len
=
BufferIO
::
Read
<
int32_t
>
(
data
);
if
(
pcard
&&
len
>
LEN_HEADER
)
pcard
->
UpdateInfo
(
data
);
RefreshCardCountDisplay
();
...
...
@@ -366,7 +366,7 @@ void ClientField::UpdateFieldCard(int controler, int location, unsigned char* da
return
;
int
len
;
for
(
auto
cit
=
lst
->
begin
();
cit
!=
lst
->
end
();
++
cit
)
{
len
=
BufferIO
::
Read
Int32
(
data
);
len
=
BufferIO
::
Read
<
int32_t
>
(
data
);
if
(
len
>
LEN_HEADER
)
(
*
cit
)
->
UpdateInfo
(
data
);
data
+=
len
-
4
;
...
...
@@ -1422,7 +1422,8 @@ bool ClientField::check_sum_trib(std::set<ClientCard*>::const_iterator index, st
||
check_sum_trib
(
index
,
end
,
acc
+
l2
)
||
check_sum_trib
(
index
,
end
,
acc
);
}
static
bool
is_declarable
(
const
CardData
&
cd
,
const
std
::
vector
<
unsigned
int
>&
opcode
)
{
template
<
class
T
>
static
bool
is_declarable
(
const
T
&
cd
,
const
std
::
vector
<
unsigned
int
>&
opcode
)
{
std
::
stack
<
int
>
stack
;
for
(
auto
it
=
opcode
.
begin
();
it
!=
opcode
.
end
();
++
it
)
{
switch
(
*
it
)
{
...
...
@@ -1512,9 +1513,15 @@ static bool is_declarable(const CardData& cd, const std::vector<unsigned int>& o
}
case
OPCODE_ISSETCARD
:
{
if
(
stack
.
size
()
>=
1
)
{
in
t
set_code
=
stack
.
top
();
uint32_
t
set_code
=
stack
.
top
();
stack
.
pop
();
bool
res
=
cd
.
is_setcode
(
set_code
);
bool
res
=
false
;
for
(
const
auto
&
x
:
cd
.
setcode
)
{
if
(
check_setcode
(
x
,
set_code
))
{
res
=
true
;
break
;
}
}
stack
.
push
(
res
);
}
break
;
...
...
@@ -1558,12 +1565,12 @@ static bool is_declarable(const CardData& cd, const std::vector<unsigned int>& o
void
ClientField
::
UpdateDeclarableList
()
{
const
wchar_t
*
pname
=
mainGame
->
ebANCard
->
getText
();
int
trycode
=
BufferIO
::
GetVal
(
pname
);
CardString
cstr
;
CardData
cd
;
if
(
dataManager
.
GetString
(
trycode
,
&
cstr
)
&&
dataManager
.
GetData
(
trycode
,
&
cd
)
&&
is_declarable
(
cd
,
declare_opcodes
))
{
if
(
dataManager
.
GetData
(
trycode
,
&
cd
)
&&
is_declarable
(
cd
,
declare_opcodes
))
{
auto
it
=
dataManager
.
GetStringPointer
(
trycode
);
mainGame
->
lstANCard
->
clear
();
ancard
.
clear
();
mainGame
->
lstANCard
->
addItem
(
cstr
.
name
.
c_str
());
mainGame
->
lstANCard
->
addItem
(
it
->
second
.
name
.
c_str
());
ancard
.
push_back
(
trycode
);
return
;
}
...
...
Classes/gframe/data_manager.cpp
View file @
5689558d
...
...
@@ -15,69 +15,63 @@ DataManager::DataManager() : _datas(32768), _strings(32768) {
bool
DataManager
::
ReadDB
(
sqlite3
*
pDB
)
{
sqlite3_stmt
*
pStmt
=
nullptr
;
const
char
*
sql
=
"select * from datas,texts where datas.id=texts.id"
;
if
(
sqlite3_prepare_v2
(
pDB
,
sql
,
-
1
,
&
pStmt
,
0
)
!=
SQLITE_OK
)
if
(
sqlite3_prepare_v2
(
pDB
,
sql
,
-
1
,
&
pStmt
,
nullptr
)
!=
SQLITE_OK
)
return
Error
(
pDB
,
pStmt
);
wchar_t
strBuffer
[
4096
];
int
step
=
0
;
do
{
CardDataC
cd
;
CardString
cs
;
step
=
sqlite3_step
(
pStmt
);
if
(
step
==
SQLITE_ROW
)
{
cd
.
code
=
sqlite3_column_int
(
pStmt
,
0
);
cd
.
ot
=
sqlite3_column_int
(
pStmt
,
1
);
cd
.
alias
=
sqlite3_column_int
(
pStmt
,
2
);
uint64_t
setcode
=
static_cast
<
uint64_t
>
(
sqlite3_column_int64
(
pStmt
,
3
));
if
(
setcode
)
{
auto
it
=
extra_setcode
.
find
(
cd
.
code
);
if
(
it
!=
extra_setcode
.
end
())
{
int
len
=
it
->
second
.
size
();
if
(
len
>
SIZE_SETCODE
)
len
=
SIZE_SETCODE
;
if
(
len
)
std
::
memcpy
(
cd
.
setcode
,
it
->
second
.
data
(),
len
*
sizeof
(
uint16_t
));
}
else
cd
.
set_setcode
(
setcode
);
}
cd
.
type
=
static_cast
<
decltype
(
cd
.
type
)
>
(
sqlite3_column_int64
(
pStmt
,
4
));
cd
.
attack
=
sqlite3_column_int
(
pStmt
,
5
);
cd
.
defense
=
sqlite3_column_int
(
pStmt
,
6
);
if
(
cd
.
type
&
TYPE_LINK
)
{
cd
.
link_marker
=
cd
.
defense
;
cd
.
defense
=
0
;
}
else
cd
.
link_marker
=
0
;
uint32_t
level
=
static_cast
<
uint32_t
>
(
sqlite3_column_int
(
pStmt
,
7
));
cd
.
level
=
level
&
0xff
;
cd
.
lscale
=
(
level
>>
24
)
&
0xff
;
cd
.
rscale
=
(
level
>>
16
)
&
0xff
;
cd
.
race
=
static_cast
<
decltype
(
cd
.
race
)
>
(
sqlite3_column_int64
(
pStmt
,
8
));
cd
.
attribute
=
static_cast
<
decltype
(
cd
.
attribute
)
>
(
sqlite3_column_int64
(
pStmt
,
9
));
cd
.
category
=
static_cast
<
decltype
(
cd
.
category
)
>
(
sqlite3_column_int64
(
pStmt
,
10
));
_datas
[
cd
.
code
]
=
cd
;
if
(
const
char
*
text
=
(
const
char
*
)
sqlite3_column_text
(
pStmt
,
12
))
{
BufferIO
::
DecodeUTF8
(
text
,
strBuffer
);
cs
.
name
=
strBuffer
;
}
if
(
const
char
*
text
=
(
const
char
*
)
sqlite3_column_text
(
pStmt
,
13
))
{
for
(
int
step
=
sqlite3_step
(
pStmt
);
step
!=
SQLITE_DONE
;
step
=
sqlite3_step
(
pStmt
))
{
if
(
step
!=
SQLITE_ROW
)
return
Error
(
pDB
,
pStmt
);
uint32_t
code
=
static_cast
<
uint32_t
>
(
sqlite3_column_int64
(
pStmt
,
0
));
auto
&
cd
=
_datas
[
code
];
cd
.
code
=
code
;
cd
.
ot
=
sqlite3_column_int
(
pStmt
,
1
);
cd
.
alias
=
sqlite3_column_int
(
pStmt
,
2
);
uint64_t
setcode
=
static_cast
<
uint64_t
>
(
sqlite3_column_int64
(
pStmt
,
3
));
write_setcode
(
cd
.
setcode
,
setcode
);
cd
.
type
=
static_cast
<
decltype
(
cd
.
type
)
>
(
sqlite3_column_int64
(
pStmt
,
4
));
cd
.
attack
=
sqlite3_column_int
(
pStmt
,
5
);
cd
.
defense
=
sqlite3_column_int
(
pStmt
,
6
);
if
(
cd
.
type
&
TYPE_LINK
)
{
cd
.
link_marker
=
cd
.
defense
;
cd
.
defense
=
0
;
}
else
cd
.
link_marker
=
0
;
uint32_t
level
=
static_cast
<
uint32_t
>
(
sqlite3_column_int64
(
pStmt
,
7
));
cd
.
level
=
level
&
0xff
;
cd
.
lscale
=
(
level
>>
24
)
&
0xff
;
cd
.
rscale
=
(
level
>>
16
)
&
0xff
;
cd
.
race
=
static_cast
<
decltype
(
cd
.
race
)
>
(
sqlite3_column_int64
(
pStmt
,
8
));
cd
.
attribute
=
static_cast
<
decltype
(
cd
.
attribute
)
>
(
sqlite3_column_int64
(
pStmt
,
9
));
cd
.
category
=
static_cast
<
decltype
(
cd
.
category
)
>
(
sqlite3_column_int64
(
pStmt
,
10
));
auto
&
cs
=
_strings
[
code
];
if
(
const
char
*
text
=
(
const
char
*
)
sqlite3_column_text
(
pStmt
,
12
))
{
BufferIO
::
DecodeUTF8
(
text
,
strBuffer
);
cs
.
name
=
strBuffer
;
}
if
(
const
char
*
text
=
(
const
char
*
)
sqlite3_column_text
(
pStmt
,
13
))
{
BufferIO
::
DecodeUTF8
(
text
,
strBuffer
);
cs
.
text
=
strBuffer
;
}
constexpr
int
desc_count
=
sizeof
cs
.
desc
/
sizeof
cs
.
desc
[
0
];
for
(
int
i
=
0
;
i
<
desc_count
;
++
i
)
{
if
(
const
char
*
text
=
(
const
char
*
)
sqlite3_column_text
(
pStmt
,
i
+
14
))
{
BufferIO
::
DecodeUTF8
(
text
,
strBuffer
);
cs
.
text
=
strBuffer
;
}
constexpr
int
desc_count
=
sizeof
cs
.
desc
/
sizeof
cs
.
desc
[
0
];
for
(
int
i
=
0
;
i
<
desc_count
;
++
i
)
{
if
(
const
char
*
text
=
(
const
char
*
)
sqlite3_column_text
(
pStmt
,
i
+
14
))
{
BufferIO
::
DecodeUTF8
(
text
,
strBuffer
);
cs
.
desc
[
i
]
=
strBuffer
;
}
cs
.
desc
[
i
]
=
strBuffer
;
}
_strings
[
cd
.
code
]
=
cs
;
}
else
if
(
step
!=
SQLITE_DONE
)
return
Error
(
pDB
,
pStmt
);
}
while
(
step
==
SQLITE_ROW
);
}
sqlite3_finalize
(
pStmt
);
for
(
const
auto
&
entry
:
extra_setcode
)
{
const
auto
&
code
=
entry
.
first
;
const
auto
&
list
=
entry
.
second
;
if
(
list
.
size
()
>
SIZE_SETCODE
||
list
.
empty
())
continue
;
auto
it
=
_datas
.
find
(
code
);
if
(
it
==
_datas
.
end
())
continue
;
std
::
memcpy
(
it
->
second
.
setcode
,
list
.
data
(),
list
.
size
()
*
sizeof
(
uint16_t
));
}
return
true
;
}
bool
DataManager
::
LoadDB
(
const
wchar_t
*
wfile
)
{
...
...
@@ -161,40 +155,30 @@ void DataManager::ReadStringConfLine(const char* linebuf) {
}
}
bool
DataManager
::
Error
(
sqlite3
*
pDB
,
sqlite3_stmt
*
pStmt
)
{
std
::
snprintf
(
errmsg
,
sizeof
errmsg
,
"%s"
,
sqlite3_errmsg
(
pDB
));
if
(
pStmt
)
sqlite3_finalize
(
pStmt
);
if
(
const
char
*
msg
=
sqlite3_errmsg
(
pDB
))
std
::
snprintf
(
errmsg
,
sizeof
errmsg
,
"%s"
,
msg
);
else
errmsg
[
0
]
=
'\0'
;
sqlite3_finalize
(
pStmt
);
ALOGE
(
"cc data_manager: cdb Error="
,
errmsg
);
return
false
;
}
code_pointer
DataManager
::
GetCodePointer
(
u
nsigned
in
t
code
)
const
{
code_pointer
DataManager
::
GetCodePointer
(
u
int32_
t
code
)
const
{
return
_datas
.
find
(
code
);
}
string_pointer
DataManager
::
GetStringPointer
(
u
nsigned
in
t
code
)
const
{
string_pointer
DataManager
::
GetStringPointer
(
u
int32_
t
code
)
const
{
return
_strings
.
find
(
code
);
}
code_pointer
DataManager
::
datas_begin
()
const
{
return
_datas
.
cbegin
();
}
code_pointer
DataManager
::
datas_end
()
const
{
return
_datas
.
cend
();
}
string_pointer
DataManager
::
strings_begin
()
const
{
return
_strings
.
cbegin
();
}
string_pointer
DataManager
::
strings_end
()
const
{
return
_strings
.
cend
();
}
bool
DataManager
::
GetData
(
unsigned
int
code
,
CardData
*
pData
)
const
{
bool
DataManager
::
GetData
(
uint32_t
code
,
CardData
*
pData
)
const
{
auto
cdit
=
_datas
.
find
(
code
);
if
(
cdit
==
_datas
.
end
())
return
false
;
if
(
pData
)
{
*
pData
=
cdit
->
second
;
std
::
memcpy
(
pData
,
&
cdit
->
second
,
sizeof
(
CardData
))
;
}
return
true
;
}
bool
DataManager
::
GetString
(
u
nsigned
in
t
code
,
CardString
*
pStr
)
const
{
bool
DataManager
::
GetString
(
u
int32_
t
code
,
CardString
*
pStr
)
const
{
auto
csit
=
_strings
.
find
(
code
);
if
(
csit
==
_strings
.
end
())
{
pStr
->
name
=
unknown_string
;
...
...
@@ -204,7 +188,7 @@ bool DataManager::GetString(unsigned int code, CardString* pStr) const {
*
pStr
=
csit
->
second
;
return
true
;
}
const
wchar_t
*
DataManager
::
GetName
(
u
nsigned
in
t
code
)
const
{
const
wchar_t
*
DataManager
::
GetName
(
u
int32_
t
code
)
const
{
auto
csit
=
_strings
.
find
(
code
);
if
(
csit
==
_strings
.
end
())
return
unknown_string
;
...
...
@@ -212,7 +196,7 @@ const wchar_t* DataManager::GetName(unsigned int code) const {
return
csit
->
second
.
name
.
c_str
();
return
unknown_string
;
}
const
wchar_t
*
DataManager
::
GetText
(
u
nsigned
in
t
code
)
const
{
const
wchar_t
*
DataManager
::
GetText
(
u
int32_
t
code
)
const
{
auto
csit
=
_strings
.
find
(
code
);
if
(
csit
==
_strings
.
end
())
return
unknown_string
;
...
...
@@ -220,7 +204,7 @@ const wchar_t* DataManager::GetText(unsigned int code) const {
return
csit
->
second
.
text
.
c_str
();
return
unknown_string
;
}
const
wchar_t
*
DataManager
::
GetDesc
(
u
nsigned
in
t
strCode
)
const
{
const
wchar_t
*
DataManager
::
GetDesc
(
u
int32_
t
strCode
)
const
{
if
(
strCode
<
(
MIN_CARD_ID
<<
4
))
return
GetSysString
(
strCode
);
unsigned
int
code
=
(
strCode
>>
4
)
&
0x0fffffff
;
...
...
Classes/gframe/data_manager.h
View file @
5689558d
...
...
@@ -16,18 +16,34 @@ namespace irr {
namespace
ygo
{
constexpr
int
MAX_STRING_ID
=
0x7ff
;
constexpr
u
nsigned
int
MIN_CARD_ID
=
(
unsigned
in
t
)(
MAX_STRING_ID
+
1
)
>>
4
;
constexpr
u
nsigned
in
t
MAX_CARD_ID
=
0x0fffffffU
;
constexpr
u
int32_t
MIN_CARD_ID
=
(
uint32_
t
)(
MAX_STRING_ID
+
1
)
>>
4
;
constexpr
u
int32_
t
MAX_CARD_ID
=
0x0fffffffU
;
using
CardData
=
card_data
;
struct
CardDataC
:
card_data
{
struct
CardDataC
{
uint32_t
code
{};
uint32_t
alias
{};
uint16_t
setcode
[
SIZE_SETCODE
]{};
uint32_t
type
{};
uint32_t
level
{};
uint32_t
attribute
{};
uint32_t
race
{};
int32_t
attack
{};
int32_t
defense
{};
uint32_t
lscale
{};
uint32_t
rscale
{};
uint32_t
link_marker
{};
uint32_t
ot
{};
uint32_t
category
{};
bool
is_setcodes
(
const
std
::
vector
<
unsigned
int
>&
values
)
const
{
for
(
auto
&
value
:
values
)
{
if
(
is_setcode
(
value
))
return
true
;
for
(
const
auto
&
x
:
setcode
)
{
if
(
!
x
)
break
;
if
(
check_setcode
(
x
,
value
))
return
true
;
}
}
return
false
;
}
...
...
@@ -37,8 +53,8 @@ struct CardString {
std
::
wstring
text
;
std
::
wstring
desc
[
16
];
};
using
code_pointer
=
std
::
unordered_map
<
u
nsigned
in
t
,
CardDataC
>::
const_iterator
;
using
string_pointer
=
std
::
unordered_map
<
u
nsigned
in
t
,
CardString
>::
const_iterator
;
using
code_pointer
=
std
::
unordered_map
<
u
int32_
t
,
CardDataC
>::
const_iterator
;
using
string_pointer
=
std
::
unordered_map
<
u
int32_
t
,
CardString
>::
const_iterator
;
class
DataManager
{
public:
...
...
@@ -50,17 +66,25 @@ public:
void
ReadStringConfLine
(
const
char
*
linebuf
);
bool
Error
(
sqlite3
*
pDB
,
sqlite3_stmt
*
pStmt
=
nullptr
);
code_pointer
GetCodePointer
(
unsigned
int
code
)
const
;
string_pointer
GetStringPointer
(
unsigned
int
code
)
const
;
code_pointer
datas_begin
()
const
;
code_pointer
datas_end
()
const
;
string_pointer
strings_begin
()
const
;
string_pointer
strings_end
()
const
;
bool
GetData
(
unsigned
int
code
,
CardData
*
pData
)
const
;
bool
GetString
(
unsigned
int
code
,
CardString
*
pStr
)
const
;
const
wchar_t
*
GetName
(
unsigned
int
code
)
const
;
const
wchar_t
*
GetText
(
unsigned
int
code
)
const
;
const
wchar_t
*
GetDesc
(
unsigned
int
strCode
)
const
;
code_pointer
GetCodePointer
(
uint32_t
code
)
const
;
string_pointer
GetStringPointer
(
uint32_t
code
)
const
;
code_pointer
datas_begin
()
const
noexcept
{
return
_datas
.
cbegin
();
}
code_pointer
datas_end
()
const
noexcept
{
return
_datas
.
cend
();
}
string_pointer
strings_begin
()
const
noexcept
{
return
_strings
.
cbegin
();
}
string_pointer
strings_end
()
const
noexcept
{
return
_strings
.
cend
();
}
bool
GetData
(
uint32_t
code
,
CardData
*
pData
)
const
;
bool
GetString
(
uint32_t
code
,
CardString
*
pStr
)
const
;
const
wchar_t
*
GetName
(
uint32_t
code
)
const
;
const
wchar_t
*
GetText
(
uint32_t
code
)
const
;
const
wchar_t
*
GetDesc
(
uint32_t
strCode
)
const
;
const
wchar_t
*
GetSysString
(
int
code
)
const
;
const
wchar_t
*
GetVictoryString
(
int
code
)
const
;
const
wchar_t
*
GetCounterName
(
int
code
)
const
;
...
...
@@ -98,9 +122,9 @@ public:
static
bool
deck_sort_name
(
code_pointer
l1
,
code_pointer
l2
);
private:
std
::
unordered_map
<
u
nsigned
in
t
,
CardDataC
>
_datas
;
std
::
unordered_map
<
u
nsigned
in
t
,
CardString
>
_strings
;
std
::
unordered_map
<
u
nsigned
in
t
,
std
::
vector
<
uint16_t
>>
extra_setcode
;
std
::
unordered_map
<
u
int32_
t
,
CardDataC
>
_datas
;
std
::
unordered_map
<
u
int32_
t
,
CardString
>
_strings
;
std
::
unordered_map
<
u
int32_
t
,
std
::
vector
<
uint16_t
>>
extra_setcode
;
};
extern
DataManager
dataManager
;
...
...
Classes/gframe/deck_con.cpp
View file @
5689558d
...
...
@@ -752,16 +752,16 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
}
mainGame
->
ClearCardInfo
();
mainGame
->
imgChat
->
setVisible
(
true
);
unsigned
char
deckbuf
[
1024
];
unsigned
char
deckbuf
[
1024
]
{}
;
auto
pdeck
=
deckbuf
;
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
main
.
size
()
+
deckManager
.
current_deck
.
extra
.
size
(
));
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
side
.
size
(
));
BufferIO
::
Write
<
int32_t
>
(
pdeck
,
static_cast
<
int32_t
>
(
deckManager
.
current_deck
.
main
.
size
()
+
deckManager
.
current_deck
.
extra
.
size
()
));
BufferIO
::
Write
<
int32_t
>
(
pdeck
,
static_cast
<
int32_t
>
(
deckManager
.
current_deck
.
side
.
size
()
));
for
(
size_t
i
=
0
;
i
<
deckManager
.
current_deck
.
main
.
size
();
++
i
)
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
main
[
i
]
->
first
);
BufferIO
::
Write
<
uint32_t
>
(
pdeck
,
deckManager
.
current_deck
.
main
[
i
]
->
first
);
for
(
size_t
i
=
0
;
i
<
deckManager
.
current_deck
.
extra
.
size
();
++
i
)
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
extra
[
i
]
->
first
);
BufferIO
::
Write
<
uint32_t
>
(
pdeck
,
deckManager
.
current_deck
.
extra
[
i
]
->
first
);
for
(
size_t
i
=
0
;
i
<
deckManager
.
current_deck
.
side
.
size
();
++
i
)
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
side
[
i
]
->
first
);
BufferIO
::
Write
<
uint32_t
>
(
pdeck
,
deckManager
.
current_deck
.
side
[
i
]
->
first
);
DuelClient
::
SendBufferToServer
(
CTOS_UPDATE_DECK
,
deckbuf
,
pdeck
-
deckbuf
);
break
;
}
...
...
@@ -1498,7 +1498,7 @@ void DeckBuilder::FilterCards() {
auto
strpointer
=
dataManager
.
GetStringPointer
(
ptr
->
first
);
if
(
strpointer
==
dataManager
.
strings_end
())
continue
;
const
CardString
&
text
=
strpointer
->
second
;
const
CardString
&
strings
=
strpointer
->
second
;
if
(
data
.
type
&
TYPE_TOKEN
)
continue
;
switch
(
filter_type
)
{
...
...
@@ -1574,14 +1574,14 @@ void DeckBuilder::FilterCards() {
for
(
auto
elements_iterator
=
query_elements
.
begin
();
elements_iterator
!=
query_elements
.
end
();
++
elements_iterator
)
{
bool
match
=
false
;
if
(
elements_iterator
->
type
==
element_t
::
type_t
::
name
)
{
match
=
CardNameContains
(
text
.
name
.
c_str
(),
elements_iterator
->
keyword
.
c_str
());
match
=
CardNameContains
(
strings
.
name
.
c_str
(),
elements_iterator
->
keyword
.
c_str
());
}
else
if
(
elements_iterator
->
type
==
element_t
::
type_t
::
setcode
)
{
match
=
data
.
is_setcodes
(
elements_iterator
->
setcodes
);
}
else
if
(
trycode
&&
(
data
.
code
==
trycode
||
data
.
alias
==
trycode
&&
data
.
is_alternative
(
))){
}
else
if
(
trycode
&&
(
data
.
code
==
trycode
||
data
.
alias
==
trycode
&&
is_alternative
(
data
.
code
,
data
.
alias
))){
match
=
true
;
}
else
{
match
=
CardNameContains
(
text
.
name
.
c_str
(),
elements_iterator
->
keyword
.
c_str
())
||
text
.
text
.
find
(
elements_iterator
->
keyword
)
!=
std
::
wstring
::
npos
match
=
CardNameContains
(
strings
.
name
.
c_str
(),
elements_iterator
->
keyword
.
c_str
())
||
strings
.
text
.
find
(
elements_iterator
->
keyword
)
!=
std
::
wstring
::
npos
||
data
.
is_setcodes
(
elements_iterator
->
setcodes
);
}
if
(
elements_iterator
->
exclude
)
...
...
@@ -1849,7 +1849,7 @@ void DeckBuilder::pop_side(int seq) {
GetHoveredCard
();
}
bool
DeckBuilder
::
check_limit
(
code_pointer
pointer
)
{
unsigned
int
limitcode
=
pointer
->
second
.
alias
?
pointer
->
second
.
alias
:
pointer
->
first
;
auto
limitcode
=
pointer
->
second
.
alias
?
pointer
->
second
.
alias
:
pointer
->
first
;
int
limit
=
3
;
auto
flit
=
filterList
->
content
.
find
(
limitcode
);
if
(
flit
!=
filterList
->
content
.
end
())
...
...
Classes/gframe/deck_manager.cpp
View file @
5689558d
...
...
@@ -13,7 +13,6 @@ void DeckManager::LoadLFListSingle(const char* path) {
FILE
*
fp
=
myfopen
(
path
,
"r"
);
char
linebuf
[
256
]{};
wchar_t
strBuffer
[
256
]{};
char
str1
[
16
]{};
if
(
fp
)
{
while
(
std
::
fgets
(
linebuf
,
sizeof
linebuf
,
fp
))
{
if
(
linebuf
[
0
]
==
'#'
)
...
...
@@ -31,13 +30,20 @@ void DeckManager::LoadLFListSingle(const char* path) {
}
if
(
cur
==
_lfList
.
rend
())
continue
;
unsigned
int
code
=
0
;
int
count
=
-
1
;
if
(
std
::
sscanf
(
linebuf
,
"%10s%*[ ]%1d"
,
str1
,
&
count
)
!=
2
)
char
*
pos
=
linebuf
;
errno
=
0
;
auto
result
=
std
::
strtoul
(
pos
,
&
pos
,
10
);
if
(
errno
||
result
>
UINT32_MAX
)
continue
;
if
(
pos
==
linebuf
||
*
pos
!=
' '
)
continue
;
uint32_t
code
=
static_cast
<
uint32_t
>
(
result
);
errno
=
0
;
int
count
=
std
::
strtol
(
pos
,
&
pos
,
10
);
if
(
errno
)
continue
;
if
(
count
<
0
||
count
>
2
)
continue
;
code
=
std
::
strtoul
(
str1
,
nullptr
,
10
);
cur
->
content
[
code
]
=
count
;
cur
->
hash
=
cur
->
hash
^
((
code
<<
18
)
|
(
code
>>
14
))
^
((
code
<<
(
27
+
count
))
|
(
code
>>
(
5
-
count
)));
}
...
...
@@ -197,8 +203,9 @@ uint32_t DeckManager::LoadDeckFromStream(Deck& deck, std::istringstream& deckStr
}
if
(
linebuf
[
0
]
<
'0'
||
linebuf
[
0
]
>
'9'
)
continue
;
errno
=
0
;
auto
code
=
std
::
strtoul
(
linebuf
.
c_str
(),
nullptr
,
10
);
if
(
code
>=
UINT32_MAX
)
if
(
errno
||
code
>
UINT32_MAX
)
continue
;
cardlist
[
ct
++
]
=
code
;
if
(
is_side
)
...
...
Classes/gframe/deck_manager.h
View file @
5689558d
#ifndef DECKMANAGER_H
#define DECKMANAGER_H
#include "config.h"
#include <unordered_map>
#include <vector>
#include <sstream>
#include "data_manager.h"
#include "config.h"
namespace
ygo
{
constexpr
int
DECK_MAX_SIZE
=
60
;
...
...
@@ -14,10 +14,13 @@ namespace ygo {
constexpr
int
SIDE_MAX_SIZE
=
15
;
constexpr
int
PACK_MAX_SIZE
=
1000
;
constexpr
int
MAINC_MAX
=
250
;
// the limit of card_state
constexpr
int
SIDEC_MAX
=
MAINC_MAX
;
struct
LFList
{
unsigned
int
hash
{};
std
::
wstring
listName
;
std
::
unordered_map
<
u
nsigned
in
t
,
int
>
content
;
std
::
unordered_map
<
u
int32_
t
,
int
>
content
;
};
struct
Deck
{
std
::
vector
<
code_pointer
>
main
;
...
...
Classes/gframe/drawing.cpp
View file @
5689558d
...
...
@@ -1141,7 +1141,7 @@ void Game::WaitFrameSignal(int frame) {
frameSignal
.
Wait
();
}
void
Game
::
DrawThumb
(
code_pointer
cp
,
irr
::
core
::
vector2di
pos
,
const
LFList
*
lflist
,
bool
drag
)
{
int
code
=
cp
->
first
;
auto
code
=
cp
->
first
;
auto
lcode
=
cp
->
second
.
alias
;
if
(
lcode
==
0
)
lcode
=
code
;
...
...
Classes/gframe/duelclient.cpp
View file @
5689558d
This diff is collapsed.
Click to expand it.
Classes/gframe/duelclient.h
View file @
5689558d
...
...
@@ -4,6 +4,7 @@
#include <vector>
#include <set>
#include <random>
#include "config.h"
#include "network.h"
namespace
ygo
{
...
...
@@ -49,16 +50,16 @@ public:
static
void
SendResponse
();
static
void
SendPacketToServer
(
unsigned
char
proto
)
{
auto
p
=
duel_client_write
;
buffer_w
rite
<
uint16_t
>
(
p
,
1
);
buffer_w
rite
<
uint8_t
>
(
p
,
proto
);
BufferIO
::
W
rite
<
uint16_t
>
(
p
,
1
);
BufferIO
::
W
rite
<
uint8_t
>
(
p
,
proto
);
bufferevent_write
(
client_bev
,
duel_client_write
,
3
);
}
template
<
typename
ST
>
static
void
SendPacketToServer
(
unsigned
char
proto
,
const
ST
&
st
)
{
auto
p
=
duel_client_write
;
static_assert
(
sizeof
(
ST
)
<=
MAX_DATA_SIZE
,
"Packet size is too large."
);
buffer_w
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
sizeof
(
ST
)));
buffer_w
rite
<
uint8_t
>
(
p
,
proto
);
BufferIO
::
W
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
sizeof
(
ST
)));
BufferIO
::
W
rite
<
uint8_t
>
(
p
,
proto
);
std
::
memcpy
(
p
,
&
st
,
sizeof
(
ST
));
bufferevent_write
(
client_bev
,
duel_client_write
,
sizeof
(
ST
)
+
3
);
}
...
...
@@ -66,8 +67,8 @@ public:
auto
p
=
duel_client_write
;
if
(
len
>
MAX_DATA_SIZE
)
len
=
MAX_DATA_SIZE
;
buffer_w
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
len
));
buffer_w
rite
<
uint8_t
>
(
p
,
proto
);
BufferIO
::
W
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
len
));
BufferIO
::
W
rite
<
uint8_t
>
(
p
,
proto
);
std
::
memcpy
(
p
,
buffer
,
len
);
bufferevent_write
(
client_bev
,
duel_client_write
,
len
+
3
);
}
...
...
Classes/gframe/game.cpp
View file @
5689558d
...
...
@@ -1700,11 +1700,8 @@ void Game::RefreshDeck(const wchar_t* deckpath, const std::function<void(const w
}
FileSystem
::
TraversalDir
(
deckpath
,
[
additem
](
const
wchar_t
*
name
,
bool
isdir
)
{
if
(
!
isdir
&&
IsExtension
(
name
,
L".ydk"
))
{
size_t
len
=
std
::
wcslen
(
name
);
wchar_t
deckname
[
256
]{};
size_t
count
=
std
::
min
(
len
-
4
,
sizeof
deckname
/
sizeof
deckname
[
0
]
-
1
);
std
::
wcsncpy
(
deckname
,
name
,
count
);
deckname
[
count
]
=
0
;
BufferIO
::
CopyWideString
(
name
,
deckname
,
std
::
wcslen
(
name
)
-
4
);
additem
(
deckname
);
}
});
...
...
@@ -1728,7 +1725,7 @@ void Game::RefreshBot() {
if
(
!
gameConf
.
enable_bot_mode
)
return
;
botInfo
.
clear
();
FILE
*
fp
=
std
::
fopen
(
"bot.conf"
,
"r"
);
FILE
*
fp
=
my
fopen
(
"bot.conf"
,
"r"
);
char
linebuf
[
256
]{};
char
strbuf
[
256
]{};
if
(
fp
)
{
...
...
@@ -1903,7 +1900,7 @@ void Game::ShowCardInfo(int code) {
imgCard
->
setScaleImage
(
true
);
if
(
is_valid
)
{
auto
&
cd
=
cit
->
second
;
if
(
cd
.
is_alternative
(
))
if
(
is_alternative
(
cd
.
code
,
cd
.
alias
))
myswprintf
(
formatBuffer
,
L"%ls[%08d]"
,
dataManager
.
GetName
(
cd
.
alias
),
cd
.
alias
);
else
myswprintf
(
formatBuffer
,
L"%ls[%08d]"
,
dataManager
.
GetName
(
code
),
code
);
...
...
Classes/gframe/menu_handler.cpp
View file @
5689558d
...
...
@@ -24,14 +24,14 @@ void UpdateDeck() {
unsigned
char
deckbuf
[
1024
]{};
auto
pdeck
=
deckbuf
;
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
main
.
size
()
+
deckManager
.
current_deck
.
extra
.
size
(
));
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
side
.
size
(
));
BufferIO
::
Write
<
int32_t
>
(
pdeck
,
static_cast
<
int32_t
>
(
deckManager
.
current_deck
.
main
.
size
()
+
deckManager
.
current_deck
.
extra
.
size
()
));
BufferIO
::
Write
<
int32_t
>
(
pdeck
,
static_cast
<
int32_t
>
(
deckManager
.
current_deck
.
side
.
size
()
));
for
(
size_t
i
=
0
;
i
<
deckManager
.
current_deck
.
main
.
size
();
++
i
)
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
main
[
i
]
->
first
);
BufferIO
::
Write
<
uint32_t
>
(
pdeck
,
deckManager
.
current_deck
.
main
[
i
]
->
first
);
for
(
size_t
i
=
0
;
i
<
deckManager
.
current_deck
.
extra
.
size
();
++
i
)
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
extra
[
i
]
->
first
);
BufferIO
::
Write
<
uint32_t
>
(
pdeck
,
deckManager
.
current_deck
.
extra
[
i
]
->
first
);
for
(
size_t
i
=
0
;
i
<
deckManager
.
current_deck
.
side
.
size
();
++
i
)
BufferIO
::
Write
Int32
(
pdeck
,
deckManager
.
current_deck
.
side
[
i
]
->
first
);
BufferIO
::
Write
<
uint32_t
>
(
pdeck
,
deckManager
.
current_deck
.
side
[
i
]
->
first
);
DuelClient
::
SendBufferToServer
(
CTOS_UPDATE_DECK
,
deckbuf
,
pdeck
-
deckbuf
);
}
...
...
Classes/gframe/netserver.cpp
View file @
5689558d
...
...
@@ -185,7 +185,7 @@ void NetServer::DisconnectPlayer(DuelPlayer* dp) {
}
void
NetServer
::
HandleCTOSPacket
(
DuelPlayer
*
dp
,
unsigned
char
*
data
,
int
len
)
{
auto
pdata
=
data
;
unsigned
char
pktType
=
BufferIO
::
Read
UInt8
(
pdata
);
unsigned
char
pktType
=
BufferIO
::
Read
<
uint8_t
>
(
pdata
);
if
((
pktType
!=
CTOS_SURRENDER
)
&&
(
pktType
!=
CTOS_CHAT
)
&&
(
dp
->
state
==
0xff
||
(
dp
->
state
&&
dp
->
state
!=
pktType
)))
return
;
switch
(
pktType
)
{
...
...
@@ -261,7 +261,7 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, unsigned char* data, int len) {
// for other server & reverse proxy use only
/*
wchar_t hostname[LEN_HOSTNAME];
uint32_t real_ip = ntohl(BufferIO::Read
Int32
(pdata));
uint32_t real_ip = ntohl(BufferIO::Read
<int32_t>
(pdata));
BufferIO::CopyCharArray((uint16_t*)pdata, hostname);
*/
break
;
...
...
@@ -386,8 +386,9 @@ size_t NetServer::CreateChatPacket(unsigned char* src, int src_size, unsigned ch
return
0
;
// STOC_Chat packet
auto
pdst
=
dst
;
buffer_write
<
uint16_t
>
(
pdst
,
dst_player_type
);
buffer_write_block
(
pdst
,
src_msg
,
src_size
);
BufferIO
::
Write
<
uint16_t
>
(
pdst
,
dst_player_type
);
std
::
memcpy
(
pdst
,
src_msg
,
src_size
);
pdst
+=
src_size
;
return
sizeof
(
dst_player_type
)
+
src_size
;
}
...
...
Classes/gframe/netserver.h
View file @
5689558d
#ifndef NETSERVER_H
#define NETSERVER_H
#include "network.h"
#include <unordered_map>
#include "config.h"
#include "network.h"
namespace
ygo
{
...
...
@@ -34,8 +35,8 @@ public:
static
size_t
CreateChatPacket
(
unsigned
char
*
src
,
int
src_size
,
unsigned
char
*
dst
,
uint16_t
dst_player_type
);
static
void
SendPacketToPlayer
(
DuelPlayer
*
dp
,
unsigned
char
proto
)
{
auto
p
=
net_server_write
;
buffer_w
rite
<
uint16_t
>
(
p
,
1
);
buffer_w
rite
<
uint8_t
>
(
p
,
proto
);
BufferIO
::
W
rite
<
uint16_t
>
(
p
,
1
);
BufferIO
::
W
rite
<
uint8_t
>
(
p
,
proto
);
last_sent
=
3
;
if
(
dp
)
bufferevent_write
(
dp
->
bev
,
net_server_write
,
3
);
...
...
@@ -44,8 +45,8 @@ public:
static
void
SendPacketToPlayer
(
DuelPlayer
*
dp
,
unsigned
char
proto
,
const
ST
&
st
)
{
auto
p
=
net_server_write
;
static_assert
(
sizeof
(
ST
)
<=
MAX_DATA_SIZE
,
"Packet size is too large."
);
buffer_w
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
sizeof
(
ST
)));
buffer_w
rite
<
uint8_t
>
(
p
,
proto
);
BufferIO
::
W
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
sizeof
(
ST
)));
BufferIO
::
W
rite
<
uint8_t
>
(
p
,
proto
);
std
::
memcpy
(
p
,
&
st
,
sizeof
(
ST
));
last_sent
=
sizeof
(
ST
)
+
3
;
if
(
dp
)
...
...
@@ -55,8 +56,8 @@ public:
auto
p
=
net_server_write
;
if
(
len
>
MAX_DATA_SIZE
)
len
=
MAX_DATA_SIZE
;
buffer_w
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
len
));
buffer_w
rite
<
uint8_t
>
(
p
,
proto
);
BufferIO
::
W
rite
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
len
));
BufferIO
::
W
rite
<
uint8_t
>
(
p
,
proto
);
std
::
memcpy
(
p
,
buffer
,
len
);
last_sent
=
len
+
3
;
if
(
dp
)
...
...
Classes/gframe/network.h
View file @
5689558d
...
...
@@ -9,14 +9,13 @@
#include <event2/buffer.h>
#include <event2/thread.h>
#include <type_traits>
#include "deck_manager.h"
#define check_trivially_copyable(T) static_assert(std::is_trivially_copyable<T>::value == true && std::is_standard_layout<T>::value == true, "not trivially copyable")
namespace
ygo
{
constexpr
int
SIZE_NETWORK_BUFFER
=
0x20000
;
constexpr
int
MAX_DATA_SIZE
=
UINT16_MAX
-
1
;
constexpr
int
MAINC_MAX
=
250
;
// the limit of card_state
constexpr
int
SIDEC_MAX
=
MAINC_MAX
;
struct
HostInfo
{
uint32_t
lflist
{};
...
...
Classes/gframe/replay.cpp
View file @
5689558d
#include "config.h"
#include "replay.h"
#include "myfilesystem.h"
#include "network.h"
#include "lzma/LzmaLib.h"
namespace
ygo
{
...
...
@@ -16,31 +16,18 @@ Replay::~Replay() {
void
Replay
::
BeginRecord
()
{
if
(
!
FileSystem
::
IsDirExists
(
L"./replay"
)
&&
!
FileSystem
::
MakeDir
(
L"./replay"
))
return
;
#ifdef _WIN32
if
(
is_recording
)
CloseHandle
(
recording_fp
);
recording_fp
=
CreateFileW
(
L"./replay/_LastReplay.yrp"
,
GENERIC_WRITE
,
0
,
nullptr
,
CREATE_ALWAYS
,
FILE_FLAG_WRITE_THROUGH
,
nullptr
);
if
(
recording_fp
==
INVALID_HANDLE_VALUE
)
return
;
#else
if
(
is_recording
)
std
::
fclose
(
fp
);
fp
=
myfopen
(
"./replay/_LastReplay.yrp"
,
"wb"
);
if
(
!
fp
)
return
;
#endif
Reset
();
is_recording
=
true
;
}
void
Replay
::
WriteHeader
(
ExtendedReplayHeader
&
header
)
{
pheader
=
header
;
#ifdef _WIN32
DWORD
size
;
WriteFile
(
recording_fp
,
&
header
,
sizeof
(
header
),
&
size
,
nullptr
);
#else
std
::
fwrite
(
&
header
,
sizeof
(
header
),
1
,
fp
);
std
::
fwrite
(
&
header
,
sizeof
header
,
1
,
fp
);
std
::
fflush
(
fp
);
#endif
}
void
Replay
::
WriteData
(
const
void
*
data
,
size_t
length
,
bool
flush
)
{
if
(
!
is_recording
)
...
...
@@ -49,14 +36,9 @@ void Replay::WriteData(const void* data, size_t length, bool flush) {
return
;
std
::
memcpy
(
replay_data
+
replay_size
,
data
,
length
);
replay_size
+=
length
;
#ifdef _WIN32
DWORD
size
;
WriteFile
(
recording_fp
,
data
,
length
,
&
size
,
nullptr
);
#else
std
::
fwrite
(
data
,
length
,
1
,
fp
);
if
(
flush
)
std
::
fflush
(
fp
);
#endif
}
void
Replay
::
WriteInt32
(
int32_t
data
,
bool
flush
)
{
Write
<
int32_t
>
(
data
,
flush
);
...
...
@@ -64,19 +46,12 @@ void Replay::WriteInt32(int32_t data, bool flush) {
void
Replay
::
Flush
()
{
if
(
!
is_recording
)
return
;
#ifdef _WIN32
#else
std
::
fflush
(
fp
);
#endif
}
void
Replay
::
EndRecord
()
{
if
(
!
is_recording
)
return
;
#ifdef _WIN32
CloseHandle
(
recording_fp
);
#else
std
::
fclose
(
fp
);
#endif
pheader
.
base
.
datasize
=
replay_size
;
pheader
.
base
.
flag
|=
REPLAY_COMPRESSED
;
size_t
propsize
=
5
;
...
...
Classes/gframe/replay.h
View file @
5689558d
#ifndef REPLAY_H
#define REPLAY_H
#include "config.h"
#include <cstdio>
#include <vector>
#include <string>
#include "../ocgcore/ocgapi.h"
#include "deck_manager.h"
namespace
ygo
{
...
...
@@ -95,7 +98,6 @@ public:
bool
IsReplaying
()
const
;
FILE
*
fp
{
nullptr
};
ExtendedReplayHeader
pheader
;
unsigned
char
*
comp_data
;
size_t
comp_size
{};
...
...
Classes/gframe/replay_mode.cpp
View file @
5689558d
This diff is collapsed.
Click to expand it.
Classes/gframe/single_duel.cpp
View file @
5689558d
This diff is collapsed.
Click to expand it.
Classes/gframe/single_mode.cpp
View file @
5689558d
This diff is collapsed.
Click to expand it.
Classes/gframe/tag_duel.cpp
View file @
5689558d
This diff is collapsed.
Click to expand it.
libcore/android/bufferio_android.h
View file @
5689558d
...
...
@@ -2,31 +2,52 @@
#define BUFFERIO_H
#include <cstdint>
#include <cstring>
#include <cwchar>
#include "../ocgcore/buffer.h"
class
BufferIO
{
public:
static
int
ReadInt32
(
unsigned
char
*&
p
)
{
return
buffer_read
<
int32_t
>
(
p
);
template
<
typename
T
>
static
T
Read
(
unsigned
char
*&
p
)
{
T
ret
{};
std
::
memcpy
(
&
ret
,
p
,
sizeof
(
T
));
p
+=
sizeof
(
T
);
return
ret
;
}
template
<
typename
T
>
static
void
Write
(
unsigned
char
*&
p
,
T
value
)
{
std
::
memcpy
(
p
,
&
value
,
sizeof
(
T
));
p
+=
sizeof
(
T
);
}
// for compatibility
[[
deprecated
]]
static
int32_t
ReadInt32
(
unsigned
char
*&
p
)
{
return
Read
<
int32_t
>
(
p
);
}
[[
deprecated
]]
static
short
ReadInt16
(
unsigned
char
*&
p
)
{
return
buffer_r
ead
<
int16_t
>
(
p
);
return
R
ead
<
int16_t
>
(
p
);
}
[[
deprecated
]]
static
char
ReadInt8
(
unsigned
char
*&
p
)
{
return
buffer_r
ead
<
char
>
(
p
);
return
R
ead
<
char
>
(
p
);
}
[[
deprecated
]]
static
unsigned
char
ReadUInt8
(
unsigned
char
*&
p
)
{
return
buffer_r
ead
<
unsigned
char
>
(
p
);
return
R
ead
<
unsigned
char
>
(
p
);
}
static
void
WriteInt32
(
unsigned
char
*&
p
,
int
val
)
{
buffer_write
<
int32_t
>
(
p
,
val
);
[[
deprecated
]]
static
void
WriteInt32
(
unsigned
char
*&
p
,
int32_t
val
)
{
Write
<
int32_t
>
(
p
,
val
);
}
[[
deprecated
]]
static
void
WriteInt16
(
unsigned
char
*&
p
,
short
val
)
{
buffer_w
rite
<
int16_t
>
(
p
,
val
);
W
rite
<
int16_t
>
(
p
,
val
);
}
[[
deprecated
]]
static
void
WriteInt8
(
unsigned
char
*&
p
,
char
val
)
{
buffer_w
rite
<
char
>
(
p
,
val
);
W
rite
<
char
>
(
p
,
val
);
}
/**
* @brief Copy a C-style string to another C-style string.
...
...
@@ -61,64 +82,18 @@ public:
return
CopyWStr
(
src
,
dst
,
N
);
}
template
<
size_t
N
>
static
void
CopyString
(
const
char
*
src
,
char
(
&
dst
)[
N
])
{
std
::
strncpy
(
dst
,
src
,
N
-
1
);
dst
[
N
-
1
]
=
0
;
static
void
CopyString
(
const
char
*
src
,
char
(
&
dst
)[
N
],
size_t
len
=
N
-
1
)
{
if
(
len
>=
N
)
len
=
N
-
1
;
std
::
strncpy
(
dst
,
src
,
len
);
dst
[
len
]
=
0
;
}
template
<
size_t
N
>
static
void
CopyWideString
(
const
wchar_t
*
src
,
wchar_t
(
&
dst
)[
N
])
{
std
::
wcsncpy
(
dst
,
src
,
N
-
1
);
dst
[
N
-
1
]
=
0
;
}
template
<
typename
T
>
static
bool
CheckUTF8Byte
(
const
T
*
str
,
int
len
)
{
for
(
int
i
=
1
;
i
<
len
;
++
i
)
{
if
((
str
[
i
]
&
0xc0U
)
!=
0x80U
)
return
false
;
}
return
true
;
}
static
unsigned
int
ConvertUTF8
(
const
char
*&
p
)
{
unsigned
int
cur
=
0
;
if
((
p
[
0
]
&
0x80U
)
==
0
)
{
cur
=
p
[
0
]
&
0xffU
;
p
++
;
}
else
if
((
p
[
0
]
&
0xe0U
)
==
0xc0U
)
{
if
(
!
CheckUTF8Byte
(
p
,
2
))
{
p
++
;
return
UINT32_MAX
;
}
cur
=
((
p
[
0
]
&
0x1fU
)
<<
6
)
|
(
p
[
1
]
&
0x3fU
);
p
+=
2
;
if
(
cur
<
0x80U
)
return
UINT32_MAX
;
}
else
if
((
p
[
0
]
&
0xf0U
)
==
0xe0U
)
{
if
(
!
CheckUTF8Byte
(
p
,
3
))
{
p
++
;
return
UINT32_MAX
;
}
cur
=
((
p
[
0
]
&
0xfU
)
<<
12
)
|
((
p
[
1
]
&
0x3fU
)
<<
6
)
|
(
p
[
2
]
&
0x3fU
);
p
+=
3
;
if
(
cur
<
0x800U
)
return
UINT32_MAX
;
}
else
if
((
p
[
0
]
&
0xf8U
)
==
0xf0U
)
{
if
(
!
CheckUTF8Byte
(
p
,
4
))
{
p
++
;
return
UINT32_MAX
;
}
cur
=
((
p
[
0
]
&
0x7U
)
<<
18
)
|
((
p
[
1
]
&
0x3fU
)
<<
12
)
|
((
p
[
2
]
&
0x3fU
)
<<
6
)
|
(
p
[
3
]
&
0x3fU
);
p
+=
4
;
if
(
cur
<
0x10000U
)
return
UINT32_MAX
;
}
else
{
p
++
;
return
UINT32_MAX
;
}
return
cur
;
static
void
CopyWideString
(
const
wchar_t
*
src
,
wchar_t
(
&
dst
)[
N
],
size_t
len
=
N
-
1
)
{
if
(
len
>=
N
)
len
=
N
-
1
;
std
::
wcsncpy
(
dst
,
src
,
len
);
dst
[
len
]
=
0
;
}
static
bool
IsHighSurrogate
(
unsigned
int
c
)
{
return
(
c
>=
0xd800U
&&
c
<=
0xdbffU
);
...
...
@@ -137,111 +112,31 @@ public:
}
// UTF-16/UTF-32 to UTF-8
// return: string length
static
int
EncodeUTF8String
(
const
wchar_t
*
wsrc
,
char
*
str
,
int
size
)
{
auto
pw
=
wsrc
;
auto
pstr
=
str
;
while
(
*
pw
!=
0
)
{
unsigned
cur
=
0
;
int
codepoint_size
=
0
;
if
(
sizeof
(
wchar_t
)
==
2
)
{
if
(
IsHighSurrogate
(
pw
[
0
]))
{
if
(
pw
[
1
]
==
0
)
break
;
if
(
IsLowSurrogate
(
pw
[
1
]))
{
cur
=
((
pw
[
0
]
&
0x3ffU
)
<<
10
)
|
(
pw
[
1
]
&
0x3ffU
);
cur
+=
0x10000
;
pw
+=
2
;
}
else
{
pw
++
;
continue
;
}
}
else
if
(
IsLowSurrogate
(
pw
[
0
]))
{
pw
++
;
continue
;
}
else
{
cur
=
*
pw
;
pw
++
;
}
}
else
{
cur
=
*
pw
;
pw
++
;
}
if
(
!
IsUnicodeChar
(
cur
))
continue
;
if
(
cur
<
0x80U
)
codepoint_size
=
1
;
else
if
(
cur
<
0x800U
)
codepoint_size
=
2
;
else
if
(
cur
<
0x10000U
)
codepoint_size
=
3
;
else
codepoint_size
=
4
;
if
((
int
)(
pstr
-
str
)
+
codepoint_size
>
size
-
1
)
break
;
switch
(
codepoint_size
)
{
case
1
:
*
pstr
=
(
char
)
cur
;
break
;
case
2
:
pstr
[
0
]
=
((
cur
>>
6
)
&
0x1f
)
|
0xc0
;
pstr
[
1
]
=
(
cur
&
0x3f
)
|
0x80
;
break
;
case
3
:
pstr
[
0
]
=
((
cur
>>
12
)
&
0xf
)
|
0xe0
;
pstr
[
1
]
=
((
cur
>>
6
)
&
0x3f
)
|
0x80
;
pstr
[
2
]
=
(
cur
&
0x3f
)
|
0x80
;
break
;
case
4
:
pstr
[
0
]
=
((
cur
>>
18
)
&
0x7
)
|
0xf0
;
pstr
[
1
]
=
((
cur
>>
12
)
&
0x3f
)
|
0x80
;
pstr
[
2
]
=
((
cur
>>
6
)
&
0x3f
)
|
0x80
;
pstr
[
3
]
=
(
cur
&
0x3f
)
|
0x80
;
break
;
default:
break
;
}
pstr
+=
codepoint_size
;
static
int
EncodeUTF8String
(
const
wchar_t
*
wsrc
,
char
*
str
,
size_t
len
)
{
if
(
len
==
0
)
{
str
[
0
]
=
0
;
return
0
;
}
*
pstr
=
0
;
return
(
int
)(
pstr
-
str
);
std
::
mbstate_t
state
{};
size_t
result_len
=
std
::
wcsrtombs
(
str
,
&
wsrc
,
len
-
1
,
&
state
);
if
(
result_len
==
static_cast
<
size_t
>
(
-
1
))
result_len
=
0
;
str
[
result_len
]
=
0
;
return
static_cast
<
int
>
(
result_len
);
}
// UTF-8 to UTF-16/UTF-32
// return: string length
static
int
DecodeUTF8String
(
const
char
*
src
,
wchar_t
*
wstr
,
int
size
)
{
const
char
*
p
=
src
;
wchar_t
*
wp
=
wstr
;
while
(
*
p
!=
0
)
{
unsigned
int
cur
=
ConvertUTF8
(
p
);
int
codepoint_size
=
0
;
if
(
!
IsUnicodeChar
(
cur
))
continue
;
if
(
cur
>=
0x10000
)
{
if
(
sizeof
(
wchar_t
)
==
2
)
codepoint_size
=
2
;
else
codepoint_size
=
1
;
}
else
codepoint_size
=
1
;
if
((
int
)(
wp
-
wstr
)
+
codepoint_size
>
size
-
1
)
break
;
if
(
codepoint_size
==
1
)
{
wp
[
0
]
=
cur
;
wp
++
;
}
else
{
cur
-=
0x10000U
;
wp
[
0
]
=
(
cur
>>
10
)
|
0xd800
;
wp
[
1
]
=
(
cur
&
0x3ff
)
|
0xdc00
;
wp
+=
2
;
}
static
int
DecodeUTF8String
(
const
char
*
src
,
wchar_t
*
wstr
,
size_t
len
)
{
if
(
len
==
0
)
{
wstr
[
0
]
=
0
;
return
0
;
}
*
wp
=
0
;
return
wp
-
wstr
;
std
::
mbstate_t
state
{};
size_t
result_len
=
std
::
mbsrtowcs
(
wstr
,
&
src
,
len
-
1
,
&
state
);
if
(
result_len
==
static_cast
<
size_t
>
(
-
1
))
result_len
=
0
;
wstr
[
result_len
]
=
0
;
return
static_cast
<
int
>
(
result_len
);
}
template
<
size_t
N
>
static
int
EncodeUTF8
(
const
wchar_t
*
src
,
char
(
&
dst
)[
N
])
{
...
...
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