增加ACE安全测试工程
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
#include "stdafx.h"
|
||||
#include "AceClientInterface.h"
|
||||
|
||||
#include <ace_sdk_client.h>
|
||||
#include <ace_sdk_client_anti_cheat_core.h>
|
||||
#include <ace_sdk_protocol_binding.h>
|
||||
|
||||
bool AceClientInterface::init()
|
||||
{
|
||||
//init ace sdk client protocol binding
|
||||
m_protoBindingInitRetCode = AceProtocolBindingSDK::__ace_sdk_protocol_binding_init();
|
||||
if (m_protoBindingInitRetCode != ACE_SDK_RESULT_OK)
|
||||
{
|
||||
printf(">>ACE fail to init ace sdk client proto binding, ret : %d\n", m_protoBindingInitRetCode);
|
||||
//continue even failed...
|
||||
}
|
||||
printf(">>ACE SDK client proto binding init success.\n");
|
||||
|
||||
//init ace sdk
|
||||
AceSdkResult ret = ace_sdk_client_init();
|
||||
if(ret!= ACE_SDK_RESULT_OK)
|
||||
{
|
||||
printf(">>ACE fail to init ace sdk client, ret : %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AceClientInterface::deinit()
|
||||
{
|
||||
AceSdkResult ret = ace_sdk_client_deinit();
|
||||
}
|
||||
|
||||
bool AceClientInterface::onServerLoginReply(const char* accountID, uint32_t worldID,
|
||||
const char* loginToken,
|
||||
const char* lightFeatureName, uint32_t lightFeatureDataCRC,
|
||||
const uint8_t* lightFeatureData, uint32_t lightFeatureDataLengh)
|
||||
{
|
||||
//call ace client login
|
||||
AceSdkResult ret = ace_sdk_client_log_in(
|
||||
accountID, ACE_SDK_ACCOUNT_TYPE_QQ,
|
||||
worldID, loginToken
|
||||
);
|
||||
if(ret != ACE_SDK_RESULT_OK)
|
||||
{
|
||||
printf(">>ACE fail to call ace_sdk_client_log_in, ret : %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
//call ace client light feature data
|
||||
AceProtocolBindingSDK::g__ace_sdk_on_receive_signature(
|
||||
lightFeatureName,
|
||||
lightFeatureData,
|
||||
lightFeatureDataLengh,
|
||||
lightFeatureDataCRC
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AceClientInterface::onServerLogout()
|
||||
{
|
||||
AceSdkResult ret = ace_sdk_client_log_out();
|
||||
if(ret != ACE_SDK_RESULT_OK)
|
||||
{
|
||||
printf(">>ACE fail to call ace_sdk_client_log_out, ret : %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AceClientInterface::getClientTickPacket(uint8_t* out_buffer, uint32_t& out_len)
|
||||
{
|
||||
int64_t timeNow = cyclone::sys_api::utc_time_now();
|
||||
if(timeNow - m_lastTickTime < 100ll*1000ll)
|
||||
{
|
||||
out_len = 0;
|
||||
return;
|
||||
}
|
||||
m_lastTickTime = timeNow;
|
||||
AceSdkClientPacket packet;
|
||||
AceSdkResult ret = ace_sdk_client_get_packet(&packet);
|
||||
if (ret == ACE_SDK_RESULT_OK)
|
||||
{
|
||||
printf(">>ACE ace_sdk_client_get_packet, len : %d\n", packet.len);
|
||||
out_len = packet.len;
|
||||
memcpy(out_buffer, packet.buffer, packet.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_len = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void AceClientInterface::onServerTickPacket(const uint8_t* input_buffer, uint32_t input_len)
|
||||
{
|
||||
AceSdkResult ret = ace_sdk_client_on_packet_received(input_buffer, input_len);
|
||||
if(ret != ACE_SDK_RESULT_OK)
|
||||
{
|
||||
printf(">>ACE fail to call ace_sdk_client_on_packet_received, ret : %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AceClientInterface::getProtoBindingData(uint8_t* bindDataBuf, uint32_t buffSize)
|
||||
{
|
||||
AceProtocolBindingSDK::AceSdkAntiDataInfo bindingData;
|
||||
memset(&bindingData, 0, sizeof(bindingData));
|
||||
|
||||
AceProtocolBindingSDK::g__ace_sdk_get_report_data3(&bindingData);
|
||||
uint32_t dataLength = bindingData.anti_data_len_;
|
||||
|
||||
if (bindingData.anti_data_len_ <= buffSize)
|
||||
{
|
||||
memcpy(bindDataBuf, bindingData.anti_data_, bindingData.anti_data_len_);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(">>ACE fail to get proto binding data, buffer size too small!\n");
|
||||
}
|
||||
|
||||
AceProtocolBindingSDK::g__ace_sdk_del_report_data(&bindingData);
|
||||
return dataLength;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
class AceClientInterface
|
||||
{
|
||||
public:
|
||||
bool init();
|
||||
void deinit();
|
||||
|
||||
uint32_t getPbRetCode() const {
|
||||
return m_protoBindingInitRetCode;
|
||||
}
|
||||
|
||||
bool onServerLoginReply(const char* accountID, uint32_t worldID,
|
||||
const char* loginToken,
|
||||
const char* lightFeatureName, uint32_t lightFeatureDataCRC,
|
||||
const uint8_t* lightFeatureData, uint32_t lightFeatureDataLengh);
|
||||
void onServerLogout();
|
||||
|
||||
void getClientTickPacket(uint8_t* out_buffer, uint32_t& out_len);
|
||||
void onServerTickPacket(const uint8_t* input_buffer, uint32_t input_len);
|
||||
uint32_t getProtoBindingData(uint8_t* bindDataBuf, uint32_t buffSize);
|
||||
|
||||
protected:
|
||||
uint32_t m_protoBindingInitRetCode = 0;
|
||||
int64_t m_lastTickTime = 0;
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
#include "stdafx.h"
|
||||
#include "AceReportInterface.h"
|
||||
#include "GameProto.h"
|
||||
#include "GameProto.pb.h"
|
||||
#include "GameClient.h"
|
||||
|
||||
struct ACEReportStruct
|
||||
{
|
||||
int32_t id;
|
||||
Game::GameReportReq reportRequest;
|
||||
ACEReport::CallbackFunction callback;
|
||||
};
|
||||
|
||||
|
||||
ACEReport::ACEReport()
|
||||
{
|
||||
m_nextID = 1;
|
||||
}
|
||||
|
||||
ACEReport::~ACEReport()
|
||||
{
|
||||
}
|
||||
|
||||
void ACEReport::init(GameClient* client)
|
||||
{
|
||||
m_client = client;
|
||||
}
|
||||
|
||||
ACEReportContext ACEReport::createReportContext(
|
||||
const char* account,
|
||||
int32_t worldID,
|
||||
const char* reported_name,
|
||||
const char* reported_roldid,
|
||||
ACEReportScene scene,
|
||||
ACEReportCategory category,
|
||||
const ACEReportReasonArray& reasons,
|
||||
DNFReportEntranceID entranceID
|
||||
)
|
||||
{
|
||||
ACEReportStruct* ctx = new ACEReportStruct();
|
||||
ctx->id = m_nextID++;
|
||||
ctx->callback = nullptr;
|
||||
ctx->reportRequest.set_ctx_id(ctx->id);
|
||||
ctx->reportRequest.set_reported_account_id(account);
|
||||
ctx->reportRequest.set_reported_world_id(worldID);
|
||||
ctx->reportRequest.set_reported_name(reported_name);
|
||||
ctx->reportRequest.set_reported_roleid(reported_roldid);
|
||||
ctx->reportRequest.set_report_scene(static_cast<int32_t>(scene));
|
||||
ctx->reportRequest.set_report_category(static_cast<int32_t>(category));
|
||||
ctx->reportRequest.set_report_entrance(static_cast<int32_t>(entranceID));
|
||||
for(ACEReportReason reason: reasons)
|
||||
{
|
||||
ctx->reportRequest.add_report_reason(static_cast<int32_t>(reason));
|
||||
}
|
||||
|
||||
m_reportStructMap.insert(std::make_pair(ctx->id, ctx));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
ACEReportStruct* ACEReport::getReport(ACEReportContext ctx)
|
||||
{
|
||||
if (ctx == nullptr) return nullptr;
|
||||
ReportStructMap::iterator it = m_reportStructMap.find(ctx->id);
|
||||
if (it == m_reportStructMap.end()) return nullptr;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool ACEReport::uploadReport(ACEReportContext ctx, CallbackFunction callback)
|
||||
{
|
||||
ACEReportStruct* report = getReport(ctx);
|
||||
if (report == nullptr) return false;
|
||||
|
||||
Game::GameReportReq& reportReq = report->reportRequest;
|
||||
if(reportReq.report_reason_size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
report->callback = callback;
|
||||
|
||||
m_client->sendProtobufMessage(GAME_PROTO_REPORT_REQ, &reportReq);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
enum ACEReportScene
|
||||
{
|
||||
REPORT_SCENE_UGC = 1,
|
||||
REPORT_SCENE_INFORMATION=2,
|
||||
REPORT_SCENE_BATTLE=3,
|
||||
REPORT_SCENE_ARTICLE=4,
|
||||
REPORT_SCENE_COMMENT=5,
|
||||
REPORT_SCENE_IMAGE=6,
|
||||
REPORT_SCENE_ORGANIZE=7,
|
||||
REPORT_SCENE_OTHER=8,
|
||||
};
|
||||
|
||||
enum ACEReportCategory
|
||||
{
|
||||
REPORT_CATEGORY_ILLEGAL = 1,
|
||||
REPORT_CATEGORY_BEHAVIOR = 2,
|
||||
REPORT_CATEGORY_CHEAT = 3,
|
||||
REPORT_CATEGORY_STUDIO = 4,
|
||||
|
||||
REPORT_CATEGORY_UGC = 7,
|
||||
REPORT_CATEGORY_ORGANIZE = 8,
|
||||
REPORT_CATEGORY_PERSONAL = 9,
|
||||
};
|
||||
|
||||
enum ACEReportReason
|
||||
{
|
||||
//发布违规信息 REPORT_CATEGORY_ILLEGAL
|
||||
REPORT_REASON_ILLEGAL_ABUSE = 101,
|
||||
REPORT_REASON_ILLEGAL_ADVERTISEMENT = 102,
|
||||
REPORT_REASON_ILLEGAL_PORN = 103,
|
||||
REPORT_REASON_ILLEGAL_POLITICS = 104,
|
||||
REPORT_REASON_ILLEGAL_HARASS = 105,
|
||||
REPORT_REASON_ILLEGAL_VIOLENT = 106,
|
||||
REPORT_REASON_ILLEGAL_GAMBLE = 107,
|
||||
REPORT_REASON_ILLEGAL_CHEAT = 108,
|
||||
REPORT_REASON_ILLEGAL_PRIVACY_LEAKS = 109,
|
||||
REPORT_REASON_IULEGAL_INFRINGEMENT = 110,
|
||||
REPORT_REASON_ILLEGAL_OTHER = 199,
|
||||
|
||||
//恶意游戏行为 REPORT_CATEGORY BEHAVIOR
|
||||
REPORT_REASON_BEHAVIOR_FRIENDLYFIRE = 201,
|
||||
REPORT_REASON_BEHAVIOR_FORM_CHEATER_TEAM = 202,
|
||||
REPORT_REASON_BEHAVIOR_JOIN_CHEATER_TEAM = 203,
|
||||
REPORT_REASON_BEHAVIOR_GUARDED_BY_CHEATER = 204,
|
||||
REPORT_REASON_BEHAVIOR_EXPLOITING = 205,
|
||||
REPORT_REASON_BEHAVIOR_AUTO_ROBOT = 206,
|
||||
REPORT_REASON_BEHAVIOR_PASSIVE_PLAY = 207,
|
||||
REPORT_REASON_BEHAVIOR_MALICIOUS_REPEAT = 208,
|
||||
REPORT_REASON_BEHAVIOR_REFUSE_COOPERATE = 210,
|
||||
REPORT_REASON_BEHAVIOR_OTHER=299,
|
||||
|
||||
//使用作弊工具REPORT_CATEGORY_CHEAT
|
||||
REPORT_REASON_CHEAT_SEE_THROUTH = 301,
|
||||
REPORT_REASON_CHEAT_AUTO_AIM = 302,
|
||||
REPORT_REASON_CHEAT_NO_RECOIL = 303,
|
||||
REPORT_REASON_CHEAT_SPEED_UP = 304,
|
||||
REPORT_REASON_CHEAT_DAMAGE_RANGE = 305,
|
||||
REPORT_REASON_CHEAT_WALL_THROUGH = 306,
|
||||
REPORT_REASON_CHEAT_FLYING = 307,
|
||||
REPORT_REASON_CHEAT_TELEPORT = 308,
|
||||
REPORT_REASON_CHEAT_INSTANT_KILLING = 309,
|
||||
REPORT_REASON_CHEAT_AUTO_FIRING = 310,
|
||||
REPORT_REASON_CHEAT_MACRO = 311,
|
||||
REPORT_REASON_CHEAT_INF_PROJECTILES = 312,
|
||||
REPORT_REASON_CHEAT_SHOOTING_SPEED = 313,
|
||||
REPORT_REASON_CHEAT_INF_BULLETS = 314,
|
||||
REPORT_REASON_CHEAT_EXTERNAL_DEVICE = 315,
|
||||
REPORT_REASON_CHEAT_REMOTE_PICKING = 316,
|
||||
REPORT_REASON_CHEAT_REMOTE_KILLING = 317,
|
||||
REPORT_REASON_CHEAT_OTHER=399,
|
||||
|
||||
//工作室行为REPORT_CATEGORY_STUDIO
|
||||
REPORT_REASON_STUDIO_COMPETE_RESOURCE = 401,
|
||||
REPORT_REASON_STUDIO_OFFLINE_DEAL = 402,
|
||||
REPORT_REASON_STUDIO_ILLEGAL_BENEFITS = 403,
|
||||
REPORT_REASON_STUDIO_TEAM = 404,
|
||||
REPORT_REASON_STUDIO_MULTI_PLAVING = 405,
|
||||
REPORT_REASON_STUDIO_OTHER=499,
|
||||
|
||||
//自定义内容违规REPORT_CATEGORY_UGC
|
||||
REPORT_REASON_UGC_ILLEGAL_NAME = 701,
|
||||
REPORT_REASON_UGC_ILLEGAL_BRIEF = 702,
|
||||
REPORT_REASON_UGC_PORN_CONTENT = 703,
|
||||
REPORT_REASON_UGC_POLITICAL_CONTENT = 704,
|
||||
REPORT_REASON_UGC_ABUSIVE_CONTENT = 705,
|
||||
REPORT_REASON_UGC_FRAUDULENT_CONTENT = 706,
|
||||
REPORT_REASON_UGC_OTHER=799,
|
||||
};
|
||||
|
||||
enum DNFReportEntranceID
|
||||
{
|
||||
DNF_REPORT_ENTRANCE_TEST = 0,
|
||||
};
|
||||
|
||||
typedef std::vector<ACEReportReason> ACEReportReasonArray;
|
||||
struct ACEReportStruct;
|
||||
typedef ACEReportStruct* ACEReportContext;
|
||||
|
||||
class GameClient;
|
||||
|
||||
class ACEReport
|
||||
{
|
||||
public:
|
||||
ACEReport();
|
||||
~ACEReport();
|
||||
|
||||
void init(GameClient* client);
|
||||
|
||||
public:
|
||||
ACEReportContext createReportContext(
|
||||
const char* account,
|
||||
int32_t worldID,
|
||||
const char* reported_name,
|
||||
const char* reported_roldid,
|
||||
|
||||
ACEReportScene scene,
|
||||
ACEReportCategory category,
|
||||
const ACEReportReasonArray& reasons,
|
||||
DNFReportEntranceID entranceID = DNF_REPORT_ENTRANCE_TEST
|
||||
);
|
||||
|
||||
//设置对局ID和时间,如果要举报和战局有关的信息,这两条必须同时设置
|
||||
void setReportBattleID(ACEReportContext ctx, const char* battle_id, int32_t battle_time);
|
||||
//设置举报的描述信息,这里举报者自己描述的文本信息
|
||||
void setReportDesc(ACEReportContext ctx, const char* desc);
|
||||
//设置举报内容,这里是指要举报的目标内容
|
||||
void setContent(ACEReportContext ctx, const char* content);
|
||||
//设置举报的公会、战队、房间等组织的ID和名称
|
||||
void setGroupID(ACEReportContext ctx, const char* groupID, const char* groupName);
|
||||
//设置举报者的头像URL,最大长度4096字寸,要求外网或者IDC个的多访问下载
|
||||
void setReportedProfileUrl(ACEReportContext ctx, const char* profileURL);
|
||||
//添加举报的图片URL,可以添加多个(最多12个),单条最人长度4096字节,要求外网或者IDC能够访问下载
|
||||
void addReportedPictureURL(ACEReportContext ctx, const char* profileURL);
|
||||
//添加举报的视频URL,可以添加多个(最务1个),单条最人长度4096字节,要求外网或者IDC能够访问下载
|
||||
void addReportedVideoURL(ACEReportContext ctx, const char* profileuRL);
|
||||
//添加举报的语音URL,可以添加多个(最多12个),单条最大长度409
|
||||
void addReportedVoiceURL(ACEReportContext tx, const char* profileURL);
|
||||
//添加其他需要添加的ID,例如文章T,房间T0等,每种类型都可以添加多个, addReportcontent(ctx, "room id",“123456");
|
||||
void addReportIDContent(ACEReportContext ctx, const char* idTyne, const char* idContent);
|
||||
|
||||
//上报结果回调
|
||||
typedef std::function<void(ACEReportContext ctx, int32_t result, const char* error_message)> CallbackFunction;
|
||||
bool uploadReport(ACEReportContext ctx, CallbackFunction callback);
|
||||
|
||||
private:
|
||||
void onReportResult(int32_t reportID, uint32_t result, const char* errorMessage);
|
||||
ACEReportStruct* getReport(ACEReportContext ctx);
|
||||
|
||||
private:
|
||||
GameClient* m_client = nullptr;
|
||||
|
||||
typedef std::map<int32_t, ACEReportContext> ReportStructMap;
|
||||
ReportStructMap m_reportStructMap;
|
||||
int32_t m_nextID = 0;
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
|
||||
set(ACLIENT_SOURCE_FILES
|
||||
stdafx.h
|
||||
main.cpp
|
||||
MainDialog.h
|
||||
MainDialog.cpp
|
||||
GameClient.h
|
||||
GameClient.cpp
|
||||
AceClientInterface.h
|
||||
AceClientInterface.cpp
|
||||
AceReportInterface.h
|
||||
AceReportInterface.cpp
|
||||
NetbarInterface.h
|
||||
NetbarInterface.cpp
|
||||
)
|
||||
|
||||
set(ACLIENT_RC_FILES
|
||||
aClient.rc
|
||||
)
|
||||
|
||||
source_group("Resource Files" FILES ${ACLIENT_RC_FILES})
|
||||
|
||||
set(ACLIENT_PRECOMPILE_FILE
|
||||
stdafx.cpp
|
||||
)
|
||||
|
||||
foreach(filename ${ACLIENT_SOURCE_FILES})
|
||||
get_filename_component(ext ${filename} LAST_EXT ABSOLUTE)
|
||||
string(TOLOWER ${ext} ext_lower)
|
||||
if(${ext_lower} STREQUAL ".cpp" )
|
||||
set_source_files_properties(
|
||||
${filename}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "/Yustdafx.h"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set_source_files_properties(${ACLIENT_PRECOMPILE_FILE}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "/Ycstdafx.h"
|
||||
)
|
||||
|
||||
add_executable(aClient WIN32
|
||||
${ACLIENT_SOURCE_FILES}
|
||||
${ACLIENT_RC_FILES}
|
||||
${ACLIENT_PRECOMPILE_FILE}
|
||||
)
|
||||
|
||||
target_include_directories(aClient
|
||||
PRIVATE
|
||||
${ACE_CLIENT_DIR}/include
|
||||
${WTL_DIR}/include
|
||||
${CYCLONE_DIR}/include
|
||||
${GAME_PROTO_DIR}
|
||||
)
|
||||
|
||||
target_link_directories(aClient
|
||||
PRIVATE
|
||||
${CYCLONE_DIR}/lib
|
||||
)
|
||||
|
||||
target_link_libraries(aClient
|
||||
PRIVATE
|
||||
aGameProto
|
||||
cyclone.lib
|
||||
ws2_32.lib
|
||||
shlwapi.lib
|
||||
winmm.lib
|
||||
)
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include "GameProto.h"
|
||||
#include "GameProto.pb.h"
|
||||
#include "AceClientInterface.h"
|
||||
#include "AceReportInterface.h"
|
||||
#include "NetbarInterface.h"
|
||||
|
||||
class GameClient
|
||||
{
|
||||
public:
|
||||
enum Status
|
||||
{
|
||||
STATUS_DISCONNECTED = 0,
|
||||
//call connectToGameServer...
|
||||
STATUS_CONNECTING,
|
||||
//onConnected
|
||||
STATUS_CONNECTED,
|
||||
//call sendLoginRequest...
|
||||
STATUS_LOGGING_IN,
|
||||
//onServerLoginReply
|
||||
STATUS_LOGGED_IN,
|
||||
|
||||
//call sendLogoutRequest...
|
||||
|
||||
STATUS_LOGGING_OUT,
|
||||
//socket closed
|
||||
STATUS_LOGGED_OUT,
|
||||
|
||||
STATUS_FAILED,
|
||||
};
|
||||
|
||||
const static char* s_default_account_id;
|
||||
const static uint32_t s_default_world_id;
|
||||
|
||||
public:
|
||||
bool init();
|
||||
void deinit();
|
||||
void connectToGameServer(const std::string& server_ip, uint16_t server_port);
|
||||
void disconnectFromGameServer();
|
||||
|
||||
void sendProtobufMessage(uint16_t id, ::google::protobuf::Message* message);
|
||||
void sendUGCContent(int32_t ugcSceneID, const char* content);
|
||||
|
||||
ACEReport* getAceReportInterface(void) { return &m_reportInterface; }
|
||||
TencentNetbarInterface* getNetbarInterface(void) { return &m_clientNetbarInterface; }
|
||||
|
||||
void tick();
|
||||
cyclone::TcpClientPtr get_client(void) { return m_client; }
|
||||
|
||||
protected:
|
||||
uint32_t onConnected(cyclone::TcpClientPtr client, bool success);
|
||||
void onMessage(cyclone::TcpConnectionPtr conn);
|
||||
void onClose(void);
|
||||
|
||||
protected:
|
||||
void sendLoginRequest(const char* accountID, int32_t worldID);
|
||||
void onServerLoginReply(cyclone::TcpConnectionPtr conn, Game::LoginReply* reply);
|
||||
void onServerTickPacket(cyclone::TcpConnectionPtr conn, Game::ServerTickPacket* reply);
|
||||
void onServerUGCReply(cyclone::TcpConnectionPtr conn, Game::UGCReply* reply);
|
||||
void onServerNetbarResponse(cyclone::TcpConnectionPtr conn, Game::NetbarStatusRes* reply);
|
||||
void sendHeartBeat();
|
||||
private:
|
||||
Status m_status = STATUS_DISCONNECTED;
|
||||
cyclone::TcpClientPtr m_client;
|
||||
cyclone::Looper* m_looper;
|
||||
std::string m_server_ip;
|
||||
uint16_t m_server_port;
|
||||
uint64_t m_lastHeartBeatTime = 0;
|
||||
|
||||
AceClientInterface m_aceClientInterface;
|
||||
uint8_t* m_clientTickBuffer = nullptr;
|
||||
|
||||
ACEReport m_reportInterface;
|
||||
int32_t m_nextUGCContextID = 1;
|
||||
|
||||
TencentNetbarInterface m_clientNetbarInterface;
|
||||
public:
|
||||
GameClient();
|
||||
~GameClient();
|
||||
};
|
||||
@@ -0,0 +1,170 @@
|
||||
#include "stdafx.h"
|
||||
#include "MainDialog.h"
|
||||
|
||||
#include "AceReportInterface.h"
|
||||
|
||||
#include <tlhelp32.h>
|
||||
#include <psapi.h>
|
||||
|
||||
LRESULT CMainDialog::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
CenterWindow(GetParent());
|
||||
if(m_gameClient.init()==false)
|
||||
{
|
||||
MessageBoxA("Failed to init Ace SDK client interface!", "Error", MB_OK|MB_ICONERROR);
|
||||
CloseDialog(IDCANCEL);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
CloseDialog(wID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
CloseDialog(wID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CMainDialog::CloseDialog(int nVal)
|
||||
{
|
||||
m_gameClient.deinit();
|
||||
DestroyWindow();
|
||||
::PostQuitMessage(nVal);
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
if(wParam==101)
|
||||
{
|
||||
m_gameClient.tick();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnConnectToGameServer(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
m_gameClient.connectToGameServer("127.0.0.1", 2025);
|
||||
this->SetTimer(101, 100, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnDisconnectToGameServer(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
this->KillTimer(101);
|
||||
m_gameClient.disconnectFromGameServer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnSendUGCContent(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
// To be implemented
|
||||
wchar_t wszUgcContent[2048];
|
||||
::GetDlgItemTextW(m_hWnd, IDC_EDIT_UGC_CONTENT, wszUgcContent, sizeof(wszUgcContent)/sizeof(wchar_t));
|
||||
|
||||
char szUtf8UgcContent[2048] = { 0 };
|
||||
::WideCharToMultiByte(CP_UTF8, 0, wszUgcContent, -1, szUtf8UgcContent, sizeof(szUtf8UgcContent), NULL, NULL);
|
||||
|
||||
m_gameClient.sendUGCContent(101, szUtf8UgcContent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnSendReport(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
ACEReport* reportInterface = m_gameClient.getAceReportInterface();
|
||||
|
||||
auto ctx = reportInterface->createReportContext(
|
||||
"reporter_account",
|
||||
1,
|
||||
"reported_name",
|
||||
"reported_roleid",
|
||||
ACEReportScene::REPORT_SCENE_UGC,
|
||||
ACEReportCategory::REPORT_CATEGORY_BEHAVIOR,
|
||||
ACEReportReasonArray{ ACEReportReason::REPORT_REASON_ILLEGAL_ABUSE, ACEReportReason::REPORT_REASON_ILLEGAL_ADVERTISEMENT },
|
||||
DNF_REPORT_ENTRANCE_TEST
|
||||
);
|
||||
|
||||
reportInterface->uploadReport(ctx, [this](ACEReportContext ctx, int32_t result, const char* error_message) {
|
||||
if (result == 0) {
|
||||
::MessageBoxA(m_hWnd, "Report uploaded successfully!", "Info", MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
else {
|
||||
::MessageBoxA(m_hWnd, error_message, "Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnNetbarClientLoad(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
TencentNetbarInterface* netbarInterface = m_gameClient.getNetbarInterface();
|
||||
netbarInterface->beginRequestNetbarStatus(
|
||||
[this](TencentNetbarInterface::RequestStatus status)
|
||||
{
|
||||
// Handle the request status update here
|
||||
switch (status) {
|
||||
case TencentNetbarInterface::RS_RequestDone:
|
||||
::MessageBoxA(m_hWnd, "Netbar status request completed successfully!", "Info", MB_OK | MB_ICONINFORMATION);
|
||||
break;
|
||||
case TencentNetbarInterface::RS_ReqestFailed:
|
||||
::MessageBoxA(m_hWnd, "Netbar status request failed!", "Error", MB_OK | MB_ICONERROR);
|
||||
break;
|
||||
default:
|
||||
// Other statuses can be handled as needed
|
||||
break;
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsProcessRunning(DWORD pid)
|
||||
{
|
||||
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (hSnapshot == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PROCESSENTRY32 pe;
|
||||
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
bool isRunning = false;
|
||||
if (Process32First(hSnapshot, &pe)) {
|
||||
do {
|
||||
if (pe.th32ProcessID == pid) {
|
||||
isRunning = true;
|
||||
break;
|
||||
}
|
||||
} while (Process32Next(hSnapshot, &pe));
|
||||
}
|
||||
|
||||
CloseHandle(hSnapshot);
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
LRESULT CMainDialog::OnCheckMainPlayProcess(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
wchar_t wszPid[64];
|
||||
::GetDlgItemTextW(m_hWnd, IDC_EDIT_MAINPLAY_PID, wszPid, sizeof(wszPid)/sizeof(wchar_t));
|
||||
DWORD pid = _wtoi(wszPid);
|
||||
if (pid == 0)
|
||||
{
|
||||
::MessageBoxA(m_hWnd, "Invalid PID!", "Error", MB_OK | MB_ICONERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isRunning = IsProcessRunning(pid);
|
||||
if (isRunning)
|
||||
{
|
||||
::MessageBoxA(m_hWnd, "MainPlay process is running.", "Info", MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
::MessageBoxA(m_hWnd, "MainPlay process is not running.", "Info", MB_OK | MB_ICONSTOP);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "resource.h"
|
||||
|
||||
#include "GameClient.h"
|
||||
|
||||
class CMainDialog : public CDialogImpl<CMainDialog>
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_DIALOG_MAIN };
|
||||
|
||||
BEGIN_MSG_MAP(CMainDialog)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_ID_HANDLER(IDOK, OnOK)
|
||||
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
|
||||
|
||||
MESSAGE_HANDLER(WM_TIMER, OnTimer)
|
||||
COMMAND_ID_HANDLER(IDC_BUTTON_CONNECT_GAME_SERVER, OnConnectToGameServer)
|
||||
COMMAND_ID_HANDLER(IDC_BUTTON_DISCONNECT_GAME_SERVER, OnDisconnectToGameServer)
|
||||
COMMAND_ID_HANDLER(IDC_BUTTON_UGC_SEND, OnSendUGCContent)
|
||||
COMMAND_ID_HANDLER(IDC_BUTTON_REPORT_SEND, OnSendReport)
|
||||
COMMAND_ID_HANDLER(IDC_BUTTON_NETBAR_CLIENTLOAD, OnNetbarClientLoad)
|
||||
COMMAND_ID_HANDLER(IDC_BUTTON_CHECK_MAINPLAY_PROCESS, OnCheckMainPlayProcess)
|
||||
END_MSG_MAP()
|
||||
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
return ::IsDialogMessage(m_hWnd, pMsg);
|
||||
}
|
||||
|
||||
private:
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnTimer(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnConnectToGameServer(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnDisconnectToGameServer(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnSendUGCContent(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnSendReport(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnNetbarClientLoad(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnCheckMainPlayProcess(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
|
||||
void CloseDialog(int nVal);
|
||||
|
||||
protected:
|
||||
GameClient m_gameClient;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
#include "stdafx.h"
|
||||
#include "NetbarInterface.h"
|
||||
#include "iigw_api_client.h"
|
||||
#include "GameProto.h"
|
||||
#include "GameProto.pb.h"
|
||||
#include "GameClient.h"
|
||||
|
||||
TencentNetbarInterface::TencentNetbarInterface()
|
||||
{
|
||||
m_requestStatus.store(RS_NotRequest);
|
||||
m_workThread = NULL;
|
||||
m_netbarStatus = NS_Unknown;
|
||||
m_clientErrorCode = 0;
|
||||
m_serverErrorCode = 0;
|
||||
m_serverErrorMessage.clear();
|
||||
m_netbarLevel = -1;
|
||||
m_clientNetbarReq = new Game::NetbaraStatusReq();
|
||||
}
|
||||
|
||||
TencentNetbarInterface::~TencentNetbarInterface()
|
||||
{
|
||||
delete m_clientNetbarReq;
|
||||
m_clientNetbarReq = nullptr;
|
||||
}
|
||||
|
||||
void TencentNetbarInterface::init(GameClient* client)
|
||||
{
|
||||
m_client = client;
|
||||
}
|
||||
|
||||
void TencentNetbarInterface::tick()
|
||||
{
|
||||
switch (m_requestStatus)
|
||||
{
|
||||
case RequestStatus::RS_ClientRequest_Done:
|
||||
{
|
||||
m_client->sendProtobufMessage(GameProto::GAME_PROTO_NETBAR_REQ, m_clientNetbarReq);
|
||||
m_requestStatus = RequestStatus::RS_ServerRequesting;
|
||||
}
|
||||
break;
|
||||
|
||||
case RequestStatus::RS_ClientRequest_Failed:
|
||||
{
|
||||
m_requestStatus = RequestStatus::RS_ReqestFailed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool TencentNetbarInterface::beginRequestNetbarStatus(RequestCallback callback)
|
||||
{
|
||||
if(m_requestStatus==RequestStatus::RS_RequestDone || m_requestStatus==RequestStatus::RS_ReqestFailed)
|
||||
{
|
||||
//already done
|
||||
if(callback)
|
||||
{
|
||||
callback(m_requestStatus.load());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(m_requestStatus != RequestStatus::RS_NotRequest)
|
||||
{
|
||||
//already requesting
|
||||
return false;
|
||||
}
|
||||
|
||||
m_requestStatus = RequestStatus::RS_ClientRequesting;
|
||||
|
||||
unsigned int threadID = 0;
|
||||
m_workThread = (HANDLE)_beginthreadex(NULL, 0, TencentNetbarInterface::_workingThreadEntry, this, 0,&threadID);
|
||||
if(m_workThread == NULL)
|
||||
{
|
||||
m_requestStatus = RequestStatus::RS_ClientRequest_Failed;
|
||||
return false;
|
||||
}
|
||||
m_requestCallback = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int TencentNetbarInterface::_workingThreadEntry(void* param)
|
||||
{
|
||||
TencentNetbarInterface* pThis = (TencentNetbarInterface*)param;
|
||||
if(pThis)
|
||||
{
|
||||
pThis->workThreadEntry();
|
||||
}
|
||||
::CloseHandle(pThis->m_workThread);
|
||||
pThis->m_workThread = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TencentNetbarInterface::workThreadEntry()
|
||||
{
|
||||
HMODULE hNetbarDllHandle = NULL;
|
||||
bool isSuccess = false;
|
||||
|
||||
do {
|
||||
hNetbarDllHandle = ::LoadLibraryW(L"iigw_client_api.dll");
|
||||
if (hNetbarDllHandle == NULL)
|
||||
{
|
||||
m_clientErrorCode = GetLastError();
|
||||
m_requestStatus = RequestStatus::RS_ClientRequest_Failed;
|
||||
break;
|
||||
}
|
||||
|
||||
//create interface
|
||||
iepm_qqwb::IQQNetbarIIGWPlugin *pProxy = iepm_qqwb::CreateQQNetbarIIGWPlugin(hNetbarDllHandle);
|
||||
if(pProxy == nullptr)
|
||||
{
|
||||
m_requestStatus = RequestStatus::RS_ClientRequest_Failed;
|
||||
break;
|
||||
}
|
||||
|
||||
//call client interfae
|
||||
int ret = pProxy->IsNetbarMachine(TENCENT_NETBAR_DNF_CLIENT_GAME_ID, GameClient::s_default_account_id, iepm_qqwb::at_qq);
|
||||
bool isNetbar = (ret == IIGW_MSG_STATUS_NETBAR_PC);
|
||||
|
||||
iepm_qqwb::NetbarLv netbarlv = {0};
|
||||
memset(&netbarlv, 0, sizeof(netbarlv));
|
||||
|
||||
m_clientErrorCode = pProxy->ReqNetbarLv2(
|
||||
TENCENT_NETBAR_DNF_CLIENT_GAME_ID,
|
||||
GameClient::s_default_world_id,
|
||||
GameClient::s_default_account_id,
|
||||
iepm_qqwb::at_qq,
|
||||
nullptr,
|
||||
0,
|
||||
&netbarlv,
|
||||
5000
|
||||
);
|
||||
|
||||
if (m_clientErrorCode != 0 || netbarlv.tokenLen<=0 )
|
||||
{
|
||||
m_requestStatus = RequestStatus::RS_ClientRequest_Failed;
|
||||
break;
|
||||
}
|
||||
|
||||
m_clientNetbarReq->Clear();
|
||||
m_clientNetbarReq->set_is_netbar_machine(isNetbar);
|
||||
m_clientNetbarReq->set_token((const char*)netbarlv.tokenBuff, (size_t)netbarlv.tokenLen);
|
||||
m_clientNetbarReq->set_macs(netbarlv.macs);
|
||||
|
||||
m_requestStatus = RequestStatus::RS_ClientRequest_Done;
|
||||
|
||||
isSuccess = true;
|
||||
} while (false);
|
||||
|
||||
if(hNetbarDllHandle)
|
||||
{
|
||||
::FreeLibrary(hNetbarDllHandle);
|
||||
hNetbarDllHandle = NULL;
|
||||
}
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
void TencentNetbarInterface::onReceiveNetbarReportRequest(Game::NetbarStatusRes* response)
|
||||
{
|
||||
m_netbarLevel = response->netbar_level();
|
||||
m_serverErrorCode = response->error_code();
|
||||
m_serverErrorMessage = response->error_message();
|
||||
|
||||
if (m_serverErrorCode == 0)
|
||||
{
|
||||
m_serverErrorCode = NetbarStatus::NS_Netbar;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_serverErrorCode = NetbarStatus::NS_ServerFailed;
|
||||
}
|
||||
m_requestStatus = RequestStatus::RS_RequestDone;
|
||||
|
||||
if (m_requestCallback)
|
||||
{
|
||||
m_requestCallback(m_requestStatus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
|
||||
namespace Game
|
||||
{
|
||||
class NetbaraStatusReq;
|
||||
class NetbarStatusRes;
|
||||
};
|
||||
class GameClient;
|
||||
|
||||
class TencentNetbarInterface
|
||||
{
|
||||
public:
|
||||
TencentNetbarInterface();
|
||||
~TencentNetbarInterface();
|
||||
public:
|
||||
enum RequestStatus
|
||||
{
|
||||
RS_NotRequest=0,
|
||||
RS_ClientRequesting,
|
||||
RS_ClientRequest_Done,
|
||||
RS_ClientRequest_Failed,
|
||||
RS_ServerRequesting,
|
||||
|
||||
RS_ReqestFailed,
|
||||
RS_RequestDone,
|
||||
};
|
||||
|
||||
enum NetbarStatus
|
||||
{
|
||||
NS_Unknown = 0,
|
||||
NS_Netbar,
|
||||
|
||||
NS_ClientFailed,
|
||||
NS_ServerFailed,
|
||||
};
|
||||
|
||||
typedef std::function<void(RequestStatus)> RequestCallback;
|
||||
bool beginRequestNetbarStatus(RequestCallback callback);
|
||||
|
||||
void onReceiveNetbarReportRequest(Game::NetbarStatusRes* response);
|
||||
|
||||
void init(GameClient* client);
|
||||
void tick();
|
||||
private:
|
||||
static unsigned int _workingThreadEntry(void* param);
|
||||
bool workThreadEntry();
|
||||
|
||||
private:
|
||||
enum { TENCENT_NETBAR_DNF_CLIENT_GAME_ID = 20 };
|
||||
|
||||
private:
|
||||
GameClient* m_client = nullptr;
|
||||
|
||||
std::atomic<RequestStatus> m_requestStatus;
|
||||
HANDLE m_workThread;
|
||||
|
||||
NetbarStatus m_netbarStatus;
|
||||
|
||||
int32_t m_clientErrorCode;
|
||||
|
||||
int32_t m_serverErrorCode;
|
||||
std::string m_serverErrorMessage;
|
||||
|
||||
int32_t m_netbarLevel;
|
||||
RequestCallback m_requestCallback;
|
||||
|
||||
Game::NetbaraStatusReq* m_clientNetbarReq = nullptr;
|
||||
};
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,580 @@
|
||||
/************************************************************
|
||||
Copyright (C), 2008-2018, Tencent Tech. Co., Ltd.
|
||||
FileName: iigw_api_client.h
|
||||
Author: cooperli Version : 1.0 Date: 2008-03-25
|
||||
Description: 信息网关API头文件
|
||||
|
||||
History:
|
||||
<author> <time> <version > <desc>
|
||||
cooperli 2008-03-27 1.0 build
|
||||
***********************************************************/
|
||||
#ifndef _ITC_CLIENT_H_
|
||||
#define _ITC_CLIENT_H_
|
||||
|
||||
// VC动态库
|
||||
#ifdef iigw_client_api_EXPORTS
|
||||
#define IIGW_DLL_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define IIGW_DLL_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#define SVR_PROT 5692 // IIGW SERVER 的端口
|
||||
#define INFOGW_MAX_MSG_LEN 2048 // 最大消息长度为512 BYTE
|
||||
#define INFOGW_MAX_TO_GAME_SVR_STR_LEN 256 // 最大送到GAME SERVER的串长度为256 BYTE
|
||||
#define INFOGW_MIN_ERR_BUF_LEN 256 // 最小消息长度为256 BYTE
|
||||
#define INFOGW_OPEN_ID_LEN 64
|
||||
|
||||
// 消息类型定义INFOGW_MSG_TYPE
|
||||
enum
|
||||
{
|
||||
INFOGW_MSG_TYPE_REQ = 1, // 请求消息
|
||||
INFOGW_MSG_TYPE_ACK = 2, // 回应消息
|
||||
INFOGW_MSG_TYPE_BOTTOM // 底部,无效值
|
||||
};
|
||||
|
||||
// 消息错误类型定义
|
||||
enum IIGW_MSG_STATUS
|
||||
{
|
||||
IIGW_MSG_STATUS_OK = 0, // 正确消息
|
||||
IIGW_MSG_STATUS_UNKNOWN_VER_ERR = 1, // MAGIC KEY出错
|
||||
IIGW_MSG_STATUS_MSG_TYPE_ERR = 2, // 消息类型错误
|
||||
IIGW_MSG_STATUS_OPT_ERR = 3, // 业务类型出错
|
||||
IIGW_MSG_STATUS_NO_RETURN = 4, // 没有收到对端的回应
|
||||
IIGW_MSG_STATUS_CRYPT_LEN_ERR = 5, // TO GAME SVR的消息长度出错
|
||||
IIGW_MSG_STATUS_MSG_LEN_ERR = 6, // 消息长度出错
|
||||
IIGW_MSG_STATUS_BUF_LEN_ERR = 7, // 输入BUFFFER长度太少
|
||||
IIGW_MSG_STATUS_RD_CFG_ERR = 8, // 读配置出错
|
||||
IIGW_MSG_STATUS_CONNECT_ERR = 9, // 连接出错
|
||||
IIGW_MSG_STATUS_SENT_MSG_ERR = 10, // 发送消息出错
|
||||
IIGW_MSG_STATUS_DNS_RESOLVE_ERR = 30, // DNS解释出错,不能把域名解释成IP
|
||||
IIGW_MSG_STATUS_PARSE_RSP_ERR = 11, // 解析返回包出错
|
||||
IIGW_MSG_STATUS_PARA_ERR = -1, // 参数出错
|
||||
|
||||
// 服务端发现的错误lix
|
||||
IIGW_MSG_STATUS_UNKNOWN_VER_ERR_R = 101, // MAGIC KEY出错
|
||||
IIGW_MSG_STATUS_MSG_TYPE_ERR_R = 102, // 消息类型错误
|
||||
IIGW_MSG_STATUS_OPT_ERR_R = 103, // 业务类型出错
|
||||
IIGW_MSG_STATUS_HEARD_LEN_ERR_R = 104, // 消息协议头长度出错
|
||||
IIGW_MSG_STATUS_OPT_LEN_ERR = 105, // 业务信息长度出错
|
||||
IIGW_MSG_STATUS_OPT_COUNT_ERR = 106, // 业务信息长度出错
|
||||
IIGW_MSG_STATUS_NET_ERR_R = 107, // 网络通讯出错
|
||||
IIGW_MSG_STATUS_RES_LIMIT_R = 110, // 资源受限
|
||||
|
||||
IIGW_MSG_STATUS_BJ_NEW_USER = 200, // CF !!! 北京新用户,禁止登陆
|
||||
|
||||
IIGW_MSG_STATUS_NETBAR_PC = 256, // 是网吧机器
|
||||
IIGW_MSG_STATUS_NOT_IN_NETBAR = 300, // 非网吧环境
|
||||
IIGW_MSG_STATUS_NOT_A_CHINESE_OS = 301, // 非中文操作系统
|
||||
|
||||
IIGW_MSG_STATUS_VMP_CRC_ERROR = 400,
|
||||
IIGW_MSG_STATUS_VMP_DEBUG_ERROR = 401,
|
||||
IIGW_MSG_STATUS_OS_SEH_ERROR = 402,
|
||||
IIGW_MSG_STATUS_CPP_SEH_ERROR = 403,
|
||||
IIGW_MSG_STATUS_UNKNOW_ERROR = 404,
|
||||
IIGW_MSG_STATUS_BOTTOM // 底部,无效值
|
||||
};
|
||||
|
||||
// 业务ID定义 INFOGW_OPERATION_ID
|
||||
enum
|
||||
{
|
||||
INFOGW_OPERATION_CF = 10, // CF查询网吧等级业务ID
|
||||
INFOGW_OPERATION_DNF = 20, // DNF查询网吧等级业务ID
|
||||
INFOGW_OPERATION_ID_BOTTOM // 底部,无效值
|
||||
};
|
||||
|
||||
typedef unsigned int UINT;
|
||||
typedef struct infoGWReqMsgHeader_st
|
||||
{
|
||||
UINT uiVersion; // 版本号,认证头
|
||||
UINT uiMsgType; // 消息类型,可以表示客户端消息,服务后台消息等
|
||||
UINT uiSeqNo; //
|
||||
UINT uiTime; // 本地时间戳
|
||||
UINT uiOperationId; // 查询的业务类型 .参看 enum INFOGW_OPERATION_ID
|
||||
UINT uiStatus; // 当为接收的信息时有效
|
||||
UINT uiMsgBodyLen; // 业务消息长度
|
||||
} INFOGW_INTF_CLIENT_MSG_HEADER;
|
||||
|
||||
typedef struct infoGWReqMsg_st
|
||||
{
|
||||
INFOGW_INTF_CLIENT_MSG_HEADER stMsgHd;
|
||||
char szMsgBody[INFOGW_MAX_MSG_LEN]; // 业务相关消息体
|
||||
} INFOGW_INTF_CLIENT_MSG;
|
||||
|
||||
typedef struct infoGWReqNetbarLv_st
|
||||
{
|
||||
unsigned int uiUni;
|
||||
unsigned int ulNetbarIP;
|
||||
} INFOGW_REQ_NETBAR_LV;
|
||||
|
||||
|
||||
typedef struct infoGWReqNetbarLvOpenid_st
|
||||
{
|
||||
unsigned int uiType;
|
||||
char open_id[INFOGW_OPEN_ID_LEN];
|
||||
unsigned int ulNetbarIP;
|
||||
} INFOGW_REQ_NETBAR_LV_OPENID;
|
||||
|
||||
// TO GAME SERVER 的的加密串的明文结构
|
||||
typedef struct IIGWNetbar_st
|
||||
{
|
||||
unsigned int ulInfoGWTimeStamp; // 时间截
|
||||
unsigned int uiUni; // QQ号码
|
||||
unsigned int ulNetbarIP; // 网吧ip
|
||||
unsigned char ucNetbarLv; // 网吧等级
|
||||
//unsigned int ulNetbarLv; // 网吧等级v2
|
||||
unsigned char ucCreditRank; // 荣誉等级
|
||||
unsigned char ucTeamRank; // 战队等级
|
||||
unsigned char ucVIP; // 会员VIP
|
||||
unsigned char ucCampaign; // 活动
|
||||
unsigned char ucReserve[15]; // 备用
|
||||
} INFOGW_NETBAR;
|
||||
|
||||
//==============================================================
|
||||
#define IIGE_MAX_OP_COUNT 15 // 批量查询每次查询的最大业务数量
|
||||
#define IIGW_CRYPT_BUF_LEN 128 // 批量查询返回加密串缓存区长度
|
||||
|
||||
typedef struct IIGW_OPERATIONS
|
||||
{
|
||||
int count;
|
||||
unsigned int uiOperationId[IIGE_MAX_OP_COUNT];
|
||||
} INFOGW_OPIDS;
|
||||
|
||||
typedef struct IIGW_NETBAR_INFO_
|
||||
{
|
||||
unsigned int uiOperationId;
|
||||
int iStatus; // 返回状态:1-正常,0-非正常
|
||||
unsigned int ucCryptBufLen;
|
||||
unsigned char szCryptBuf[IIGW_CRYPT_BUF_LEN];
|
||||
} IIGW_NETBAR_INFO;
|
||||
|
||||
typedef struct IIGW_NETBAR_INFO_BATCH_ {
|
||||
int count;
|
||||
IIGW_NETBAR_INFO stNetbarInfo[IIGE_MAX_OP_COUNT];
|
||||
} IIGW_NETBAR_INFO_BATCH;
|
||||
//==============================================================
|
||||
|
||||
/*************************************************
|
||||
Function: INFOGW_api_req_netbar_lv
|
||||
Description: 请求查询网吧等级,并等待回应的加密包
|
||||
|
||||
Calls: INFOGW_api_set_server
|
||||
INFOGW_send_recv
|
||||
Called By: API 外部调用
|
||||
Table Accessed: NONE
|
||||
Table Updated: NONE
|
||||
Input:
|
||||
const int uiOperationId, -- 业务代码(不同的游戏有不同的业务代码)
|
||||
unsigned long uiUni, -- QQ号码
|
||||
const char *cIP, -- 网吧IP
|
||||
const unsigned char *ticketBuf, -- TGP票据,若不需要填空
|
||||
const int ticketLen, -- TGP票据长度,若不需要填0
|
||||
unsigned long errBufLen -- error 的BUFFER大小:不应少于256
|
||||
|
||||
INOUT
|
||||
int *bufLen, -- 输入是ack_buf的最大长度,不应少于256,输出是响应数据长度
|
||||
|
||||
Output:
|
||||
void *cryptInfoBuf, -- 响应数据的BUFFER地址
|
||||
void *error -- 错误描述的BUFFER地址,输入时BUFFER必需清空,不应少于256
|
||||
|
||||
Return: 返回0成功,其它为错误码,在iigw_api_client.h enum IIGW_MSG_STATUS中定义
|
||||
History:
|
||||
<author> <time> <version > <desc>
|
||||
anselyang 2008-03-25 1.0 build
|
||||
*************************************************/
|
||||
int IIGW_DLL_EXPORT INFOGW_api_req_netbar_lv
|
||||
(
|
||||
const int uiOperationId, // 业务代码
|
||||
unsigned long uiUni, // QQ No.
|
||||
const char *cIP, // netbar ip addr. eg: 192.168.1.1
|
||||
const unsigned char *ticketBuf, // TGP票据,若不需要填空
|
||||
const int ticketLen, // TGP票据长度,若不需要填0
|
||||
unsigned char *cryptInfoBuf, // output crypt info. . include: netbar level, netbar ip , infoGW's timestamp
|
||||
int *bufLen, // crypt info. len
|
||||
char *error, // error print char
|
||||
unsigned long errBufLen // error buffer size
|
||||
);
|
||||
|
||||
/*************************************************
|
||||
Function: INFOGW_api_req_netbar_lv_ext
|
||||
Description: 请求查询网吧等级,并等待回应的加密包 CF活动是否弹出
|
||||
|
||||
Calls: INFOGW_api_set_server
|
||||
INFOGW_send_recv
|
||||
Called By: API 外部调用
|
||||
Table Accessed: NONE
|
||||
Table Updated: NONE
|
||||
Input:
|
||||
const int uiOperationId, -- 业务代码(不同的游戏有不同的业务代码)
|
||||
unsigned long uiUni, -- QQ号码
|
||||
const char *cIP, -- 网吧IP
|
||||
const unsigned char *ticketBuf, -- TGP票据,若不需要填空
|
||||
const int ticketLen, -- TGP票据长度,若不需要填0
|
||||
unsigned long errBufLen -- error 的BUFFER大小:不应少于256
|
||||
|
||||
INOUT
|
||||
int *bufLen, -- 输入是ack_buf的最大长度,不应少于256,输出是响应数据长度
|
||||
|
||||
Output:
|
||||
void *cryptInfoBuf, -- 响应数据的BUFFER地址
|
||||
void *error -- 错误描述的BUFFER地址,输入时BUFFER必需清空,不应少于256
|
||||
char *op_buf, -- 其他可选BUF 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
int *op_buf_len -- 其他可选BUF 长度 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
|
||||
Return: 返回0成功,其它为错误码,在iigw_api_client.h enum IIGW_MSG_STATUS中定义
|
||||
History:
|
||||
<author> <time> <version > <desc>
|
||||
anselyang 2009-07-14 1.0 build
|
||||
*************************************************/
|
||||
int IIGW_DLL_EXPORT INFOGW_api_req_netbar_lv_ext
|
||||
(
|
||||
const int uiOperationId, // 业务代码
|
||||
unsigned long uiUni, // QQ No.
|
||||
const char *cIP, // netbar ip addr. eg: 192.168.1.1
|
||||
const unsigned char *ticketBuf, // TGP票据,若不需要填空
|
||||
const int ticketLen, // TGP票据长度,若不需要填0
|
||||
unsigned char *cryptInfoBuf, // output crypt info. . include: netbar level, netbar ip , infoGW's timestamp
|
||||
int *bufLen, // crypt info. len
|
||||
char *error, // error print char
|
||||
unsigned long errBufLen, // error buffer size
|
||||
char *op_buf, // 其他可选BUF 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
int *op_buf_len // 其他可选BUF 长度 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
);
|
||||
|
||||
|
||||
/*************************************************
|
||||
Function: INFOGW_api_req_platinum_netbar_lv
|
||||
Description: 请求查询铂金网吧等级
|
||||
Input:
|
||||
const int uiOperationId, -- 业务代码(不同的游戏有不同的业务代码)
|
||||
unsigned long uiUni, -- QQ号码,没有可填0
|
||||
Output:
|
||||
int &level, -- 铂金网吧等级
|
||||
|
||||
Return: 返回0成功,其它为错误码,在iigw_api_client.h enum IIGW_MSG_STATUS中定义
|
||||
History:
|
||||
<author> <time> <version > <desc>
|
||||
cooperli 2016-11-29 1.0 build
|
||||
*************************************************/
|
||||
int IIGW_DLL_EXPORT INFOGW_api_req_platinum_netbar_lv
|
||||
(
|
||||
const int uiOperationId, // 业务代码
|
||||
unsigned long uiUni, // QQ No.
|
||||
int &level // 铂金网吧等级
|
||||
);
|
||||
|
||||
/*************************************************
|
||||
Function: INFOGW_api_req_platinum_netbar_lv_ext
|
||||
Description: 请求查询铂金网吧等级
|
||||
Input:
|
||||
const int uiOperationId, -- 业务代码(不同的游戏有不同的业务代码)
|
||||
unsigned long uiUni, -- QQ号码,没有可填0
|
||||
unsigned int zone_id, -- 游戏大区,没有可填0
|
||||
Output:
|
||||
int &level, -- 铂金网吧等级
|
||||
|
||||
Return: 返回0成功,其它为错误码,在iigw_api_client.h enum IIGW_MSG_STATUS中定义
|
||||
History:
|
||||
<author> <time> <version > <desc>
|
||||
cooperli 2016-11-29 1.0 build
|
||||
*************************************************/
|
||||
int IIGW_DLL_EXPORT INFOGW_api_req_platinum_netbar_lv_ext
|
||||
(
|
||||
const int uiOperationId, // 业务代码
|
||||
unsigned long uiUni, // QQ No.
|
||||
unsigned int zone_id, //游戏大区
|
||||
int &level // 铂金网吧等级
|
||||
);
|
||||
|
||||
/*************************************************
|
||||
Function: INFOGW_api_req_netbar_lv_ext_with_zone_id
|
||||
Description: 请求查询网吧等级,并等待回应的加密包 CF活动是否弹出
|
||||
|
||||
Calls: INFOGW_api_set_server
|
||||
INFOGW_send_recv
|
||||
Called By: API 外部调用
|
||||
Table Accessed: NONE
|
||||
Table Updated: NONE
|
||||
Input:
|
||||
const int uiOperationId, -- 业务代码(不同的游戏有不同的业务代码)
|
||||
unsigned long uiUni, -- QQ号码
|
||||
unsigned long zone_id, -- 大区ID
|
||||
const char *cIP, -- 网吧IP
|
||||
const unsigned char *ticketBuf, -- TGP票据,若不需要填空
|
||||
const int ticketLen, -- TGP票据长度,若不需要填0
|
||||
unsigned long errBufLen -- error 的BUFFER大小:不应少于256
|
||||
|
||||
INOUT
|
||||
int *bufLen, -- 输入是ack_buf的最大长度,不应少于256,输出是响应数据长度
|
||||
|
||||
Output:
|
||||
void *cryptInfoBuf, -- 响应数据的BUFFER地址
|
||||
void *error -- 错误描述的BUFFER地址,输入时BUFFER必需清空,不应少于256
|
||||
char *op_buf, -- 其他可选BUF 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
int *op_buf_len -- 其他可选BUF 长度 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
|
||||
Return: 返回0成功,其它为错误码,在iigw_api_client.h enum IIGW_MSG_STATUS中定义
|
||||
History:
|
||||
<author> <time> <version > <desc>
|
||||
cooperli 2017-01-19 1.0 build
|
||||
*************************************************/
|
||||
int IIGW_DLL_EXPORT INFOGW_api_req_netbar_lv_ext_with_zone_id
|
||||
(
|
||||
const int uiOperationId, // 业务代码
|
||||
unsigned long uiUni, // QQ No.
|
||||
unsigned int zone_id, // 游戏大区.
|
||||
const char *cIP, // netbar ip addr. eg: 192.168.1.1
|
||||
const unsigned char *ticketBuf, // TGP票据,若不需要填空
|
||||
const int ticketLen, // TGP票据长度,若不需要填0
|
||||
unsigned char *cryptInfoBuf, // output crypt info. . include: netbar level, netbar ip , infoGW's timestamp
|
||||
int *bufLen, // crypt info. len
|
||||
char *error, // error print char
|
||||
unsigned long errBufLen, // error buffer size
|
||||
char *op_buf, // 其他可选BUF 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
int *op_buf_len, // 其他可选BUF 长度 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
const int time_out=5000 // 阻塞时间,单位->毫秒,范围1~10000,默认值为5000
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/** QQ网吧插件接口*/
|
||||
namespace iepm_qqwb{
|
||||
|
||||
enum account_type{
|
||||
at_qq, //0
|
||||
at_wechart, // 1
|
||||
at_facebook, //2
|
||||
at_email, // 3
|
||||
at_steam, //4
|
||||
at_gopenid,//5
|
||||
at_topenid, // 6 手机号对应的openid
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief NetbarLv QQ网吧签名结构体
|
||||
* @param tokenBuf 用来存放QQ网吧签名的buff
|
||||
* @param tokenLen QQ网吧签名的长度
|
||||
* @param ip PC的ip地址
|
||||
* @param macs PC的mac地址列表
|
||||
* @param macSize PC的mac地址个数
|
||||
*/
|
||||
struct NetbarLv {
|
||||
unsigned char tokenBuff[1024];
|
||||
int tokenLen;
|
||||
char ip[32];
|
||||
char macs[128];
|
||||
int macSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief notify_req_netbarlv_result 回调函数,返回获取签名的结果和内容
|
||||
* @param game_id 游戏ID
|
||||
* @param zone_id 登录游戏的大区号
|
||||
* @param open_id 用户登录游戏的open_id
|
||||
* @param ret_code 获取签名的结果,返回0成功,其他为错误码,参考enum IIGW_MSG_STATUS中定义
|
||||
* @param netbarlv NetbarLv信息,当ret_code=0时返回
|
||||
*/
|
||||
typedef void(*notify_req_netbarlv_result)(
|
||||
unsigned int game_id,
|
||||
unsigned int zone_id,
|
||||
const char open_id[INFOGW_OPEN_ID_LEN],
|
||||
int ret_code,
|
||||
NetbarLv *netbarlv
|
||||
);
|
||||
|
||||
struct IQQNetbarIIGWPlugin{
|
||||
/**
|
||||
* @brief 获取网吧机器信息
|
||||
* @param game_id 游戏ID,由网吧项目组这边分配
|
||||
* @param uin 用户登录游戏的QQ号
|
||||
* @param zone_id 登录游戏的大区号
|
||||
* @param cryptInfoBuf 用来存放网吧机器信息的加密串
|
||||
* @param bufLen 加密串长度
|
||||
* @param time_out 阻塞时间,单位->毫秒,范围1~10000 ,默认值为5000
|
||||
* @return int 返回0成功,其他为错误码,参考enum IIGW_MSG_STATUS中定义
|
||||
*/
|
||||
virtual int GetNetbarMachineContent(
|
||||
unsigned int game_id,
|
||||
unsigned int uin,
|
||||
unsigned int zone_id,
|
||||
unsigned char *cryptInfoBuf,
|
||||
int *bufLen,
|
||||
const int time_out=5000
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* @brief 获取机器是否在网吧
|
||||
* @param open_id 用户登录游戏的open_id,最大长度64
|
||||
* @param type open_id帐号类型,参考account_type,0是QQ号,1是微信,2是facebook,3是邮箱账号,4是steam账号
|
||||
* @return int 返回IIGW_MSG_STATUS_NETBAR_PC表示是网吧机器, IIGW_MSG_STATUS_NOT_IN_NETBAR表示非网吧机器,其他为错误码
|
||||
*/
|
||||
virtual int IsNetbarMachine(unsigned int game_id,
|
||||
const char open_id[INFOGW_OPEN_ID_LEN],
|
||||
account_type type) = 0;
|
||||
|
||||
/**
|
||||
* @brief 获取机器是否在网吧,该接口仅为pubg使用
|
||||
* @return bool 返回true表示在网吧
|
||||
*/
|
||||
virtual int IsNetbarMachine() = 0;
|
||||
|
||||
/**
|
||||
* @brief ReqNetbarLv 获取网吧等级
|
||||
* @param game_id 游戏ID,由网吧项目组这边分配(对应老接口的uiOperationId)
|
||||
* @param zone_id 登录游戏的大区号
|
||||
* @param open_id 用户登录游戏的open_id,最大长度64
|
||||
* @param ticketBuf, TGP票据,若不需要填空
|
||||
* @param ticketLen, TGP票据长度,若不需要填0
|
||||
* @param cryptInfoBuf 用来存放网吧机器信息的加密串
|
||||
* @param bufLen 加密串长度
|
||||
* @param error, 错误的msg
|
||||
* @param errBufLen, error buffer size
|
||||
* @param op_buf, 其他可选BUF 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
* @param op_buf_len, 其他可选BUF 长度 只给CF 活动用 stMsgHd.uiSeqNo
|
||||
* @param time_out 阻塞时间,单位->毫秒,范围1~10000,默认值为5000
|
||||
* @param type 保留字段,open_id帐号类型,0是QQ号,1是微信,【2是facebook,3是邮箱账号,这2个都是wegame自己的opend_id】
|
||||
* @return int 返回0成功,其他为错误码,参考enum IIGW_MSG_STATUS中定义
|
||||
*/
|
||||
virtual int ReqNetbarLv(
|
||||
unsigned int game_id,
|
||||
unsigned int zone_id,
|
||||
const char open_id[INFOGW_OPEN_ID_LEN],
|
||||
const unsigned char *ticketBuf,
|
||||
const int ticketLen,
|
||||
unsigned char *cryptInfoBuf,
|
||||
int *bufLen,
|
||||
char *error,
|
||||
unsigned long errBufLen,
|
||||
char *op_buf,
|
||||
int *op_buf_len,
|
||||
const int time_out=5000,
|
||||
unsigned int type = 1
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* @brief ReqNetbarLv2 获取网吧等级
|
||||
* @param game_id 游戏ID,由网吧项目组这边分配(对应老接口的uiOperationId)
|
||||
* @param zone_id 登录游戏的大区号
|
||||
* @param open_id 用户登录游戏的open_id,最大长度64
|
||||
* @param type open_id帐号类型,0是QQ号,1是微信,2是facebook,3是邮箱账号,4是msdk的gopen_id
|
||||
* @param ticketBuff, 用户登录游戏时的token,用于登录校验
|
||||
* @param ticketLen, 用户登录游戏时的token长度
|
||||
* @param netbarlv 输出参数,参考NetbarLv的声明
|
||||
* @param time_out 阻塞时间,单位->毫秒,范围1~10000,默认值为5000
|
||||
* @return int 返回0成功,其他为错误码,参考enum IIGW_MSG_STATUS中定义
|
||||
*/
|
||||
virtual int ReqNetbarLv2(
|
||||
unsigned int game_id,
|
||||
unsigned int zone_id,
|
||||
const char open_id[INFOGW_OPEN_ID_LEN],
|
||||
unsigned int type,
|
||||
const char *ticketBuff,
|
||||
const int ticketLen,
|
||||
NetbarLv *netbarlv,
|
||||
const int time_out = 5000
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* @brief 获取机器是否在网吧,给PUBG用的接口,其他业务请调用IsNetbarMachine
|
||||
* @param open_id 用户登录游戏的open_id,最大长度64
|
||||
* @param type open_id帐号类型,参考account_type,0是QQ号,1是微信,2是facebook,3是邮箱账号,4是steam账号
|
||||
* @return bool 返回true表示在网吧
|
||||
*/
|
||||
virtual int IsNetbar_ForPubg(const char open_id[INFOGW_OPEN_ID_LEN], account_type type) = 0;
|
||||
|
||||
/**
|
||||
* @brief 获取网吧签名token,给PUBG用的接口
|
||||
* @param open_id 用户登录游戏的open_id,最大长度64
|
||||
* @param type open_id帐号类型,参考account_type,0是QQ号,1是微信,2是facebook,3是邮箱账号,4是steam账号
|
||||
* @param opt_token 存储token用的buff,建议长度512
|
||||
* @param opt_token_len 返回的token 长度
|
||||
* @return int 返回0成功,返回IIGW_MSG_STATUS_NOT_IN_NETBAR(300)表示非网吧环境,并且opt_token会为空,
|
||||
其他为错误码,参考enum IIGW_MSG_STATUS中定义
|
||||
*/
|
||||
virtual int ReqNetbarToken_ForPubg(const char open_id[INFOGW_OPEN_ID_LEN], account_type type,
|
||||
char *opt_token, int *opt_token_len) = 0;
|
||||
|
||||
/*************************************************
|
||||
Function: SetProxy
|
||||
Description: 设置代理,在所有获取等级接口之前调用
|
||||
History:
|
||||
<author> <time> <version > <desc>
|
||||
cooperli 2019-6-11 1.0 build
|
||||
*************************************************/
|
||||
virtual void SetProxy(
|
||||
const char url[INFOGW_OPEN_ID_LEN], // 代理URL
|
||||
const char user[INFOGW_OPEN_ID_LEN], // 代理账号
|
||||
const char pwd[INFOGW_OPEN_ID_LEN] // 代理密码
|
||||
) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @brief RegNetbarLvCallback 注册异步获取网吧等级的回调函数,只需调用一次
|
||||
* @param handle_result 回调函数
|
||||
* @return int 返回0成功,其他为错误码,参考enum IIGW_MSG_STATUS中定义
|
||||
*/
|
||||
virtual int RegNetbarLvCallback(notify_req_netbarlv_result handle_result) = 0;
|
||||
|
||||
/**
|
||||
* @brief ReqNetbarLv2_Asyn 异步获取网吧等级,调用该函数之前需调用RegNetbarLvCallback注册回调
|
||||
* @param game_id 游戏ID,由网吧项目组这边分配(对应老接口的uiOperationId)
|
||||
* @param zone_id 登录游戏的大区号
|
||||
* @param open_id 用户登录游戏的open_id,最大长度64
|
||||
* @param type open_id帐号类型,0是QQ号,1是微信,2是facebook,3是邮箱账号,4是msdk的gopen_id
|
||||
* @param ticketBuff, 用户登录游戏时的token,用于登录校验
|
||||
* @param ticketLen, 用户登录游戏时的token长度
|
||||
* @param time_out 阻塞时间,单位->毫秒,范围1~10000,默认值为5000
|
||||
* @return int 返回0成功,其他为错误码,参考enum IIGW_MSG_STATUS中定义
|
||||
*/
|
||||
virtual int ReqNetbarLv2_Asyn(
|
||||
unsigned int game_id,
|
||||
unsigned int zone_id,
|
||||
const char open_id[INFOGW_OPEN_ID_LEN],
|
||||
unsigned int type,
|
||||
const char *ticketBuff,
|
||||
const int ticketLen,
|
||||
const int time_out = 5000
|
||||
) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 创建QQ网吧插件接口
|
||||
* @param hDll LoadLibrary返回的HMODULE
|
||||
* @return IQQNetbarIIGWPlugin 失败返回nullptr。该接口内存由插件管理,无需外部释放
|
||||
*/
|
||||
inline IQQNetbarIIGWPlugin *CreateQQNetbarIIGWPlugin(HMODULE hDll){
|
||||
if (!hDll) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
typedef HRESULT (WINAPI *QUERYPLUGININTERFACE)(const char*, void**);
|
||||
#ifdef _WIN64
|
||||
QUERYPLUGININTERFACE qpi = (QUERYPLUGININTERFACE)GetProcAddress(hDll,
|
||||
"QueryPluginInterface");
|
||||
#else
|
||||
QUERYPLUGININTERFACE qpi = (QUERYPLUGININTERFACE)GetProcAddress(hDll,
|
||||
"_QueryPluginInterface@8");
|
||||
#endif
|
||||
|
||||
if (qpi) {
|
||||
IQQNetbarIIGWPlugin* plugin = nullptr;
|
||||
HRESULT hresult = qpi("IQQNetbarIIGWPlugin", reinterpret_cast<void**>(&plugin));
|
||||
if (SUCCEEDED(hresult)) {
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _ITC_CLIENT_H_
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "stdafx.h"
|
||||
#include "MainDialog.h"
|
||||
|
||||
CAppModule _Module;
|
||||
|
||||
int Run(LPTSTR /*lpCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
|
||||
{
|
||||
CMessageLoop theLoop;
|
||||
_Module.AddMessageLoop(&theLoop);
|
||||
|
||||
CMainDialog dlgMain;
|
||||
|
||||
if (dlgMain.Create(NULL) == NULL)
|
||||
{
|
||||
ATLTRACE(_T("Main dialog creation failed!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
dlgMain.ShowWindow(nCmdShow);
|
||||
|
||||
int nRet = theLoop.Run();
|
||||
|
||||
_Module.RemoveMessageLoop();
|
||||
return nRet;
|
||||
}
|
||||
|
||||
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
|
||||
{
|
||||
HRESULT hRes = ::CoInitialize(NULL);
|
||||
ATLASSERT(SUCCEEDED(hRes));
|
||||
|
||||
// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
|
||||
::DefWindowProc(NULL, 0, 0, 0L);
|
||||
|
||||
AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES); // add flags to support other controls
|
||||
|
||||
hRes = _Module.Init(NULL, hInstance);
|
||||
ATLASSERT(SUCCEEDED(hRes));
|
||||
|
||||
int nRet = Run(lpstrCmdLine, nCmdShow);
|
||||
|
||||
_Module.Term();
|
||||
::CoUninitialize();
|
||||
|
||||
return nRet;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by aClient.rc
|
||||
//
|
||||
#define IDD_DIALOG_MAIN 101
|
||||
#define IDC_BUTTON_CONNECT_GAME_SERVER 1001
|
||||
#define IDC_BUTTON_DISCONNECT_GAME_SERVER 1002
|
||||
#define IDC_BUTTON_UGC_SEND 1003
|
||||
#define IDC_EDIT1 1004
|
||||
#define IDC_EDIT_UGC_CONTENT 1004
|
||||
#define IDC_BUTTON_REPORT_SEND 1005
|
||||
#define IDC_BUTTON_NETBAR_CLIENTLOAD 1006
|
||||
#define IDC_EDIT_MAINPLAY_PID 1007
|
||||
#define IDC_BUTTON1 1008
|
||||
#define IDC_BUTTON_CHECK_MAINPLAY_PROCESS 1008
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1009
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cy_core.h>
|
||||
#include <cy_event.h>
|
||||
#include <cy_network.h>
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <atlapp.h>
|
||||
#include <atldlgs.h>
|
||||
Reference in New Issue
Block a user