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
cc5ff995
Commit
cc5ff995
authored
Nov 14, 2025
by
fallenstardust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
通信注释
parent
18e94578
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
323 additions
and
23 deletions
+323
-23
Classes/gframe/netserver.cpp
Classes/gframe/netserver.cpp
+244
-8
Classes/gframe/netserver.h
Classes/gframe/netserver.h
+79
-15
No files found.
Classes/gframe/netserver.cpp
View file @
cc5ff995
This diff is collapsed.
Click to expand it.
Classes/gframe/netserver.h
View file @
cc5ff995
...
...
@@ -33,40 +33,104 @@ public:
static
void
DisconnectPlayer
(
DuelPlayer
*
dp
);
static
void
HandleCTOSPacket
(
DuelPlayer
*
dp
,
unsigned
char
*
data
,
int
len
);
static
size_t
CreateChatPacket
(
unsigned
char
*
src
,
int
src_size
,
unsigned
char
*
dst
,
uint16_t
dst_player_type
);
/**
* 向指定玩家发送数据包
* @param dp 目标玩家对象指针,如果为NULL则只准备数据不发送
* @param proto 协议类型字节
*
* 该函数构造一个3字节的数据包并发送给指定玩家:
* - 第1-2字节:固定值1(包长度)
* - 第3字节:协议类型
*/
static
void
SendPacketToPlayer
(
DuelPlayer
*
dp
,
unsigned
char
proto
)
{
// 准备数据包缓冲区
auto
p
=
net_server_write
;
// 写入包长度(1)和协议类型
BufferIO
::
Write
<
uint16_t
>
(
p
,
1
);
BufferIO
::
Write
<
uint8_t
>
(
p
,
proto
);
// 记录最后发送的包大小
last_sent
=
3
;
// 如果目标玩家存在,则发送数据包
if
(
dp
)
bufferevent_write
(
dp
->
bev
,
net_server_write
,
3
);
}
/**
* @brief 向指定玩家发送数据包
*
* 该函数将指定的数据结构序列化后通过网络发送给目标玩家。
* 数据包格式为:长度(2字节) + 协议号(1字节) + 数据内容
*
* @tparam ST 数据包结构体类型
* @param dp 目标玩家对象指针,如果为nullptr则只构建数据包不发送
* @param proto 协议号,标识数据包类型
* @param st 要发送的数据结构体引用
*/
template
<
typename
ST
>
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."
);
// 写入数据包总长度(协议号1字节 + 数据长度)
BufferIO
::
Write
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
sizeof
(
ST
)));
// 写入协议号
BufferIO
::
Write
<
uint8_t
>
(
p
,
proto
);
// 拷贝数据结构体内容到缓冲区
std
::
memcpy
(
p
,
&
st
,
sizeof
(
ST
));
// 记录最后发送的数据包长度
last_sent
=
sizeof
(
ST
)
+
3
;
// 如果目标玩家存在,则实际发送数据包
if
(
dp
)
bufferevent_write
(
dp
->
bev
,
net_server_write
,
sizeof
(
ST
)
+
3
);
}
static
void
SendBufferToPlayer
(
DuelPlayer
*
dp
,
unsigned
char
proto
,
void
*
buffer
,
size_t
len
)
{
auto
p
=
net_server_write
;
if
(
len
>
MAX_DATA_SIZE
)
len
=
MAX_DATA_SIZE
;
BufferIO
::
Write
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
len
));
BufferIO
::
Write
<
uint8_t
>
(
p
,
proto
);
std
::
memcpy
(
p
,
buffer
,
len
);
last_sent
=
len
+
3
;
if
(
dp
)
bufferevent_write
(
dp
->
bev
,
net_server_write
,
len
+
3
);
}
static
void
ReSendToPlayer
(
DuelPlayer
*
dp
)
{
if
(
dp
)
bufferevent_write
(
dp
->
bev
,
net_server_write
,
last_sent
);
}
/**
* @brief 发送数据缓冲区到指定玩家
*
* 该函数将指定的数据缓冲区内容发送给指定的决斗玩家。数据会被封装成网络消息格式,
* 包含协议类型和数据长度信息。
*
* @param dp 目标玩家对象指针,如果为nullptr则只准备数据不实际发送
* @param proto 协议类型字节,用于标识消息类型
* @param buffer 要发送的数据缓冲区指针
* @param len 要发送的数据长度
*/
static
void
SendBufferToPlayer
(
DuelPlayer
*
dp
,
unsigned
char
proto
,
void
*
buffer
,
size_t
len
)
{
auto
p
=
net_server_write
;
// 限制发送数据长度不超过最大允许值
if
(
len
>
MAX_DATA_SIZE
)
len
=
MAX_DATA_SIZE
;
// 写入数据包总长度(1字节协议号 + 数据长度)
BufferIO
::
Write
<
uint16_t
>
(
p
,
(
uint16_t
)(
1
+
len
));
// 写入协议类型字节
BufferIO
::
Write
<
uint8_t
>
(
p
,
proto
);
// 拷贝实际数据到发送缓冲区
std
::
memcpy
(
p
,
buffer
,
len
);
last_sent
=
len
+
3
;
// 如果目标玩家存在,则通过bufferevent发送数据
if
(
dp
)
bufferevent_write
(
dp
->
bev
,
net_server_write
,
len
+
3
);
}
/**
* @brief 重新发送数据给指定的决斗玩家
*
* @param dp 指向决斗玩家对象的指针
*
* @note 该函数会检查玩家指针是否有效,如果有效则将缓冲区中的数据重新发送给该玩家
*/
static
void
ReSendToPlayer
(
DuelPlayer
*
dp
)
{
// 如果玩家指针有效,则重新发送数据
if
(
dp
)
bufferevent_write
(
dp
->
bev
,
net_server_write
,
last_sent
);
}
};
}
...
...
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