diff --git a/Dice/DiceMsgSend.cpp b/Dice/DiceMsgSend.cpp
index 40a0cadf..c4a80130 100644
--- a/Dice/DiceMsgSend.cpp
+++ b/Dice/DiceMsgSend.cpp
@@ -1,151 +1,151 @@
-/*
- * _______ ________ ________ ________ __
- * | __ \ |__ __| | _____| | _____| | |
- * | | | | | | | | | |_____ | |
- * | | | | | | | | | _____| |__|
- * | |__| | __| |__ | |_____ | |_____ __
- * |_______/ |________| |________| |________| |__|
- *
- * Dice! QQ Dice Robot for TRPG
- * Copyright (C) 2018-2019 w4123溯洄
- *
- * This program is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Affero General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License along with this
- * program. If not, see .
- */
-#include
-#include
-#include
-#include
-#include "OneBotAPI.h"
-#include "DiceMsgSend.h"
-#include "MsgFormat.h"
-#include "GlobalVar.h"
-#include "DiceConsole.h"
-using namespace std;
-
-chatInfo::chatInfo(long long u, long long g, long long c) :uid(u), gid(g), chid(c) {
- if (gid) {
- if (chid)type = msgtype::Channel;
- else type = msgtype::Group;
- }
- else {
- if (chid)type = msgtype::ChannelPrivate;
- else type = msgtype::Private;
- }
-}
-chatInfo::chatInfo(const AttrObject& obj):uid(obj.get_ll("uid")), chid(obj.get_ll("chid")) {
- type = (gid = obj.get_ll("gid"))
- ? chid ? msgtype::ChannelPrivate : msgtype::Private
- : chid ? msgtype::Channel : msgtype::Group;
-}
-bool chatInfo::operator<(const chatInfo& other)const {
- return type == other.type
- ? uid == other.uid
- ? gid == other.gid
- ? chid < other.chid
- : gid < other.gid
- : uid < other.uid
- : type < other.type;
-}
-bool chatInfo::operator==(const chatInfo& other)const {
- return uid == other.uid
- && gid == other.gid
- && chid == other.chid;
-}
-fifo_json to_json(const chatInfo& chat) {
- fifo_json j = fifo_json::object();
- if (chat.chid)j["chid"] = chat.chid;
- if (chat.gid)j["gid"] = chat.gid;
- if (chat.uid)j["uid"] = chat.uid;
- return j;
-}
-chatInfo chatInfo::from_json(const fifo_json& chat) {
- if (chat.is_null())return {};
- long long uid{ 0 }, gid{ 0 }, chid{ 0 };
- if (chat.count("uid"))chat["uid"].get_to(uid);
- if (chat.count("gid"))chat["gid"].get_to(gid);
- if (chat.count("chid"))chat["chid"].get_to(chid);
- return chatInfo{ uid,gid,chid };
-}
-
-// 消息发送存储结构体
-struct msg_t
-{
- string msg;
- chatInfo target{};
- msg_t() = default;
-
- msg_t(string msg, chatInfo ct) : msg(move(msg)),target(ct)
- {
- }
-};
-
-// 消息发送队列
-std::queue msgQueue;
-
-// 消息发送队列锁
-mutex msgQueueMutex;
-
-void AddMsgToQueue(const string& msg, long long target_id)
-{
- lock_guard lock_queue(msgQueueMutex);
- msgQueue.emplace(msg_t(msg, { target_id }));
-}
-
-void AddMsgToQueue(const std::string& msg, chatInfo ct)
-{
- lock_guard lock_queue(msgQueueMutex);
- msgQueue.emplace(msg_t(msg, ct));
-}
-
-
-void SendMsg()
-{
- msgSendThreadRunning = true;
- while (Enabled)
- {
- msg_t msg;
- {
- lock_guard lock_queue(msgQueueMutex);
- if (!msgQueue.empty())
- {
- msg = msgQueue.front();
- msgQueue.pop();
- }
- }
- if (!msg.msg.empty())
- {
- if (int pos = msg.msg.find_first_not_of(" \t\r\n"); pos && pos != string::npos) {
- msg.msg = msg.msg.substr(pos);
- }
- if (int pos = msg.msg.find('\f'); pos != string::npos)
- {
- AddMsgToQueue(msg.msg.substr(pos + 1), msg.target);
- msg.msg = msg.msg.substr(0, pos);
- }
- if (msg.target.type == msgtype::Private)
- {
- api::sendPrivateMsg(msg.target.uid, msg.msg);
- }
- else if (msg.target.type == msgtype::Group)
- {
- api::sendGroupMsg(msg.target.gid, msg.msg);
- }
- else if (msg.target.type == msgtype::Channel)
- {
- api::sendChannelMsg(msg.target.gid, msg.target.chid, msg.msg);
- }
- }
- if (msgQueue.size() > 2)this_thread::sleep_for(chrono::milliseconds(console["SendIntervalBusy"]));
- else this_thread::sleep_for(chrono::milliseconds(console["SendIntervalIdle"]));
- }
- msgSendThreadRunning = false;
-}
+/*
+ * _______ ________ ________ ________ __
+ * | __ \ |__ __| | _____| | _____| | |
+ * | | | | | | | | | |_____ | |
+ * | | | | | | | | | _____| |__|
+ * | |__| | __| |__ | |_____ | |_____ __
+ * |_______/ |________| |________| |________| |__|
+ *
+ * Dice! QQ Dice Robot for TRPG
+ * Copyright (C) 2018-2019 w4123婧磩
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Affero General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License along with this
+ * program. If not, see .
+ */
+#include
+#include
+#include
+#include
+#include "OneBotAPI.h"
+#include "DiceMsgSend.h"
+#include "MsgFormat.h"
+#include "GlobalVar.h"
+#include "DiceConsole.h"
+using namespace std;
+
+chatInfo::chatInfo(long long u, long long g, long long c) :uid(u), gid(g), chid(c) {
+ if (gid) {
+ if (chid)type = msgtype::Channel;
+ else type = msgtype::Group;
+ }
+ else {
+ if (chid)type = msgtype::ChannelPrivate;
+ else type = msgtype::Private;
+ }
+}
+chatInfo::chatInfo(const AttrObject& obj):uid(obj.get_ll("uid")), chid(obj.get_ll("chid")) {
+ type = (gid = obj.get_ll("gid"))
+ ? chid ? msgtype::ChannelPrivate : msgtype::Private
+ : chid ? msgtype::Channel : msgtype::Group;
+}
+bool chatInfo::operator<(const chatInfo& other)const {
+ return type == other.type
+ ? uid == other.uid
+ ? gid == other.gid
+ ? chid < other.chid
+ : gid < other.gid
+ : uid < other.uid
+ : type < other.type;
+}
+bool chatInfo::operator==(const chatInfo& other)const {
+ return uid == other.uid
+ && gid == other.gid
+ && chid == other.chid;
+}
+fifo_json to_json(const chatInfo& chat) {
+ fifo_json j = fifo_json::object();
+ if (chat.chid)j["chid"] = chat.chid;
+ if (chat.gid)j["gid"] = chat.gid;
+ if (chat.uid)j["uid"] = chat.uid;
+ return j;
+}
+chatInfo chatInfo::from_json(const fifo_json& chat) {
+ if (chat.is_null())return {};
+ long long uid{ 0 }, gid{ 0 }, chid{ 0 };
+ if (chat.count("uid"))chat["uid"].get_to(uid);
+ if (chat.count("gid"))chat["gid"].get_to(gid);
+ if (chat.count("chid"))chat["chid"].get_to(chid);
+ return chatInfo{ uid,gid,chid };
+}
+
+// 娑堟伅鍙戦佸瓨鍌ㄧ粨鏋勪綋
+struct msg_t
+{
+ string msg;
+ chatInfo target{};
+ msg_t() = default;
+
+ msg_t(string msg, chatInfo ct) : msg(move(msg)),target(ct)
+ {
+ }
+};
+
+// 娑堟伅鍙戦侀槦鍒
+std::queue msgQueue;
+
+// 娑堟伅鍙戦侀槦鍒楅攣
+mutex msgQueueMutex;
+
+void AddMsgToQueue(const string& msg, long long target_id)
+{
+ lock_guard lock_queue(msgQueueMutex);
+ msgQueue.emplace(msg_t(msg, { target_id }));
+}
+
+void AddMsgToQueue(const std::string& msg, chatInfo ct)
+{
+ lock_guard lock_queue(msgQueueMutex);
+ msgQueue.emplace(msg_t(msg, ct));
+}
+
+
+void SendMsg()
+{
+ msgSendThreadRunning = true;
+ while (Enabled)
+ {
+ msg_t msg;
+ {
+ lock_guard lock_queue(msgQueueMutex);
+ if (!msgQueue.empty())
+ {
+ msg = msgQueue.front();
+ msgQueue.pop();
+ }
+ }
+ if (!msg.msg.empty())
+ {
+ if (int pos = msg.msg.find_first_not_of(" \t\r\n"); pos && pos != string::npos) {
+ msg.msg = msg.msg.substr(pos);
+ }
+ if (int pos = msg.msg.find('\f'); pos != string::npos)
+ {
+ AddMsgToQueue(msg.msg.substr(pos + 1), msg.target);
+ msg.msg = msg.msg.substr(0, pos);
+ }
+ if (msg.target.type == msgtype::Private)
+ {
+ api::sendPrivateMsg(msg.target.uid, msg.msg);
+ }
+ else if (msg.target.type == msgtype::Group)
+ {
+ api::sendGroupMsg(msg.target.gid, msg.msg);
+ }
+ else if (msg.target.type == msgtype::Channel)
+ {
+ api::sendChannelMsg(msg.target.gid, msg.target.chid, msg.msg);
+ }
+ }
+ if (msgQueue.size() > 2)this_thread::sleep_for(chrono::milliseconds(console["SendIntervalBusy"]));
+ else this_thread::sleep_for(chrono::milliseconds(console["SendIntervalIdle"]));
+ }
+ msgSendThreadRunning = false;
+}
diff --git a/Dice/DiceNetwork.cpp b/Dice/DiceNetwork.cpp
index ed470fdf..05eaa89d 100644
--- a/Dice/DiceNetwork.cpp
+++ b/Dice/DiceNetwork.cpp
@@ -1,419 +1,419 @@
-/*
- * _______ ________ ________ ________ __
- * | __ \ |__ __| | _____| | _____| | |
- * | | | | | | | | | |_____ | |
- * | | | | | | | | | _____| |__|
- * | |__| | __| |__ | |_____ | |_____ __
- * |_______/ |________| |________| |________| |__|
- *
- * Dice! QQ Dice Robot for TRPG
- * Copyright (C) 2018-2019 w4123溯洄
- *
- * This program is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Affero General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License along with this
- * program. If not, see .
- */
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include
-#include
-#pragma comment(lib, "WinInet.lib")
-#else
-#include
-#endif
-
-#include
-#include
-#include "GlobalVar.h"
-#include "MsgFormat.h"
-#include "DiceNetwork.h"
-#include "StrExtern.hpp"
-
-namespace Network
-{
-#ifndef _WIN32
- thread_local CURLcode lastError;
-
- size_t curlWriteToString(void *contents, size_t size, size_t nmemb, std::string *s)
- {
- size_t newLength = size*nmemb;
- s->append((char*)contents, newLength);
- return newLength;
- }
-#endif
-
- std::string getLastErrorMsg()
- {
-#ifdef _WIN32
- DWORD dwError = GetLastError();
- if (dwError == ERROR_INTERNET_EXTENDED_ERROR)
- {
- DWORD size = 512;
- wchar_t* szFormatBuffer = new wchar_t[size];
- if (InternetGetLastResponseInfoW(&dwError, szFormatBuffer, &size))
- {
- std::string ret(convert_w2a(reinterpret_cast(szFormatBuffer)));
- while (ret[ret.length() - 1] == '\n' || ret[ret.length() - 1] == '\r')ret.erase(ret.length() - 1);
- delete[] szFormatBuffer;
- return ret;
- }
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- {
- size++;
- delete[] szFormatBuffer;
- szFormatBuffer = new wchar_t[size];
- if (InternetGetLastResponseInfoW(&dwError, szFormatBuffer, &size))
- {
- std::string ret(convert_w2a(reinterpret_cast(szFormatBuffer)));
- while (ret[ret.length() - 1] == '\n' || ret[ret.length() - 1] == '\r')ret.erase(ret.length() - 1);
- delete[] szFormatBuffer;
- return ret;
- }
- delete[] szFormatBuffer;
- return getMsg("strUnableToGetErrorMsg");
- }
- delete[] szFormatBuffer;
- return getMsg("strUnableToGetErrorMsg");
- }
- wchar_t szFormatBuffer[512];
- DWORD dwBaseLength = FormatMessageW(
- FORMAT_MESSAGE_FROM_HMODULE, // dwFlags
- GetModuleHandleW(L"wininet.dll"), // lpSource
- dwError, // dwMessageId
- MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), // dwLanguageId
- szFormatBuffer, // lpBuffer
- 512, // nSize
- nullptr);
-
- if (dwBaseLength == 0)
- {
- dwBaseLength = FormatMessageW(
- FORMAT_MESSAGE_FROM_HMODULE, // dwFlags
- GetModuleHandleW(L"wininet.dll"), // lpSource
- dwError, // dwMessageId
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // dwLanguageId
- szFormatBuffer, // lpBuffer
- 512, // nSize
- nullptr);
- }
-
- if (dwBaseLength)
- {
- std::string ret(convert_w2a(reinterpret_cast(szFormatBuffer)));
- while (ret[ret.length() - 1] == '\n' || ret[ret.length() - 1] == '\r')ret.erase(ret.length() - 1);
- return ret;
- }
- return getMsg("strUnableToGetErrorMsg");
-#else
- return curl_easy_strerror(lastError);
-#endif
- }
-
- bool POST(const string& url, const string& postContent, const string& postHeader, std::string& des)
- {
- std::string strHeader = postHeader.empty() ? "Content-Type: application/x-www-form-urlencoded" : postHeader;
-#ifdef _WIN32
- std::string UserAgent{ DiceRequestHeader };
- static std::regex re{ R"(User-Agent: ([^\r\n]*))" };
- std::smatch match;
- if (std::regex_search(strHeader, match, re)) {
- UserAgent = match[1].str();
- }
- URL_COMPONENTSA urlComponents{};
- urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
- urlComponents.dwHostNameLength = 1024;
- urlComponents.dwPasswordLength = 0;
- urlComponents.dwSchemeLength = 1024;
- urlComponents.dwUrlPathLength = 1024;
- urlComponents.dwUserNameLength = 0;
- urlComponents.dwExtraInfoLength = 1024;
- urlComponents.lpszHostName = nullptr;
- urlComponents.lpszPassword = nullptr;
- urlComponents.lpszScheme = nullptr;
- urlComponents.lpszUrlPath = nullptr;
- urlComponents.lpszUserName = nullptr;
- urlComponents.lpszExtraInfo = nullptr;
- if (!InternetCrackUrlA(url.c_str(), 0, 0, &urlComponents))
- {
- des = getLastErrorMsg();
- return false;
- }
-
- if (urlComponents.nScheme != INTERNET_SCHEME_HTTP && urlComponents.nScheme != INTERNET_SCHEME_HTTPS)
- {
- des = "Unknown URL Scheme";
- return false;
- }
-
- const char* acceptTypes[] = {"*/*", nullptr};
-
- const HINTERNET hInternet = InternetOpenA(UserAgent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
- const HINTERNET hConnect = InternetConnectA(hInternet, std::string(urlComponents.lpszHostName, urlComponents.dwHostNameLength).c_str(), urlComponents.nPort, nullptr, nullptr,
- INTERNET_SERVICE_HTTP, 0, 0);
- const HINTERNET hRequest = HttpOpenRequestA(hConnect, "POST", (std::string(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength) + std::string(urlComponents.lpszExtraInfo, urlComponents.dwExtraInfoLength)).c_str(), "HTTP/1.1", nullptr, acceptTypes,
- (urlComponents.nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0), 0);
- const BOOL res = HttpSendRequestA(hRequest, strHeader.c_str(), strHeader.length(), (void*)postContent.c_str(), postContent.length());
-
-
- if (res)
- {
- DWORD dwRetCode = 0;
- DWORD dwBufferLength = sizeof(dwRetCode);
- if (!HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwBufferLength,
- nullptr))
- {
- des = getLastErrorMsg();
- goto InternetClose;
- }
- if (dwRetCode != 200)
- {
- des = getMsg("strRequestRetCodeErr", AttrVars{ {"error", std::to_string(dwRetCode)} });
- goto InternetClose;
- }
- DWORD preRcvCnt;
- if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0))
- {
- des = getLastErrorMsg();
- goto InternetClose;
- }
- if (preRcvCnt == 0)
- {
- des = getMsg("strRequestNoResponse");
- return false;
- }
- std::string finalRcvData;
- while (preRcvCnt)
- {
- char* rcvData = new char[preRcvCnt];
- DWORD rcvCnt;
-
- if (!InternetReadFile(hRequest, rcvData, preRcvCnt, &rcvCnt))
- {
- des = getLastErrorMsg();
- delete[] rcvData;
- goto InternetClose;
- }
-
- if (rcvCnt != preRcvCnt){
- des = getMsg("strUnknownErr");
- delete[] rcvData;
- goto InternetClose;
- }
-
- finalRcvData += std::string(rcvData, rcvCnt);
-
- if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0)) {
- des = getLastErrorMsg();
- delete[] rcvData;
- goto InternetClose;
- }
-
- delete[] rcvData;
- }
-
- des = finalRcvData;
-
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- return true;
- }
- des = getLastErrorMsg();
-InternetClose:
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- return false;
-
-#else
-
- CURL* curl;
- curl = curl_easy_init();
- if (curl)
- {
- struct curl_slist* header = NULL;
- header = curl_slist_append(header, strHeader.c_str());
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_USERAGENT, DiceRequestHeader);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postContent.c_str());
- curl_easy_setopt(curl, CURLOPT_POST, 1L);
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteToString);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &des);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
-
- lastError = curl_easy_perform(curl);
- if (lastError != CURLE_OK)
- {
- des = getLastErrorMsg();
- }
- curl_slist_free_all(header);
- curl_easy_cleanup(curl);
- return lastError == CURLE_OK;
- }
- return false;
-#endif
-
- }
-
- bool GET(const string& url, std::string& des) {
-#ifdef _WIN32
- URL_COMPONENTSA urlComponents{};
- urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
- urlComponents.dwHostNameLength = 1024;
- urlComponents.dwPasswordLength = 0;
- urlComponents.dwSchemeLength = 1024;
- urlComponents.dwUrlPathLength = 1024;
- urlComponents.dwUserNameLength = 0;
- urlComponents.dwExtraInfoLength = 1024;
- urlComponents.lpszHostName = nullptr;
- urlComponents.lpszPassword = nullptr;
- urlComponents.lpszScheme = nullptr;
- urlComponents.lpszUrlPath = nullptr;
- urlComponents.lpszUserName = nullptr;
- urlComponents.lpszExtraInfo = nullptr;
- if (!InternetCrackUrlA(url.c_str(), 0, 0, &urlComponents))
- {
- des = getLastErrorMsg();
- return false;
- }
-
- if (urlComponents.nScheme != INTERNET_SCHEME_HTTP && urlComponents.nScheme != INTERNET_SCHEME_HTTPS)
- {
- des = "Unknown URL Scheme";
- return false;
- }
-
- const char* acceptTypes[] = {"*/*", nullptr};
-
- const HINTERNET hInternet = InternetOpenA(DiceRequestHeader, INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
- const HINTERNET hConnect = InternetConnectA(hInternet, std::string(urlComponents.lpszHostName, urlComponents.dwHostNameLength).c_str(), urlComponents.nPort, nullptr, nullptr,
- INTERNET_SERVICE_HTTP, 0, 0);
- const HINTERNET hRequest = HttpOpenRequestA(hConnect, "GET",
- (std::string(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength) + std::string(urlComponents.lpszExtraInfo, urlComponents.dwExtraInfoLength)).c_str(),
- "HTTP/1.1", nullptr, acceptTypes, (urlComponents.nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0) | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD, 0);
- const BOOL res = HttpSendRequestA(hRequest, nullptr, 0, nullptr, 0);
-
-
- if (res)
- {
- DWORD dwRetCode = 0;
- DWORD dwBufferLength = sizeof(dwRetCode);
- if (!HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwBufferLength,
- nullptr))
- {
- des = getLastErrorMsg();
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- return false;
- }
- if (dwRetCode != 200)
- {
- des = getMsg("strRequestRetCodeErr", AttrVars{ {"error", std::to_string(dwRetCode)} });
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- return false;
- }
- DWORD preRcvCnt;
- if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0))
- {
- des = getLastErrorMsg();
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- return false;
- }
- if (preRcvCnt == 0)
- {
- des = getMsg("strRequestNoResponse");
- return false;
- }
- std::string finalRcvData;
- while (preRcvCnt)
- {
- char* rcvData = new char[preRcvCnt];
- DWORD rcvCnt;
-
- if (!InternetReadFile(hRequest, rcvData, preRcvCnt, &rcvCnt))
- {
- des = getLastErrorMsg();
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- delete[] rcvData;
- return false;
- }
-
- if (rcvCnt != preRcvCnt)
- {
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- des = getMsg("strUnknownErr");
- delete[] rcvData;
- return false;
- }
-
- finalRcvData += std::string(rcvData, rcvCnt);
-
- if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0))
- {
- des = getLastErrorMsg();
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- delete[] rcvData;
- return false;
- }
-
- delete[] rcvData;
- }
-
- des = finalRcvData;
-
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- return true;
- }
- des = getLastErrorMsg();
- InternetCloseHandle(hRequest);
- InternetCloseHandle(hConnect);
- InternetCloseHandle(hInternet);
- return false;
-#else
- CURL* curl;
- curl = curl_easy_init();
- if (curl)
- {
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_USERAGENT, DiceRequestHeader);
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteToString);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &des);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
-
- lastError = curl_easy_perform(curl);
- if (lastError != CURLE_OK)
- {
- des = getLastErrorMsg();
- }
-
- curl_easy_cleanup(curl);
- return lastError == CURLE_OK;
- }
- return false;
-#endif
- }
-
-}
+/*
+ * _______ ________ ________ ________ __
+ * | __ \ |__ __| | _____| | _____| | |
+ * | | | | | | | | | |_____ | |
+ * | | | | | | | | | _____| |__|
+ * | |__| | __| |__ | |_____ | |_____ __
+ * |_______/ |________| |________| |________| |__|
+ *
+ * Dice! QQ Dice Robot for TRPG
+ * Copyright (C) 2018-2019 w4123婧磩
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Affero General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License along with this
+ * program. If not, see .
+ */
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include
+#include
+#pragma comment(lib, "WinInet.lib")
+#else
+#include
+#endif
+
+#include
+#include
+#include "GlobalVar.h"
+#include "MsgFormat.h"
+#include "DiceNetwork.h"
+#include "StrExtern.hpp"
+
+namespace Network
+{
+#ifndef _WIN32
+ thread_local CURLcode lastError;
+
+ size_t curlWriteToString(void *contents, size_t size, size_t nmemb, std::string *s)
+ {
+ size_t newLength = size*nmemb;
+ s->append((char*)contents, newLength);
+ return newLength;
+ }
+#endif
+
+ std::string getLastErrorMsg()
+ {
+#ifdef _WIN32
+ DWORD dwError = GetLastError();
+ if (dwError == ERROR_INTERNET_EXTENDED_ERROR)
+ {
+ DWORD size = 512;
+ wchar_t* szFormatBuffer = new wchar_t[size];
+ if (InternetGetLastResponseInfoW(&dwError, szFormatBuffer, &size))
+ {
+ std::string ret(convert_w2a(reinterpret_cast(szFormatBuffer)));
+ while (ret[ret.length() - 1] == '\n' || ret[ret.length() - 1] == '\r')ret.erase(ret.length() - 1);
+ delete[] szFormatBuffer;
+ return ret;
+ }
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ size++;
+ delete[] szFormatBuffer;
+ szFormatBuffer = new wchar_t[size];
+ if (InternetGetLastResponseInfoW(&dwError, szFormatBuffer, &size))
+ {
+ std::string ret(convert_w2a(reinterpret_cast(szFormatBuffer)));
+ while (ret[ret.length() - 1] == '\n' || ret[ret.length() - 1] == '\r')ret.erase(ret.length() - 1);
+ delete[] szFormatBuffer;
+ return ret;
+ }
+ delete[] szFormatBuffer;
+ return getMsg("strUnableToGetErrorMsg");
+ }
+ delete[] szFormatBuffer;
+ return getMsg("strUnableToGetErrorMsg");
+ }
+ wchar_t szFormatBuffer[512];
+ DWORD dwBaseLength = FormatMessageW(
+ FORMAT_MESSAGE_FROM_HMODULE, // dwFlags
+ GetModuleHandleW(L"wininet.dll"), // lpSource
+ dwError, // dwMessageId
+ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), // dwLanguageId
+ szFormatBuffer, // lpBuffer
+ 512, // nSize
+ nullptr);
+
+ if (dwBaseLength == 0)
+ {
+ dwBaseLength = FormatMessageW(
+ FORMAT_MESSAGE_FROM_HMODULE, // dwFlags
+ GetModuleHandleW(L"wininet.dll"), // lpSource
+ dwError, // dwMessageId
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // dwLanguageId
+ szFormatBuffer, // lpBuffer
+ 512, // nSize
+ nullptr);
+ }
+
+ if (dwBaseLength)
+ {
+ std::string ret(convert_w2a(reinterpret_cast(szFormatBuffer)));
+ while (ret[ret.length() - 1] == '\n' || ret[ret.length() - 1] == '\r')ret.erase(ret.length() - 1);
+ return ret;
+ }
+ return getMsg("strUnableToGetErrorMsg");
+#else
+ return curl_easy_strerror(lastError);
+#endif
+ }
+
+ bool POST(const string& url, const string& postContent, const string& postHeader, std::string& des)
+ {
+ std::string strHeader = postHeader.empty() ? "Content-Type: application/x-www-form-urlencoded" : postHeader;
+#ifdef _WIN32
+ std::string UserAgent{ DiceRequestHeader };
+ static std::regex re{ R"(User-Agent: ([^\r\n]*))" };
+ std::smatch match;
+ if (std::regex_search(strHeader, match, re)) {
+ UserAgent = match[1].str();
+ }
+ URL_COMPONENTSA urlComponents{};
+ urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
+ urlComponents.dwHostNameLength = 1024;
+ urlComponents.dwPasswordLength = 0;
+ urlComponents.dwSchemeLength = 1024;
+ urlComponents.dwUrlPathLength = 1024;
+ urlComponents.dwUserNameLength = 0;
+ urlComponents.dwExtraInfoLength = 1024;
+ urlComponents.lpszHostName = nullptr;
+ urlComponents.lpszPassword = nullptr;
+ urlComponents.lpszScheme = nullptr;
+ urlComponents.lpszUrlPath = nullptr;
+ urlComponents.lpszUserName = nullptr;
+ urlComponents.lpszExtraInfo = nullptr;
+ if (!InternetCrackUrlA(url.c_str(), 0, 0, &urlComponents))
+ {
+ des = getLastErrorMsg();
+ return false;
+ }
+
+ if (urlComponents.nScheme != INTERNET_SCHEME_HTTP && urlComponents.nScheme != INTERNET_SCHEME_HTTPS)
+ {
+ des = "Unknown URL Scheme";
+ return false;
+ }
+
+ const char* acceptTypes[] = {"*/*", nullptr};
+
+ const HINTERNET hInternet = InternetOpenA(UserAgent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
+ const HINTERNET hConnect = InternetConnectA(hInternet, std::string(urlComponents.lpszHostName, urlComponents.dwHostNameLength).c_str(), urlComponents.nPort, nullptr, nullptr,
+ INTERNET_SERVICE_HTTP, 0, 0);
+ const HINTERNET hRequest = HttpOpenRequestA(hConnect, "POST", (std::string(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength) + std::string(urlComponents.lpszExtraInfo, urlComponents.dwExtraInfoLength)).c_str(), "HTTP/1.1", nullptr, acceptTypes,
+ (urlComponents.nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0), 0);
+ const BOOL res = HttpSendRequestA(hRequest, strHeader.c_str(), strHeader.length(), (void*)postContent.c_str(), postContent.length());
+
+
+ if (res)
+ {
+ DWORD dwRetCode = 0;
+ DWORD dwBufferLength = sizeof(dwRetCode);
+ if (!HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwBufferLength,
+ nullptr))
+ {
+ des = getLastErrorMsg();
+ goto InternetClose;
+ }
+ if (dwRetCode != 200)
+ {
+ des = getMsg("strRequestRetCodeErr", AttrVars{ {"error", std::to_string(dwRetCode)} });
+ goto InternetClose;
+ }
+ DWORD preRcvCnt;
+ if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0))
+ {
+ des = getLastErrorMsg();
+ goto InternetClose;
+ }
+ if (preRcvCnt == 0)
+ {
+ des = getMsg("strRequestNoResponse");
+ return false;
+ }
+ std::string finalRcvData;
+ while (preRcvCnt)
+ {
+ char* rcvData = new char[preRcvCnt];
+ DWORD rcvCnt;
+
+ if (!InternetReadFile(hRequest, rcvData, preRcvCnt, &rcvCnt))
+ {
+ des = getLastErrorMsg();
+ delete[] rcvData;
+ goto InternetClose;
+ }
+
+ if (rcvCnt != preRcvCnt){
+ des = getMsg("strUnknownErr");
+ delete[] rcvData;
+ goto InternetClose;
+ }
+
+ finalRcvData += std::string(rcvData, rcvCnt);
+
+ if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0)) {
+ des = getLastErrorMsg();
+ delete[] rcvData;
+ goto InternetClose;
+ }
+
+ delete[] rcvData;
+ }
+
+ des = finalRcvData;
+
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ return true;
+ }
+ des = getLastErrorMsg();
+InternetClose:
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ return false;
+
+#else
+
+ CURL* curl;
+ curl = curl_easy_init();
+ if (curl)
+ {
+ struct curl_slist* header = NULL;
+ header = curl_slist_append(header, strHeader.c_str());
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, DiceRequestHeader);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postContent.c_str());
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteToString);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &des);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+
+ lastError = curl_easy_perform(curl);
+ if (lastError != CURLE_OK)
+ {
+ des = getLastErrorMsg();
+ }
+ curl_slist_free_all(header);
+ curl_easy_cleanup(curl);
+ return lastError == CURLE_OK;
+ }
+ return false;
+#endif
+
+ }
+
+ bool GET(const string& url, std::string& des) {
+#ifdef _WIN32
+ URL_COMPONENTSA urlComponents{};
+ urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
+ urlComponents.dwHostNameLength = 1024;
+ urlComponents.dwPasswordLength = 0;
+ urlComponents.dwSchemeLength = 1024;
+ urlComponents.dwUrlPathLength = 1024;
+ urlComponents.dwUserNameLength = 0;
+ urlComponents.dwExtraInfoLength = 1024;
+ urlComponents.lpszHostName = nullptr;
+ urlComponents.lpszPassword = nullptr;
+ urlComponents.lpszScheme = nullptr;
+ urlComponents.lpszUrlPath = nullptr;
+ urlComponents.lpszUserName = nullptr;
+ urlComponents.lpszExtraInfo = nullptr;
+ if (!InternetCrackUrlA(url.c_str(), 0, 0, &urlComponents))
+ {
+ des = getLastErrorMsg();
+ return false;
+ }
+
+ if (urlComponents.nScheme != INTERNET_SCHEME_HTTP && urlComponents.nScheme != INTERNET_SCHEME_HTTPS)
+ {
+ des = "Unknown URL Scheme";
+ return false;
+ }
+
+ const char* acceptTypes[] = {"*/*", nullptr};
+
+ const HINTERNET hInternet = InternetOpenA(DiceRequestHeader, INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
+ const HINTERNET hConnect = InternetConnectA(hInternet, std::string(urlComponents.lpszHostName, urlComponents.dwHostNameLength).c_str(), urlComponents.nPort, nullptr, nullptr,
+ INTERNET_SERVICE_HTTP, 0, 0);
+ const HINTERNET hRequest = HttpOpenRequestA(hConnect, "GET",
+ (std::string(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength) + std::string(urlComponents.lpszExtraInfo, urlComponents.dwExtraInfoLength)).c_str(),
+ "HTTP/1.1", nullptr, acceptTypes, (urlComponents.nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0) | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD, 0);
+ const BOOL res = HttpSendRequestA(hRequest, nullptr, 0, nullptr, 0);
+
+
+ if (res)
+ {
+ DWORD dwRetCode = 0;
+ DWORD dwBufferLength = sizeof(dwRetCode);
+ if (!HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwBufferLength,
+ nullptr))
+ {
+ des = getLastErrorMsg();
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ return false;
+ }
+ if (dwRetCode != 200)
+ {
+ des = getMsg("strRequestRetCodeErr", AttrVars{ {"error", std::to_string(dwRetCode)} });
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ return false;
+ }
+ DWORD preRcvCnt;
+ if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0))
+ {
+ des = getLastErrorMsg();
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ return false;
+ }
+ if (preRcvCnt == 0)
+ {
+ des = getMsg("strRequestNoResponse");
+ return false;
+ }
+ std::string finalRcvData;
+ while (preRcvCnt)
+ {
+ char* rcvData = new char[preRcvCnt];
+ DWORD rcvCnt;
+
+ if (!InternetReadFile(hRequest, rcvData, preRcvCnt, &rcvCnt))
+ {
+ des = getLastErrorMsg();
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ delete[] rcvData;
+ return false;
+ }
+
+ if (rcvCnt != preRcvCnt)
+ {
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ des = getMsg("strUnknownErr");
+ delete[] rcvData;
+ return false;
+ }
+
+ finalRcvData += std::string(rcvData, rcvCnt);
+
+ if (!InternetQueryDataAvailable(hRequest, &preRcvCnt, 0, 0))
+ {
+ des = getLastErrorMsg();
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ delete[] rcvData;
+ return false;
+ }
+
+ delete[] rcvData;
+ }
+
+ des = finalRcvData;
+
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ return true;
+ }
+ des = getLastErrorMsg();
+ InternetCloseHandle(hRequest);
+ InternetCloseHandle(hConnect);
+ InternetCloseHandle(hInternet);
+ return false;
+#else
+ CURL* curl;
+ curl = curl_easy_init();
+ if (curl)
+ {
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, DiceRequestHeader);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteToString);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &des);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+
+ lastError = curl_easy_perform(curl);
+ if (lastError != CURLE_OK)
+ {
+ des = getLastErrorMsg();
+ }
+
+ curl_easy_cleanup(curl);
+ return lastError == CURLE_OK;
+ }
+ return false;
+#endif
+ }
+
+}
diff --git a/Dice/GlobalVar.cpp b/Dice/GlobalVar.cpp
index 8efe35d3..d9ea14dc 100644
--- a/Dice/GlobalVar.cpp
+++ b/Dice/GlobalVar.cpp
@@ -356,23 +356,18 @@ const dict_ci PlainMsg
{"strPropList", "{nick}鐨剓char}灞炴у垪琛ㄤ负锛歿show}"},
{"strStErr", "鏍煎紡閿欒:璇峰弬鑰/help st鑾峰彇.st鍛戒护鐨勪娇鐢ㄦ柟娉"},
{"strRulesFormatErr", "鏍煎紡閿欒:姝g‘鏍煎紡涓.rules[瑙勫垯鍚嶇О:]瑙勫垯鏉$洰 濡.rules COC7:鍔涢噺"},
- {"strLeaveDiscuss", "{self}鐜颁笉鏀寔璁ㄨ缁勬湇鍔★紝鍗冲皢閫鍑"},
- {"strLeaveNoPower", "{self}鏈幏寰楃兢绠$悊锛屽嵆灏嗛缇"},
- {"strLeaveUnused", "{self}宸茬粡鍦ㄨ繖閲岃鏀剧疆{day}澶╁暒锛岄┈涓婂氨浼氱寮杩欓噷浜"},
{"strGlobalOff", "{self}浼戝亣涓紝鏆傚仠鏈嶅姟脳"},
{"strPreserve", "{self}绉佹湁绉佺敤锛屽嬁鎵板嬁鎬猏n濡傞渶鐢宠璁稿彲璇峰彂閫!authorize +[缇ゅ彿] 鐢宠鐢ㄩ:[ **璇峰啓鍏ョ悊鐢** ] 鎴戝凡浜嗚ВDice!鍩烘湰鐢ㄦ硶锛屼粩缁嗛槄璇诲苟淇濊瘉閬靛畧{strSelfName}鐨勭敤鎴峰崗璁紝濡傞渶鍋滅敤鎸囦护浣跨敤[ **璇峰啓鍏ユ寚浠** ]锛岀敤鍚庝娇鐢╗ **璇峰啓鍏ユ寚浠** ]閫佸嚭缇"},
{"strJrrp", "{nick}浠婂ぉ鐨勪汉鍝佸兼槸: {res}"},
{"strJrrpErr", "JRRP鑾峰彇澶辫触! 閿欒淇℃伅: \n{res}"},
{ "strFriendDenyNotUser", "寰堥仐鎲撅紝浣犳病鏈夊{self}浣跨敤鎸囦护鐨勮褰" },
{ "strFriendDenyNoTrust", "寰堥仐鎲撅紝浣犱笉鏄瘂self}淇′换鐨勭敤鎴凤紝濡傞渶浣跨敤鍙仈绯粄print:master}" },
- {"strAddFriendWhiteQQ", "{strAddFriend}"}, //鐧藉悕鍗曠敤鎴锋坊鍔犲ソ鍙嬫椂鍥炲姝ゅ彞
{
"strAddFriend",
R"(娆㈣繋閫夋嫨{strSelfName}鐨勫厤璐规幏楠版湇鍔★紒
/help鍗忚 纭鏈嶅姟鍗忚
/help鎸囦护 鏌ョ湅鎸囦护鍒楄〃
/help璁惧畾 纭楠板璁惧畾
-/help閾炬帴 鏌ョ湅婧愮爜鏂囨。
浣跨敤鏈嶅姟榛樿宸茬粡鍚屾剰鏈嶅姟鍗忚)"
}, //鍚屾剰娣诲姞濂藉弸鏃堕澶栧彂閫佺殑璇彞
{
@@ -381,7 +376,6 @@ const dict_ci PlainMsg
/help鍗忚 纭鏈嶅姟鍗忚
/help鎸囦护 鏌ョ湅鎸囦护鍒楄〃
/help璁惧畾 纭楠板璁惧畾
-/help閾炬帴 鏌ョ湅婧愮爜鏂囨。
閭璇峰叆缇ら粯璁よ涓哄悓鎰忔湇鍔″崗璁紝鐭ユ檽绂佽█鎴栫Щ鍑虹殑鍚庢灉)"
},
{ "strNewMaster","璇曢棶锛屼綘灏辨槸{strSelfName}鐨凪aster鈭歕n璇疯鐪熼槄璇诲綋鍓嶇増鏈琈aster鎵嬪唽浠ュ強鐢ㄦ埛鎵嬪唽銆傝娉ㄦ剰鐗堟湰鍙峰搴: https://v2docs.kokona.tech\f{strSelfName}" },
@@ -394,9 +388,7 @@ const dict_ci PlainMsg
{"strHlpMsg", R"(璇蜂娇鐢
/help鍗忚 纭鏈嶅姟鍗忚
/help鎸囦护 鏌ョ湅鎸囦护鍒楄〃
-/help缇ょ 鏌ョ湅缇ょ鎸囦护
/help璁惧畾 纭楠板璁惧畾
-/help閾炬帴 鏌ョ湅婧愮爜鏂囨。
瀹樻柟璁哄潧: kokona鐐箃ech
Dice!浼楃璁″垝: afdian@suhuiw4123)"
}
@@ -530,7 +522,7 @@ const dict_ci<> HelpDoc = {
8.鏈崗璁唴瀹归殢鏃舵湁鍙兘鏀瑰姩銆傝娉ㄦ剰甯姪淇℃伅銆佺鍚嶃佺┖闂淬佸畼鏂圭兢绛夊鐨勯濞樺姩鎬併
9.楠板鎻愪緵鎺烽鏈嶅姟鏄畬鍏ㄥ厤璐圭殑锛屾杩庤嚜鎰挎姇椋熴
10.鏈湇鍔℃渶缁堣В閲婃潈褰掓湇鍔℃彁渚涙柟鎵鏈夈)"},
-{"閾炬帴","Dice!璁哄潧: https://kokona.tech\nDice!鎵嬪唽: https://v2docs.kokona.tech\n鏀寔Shiki: https://afdian.net/@dice_shiki"},
+{"閾炬帴","Dice!璁哄潧: https://kokona.tech\nDice!鎵嬪唽: https://v2docs.kokona.tech\n鏀寔Shiki: https://afdian@dice_shiki"},
{"璁惧畾",R"(Master锛歿print:master}
缇ゅ唴浣跨敤锛歿case:self.Private?else=鐧藉悕鍗曞埗锛岄渶棰勭敵璇&0={case:self.CheckGroupLicense?2=瀹℃牳鍒讹紝闇鐢宠鍚庝娇鐢&1=瀹℃牳鍒讹紝鍏ユ柊缇ら渶鐢宠&else=榛戝悕鍗曞埗锛岃嚜鐢变娇鐢▆}
鍒峰睆鐩戞祴锛歿case:self.ListenSpam?0=鍏抽棴&else=寮鍚瘆
@@ -544,21 +536,17 @@ const dict_ci<> HelpDoc = {
{at:self}.bot on
璇/help瀵瑰簲鎸囦护 鑾峰彇璇︾粏淇℃伅锛屽/help r
浜掑姩鎸囦护:
-.nn 璁剧疆绉板懠
+/nn 璁剧疆绉板懠
.bot 鐗堟湰淇℃伅
-.group 缇ょ
.send 鍚戝悗鍙板彂閫佹秷鎭
-.mod 妯″潡鎿嶄綔)"
-"\f"
-R"([绗簩椤礭璺戝洟鎸囦护
+璺戝洟鎸囦护
.game 娓告垙棰嗗煙
-.r 鎺烽
+/r 鎺烽
.rules 瑙勫垯閫熸煡
-.log 鏃ュ織璁板綍
.set 璁剧疆榛樿楠
.coc COC浜虹墿浣滄垚
.dnd DND浜虹墿浣滄垚
-.st 灞炴ц褰
+.st 瑙掕壊灞炴ц褰
.pc 瑙掕壊鍗¤褰
.rc 妫瀹
.setcoc 璁剧疆rc鎴胯
@@ -566,9 +554,8 @@ R"([绗簩椤礭璺戝洟鎸囦护
.en 鎴愰暱/澧炲己妫瀹
.ri 鍏堟敾
.init 鍏堟敾鍒楄〃
-.ww 楠版睜)"
-"\f"
-R"([绗笁椤礭鍏朵粬鎸囦护
+.ww 楠版睜
+鍏朵粬鎸囦护
.draw 鎶界墝
.deck 鐗屽爢瀹炰緥
.name 闅忔満濮撳悕
@@ -825,25 +812,6 @@ Type=[鍥炲鎬ц川](Reply/Order)
.welcome show //鏌ョ湅娆㈣繋璇
鏃犺鎸囦护鏄惁鍋滅敤锛屽彧瑕佹湁娆㈣繋璇嶆椂鏈変汉鍏ョ兢锛岄兘浼氬搷搴)"
},
- {"group", "&缇ょ"},
- {
- "缇ょ",
- R"(缇ょ鎸囦护.group(缇ょ鐞嗗憳闄愬畾)
-.group state //鏌ョ湅鍦ㄧ兢鍐呭楠板鐨勮缃
-.group pause/restart //缇ゅ叏浣撶瑷/鍏ㄤ綋瑙i櫎绂佽█
-.group card [at/鐢ㄦ埛QQ] [鍚嶇墖] //璁剧疆缇ゅ憳鍚嶇墖
-.group title [at/鐢ㄦ埛QQ] [澶磋] //璁剧疆缇ゅ憳澶磋
-.group diver //鏌ョ湅娼滄按鎴愬憳
-.group +/-[缇ょ璇嶆潯] //涓虹兢鍔犲噺璁剧疆锛岄渶瑕佸搴旀潈闄
-渚:.group +绂佺敤鍥炲 //鍏抽棴鏈兢鑷畾涔夊洖澶
-缇ょ璇嶆潯:鍋滅敤鎸囦护/绂佺敤鍥炲/绂佺敤jrrp/绂佺敤draw/绂佺敤me/绂佺敤help/绂佺敤ob/鎷︽埅娑堟伅/璁稿彲浣跨敤/鍏嶆竻/鍏嶉粦)"
- },
- { "groups_list", "&鍙栫兢鍒楄〃" },
- { "鍙栫兢鍒楄〃", R"(鍙栫兢鍒楄〃.groups list(绠$悊闄愬畾)
-.groups list idle //鎸夐棽缃ぉ鏁伴檷搴忓垪鍑虹兢
-.groups list size //鎸夌兢瑙勬ā闄嶅簭鍒楀嚭缇
-.groups list [缇ょ璇嶆潯] //鍒楀嚭甯︽湁璇嶆潯鐨勭兢
-缇ょ璇嶆潯:鍋滅敤鎸囦护/绂佺敤鍥炲/绂佺敤jrrp/绂佺敤draw/绂佺敤me/绂佺敤help/绂佺敤ob/鎷︽埅娑堟伅/璁稿彲浣跨敤/鍏嶆竻/鍏嶉粦)" },
{ "鏁忔劅璇嶆娴","&censor" },
{"censor",R"(鏁忔劅璇嶆娴.admin censor
.admin censor +([瑙﹀彂绛夌骇])=[鏁忔劅璇0](|[鏁忔劅璇1]...) //娣诲姞鏁忔劅璇
diff --git a/Dice/GlobalVar.h b/Dice/GlobalVar.h
index abac8f8c..96b535d7 100644
--- a/Dice/GlobalVar.h
+++ b/Dice/GlobalVar.h
@@ -44,7 +44,7 @@ constexpr unsigned short Dice_Build = 655u;
inline const std::string Dice_Ver_Without_Build = "2.7.0beta6[Alter]";
constexpr auto DiceRequestHeader = "Dice/2.7.0";
inline const std::string Dice_Ver = Dice_Ver_Without_Build + "(" + std::to_string(Dice_Build) + ")";
-inline const std::string Dice_Short_Ver = "Dice! by 婧磩 & Shiki Ver " + Dice_Ver;
+inline const std::string Dice_Short_Ver = "Dice!Alter by 婧磩 & Shiki Ver " + Dice_Ver;
constexpr bool isDev = true;
#ifdef __clang__
diff --git a/Dice/RandomGenerator.cpp b/Dice/RandomGenerator.cpp
index e341efc5..b64dcfa2 100644
--- a/Dice/RandomGenerator.cpp
+++ b/Dice/RandomGenerator.cpp
@@ -1,97 +1,97 @@
-/*
- * _______ ________ ________ ________ __
- * | __ \ |__ __| | _____| | _____| | |
- * | | | | | | | | | |_____ | |
- * | | | | | | | | | _____| |__|
- * | |__| | __| |__ | |_____ | |_____ __
- * |_______/ |________| |________| |________| |__|
- *
- * Dice! QQ Dice Robot for TRPG
- * Copyright (C) 2018-2019 w4123溯洄
- *
- * This program is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Affero General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License along with this
- * program. If not, see .
- */
-#include "RandomGenerator.h"
-#include
-#include
-
-#if defined(__i386__) || defined(__x86_64__)
-#ifdef _MSC_VER
-#include
-#else
-#include
-#endif
-#endif
-constexpr const char digit_chars[]{ "0123456789" };
-constexpr const char hex_chars[]{ "0123456789abcdef" };
-constexpr const char alpha_chars[]{ "abcdefghijklmnopqrstuvwxyz" };
-constexpr const char alnum_chars[]{ "abcdefghijklmnopqrstuvwxyz0123456789" };
-constexpr const char base64_chars[]{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" };
-constexpr const char base64url_chars[]{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" };
-
-namespace RandomGenerator
-{
- unsigned long long GetCycleCount()
- {
-#if defined(__i386__) || defined(__x86_64__)
- return __rdtsc();
-#else
- return static_cast (std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count());
-#endif
- }
-
-#if defined(__i386__) || defined(__x86_64__)
- int Randint(int lowest, int highest)
- {
- std::mt19937 gen(static_cast(GetCycleCount()));
- std::uniform_int_distribution dis(lowest, highest);
- return dis(gen);
- }
-#else
- std::mt19937 gen(static_cast(GetCycleCount()));
- int Randint(int lowest, int highest)
- {
- std::uniform_int_distribution dis(lowest, highest);
- return dis(gen);
- }
-#endif
- std::string genKey(size_t len, Code mode) {
- std::string res;
- std::string charset;
- switch (mode) {
- case RandomGenerator::Code::Hex:
- charset = hex_chars;
- break;
- case RandomGenerator::Code::Alpha:
- charset = alpha_chars;
- break;
- case RandomGenerator::Code::Alnum:
- charset = alnum_chars;
- break;
- case RandomGenerator::Code::Base64:
- charset = base64_chars;
- break;
- case RandomGenerator::Code::UrlBase64:
- charset = base64url_chars;
- break;
- case RandomGenerator::Code::Decimal:
- default:
- charset = digit_chars;
- break;
- }
- size_t size{ charset.length() - 1 };
- for (size_t i = 0; i < len; ++i) {
- res += charset[Randint(0, size)];
- }
- return res;
- }
-}
+/*
+ * _______ ________ ________ ________ __
+ * | __ \ |__ __| | _____| | _____| | |
+ * | | | | | | | | | |_____ | |
+ * | | | | | | | | | _____| |__|
+ * | |__| | __| |__ | |_____ | |_____ __
+ * |_______/ |________| |________| |________| |__|
+ *
+ * Dice! QQ Dice Robot for TRPG
+ * Copyright (C) 2018-2019 w4123婧磩
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Affero General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License along with this
+ * program. If not, see .
+ */
+#include "RandomGenerator.h"
+#include
+#include
+
+#if defined(__i386__) || defined(__x86_64__)
+#ifdef _MSC_VER
+#include
+#else
+#include
+#endif
+#endif
+constexpr const char digit_chars[]{ "0123456789" };
+constexpr const char hex_chars[]{ "0123456789abcdef" };
+constexpr const char alpha_chars[]{ "abcdefghijklmnopqrstuvwxyz" };
+constexpr const char alnum_chars[]{ "abcdefghijklmnopqrstuvwxyz0123456789" };
+constexpr const char base64_chars[]{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" };
+constexpr const char base64url_chars[]{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" };
+
+namespace RandomGenerator
+{
+ unsigned long long GetCycleCount()
+ {
+#if defined(__i386__) || defined(__x86_64__)
+ return __rdtsc();
+#else
+ return static_cast (std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count());
+#endif
+ }
+
+#if defined(__i386__) || defined(__x86_64__)
+ int Randint(int lowest, int highest)
+ {
+ std::mt19937 gen(static_cast(GetCycleCount()));
+ std::uniform_int_distribution dis(lowest, highest);
+ return dis(gen);
+ }
+#else
+ std::mt19937 gen(static_cast(GetCycleCount()));
+ int Randint(int lowest, int highest)
+ {
+ std::uniform_int_distribution dis(lowest, highest);
+ return dis(gen);
+ }
+#endif
+ std::string genKey(size_t len, Code mode) {
+ std::string res;
+ std::string charset;
+ switch (mode) {
+ case RandomGenerator::Code::Hex:
+ charset = hex_chars;
+ break;
+ case RandomGenerator::Code::Alpha:
+ charset = alpha_chars;
+ break;
+ case RandomGenerator::Code::Alnum:
+ charset = alnum_chars;
+ break;
+ case RandomGenerator::Code::Base64:
+ charset = base64_chars;
+ break;
+ case RandomGenerator::Code::UrlBase64:
+ charset = base64url_chars;
+ break;
+ case RandomGenerator::Code::Decimal:
+ default:
+ charset = digit_chars;
+ break;
+ }
+ size_t size{ charset.length() - 1 };
+ for (size_t i = 0; i < len; ++i) {
+ res += charset[Randint(0, size)];
+ }
+ return res;
+ }
+}
diff --git a/OneBot/OneBotAPI.cpp b/OneBot/OneBotAPI.cpp
index f1921ef2..5d0029b9 100644
--- a/OneBot/OneBotAPI.cpp
+++ b/OneBot/OneBotAPI.cpp
@@ -487,7 +487,6 @@ void OneBot_Event(fifo_json& j) {
}
//缇よ亰
else if (j["message_type"] == "group") {
- api::printLog("group msg:" + msg);
ptr Msg(std::make_shared(
AttrObject({ { "Event", "Message" },
{ "fromMsg", msg },