Skip to content
This repository has been archived by the owner on Jan 7, 2020. It is now read-only.

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
stdrc committed Jan 10, 2019
0 parents commit 385e1a0
Show file tree
Hide file tree
Showing 31 changed files with 2,169 additions and 0 deletions.
30 changes: 30 additions & 0 deletions api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "./api.h"

using namespace std;

namespace cq::api {
static vector<function<void(HMODULE)>> api_func_initializers;

static bool add_func_initializer(const function<void(HMODULE)> &initializer) {
api_func_initializers.push_back(initializer);
return true;
}

void __init() {
const auto dll = GetModuleHandleW(L"CQP.dll");
for (const auto &initializer : api_func_initializers) {
initializer(dll);
}
}

namespace raw {
#define FUNC(ReturnType, FuncName, ...) \
typedef __declspec(dllimport) ReturnType(__stdcall *__CQ_##FuncName##_T)(__VA_ARGS__); \
__CQ_##FuncName##_T CQ_##FuncName; \
static bool __dummy_CQ_##FuncName = add_func_initializer([](auto dll) { \
CQ_##FuncName = reinterpret_cast<__CQ_##FuncName##_T>(GetProcAddress(dll, "CQ_" #FuncName)); \
});

#include "./api_funcs.h"
} // namespace raw
} // namespace cq::api
285 changes: 285 additions & 0 deletions api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
#pragma once

#include "./common.h"

#include "./app.h"
#include "./enums.h"
#include "./target.h"
#include "./types.h"
#include "./utils/string.h"

namespace cq::exception {
struct ApiError : RuntimeError {
int code;
ApiError(const int code) : RuntimeError("failed to call coolq api") { this->code = code; }

static const auto INVALID_DATA = 100;
static const auto INVALID_TARGET = 101;
};
} // namespace cq::exception

namespace cq::api {
/**
* Init all API functions.
* This is internally called in the Initialize exported function.
*/
void __init();

/**
* Provide ways to access the raw CoolQ API functions.
*/
namespace raw {
#include "./api_funcs.h"
}

inline void __throw_if_needed(const int32_t ret) noexcept(false) {
if (ret < 0) {
throw exception::ApiError(ret);
}
}

inline void __throw_if_needed(const void *const ret_ptr) noexcept(false) {
if (!ret_ptr) {
throw exception::ApiError(exception::ApiError::INVALID_DATA);
}
}

#pragma region Message

inline int64_t send_private_msg(const int64_t user_id, const std::string &msg) noexcept(false) {
const auto ret = raw::CQ_sendPrivateMsg(app::auth_code, user_id, utils::string_to_coolq(msg).c_str());
__throw_if_needed(ret);
return ret;
}

inline int64_t send_group_msg(const int64_t group_id, const std::string &msg) noexcept(false) {
const auto ret = raw::CQ_sendGroupMsg(app::auth_code, group_id, utils::string_to_coolq(msg).c_str());
__throw_if_needed(ret);
return ret;
}

inline int64_t send_discuss_msg(const int64_t discuss_id, const std::string &msg) noexcept(false) {
const auto ret = raw::CQ_sendDiscussMsg(app::auth_code, discuss_id, utils::string_to_coolq(msg).c_str());
__throw_if_needed(ret);
return ret;
}

inline void delete_msg(const int64_t msg_id) noexcept(false) {
__throw_if_needed(raw::CQ_deleteMsg(app::auth_code, msg_id));
}

#pragma endregion

#pragma region Send Like

inline void send_like(const int64_t user_id) noexcept(false) {
__throw_if_needed(raw::CQ_sendLike(app::auth_code, user_id));
}

inline void send_like(const int64_t user_id, const int32_t times) noexcept(false) {
__throw_if_needed(raw::CQ_sendLikeV2(app::auth_code, user_id, times));
}

#pragma endregion

#pragma region Group &Discuss Operation

inline void set_group_kick(const int64_t group_id, const int64_t user_id,
const bool reject_add_request) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupKick(app::auth_code, group_id, user_id, reject_add_request));
}

inline void set_group_ban(const int64_t group_id, const int64_t user_id, const int64_t duration) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupBan(app::auth_code, group_id, user_id, duration));
}

inline void set_group_anonymous_ban(const int64_t group_id, const std::string &flag,
const int64_t duration) noexcept(false) {
__throw_if_needed(
raw::CQ_setGroupAnonymousBan(app::auth_code, group_id, utils::string_to_coolq(flag).c_str(), duration));
}

inline void set_group_whole_ban(const int64_t group_id, const bool enable) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupWholeBan(app::auth_code, group_id, enable));
}

inline void set_group_admin(const int64_t group_id, const int64_t user_id, const bool enable) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupAdmin(app::auth_code, group_id, user_id, enable));
}

inline void set_group_anonymous(const int64_t group_id, const bool enable) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupAnonymous(app::auth_code, group_id, enable));
}

inline void set_group_card(const int64_t group_id, const int64_t user_id, const std::string &card) noexcept(false) {
__throw_if_needed(
raw::CQ_setGroupCard(app::auth_code, group_id, user_id, utils::string_to_coolq(card).c_str()));
}

inline void set_group_leave(const int64_t group_id, const bool is_dismiss) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupLeave(app::auth_code, group_id, is_dismiss));
}

inline void set_group_special_title(const int64_t group_id, const int64_t user_id, const std::string &special_title,
const int64_t duration) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupSpecialTitle(
app::auth_code, group_id, user_id, utils::string_to_coolq(special_title).c_str(), duration));
}

inline void set_discuss_leave(const int64_t discuss_id) noexcept(false) {
__throw_if_needed(raw::CQ_setDiscussLeave(app::auth_code, discuss_id));
}

#pragma endregion

#pragma region Request Operation

inline void set_friend_add_request(const std::string &flag, const request::Operation operation,
const std::string &remark) noexcept(false) {
__throw_if_needed(raw::CQ_setFriendAddRequest(
app::auth_code, utils::string_to_coolq(flag).c_str(), operation, utils::string_to_coolq(remark).c_str()));
}

inline void set_group_add_request(const std::string &flag, const request::SubType type,
const request::Operation operation) noexcept(false) {
__throw_if_needed(
raw::CQ_setGroupAddRequest(app::auth_code, utils::string_to_coolq(flag).c_str(), type, operation));
}

inline void set_group_add_request(const std::string &flag, const request::SubType type,
const request::Operation operation, const std::string &reason) noexcept(false) {
__throw_if_needed(raw::CQ_setGroupAddRequestV2(app::auth_code,
utils::string_to_coolq(flag).c_str(),
type,
operation,
utils::string_to_coolq(reason).c_str()));
}

#pragma endregion

#pragma region Get QQ Information

inline int64_t get_login_user_id() noexcept { return raw::CQ_getLoginQQ(app::auth_code); }

inline std::string get_login_nickname() noexcept(false) {
const auto ret = raw::CQ_getLoginNick(app::auth_code);
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

inline std::string get_stranger_info_base64(const int64_t user_id, const bool no_cache = false) noexcept(false) {
const auto ret = raw::CQ_getStrangerInfo(app::auth_code, user_id, no_cache);
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

inline std::string get_group_list_base64() noexcept(false) {
const auto ret = raw::CQ_getGroupList(app::auth_code);
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

inline std::string get_group_member_list_base64(const int64_t group_id) noexcept(false) {
const auto ret = raw::CQ_getGroupMemberList(app::auth_code, group_id);
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

inline std::string get_group_member_info_base64(const int64_t group_id, const int64_t user_id,
const bool no_cache = false) noexcept(false) {
const auto ret = raw::CQ_getGroupMemberInfoV2(app::auth_code, group_id, user_id, no_cache);
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

#pragma endregion

#pragma region Get CoolQ Information

inline std::string get_cookies() noexcept(false) {
const auto ret = raw::CQ_getCookies(app::auth_code);
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

inline int32_t get_csrf_token() noexcept { return raw::CQ_getCsrfToken(app::auth_code); }

inline std::string get_app_directory() noexcept(false) {
const auto ret = raw::CQ_getAppDirectory(app::auth_code);
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

inline std::string get_record(const std::string &file, const std::string &out_format) noexcept(false) {
const auto ret = raw::CQ_getRecord(
app::auth_code, utils::string_to_coolq(file).c_str(), utils::string_to_coolq(out_format).c_str());
__throw_if_needed(ret);
return utils::string_from_coolq(ret);
}

#pragma endregion

#pragma region CoolQ Self - operation

// int32_t set_fatal(const char *error_info) {
// return raw::CQ_setFatal(app::auth_code, error_info);
//}
//
// int32_t set_restart() {
// return raw::CQ_setRestart(app::auth_code);
//}

#pragma endregion

#pragma region CQSDK Bonus

inline int64_t send_msg(const Target &target, const std::string &msg) noexcept(false) {
if (target.group_id.has_value()) {
return send_group_msg(target.group_id.value(), msg);
}
if (target.discuss_id.has_value()) {
return send_discuss_msg(target.discuss_id.value(), msg);
}
if (target.user_id.has_value()) {
return send_private_msg(target.user_id.value(), msg);
}
throw exception::ApiError(exception::ApiError::INVALID_TARGET);
}

inline User get_stranger_info(const int64_t user_id, const bool no_cache = false) noexcept(false) {
try {
return ObjectHelper::from_base64<User>(get_stranger_info_base64(user_id, no_cache));
} catch (exception::ParseError &) {
throw exception::ApiError(exception::ApiError::INVALID_DATA);
}
}

inline std::vector<Group> get_group_list() noexcept(false) {
try {
return ObjectHelper::multi_from_base64<std::vector<Group>>(get_group_list_base64());
} catch (exception::ParseError &) {
throw exception::ApiError(exception::ApiError::INVALID_DATA);
}
}

inline std::vector<GroupMember> get_group_member_list(const int64_t group_id) noexcept(false) {
try {
return ObjectHelper::multi_from_base64<std::vector<GroupMember>>(get_group_member_list_base64(group_id));
} catch (exception::ParseError &) {
throw exception::ApiError(exception::ApiError::INVALID_DATA);
}
}

inline GroupMember get_group_member_info(const int64_t group_id, const int64_t user_id,
const bool no_cache = false) noexcept(false) {
try {
return ObjectHelper::from_base64<GroupMember>(get_group_member_info_base64(group_id, user_id, no_cache));
} catch (exception::ParseError &) {
throw exception::ApiError(exception::ApiError::INVALID_DATA);
}
}

inline User get_login_info() noexcept(false) { return get_stranger_info(get_login_user_id()); }

#pragma endregion
} // namespace cq::api
67 changes: 67 additions & 0 deletions api_funcs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// We don't use "#pragma once" here, because this file is intended to be included twice,
// by sdk_class.h and sdk.cpp, respectively to declare and define SDK functions.
// Except for the two files mentioned above, no file is allowed to include this.

#ifndef FUNC
#define DEFINED_FUNC_MACRO
#define FUNC(ReturnType, FuncName, ...) \
typedef ReturnType(__stdcall *__CQ_##FuncName##_T)(__VA_ARGS__); \
extern __CQ_##FuncName##_T CQ_##FuncName; // only DECLARE the functions
#endif

#include <cstdint>

using cq_bool_t = int32_t;

// Message
FUNC(int32_t, sendPrivateMsg, int32_t auth_code, int64_t qq, const char *msg)
FUNC(int32_t, sendGroupMsg, int32_t auth_code, int64_t group_id, const char *msg)
FUNC(int32_t, sendDiscussMsg, int32_t auth_code, int64_t discuss_id, const char *msg)
FUNC(int32_t, deleteMsg, int32_t auth_code, int64_t msg_id)

// Send Like
FUNC(int32_t, sendLike, int32_t auth_code, int64_t qq)
FUNC(int32_t, sendLikeV2, int32_t auth_code, int64_t qq, int32_t times)

// Group & Discuss Operation
FUNC(int32_t, setGroupKick, int32_t auth_code, int64_t group_id, int64_t qq, cq_bool_t reject_add_request)
FUNC(int32_t, setGroupBan, int32_t auth_code, int64_t group_id, int64_t qq, int64_t duration)
FUNC(int32_t, setGroupAnonymousBan, int32_t auth_code, int64_t group_id, const char *anonymous, int64_t duration)
FUNC(int32_t, setGroupWholeBan, int32_t auth_code, int64_t group_id, cq_bool_t enable)
FUNC(int32_t, setGroupAdmin, int32_t auth_code, int64_t group_id, int64_t qq, cq_bool_t set)
FUNC(int32_t, setGroupAnonymous, int32_t auth_code, int64_t group_id, cq_bool_t enable)
FUNC(int32_t, setGroupCard, int32_t auth_code, int64_t group_id, int64_t qq, const char *new_card)
FUNC(int32_t, setGroupLeave, int32_t auth_code, int64_t group_id, cq_bool_t is_dismiss)
FUNC(int32_t, setGroupSpecialTitle, int32_t auth_code, int64_t group_id, int64_t qq, const char *new_special_title,
int64_t duration)
FUNC(int32_t, setDiscussLeave, int32_t auth_code, int64_t discuss_id)

// Request Operation
FUNC(int32_t, setFriendAddRequest, int32_t auth_code, const char *response_flag, int32_t response_operation,
const char *remark)
FUNC(int32_t, setGroupAddRequest, int32_t auth_code, const char *response_flag, int32_t request_type,
int32_t response_operation)
FUNC(int32_t, setGroupAddRequestV2, int32_t auth_code, const char *response_flag, int32_t request_type,
int32_t response_operation, const char *reason)

// Get QQ Information
FUNC(int64_t, getLoginQQ, int32_t auth_code)
FUNC(const char *, getLoginNick, int32_t auth_code)
FUNC(const char *, getStrangerInfo, int32_t auth_code, int64_t qq, cq_bool_t no_cache)
FUNC(const char *, getGroupList, int32_t auth_code)
FUNC(const char *, getGroupMemberList, int32_t auth_code, int64_t group_id)
FUNC(const char *, getGroupMemberInfoV2, int32_t auth_code, int64_t group_id, int64_t qq, cq_bool_t no_cache)

// Get CoolQ Information
FUNC(const char *, getCookies, int32_t auth_code)
FUNC(int32_t, getCsrfToken, int32_t auth_code)
FUNC(const char *, getAppDirectory, int32_t auth_code)
FUNC(const char *, getRecord, int32_t auth_code, const char *file, const char *out_format)

FUNC(int32_t, addLog, int32_t auth_code, int32_t log_level, const char *category, const char *log_msg)
FUNC(int32_t, setFatal, int32_t auth_code, const char *error_info)
FUNC(int32_t, setRestart, int32_t auth_code) // currently ineffective

#ifdef DEFINED_FUNC_MACRO
#undef FUNC
#endif
Loading

0 comments on commit 385e1a0

Please sign in to comment.