Skip to content

同行检测

概述

同行检测系统用于检测同一局游戏中是否有其他用户也在使用本程序(或同系列程序)。可用于显示友好标识、避免误伤等场景。

工作原理

  1. 客户端提交自身信息(UID、昵称、世界地址)到服务器
  2. 客户端提交待检测的玩家列表
  3. 服务器比对同一世界地址下的所有用户
  4. 返回检测结果(是否同行、使用的程序列表)

内部机制

机制说明
自动去重已检测过的玩家不会重复提交
自动限流每 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);

提交自身信息到服务器。

参数类型说明
uidconst char*自身游戏内 UID
nicknameconst char*自身游戏内昵称
world_addressunsigned long long当前游戏世界的内存地址

调用频率

每帧调用。world_address 变化时自动清空所有检测状态。

txnet_peer_add_player

cpp
void txnet_peer_add_player(const char* uid, const char* nickname);

添加一个待检测的玩家。

参数类型说明
uidconst char*玩家游戏内 UID
nicknameconst 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);

获取同行使用的程序列表。

参数类型说明
uidconst char*玩家游戏内 UID
out_programsconst char**输出数组
max_countint输出数组的最大容量

返回值: 实际的程序数量

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
);
参数类型说明
uidconst char*玩家 UID
is_same_serverbool是否为同行
programsconst char**程序名称数组
program_countint程序数量

示例

基础用法

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]);
    }
}

TxNet 网络通信库文档