同行检测
概述
同行检测系统用于检测同一局游戏中是否有其他用户也在使用本程序(或同系列程序)。可用于显示友好标识、避免误伤等场景。
工作原理
- 客户端提交自身信息(UID、昵称、世界地址)到服务器
- 客户端提交待检测的玩家列表
- 服务器比对同一世界地址下的所有用户
- 返回检测结果(是否同行、使用的程序列表)
内部机制
| 机制 | 说明 |
|---|---|
| 自动去重 | 已检测过的玩家不会重复提交 |
| 自动限流 | 每 2 秒最多发送一批请求 |
| 自动批量 | 每批最多 50 个玩家 |
| 换局检测 | world_address 变化时自动清空所有状态 |
函数
txnet_peer_init
cpp
void txnet_peer_init(txnet_peer_callback callback);初始化同行检测模块,设置结果回调。
txnet_peer_submit_self
cpp
void txnet_peer_submit_self(const char* uid, const char* nickname, unsigned long long world_address);提交自身信息到服务器。
| 参数 | 类型 | 说明 |
|---|---|---|
uid | const char* | 自身游戏内 UID |
nickname | const char* | 自身游戏内昵称 |
world_address | unsigned long long | 当前游戏世界的内存地址 |
调用频率
每帧调用。world_address 变化时自动清空所有检测状态。
txnet_peer_add_player
cpp
void txnet_peer_add_player(const char* uid, const char* nickname);添加一个待检测的玩家。
| 参数 | 类型 | 说明 |
|---|---|---|
uid | const char* | 玩家游戏内 UID |
nickname | const char* | 玩家游戏内昵称 |
txnet_peer_is_same_server
cpp
bool txnet_peer_is_same_server(const char* uid);查询指定玩家是否为同行(基于本地缓存,无网络请求)。
| 返回值 | 说明 |
|---|---|
true | 是同行 |
false | 不是同行或尚未检测 |
txnet_peer_get_programs
cpp
int txnet_peer_get_programs(const char* uid, const char** out_programs, int max_count);获取同行使用的程序列表。
| 参数 | 类型 | 说明 |
|---|---|---|
uid | const char* | 玩家游戏内 UID |
out_programs | const char** | 输出数组 |
max_count | int | 输出数组的最大容量 |
返回值: 实际的程序数量
txnet_peer_clear
cpp
void txnet_peer_clear();手动清空所有同行检测状态。
回调函数
txnet_peer_callback
cpp
typedef void (*txnet_peer_callback)(
const char* uid,
bool is_same_server,
const char** programs,
int program_count
);| 参数 | 类型 | 说明 |
|---|---|---|
uid | const char* | 玩家 UID |
is_same_server | bool | 是否为同行 |
programs | const char** | 程序名称数组 |
program_count | int | 程序数量 |
示例
基础用法
cpp
#include "txnet.h"
void onPeerResult(const char* uid, bool isSame, const char** progs, int count) {
if (isSame) {
printf("发现同行: %s\n", uid);
}
}
void initPeerDetection() {
txnet_peer_init(onPeerResult);
}
void gameLoop(GameData& game) {
txnet_peer_submit_self(game.localPlayer.uid, game.localPlayer.name, game.worldAddress);
for (auto& player : game.players) {
txnet_peer_add_player(player.uid, player.name);
}
}在游戏中标记同行
cpp
void renderPlayers(GameData& game) {
for (auto& player : game.players) {
bool isPeer = txnet_peer_is_same_server(player.uid);
if (isPeer) {
drawPlayerBox(player, COLOR_GREEN);
drawText(player.pos, "[同行]", COLOR_GREEN);
} else if (player.team == game.localPlayer.team) {
drawPlayerBox(player, COLOR_BLUE);
} else {
drawPlayerBox(player, COLOR_RED);
}
}
}获取同行详细信息
cpp
void showPeerInfo(const char* uid) {
if (!txnet_peer_is_same_server(uid)) {
printf("%s 不是同行\n", uid);
return;
}
const char* programs[10];
int count = txnet_peer_get_programs(uid, programs, 10);
printf("%s 是同行,使用了 %d 个程序:\n", uid, count);
for (int i = 0; i < count; i++) {
printf(" - %s\n", programs[i]);
}
}