Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
YGOMobile
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
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