This repository has been archived by the owner on Jan 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 385e1a0
Showing
31 changed files
with
2,169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.