Files
ViewDesignEngine/include/vde/core/license_manager.h
T

279 lines
10 KiB
C++
Raw Normal View History

#pragma once
/**
* @file license_manager.h
* @brief ViewDesignEngine 许可证管理系统
*
* 提供三层许可证体系:
* - Community(社区版):基础 B-Rep + STEP/IGES 导入导出
* - Professional(专业版):+ 5轴CAM + 高级曲面 + GD&T
* - Enterprise(企业版):+ 技术支持 + 自定义格式
*
* LicenseKey 格式:VDE-XXXX-XXXX-XXXXBase32编码)
* 包含:版本号 + tier + 过期时间 + 签名(HMAC-SHA256
*
* @ingroup core
*/
#include <cstdint>
#include <string>
#include <vector>
#include <set>
#include <ctime>
#include <mutex>
namespace vde::core {
// ═══════════════════════════════════════════════════════════════
// LicenseTier 枚举
// ═══════════════════════════════════════════════════════════════
/// 许可证层级
enum class LicenseTier : int {
Community = 0, ///< 社区版
Professional = 1, ///< 专业版
Enterprise = 2, ///< 企业版
};
/// 将 LicenseTier 转为字符串
inline const char* license_tier_name(LicenseTier tier) {
switch (tier) {
case LicenseTier::Community: return "Community";
case LicenseTier::Professional: return "Professional";
case LicenseTier::Enterprise: return "Enterprise";
}
return "Unknown";
}
/// 从字符串解析 LicenseTier,失败返回 -1
int parse_license_tier(const std::string& name);
// ═══════════════════════════════════════════════════════════════
// Feature 枚举(按 tier 区分)
// ═══════════════════════════════════════════════════════════════
/// 功能特性标识
enum class Feature : int {
// Community 级别
BASIC_BREP = 0, ///< 基础B-Rep建模
STEP_IMPORT_EXPORT = 1, ///< STEP导入导出
IGES_IMPORT_EXPORT = 2, ///< IGES导入导出
BASE_IO_FORMATS = 3, ///< 基础格式IOOBJ/STL/PLY
MESH_OPERATIONS = 4, ///< 基本网格操作
SKETCH_SOLVER = 5, ///< 草图约束求解
// Professional 级别
CAM_5AXIS = 10, ///< 5轴CAM加工
ADVANCED_SURFACING = 11, ///< 高级曲面建模(A级曲面等)
GD_T = 12, ///< GD&T 几何尺寸和公差
PMI_MBD = 13, ///< PMI / 基于模型的定义
ASSEMBLY_DESIGN = 14, ///< 装配设计
SHEET_METAL = 15, ///< 钣金设计
ADVANCED_HEALING = 16, ///< 高级修复
FEA_MESH = 17, ///< FEA网格生成
IGA_ANALYSIS = 18, ///< IGA等几何分析
COLLISION_DETECTION = 19, ///< 碰撞检测
DIRECT_MODELING = 20, ///< 直接建模
SURFACE_FAIRING = 21, ///< 曲面光顺
// Enterprise 级别
TECHNICAL_SUPPORT = 30, ///< 技术支持
CUSTOM_FORMATS = 31, ///< 自定义格式支持
SCRIPTING_API = 32, ///< 脚本API
GPU_ACCELERATION = 33, ///< GPU加速
CLOUD_COLLABORATION = 34, ///< 云端协作
SDF_MODELING = 35, ///< SDF隐式建模
LICENSE_MANAGER_SDK = 36, ///< License SDK分发
};
/// Feature 转字符串
const char* feature_name(Feature f);
/// 字符串转 Feature,失败返回 -1
int parse_feature(const std::string& name);
/// 获取指定 tier 包含的所有 feature
std::set<Feature> features_for_tier(LicenseTier tier);
/// 检查某个 feature 是否属于指定 tier
bool feature_available_in_tier(Feature f, LicenseTier tier);
// ═══════════════════════════════════════════════════════════════
// LicenseInfo 结构体
// ═══════════════════════════════════════════════════════════════
/// 许可证信息
struct LicenseInfo {
LicenseTier tier; ///< 层级
std::string licensee; ///< 被许可方(公司/个人名称)
std::time_t expiry; ///< 过期时间(Unix时间戳,0=永久)
std::set<Feature> features; ///< 启用的功能列表
std::string key_string; ///< 原始License Key字符串
int version; ///< License版本号
/// 默认构造(Community试用版)
LicenseInfo()
: tier(LicenseTier::Community)
, licensee("Trial User")
, expiry(0)
, version(1) {}
/// 是否已过期
[[nodiscard]] bool is_expired() const;
/// 距离过期还剩多少天(返回 -1 表示永久有效)
[[nodiscard]] int days_until_expiry() const;
};
// ═══════════════════════════════════════════════════════════════
// LicenseKey 类
// ═══════════════════════════════════════════════════════════════
/**
* @brief LicenseKey 生成/验证/解析类
*
* License Key 格式:VDE-XXXX-XXXX-XXXX
* 其中 XXXX 段为 Base32 编码的二进制数据。
*
* 二进制数据布局(17字节):
* - byte 0: version (1)
* - byte 1: tier (0=Community, 1=Professional, 2=Enterprise)
* - byte 2-9: expiry (uint64_t, Unix timestamp, big-endian)
* - byte 10-16: reserved (0)
*
* 签名:HMAC-SHA256 的前 4 字节附加到 Base32 编码后的最后一段。
*
* 完整的 Key 编码流程:
* payload(17B) → HMAC-SHA256 → 取前4B → payload+signature(21B) → Base32 → VDE-XXXX-XXXX-XXXX
*/
class LicenseKey {
public:
/// 默认构造(无效Key
LicenseKey() = default;
/**
* @brief 从字符串解析 LicenseKey
* @param key_str 如 "VDE-ABCD-EFGH-IJKL"
* @return 如果格式有效返回 true
*/
bool parse(const std::string& key_str);
/**
* @brief 生成 LicenseKey
* @param tier 许可证层级
* @param expiry 过期时间(Unix时间戳,0=永久)
* @param licensee 被许可方名称
* @return 格式化的License Key字符串
*/
static std::string generate(LicenseTier tier, std::time_t expiry,
const std::string& licensee);
/**
* @brief 验证 LicenseKey 是否有效
* @param key_str License Key 字符串
* @return 有效则返回 true
*/
static bool validate(const std::string& key_str);
/// 获取解析后的 LicenseInfo
[[nodiscard]] const LicenseInfo& info() const { return info_; }
/// 原始 Key 字符串
[[nodiscard]] const std::string& key_string() const { return key_string_; }
/// 签名验证是否通过
[[nodiscard]] bool signature_valid() const { return sig_valid_; }
private:
/// Base32 编解码(RFC 4648,无填充)
static std::string base32_encode(const std::vector<uint8_t>& data);
static std::vector<uint8_t> base32_decode(const std::string& encoded);
/// HMAC-SHA256 简化实现(使用占位密钥)
static std::vector<uint8_t> compute_hmac(const std::vector<uint8_t>& data);
LicenseInfo info_;
std::string key_string_;
bool sig_valid_ = false;
};
// ═══════════════════════════════════════════════════════════════
// LicenseManager 单例
// ═══════════════════════════════════════════════════════════════
/**
* @brief LicenseManager 全局许可证管理器(单例)
*
* 管理当前运行时使用的许可证,提供功能查询接口。
*
* 用法:
* @code
* auto& mgr = LicenseManager::instance();
* mgr.set_license("VDE-ABCD-EFGH-IJKL");
* if (mgr.has_feature("CAM_5AXIS")) { ... }
* if (mgr.is_expired()) { ... }
* @endcode
*/
class LicenseManager {
public:
/// 获取单例实例
static LicenseManager& instance();
// ── 禁止拷贝和移动 ──────────────────────────────
LicenseManager(const LicenseManager&) = delete;
LicenseManager& operator=(const LicenseManager&) = delete;
/**
* @brief 设置 License Key
* @param key License Key 字符串
* @return true 设置成功(Key有效且未过期)
*/
bool set_license(const std::string& key);
/**
* @brief 进入试用模式(30天Community试用)
* @param days 试用天数(默认30
*/
void start_trial(int days = 30);
/// 当前许可证层级
[[nodiscard]] LicenseTier current_tier() const;
/**
* @brief 检查是否拥有某个功能
* @param feature_name 功能名称字符串(如 "CAM_5AXIS"
* @return true 表示该功能可用
*/
[[nodiscard]] bool has_feature(const std::string& feature_name) const;
/**
* @brief 检查 Feature 枚举是否可用
* @param f Feature 枚举值
* @return true 表示该功能可用
*/
[[nodiscard]] bool has_feature(Feature f) const;
/// 许可证是否已过期
[[nodiscard]] bool is_expired() const;
/// 试用剩余天数(-1 表示已过期或无试用)
[[nodiscard]] int trial_days_left() const;
/// 获取当前许可证信息
[[nodiscard]] const LicenseInfo& current_license() const;
/// 是否处于试用模式
[[nodiscard]] bool is_trial() const;
private:
LicenseManager();
~LicenseManager() = default;
LicenseInfo current_;
bool trial_mode_ = false;
std::time_t trial_start_ = 0;
int trial_days_ = 30;
mutable std::mutex mutex_;
};
} // namespace vde::core