增加ACE安全测试工程

This commit is contained in:
2025-12-06 16:42:21 +08:00
parent b78ee53326
commit b38ad590a9
68 changed files with 5385 additions and 0 deletions
+285
View File
@@ -0,0 +1,285 @@
#include "stdafx.h"
#include "GameClient.h"
#include <strsafe.h>
const char* GameClient::s_default_account_id = "979591";
const uint32_t GameClient::s_default_world_id = 160;
GameClient::GameClient()
: m_status(STATUS_DISCONNECTED)
, m_client(nullptr)
, m_looper(nullptr)
{
m_clientTickBuffer = new uint8_t[2048];
}
GameClient::~GameClient()
{
m_client = nullptr;
cyclone::Looper::destroy_looper(m_looper);
m_looper = nullptr;
delete[] m_clientTickBuffer;
m_clientTickBuffer = nullptr;
}
bool GameClient::init()
{
assert(m_status == STATUS_DISCONNECTED);
m_reportInterface.init(this);
m_clientNetbarInterface.init(this);
return m_aceClientInterface.init();
}
void GameClient::deinit()
{
m_aceClientInterface.deinit();
}
void GameClient::connectToGameServer(const std::string& server_ip, uint16_t server_port)
{
assert(m_status == STATUS_DISCONNECTED);
m_server_ip = server_ip;
m_server_port = server_port;
CY_LOG(cyclone::L_DEBUG, "connect to %s:%d...", server_ip.c_str(), server_port);
m_looper = cyclone::Looper::create_looper();
m_client = std::make_shared<cyclone::TcpClient>(m_looper, nullptr);
m_client->m_listener.on_connected = std::bind(&GameClient::onConnected, this, std::placeholders::_1, std::placeholders::_3);
m_client->m_listener.on_message = std::bind(&GameClient::onMessage, this, std::placeholders::_2);
m_client->m_listener.on_close = std::bind(&GameClient::onClose, this);
m_client->connect(cyclone::Address(m_server_ip.c_str(), m_server_port));
m_status = STATUS_CONNECTING;
}
void GameClient::disconnectFromGameServer()
{
if (m_client)
{
m_client->disconnect();
m_status = STATUS_LOGGING_OUT;
}
}
void GameClient::tick()
{
if (m_looper)
{
m_looper->step();
}
if (m_status == STATUS_LOGGED_IN)
{
uint32_t packetLen = 0;
m_aceClientInterface.getClientTickPacket(m_clientTickBuffer, packetLen);
if (packetLen > 0)
{
Game::ClientTickPacket clientTickPacket;
clientTickPacket.mutable_client_packet()->assign((const char*)m_clientTickBuffer, packetLen);
cyclone::Packet packet;
serializeProtoMessage(GAME_PROTO_CLIENT_PACKET, &clientTickPacket, packet);
m_client->send(packet.get_memory_buf(), packet.get_memory_size());
}
sendHeartBeat();
}
m_clientNetbarInterface.tick();
}
uint32_t GameClient::onConnected(cyclone::TcpClientPtr client, bool success)
{
assert(m_status == STATUS_CONNECTING);
CY_LOG(cyclone::L_DEBUG, "connect to %s:%d %s.",
client->get_server_address().get_ip(), client->get_server_address().get_port(),
success ? "OK" : "FAILED");
if (success)
{
m_status = STATUS_CONNECTED;
sendLoginRequest(s_default_account_id, s_default_world_id);
return 0;
}
else
{
return 1000 * 5;
}
}
void GameClient::sendLoginRequest(const char* accountID, int32_t worldID)
{
assert(m_status == STATUS_CONNECTED);
Game::LoginRequest loginRequest;
loginRequest.set_accound_id(accountID);
loginRequest.set_world_id(worldID);
loginRequest.set_pb_retcode(m_aceClientInterface.getPbRetCode());
cyclone::Packet packet;
serializeProtoMessage(GAME_PROTO_LOGIN_REQUEST, &loginRequest, packet);
m_client->send(packet.get_memory_buf(), packet.get_memory_size());
m_status = STATUS_LOGGING_IN;
}
void GameClient::onMessage(cyclone::TcpConnectionPtr conn)
{
cyclone::RingBuf& buf = conn->get_input_buf();
for (;;)
{
cyclone::Packet packet;
if (!packet.build_from_ringbuf(GAME_PACKET_HEAD_SIZE, buf)) return;
::google::protobuf::Message* message = parserProtoMessage(packet);
switch (packet.get_packet_id())
{
case GAME_PROTO_LOGIN_REPLY:
{
Game::LoginReply* loginReply = dynamic_cast<Game::LoginReply*>(message);
onServerLoginReply(conn, loginReply);
}
break;
case GAME_PROTO_SERVER_PACKET:
{
Game::ServerTickPacket* serverTickPacket = dynamic_cast<Game::ServerTickPacket*>(message);
onServerTickPacket(conn, serverTickPacket);
}
break;
case GAME_PROTO_UGC_REPLY:
{
Game::UGCReply* ugcReply = dynamic_cast<Game::UGCReply*>(message);
onServerUGCReply(conn, ugcReply);
}
break;
case GAME_PROTO_NETBAR_RES:
{
Game::NetbarStatusRes* netbarResponse = dynamic_cast<Game::NetbarStatusRes*>(message);
onServerNetbarResponse(conn, netbarResponse);
}
break;
}
}
}
void GameClient::onServerLoginReply(cyclone::TcpConnectionPtr conn, Game::LoginReply* reply)
{
assert(m_status == STATUS_LOGGING_IN);
m_aceClientInterface.onServerLoginReply(s_default_account_id, s_default_world_id,
reply->ace_token().c_str(),
reply->light_feature().name().c_str(),
reply->light_feature().data_crc(),
(const uint8_t*)reply->light_feature().data().data(),
(uint32_t)reply->light_feature().data().size()
);
m_status = STATUS_LOGGED_IN;
}
void GameClient::onServerTickPacket(cyclone::TcpConnectionPtr conn, Game::ServerTickPacket* reply)
{
assert(m_status == STATUS_LOGGED_IN || m_status==STATUS_LOGGING_IN);
m_aceClientInterface.onServerTickPacket(
(const uint8_t*)(reply->server_packet().data()),
(uint32_t)(reply->server_packet().size())
);
}
void GameClient::sendHeartBeat()
{
assert(m_status == STATUS_LOGGED_IN);
uint64_t timeNow = cyclone::sys_api::utc_time_now();
if(timeNow-m_lastHeartBeatTime < 60 * 1000ll*1000ll)
{
return;
}
m_lastHeartBeatTime = timeNow;
uint8_t bindBuffer[1024];
uint32_t bindDataLength = m_aceClientInterface.getProtoBindingData(bindBuffer, sizeof(bindBuffer));
Game::HeartBeat heartBeat;
heartBeat.set_timestamp((int32_t)timeGetTime());
heartBeat.mutable_pb_data()->assign((const char*)bindBuffer, bindDataLength);
cyclone::Packet packet;
serializeProtoMessage(GAME_PROTO_HEART_BEAT, &heartBeat, packet);
m_client->send(packet.get_memory_buf(), packet.get_memory_size());
}
void GameClient::onServerUGCReply(cyclone::TcpConnectionPtr conn, Game::UGCReply* reply)
{
assert(m_status == STATUS_LOGGED_IN);
wchar_t wszTemp[2048];
UINT btn = MB_OK;
if (reply->result() == 0)
{
StringCchPrintfW(wszTemp, sizeof(wszTemp)/sizeof(wszTemp[0]),
L"UGC Reply: ContextID=%d, ErrorCode=%d, Result=%d",
reply->ugc_ctx_id(),
reply->error_code(),
reply->result()
);
}
else
{
btn = MB_OK | MB_ICONERROR;
wchar_t wszFiltedContent[1024];
::MultiByteToWideChar(CP_UTF8, 0, reply->filted_content().c_str(), -1,
wszFiltedContent, sizeof(wszFiltedContent) / sizeof(wszFiltedContent[0]));
StringCchPrintfW(wszTemp, sizeof(wszTemp)/sizeof(wszTemp[0]),
L"UGC Reply: ContextID=%d, ErrorCode=%d, Result=%d, FiltedText='%s'",
reply->ugc_ctx_id(),
reply->error_code(),
reply->result(),
wszFiltedContent
);
}
MessageBoxW(NULL, wszTemp, L"UGC Reply", btn);
}
void GameClient::sendUGCContent(int32_t ugcSceneID, const char* content)
{
assert(m_status == STATUS_LOGGED_IN);
Game::UGCRequest ugcRequest;
ugcRequest.set_ugc_ctx_id(m_nextUGCContextID++);
ugcRequest.set_ugc_scene_id(ugcSceneID);
ugcRequest.set_ugc_content(content);
cyclone::Packet packet;
serializeProtoMessage(GAME_PROTO_UGC_REQUEST, &ugcRequest, packet);
m_client->send(packet.get_memory_buf(), packet.get_memory_size());
}
void GameClient::onClose(void)
{
m_aceClientInterface.onServerLogout();
m_status = STATUS_LOGGED_OUT;
}
void GameClient::sendProtobufMessage(uint16_t id, ::google::protobuf::Message* message)
{
cyclone::Packet packet;
serializeProtoMessage(id, message, packet);
m_client->send(packet.get_memory_buf(), packet.get_memory_size());
}
void GameClient::onServerNetbarResponse(cyclone::TcpConnectionPtr conn, Game::NetbarStatusRes* reply)
{
m_clientNetbarInterface.onReceiveNetbarReportRequest(reply);
}