Skip to content

Commit

Permalink
更新天气插件(API实现)
Browse files Browse the repository at this point in the history
  • Loading branch information
quqiOnfree committed Apr 14, 2023
1 parent b08e263 commit 12d8ad4
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.vs
/out
/include
/include
/lib
17 changes: 17 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,26 @@ if (MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd /utf-8")
endif(MSVC)

#openssl支持
find_package(OpenSSL REQUIRED)
if(OPENSSL_FOUND)
set(HTTPLIB_IS_USING_OPENSSL TRUE)
endif()

link_directories("${CMAKE_SOURCE_DIR}/lib")

# 将源代码添加到此项目的可执行文件。
add_executable (qqbot "${INCLUDEFILE}" "${SOURCEFILE}")

#openssl
target_link_libraries(${PROJECT_NAME} PUBLIC
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::SSL>
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:OpenSSL::Crypto>)

target_compile_definitions(${PROJECT_NAME} PUBLIC
$<$<BOOL:${HTTPLIB_IS_USING_OPENSSL}>:CPPHTTPLIB_OPENSSL_SUPPORT>
)

if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET qqbot PROPERTY CXX_STANDARD 20)
endif()
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# QQ机器人
# QQ机器人
## 介绍
- 这个QQ机器人拥有插件系统,可以轻松扩展
- 语言:C++
Expand All @@ -9,6 +9,7 @@
- [cpp-httplib](https://github.com/yhirose/cpp-httplib)
- [go-cqhttp](https://github.com/Mrs4s/go-cqhttp)
- [asio](https://github.com/chriskohlhoff/asio)
- [openssl](https://github.com/openssl/openssl)
### 导入
-[CMakeLists.txt](./CMakeLists.txt)里面进行编辑然后再编译

Expand Down
1 change: 1 addition & 0 deletions citycodes.json

Large diffs are not rendered by default.

277 changes: 277 additions & 0 deletions plugin/weather.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
#pragma once

#include <iostream>
#include <Json.h>
#include <httplib.h>
#include <vector>
#include <string>
#include <unordered_map>
#include <set>

#include "cppPlugin.h"
#include "pluginLibrary.h"
#include "network.h"

namespace Weather
{
class WeatherPlugin : public qqbot::CppPlugin
{
public:
//字符串关键字搜索树
class SearchTree
{
public:
SearchTree() = default;
~SearchTree() = default;

void insert(const std::string& data)
{
m_strings.push_back(data);
size_t position = m_strings.size() - 1;
for (auto i = data.begin(); i != data.end(); i++)
{
m_tree[*i].insert(position);
}
}

std::string getOriginalString(const std::string& data)
{
if (data.empty())
{
throw std::exception("data is empty");
}

std::set<size_t> locSet;
locSet = m_tree[data[0]];

for (auto i = data.begin() + 1; i != data.end(); i++)
{
std::set<size_t> locSet_2 = locSet;

for (auto j = locSet_2.begin(); j != locSet_2.end(); j++)
{
if (m_tree[*i].find(*j) == m_tree[*i].end())
{
locSet.erase(*j);
}
}

if (locSet.empty())
{
size_t min = m_strings[*locSet_2.begin()].size();
size_t pos = *locSet_2.begin();

for (auto i = locSet_2.begin(); i != locSet_2.end(); i++)
{
if (m_strings[*i].size() < min)
{
min = m_strings[*i].size();
pos = *i;
}
}

return m_strings[pos];
}
else if (locSet.size() == 1)
{
return m_strings[*locSet.begin()];
}
}

{
size_t min = m_strings[*locSet.begin()].size();
size_t pos = *locSet.begin();

for (auto i = locSet.begin(); i != locSet.end(); i++)
{
if (m_strings[*i] == data)
{
return data;
}
else if (m_strings[*i].size() < min)
{
min = m_strings[*i].size();
pos = *i;
}
}

bool canFindout = false;
std::string_view getStr = m_strings[pos];
for (size_t i = 0; i < getStr.size() - data.size(); i++)
{
if (getStr.substr(i, data.size()) == data)
{
canFindout = true;
break;
}
}


if (canFindout)
{
return m_strings[pos];
}
else
{
throw std::exception("找不到此地点");
}
}
}
private:
std::unordered_map<char, std::set<size_t>> m_tree;
std::vector<std::string> m_strings;
};

WeatherPlugin() : m_apiKey("dffc4517b36352b24303ecd2493658c7")
{
qqbot::CppPlugin::pluginInfo.author = "quqiOnfree";
qqbot::CppPlugin::pluginInfo.name = "Weather";
qqbot::CppPlugin::pluginInfo.version = "0.0.1";
}

~WeatherPlugin() = default;

virtual void onLoad()
{
std::cout << "[Weather]Hello!I'm on Loading...\n";
if (m_cityCode.empty())
{
std::ifstream infile("./citycodes.json");
qjson::JObject cityCode(qjson::JParser::fastParse(infile));
qjson::dict_t& locDict = cityCode.getDict();
for (auto i = locDict.begin(); i != locDict.end(); i++)
{
qjson::dict_t& locDict_2 = i->second.getDict();
for (auto j = locDict_2.begin(); j != locDict_2.end(); j++)
{
m_cityCode[i->first][j->first] = j->second.getString();
m_searchTree.insert(i->first);
}
}
}
std::cout << "[Weather]Sussessfully Loaded!\n";
}

virtual void onEnable()
{
qqbot::ServerInfo::getCommander().addCommand("tq",
[this](long long groupID, long long senderID, const std::string& commandName, std::vector<std::string> Args)
{
if (Args.empty())
{
qqbot::Network::sendGroupMessage(groupID, "tq 位置 a(实况)/b(预报) -天气查询");
}
else if (Args.size() == 2)
{
//地点
std::string position = m_searchTree.getOriginalString(Args[0]);
std::string code = m_cityCode[position]["adcode"];

//实况
if (Args[1] == "a")
{
//请求API
httplib::Client client("https://restapi.amap.com");
httplib::Params params = {
{ "key",m_apiKey },
{ "city",code },
{ "extensions","base" },
{ "output","JSON" }
};

httplib::Result result = client.Get("/v3/weather/weatherInfo", params, httplib::Headers());

if (result.error() != httplib::Error::Success && result.error() != httplib::Error::Connection)
{
qqbot::Network::sendGroupMessage(groupID, std::format("请求API出现问题,请稍后再试"));
return;
}
else if (!result)
{
qqbot::Network::sendGroupMessage(groupID, std::format("发生错误,无法连接API"));
return;
}
else if (result->status != 200)
{
qqbot::Network::sendGroupMessage(groupID, std::format("发生错误,API错误码:{}", result->status));
return;
}

qjson::JObject jo = qjson::JParser::fastParse(result->body);

if (jo["status"].getString() == "1" && jo["infocode"].getString() == "10000")
{
qqbot::Network::sendGroupMessage(groupID, std::format(
R"({}省{}的天气:
天气状况:{}
气温:{}
风向:{}风{}级
空气湿度:{}%
数据发布时间:{})",
jo["lives"][0]["province"].getString(),
jo["lives"][0]["city"].getString(),
jo["lives"][0]["weather"].getString(),
jo["lives"][0]["temperature"].getString(),
jo["lives"][0]["winddirection"].getString(),
jo["lives"][0]["windpower"].getString(),
jo["lives"][0]["humidity"].getString(),
jo["lives"][0]["reporttime"].getString()
));
}
else
{
qqbot::Network::sendGroupMessage(groupID, std::format("发生错误,无法获取相应的天气信息:{}", jo["info"].getString()));
}
}
//预报
else if (Args[1] == "b")
{
//请求API
httplib::SSLClient client("https://restapi.amap.com", 443);
httplib::Params params = {
{ "key",m_apiKey },
{ "city",code },
{ "extensions","base" },
{ "output","JSON" }
};
httplib::Headers headers;
httplib::Result result = client.Get("/v3/weather/weatherInfo", params, headers,
[&](const char* data, size_t data_length) {
//qjson::JObject jo = qjson::JParser::fastParse(std::string(data, data_length));
//qqbot::Network::sendGroupMessage(groupID, std::string(data, data_length));
return true;
});

if (result.error() != httplib::Error::Success)
{
qqbot::Network::sendGroupMessage(groupID, "请求API出现问题,请稍后再试");
return;
}
}
else
{
qqbot::Network::sendGroupMessage(groupID, "参数错误");
}
}
else
{
qqbot::Network::sendGroupMessage(groupID, "参数错误");
}
},
"tq 位置 a(实况)/b(预报)",
"天气查询"
);

qqbot::ServerInfo::getPermission().setGroupDefaultPermission("tq", true);
}

private:
static std::unordered_map<std::string, std::unordered_map<std::string, std::string>> m_cityCode;
static SearchTree m_searchTree;

std::string m_apiKey;
};
}

std::unordered_map<std::string, std::unordered_map<std::string, std::string>> Weather::WeatherPlugin::m_cityCode;
Weather::WeatherPlugin::SearchTree Weather::WeatherPlugin::m_searchTree;
4 changes: 4 additions & 0 deletions register/register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "divination.h"
#include "mil.h"
#include "groupOperator.h"
#include "weather.h"

namespace qqbot
{
Expand All @@ -23,6 +24,9 @@ namespace qqbot

//添加群组管理插件
this->addPlugin(std::make_shared<GroupOperator::GroupOperatorPlugin>());

//添加天气插件
this->addPlugin(std::make_shared<Weather::WeatherPlugin>());
}

void Register::run()
Expand Down

0 comments on commit 12d8ad4

Please sign in to comment.