mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-20 02:55:38 +08:00
feat.更新企鹅识别库4.2.2版本,新增对第十章磨难/普通的识别支持
This commit is contained in:
422
3rdparty/include/meojson/json.hpp
vendored
422
3rdparty/include/meojson/json.hpp
vendored
@@ -128,6 +128,30 @@ namespace json
|
||||
value& operator[](const std::string& key);
|
||||
value& operator[](std::string&& key);
|
||||
|
||||
value operator|(const object& rhs)&;
|
||||
value operator|(object&& rhs)&;
|
||||
value operator|(const object& rhs)&&;
|
||||
value operator|(object&& rhs)&&;
|
||||
|
||||
value& operator|=(const object& rhs);
|
||||
value& operator|=(object&& rhs);
|
||||
|
||||
//value operator&(const object& rhs)&;
|
||||
//value operator&(object&& rhs)&;
|
||||
//value operator&(const object& rhs)&&;
|
||||
//value operator&(object&& rhs)&&;
|
||||
|
||||
//value& operator&=(const object& rhs);
|
||||
//value& operator&=(object&& rhs);
|
||||
|
||||
value operator+(const array& rhs)&;
|
||||
value operator+(array&& rhs)&;
|
||||
value operator+(const array& rhs)&&;
|
||||
value operator+(array&& rhs)&&;
|
||||
|
||||
value& operator+=(const array& rhs);
|
||||
value& operator+=(array&& rhs);
|
||||
|
||||
explicit operator bool() const { return as_boolean(); }
|
||||
explicit operator int() const { return as_integer(); }
|
||||
explicit operator long() const { return as_long(); }
|
||||
@@ -141,14 +165,19 @@ namespace json
|
||||
|
||||
private:
|
||||
static var_t deep_copy(const var_t& src);
|
||||
|
||||
template <typename... KeysThenDefaultValue, size_t... KeysIndexes>
|
||||
decltype(auto) get(std::tuple<KeysThenDefaultValue...> keys_then_default_value, std::index_sequence<KeysIndexes...>) const;
|
||||
decltype(auto) get(
|
||||
std::tuple<KeysThenDefaultValue...> keys_then_default_value,
|
||||
std::index_sequence<KeysIndexes...>) const;
|
||||
|
||||
template <typename T, typename FirstKey, typename... RestKeys>
|
||||
decltype(auto) get_aux(T&& default_value, FirstKey&& first, RestKeys &&... rest) const;
|
||||
template <typename T, typename UniqueKey>
|
||||
decltype(auto) get_aux(T&& default_value, UniqueKey&& first) const;
|
||||
|
||||
const std::string& as_basic_type_str() const;
|
||||
std::string& as_basic_type_str();
|
||||
|
||||
value_type _type = value_type::Null;
|
||||
var_t _raw_data;
|
||||
@@ -164,6 +193,7 @@ namespace json
|
||||
{
|
||||
public:
|
||||
using raw_array = std::vector<value>;
|
||||
using value_type = raw_array::value_type;
|
||||
using iterator = raw_array::iterator;
|
||||
using const_iterator = raw_array::const_iterator;
|
||||
using reverse_iterator = raw_array::reverse_iterator;
|
||||
@@ -225,6 +255,14 @@ namespace json
|
||||
const value& operator[](size_t pos) const;
|
||||
value& operator[](size_t pos);
|
||||
|
||||
array operator+(const array& rhs)&;
|
||||
array operator+(array&& rhs)&;
|
||||
array operator+(const array& rhs)&&;
|
||||
array operator+(array&& rhs)&&;
|
||||
|
||||
array& operator+=(const array& rhs);
|
||||
array& operator+=(array&& rhs);
|
||||
|
||||
array& operator=(const array&) = default;
|
||||
array& operator=(array&&) noexcept = default;
|
||||
|
||||
@@ -243,13 +281,14 @@ namespace json
|
||||
{
|
||||
public:
|
||||
using raw_object = std::unordered_map<std::string, value>;
|
||||
using value_type = raw_object::value_type;
|
||||
using iterator = raw_object::iterator;
|
||||
using const_iterator = raw_object::const_iterator;
|
||||
|
||||
public:
|
||||
object() = default;
|
||||
object(const object& rhs) = default;
|
||||
object(object&& rhs) = default;
|
||||
object(object&& rhs) noexcept = default;
|
||||
object(const raw_object& raw_obj);
|
||||
object(raw_object&& raw_obj);
|
||||
object(std::initializer_list<raw_object::value_type> init_list);
|
||||
@@ -283,6 +322,7 @@ namespace json
|
||||
const value& get(const std::string& key) const;
|
||||
|
||||
template <typename... Args> decltype(auto) emplace(Args &&...args);
|
||||
template <typename... Args> decltype(auto) insert(Args &&...args);
|
||||
|
||||
void clear() noexcept;
|
||||
bool earse(const std::string& key);
|
||||
@@ -297,6 +337,22 @@ namespace json
|
||||
value& operator[](const std::string& key);
|
||||
value& operator[](std::string&& key);
|
||||
|
||||
object operator|(const object& rhs)&;
|
||||
object operator|(object&& rhs)&;
|
||||
object operator|(const object& rhs)&&;
|
||||
object operator|(object&& rhs)&&;
|
||||
|
||||
object& operator|=(const object& rhs);
|
||||
object& operator|=(object&& rhs);
|
||||
|
||||
//object operator&(const object& rhs)&;
|
||||
//object operator&(object&& rhs)&;
|
||||
//object operator&(const object& rhs)&&;
|
||||
//object operator&(object&& rhs)&&;
|
||||
|
||||
//object& operator&=(const object& rhs);
|
||||
//object& operator&=(object&& rhs);
|
||||
|
||||
object& operator=(const object&) = default;
|
||||
object& operator=(object&&) = default;
|
||||
|
||||
@@ -454,20 +510,12 @@ namespace json
|
||||
|
||||
MEOJSON_INLINE const value& value::at(size_t pos) const
|
||||
{
|
||||
if (is_array()) {
|
||||
return std::get<array_ptr>(_raw_data)->at(pos);
|
||||
}
|
||||
|
||||
throw exception("Wrong Type or data empty");
|
||||
return as_array().at(pos);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE const value& value::at(const std::string& key) const
|
||||
{
|
||||
if (is_object()) {
|
||||
return std::get<object_ptr>(_raw_data)->at(key);
|
||||
}
|
||||
|
||||
throw exception("Wrong Type or data empty");
|
||||
return as_object().at(key);
|
||||
}
|
||||
|
||||
template <typename... KeysThenDefaultValue>
|
||||
@@ -533,7 +581,7 @@ namespace json
|
||||
MEOJSON_INLINE bool value::as_boolean() const
|
||||
{
|
||||
if (is_boolean()) {
|
||||
if (std::string b_str = std::get<std::string>(_raw_data);
|
||||
if (const std::string& b_str = as_basic_type_str();
|
||||
b_str == "true") {
|
||||
return true;
|
||||
}
|
||||
@@ -552,7 +600,7 @@ namespace json
|
||||
MEOJSON_INLINE int value::as_integer() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stoi(std::get<std::string>(_raw_data));
|
||||
return std::stoi(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -574,7 +622,7 @@ namespace json
|
||||
MEOJSON_INLINE long value::as_long() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stol(std::get<std::string>(_raw_data));
|
||||
return std::stol(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -584,7 +632,7 @@ namespace json
|
||||
MEOJSON_INLINE unsigned long value::as_unsigned_long() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stoul(std::get<std::string>(_raw_data));
|
||||
return std::stoul(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -594,7 +642,7 @@ namespace json
|
||||
MEOJSON_INLINE long long value::as_long_long() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stoll(std::get<std::string>(_raw_data));
|
||||
return std::stoll(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -604,7 +652,7 @@ namespace json
|
||||
MEOJSON_INLINE unsigned long long value::as_unsigned_long_long() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stoull(std::get<std::string>(_raw_data));
|
||||
return std::stoull(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -614,7 +662,7 @@ namespace json
|
||||
MEOJSON_INLINE float value::as_float() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stof(std::get<std::string>(_raw_data));
|
||||
return std::stof(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -624,7 +672,7 @@ namespace json
|
||||
MEOJSON_INLINE double value::as_double() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stod(std::get<std::string>(_raw_data));
|
||||
return std::stod(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -634,7 +682,7 @@ namespace json
|
||||
MEOJSON_INLINE long double value::as_long_double() const
|
||||
{
|
||||
if (is_number()) {
|
||||
return std::stold(std::get<std::string>(_raw_data));
|
||||
return std::stold(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -644,7 +692,7 @@ namespace json
|
||||
MEOJSON_INLINE const std::string value::as_string() const
|
||||
{
|
||||
if (is_string()) {
|
||||
return escape_string(std::get<std::string>(_raw_data));
|
||||
return escape_string(as_basic_type_str());
|
||||
}
|
||||
else {
|
||||
throw exception("Wrong Type");
|
||||
@@ -671,11 +719,11 @@ namespace json
|
||||
|
||||
MEOJSON_INLINE array& value::as_array()
|
||||
{
|
||||
if (is_array()) {
|
||||
return *std::get<array_ptr>(_raw_data);
|
||||
}
|
||||
else if (empty()) {
|
||||
if (empty()) {
|
||||
*this = array();
|
||||
}
|
||||
|
||||
if (is_array()) {
|
||||
return *std::get<array_ptr>(_raw_data);
|
||||
}
|
||||
|
||||
@@ -684,17 +732,26 @@ namespace json
|
||||
|
||||
MEOJSON_INLINE object& value::as_object()
|
||||
{
|
||||
if (is_object()) {
|
||||
return *std::get<object_ptr>(_raw_data);
|
||||
}
|
||||
else if (empty()) {
|
||||
if (empty()) {
|
||||
*this = object();
|
||||
}
|
||||
|
||||
if (is_object()) {
|
||||
return *std::get<object_ptr>(_raw_data);
|
||||
}
|
||||
|
||||
throw exception("Wrong Type or data empty");
|
||||
}
|
||||
|
||||
MEOJSON_INLINE const std::string& value::as_basic_type_str() const
|
||||
{
|
||||
return std::get<std::string>(_raw_data);
|
||||
}
|
||||
MEOJSON_INLINE std::string& value::as_basic_type_str()
|
||||
{
|
||||
return std::get<std::string>(_raw_data);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
MEOJSON_INLINE decltype(auto) value::array_emplace(Args &&...args)
|
||||
{
|
||||
@@ -719,13 +776,13 @@ namespace json
|
||||
return "null";
|
||||
case value_type::Boolean:
|
||||
case value_type::Number:
|
||||
return std::get<std::string>(_raw_data);
|
||||
return as_basic_type_str();
|
||||
case value_type::String:
|
||||
return '"' + std::get<std::string>(_raw_data) + '"';
|
||||
return '"' + as_basic_type_str() + '"';
|
||||
case value_type::Array:
|
||||
return std::get<array_ptr>(_raw_data)->to_string();
|
||||
return as_array().to_string();
|
||||
case value_type::Object:
|
||||
return std::get<object_ptr>(_raw_data)->to_string();
|
||||
return as_object().to_string();
|
||||
default:
|
||||
throw exception("Unknown Value Type");
|
||||
}
|
||||
@@ -739,13 +796,13 @@ namespace json
|
||||
return "null";
|
||||
case value_type::Boolean:
|
||||
case value_type::Number:
|
||||
return std::get<std::string>(_raw_data);
|
||||
return as_basic_type_str();
|
||||
case value_type::String:
|
||||
return '"' + std::get<std::string>(_raw_data) + '"';
|
||||
return '"' + as_basic_type_str() + '"';
|
||||
case value_type::Array:
|
||||
return std::get<array_ptr>(_raw_data)->format(shift_str, basic_shift_count);
|
||||
return as_array().format(shift_str, basic_shift_count);
|
||||
case value_type::Object:
|
||||
return std::get<object_ptr>(_raw_data)->format(shift_str, basic_shift_count);
|
||||
return as_object().format(shift_str, basic_shift_count);
|
||||
default:
|
||||
throw exception("Unknown Value Type");
|
||||
}
|
||||
@@ -763,50 +820,130 @@ namespace json
|
||||
|
||||
MEOJSON_INLINE const value& value::operator[](size_t pos) const
|
||||
{
|
||||
if (is_array()) {
|
||||
return std::get<array_ptr>(_raw_data)->operator[](pos);
|
||||
}
|
||||
// Array not support to create by operator[]
|
||||
|
||||
throw exception("Wrong Type");
|
||||
return as_array()[pos];
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value& value::operator[](size_t pos)
|
||||
{
|
||||
if (is_array()) {
|
||||
return std::get<array_ptr>(_raw_data)->operator[](pos);
|
||||
}
|
||||
// Array not support to create by operator[]
|
||||
|
||||
throw exception("Wrong Type");
|
||||
return as_array()[pos];
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value& value::operator[](const std::string& key)
|
||||
{
|
||||
if (is_object()) {
|
||||
return std::get<object_ptr>(_raw_data)->operator[](key);
|
||||
}
|
||||
// Create a new value by operator[]
|
||||
else if (empty()) {
|
||||
if (empty()) {
|
||||
*this = object();
|
||||
return std::get<object_ptr>(_raw_data)->operator[](key);
|
||||
}
|
||||
|
||||
throw exception("Wrong Type");
|
||||
return as_object()[key];
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value& value::operator[](std::string&& key)
|
||||
{
|
||||
if (is_object()) {
|
||||
return std::get<object_ptr>(_raw_data)->operator[](key);
|
||||
}
|
||||
// Create a new value by operator[]
|
||||
else if (empty()) {
|
||||
if (empty()) {
|
||||
*this = object();
|
||||
return std::get<object_ptr>(_raw_data)->operator[](key);
|
||||
}
|
||||
|
||||
throw exception("Wrong Type");
|
||||
return as_object()[std::move(key)];
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value value::operator|(const object& rhs)&
|
||||
{
|
||||
return as_object() | rhs;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value value::operator|(object&& rhs)&
|
||||
{
|
||||
return as_object() | std::move(rhs);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value value::operator|(const object& rhs)&&
|
||||
{
|
||||
return std::move(as_object()) | rhs;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value value::operator|(object&& rhs)&&
|
||||
{
|
||||
return std::move(as_object()) | std::move(rhs);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value& value::operator|=(const object& rhs)
|
||||
{
|
||||
as_object() |= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value& value::operator|=(object&& rhs)
|
||||
{
|
||||
as_object() |= std::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//MEOJSON_INLINE value value::operator&(const object& rhs)&
|
||||
//{
|
||||
// return as_object() & rhs;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE value value::operator&(object&& rhs)&
|
||||
//{
|
||||
// return as_object() & std::move(rhs);
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE value value::operator&(const object& rhs)&&
|
||||
//{
|
||||
// return std::move(as_object()) & rhs;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE value value::operator&(object&& rhs)&&
|
||||
//{
|
||||
// return std::move(as_object()) & std::move(rhs);
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE value& value::operator&=(const object& rhs)
|
||||
//{
|
||||
// as_object() &= rhs;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE value& value::operator&=(object&& rhs)
|
||||
//{
|
||||
// as_object() &= std::move(rhs);
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
MEOJSON_INLINE value value::operator+(const array& rhs)&
|
||||
{
|
||||
return as_array() + rhs;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value value::operator+(array&& rhs)&
|
||||
{
|
||||
return as_array() + std::move(rhs);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value value::operator+(const array& rhs)&&
|
||||
{
|
||||
return std::move(as_array()) + rhs;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value value::operator+(array&& rhs)&&
|
||||
{
|
||||
return std::move(as_array()) + std::move(rhs);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value& value::operator+=(const array& rhs)
|
||||
{
|
||||
as_array() += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE value& value::operator+=(array&& rhs)
|
||||
{
|
||||
as_array() += std::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
@@ -885,10 +1022,9 @@ namespace json
|
||||
static_assert(
|
||||
std::is_constructible<json::value, typename ArrayType::value_type>::value,
|
||||
"Parameter can't be used to construct a json::value");
|
||||
_array_data.reserve(arr.size());
|
||||
for (auto&& ele : arr) {
|
||||
_array_data.emplace_back(std::move(ele));
|
||||
}
|
||||
_array_data.assign(
|
||||
std::make_move_iterator(arr.begin()),
|
||||
std::make_move_iterator(arr.end()));
|
||||
}
|
||||
|
||||
MEOJSON_INLINE const value& array::at(size_t pos) const
|
||||
@@ -1195,6 +1331,50 @@ namespace json
|
||||
return _array_data[pos];
|
||||
}
|
||||
|
||||
MEOJSON_INLINE array array::operator+(const array& rhs)&
|
||||
{
|
||||
array temp = *this;
|
||||
temp._array_data.insert(_array_data.end(), rhs.begin(), rhs.end());
|
||||
return temp;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE array array::operator+(array&& rhs)&
|
||||
{
|
||||
array temp = *this;
|
||||
temp._array_data.insert(_array_data.end(),
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return temp;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE array array::operator+(const array& rhs)&&
|
||||
{
|
||||
_array_data.insert(_array_data.end(), rhs.begin(), rhs.end());
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE array array::operator+(array&& rhs)&&
|
||||
{
|
||||
_array_data.insert(_array_data.end(),
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE array& array::operator+=(const array& rhs)
|
||||
{
|
||||
_array_data.insert(_array_data.end(), rhs.begin(), rhs.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE array& array::operator+=(array&& rhs)
|
||||
{
|
||||
_array_data.insert(_array_data.end(),
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// const raw_array &array::raw_data() const
|
||||
// {
|
||||
// return _array_data;
|
||||
@@ -1211,6 +1391,11 @@ namespace json
|
||||
return _object_data.emplace(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args> decltype(auto) object::insert(Args &&...args)
|
||||
{
|
||||
return _object_data.insert(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE std::ostream& operator<<(std::ostream& out, const array& arr)
|
||||
{
|
||||
// TODO: format output
|
||||
@@ -1528,6 +1713,108 @@ namespace json
|
||||
return _object_data[std::move(key)];
|
||||
}
|
||||
|
||||
MEOJSON_INLINE object object::operator|(const object& rhs)&
|
||||
{
|
||||
object temp = *this;
|
||||
temp._object_data.insert(rhs.begin(), rhs.end());
|
||||
return temp;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE object object::operator|(object&& rhs)&
|
||||
{
|
||||
object temp = *this;
|
||||
//temp._object_data.merge(std::move(rhs._object_data));
|
||||
temp._object_data.insert(
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return temp;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE object object::operator|(const object& rhs)&&
|
||||
{
|
||||
_object_data.insert(rhs.begin(), rhs.end());
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE object object::operator|(object&& rhs)&&
|
||||
{
|
||||
//_object_data.merge(std::move(rhs._object_data));
|
||||
_object_data.insert(
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
MEOJSON_INLINE object& object::operator|=(const object& rhs)
|
||||
{
|
||||
_object_data.insert(rhs.begin(), rhs.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
MEOJSON_INLINE object& object::operator|=(object&& rhs)
|
||||
{
|
||||
_object_data.insert(
|
||||
std::make_move_iterator(rhs.begin()),
|
||||
std::make_move_iterator(rhs.end()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//MEOJSON_INLINE object object::operator&(const object& rhs)&
|
||||
//{
|
||||
// object temp;
|
||||
// for (const auto& [key, value] : *this) {
|
||||
// if (rhs.contains(key)) {
|
||||
// temp.emplace(key, value);
|
||||
// }
|
||||
// }
|
||||
// return temp;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE object object::operator&(object&& rhs)&
|
||||
//{
|
||||
// object temp;
|
||||
// for (const auto& [key, value] : *this) {
|
||||
// if (rhs.contains(key)) {
|
||||
// temp.emplace(key, value);
|
||||
// }
|
||||
// }
|
||||
// return temp;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE object object::operator&(const object& rhs)&&
|
||||
//{
|
||||
// object temp;
|
||||
// for (auto&& [key, value] : *this) {
|
||||
// if (rhs.contains(key)) {
|
||||
// temp.emplace(key, std::move(value));
|
||||
// }
|
||||
// }
|
||||
// return temp;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE object object::operator&(object&& rhs)&&
|
||||
//{
|
||||
// object temp;
|
||||
// for (auto&& [key, value] : *this) {
|
||||
// if (rhs.contains(key)) {
|
||||
// temp.emplace(key, std::move(value));
|
||||
// }
|
||||
// }
|
||||
// return temp;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE object& object::operator&=(const object& rhs)
|
||||
//{
|
||||
// *this = std::move(*this) & rhs;
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
//MEOJSON_INLINE object& object::operator&=(object&& rhs)
|
||||
//{
|
||||
// *this = std::move(*this) & std::move(rhs);
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
// const raw_object &object::raw_data() const
|
||||
// {
|
||||
// return _object_data;
|
||||
@@ -1547,10 +1834,9 @@ namespace json
|
||||
typename MapType::value_type>::value,
|
||||
"Parameter can't be used to construct a "
|
||||
"object::raw_object::value_type");
|
||||
_object_data.reserve(map.size());
|
||||
for (auto&& ele : map) {
|
||||
_object_data.emplace(std::move(ele));
|
||||
}
|
||||
_object_data.insert(
|
||||
std::make_move_iterator(map.begin()),
|
||||
std::make_move_iterator(map.end()));
|
||||
}
|
||||
|
||||
// *************************
|
||||
|
||||
@@ -61,11 +61,11 @@ public:
|
||||
static Resource instance;
|
||||
return instance;
|
||||
}
|
||||
void add(std::string key, std::any src)
|
||||
void add(const std::string& key, const std::any& src)
|
||||
{
|
||||
if (!key.empty())
|
||||
{
|
||||
_resource[std::move(key)] = std::move(src);
|
||||
_resource.insert_or_assign(key, src);
|
||||
}
|
||||
}
|
||||
template <typename ResourceType>
|
||||
|
||||
@@ -16,6 +16,7 @@ using dict = nlohmann::ordered_json;
|
||||
|
||||
namespace penguin
|
||||
{
|
||||
|
||||
enum CircleFlags
|
||||
{
|
||||
X = 0,
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
_get_item_list();
|
||||
return *this;
|
||||
}
|
||||
const dict report([[maybe_unused]] bool debug = false)
|
||||
const dict report(bool debug = false)
|
||||
{
|
||||
dict _report = dict::object();
|
||||
return _report;
|
||||
@@ -112,7 +113,7 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
_item_diameter = static_cast<int>(round(cv::mean(item_circles)[R] * 2));
|
||||
_item_diameter = round(cv::mean(item_circles)[R] * 2);
|
||||
|
||||
for (const cv::Vec3i& c : item_circles)
|
||||
{
|
||||
@@ -127,7 +128,7 @@ private:
|
||||
// show_img(img_blur);
|
||||
|
||||
int radius = _item_diameter / 2;
|
||||
int offset = static_cast<int>(radius * 1.2);
|
||||
int offset = radius * 1.2;
|
||||
ItemTemplates templs;
|
||||
for (const cv::Vec3i& c : item_circles)
|
||||
{
|
||||
@@ -156,6 +157,7 @@ private:
|
||||
// show_img(_img_ext);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace penguin
|
||||
|
||||
#endif // PENGUIN_DEPOT_HPP_
|
||||
|
||||
@@ -15,6 +15,7 @@ using dict = nlohmann::ordered_json;
|
||||
|
||||
namespace penguin
|
||||
{
|
||||
|
||||
enum class StatusFlags
|
||||
{
|
||||
NORMAL = 0,
|
||||
@@ -162,10 +163,10 @@ public:
|
||||
_templ_list.emplace_back(templ);
|
||||
}
|
||||
}
|
||||
ItemTemplates(const std::string stage_code)
|
||||
ItemTemplates(const std::string& stage_code, const std::string& difficulty = "NORMAL")
|
||||
{
|
||||
const auto& stage_drop =
|
||||
resource.get<dict>("stage_index")[stage_code]["drops"];
|
||||
resource.get<dict>("stage_index")[stage_code][difficulty]["drops"];
|
||||
const auto& item_templs =
|
||||
resource.get<std::map<std::string, cv::Mat>>("item_templs");
|
||||
for (const auto& [_, itemId] : stage_drop.items())
|
||||
@@ -822,8 +823,8 @@ private:
|
||||
topleft_new.x *= coeff_multiinv;
|
||||
topleft_new.y *= coeff_multiinv;
|
||||
cv::Size size_new = cv::Size(
|
||||
static_cast<int>(round(TEMPLATE_WIDTH * ((double)_diameter / TEMPLATE_DIAMETER))),
|
||||
static_cast<int>(round(TEMPLATE_HEIGHT * ((double)_diameter / TEMPLATE_DIAMETER))));
|
||||
round(TEMPLATE_WIDTH * ((double)_diameter / TEMPLATE_DIAMETER)),
|
||||
round(TEMPLATE_HEIGHT * ((double)_diameter / TEMPLATE_DIAMETER)));
|
||||
if (topleft_new.x + size_new.width > width)
|
||||
{
|
||||
size_new.width = width - topleft_new.x;
|
||||
@@ -842,9 +843,9 @@ private:
|
||||
}
|
||||
void _get_quantity()
|
||||
{
|
||||
cv::Rect quantityrect = cv::Rect(0, static_cast<int>(round(height * _ITEM_QTY_Y_PROP)),
|
||||
static_cast<int>(round(width * _ITEM_QTY_WIDTH_PROP)),
|
||||
static_cast<int>(round(height * _ITEM_QTY_HEIGHT_PROP)));
|
||||
cv::Rect quantityrect = cv::Rect(0, round(height * _ITEM_QTY_Y_PROP),
|
||||
round(width * _ITEM_QTY_WIDTH_PROP),
|
||||
round(height * _ITEM_QTY_HEIGHT_PROP));
|
||||
cv::Mat quantityimg = _img(quantityrect);
|
||||
_quantity.set_img(quantityimg);
|
||||
_quantity.analyze();
|
||||
|
||||
@@ -18,25 +18,19 @@
|
||||
#include "depot.hpp"
|
||||
#include "result.hpp"
|
||||
|
||||
static const std::string version = "4.1.1";
|
||||
static const std::string version = "4.2.2";
|
||||
static const std::string opencv_version = CV_VERSION;
|
||||
|
||||
cv::Mat decode(std::string JSarrayBuffer)
|
||||
{
|
||||
std::vector buf(std::make_move_iterator(JSarrayBuffer.begin()),
|
||||
std::make_move_iterator(JSarrayBuffer.end()));
|
||||
return cv::imdecode(buf, cv::IMREAD_COLOR);
|
||||
}
|
||||
|
||||
cv::Mat decode(uint8_t* buffer, size_t size)
|
||||
{
|
||||
std::vector buf(buffer, buffer + size);
|
||||
std::vector<uint8_t> buf(std::make_move_iterator(JSarrayBuffer.begin()),
|
||||
std::make_move_iterator(JSarrayBuffer.end()));
|
||||
return cv::imdecode(buf, cv::IMREAD_COLOR);
|
||||
}
|
||||
|
||||
void load_server(std::string server)
|
||||
{
|
||||
penguin::server = std::move(server);
|
||||
penguin::server = server;
|
||||
}
|
||||
|
||||
void load_stage_index() // local
|
||||
@@ -44,14 +38,13 @@ void load_stage_index() // local
|
||||
dict stage_index;
|
||||
std::ifstream f("../resources/json/stage_index.json");
|
||||
f >> stage_index;
|
||||
f.close();
|
||||
penguin::resource.add("stage_index", std::move(stage_index));
|
||||
penguin::resource.add("stage_index", stage_index);
|
||||
}
|
||||
|
||||
void wload_stage_index(std::string stage_index) // wasm
|
||||
{
|
||||
auto& resource = penguin::resource;
|
||||
resource.add("stage_index", dict::parse(std::move(stage_index)));
|
||||
resource.add("stage_index", dict::parse(stage_index));
|
||||
}
|
||||
|
||||
void load_hash_index() // local
|
||||
@@ -59,14 +52,13 @@ void load_hash_index() // local
|
||||
dict hash_index;
|
||||
std::ifstream f("../resources/json/hash_index.json");
|
||||
f >> hash_index;
|
||||
f.close();
|
||||
penguin::resource.add("hash_index", std::move(hash_index));
|
||||
penguin::resource.add("hash_index", hash_index);
|
||||
}
|
||||
|
||||
void wload_hash_index(std::string hash_index) // wasm
|
||||
{
|
||||
auto& resource = penguin::resource;
|
||||
resource.add("hash_index", dict::parse(std::move(hash_index)));
|
||||
resource.add("hash_index", dict::parse(hash_index));
|
||||
}
|
||||
|
||||
void load_templs() // local
|
||||
@@ -77,9 +69,9 @@ void load_templs() // local
|
||||
{
|
||||
std::string itemId = templ.path().stem().string();
|
||||
cv::Mat templimg = cv::imread(templ.path().string());
|
||||
item_templs[std::move(itemId)] = templimg; // cv::Mat is a shallow copy
|
||||
item_templs.insert_or_assign(itemId, templimg);
|
||||
}
|
||||
penguin::resource.add("item_templs", std::move(item_templs));
|
||||
penguin::resource.add("item_templs", item_templs);
|
||||
}
|
||||
|
||||
void wload_templs(std::string itemId, std::string JSarrayBuffer) // wasm
|
||||
@@ -91,7 +83,7 @@ void wload_templs(std::string itemId, std::string JSarrayBuffer) // wasm
|
||||
}
|
||||
auto& item_templs =
|
||||
resource.get<std::map<std::string, cv::Mat>>("item_templs");
|
||||
item_templs[std::move(itemId)] = decode(std::move(JSarrayBuffer));
|
||||
item_templs.insert_or_assign(itemId, decode(std::move(JSarrayBuffer)));
|
||||
}
|
||||
|
||||
const bool env_check()
|
||||
@@ -103,9 +95,7 @@ class Recognizer
|
||||
{
|
||||
public:
|
||||
Recognizer(std::string mode)
|
||||
: _mode(std::move(mode))
|
||||
{
|
||||
}
|
||||
: _mode(mode) {}
|
||||
|
||||
dict recognize(cv::Mat img, bool detail = false)
|
||||
{
|
||||
@@ -115,7 +105,7 @@ public:
|
||||
}
|
||||
std::string wrecognize(std::string JSarrayBuffer, bool detail, bool pretty_print)
|
||||
{
|
||||
_wset_img(std::move(JSarrayBuffer));
|
||||
_wset_img(JSarrayBuffer);
|
||||
_recognize();
|
||||
return _wget_report(detail, pretty_print);
|
||||
}
|
||||
|
||||
317
3rdparty/include/penguin-stats-recognize/result.hpp
vendored
317
3rdparty/include/penguin-stats-recognize/result.hpp
vendored
@@ -14,7 +14,7 @@
|
||||
#include "recognize.hpp"
|
||||
|
||||
using dict = nlohmann::ordered_json;
|
||||
// extern void show_img(cv::Mat src);
|
||||
extern void show_img(cv::Mat src);
|
||||
|
||||
namespace penguin
|
||||
{ // result
|
||||
@@ -123,13 +123,13 @@ private:
|
||||
void _get_is_result()
|
||||
{
|
||||
auto& self = *this;
|
||||
auto resultrect = cv::boundingRect(_img);
|
||||
self._relate(resultrect.tl());
|
||||
if (resultrect.empty())
|
||||
auto result_rect = cv::boundingRect(_img);
|
||||
self._relate(result_rect.tl());
|
||||
if (result_rect.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_img = _img(resultrect);
|
||||
_img = _img(result_rect);
|
||||
auto result_img = _img;
|
||||
_hash = shash(result_img, ResizeFlags::RESIZE_W32_H8);
|
||||
std::string hash_std =
|
||||
@@ -146,6 +146,90 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class Widget_Stars : public Widget
|
||||
{
|
||||
public:
|
||||
const bool is_3stars() const { return _stars == 3; }
|
||||
Widget_Stars() = default;
|
||||
Widget_Stars(Widget* const parent_widget)
|
||||
: Widget("stars", parent_widget) {}
|
||||
Widget_Stars(const cv::Mat& img, Widget* const parent_widget = nullptr)
|
||||
: Widget("stars", parent_widget)
|
||||
{
|
||||
set_img(img);
|
||||
}
|
||||
void set_img(const cv::Mat& img)
|
||||
{
|
||||
Widget::set_img(img);
|
||||
if (_img.channels() == 3)
|
||||
{
|
||||
cv::cvtColor(_img, _img, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(_img, _img, 127, 255, cv::THRESH_BINARY);
|
||||
}
|
||||
}
|
||||
Widget_Stars& analyze()
|
||||
{
|
||||
if (!_img.empty())
|
||||
{
|
||||
_get_is_3stars();
|
||||
}
|
||||
if (_stars != 3)
|
||||
{
|
||||
push_exception(ERROR, ExcSubtypeFlags::EXC_FALSE);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
const dict report(bool debug = false)
|
||||
{
|
||||
dict rpt = dict::object();
|
||||
rpt.merge_patch(Widget::report(debug));
|
||||
if (!debug)
|
||||
{
|
||||
rpt["count"] = _stars;
|
||||
}
|
||||
else
|
||||
{
|
||||
rpt["count"] = _stars;
|
||||
}
|
||||
return rpt;
|
||||
}
|
||||
|
||||
private:
|
||||
int _stars = 0;
|
||||
void _get_is_3stars()
|
||||
{
|
||||
auto& self = *this;
|
||||
auto star_img = _img;
|
||||
auto sp_ = separate(star_img, DirectionFlags::RIGHT, 1);
|
||||
auto laststar_range = separate(star_img, DirectionFlags::RIGHT, 1)[0];
|
||||
auto laststar = star_img(cv::Range(0, height), laststar_range);
|
||||
auto star_rect = cv::boundingRect(laststar);
|
||||
if (star_rect.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto sp = separate(star_img(cv::Rect(0, 0, width, height / 2)), DirectionFlags::LEFT);
|
||||
for (auto it = sp.cbegin(); it != sp.cend();)
|
||||
{
|
||||
const auto& range = *it;
|
||||
if (const auto length = range.end - range.start;
|
||||
length < height * STAR_WIDTH_PROP)
|
||||
{
|
||||
it = sp.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
star_rect.x = sp.front().start;
|
||||
star_rect.width = sp.back().end - star_rect.x;
|
||||
_img = star_img = star_img(star_rect);
|
||||
self._relate(star_rect.tl());
|
||||
_stars = sp.size();
|
||||
}
|
||||
};
|
||||
|
||||
class Widget_Stage : public WidgetWithCandidate<std::vector<int>, int>
|
||||
{
|
||||
public:
|
||||
@@ -181,7 +265,7 @@ public:
|
||||
push_exception(ERROR, ExcSubtypeFlags::EXC_NOTFOUND);
|
||||
}
|
||||
else if (const auto& stage_index = resource.get<dict>("stage_index");
|
||||
stage_index[_stage_code()]["existence"] == false)
|
||||
stage_index[_stage_code()][_difficulty]["existence"] == false)
|
||||
{
|
||||
push_exception(ERROR, ExcSubtypeFlags::EXC_ILLEGAL);
|
||||
}
|
||||
@@ -229,10 +313,16 @@ public:
|
||||
}
|
||||
return rpt;
|
||||
}
|
||||
// for temporary workaround
|
||||
void _set_difficulty(const std::string& difficulty)
|
||||
{
|
||||
_difficulty = difficulty;
|
||||
}
|
||||
|
||||
private:
|
||||
const int _CANDIDATES_COUNT = 5;
|
||||
bool _existance = false;
|
||||
std::string _difficulty = "NORMAL"; // for temporary workaround
|
||||
std::vector<Widget_Character> _stage_chrs;
|
||||
const std::string _stage_code() const
|
||||
{
|
||||
@@ -260,7 +350,7 @@ private:
|
||||
if (const auto& stage_index = resource.get<dict>("stage_index");
|
||||
stage_index.contains(stage_code))
|
||||
{
|
||||
return (std::string)stage_index[stage_code]["stageId"];
|
||||
return (std::string)stage_index[stage_code][_difficulty]["stageId"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -359,36 +449,31 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class Widget_Stars : public Widget
|
||||
class Widget_Difficulty : public Widget
|
||||
{
|
||||
public:
|
||||
const bool is_3stars() const { return _stars == 3; }
|
||||
Widget_Stars() = default;
|
||||
Widget_Stars(Widget* const parent_widget)
|
||||
: Widget("stars", parent_widget) {}
|
||||
Widget_Stars(const cv::Mat& img, Widget* const parent_widget = nullptr)
|
||||
: Widget("stars", parent_widget)
|
||||
const std::string difficulty() const { return _difficulty; }
|
||||
Widget_Difficulty() = default;
|
||||
Widget_Difficulty(Widget* const parent_widget)
|
||||
: Widget("difficulty", parent_widget) {}
|
||||
Widget_Difficulty(const cv::Mat& img, Widget* const parent_widget = nullptr)
|
||||
: Widget("difficulty", parent_widget)
|
||||
{
|
||||
set_img(img);
|
||||
}
|
||||
void set_img(const cv::Mat& img)
|
||||
{
|
||||
Widget::set_img(img);
|
||||
if (_img.channels() == 3)
|
||||
{
|
||||
cv::cvtColor(_img, _img, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(_img, _img, 127, 255, cv::THRESH_BINARY);
|
||||
}
|
||||
}
|
||||
Widget_Stars& analyze()
|
||||
Widget_Difficulty& analyze()
|
||||
{
|
||||
if (!_img.empty())
|
||||
{
|
||||
_get_is_3stars();
|
||||
_get_difficulty();
|
||||
}
|
||||
if (_stars != 3)
|
||||
if (_difficulty.empty())
|
||||
{
|
||||
push_exception(ERROR, ExcSubtypeFlags::EXC_FALSE);
|
||||
push_exception(ERROR, ExcSubtypeFlags::EXC_ILLEGAL);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -398,48 +483,59 @@ public:
|
||||
rpt.merge_patch(Widget::report(debug));
|
||||
if (!debug)
|
||||
{
|
||||
rpt["count"] = _stars;
|
||||
rpt["difficulty"] = _difficulty;
|
||||
}
|
||||
else
|
||||
{
|
||||
rpt["count"] = _stars;
|
||||
rpt["difficulty"] = _difficulty;
|
||||
}
|
||||
return rpt;
|
||||
}
|
||||
|
||||
private:
|
||||
int _stars = 0;
|
||||
void _get_is_3stars()
|
||||
std::string _difficulty;
|
||||
void _get_difficulty()
|
||||
{
|
||||
auto& self = *this;
|
||||
auto star_img = _img;
|
||||
auto sp_ = separate(star_img, DirectionFlags::RIGHT, 1);
|
||||
auto laststar_range = separate(star_img, DirectionFlags::RIGHT, 1)[0];
|
||||
auto laststar = star_img(cv::Range(0, height), laststar_range);
|
||||
auto starrect = cv::boundingRect(laststar);
|
||||
if (starrect.empty())
|
||||
auto img_bin = _img;
|
||||
cv::cvtColor(img_bin, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 25, 255, cv::THRESH_BINARY);
|
||||
auto diff_rect = cv::boundingRect(img_bin);
|
||||
if (diff_rect.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto sp = separate(star_img(cv::Rect(0, 0, width, height / 2)), DirectionFlags::LEFT);
|
||||
for (auto it = sp.cbegin(); it != sp.cend();)
|
||||
_img = _img(diff_rect);
|
||||
auto& self = *this;
|
||||
self._relate(diff_rect.tl());
|
||||
|
||||
int diff_count = 0;
|
||||
|
||||
if (!(height < width / 4))
|
||||
{
|
||||
const auto& range = *it;
|
||||
if (auto length = range.end - range.start;
|
||||
length < height * STAR_WIDTH_PROP)
|
||||
{
|
||||
it = sp.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
img_bin = _img;
|
||||
cv::cvtColor(img_bin, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 200, 255, cv::THRESH_BINARY);
|
||||
int inspction_line = 0.8 * cv::boundingRect(img_bin).y;
|
||||
|
||||
img_bin = _img;
|
||||
cv::cvtColor(img_bin, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 64, 255, cv::THRESH_BINARY);
|
||||
auto diff_img = img_bin(cv::Rect(0, inspction_line, width, 1));
|
||||
diff_count = separate(diff_img, DirectionFlags::LEFT).size();
|
||||
}
|
||||
|
||||
switch (diff_count)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
_difficulty = "NORMAL";
|
||||
break;
|
||||
case 3:
|
||||
_difficulty = "TOUGH";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
starrect.x = sp.front().start;
|
||||
starrect.width = sp.back().end - starrect.x;
|
||||
_img = star_img = star_img(starrect);
|
||||
self._relate(starrect.tl());
|
||||
_stars = static_cast<int>(sp.size());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -506,7 +602,7 @@ private:
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int dist = static_cast<int>(abs(kh - hsv[H]));
|
||||
int dist = abs(kh - hsv[H]);
|
||||
_candidates.emplace_back(vtype, dist);
|
||||
}
|
||||
std::sort(_candidates.begin(), _candidates.end(),
|
||||
@@ -616,7 +712,7 @@ private:
|
||||
while (droptextimg.rows > 0)
|
||||
{
|
||||
cv::Mat topline = droptextimg.row(0);
|
||||
int meanval = static_cast<int>(cv::mean(topline)[0]);
|
||||
int meanval = cv::mean(topline)[0];
|
||||
if (meanval < 127)
|
||||
{
|
||||
break;
|
||||
@@ -627,13 +723,13 @@ private:
|
||||
self.y++;
|
||||
}
|
||||
}
|
||||
auto droptextrect = cv::boundingRect(droptextimg);
|
||||
if (droptextrect.empty())
|
||||
auto droptext_rect = cv::boundingRect(droptextimg);
|
||||
if (droptext_rect.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
droptextimg = droptextimg(droptextrect);
|
||||
self._relate(droptextrect.tl());
|
||||
droptextimg = droptextimg(droptext_rect);
|
||||
self._relate(droptext_rect.tl());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -684,7 +780,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
int _items_count = static_cast<int>(round(width / (height * W_H_PROP)));
|
||||
int _items_count = round(width / (height * W_H_PROP));
|
||||
Widget_DroptypeLine _line {this};
|
||||
Widget_DroptypeText _text {this};
|
||||
void _get_candidates()
|
||||
@@ -719,9 +815,10 @@ public:
|
||||
Widget_DropArea() = default;
|
||||
Widget_DropArea(Widget* const parent_widget)
|
||||
: Widget("dropArea", parent_widget) {}
|
||||
Widget_DropArea(const cv::Mat& img, [[maybe_unused]] const std::string& stage, Widget* const parent_widget = nullptr)
|
||||
Widget_DropArea(const cv::Mat& img, Widget* const parent_widget = nullptr)
|
||||
: Widget(img, "dropArea", parent_widget) {}
|
||||
Widget_DropArea& analyze(const std::string& stage)
|
||||
Widget_DropArea& analyze(const std::string& stage,
|
||||
const std::string& difficulty)
|
||||
{
|
||||
if (!_img.empty())
|
||||
{
|
||||
@@ -742,7 +839,7 @@ public:
|
||||
widget_label = "droptypes";
|
||||
push_exception(ERROR, ExcSubtypeFlags::EXC_ILLEGAL);
|
||||
}
|
||||
_get_drops(stage);
|
||||
_get_drops(stage, difficulty);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -762,13 +859,13 @@ public:
|
||||
rpt["dropTypes"] = dict::array();
|
||||
rpt["drops"] = dict::array();
|
||||
|
||||
size_t droptypes_count = _droptype_list.size(); // will move in "for" in C++20
|
||||
for (size_t i = 0; i < droptypes_count; i++)
|
||||
int droptypes_count = _droptype_list.size(); // will move in "for" in C++20
|
||||
for (int i = 0; i < droptypes_count; i++)
|
||||
{
|
||||
rpt["dropTypes"].push_back(_droptype_list[i].report(debug));
|
||||
}
|
||||
size_t drops_count = _drop_list.size(); // will move in "for" in C++20
|
||||
for (size_t i = 0; i < drops_count; i++)
|
||||
int drops_count = _drop_list.size(); // will move in "for" in C++20
|
||||
for (int i = 0; i < drops_count; i++)
|
||||
{
|
||||
rpt["drops"].push_back(
|
||||
{{"dropType", Droptype2Str[_drop_list[i].droptype]}});
|
||||
@@ -785,7 +882,7 @@ private:
|
||||
auto _get_separate()
|
||||
{
|
||||
cv::Mat img_bin = _img;
|
||||
int offset = static_cast<int>(round(height * 0.75));
|
||||
int offset = round(height * 0.75);
|
||||
img_bin.adjustROI(-offset, 0, 0, 0);
|
||||
cv::cvtColor(img_bin, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::adaptiveThreshold(img_bin, img_bin, 255, cv::ADAPTIVE_THRESH_MEAN_C,
|
||||
@@ -814,11 +911,12 @@ private:
|
||||
}
|
||||
int baseline_h = row + offset;
|
||||
auto sp = separate(img_bin(cv::Rect(0, row, width, 1)), DirectionFlags::LEFT);
|
||||
int item_diameter = static_cast<int>(height / DROP_AREA_HEIGHT_PROP * ITEM_DIAMETER_PROP);
|
||||
int item_diameter = height / DROP_AREA_HEIGHT_PROP * ITEM_DIAMETER_PROP;
|
||||
for (auto it = sp.cbegin(); it != sp.cend();)
|
||||
{
|
||||
const auto& range = *it;
|
||||
if (auto length = range.end - range.start; length < item_diameter)
|
||||
if (const auto length = range.end - range.start;
|
||||
length < item_diameter)
|
||||
{
|
||||
it = sp.erase(it);
|
||||
}
|
||||
@@ -887,13 +985,13 @@ private:
|
||||
_droptype_list = q.top();
|
||||
}
|
||||
|
||||
void _get_drops(std::string stage)
|
||||
void _get_drops(const std::string& stage, const std::string& difficulty)
|
||||
{
|
||||
if (_status == StatusFlags::HAS_ERROR || _status == StatusFlags::ERROR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int item_diameter = static_cast<int>(height / DROP_AREA_HEIGHT_PROP * ITEM_DIAMETER_PROP);
|
||||
int item_diameter = height / DROP_AREA_HEIGHT_PROP * ITEM_DIAMETER_PROP;
|
||||
ItemTemplates templs {stage};
|
||||
for (const auto& droptype : _droptype_list)
|
||||
{
|
||||
@@ -926,13 +1024,13 @@ private:
|
||||
int length = (droptype.width) / items_count;
|
||||
for (int i = 0; i < items_count; i++)
|
||||
{
|
||||
std::string cur_label =
|
||||
std::string label =
|
||||
"drops." + std::to_string(_drop_list.size());
|
||||
auto range =
|
||||
cv::Range(droptype.x - x + length * i,
|
||||
droptype.x - x + length * (i + 1));
|
||||
auto dropimg = _img(cv::Range(0, droptype.y - y), range);
|
||||
Widget_Item drop {dropimg, item_diameter, cur_label, this};
|
||||
Widget_Item drop {dropimg, item_diameter, label, this};
|
||||
drop.analyze(templs);
|
||||
_drop_list.emplace_back(drop, type);
|
||||
_drops_data.push_back({{"dropType", Droptype2Str[type]},
|
||||
@@ -1108,10 +1206,10 @@ private:
|
||||
}
|
||||
const auto& bv = _baseline_v;
|
||||
auto drop_area_img = _img(
|
||||
cv::Range(static_cast<int>(bv.y + bv.height * DROP_AREA_Y_PROP), bv.y + bv.height),
|
||||
cv::Range(static_cast<int>(bv.x + bv.height * DROP_AREA_X_PROP), width));
|
||||
cv::Range(bv.y + bv.height * DROP_AREA_Y_PROP, bv.y + bv.height),
|
||||
cv::Range(bv.x + bv.height * DROP_AREA_X_PROP, width));
|
||||
_drop_area.set_img(drop_area_img);
|
||||
_drop_area.analyze(_stage.stage_code());
|
||||
_drop_area.analyze(_stage.stage_code(), "NORMAL");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1127,6 +1225,8 @@ public:
|
||||
_get_result_label();
|
||||
_get_stars();
|
||||
_get_stage();
|
||||
_get_difficulty();
|
||||
_stage._set_difficulty(_difficutly.difficulty());
|
||||
_get_drop_area();
|
||||
return *this;
|
||||
}
|
||||
@@ -1146,6 +1246,7 @@ public:
|
||||
{
|
||||
rpt["resultLabel"] = _result_label.report()["isResult"];
|
||||
rpt["stage"] = _stage.report();
|
||||
rpt["difficulty"] = _difficutly.report()["difficulty"];
|
||||
rpt["stars"] = _stars.report()["count"];
|
||||
rpt["dropArea"] = _drop_area.report();
|
||||
}
|
||||
@@ -1153,6 +1254,7 @@ public:
|
||||
{
|
||||
rpt["resultLabel"] = _result_label.report(debug);
|
||||
rpt["stage"] = _stage.report(debug);
|
||||
rpt["difficulty"] = _difficutly.report(debug);
|
||||
rpt["stars"] = _stars.report(debug);
|
||||
rpt["dropArea"] = _drop_area.report(debug);
|
||||
}
|
||||
@@ -1161,8 +1263,9 @@ public:
|
||||
|
||||
private:
|
||||
Widget _baseline_v {this};
|
||||
Widget_Stage _stage {this};
|
||||
Widget_Stars _stars {this};
|
||||
Widget_Stage _stage {this};
|
||||
Widget_Difficulty _difficutly {this};
|
||||
Widget_ResultLabel _result_label {this};
|
||||
Widget_DropArea _drop_area {this};
|
||||
|
||||
@@ -1172,11 +1275,7 @@ private:
|
||||
{
|
||||
return;
|
||||
}
|
||||
cv::Mat img_bin = _img(cv::Rect(
|
||||
0,
|
||||
static_cast<int>(0.2 * height),
|
||||
static_cast<int>(0.2 * width),
|
||||
static_cast<int>(0.4 * height)));
|
||||
cv::Mat img_bin = _img(cv::Rect(0, 0.2 * height, 0.2 * width, 0.4 * height));
|
||||
cv::cvtColor(img_bin, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 120, 255, cv::THRESH_BINARY);
|
||||
|
||||
@@ -1192,7 +1291,7 @@ private:
|
||||
abs(img_temp.cols - last_height) <= 1 &&
|
||||
abs(first_height - last_height) <= 1)
|
||||
{
|
||||
baseline_v_rect = cv::Rect(range.start, sp2.front().start + static_cast<int>(0.2 * height),
|
||||
baseline_v_rect = cv::Rect(range.start, sp2.front().start + 0.2 * height,
|
||||
img_temp.cols, sp2.back().end - sp2.front().start);
|
||||
break;
|
||||
}
|
||||
@@ -1219,11 +1318,7 @@ private:
|
||||
: x(x_), y(y_), width(width_), height(height_), area(area_) {}
|
||||
};
|
||||
|
||||
cv::Mat img_bin = _img(cv::Rect(
|
||||
0,
|
||||
static_cast<int>(0.2 * height),
|
||||
static_cast<int>(0.2 * width),
|
||||
static_cast<int>(0.4 * height)));
|
||||
cv::Mat img_bin = _img(cv::Rect(0, 0.2 * height, 0.2 * width, 0.4 * height));
|
||||
cv::cvtColor(img_bin, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 120, 255, cv::THRESH_BINARY);
|
||||
cv::Mat _;
|
||||
@@ -1265,7 +1360,7 @@ private:
|
||||
if (ccomps[0].x == ccomps[1].x)
|
||||
{
|
||||
baseline_v_rect = cv::Rect(ccomps[0].x,
|
||||
ccomps[0].y + static_cast<int>(0.2 * height),
|
||||
ccomps[0].y + 0.2 * height,
|
||||
ccomps[0].width,
|
||||
ccomps[1].y - ccomps[0].y + ccomps[1].height);
|
||||
}
|
||||
@@ -1277,7 +1372,7 @@ private:
|
||||
{
|
||||
if (ccomps[i].x == ccomps[i + 1].x)
|
||||
baseline_v_rect = cv::Rect(ccomps[i].x,
|
||||
ccomps[i].y + static_cast<int>(0.2 * height),
|
||||
ccomps[i].y + 0.2 * height,
|
||||
ccomps[i].width,
|
||||
ccomps[i + 1].y - ccomps[i].y + ccomps[i + 1].height);
|
||||
}
|
||||
@@ -1302,8 +1397,9 @@ private:
|
||||
return;
|
||||
}
|
||||
const auto& bv = _baseline_v;
|
||||
auto result_img = _img(cv::Rect(bv.x + bv.width, bv.y,
|
||||
static_cast<int>(1.6 * bv.height), bv.height));
|
||||
int left_margin = bv.x + bv.width;
|
||||
auto result_img = _img(cv::Range(bv.y, bv.y + bv.height / 2),
|
||||
cv::Range(left_margin, left_margin + 1.5 * bv.height));
|
||||
cv::Mat img_bin;
|
||||
cv::cvtColor(result_img, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 200, 255, cv::THRESH_BINARY);
|
||||
@@ -1319,8 +1415,9 @@ private:
|
||||
return;
|
||||
}
|
||||
const auto& bv = _baseline_v;
|
||||
auto star_img = _img(cv::Rect(bv.x + bv.width, bv.y,
|
||||
static_cast<int>(1.2 * bv.height), bv.height));
|
||||
int left_margin = bv.x + bv.width;
|
||||
auto star_img = _img(cv::Range(bv.y + bv.height / 2, bv.y + bv.height),
|
||||
cv::Range(left_margin, left_margin + 1.2 * bv.height));
|
||||
cv::Mat img_bin;
|
||||
cv::cvtColor(star_img, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 127, 255, cv::THRESH_BINARY);
|
||||
@@ -1336,11 +1433,10 @@ private:
|
||||
return;
|
||||
}
|
||||
const auto& bv = _baseline_v;
|
||||
auto stage_img = _img(cv::Rect(
|
||||
static_cast<int>(bv.x + bv.width + 0.43 * bv.height),
|
||||
0,
|
||||
static_cast<int>(1.6 * bv.height),
|
||||
bv.y));
|
||||
int left_margin = bv.x + bv.width;
|
||||
auto stage_img = _img(cv::Range(0, bv.y),
|
||||
cv::Range(left_margin + 0.43 * bv.height,
|
||||
left_margin + 1.5 * bv.height));
|
||||
cv::Mat img_bin;
|
||||
cv::cvtColor(stage_img, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 200, 255, cv::THRESH_BINARY);
|
||||
@@ -1349,6 +1445,24 @@ private:
|
||||
_stage.set_img(stage_img);
|
||||
_stage.analyze();
|
||||
}
|
||||
void _get_difficulty()
|
||||
{
|
||||
if (_status == StatusFlags::HAS_ERROR || _status == StatusFlags::ERROR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto& bv = _baseline_v;
|
||||
int left_margin = bv.x + bv.width;
|
||||
auto diff_img = _img(cv::Range(0, bv.y),
|
||||
cv::Range(left_margin, left_margin + 0.43 * bv.height));
|
||||
cv::Mat img_bin;
|
||||
cv::cvtColor(diff_img, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 25, 255, cv::THRESH_BINARY);
|
||||
diff_img = diff_img(separate(img_bin, DirectionFlags::TOP, 1)[0],
|
||||
cv::Range(0, img_bin.cols));
|
||||
_difficutly.set_img(diff_img);
|
||||
_difficutly.analyze();
|
||||
}
|
||||
void _get_drop_area()
|
||||
{
|
||||
if (_status == StatusFlags::HAS_ERROR || _status == StatusFlags::ERROR)
|
||||
@@ -1357,18 +1471,19 @@ private:
|
||||
}
|
||||
const auto& bv = _baseline_v;
|
||||
cv::Mat img_bin = _img(cv::Range(bv.y + bv.height, height),
|
||||
cv::Range(bv.x + bv.width, static_cast<int>(0.2 * width)));
|
||||
cv::Range(bv.x + bv.width, 0.2 * width));
|
||||
cv::cvtColor(img_bin, img_bin, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(img_bin, img_bin, 127, 255, cv::THRESH_BINARY);
|
||||
auto sp = separate(img_bin, DirectionFlags::TOP, 2);
|
||||
int top_margin = bv.y + bv.height + sp[1].start;
|
||||
auto drop_area_img = _img(
|
||||
cv::Range(top_margin + static_cast<int>(bv.height * DROP_AREA_Y_PROP), top_margin + bv.height),
|
||||
cv::Range(top_margin + bv.height * DROP_AREA_Y_PROP, top_margin + bv.height),
|
||||
cv::Range(bv.x + bv.width, width));
|
||||
_drop_area.set_img(drop_area_img);
|
||||
_drop_area.analyze(_stage.stage_code());
|
||||
_drop_area.analyze(_stage.stage_code(), _difficutly.difficulty());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace penguin
|
||||
|
||||
#endif // PENGUIN_RESULT_HPP_
|
||||
|
||||
@@ -80,7 +80,7 @@ MAA 的意思是 MAA Assistant Arknights
|
||||
- 图像识别库:[opencv](https://github.com/opencv/opencv.git)
|
||||
- ~~文字识别库:[chineseocr_lite](https://github.com/DayBreak-u/chineseocr_lite.git)~~
|
||||
- 文字识别库:[PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR)
|
||||
- 关卡掉落识别:[企鹅物流识别](https://github.com/KumoSiunaus/penguin-stats-recognize-v3)
|
||||
- 关卡掉落识别:[企鹅物流识别](https://github.com/penguin-statistics/recognizer)
|
||||
- 地图格子识别:[Arknights-Tile-Pos](https://github.com/yuanyan3060/Arknights-Tile-Pos)
|
||||
- C++ JSON库:[meojson](https://github.com/MistEO/meojson.git)
|
||||
- C++ 运算符解析器:[calculator](https://github.com/kimwalisch/calculator)
|
||||
|
||||
@@ -64,14 +64,23 @@ bool asst::PenguinPack::load_json(const std::string& stage_path, const std::stri
|
||||
stage_dst["drops"] = json::array(std::move(drops_vector));
|
||||
stage_dst["existence"] = stage_info.at("existence").at(m_language).at("exist");
|
||||
|
||||
cvt_stage_json[std::move(key)] = std::move(stage_dst);
|
||||
// 企鹅识别 4.2 新增的字段,为了区分第十章的 标准关卡 or 磨难关卡
|
||||
json::value difficulty_json;
|
||||
if (stage_dst["stageId"].as_string().find("tough_") == 0) {
|
||||
difficulty_json["TOUGH"] = std::move(stage_dst);
|
||||
}
|
||||
else {
|
||||
difficulty_json["NORMAL"] = std::move(stage_dst);
|
||||
}
|
||||
cvt_stage_json[std::move(key)] |= std::move(difficulty_json.as_object());
|
||||
}
|
||||
}
|
||||
catch (json::exception& e) {
|
||||
m_last_error = stage_path + " parsing error " + e.what();
|
||||
return false;
|
||||
}
|
||||
::wload_stage_index(cvt_stage_json.to_string());
|
||||
std::string cvt_string = cvt_stage_json.to_string();
|
||||
::wload_stage_index(std::move(cvt_stage_json.to_string()));
|
||||
|
||||
::wload_hash_index(utils::load_file_without_bom(hash_path));
|
||||
return true;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- 图像识别库:[opencv](https://github.com/opencv/opencv.git)
|
||||
- ~~文字识别库:[chineseocr_lite](https://github.com/DayBreak-u/chineseocr_lite.git)~~
|
||||
- 文字识别库:[PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR)
|
||||
- 关卡掉落识别:[企鹅物流识别](https://github.com/KumoSiunaus/penguin-stats-recognize-v3)
|
||||
- 关卡掉落识别:[企鹅物流识别](https://github.com/penguin-statistics/recognizer)
|
||||
- C++ JSON库:[meojson](https://github.com/MistEO/meojson.git)
|
||||
- C++ 运算符解析器:[calculator](https://github.com/kimwalisch/calculator)
|
||||
- C++ base64编解码:[cpp-base64](https://github.com/ReneNyffenegger/cpp-base64)
|
||||
|
||||
Reference in New Issue
Block a user