/// <summary>
        /// 每月1号领取大会员福利(B币券、大会员权益)
        /// </summary>
        /// <param name="useInfo"></param>
        public void ReceiveVipPrivilege(UseInfo useInfo)
        {
            if (_dailyTaskOptions.DayOfReceiveVipPrivilege == 0)
            {
                _logger.LogInformation("已配置为不进行自动领取会员权益,跳过领取任务");
                return;
            }

            int targetDay = _dailyTaskOptions.DayOfReceiveVipPrivilege == -1
                ? 1
                : _dailyTaskOptions.DayOfReceiveVipPrivilege;

            if (DateTime.Today.Day != targetDay)
            {
                _logger.LogInformation("目标领取日期为{targetDay}号,今天是{day}号,跳过领取任务", targetDay, DateTime.Today.Day);
                return;
            }

            //大会员类型
            int vipType = useInfo.GetVipType();

            if (vipType == 2)
            {
                ReceiveVipPrivilege(1);
                ReceiveVipPrivilege(2);
            }
            else
            {
                _logger.LogInformation("普通会员和月度大会员每月不赠送B币券,所以不需要领取权益喽");
            }
        }
        /// <summary>
        /// 获取大会员漫画权益
        /// </summary>
        /// <param name="reason_id">权益号,由https://api.bilibili.com/x/vip/privilege/my得到权益号数组,取值范围为数组中的整数
        /// 这里为方便直接取1,为领取漫读劵,暂时不取其他的值</param>
        public void ReceiveMangaVipReward(int reason_id, UseInfo userIfo)
        {
            int day = DateTime.Today.Day;

            if (day != _dailyTaskOptions.DayOfReceiveVipPrivilege)
            {
                //一个月执行一次就行
                _logger.LogInformation("目标领取日期为{target}号,今天是{day}号,跳过领取任务", _dailyTaskOptions.DayOfReceiveVipPrivilege, day);
                return;
            }

            if (userIfo.GetVipType() == 0)
            {
                _logger.LogInformation("不是会员或会员已过期,跳过领取任务");
                return;
            }

            var response = _mangaApi.ReceiveMangaVipReward(reason_id).Result;

            if (response.Code == 0)
            {
                _logger.LogInformation($"大会员成功领取{response.Data.Amount}张漫读劵");
            }
            else
            {
                _logger.LogInformation($"大会员领取漫读劵失败,原因为:{response.Message}");
            }
        }
Пример #3
0
        /// <summary>
        /// 登录
        /// </summary>
        /// <returns></returns>
        public UseInfo LoginByCookie()
        {
            BiliApiResponse <UseInfo> apiResponse = _dailyTaskApi.LoginByCookie().Result;

            if (apiResponse.Code != 0 || !apiResponse.Data.IsLogin)
            {
                _logger.LogWarning("登录异常,Cookies可能失效了,请仔细检查Github Secrets中DEDEUSERID、SESSDATA、BILI_JCT三项的值是否正确");
                return(null);
            }

            UseInfo useInfo = apiResponse.Data;

            //获取到UserId
            _cookie.SetUserId(useInfo.Mid.ToString());

            //用户名模糊处理
            _logger.LogInformation("登录成功,用户名: {0}", useInfo.GetFuzzyUname());
            _logger.LogInformation("硬币余额: {0}", useInfo.Money ?? 0);

            if (useInfo.Level_info.Current_level < 6)
            {
                _logger.LogInformation("距离升级到Lv{0}还有: {1}天",
                                       useInfo.Level_info.Current_level + 1,
                                       (useInfo.Level_info.GetNext_expLong() - useInfo.Level_info.Current_exp) / Constants.EveryDayExp);
            }
            else
            {
                _logger.LogInformation("当前等级Lv6,经验值为:{0}", useInfo.Level_info.Current_exp);
            }

            return(useInfo);
        }
        private string CheckOutLicense(string lic)
        {
            string result = CommandResult.OK;

            // lic: [0]SerialID;[1]Software;[2]Mac;
            // lic: [3]DomainName;[4]UserName

            var lics = lic.Split(';');

            if (lics.Length < 5)
            {
                result = CommandResult.InvalidCommand;
                return(result);
            }

            LicenseInfo licInfo = RetrieveEntityUsingPointQuery(table, lics[1], lics[0]);

            if (licInfo == null)
            {
                result = CommandResult.NotFound;
                return(result);
            }

            UseInfo useInfos = null;

            if (licInfo.UseInfo == null || licInfo.UseInfo == "")
            {
                useInfos             = new UseInfo();
                useInfos.UseInfoList = new List <string>();
            }
            else
            {
                useInfos = JsonConvert.DeserializeObject <UseInfo>(licInfo.UseInfo);
            }

            // Mac;DomainName;UserName
            string iUseInfo = lics[2] + ";" + lics[3] + ";" + lics[4];

            for (int i = 0; i < useInfos.UseInfoList.Count; ++i)
            {
                if (useInfos.UseInfoList[i].IndexOf(iUseInfo) >= 0 && (!useInfos.UseInfoList[i].Contains(InfoItem.Borrow)))
                {
                    //useInfos.UseInfoList.RemoveAt(i);
                    useInfos.UseInfoList[i] = iUseInfo + ";" + InfoItem.TimeOut + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci);
                    break;
                }
            }

            licInfo.UseInfo = JsonConvert.SerializeObject(useInfos, Formatting.Indented);

            try {
                // https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/
                TableOperation mergeOperation = TableOperation.Merge(licInfo);
                table.Execute(mergeOperation);
            } catch (StorageException) {
            }

            return(result);
        }
        private string ReturnLicense(string lic)
        {
            string result = CommandResult.OK;

            // lic: [0]SerialID;[1]Software;[2]Mac;
            // lic: [3]DomainName;[4]UserName

            var lics = lic.Split(';');

            if (lics.Length < 5)
            {
                result = CommandResult.InvalidCommand;
                return(result);
            }

            LicenseInfo licInfo = RetrieveEntityUsingPointQuery(table, lics[1], lics[0]);

            if (licInfo == null)
            {
                result = CommandResult.NotFound;
                return(result);
            }

            UseInfo useInfos = null;

            if (licInfo.UseInfo == null)
            {
                return(result);
            }
            else
            {
                useInfos = JsonConvert.DeserializeObject <UseInfo>(licInfo.UseInfo);
            }

            // Mac;DomainName;UserName
            string iUseInfo = lics[2] + ";" + lics[3] + ";" + lics[4];

            for (int i = 0; i < useInfos.UseInfoList.Count; ++i)
            {
                if (useInfos.UseInfoList[i].IndexOf(iUseInfo) >= 0)
                {
                    useInfos.UseInfoList[i] = iUseInfo;
                    licInfo.UseInfo         = JsonConvert.SerializeObject(useInfos, Formatting.Indented);

                    try {
                        // https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/
                        TableOperation mergeOperation = TableOperation.Merge(licInfo);
                        table.Execute(mergeOperation);
                    } catch (StorageException) {
                        result = "Wrong with Return License, Please try it again.";
                        return(result);
                    }

                    break;
                }
            }

            return(result);
        }
Пример #6
0
        /// <summary>
        /// 月底自动给自己充电
        /// 仅充会到期的B币券,低于2的时候不会充
        /// </summary>
        public void Charge(UseInfo userInfo)
        {
            if (_dailyTaskOptions.DayOfAutoCharge == 0)
            {
                _logger.LogInformation("已配置为不进行自动充电,跳过充电任务");
                return;
            }

            int targetDay = _dailyTaskOptions.DayOfAutoCharge == -1
                ? DateTime.Today.LastDayOfMonth().Day
                : _dailyTaskOptions.DayOfAutoCharge;

            if (DateTime.Today.Day != targetDay)
            {
                _logger.LogInformation("目标充电日期为{targetDay}号,今天是{today}号,跳过充电任务", targetDay, DateTime.Today.Day);
                return;
            }

            //B币券余额
            decimal couponBalance = userInfo.Wallet.Coupon_balance;

            if (couponBalance < 2)
            {
                _logger.LogInformation("不是年度大会员或已过期,无法充电");
                return;
            }

            //大会员类型
            int vipType = userInfo.GetVipType();

            if (vipType != 2)
            {
                _logger.LogInformation("不是年度大会员或已过期,无法充电");
                return;
            }

            BiliApiResponse <ChargeResponse> response = _dailyTaskApi.Charge(couponBalance * 10, _cookieOptions.UserId, _cookieOptions.UserId, _cookieOptions.BiliJct).Result;

            if (response.Code == 0)
            {
                if (response.Data.Status == 4)
                {
                    _logger.LogInformation("给自己充电成功啦,送的B币券没有浪费哦");
                    _logger.LogInformation("本次给自己充值了: {num}个电池哦", couponBalance * 10);

                    //获取充电留言token
                    ChargeComments(response.Data.Order_no);
                }
                else
                {
                    _logger.LogDebug("充电失败了啊 原因:{reason}", response.ToJson());
                }
            }
            else
            {
                _logger.LogDebug("充电失败了啊 原因:{reason}", response.Message);
            }
        }
Пример #7
0
        private UseInfo Login()
        {
            UseInfo userInfo = _loginDomainService.LoginByCookie();

            if (userInfo == null)
            {
                throw new Exception("登录失败,请检查Cookie");                  //终止流程
            }
            return(userInfo);
        }
        private string CreateLicense(string lic)
        {
            string result = CommandResult.OK;

            // lic: [0]SerialID;[1]Software;[2]Version;[3]MaintenanceDate;[4]ExpireDate;[5]IssueDate;[6]Keys;
            // lic: [7]Customer;[8]Contact;[9]Email;[10]Phone;[11]Host;

            var lics = lic.Split(';');

            if (lics.Length < 2)
            {
                result = CommandResult.InvalidCommand;
                return(result);
            }

            LicenseInfo licInfo = RetrieveEntityUsingPointQuery(table, lics[1], lics[0]);

            if (licInfo == null)
            {
                licInfo = new LicenseInfo(lics[1], lics[0]);

                licInfo.Customer = licInfo.Contact = licInfo.Email = licInfo.Phone = "";

                UseInfo useInfos = new UseInfo();
                useInfos.UseInfoList = new List <string>();
                licInfo.UseInfo      = JsonConvert.SerializeObject(useInfos, Formatting.Indented);
            }
            //else
            //{
            //    result = CommandResult.IDRepeated;
            //    return result;
            //}
            licInfo.SoftVersion     = lics[2];
            licInfo.MaintenanceDate = new DateTime(Int32.Parse(lics[3].Substring(0, 4)), Int32.Parse(lics[3].Substring(4, 2)), Int32.Parse(lics[3].Substring(6, 2)));
            licInfo.ExpireDate      = new DateTime(Int32.Parse(lics[4].Substring(0, 4)), Int32.Parse(lics[4].Substring(4, 2)), Int32.Parse(lics[4].Substring(6, 2)));
            licInfo.IssueDate       = new DateTime(Int32.Parse(lics[5].Substring(0, 4)), Int32.Parse(lics[5].Substring(4, 2)), Int32.Parse(lics[5].Substring(6, 2)));
            licInfo.Keys            = Int32.Parse(lics[6]);

            if (lics.Length > 10)
            {
                licInfo.Customer = lics[7];
                licInfo.Contact  = lics[8];
                licInfo.Email    = lics[9];
                licInfo.Phone    = lics[10];
            }

            // Create the InsertOrReplace  TableOperation
            TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(licInfo);

            // Execute the operation.
            table.Execute(insertOrMergeOperation);

            return(result);
        }
Пример #9
0
 private void ReceiveMangaVipReward(UseInfo userInfo)
 {
     _mangaDomainService.ReceiveMangaVipReward(1, userInfo);
 }
Пример #10
0
 private void Charge(UseInfo userInfo)
 {
     _chargeDomainService.Charge(userInfo);
 }
Пример #11
0
 private void ReceiveVipPrivilege(UseInfo userInfo)
 {
     _vipPrivilegeDomainService.ReceiveVipPrivilege(userInfo);
 }
        private string RegisterLicense(string lic)
        {
            string result = CommandResult.OK;

            // lic: [0]SerialID;[1]Software;[2]SoftVersion;[3]MaintenanceDate;[4]ExpireDate;[5]IssueDate;[6]Keys;
            // lic: [7]Mac;[8]DomainName;[9]Customer;[10]Contact;[11]Email;[12]Phone;[13]userSoft;[14]userVersion;[15]UserName

            var lics = lic.Split(';');

            if (lics.Length < 16)
            {
                result = CommandResult.InvalidCommand;
                return(result);
            }

            // use userSoft = lics[13] check software name
            LicenseInfo licInfo = RetrieveEntityUsingPointQuery(table, lics[1], lics[0]);

            // TODO: validate lic[0] SerialID

            if (licInfo == null)
            {
                result = CommandResult.NotFound;
                return(result);
            }

            string softVersion = lics[1];

            // check userVersion
            if (lics[1] == "Package")
            {
                if (!lics[2].Contains(lics[13] + " " + lics[14]))
                {
                    result = CommandResult.NotFound;
                    return(result);
                }
                softVersion = lics[2];
            }
            else
            {
                if (lics[14] != licInfo.SoftVersion)
                {
                    result = CommandResult.InvalidVersion;
                    return(result);
                }
            }

            // check expireDate
            TimeSpan span = licInfo.ExpireDate - nowEST;

            if (span.TotalDays < 0)
            {
                result = CommandResult.EXPIRED;
                return(result);
            }

            // check [6]Keys
            //int numKey = Int32.Parse(lics[6]);
            //if (numKey != licInfo.Keys) {
            //    result = CommandResult.LicenseUsed + ";NOT" + lics[6];
            //    return result;
            //}

            UseInfo useInfos = null;

            if (licInfo.UseInfo == null || licInfo.UseInfo == "")
            {
                useInfos             = new UseInfo();
                useInfos.UseInfoList = new List <string>();
            }
            else
            {
                useInfos = JsonConvert.DeserializeObject <UseInfo>(licInfo.UseInfo);
            }

            // check DomainName
            if (useInfos.UseInfoList.Count > 0)
            {
                var      parts      = useInfos.UseInfoList[0].Split(';');
                string   domainName = parts[1];
                string[] ds         = domainName.ToLower().Split('.');
                string[] us         = lics[8].ToLower().Split('.');
                if (ds.Length > 1)
                {
                    bool isFalse = false;
                    for (int i = 0; i < 2; ++i)
                    {
                        if (ds[ds.Length - 1 - i] != us[us.Length - 1 - i])
                        {
                            isFalse = true;
                            break;
                        }
                    }
                    if (isFalse)
                    {
                        result = CommandResult.ErrorRegister;
                        return(result);
                    }
                }
            }

            //register customer info
            licInfo.Customer = lics[9];
            licInfo.Contact  = lics[10];
            licInfo.Email    = lics[11];
            licInfo.Phone    = lics[12];

            // register Mac;DomainName;UserName
            string iUseInfo     = lics[7] + ";" + lics[8] + ";" + lics[15];
            bool   isRegistered = false;

            for (int i = 0; i < useInfos.UseInfoList.Count; ++i)
            {
                if (useInfos.UseInfoList[i].IndexOf(iUseInfo) >= 0)
                {
                    isRegistered = true;
                    break;
                }
            }
            if (!isRegistered)
            {
                if (useInfos.UseInfoList.Count < licInfo.Keys)
                {
                    useInfos.UseInfoList.Add(iUseInfo);
                    licInfo.UseInfo = JsonConvert.SerializeObject(useInfos, Formatting.Indented);
                }
                //Let VerifyLicense check if FULL
                //else {
                //    result = CommandResult.LicenseUsed + ";FULL";
                //    return result;
                //}
            }

            try {
                // https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/
                TableOperation mergeOperation = TableOperation.Merge(licInfo);
                table.Execute(mergeOperation);
            } catch (StorageException) { }

            // return ID;Software;Mac - For safety reason, Double Base64 encode
            System.Text.Encoding ascii = System.Text.Encoding.ASCII;
            string base64 = Convert.ToBase64String(ascii.GetBytes(lics[0] + ";" + softVersion + ";" + lics[7]));

            base64  = Convert.ToBase64String(ascii.GetBytes(base64));
            result += ";" + base64;

            return(result);
        }
        private string CheckInLicense(string lic)
        {
            string result = CommandResult.OK;

            // lic: [0]SerialID;[1]Software;[2]Mac;
            // lic: [3]DomainName;[4]UserName

            var lics = lic.Split(';');

            if (lics.Length < 5)
            {
                result = CommandResult.InvalidCommand;
                return(result);
            }

            LicenseInfo licInfo = RetrieveEntityUsingPointQuery(table, lics[1], lics[0]);

            if (licInfo == null)
            {
                result = CommandResult.NotFound;
                return(result);
            }

            // check expireDate
            TimeSpan span = licInfo.ExpireDate - nowEST;

            if (span.TotalDays < 0)
            {
                result = CommandResult.EXPIRED;
                return(result);
            }

            UseInfo useInfos = null;

            if (licInfo.UseInfo == null || licInfo.UseInfo == "")
            {
                useInfos             = new UseInfo();
                useInfos.UseInfoList = new List <string>();
            }
            else
            {
                useInfos = JsonConvert.DeserializeObject <UseInfo>(licInfo.UseInfo);
            }

            // Mac;DomainName;UserName
            string iUseInfo = lics[2] + ";" + lics[3] + ";" + lics[4];

            bool isCheckedIn = false;

            for (int i = 0; i < useInfos.UseInfoList.Count; ++i)
            {
                if (useInfos.UseInfoList[i].Contains(iUseInfo))
                {
                    if (useInfos.UseInfoList[i].Contains(InfoItem.TimeIn))
                    {
                        useInfos.UseInfoList[i] = iUseInfo + ";" + InfoItem.TimeIn + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci);
                    }
                    isCheckedIn = true;
                    break;
                }
            }

            if (!isCheckedIn)
            {
                result = CommandResult.LicenseUsed + ";FULL";
                return(result);
            }

            licInfo.UseInfo = JsonConvert.SerializeObject(useInfos, Formatting.Indented);

            try {
                // https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/
                TableOperation mergeOperation = TableOperation.Merge(licInfo);
                table.Execute(mergeOperation);
            } catch (StorageException) {
                result = CommandResult.StorageException;
            }

            return(result);
        }
        private string VerifyLicense(string lic)
        {
            string result = CommandResult.OK;

            // lic: [0]SerialID;[1]SoftVersion;[2]Mac;
            // lic: [3]DomainName;[4]UserName;[5]MachineName;[6]OS;[7]userSoft;[8]userVersion

            var lics = lic.Split(';');

            if (lics.Length < 9)
            {
                result = CommandResult.InvalidCommand;
                return(result);
            }

            LicenseInfo licInfo = null;

            if (lics[1].Contains(lics[7] + " " + lics[8]))     // Package License
            {
                licInfo = RetrieveEntityUsingPointQuery(table, "Package", lics[0]);
            }
            else       // use userSoft = lics[7] check software name - SerialID
            {
                licInfo = RetrieveEntityUsingPointQuery(table, lics[7], lics[0]);
            }

            if (licInfo == null)
            {
                result = CommandResult.NotFound;
                return(result);
            }

            // check userVersion
            var     vs   = licInfo.SoftVersion.Split('.');
            int     plus = int.Parse(vs[1]) + 1;
            Version iv   = new Version(vs[0] + "." + plus);
            Version uv   = new Version(lics[8]);

            //!licInfo.SoftVersion.Contains(lics[8])
            if (uv >= iv)
            {
                result = CommandResult.InvalidVersion;
                return(result);
            }

            // check expireDate
            TimeSpan span = licInfo.ExpireDate - nowEST;

            if (span.TotalDays < 0)
            {
                result = CommandResult.EXPIRED;
                return(result);
            }
            else
            {
                System.Text.Encoding ascii = System.Text.Encoding.ASCII;
                int tDay = Convert.ToInt32(span.TotalDays);
                result += ";" + Convert.ToBase64String(ascii.GetBytes(tDay.ToString()));   //Convert.ToString(span.TotalDays)));
            }

            UseInfo useInfos = null;

            if (licInfo.UseInfo == null || licInfo.UseInfo == "")
            {
                useInfos             = new UseInfo();
                useInfos.UseInfoList = new List <string>();
            }
            else
            {
                useInfos = JsonConvert.DeserializeObject <UseInfo>(licInfo.UseInfo);
            }

            // Mac;DomainName;UserName
            string iUseInfo = lics[2] + ";" + lics[3] + ";" + lics[4];

            bool isRegistered = false;

            for (int i = 0; i < useInfos.UseInfoList.Count; ++i)
            {
                if (useInfos.UseInfoList[i].IndexOf(iUseInfo) >= 0)
                {
                    int idx = useInfos.UseInfoList[i].IndexOf(InfoItem.Borrow);
                    if (idx >= 0)
                    {
                        var      borrowStr  = useInfos.UseInfoList[i].Substring(idx + InfoItem.Borrow.Length);
                        DateTime borrowDate = DateTime.ParseExact(borrowStr, "yyyyMMMdd", ci);
                        span = borrowDate - nowEST;
                        if (span.TotalDays < 0)
                        {
                            useInfos.UseInfoList[i] = iUseInfo + ";" + InfoItem.TimeIn + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci);
                        }
                    }
                    else
                    {
                        useInfos.UseInfoList[i] = iUseInfo + ";" + InfoItem.TimeIn + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci);
                    }
                    isRegistered = true;
                    break;
                }
            }

            if (!isRegistered)
            {
                /*
                 * if (useInfos.UseInfoList.Count == licInfo.Keys) {
                 *  result = CommandResult.LicenseUsed + ";FULL";
                 *  return result;
                 * } else if (licInfo.PartitionKey.StartsWith("DYNMIK")) {
                 *  useInfos.UseInfoList.Add(iUseInfo + ";" + InfoItem.TimeIn + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci));
                 * } else {
                 *  result = CommandResult.NoRegister;
                 *  return result;
                 * }
                 */

                // Check Domain

                /*
                 * if (useInfos.UseInfoList.Count > 0) {
                 *  var domains = useInfos.UseInfoList[0].Split(';');
                 *  if (domains.Length > 2) {
                 *      var domain = domains[1];
                 *      var ds = domain.Split('.');
                 *      var dsUser = lics[3].Split('.');
                 *
                 *      if (ds.Length > 1) {
                 *          if (dsUser.Length > 1) {
                 *              int nDomain = 1;
                 *              if (ds.Length > 2) nDomain = 2;
                 *
                 *              for (int i = 0; i < nDomain; ++i) {
                 *                  if (String.Compare(ds[ds.Length - i], dsUser[dsUser.Length - i], true) != 0) {
                 *                      result = CommandResult.ErrorRegister;
                 *                      return result;
                 *                  }
                 *              }
                 *          } else {
                 *              result = CommandResult.ErrorRegister;
                 *              return result;
                 *          }
                 *
                 *      }
                 *  }
                 * }
                 */

                if (useInfos.UseInfoList.Count < licInfo.Keys)
                {
                    useInfos.UseInfoList.Add(iUseInfo + ";" + InfoItem.TimeIn + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci));
                }
                else
                {
                    bool isCheckedIn = false;
                    for (int i = 0; i < useInfos.UseInfoList.Count; ++i)
                    {
                        var iInfo = useInfos.UseInfoList[i];
                        int idx   = iInfo.IndexOf(InfoItem.TimeIn);
                        if (idx < 0)
                        {
                            useInfos.UseInfoList[i] = iUseInfo + ";" + InfoItem.TimeIn + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci);
                            isCheckedIn             = true;
                            break;
                        }
                        else
                        {
                            var      timeInStr = iInfo.Substring(idx + InfoItem.TimeIn.Length);
                            DateTime timeIn    = DateTime.ParseExact(timeInStr, "yyyyMMMdd HH:mm:ss", ci);
                            span = nowEST - timeIn;
                            if (span.TotalSeconds > maxInterval)
                            {
                                useInfos.UseInfoList[i] = iUseInfo + ";" + InfoItem.TimeIn + nowEST.ToString("yyyyMMMdd HH:mm:ss", ci);
                                isCheckedIn             = true;
                                break;
                            }
                        }
                    }
                    if (!isCheckedIn)
                    {
                        result = CommandResult.LicenseUsed + ";FULL";
                        return(result);
                    }
                }
            }
            useInfos.UseInfoList = useInfos.UseInfoList.OrderBy(x => x.Length).ToList();

            licInfo.UseInfo = JsonConvert.SerializeObject(useInfos, Formatting.Indented);

            try {
                // https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/
                TableOperation mergeOperation = TableOperation.Merge(licInfo);
                table.Execute(mergeOperation);
            } catch (StorageException ex) {
                result = "Please run the program again or contact Longterm Services with: " + ex.Message;
            }

            return(result);
        }
        private string BorrowLicense(string lic)
        {
            string result = CommandResult.OK;

            // lic: [0]SerialID;[1]Software;[2]Mac;
            // lic: [3]DomainName;[4]UserName;[5]BorrowDays
            // version 1.2
            // lic: [6]CPUID

            var lics = lic.Split(';');

            if (lics.Length < 6)
            {
                result = CommandResult.InvalidCommand;
                return(result);
            }

            LicenseInfo licInfo = RetrieveEntityUsingPointQuery(table, lics[1], lics[0]);

            if (licInfo == null)
            {
                result = CommandResult.NotFound;
                return(result);
            }

            // check expireDate
            TimeSpan span = licInfo.ExpireDate - nowEST;

            if (span.TotalDays < 0)
            {
                result = CommandResult.EXPIRED;
                return(result);
            }

            UseInfo useInfos = null;

            if (licInfo.UseInfo == null || licInfo.UseInfo == "")
            {
                useInfos             = new UseInfo();
                useInfos.UseInfoList = new List <string>();
            }
            else
            {
                useInfos = JsonConvert.DeserializeObject <UseInfo>(licInfo.UseInfo);
            }

            // Mac;DomainName;UserName
            string iUseInfo     = lics[2] + ";" + lics[3] + ";" + lics[4];
            bool   isRegistered = false;
            int    days         = Convert.ToInt32(lics[5]);
            int    tDay         = Convert.ToInt32(span.TotalDays);
            string borrowDate   = nowEST.AddDays((days < tDay) ? days : tDay).ToString("yyyyMMMdd", ci);

            for (int i = 0; i < useInfos.UseInfoList.Count; ++i)
            {
                if (useInfos.UseInfoList[i].IndexOf(iUseInfo) >= 0)
                {
                    useInfos.UseInfoList[i] = iUseInfo + ";" + InfoItem.Borrow + borrowDate;
                    licInfo.UseInfo         = JsonConvert.SerializeObject(useInfos, Formatting.Indented);

                    try {
                        // https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/
                        TableOperation mergeOperation = TableOperation.Merge(licInfo);
                        table.Execute(mergeOperation);
                    } catch (StorageException) {
                        result = "Wrong with Borrowing License, Please try it again.";
                        return(result);
                    }

                    isRegistered = true;
                    break;
                }
            }

            if (isRegistered)
            {
                System.Text.Encoding ascii = System.Text.Encoding.ASCII;
                result += ";" + Convert.ToBase64String(ascii.GetBytes(borrowDate));
                // encrypt iUseInfo + cpuID
                using (MD5 md5Hash = MD5.Create()) {
                    result += ";" + GetMd5Hash(md5Hash, lics[2]);
                    if (lics.Length > 5)
                    {
                        result += ";" + GetMd5Hash(md5Hash, lics[6]);
                    }
                }
            }
            else
            {
                result = CommandResult.LicenseUsed + ";FULL";
            }

            return(result);
        }