首先说下我们要做什么:
1.使用特定特征码,为加密狗拷入【限制访问次数】的特征
2.在Unity端,根据特征码读取当前状态,已使用的登陆次数和总次数
3.在Unity端,通过函数(点击按钮),模拟登陆,以扣除一次登陆次数
在使用unity前,先简单说下SuperDog这个加密狗
目前我手里有两种狗,Master和Drive
1.Master是用来做管理验证的,想要加密程序,会检查电脑上是否插入了Master,未插入则不允许高级操作
2.Drive是用来给客户的,插上Master的前提下,可以使用Drive来加密程序。
购买完后,买家会给你一些文档资料,假设目前你已经按照里面教程,安装好了必要API,并且安装了加密所需的客户端。
===
预留,如果后期有需,会在这里,补充如何做这些安装软件和API等前期准备工作
===
下面介绍一下SuperDog的特征码
首先我们知道,软件使用加密狗加密后,需要在软件运行的电脑上,插入加密狗,该软件才能运行,当为了适应一些特殊需求,比如限制访问时间,或者限制访问次数,就可以通过添加特征码来实现。
目前我手里的SuperDog提供的几种特征码如下
1.永久
2.执行次数:可以通过软件,设置可执行次数,每次打开软件,扣除一次,次数扣光,授权失效
3.过期日期:限制过期日期,是一个固定的日期
4.执行天数:限制程序运行的时长
这些内容可以在【超级狗授权管理工具】中找到。
下面我们添加如下特征
添加特征id为1,类型为执行次数,次数值设置为30
然后点击【编程超级狗】,可以看见左下角,我已经将Master插入电脑
如果未连接Master会报错
如果只连接Master未连接Drive会报错
当二者均插入电脑时,成功编程超级狗(即,将这个特征,添加到Drive)
下面开始准备在unity端读取信息
目前,只需要,读取和模拟登陆,因此不需要分布测试程序,直接在Unity的Editor下使用即可
首先将SuperDog安装向导安装的API,的DLL找到,在【文档】中即可快速访问
创建Unity测试项目,(这里我放了一些舒服的UI和一些简单的UI控制脚本,不是重点,暂且略过)
基本功能就是:上面几个控制按钮,下面是输出面板,可以打印一些信息。
右侧【clear】清空输出面板
【加一次Login】为模拟一次登陆,需要扣除一次可登录次数
【获取状态】即读取当前,【右侧输入框】内输入的特征码的,剩余次数及总次数信息
==
预留,如果有需要,会将UI这部分内容贴出来
==
将以上5个DLL拷贝到Unity项目根目录Asset文件夹下。
新建任意合理C#脚本,挂载到场景中,
脚本需要引用
using UnityEngine;
using UnityEngine.UI;
using SuperDog;
using System;
using System.Xml.Linq;
核心代码
获取加密狗状态:
String scope ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?><dogscope/>";
/// <summary>
///
/// </summary>
/// <param name="feature">特征码</param>
/// <param name="msg">保存输出信息</param>
private void GetInfo_test(int feature,ref string msg) {
string info = "";//保存XML
DogStatus status;
status = Dog.GetInfo(scope, "<dogformat><feature><attribute name=\"id\"/><element name=\"license\"/></feature></dogformat>", strVenderCode,ref info);
//Debug.Log(info);
//Debug.Log(status);
XElement xElement = XElement.Parse(info);
foreach (XElement element in xElement.Descendants("feature")) {
if (element.Attribute("id").Value == feature.ToString()) {
//Debug.Log(element);
if(element.Element("license").Element("license_type").Value!= "executions") {
msg = "您获取的许可类型,不是次数限制类型:"+ element.Element("license").Element("license_type").Value + "\n" + info;
}
else {
msg = "总次数=" + element.Element("license").Element("counter_fix").Value + ",已用次数=" + element.Element("license").Element("counter_var").Value;
}
}
}
}
模拟登陆:
private void AddLoginToFeature(int featureInt) {
DogStatus status;
Dog curDog = new Dog(new DogFeature(featureInt));
status = curDog.Login(strVenderCode);
if (status == DogStatus.StatusOk) {
text_DebugInfo.text += "\n 添加一次 login,加密狗可登录次数-1";
//在这里添加自己的逻辑,或者打印信息
}
else {
text_DebugInfo.text += "\n login failed";
}
}
完整脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using SuperDog;
using System;
using System.Xml.Linq;
public class MainManager : MonoBehaviour {
#region singleton
private static MainManager _instance;
public static MainManager instance {
get {
return _instance;
}
}
private void Awake() {
_instance = this;
}
#endregion
public Button btn_AddLogin;
public Button btn_showDogInfo;
public Button btn_clear;
public InputField ipf_tzm;
public Text text_DebugInfo;
public const string strVenderCode = "这里输入你们自己的VenderCode";
private void Start() {
AddListeners();
}
String scope ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?><dogscope/>";
/// <summary>
///
/// </summary>
/// <param name="feature">特征码</param>
/// <param name="msg">保存输出信息</param>
private void GetInfo_test(int feature,ref string msg) {
string info = "";//保存XML
DogStatus status;
status = Dog.GetInfo(scope, "<dogformat><feature><attribute name=\"id\"/><element name=\"license\"/></feature></dogformat>", strVenderCode,ref info);
//Debug.Log(info);
//Debug.Log(status);
XElement xElement = XElement.Parse(info);
foreach (XElement element in xElement.Descendants("feature")) {
if (element.Attribute("id").Value == feature.ToString()) {
//Debug.Log(element);
if(element.Element("license").Element("license_type").Value!= "executions") {
msg = "您获取的许可类型,不是次数限制类型:"+ element.Element("license").Element("license_type").Value + "\n" + info;
}
else {
msg = "总次数=" + element.Element("license").Element("counter_fix").Value + ",已用次数=" + element.Element("license").Element("counter_var").Value;
}
}
}
}
#region UI Functions
private void AddListeners() {
btn_AddLogin.onClick.AddListener(OnAddLoginButtonClick);
btn_showDogInfo.onClick.AddListener(OnShowDogInfoButtonClick);
btn_clear.onClick.AddListener(OnClearButtonClick);
}
private void OnAddLoginButtonClick() {
AddLoginToFeature(1);
}
private void AddLoginToFeature(int featureInt) {
DogStatus status;
Dog curDog = new Dog(new DogFeature(featureInt));
status = curDog.Login(strVenderCode);
if (status == DogStatus.StatusOk) {
text_DebugInfo.text += "\n 添加一次 login,加密狗可登录次数-1";
}
else {
text_DebugInfo.text += "\n login failed";
}
}
private void OnShowDogInfoButtonClick() {
int feature;
if (!int.TryParse(ipf_tzm.text,out feature)) {
text_DebugInfo.text += "\n 特征码格式输入错误,请输入数字";
return;
}
string msg="";
text_DebugInfo.text += "\n 输入的特征码为:" + feature;
GetInfo_test(feature,ref msg);
//DogStatus status = ReadDogActiveString(feature, strVenderCode, out msg);
text_DebugInfo.text += ", 信息为" + msg;
}
private void OnClearButtonClick() {
text_DebugInfo.text = "ready ->";
}
private int GetFeatureinput() {
return int.Parse(ipf_tzm.text);
}
#endregion
将代码写好,场景准备好之后。创建好UI空间,赋值给脚本
然后确保做以下工作:
1.要将之前的5个DLL,拷贝到系统盘system32下!才可以在Unity Editor下访问
2.一定要将VenderCode改成你们自己的!才能运行
一定要将VenderCode改成你们自己的!才能运行
一定要将VenderCode改成你们自己的!才能运行
自己的VenderCode在你安装官方API和工具的文件夹下,我将它们安装到了E盘。不要使用DEMOMA.hvc,使用下面你们自己特有的,打开将里面的字符串复制出来。
3.电脑插入加密狗
运行即可查看效果。
PS:我们Getinfo获取的数据是XML,一个字符串,长得像,下面这样,所以,可以自行修改其解析方式
<?xml version="1.0" encoding="UTF-8" ?>
<dog_info>
<feature id="0">
<license>
<license_type>perpetual</license_type>
</license>
</feature>
<feature id="1">
<license>
<license_type>executions</license_type>
<counter_fix>30</counter_fix>
<counter_var>5</counter_var>
</license>
</feature>
<feature id="2">
<license>
<license_type>trial</license_type>
<time_start>uninitialized</time_start>
<total_time>5184000</total_time>
</license>
</feature>
</dog_info>
发布程序
无论我这个unity发布的程序是否已经被加密,都可以读取到drive的信息。我们只需要将Drive插入电脑,就可以通过软件读取其信息。
不过发布前,需要将API Level设置为2.0,否则无法读取
发布后,再将之前的5个Dll,拷贝到发布好的程序根目录
Notice!
一个小问题提下,(发布好后)Dll放在根目录还是plugin下,我没有具体去测,我是两面都放了,