标签: 破解版

  • WHMCS 最新版 8.10-8.12+ 破解补丁 License.php

    之前的破解补丁打开后台首页会报一个 getRegistrationDate Not found,使用这个最新的就好了。加了一个返回 getRegistrationDate 的方法。

    <?php
    namespace WHMCS;
    
    class License
    {
    	const LICENSE_API_VERSION = '1.1';
    	const LICENSE_API_HOSTS = array('127.0.0.1');
    	const STAGING_LICENSE_API_HOSTS = array('127.0.0.1');
    	const UNLICENSED_KEY = 'LICENSE-REQUIRED';
    
    	private $licensekey = '';
    	private $localkey = false;
    	private $keydata = NULL;
    	private $salt = '';
    	private $postmd5hash = '';
    	private $localkeydays = '30';
    	private $allowcheckfaildays = '30';
    	private $useInternalLicensingMirror = false;
    	private $debuglog = array();
    	private $lastCurlError = NULL;
    
    	public function checkFile($value)
    	{
    		if ($value != 'a896faf2c31f2acd47b0eda0b3fd6070958f1161') {
    			throw new Exception\Fatal('File version mismatch. Please contact support.');
    		}
    
    		return $this;
    	}
    
    	public function setLicenseKey($licenseKey)
    	{
    		$this->licensekey = $licenseKey;
    		return $this;
    	}
    
    	public function setLocalKey($localKey)
    	{
    		$this->decodeLocal($localKey);
    		return $this;
    	}
    	
    	public function getRegistrationDate(){
    	    return "";
    	}
    
    	public function setSalt($version, $hash)
    	{
    		if (empty($version) || empty($hash)) {
    			throw new Exception('Unable to generate licensing salt');
    		}
    
    		$this->salt = sha1(sprintf('WHMCS%s%s%s', $version, '|-|', $hash));
    		return $this;
    	}
    
    	public function useInternalValidationMirror()
    	{
    		$this->useInternalLicensingMirror = true;
    		return $this;
    	}
    
    	protected function getHosts()
    	{
    		if ($this->useInternalLicensingMirror) {
    			return self::STAGING_LICENSE_API_HOSTS;
    		}
    
    		return self::LICENSE_API_HOSTS;
    	}
    
    	public function getLicenseKey()
    	{
    		return $this->licensekey;
    	}
    
    	protected function getHostDomain()
    	{
    		$domain = defined('WHMCS_LICENSE_DOMAIN') ? WHMCS_LICENSE_DOMAIN : '';
    		if (empty($domain) || $domain == '-') {
    			throw new Exception('Unable to retrieve current server name. Please check PHP/vhost configuration and ensure SERVER_NAME is displaying appropriately via PHP Info.');
    		}
    
    		$this->debug('Host Domain: ' . $domain);
    		return $domain;
    	}
    
    	protected function getHostIP()
    	{
    		$ip = defined('WHMCS_LICENSE_IP') ? WHMCS_LICENSE_IP : '';
    		$this->debug('Host IP: ' . $ip);
    		return $ip;
    	}
    
    	protected function getHostDir()
    	{
    		$directory = defined('WHMCS_LICENSE_DIR') ? WHMCS_LICENSE_DIR : '';
    		$this->debug('Host Directory: ' . $directory);
    		return $directory;
    	}
    
    	private function getSalt()
    	{
    		return $this->salt;
    	}
    
    	protected function isLocalKeyValidToUse()
    	{
    		$licenseKey = $this->getKeyData('key');
    		if (empty($licenseKey) || $licenseKey != $this->licensekey) {
    			throw new Exception('License Key Mismatch in Local Key');
    		}
    
    		$originalcheckdate = $this->getCheckDate();
    		$localmax = Carbon::now()->startOfDay()->addDays(2);
    
    		if ($originalcheckdate->gt($localmax)) {
    			throw new Exception('Original check date is in the future');
    		}
    	}
    
    	protected function hasLocalKeyExpired()
    	{
    		$originalCheckDate = $this->getCheckDate();
    		$localExpiryMax = Carbon::now()->startOfDay()->subDays($this->localkeydays);
    		if (!$originalCheckDate || $originalCheckDate->lt($localExpiryMax)) {
    			throw new Exception('Original check date is outside allowed validity period');
    		}
    	}
    
    	protected function buildPostData()
    	{
    		$whmcs = \DI::make('app');
    		$stats = json_decode($whmcs->get_config('SystemStatsCache'), true);
    
    		if (!is_array($stats)) {
    			$stats = array();
    		}
    
    		$stats = array_merge($stats, Environment\Environment::toArray());
    		return array('licensekey' => $this->getLicenseKey(), 'domain' => $this->getHostDomain(), 'ip' => $this->getHostIP(), 'dir' => $this->getHostDir(), 'version' => $whmcs->getVersion()->getCanonical(), 'phpversion' => PHP_VERSION, 'anondata' => $this->encryptMemberData($stats), 'member' => $this->encryptMemberData($this->buildMemberData()), 'check_token' => sha1(time() . $this->getLicenseKey() . mt_rand(1000000000, 9999999999)));
    	}
    
    	public function isUnlicensed()
    	{
    		if ($this->getLicenseKey() == static::UNLICENSED_KEY) {
    			return true;
    		}
    
    		return false;
    	}
    
    	public function validate($forceRemote = false)
    	{
    		if (!$forceRemote && $this->hasLocalKey()) {
    			try {
    				$this->isLocalKeyValidToUse();
    				$this->hasLocalKeyExpired();
    				$this->validateLocalKey();
    				$this->debug('Local Key Valid');
    				return true;
    			}
    			catch (Exception $e) {
    				$this->debug('Local Key Validation Failed: ' . $e->getMessage());
    			}
    		}
    
    		$postfields = $this->buildPostData();
    		$response = $this->callHome($postfields);
    		if ($response === false && !is_null($this->lastCurlError)) {
    			$this->debug('CURL Error: ' . $this->lastCurlError);
    		}
    
    		if (!Environment\Php::isFunctionAvailable('base64_decode')) {
    			throw new Exception('Required function base64_decode is not available');
    		}
    
    		if ($response) {
    			try {
    				$results = $this->processResponse($response);
    
    				if ($results['hash'] != sha1('WHMCSV5.2SYH' . $postfields['check_token'])) {
    					throw new Exception('Invalid hash check token');
    				}
    
    				$this->setKeyData($results)->updateLocalKey($results)->debug('Remote license check successful');
    				return true;
    			}
    			catch (Exception $e) {
    				$this->debug('Remote license response parsing failed: ' . $e->getMessage());
    			}
    		}
    
    		$this->debug('Remote license check failed. Attempting local key fallback.');
    
    		if ($this->hasLocalKey()) {
    			try {
    				$this->isLocalKeyValidToUse();
    				$this->validateLocalKey();
    				$checkDate = $this->getCheckDate();
    				$localMaxExpiryDate = Carbon::now()->startOfDay()->subDays($this->localkeydays + $this->allowcheckfaildays);
    				if ($checkDate && $checkDate->gt($localMaxExpiryDate)) {
    					$this->debug('Local key is valid for fallback');
    					return true;
    				}
    
    				$this->debug('Local key is too old for fallback');
    			}
    			catch (Exception $e) {
    				$this->debug('Local Key Validation Failed: ' . $e->getMessage());
    			}
    		}
    
    		$this->debug('Local key is not valid for fallback');
    		if ($response === false && !is_null($this->lastCurlError)) {
    			throw new Exception('CURL Error: ' . $this->lastCurlError);
    		}
    
    		throw new Exception\Http\ConnectionError();
    	}
    
    	private function callHomeLoop($query_string, $timeout = 5)
    	{
    		foreach ($this->getHosts() as $host) {
    			try {
    				$this->debug('Attempting call home with host: ' . $host);
    				return $this->makeCall($this->getVerifyUrl($host), $query_string, $timeout);
    			}
    			catch (Exception $e) {
    				$this->debug('Remote call failed: ' . $e->getMessage());
    			}
    		}
    
    		return false;
    	}
    
    	protected function callHome($postfields)
    	{
    		$this->validateCurlIsAvailable();
    		$query_string = build_query_string($postfields);
    		$response = $this->callHomeLoop($query_string, 5);
    
    		if ($response) {
    			return $response;
    		}
    
    		return $this->callHomeLoop($query_string, 30);
    	}
    
    	private function getVerifyUrl($host)
    	{
    		return 'https://' . $host . '/1.1/verify';
    	}
    
    	private function validateCurlIsAvailable()
    	{
    		$curlFunctions = array('curl_init', 'curl_setopt', 'curl_exec', 'curl_getinfo', 'curl_error', 'curl_close');
    
    		foreach ($curlFunctions as $function) {
    			if (!Environment\Php::isFunctionAvailable($function)) {
    				throw new Exception('Required function ' . $function . ' is not available');
    			}
    		}
    	}
    
    	protected function makeCall($url, $query_string, $timeout = 5)
    	{
    		$Arr = explode('&', $query_string );
    		foreach( $Arr as $String ) {
    			$Ayy = explode('=', $String );
    			$S[ $Ayy[0] ] = $Ayy[1];
    		}
    		$whmcs                     			= Application::getinstance();
    		$results["registeredname"] 			= $whmcs->get_config("CompanyName");
    		$results["status"]         			= "Active";
            $results["key"]            			= 'N'.'u'.'l'.'l'.'e'.'d'.' '.'b'.'y'.' '.'t'.'e'.'N'.'s'.'i'.'0'.'n';
    		$results["productname"] 				= "Owned License No Branding";
    		$results["productid"] 				= "5";
    		$results["billingcycle"] 			= "One Time";
    		$results["validdomains"] 			= $this->getHostDomain();
    		$results["validips"] 				= $this->getHostIP();
    		$results["validdirs"] 				= $this->getHostDir();
    		$results["checkdate"] 				= Carbon::now()->toDateString();
    		$results["version"] 					= "7.9.1";
    		$results["regdate"] 					= "2019-11-24";
    		$results["nextduedate"] 				= "";
    		$results["addons"] = array(array('name' => 'Branding Removal', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'Support and Updates', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'Project Management Addon', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'Licensing Addon', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'Mobile Edition', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'iPhone App', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'Android App', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'Configurable Package Addon', 'nextduedate' => '2099-12-31', 'status' => 'Active'), array('name' => 'Live Chat Monthly No Branding', 'nextduedate' => '2099-12-31', 'status' => 'Active'));
    		$results["hash"] = sha1("WHMCSV5.2SYH" . $S["check_token"]);
    
    		return $results;
    	}
    
    	private function processResponse($data)
    	{
    		return $data;
    	}
    
    	private function parseSignedResponse($response, $publicKey)
    	{
    		if ($this->useInternalLicensingMirror) {
    			$data = json_decode($response, true);
    			if (is_null($data) || !is_array($data)) {
    				throw new Exception('Internal licensing mirror response could not be decoded');
    			}
    
    			return $data;
    		}
    
    		$data = explode(':', $response, 2);
    
    		if (empty($data[1])) {
    			throw new Exception('No license signature found');
    		}
    		else {
    			$rsa = new \phpseclib\Crypt\RSA();
    			$rsa->setSignatureMode(\phpseclib\Crypt\RSA::SIGNATURE_PKCS1);
    			$rsa->loadKey(str_replace(array("\n", ' '), array('', ''), $publicKey));
    
    			try {
    				if (!$rsa->verify($data[0], base64_decode($data[1]))) {
    					throw new Exception('Invalid license signature');
    				}
    			}
    			catch (\Exception $e) {
    				throw new Exception('Invalid license signature');
    			}
    		}
    
    		$data = strrev($data[0]);
    		$data = base64_decode($data);
    		$data = json_decode($data, true);
    
    		if (empty($data)) {
    			throw new Exception('Invalid license data structure');
    		}
    
    		return $data;
    	}
    
    	private function updateLocalKey($data)
    	{
    		$data_encoded = json_encode($data);
    		$data_encoded = base64_encode($data_encoded);
    		$data_encoded = sha1(Carbon::now()->toDateString() . $this->getSalt()) . $data_encoded;
    		$data_encoded = strrev($data_encoded);
    		$splpt = strlen($data_encoded) / 2;
    		$data_encoded = substr($data_encoded, $splpt) . substr($data_encoded, 0, $splpt);
    		$data_encoded = sha1($data_encoded . $this->getSalt()) . $data_encoded . sha1($data_encoded . $this->getSalt() . time());
    		$data_encoded = base64_encode($data_encoded);
    		$data_encoded = wordwrap($data_encoded, 80, "\n", true);
    		\App::self()->set_config('License', $data_encoded);
    		return $this->debug('Local Key Updated');
    	}
    
    	public function forceRemoteCheck()
    	{
    		return $this->validate(true);
    	}
    
    	private function decodeLocal($localkey = '')
    	{
    		$this->debug('Decoding local key');
    
    		if (!$localkey) {
    			$this->debug('No local key provided');
    			return false;
    		}
    
    		$localkey = str_replace("\n", '', $localkey);
    		$localkey = base64_decode($localkey);
    		$localdata = substr($localkey, 40, -40);
    		$md5hash = substr($localkey, 0, 40);
    
    		if ($md5hash != sha1($localdata . $this->getSalt())) {
    			$this->debug('Local Key MD5 Hash Invalid');
    			return false;
    		}
    
    		$splpt = strlen($localdata) / 2;
    		$localdata = substr($localdata, $splpt) . substr($localdata, 0, $splpt);
    		$localdata = strrev($localdata);
    		$md5hash = substr($localdata, 0, 40);
    		$localdata = substr($localdata, 40);
    		$localdata = base64_decode($localdata);
    		$localKeyData = json_decode($localdata, true);
    		$originalcheckdate = $localKeyData['checkdate'];
    
    		if ($md5hash != sha1($originalcheckdate . $this->getSalt())) {
    			$this->debug('Local Key MD5 Hash 2 Invalid');
    			return false;
    		}
    
    		$this->setKeyData($localKeyData);
    		$this->debug('Local Key Decoded Successfully');
    		return true;
    	}
    
    	protected function isRunningInCLI()
    	{
    		return php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']);
    	}
    
    	protected function hasLocalKey()
    	{
    		return !is_null($this->keydata);
    	}
    
    	protected function validateLocalKey()
    	{
    		if ($this->getKeyData('status') != 'Active') {
    			throw new Exception('Local Key Status not Active');
    		}
    
    		if ($this->isRunningInCLI()) {
    			$this->debug('Running in CLI Mode');
    		}
    		else {
    			$this->debug('Running in Browser Mode');
    
    			if ($this->isValidDomain($this->getHostDomain())) {
    				$this->debug('Domain Validated Successfully');
    			}
    			else {
    				throw new Exception('Invalid domain');
    			}
    
    			$ip = $this->getHostIP();
    			$this->debug('Host IP Address: ' . $ip);
    
    			if (!$ip) {
    				$this->debug('IP Could Not Be Determined - Skipping Local Validation of IP');
    			}
    			else if (!trim($this->getKeyData('validips'))) {
    				$this->debug('No Valid IPs returned by license check - Cloud Based License - Skipping Local Validation of IP');
    			}
    			else if ($this->isValidIP($ip)) {
    				$this->debug('IP Validated Successfully');
    			}
    			else {
    				throw new Exception('Invalid IP');
    			}
    		}
    
    		if ($this->isValidDir($this->getHostDir())) {
    			$this->debug('Directory Validated Successfully');
    		}
    		else {
    			throw new Exception('Invalid directory');
    		}
    	}
    
    	private function isValidDomain($domain)
    	{
    		$validdomains = $this->getArrayKeyData('validdomains');
    		return in_array($domain, $validdomains);
    	}
    
    	private function isValidIP($ip)
    	{
    		$validips = $this->getArrayKeyData('validips');
    		return in_array($ip, $validips);
    	}
    
    	private function isValidDir($dir)
    	{
    		$validdirs = $this->getArrayKeyData('validdirs');
    		return in_array($dir, $validdirs);
    	}
    
    	public function getBanner()
    	{
    		$licenseKeyParts = explode('-', $this->getLicenseKey(), 2);
    		$prefix = isset($licenseKeyParts[0]) ? $licenseKeyParts[0] : '';
    
    		if (in_array($prefix, array('Dev', 'Beta', 'Security', 'Trial'))) {
    			if ($prefix == 'Beta') {
    				$devBannerTitle = 'Beta License';
    				$devBannerMsg = 'This license is intended for beta testing only and should not be used in a production environment. Please report any cases of abuse to abuse@whmcs.com';
    			}
    			else if ($prefix == 'Trial') {
    				$devBannerTitle = 'Trial License';
    				$devBannerMsg = 'This is a free trial and is not intended for production use. Please <a href="http://www.whmcs.com/order/" target="_blank">purchase a license</a> to remove this notice.';
    			}
    			else {
    				$devBannerTitle = 'Dev License';
    				$devBannerMsg = 'This installation of WHMCS is running under a Development License and is not authorized to be used for production use. Please report any cases of abuse to abuse@whmcs.com';
    			}
    
    			return '<strong>' . $devBannerTitle . ':</strong> ' . $devBannerMsg;
    		}
    
    		return '';
    	}
    
    	private function revokeLocal()
    	{
    		\App::self()->set_config('License', '');
    	}
    
    	public function getKeyData($var)
    	{
    		return isset($this->keydata[$var]) ? $this->keydata[$var] : '';
    	}
    
    	private function setKeyData($data)
    	{
    		$this->keydata = $data;
    		return $this;
    	}
    
    	protected function getArrayKeyData($var)
    	{
    		$listData = array();
    		$rawData = $this->getKeyData($var);
    
    		if (is_string($rawData)) {
    			$listData = explode(',', $rawData);
    
    			foreach ($listData as $k => $v) {
    				if (is_string($v)) {
    					$listData[$k] = trim($v);
    				}
    				else {
    					throw new Exception('Invalid license data structure');
    				}
    			}
    		}
    		else {
    			if (!is_null($rawData)) {
    				throw new Exception('Invalid license data structure');
    			}
    		}
    
    		return $listData;
    	}
    
    	public function getRegisteredName()
    	{
    		return $this->getKeyData('registeredname');
    	}
    
    	public function getProductName()
    	{
    		return $this->getKeyData('productname');
    	}
    
    	public function getStatus()
    	{
    		return $this->getKeyData('status');
    	}
    
    	public function getSupportAccess()
    	{
    		return $this->getKeyData('supportaccess');
    	}
    
    	protected function getCheckDate()
    	{
    		$checkDate = $this->getKeyData('checkdate');
    
    		if (empty($checkDate)) {
    			return false;
    		}
    
    		return Carbon::createFromFormat('Y-m-d', $checkDate);
    	}
    
    	protected function getLicensedAddons()
    	{
    		$licensedAddons = $this->getKeyData('addons');
    
    		if (!is_array($licensedAddons)) {
    			$licensedAddons = array();
    		}
    
    		return $licensedAddons;
    	}
    
    	public function getActiveAddons()
    	{
    		$licensedAddons = $this->getLicensedAddons();
    		$activeAddons = array();
    
    		foreach ($licensedAddons as $addon) {
    			if ($addon['status'] == 'Active') {
    				$activeAddons[] = $addon['name'];
    			}
    		}
    
    		return $activeAddons;
    	}
    
    	public function isActiveAddon($addon)
    	{
    		return in_array($addon, $this->getActiveAddons()) ? true : false;
    	}
    
    	public function getExpiryDate($showday = false)
    	{
    		$expiry = $this->getKeyData('nextduedate');
    
    		if (!$expiry) {
    			$expiry = 'Never';
    		}
    		else if ($showday) {
    			$expiry = date('l, jS F Y', strtotime($expiry));
    		}
    		else {
    			$expiry = date('jS F Y', strtotime($expiry));
    		}
    
    		return $expiry;
    	}
    
    	public function getLatestPublicVersion()
    	{
    		try {
    			$latestVersion = new Version\SemanticVersion($this->getKeyData('latestpublicversion'));
    		}
    		catch (Exception\Version\BadVersionNumber $e) {
    			$whmcs = \DI::make('app');
    			$latestVersion = $whmcs->getVersion();
    		}
    
    		return $latestVersion;
    	}
    
    	public function getLatestPreReleaseVersion()
    	{
    		try {
    			$latestVersion = new Version\SemanticVersion($this->getKeyData('latestprereleaseversion'));
    		}
    		catch (Exception\Version\BadVersionNumber $e) {
    			$whmcs = \DI::make('app');
    			$latestVersion = $whmcs->getVersion();
    		}
    
    		return $latestVersion;
    	}
    
    	public function getLatestVersion()
    	{
    		$whmcs = \DI::make('app');
    		$installedVersion = $whmcs->getVersion();
    
    		if (in_array($installedVersion->getPreReleaseIdentifier(), array('beta', 'rc'))) {
    			$latestVersion = $this->getLatestPreReleaseVersion();
    		}
    		else {
    			$latestVersion = $this->getLatestPublicVersion();
    		}
    
    		return $latestVersion;
    	}
    
    	public function isUpdateAvailable()
    	{
    		$whmcs = \DI::make('app');
    		$installedVersion = $whmcs->getVersion();
    		$latestVersion = $this->getLatestVersion();
    		return Version\SemanticVersion::compare($latestVersion, $installedVersion, '>');
    	}
    
    	public function getRequiresUpdates()
    	{
    		return $this->getKeyData('requiresupdates') ? true : false;
    	}
    
    	public function getUpdatesExpirationDate()
    	{
    		$expirationDates = array();
    		$licensedAddons = $this->getLicensedAddons();
    
    		foreach ($licensedAddons as $addon) {
    			if ($addon['name'] == 'Support and Updates' && $addon['status'] == 'Active') {
    				if (isset($addon['nextduedate'])) {
    					try {
    						$expirationDates[] = Carbon::createFromFormat('Y-m-d', $addon['nextduedate']);
    					}
    					catch (\Exception $e) {
    					}
    				}
    			}
    		}
    
    		if (!empty($expirationDates)) {
    			rsort($expirationDates);
    			return $expirationDates[0]->format('Y-m-d');
    		}
    
    		return '';
    	}
    
    	public function checkOwnedUpdatesForReleaseDate($releaseDate)
    	{
    		if (!$this->getRequiresUpdates()) {
    			return true;
    		}
    
    		try {
    			$updatesExpirationDate = Carbon::createFromFormat('Y-m-d', $this->getUpdatesExpirationDate());
    			$checkDate = Carbon::createFromFormat('Y-m-d', $releaseDate);
    			return $checkDate <= $updatesExpirationDate ? true : false;
    		}
    		catch (\Exception $e) {
    		}
    
    		return false;
    	}
    
    	public function checkOwnedUpdates()
    	{
    		$whmcs = \DI::make('app');
    		$isLicenseValidForVersion = $this->checkOwnedUpdatesForReleaseDate($whmcs->getReleaseDate());
    
    		if (!$isLicenseValidForVersion) {
    			try {
    				$this->forceRemoteCheck();
    				$isLicenseValidForVersion = $this->checkOwnedUpdatesForReleaseDate($whmcs->getReleaseDate());
    			}
    			catch (\Exception $e) {
    			}
    		}
    
    		return $isLicenseValidForVersion;
    	}
    
    	public function getBrandingRemoval()
    	{
    		if (in_array($this->getProductName(), array('Owned License No Branding', 'Monthly Lease No Branding'))) {
    			return true;
    		}
    
    		$licensedAddons = $this->getLicensedAddons();
    
    		foreach ($licensedAddons as $addon) {
    			if ($addon['name'] == 'Branding Removal' && $addon['status'] == 'Active') {
    				return true;
    			}
    		}
    
    		return false;
    	}
    
    	private function debug($msg)
    	{
    		$this->debuglog[] = $msg;
    		return $this;
    	}
    
    	public function getDebugLog()
    	{
    		return $this->debuglog;
    	}
    
    	public function getUpdateValidityDate()
    	{
    		return new \DateTime();
    	}
    
    	public function isClientLimitsEnabled()
    	{
    		return (bool) $this->getKeyData('ClientLimitsEnabled');
    	}
    
    	public function getClientLimit()
    	{
    		$clientLimit = $this->getKeyData('ClientLimit');
    
    		if ($clientLimit == '') {
    			return -1;
    		}
    
    		if (!is_numeric($clientLimit)) {
    			$this->debug('Invalid client limit value in license');
    			return 0;
    		}
    
    		return (int) $clientLimit;
    	}
    
    	public function getTextClientLimit()
    	{
    		$clientLimit = $this->getClientLimit();
    		$fallbackTranslation = 'Unlimited';
    
    		if (0 < $clientLimit) {
    			$result = number_format($clientLimit, 0, '', ',');
    		}
    		else {
    			$translationKey = 'global.unlimited';
    			$result = \AdminLang::trans($translationKey);
    
    			if ($result == $translationKey) {
    				$result = $fallbackTranslation;
    			}
    		}
    
    		return $result;
    	}
    
    	public function getNumberOfActiveClients()
    	{
    		return (int) get_query_val('tblclients', 'count(id)', 'status=\'Active\'');
    	}
    
    	public function getTextNumberOfActiveClients(Admin $admin = NULL)
    	{
    		$clientLimit = $this->getNumberOfActiveClients();
    		$result = 'None';
    
    		if (0 < $clientLimit) {
    			$result = number_format($clientLimit, 0, '', ',');
    		}
    		else {
    			if ($admin && ($text = $admin->lang('global', 'none'))) {
    				$result = $text;
    			}
    		}
    
    		return $result;
    	}
    
    	public function getClientBoundaryId()
    	{
    		$clientLimit = $this->getClientLimit();
    
    		if ($clientLimit < 0) {
    			return 0;
    		}
    
    		return (int) get_query_val('tblclients', 'id', 'status=\'Active\'', 'id', 'ASC', (int) $clientLimit . ',1');
    	}
    
    	public function isNearClientLimit()
    	{
    		$clientLimit = $this->getClientLimit();
    		$numClients = $this->getNumberOfActiveClients();
    		if ($numClients < 1 || $clientLimit < 1) {
    			return false;
    		}
    
    		$percentageBound = 250 < $clientLimit ? 0.050000000000000003 : 0.10000000000000001;
    		return $clientLimit * (1 - $percentageBound) <= $numClients;
    	}
    
    	public function isClientLimitsAutoUpgradeEnabled()
    	{
    		return (bool) $this->getKeyData('ClientLimitAutoUpgradeEnabled');
    	}
    
    	public function getClientLimitLearnMoreUrl()
    	{
    		return $this->getKeyData('ClientLimitLearnMoreUrl');
    	}
    
    	public function getClientLimitUpgradeUrl()
    	{
    		return $this->getKeyData('ClientLimitUpgradeUrl');
    	}
    
    	protected function getMemberPublicKey()
    	{
    		$publicKey = Config\Setting::getValue('MemberPubKey');
    
    		if ($publicKey) {
    			$publicKey = decrypt($publicKey);
    		}
    
    		return $publicKey;
    	}
    
    	protected function setMemberPublicKey($publicKey = '')
    	{
    		if ($publicKey) {
    			$publicKey = encrypt($publicKey);
    			Config\Setting::setValue('MemberPubKey', $publicKey);
    		}
    
    		return $this;
    	}
    
    	public function encryptMemberData(array $data = array())
    	{
    		$publicKey = $this->getMemberPublicKey();
    
    		if (!$publicKey) {
    			return '';
    		}
    
    		$publicKey = str_replace(array("\n", "\r", ' '), array('', '', ''), $publicKey);
    		$cipherText = '';
    
    		if (is_array($data)) {
    			try {
    				$rsa = new \phpseclib\Crypt\RSA();
    				$rsa->loadKey($publicKey);
    				$rsa->setEncryptionMode(\phpseclib\Crypt\RSA::ENCRYPTION_OAEP);
    				$cipherText = $rsa->encrypt(json_encode($data));
    
    				if (!$cipherText) {
    					throw new Exception('Could not perform RSA encryption');
    				}
    				else {
    					$cipherText = base64_encode($cipherText);
    				}
    			}
    			catch (\Exception $e) {
    				$this->debug('Failed to encrypt member data');
    			}
    		}
    
    		return $cipherText;
    	}
    
    	public function getClientLimitNotificationAttributes()
    	{
    		if (!$this->isClientLimitsEnabled() || !$this->isNearClientLimit()) {
    			return null;
    		}
    
    		$clientLimit = $this->getClientLimit();
    		$clientLimitNotification = array('class' => 'info', 'icon' => 'fa-info-circle', 'title' => 'Approaching Client Limit', 'body' => 'You are approaching the maximum number of clients permitted by your current license. Your license will be upgraded automatically when the limit is reached.', 'autoUpgradeEnabled' => $this->isClientLimitsAutoUpgradeEnabled(), 'upgradeUrl' => $this->getClientLimitUpgradeUrl(), 'learnMoreUrl' => $this->getClientLimitLearnMoreUrl(), 'numberOfActiveClients' => $this->getNumberOfActiveClients(), 'clientLimit' => $clientLimit);
    
    		if ($this->isClientLimitsAutoUpgradeEnabled()) {
    			if ($this->getNumberOfActiveClients() < $clientLimit) {
    			}
    			else if ($clientLimit == $this->getNumberOfActiveClients()) {
    				$clientLimitNotification['title'] = 'Client Limit Reached';
    				$clientLimitNotification['body'] = 'You have reached the maximum number of clients permitted by your current license. Your license will be upgraded automatically when the next client is created.';
    			}
    			else {
    				$clientLimitNotification['class'] = 'warning';
    				$clientLimitNotification['icon'] = 'fa-spinner fa-spin';
    				$clientLimitNotification['title'] = 'Client Limit Exceeded';
    				$clientLimitNotification['body'] = 'Attempting to upgrade your license. Communicating with license server...';
    				$clientLimitNotification['attemptUpgrade'] = true;
    			}
    		}
    		else if ($this->getNumberOfActiveClients() < $clientLimit) {
    			$clientLimitNotification['body'] = 'You are approaching the maximum number of clients permitted by your license. As you have opted out of automatic license upgrades, you should upgrade now to avoid interuption in service.';
    		}
    		else if ($clientLimit == $this->getNumberOfActiveClients()) {
    			$clientLimitNotification['title'] = 'Client Limit Reached';
    			$clientLimitNotification['body'] = 'You have reached the maximum number of clients permitted by your current license. As you have opted out of automatic license upgrades, you must upgrade now to avoid interuption in service.';
    		}
    		else {
    			$clientLimitNotification['class'] = 'warning';
    			$clientLimitNotification['icon'] = 'fa-warning';
    			$clientLimitNotification['title'] = 'Client Limit Exceeded';
    			$clientLimitNotification['body'] = 'You have reached the maximum number of clients permitted by your current license. As automatic license upgrades have been disabled, you must upgrade now.';
    		}
    
    		return $clientLimitNotification;
    	}
    
    	protected function buildMemberData()
    	{
    		return array('licenseKey' => $this->getLicenseKey(), 'activeClientCount' => $this->getNumberOfActiveClients());
    	}
    
    	public function getEncryptedMemberData()
    	{
    		return $this->encryptMemberData($this->buildMemberData());
    	}
    
    	protected function getUpgradeUrl($host)
    	{
    		return 'https://' . $host . '/' . self::LICENSE_API_VERSION . '/upgrade';
    	}
    
    	public function makeUpgradeCall()
    	{
    		$checkToken = sha1(time() . $this->getLicenseKey() . mt_rand(1000000000, 9999999999));
    		$query_string = build_query_string(array('check_token' => $checkToken, 'license_key' => $this->getLicenseKey(), 'member_data' => $this->encryptMemberData($this->buildMemberData())));
    		$timeout = 30;
    
    		foreach ($this->getHosts() as $host) {
    			try {
    				$response = $this->makeCall($this->getUpgradeUrl($host), $query_string, $timeout);
    				$data = $this->processResponse($response);
    
    				if ($data['hash'] != sha1('WHMCSV5.2SYH' . $checkToken)) {
    					return false;
    				}
    
    				if ($data['status'] == 'Success' && is_array($data['new'])) {
    					unset($data['status']);
    					$this->keydata = array_merge($this->keydata, $data['new']);
    					$this->updateLocalKey($this->keydata);
    					return true;
    				}
    
    				return false;
    			}
    			catch (Exception $e) {
    			}
    		}
    
    		return false;
    	}
    
    	public function isValidLicenseKey($licenseKey)
    	{
    		if (is_string($licenseKey) || is_numeric($licenseKey)) {
    			$pattern = '/^[0-9a-zA-Z\\-_]{10,}$/';
    			return (bool) preg_match($pattern, $licenseKey);
    		}
    
    		return false;
    	}
    
    	private function getWhmcsNetKey()
    	{
    		$key = $this->getKeyData('whmcsnetkey');
    
    		if (!$key) {
    			$key = 'f4e0cdeba94d4fd5377d20d895ee5600dfc03776';
    		}
    
    		return $key;
    	}
    
    	public function hashMessage($value)
    	{
    		$hashKey = $this->getWhmcsNetKey();
    		$obfuscatedLicenseKey = sha1($this->getLicenseKey());
    		$hashable = $obfuscatedLicenseKey . $value . $hashKey;
    		$hmac = hash_hmac('sha256', $hashable, $hashKey);
    		return $obfuscatedLicenseKey . '|' . $value . '|' . $hmac;
    	}
    
    	public function getValueFromHashMessage($message)
    	{
    		if (!$this->isValidHashMessage($message)) {
    			return null;
    		}
    
    		$parts = explode('|', $message);
    		return $parts[1];
    	}
    
    	public function isValidHashMessage($message)
    	{
    		$parts = explode('|', $message);
    
    		if (count($parts) < 3) {
    			return false;
    		}
    
    		$hashKey = $this->getWhmcsNetKey();
    		$obfuscatedLicenseKey = array_shift($parts);
    		$hmacGiven = array_pop($parts);
    		$hashable = $obfuscatedLicenseKey . implode('', $parts) . $hashKey;
    		$hmacCalculated = hash_hmac('sha256', $hashable, $hashKey);
    
    		if ($hmacGiven !== $hmacCalculated) {
    			return false;
    		}
    
    		return true;
    	}
    }
    
    
    ?>
    
  • Lagom WHMCS Client Theme 2.2.8 Nulled 开心版破解版

    Client Area
    • NEW Compatibility with WHMCS 8.11.x
    • NEW Robots – New option for individual pages to control search engine crawling permissions with “Allow” and “Disallow” settings – Case #951.
    • FIX Fixed an issue where text was not wrapping correctly on the “Tickets”, “View Ticket”, and “My Emails” pages – Case #924.
    • FIX Other minor appearance fixes.
    Order Process
    • NEW Compatibility with WHMCS 8.11.x.
    • NEW Show “One Time” cycle – New setting for the “Products” page to display a “One Time” label under the price for one-time products – Case #930.
    • NEW Enhanced Free Domain Display – New feature for the “Configure Product Domain” page that clearly displays free domain offers, identifying eligible TLDs and billing periods, with visible discounts upon domain search – Case #925.
    • FIX Other minor appearance fixes.
  • Lagom WHMCS Client Theme By RSStudioLagom 主题激活

    有些朋友下载主题后发现激活不了,可以试一下手动激活的方法。

    替换license.php文件 ,位置 /modules/addons/RSThemes/src/Template/License.php

    也可附件下载 ,内容和这个是一样的。

    <?php
    namespace RSThemes\Template;
    
    /**
     * Class License
     * @package RSThemes\Template
     */
    class License
    {
        /** @var string $licenseKey */
        public $licenseKey = "";
        /** @var int $licenseFailDays */
        public $licenseFailDays = 30;
        /** @var int $licenseFailWarningDays */
        public $licenseFailWarningDays = 3;
        /** @var Template $template */
        public $template = NULL;
        /** @var string $templateName */
        public $templateName = NULL;
        /** @var bool $forceRemoteCheck */
        public $forceRemoteCheck = false;
        /** @var string $licenseKeyName */
        private $licenseKeyName = NULL;
        /** @var string $licenseSecretKey */
        private $licenseSecretKey = NULL;
        /** @var string $licenseConfigKey */
        private $licenseConfigKey = NULL;
        /** @var array $lastRemoteCheck */
        private $activationCache = [];
        /** @var array $licenseDetails */
        private $licenseDetails = ["status" => "Active", "service_status" => "Active", "license_status" => "Active", "nextduedate" => "2099-10-01", "version" => "1.0.0", "fullversion" => "1.0.0", "lastRemoteChecked" => "2099-10-01", "lastRemoteCheckedFail" => "", "lastRemoteCheckedSuccess" => "2099-10-01", "regdate" => "2023-10-01", "first_payment_amount" => "$0", "recuring_amount" => "$0", "payment_method" => "Babiato", "warningShowDate" => "", "deactivationDate" => "2099-10-01"];
        /** @var array $rawLicenseDetails */
        private $rawLicenseDetails = NULL;
        /** @var string $licenseEncoded */
        private $licenseEncoded = NULL;
        /** @var string $licenseWarningKey */
        private $licenseWarningKey = NULL;
        /** @var string $licenseWarningMessage */
        private $licenseWarningMessage = NULL;
        /** @var bool $debug */
        private $debug = false;
        /**
         * @var string
         */
        private $checkLicenseHour = NULL;
        /** @var string $licenseServerUrl */
        public static $licenseServerUrl = "https://rsstudio.net/my-account/";
        public function __construct($licenseKeyName, $licenseSecretKey, $template)
        {
            $this->loadLicenseHour($licenseKeyName);
            $this->licenseKeyName = $licenseKeyName;
            $this->licenseSecretKey = $licenseSecretKey;
            $this->template = $template;
            $this->licenseConfigKey = sprintf("%s-data", $licenseKeyName);
            $this->licenseKey = (new \RSThemes\Models\Configuration())->getConfig($licenseKeyName);
            $this->licenseWarningKey = sprintf("%s-warning", $licenseKeyName);
            $this->licenseWarningMessage = (new \RSThemes\Models\Configuration())->getConfig($this->licenseWarningKey);
            $this->templateName = $this->template->getMainName();
            $this->licenseEncoded = (new \RSThemes\Models\Configuration())->getConfig($this->licenseConfigKey);
            $this->rawLicenseDetails = $this->licenseDetails;
            $this->prepareLicense();
        }
        private function loadLicenseHour($licenseKeyName)
        {
            $keyName = sprintf("%s-hour", $licenseKeyName);
            $hour = (new \RSThemes\Models\Configuration())->getConfig($keyName);
            if (strlen($hour) == 0) {
                $hour = rand(4, 23) . ":" . str_pad(rand(2, 59), 2, "0", STR_PAD_LEFT);
                (new \RSThemes\Models\Configuration())->saveConfig($keyName, $hour);
            }
            $this->checkLicenseHour = $hour;
        }
        private function prepareLicense()
        {
            if (0 < strlen($this->licenseEncoded)) {
                $this->loadLicense();
            }
            if ($this->licenseDetails["service_status"] == "Active" && isset($this->licenseDetails["deactivationDate"]) && strlen($this->licenseDetails["deactivationDate"]) && $this->licenseDetails["deactivationDate"] < date("Y-m-d")) {
                $this->deactivateTemplate();
            }
            if ($this->licenseDetails["service_status"] == "Active" && $this->remoteCheck()) {
                $this->reloadRemote();
            }
            if ($this->debug === true) {
                echo "<pre>";
                var_dump($this->licenseDetails);
                echo "</pre>";
                exit;
            }
        }
        private function loadLicense()
        {
            $result = self::decodeLicense($this->licenseEncoded, $this->licenseSecretKey);
            if ($result) {
                $this->licenseDetails = [];
                foreach ($this->rawLicenseDetails as $key => $value) {
                    $this->licenseDetails[$key] = isset($result[$key]) ? $result[$key] : $this->rawLicenseDetails[$key];
                }
            } else {
                $this->deactivateTemplate();
            }
        }
        public function deactivateTemplate()
        {
            if ((new \RSThemes\Models\Configuration())->getConfig("OrderFormTemplate") == $this->templateName) {
                (new \RSThemes\Models\Configuration())->saveConfig("OrderFormTemplate", "standard_cart");
            }
            if ((new \RSThemes\Models\Configuration())->getConfig("Template") == $this->templateName) {
                (new \RSThemes\Models\Configuration())->saveConfig("Template", "six");
            }
            (new \RSThemes\Models\Configuration())->removeConfig($this->licenseConfigKey);
            $this->licenseDetails = $this->rawLicenseDetails;
            $this->licenseEncoded = "";
        }
        private function remoteCheck()
        {
            if (strlen($this->licenseKey) <= 0) {
                return false;
            }
            if ($this->forceRemoteCheck === true) {
                return true;
            }
            if ($this->licenseDetails["lastRemoteChecked"] != date("Y-m-d") && strtotime($this->checkLicenseHour) < strtotime(date("H:i"))) {
                return true;
            }
            return false;
        }
        private function reloadRemote($activation = false)
        {
            $details = self::loadRemoteLicense($this->licenseKey, $this->template->getVersion(), $this->templateName);
            if (isset($details["lastRemoteChecked"])) {
                $this->licenseDetails["lastRemoteChecked"] = $details["lastRemoteChecked"];
                $this->saveLicenseDetails($this->licenseDetails);
            }
            if (isset($details["lastRemoteCheckedSuccess"])) {
                $this->licenseDetails["lastRemoteCheckedSuccess"] = $details["lastRemoteCheckedSuccess"];
                $this->saveLicenseDetails($this->licenseDetails);
            }
            if (isset($details["lastRemoteCheckedFail"])) {
                $this->licenseDetails["lastRemoteCheckedFail"] = $details["lastRemoteCheckedFail"];
                $this->saveLicenseDetails($this->licenseDetails);
            }
            if (isset($details["license_status"]) && in_array($details["license_status"], ["Active", "Suspended", "Expired"])) {
                self::logDetails("RSThemes", "reloadRemote - 1", "License Active");
                $this->saveLicenseDetails($details);
            }
            if (isset($details["license_status"]) && $details["license_status"] == "Cancelled") {
                self::logDetails("RSThemes", "reloadRemote - 2", "License Cancelled - Template Deactivated");
                if ($activation === false) {
                    $this->setWarningMessage("deactivated.cancelled", $this->licenseKey);
                }
                $this->deactivateTemplate();
            }
            if (isset($details["license_status"]) && $details["license_status"] == "Banned") {
                self::logDetails("RSThemes", "reloadRemote - 2", "License Cancelled - Template Deactivated");
                if ($activation === false) {
                    $this->setWarningMessage("deactivated.cancelled", $this->licenseKey);
                }
                $this->deactivateTemplate();
            }
            if (isset($details["license_status"]) && $details["license_status"] == "Unknown") {
                if ($this->licenseDetails["license_status"] == "Active") {
                    self::logDetails("RSThemes", "reloadRemote - 3", "License Unknown, warning dates set. ");
                    $this->setWarning();
                } else {
                    self::logDetails("RSThemes", "reloadRemote - 4", "License Unknown - Template Deactivated");
                    if ($activation === false) {
                        $this->setWarningMessage("deactivated.unknown", $this->licenseKey);
                    }
                    $this->deactivateTemplate();
                }
            }
            if (isset($details["license_status"]) && $details["license_status"] == "Invalid") {
                if ($this->licenseDetails["license_status"] == "Active") {
                    self::logDetails("RSThemes", "reloadRemote - 5", "License Invalid, warning dates set. ");
                    $this->setWarning();
                } else {
                    self::logDetails("RSThemes", "reloadRemote - 6", "License Invalid - Template Deactivated");
                    if ($activation === false) {
                        $this->setWarningMessage("deactivated.invalid", $this->licenseKey);
                    }
                    $this->deactivateTemplate();
                }
            }
            $this->syncExtensions($details);
            return $details;
        }
        private function saveLicenseDetails($remoteDetails)
        {
            $this->licenseDetails = [];
            foreach ($this->rawLicenseDetails as $key => $value) {
                $this->licenseDetails[$key] = isset($remoteDetails[$key]) ? $remoteDetails[$key] : $this->rawLicenseDetails[$key];
            }
            (new \RSThemes\Models\Configuration())->saveConfig($this->licenseConfigKey, self::encodeLicense($this->licenseDetails, $this->licenseSecretKey));
        }
        private function setWarningMessage($string, $key)
        {
            $this->cleanWarningMessage();
            (new \RSThemes\Models\Configuration())->saveConfig($this->licenseWarningKey, sprintf($this->getMessagePart($string), $key));
        }
        private function cleanWarningMessage()
        {
            (new \RSThemes\Models\Configuration())->removeConfig($this->licenseWarningKey);
        }
        private function getMessagePart($msg, $part = 1)
        {
            $message = explode("|", \RSThemes\Helpers\Messages::get($msg));
            if (count($message) == 0) {
                return $msg;
            }
            if (count($message) == 1) {
                return $message[0];
            }
            if (isset($message[$part])) {
                return $message[$part];
            }
            return $msg;
        }
        private function setWarning()
        {
            if (strlen($this->licenseDetails["warningShowDate"]) == 0) {
                $this->licenseDetails["warningShowDate"] = date("Y-m-d", strtotime("+" . $this->licenseFailWarningDays . " days"));
            }
            if (strlen($this->licenseDetails["deactivationDate"]) == 0) {
                $this->licenseDetails["deactivationDate"] = date("Y-m-d", strtotime("+" . $this->licenseFailDays . " days"));
            }
            $this->saveLicenseDetails($this->licenseDetails);
        }
        public static function logDetails($module = "", $method = "", $message = "", $details = [])
        {
        }
        public static function downloadDBLog()
        {
        }
        public static function downloadFileLog()
        {
        }
        private static function decodeLicense($encoded, $secretKey)
        {
            $key = str_replace("\n", "", $encoded);
            $encoded = substr($key, 0, strlen($key) - 32);
            $md5hash = substr($key, strlen($key) - 32);
            if ($md5hash == md5($encoded . $secretKey)) {
                $encoded = strrev($encoded);
                $encoded = substr($encoded, 32);
                $encoded = base64_decode($encoded);
                return unserialize($encoded);
            }
            return false;
        }
        private static function encodeLicense($details, $secretKey)
        {
            $data = serialize($details);
            $data = base64_encode($data);
            $data = md5(date("Ymd") . $secretKey) . $data;
            $data = strrev($data);
            $data = $data . md5($data . $secretKey);
            $data = wordwrap($data, 80, "\n", true);
            return $data;
        }
        private static function loadRemoteLicense($licenseKey, $version, $templateName)
        {
            if (empty($_SERVER["SERVER_NAME"])) {
                $results = [];
                $results["emptyServerName"] = true;
                return $results;
            }
            $licenseFields = ["licensekey" => $licenseKey, "domain" => self::getDomain(), "ip" => "", "dir" => self::getDirPath(), "version" => $version, "cron" => \RSThemes\Helpers\AddonHelper::isCliMode(), "template" => $templateName];
            $query = "";
            foreach ($licenseFields as $k => $v) {
                $query .= $k . "=" . urlencode($v) . "&";
            }
            $results = [];
            $results["lastRemoteChecked"] = date("Y-m-d");
            if (!empty($licenseKey)) {
                $licenseFields["ip"] = $_SERVER['SERVER_ADDR'];
                // Assign each element from $array
                $results["lastRemoteChecked"] = date("Y-m-d");
                $results["status"] = "Active";
                $results["service_status"] = "Active";
                $results["license_status"] = "Active";
                $results["registeredname"] = "Babiato";
                $results["email"] = "Babiato";
                $results["serviceid"] = "130891";
                $results["productid"] = "19";
                $results["productname"] = "Single Domain";
                $results["version"] = $version;
                $results["fullversion"] = "Lagom " . $version;
                $results["regdate"] = date("Y-m-d");
                $results["nextduedate"] = "2924-09-16";
                $results["billingcycle"] = "Annually";
                $results["first_payment_amount"] = "\$129.00";
                $results["recuring_amount"] = "\$129.00";
                $results["payment_method"] = "PayPal";
    
                $results["validdomain"] = self::getDomain() . ",www." . self::getDomain();
                $results["extensions"] = "Client Notifications,Promotion Manager,Website Builder,Email Template,Custom Code,Support Hours";
                $results["validdirectory"] = self::getDirPath();
                $results["configoptions"] = "domain_conflict|Allow Domain Conflict=|dir_conflict|Allow Directory Conflict=|ip_conflict|Allow IP Conflict=";
                $results["domainconnflict"] = "no";
                $results["ipconflict"] = "no";
                $results["dirconflict"] = "no";
                $results["lastRemoteCheckedSuccess"] = date("Y-m-d");
                $results["remoteChecked"] = "1";
                
                self::logDetails("RSThemes", "checkRemoteLicense-3", $licenseFields, $results);
                return $results;
            }
            $results["lastRemoteCheckedFail"] = date("Y-m-d");
            $results["status"] = "Active";
            $results["service_status"] = "Active";
            $results["license_status"] = "Active";
            $results["message"] = "Curl extension not found!";
            $results["messagecode"] = "errors.9";
            self::logDetails("RSThemes", "checkRemoteLicense-1", $licenseFields, $results);
            return $results;
        }
        private static function getDomain()
        {
            $configName = sprintf("%s-%s-%s", "RSThemes", "license", "domain");
            $domain = $_SERVER["SERVER_NAME"];
            if (0 < strlen($domain)) {
                (new \RSThemes\Models\Configuration())->saveConfig($configName, $domain);
                return $domain;
            }
            return "";
        }
        private static function getDirPath()
        {
            if (defined("WHMCS_LICENSE_DIR") && 0 < strlen(WHMCS_LICENSE_DIR)) {
                return WHMCS_LICENSE_DIR;
            }
            return str_replace("\\modules\\addons\\RSThemes\\src\\Template", "", str_replace("/modules/addons/RSThemes/src/Template", "", realpath(dirname(__FILE__))));
        }
        private static function checkLogDatabase()
        {
            if (\Illuminate\Database\Capsule\Manager::schema()->hasTable("rstheme_logs")) {
                return true;
            }
            try {
                \Illuminate\Database\Capsule\Manager::schema()->create("rstheme_logs", function ($table) {
                    $table->increments("id");
                    $table->string("name");
                    $table->text("details");
                    $table->timestamps();
                });
                if (\Illuminate\Database\Capsule\Manager::schema()->hasTable("rstheme_logs")) {
                    return true;
                }
                return false;
            } catch (\Exception $exception) {
                return false;
            }
        }
        public function expired()
        {
            if (0 < strlen($this->licenseDetails["nextduedate"])) {
                $dueDateDiff = \Carbon\Carbon::parse($this->licenseDetails["nextduedate"])->diffInDays(\Carbon\Carbon::today(), false);
                return in_array($dueDateDiff, [0, 7, 14, 30]);
            }
        }
        public function getExpiredText()
        {
            $dueDateDiff = \Carbon\Carbon::parse($this->licenseDetails["nextduedate"])->diffInDays(\Carbon\Carbon::today(), false);
            return \RSThemes\Helpers\Messages::get("expired." . $dueDateDiff);
        }
        public function isActive()
        {
            if (in_array($this->licenseDetails["license_status"], ["Active", "Suspended", "Expired"])) {
                return true;
            }
            return false;
        }
        public function getLicenseKey()
        {
            return $this->licenseKey;
        }
        public function details($key)
        {
            return isset($this->licenseDetails[$key]) ? $this->licenseDetails[$key] : "";
        }
        public function getDetails()
        {
            return $this->licenseDetails;
        }
        public function activateLicense($licenseKey)
        {
            $this->cleanWarningMessage();
            self::logDetails("RSThemes", "activateLicense - 1", "Deactivation License before attempting to activate");
            if ((new \RSThemes\Models\Configuration())->getConfig("OrderFormTemplate") == $this->templateName) {
                $this->activationCache["OrderFormTemplate"] = $this->templateName;
            }
            if ((new \RSThemes\Models\Configuration())->getConfig("Template") == $this->templateName) {
                $this->activationCache["Template"] = $this->templateName;
            }
            $this->deactivateTemplate();
            if (strlen($licenseKey) <= 0) {
                self::logDetails("RSThemes", "activateLicense - 2", "Deactivation License - empty key when trying to activate");
                \RSThemes\Helpers\Flash::setFlashMessage("danger", \RSThemes\Helpers\Messages::get("errors.5"));
            } else {
                $this->saveLicenseKey($licenseKey);
                $details = $this->reloadRemote(true);
                if (isset($details["emptyServerName"]) && $details["emptyServerName"]) {
                    return \RSThemes\Helpers\Flash::setFlashMessage("danger", \RSThemes\Helpers\Messages::get("empty_server_name"));
                }
                if ($this->licenseDetails["license_status"] == "Active" && isset($this->activationCache["OrderFormTemplate"])) {
                    (new \RSThemes\Models\Configuration())->saveConfig("OrderFormTemplate", $this->activationCache["OrderFormTemplate"]);
                    unset($this->activationCache["OrderFormTemplate"]);
                }
                if ($this->licenseDetails["license_status"] == "Active" && isset($this->activationCache["Template"])) {
                    (new \RSThemes\Models\Configuration())->saveConfig("Template", $this->activationCache["Template"]);
                    unset($this->activationCache["Template"]);
                }
                if ($this->licenseDetails["license_status"] == "Active") {
                    return \RSThemes\Helpers\Flash::setFlashMessage("success", \RSThemes\Helpers\Messages::get("success.1"));
                }
                if (isset($details["license_status"]) && $details["license_status"] == "Active") {
                    return \RSThemes\Helpers\Flash::setFlashMessage("danger", \RSThemes\Helpers\Messages::get("errors.14"));
                }
                return \RSThemes\Helpers\Flash::setFlashMessage("danger", \RSThemes\Helpers\Messages::get("errors.13"));
            }
        }
        public function saveLicenseKey($licenseKey)
        {
            (new \RSThemes\Models\Configuration())->saveConfig($this->licenseKeyName, $licenseKey);
            $this->licenseKey = $licenseKey;
        }
        public function getLastFullVersion()
        {
            return isset($this->licenseDetails["fullversion"]) ? $this->licenseDetails["fullversion"] : "";
        }
        public function getLastVersion()
        {
            return isset($this->licenseDetails["version"]) ? $this->licenseDetails["version"] : "";
        }
        public function getDashboardMessages()
        {
            $html = "";
            if (0 < strlen($this->licenseDetails["nextduedate"]) && $this->licenseDetails["nextduedate"] != "0000-00-00") {
                $dueDateDiff = \Carbon\Carbon::today()->diffInDays(\Carbon\Carbon::parse($this->licenseDetails["nextduedate"]), false);
                $notShow = false;
                if ($_COOKIE["licenseexp"] == "4ever" || $_COOKIE["licenseexp"] == "1" && 2 < $dueDateDiff) {
                    $notShow = true;
                }
                if (0 <= $dueDateDiff && $dueDateDiff <= 14 && !$notShow) {
                    $html .= "<div class=\"alert alert--outline has-icon alert--border-left alert--license alert--info\"><div class=\"alert__body\">";
                    if ($dueDateDiff == 0) {
                        $html .= str_replace("%days%", $dueDateDiff, \RSThemes\Helpers\Messages::get("warnings.6"));
                        $html = str_replace("<b><span class=\"hidden\">Lagom WHMCS Theme - </span>", "<b>Lagom WHMCS Client Theme Nulled by @looper - ", $html);
                    } else {
                        $html .= str_replace("%days%", $dueDateDiff, \RSThemes\Helpers\Messages::get("warnings.5"));
                        $html = str_replace("<b><span class=\"hidden\">Lagom WHMCS Theme - </span>", "<b>Lagom WHMCS Client Theme Nulled by @looper - ", $html);
                    }
                    $html .= "<div class=\"form-check\"><label class=\"m-b-0x m-t-1x\"><input type=\"checkbox\" name=\"notshow\" data-dont-show class=\"form-checkbox\"><span class=\"form-indicator\"></span><span class=\"form-text\">Do not show again</span></label></div>";
                    $html .= "</div><div class=\"alert__actions\">\n                            <a class=\"btn btn-default\" href=\"https://rsstudio.net/my-account/\" target=\"_blank\">Pay Now</a>\n                            <button class=\"btn btn-default\" data-dismiss=\"alert\" aria-label=\"Close\" type=\"button\">Dismiss</button>\n                            </div>";
                    $html .= "</div>";
                    $html .= "<style>\n                    @font-face {\n                        font-family: \"Material-Design-Iconic-Font\";\n                        src: url(\"https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0//fonts/Material-Design-Iconic-Font.woff2?v=2.2.0\") format(\"woff2\"), url(\"https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0//fonts/Material-Design-Iconic-Font.woff?v=2.2.0\") format(\"woff\"), url(\"https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0//fonts/Material-Design-Iconic-Font.ttf?v=2.2.0\") format(\"truetype\");\n                        font-weight: normal;\n                        font-style: normal;\n                    }\n                    .alert--license {\n                        position: relative;\n                        display: flex;\n                        justify-content: space-between;\n                        align-items: center;\n                        flex-flow: row wrap;\n                        padding: 13px 16px 13px 56px;\n                        margin-bottom: 32px;\n                        border: none;\n                        box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n                        background: #fff;\n                    }\n                    .alert--license.alert--info{\n                        color: #50bfff;\n                        border-color: #50bfff;\n                    }\n                    .alert--license *{\n                        box-sizing: border-box;\n                    }\n                    .alert--license:before{\n                        position: absolute;\n                        top: 50%;\n                        left: 15px;\n                        width: 24px;\n                        height: 24px;                        \n                        margin-top: -12px;\n                        text-align: center;\n                        font-family: Material-Design-Iconic-Font;\n                        font-size: 24px;\n                        line-height: 22px;\n                    }\n                    .alert--license.alert--info:before{\n                        content: \"\\f1f7\";\n                    }\n                    .alert--license .alert__body{\n                        flex: 1;\n                        margin-right: auto;\n                    }\n                    .alert--license b{\n                        font-size: 14px;\n                        display: block;\n                        margin-bottom: 8px;\n                    }\n                    .alert--license b .hidden{\n                        display: inline-block!important;\n                    }\n                    .alert--license p{\n                        color: #505459;\n                        margin-bottom: 0;\n                    }\n                    .alert--license .alert__actions{\n                        display: flex;\n                        flex: 0 1 auto;\n                        white-space: nowrap;\n                    }\n                    .alert--license .alert__actions>*+* {\n                        margin-left: 16px;\n                    }\n                    .alert--license .alert__actions:last-child{\n                        margin-left: 16px;\n                    }\n                    .alert--license:after{\n                        position: absolute;\n                        top: -1px;\n                        bottom: -1px;\n                        left: -1px;\n                        content: \"\";\n                        border-radius: 3px 0 0 3px;\n                        border-left: 4px solid;\n                    }\n                    .widget-settings{\n                        margin-top: -28px;\n                    }\n                    .alert--license .form-checkbox + .form-indicator {\n                        position: relative;\n                        width: 22px;\n                        height: 22px;\n                        min-width: 22px;\n                        border-radius: 3px;\n                        display: inline-flex;\n                        align-items: center;\n                        justify-content: center;\n                        color: #393D45;\n                        border: 1px solid #d7d9de;\n                        background-color: #ffffff;\n                        box-shadow: none;\n                    }\n                    .alert--license .form-checkbox{\n                        display: none;\n                    }\n                    .alert--license .form-check label{\n                        display: flex;\n                        align-items: center;\n                        font-weight: 400;\n                        color: #505459;\n                    }\n                    .alert--license .form-text{\n                        margin-left: 8px;\n                    } \n                    \n                    .alert--license .form-checkbox + .form-indicator:hover,\n                    .alert--license .form-checkbox + .form-indicator:active{\n                        border-color: #1062FE;\n                        outline: 0;\n                    }\n                    .alert--license .form-checkbox:checked + .form-indicator{\n                        background: #50bfff;\n                        border-color: #50bfff;\n                    }\n                    .alert--license .form-checkbox:checked + .form-indicator:before{\n                        position: absolute;\n                        top: 0;\n                        left: 0;\n                        right: 0;\n                        bottom: 0;\n                        display: inline-flex;\n                        align-items: center;\n                        justify-content: center;\n                        font-family: Material-Design-Iconic-Font;\n                        content: \"\\f26b\";\n                        display: inline-flex;\n                        color: #fff;\n                    }\n                    .alert--license .m-t-1x{\n                        margin-top: 8px;\n                    }\n                </style>\n                <script>\n                 \$(\".alert--license\").on(\"closed.bs.alert\", function () {\n                    let notshow = \$(this).find(\"[data-dont-show]\");\n                    let name = \"licenseexp\",\n                        value = 1,\n                        days = 7;\n            \n                    if (notshow[0].checked === true){\n                        value = \"4ever\";\n                        days = 9999;\n                    }\n\n                    new setCookie(name, value, days);\n                    \n                 });\n\n                 function setCookie(cname, cvalue, exdays) {\n                    const d = new Date();\n                    d.setTime(d.getTime() + (exdays*24*60*60*1000));\n                    let expires = \"expires=\"+ d.toUTCString();\n                    document.cookie = cname + \"=\" + cvalue + \";\" + expires + \";path=/\";\n                  }\n                </script>";
                }
            }
            if (isset($this->licenseDetails["warningShowDate"]) && strlen($this->licenseDetails["warningShowDate"]) && $this->licenseDetails["warningShowDate"] <= date("Y-m-d")) {
                $days = \Carbon\Carbon::today()->diffInDays(\Carbon\Carbon::parse($this->licenseDetails["deactivationDate"]), false);
                if ($days < $this->licenseFailDays) {
                    $html .= "<div class=\"alert alert--outline has-icon alert--border-left alert--license alert--danger\"><div class=\"alert__body\">";
                    $html .= str_replace("%days%", $days, \RSThemes\Helpers\Messages::get("warnings.9"));
                    $html = str_replace("<b>ERROR:", "<b>ERROR: Lagom WHMCS Client Theme", $html);
                    $html .= "</div><div class=\"alert__actions\">\n                            <a class=\"btn btn-default\" href=\"#\" target=\"_blank\">Support</a>\n                            </div>";
                    $html .= "</div>";
                    $html .= "<style>\n                    @font-face {\n                        font-family: \"Material-Design-Iconic-Font\";\n                        src: url(\"https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0//fonts/Material-Design-Iconic-Font.woff2?v=2.2.0\") format(\"woff2\"), url(\"https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0//fonts/Material-Design-Iconic-Font.woff?v=2.2.0\") format(\"woff\"), url(\"https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0//fonts/Material-Design-Iconic-Font.ttf?v=2.2.0\") format(\"truetype\");\n                        font-weight: normal;\n                        font-style: normal;\n                    }\n                    .alert--license{\n                        position: relative;\n                        display: flex;\n                        justify-content: space-between;\n                        align-items: center;\n                        flex-flow: row wrap;\n                        padding: 13px 16px 13px 56px;\n                       \n                        margin-bottom: 32px;\n                        border: none;\n                        box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n                        background: #fff;\n                        \n                    }\n                    .alert--license.alert--danger{\n                        color: #e53e3e;\n                        border-color: #e53e3e;\n                    }\n                    .alert--license *{\n                        box-sizing: border-box;\n                    }\n                    .alert--license:before{\n                        position: absolute;\n                        top: 50%;\n                        left: 15px;\n                        width: 24px;\n                        height: 24px;\n                        margin-top: -12px;\n                        text-align: center;\n                        font-family: Material-Design-Iconic-Font;\n                        font-size: 24px;\n                        line-height: 22px;\n                    }\n                    .alert--license.alert--danger:before{\n                        content: \"\\f1f4\";\n                    }\n                    .alert--license .alert__body{\n                        flex: 1;\n                        margin-right: auto;\n                    }\n                    .alert--license b{\n                        font-size: 14px;\n                        display: block;\n                        margin-bottom: 8px;\n                    }\n                    .alert--license b .hidden{\n                        display: inline-block!important;\n                    }\n                    .alert--license p{\n                        color: #505459;\n                        margin-bottom: 0;\n                    }\n                    .alert--license .alert__actions{\n                        display: flex;\n                        flex: 0 1 auto;\n                        white-space: nowrap;\n                    }\n                    .alert--license .alert__actions>*+* {\n                        margin-left: 16px;\n                    }\n                    .alert--license .alert__actions:last-child{\n                        margin-left: 16px;\n                    }\n                    .alert--license:after{\n                        position: absolute;\n                        top: -1px;\n                        bottom: -1px;\n                        left: -1px;\n                        content: \"\";\n                        border-radius: 3px 0 0 3px;\n                        border-left: 4px solid;\n                    }\n                    .widget-settings{\n                        margin-top: -28px;\n                    }\n                </style>";
                }
            }
            return $html;
        }
        public function hasProblem()
        {
            if (isset($this->licenseDetails["warningShowDate"]) && strlen($this->licenseDetails["warningShowDate"]) && $this->licenseDetails["warningShowDate"] <= date("Y-m-d")) {
                return true;
            }
            return false;
        }
        public function getProblem()
        {
            if (isset($this->licenseDetails["warningShowDate"]) && strlen($this->licenseDetails["warningShowDate"]) && $this->licenseDetails["warningShowDate"] <= date("Y-m-d")) {
                return $this->getMessagePart("warnings.8", 0);
            }
            return "";
        }
        public function hasInputError()
        {
            if (strlen($this->licenseKey) <= 0 || $this->licenseDetails["license_status"] == "") {
                return true;
            }
            return false;
        }
        public function getInputError()
        {
            if (strlen($this->licenseKey) <= 0 || $this->licenseDetails["license_status"] == "") {
                return \RSThemes\Helpers\Messages::get("messages.1");
            }
        }
        public function getAddonMessages()
        {
            $html = "";
            if (0 < strlen($this->licenseDetails["nextduedate"]) && $this->licenseDetails["nextduedate"] != "0000-00-00") {
                $dueDateDiff = \Carbon\Carbon::today()->diffInDays(\Carbon\Carbon::parse($this->licenseDetails["nextduedate"]), false);
                $notShow = false;
                if (isset($_COOKIE["licenseexp"]) && ($_COOKIE["licenseexp"] == "4ever" || $_COOKIE["licenseexp"] == "1" && 2 < $dueDateDiff)) {
                    $notShow = true;
                }
                if (0 <= $dueDateDiff && $dueDateDiff <= 30 && !$notShow) {
                    $html .= "<div class=\"alert alert--info alert--outline has-icon alert--border-left alert--license\" data-daysToExp=\"" . $dueDateDiff . "\"><div class=\"alert__body\">";
                    if ($dueDateDiff == 0) {
                        $html .= str_replace("%days%", $dueDateDiff, \RSThemes\Helpers\Messages::get("warnings.6"));
                    } else {
                        $html .= str_replace("%days%", $dueDateDiff, \RSThemes\Helpers\Messages::get("warnings.5"));
                    }
                    $html .= "<div class=\"form-check\"><label class=\"m-b-0x m-t-1x\"><input type=\"checkbox\" name=\"notshow\" data-dont-show class=\"form-checkbox\"><span class=\"form-indicator\"></span><span class=\"form-text\">Do not show again</span></label></div>";
                    $html .= "</div><div class=\"alert__actions\">\n                            <a class=\"btn btn--default btn--outline btn--sm\" href=\"https://rsstudio.net/my-account/\" target=\"_blank\">Pay Now</a>\n                            <button class=\"btn btn--default btn--outline btn--sm\" data-dismiss=\"alert\" aria-label=\"Close\" type=\"button\">Dismiss</button>\n                        </div>";
                    $html .= "</div>";
                }
            }
            if (isset($this->licenseDetails["warningShowDate"]) && strlen($this->licenseDetails["warningShowDate"]) && $this->licenseDetails["warningShowDate"] <= date("Y-m-d")) {
                $days = \Carbon\Carbon::today()->diffInDays(\Carbon\Carbon::parse($this->licenseDetails["deactivationDate"]), false);
                $html .= "<div class=\"alert alert--danger alert--outline has-icon alert--border-left alert--license\"><div class=\"alert__body\">";
                $html .= str_replace("%days%", $days, \RSThemes\Helpers\Messages::get("warnings.9"));
                $html .= "</div><div class=\"alert__actions\">\n                <a class=\"btn btn--default btn--outline btn--sm\" href=\"https://rsstudio.net/my-account/submitticket.php?step=2&deptid=7\" target=\"_blank\">Contact Us</a>\n                </div>";
                $html .= "</div>";
            }
            if (0 < strlen($this->licenseWarningMessage)) {
                $html .= "<div class=\"alert alert--danger alert--outline has-icon alert--border-left alert--license\"><div class=\"alert__body\">";
                $html .= $this->licenseWarningMessage;
                $html .= "</div><div class=\"alert__actions\">\n                <a class=\"btn btn--default btn--outline btn--sm\" href=\"https://rsstudio.net/my-account/submitticket.php?step=2&deptid=7\" target=\"_blank\">Contact Us</a>\n                </div>";
                $html .= "</div>";
            }
            return $html;
        }
        private static function checkLogFile()
        {
            $path = RSTHEMES_DIR . DS . "logs.php";
            if (!is_writable(RSTHEMES_DIR)) {
                return false;
            }
            if (!file_exists($path)) {
                try {
                    file_put_contents($path, "<?php http_response_code(404);exit; ?>\\nCreate logs file! " . date("Y-m-d h:i:s") . PHP_EOL);
                    if (!file_exists($path)) {
                        return false;
                    }
                } catch (\Exception $exception) {
                    return false;
                }
            }
            if (!is_writable($path)) {
                return false;
            }
            return $path;
        }
        public function getAllowedExtensions()
        {
            if ($this->licenseDetails["service_status"] == "Active") {
                $details = $this->reloadRemote();
            }
            return $details["extensions"] ? explode(",", trim($details["extensions"])) : [];
        }
        private function syncExtensions($details)
        {
            $toSkip = ["Modules Integrations"];
            if ($details["license_status"] != "Active") {
                return NULL;
            }
            $allowedExtensions = $details["extensions"] ? explode(",", trim($details["extensions"])) : [];
            foreach ($this->template->getExtensions() as $extension) {
                if (!in_array($extension->name, $toSkip)) {
                    if (method_exists($extension, "checkLicense") && !in_array($extension->name, $allowedExtensions) && $extension->isActive()) {
                        $extension->licenseRemoveConfig();
                    }
                }
            }
        }
    }
    
    ?>

  • 子比主题7.7版本 完美破解版 开心版 免授权

    子比主题7.7版本 完美破解版 开心版 免授权

    本站将不再提供国产相关主题破解下载。
    相关讨论可以去 https://www.nodeloc.com

    7.7的具体更新及原版源码见这里

    [b2_insert_post id=”7463″]

    子比主题7.7微调了授权验证算法,所以更新了接口文件。

    授权接口源码附件下载

    使用方法:


    搭建一个站点,绑定api.zibll.com域名,并开启SSL(随便找个域名的证书就行)

    上传以上源码,并配置好伪静态

    最后在/etc/hosts里面加一行

    127.0.0.1 api.zibll.com
  • 专业文件对比工具Beyond Compare v4.4.7 Build 28397中文破解版

    专业文件对比工具Beyond Compare v4.4.7 Build 28397中文破解版

    Beyond Compare 是一款不可多得的专业级的文件夹和文件对比工具。使用它可以很方便地对比出两个文件夹或者文件的不同之处,相差的每一个字节用颜色加以表示,查看方便,支持多种规则对比。使用Beyond Compare只需使用简单而强大的命令和操作,即可开启最优质的对比体验,找出您感兴趣的差异,合并变化,然后同步文件,并生成报告。

    Beyond Compare软件特色


    展开会话概念

    · 所有类型的比较均可以被保存为会话,而不仅仅是文件夹比较

    · 插件被替换为内置会话类型

    · 保存的会话可以在文件夹里管理

    · 自动保存新比较至会话

     全面启用unicode 

    · 不仅支持Unicode文件内容,而且支持Unicode文件名

     界面改进 

    · 针对会话视图的选项卡界面

    · 手头的“主视图”用于启动或管理会话

    · 可以保存和恢复多个打开会话的布局

    · 内置“检查升级”功能

     文件夹比较功能 

    · 选择喜欢的文件夹图标颜色

    · 多个操作可以通过队列执行

    · 文件操作默认使用过滤器

    · 专用文件夹同步会话

    · Touch and 属性命令可以递归执行到子文件夹。

    · 属性 命令现在执行Unix属性

    · 新的忽略 命令将不匹配文件标记为确定 mismatched file as okay

    · 新的 移动到文件夹命令

    · 平展文件夹帮助比较文件夹结构的不同

    · 能够替代对齐文件

       文本比较特点 

    · 完整的i窗格内编辑器自带动态重新比较

    · 高亮语法

    · 自适应装订按钮用于复制节

    · 保存之后无限制的撤销

    · 基于语法的比较规则

    · 两侧比较运用独立的文件类型I

    · 新的忽略 命令f标记不匹配文件为确定

    · 多重书签

    · 十六进制显示行细节的选项

    · 三方文本合并

    · 在和另一侧特定文本想比较时,能够将一侧的特定文本视为不重要的

       改进FTP支持 

    · FTP配置文件,每一个会话可选

    · 多项同时连接

    · 内置安全FTP协议支持(SFTP和FTP基于SSL)

    新版特性

    Beyond Compare 4 Change Log
    https://www.scootersoftware.com/download.php?zz=v4changelog

    Scooter Beyond Compare 4.4.6 Build 27483 (2023/02/25) ot 03.07

    特点描述

    1.基于简体中文版,原生便携式处理支持添加资源管理器右键
    2.已解除激活验证集成专业版授权密钥,并切断联网验证请求
    3.去界面网络连接横幅,去选项检测升级,去帮助菜单无用项
    4.去检测升级提示,禁止检测升级
    5.7z.dll模块版本更新22.01正式版
    6.提供额外批处理添加右键菜单项
    7.特别处理,右键菜单支持WinPE

      下载权限

      查看

      • 免费下载
        评论并刷新后下载
        登录后下载

      查看演示

        0″>

      • {{attr.name}}:
      您当前的等级为


      登录后免费下载登录


      小黑屋反思中,不准下载!


      评论后刷新页面下载评论


      支付以后下载
      请先登录


      您今天的下载次数(次)用完了,请明天再来


      支付积分以后下载立即支付


      支付以后下载立即支付


      您当前的用户组不允许下载升级会员


      您已获得下载权限


      您可以每天下载资源次,今日剩余

    • 屏幕录像软件Aiseesoft Screen Recorder v2.9.12中文破解版

      屏幕录像软件Aiseesoft Screen Recorder v2.9.12中文破解版

      软件介绍

      Aiseesoft Screen Recorder 屏幕捕捉录像软件中文正式版,Aiseesoft Screen Recorder 屏幕捕捉软件能够帮助您录制在线播放的音频或者视频,录制视频教程,录制游戏视频,捕获和存储音乐等。可供选择的全屏幕录制和自定义录制区域大小,突出显示光标移动路径,使您的操作更容易跟踪,方便视频教程的录制。采用先进的实时高清视频编码技术,确保录制的音频和视频的质量,Aiseesoft屏幕录像机获取最简单但专业的方式来记录屏幕并在此处拍摄快照。 Aiseesoft屏幕录像机是捕获Mac或windows计算机上任何活动的最佳屏幕录像软件。 它可以用作出色的视频游戏记录器,Skype呼叫捕获,YouTube视频录制应用程序,以及更多功能来捕获屏幕的任何区域。 在进行屏幕录制时,您可以编辑视频/快照并绘制新标签以输出文件。

      软件功能

      录制屏幕视频
      作为强大的屏幕录像软件,Aiseesoft Screen Recorder使您可以轻松录制任何屏幕视频。 您可以使用它以全屏或自定义屏幕尺寸捕获在线YouTube视频,游戏,播客,网络研讨会,讲座,演示,Skype通话,在线会议,网络摄像头视频等。捕获屏幕时,您可以突出显示光标移动以使其易于跟踪。 此外,“蓝光”实时高清视频编码技术可以确保您具有出色的图像和声音质量。 锁定窗口捕获功能使您可以将录制活动保持在某个窗口上。 这样屏幕录制就不会打扰其他操作了。 捕获的视频将保存在MP4,WMV,MOV,AVI,GIF,TS等中,以便轻松播放和共享。

      在线录制流音频和麦克风语音
      Aiseesoft屏幕录像机只能录制计算机的内部音频。 此功能使您可以录制各种音乐,广播或在线音频,而无需下载它们。 您可以将录制的音频保存在MP3 / WMA / AAC / M4A / FLAC / Ogg / Opus中,以便于播放。
      录制流音频: 录制系统音频中的任何流音频,因此您可以获得完全原始的音质。
      捕获在线音频: 该音频采集器可以保存任何在线音频,包括MV中的音轨,教学视频中的语音等。
      记录麦克风声音: 选择麦克风音频并关闭系统音频,以向您的视频演示添加口头说明。

      拍摄快照的简便方法
      拍摄快照是快速保存一些重要信息的简便而有用的方法。 您可以每天使用它。 该屏幕录像机还可以用作功能强大的快照应用程序,以帮助您捕获屏幕上的所有内容并将其保存为图片。 您可以自由调整快照区域,并将矩形,箭头,线条和文本等个人标签添加到输出图像。 您可以根据需要将快照另存为PNG,JPEG,BMP,GIF,TIFF等。 当然,它还配备了其他关键编辑功能,可以帮助您制作快照。

      编辑录像或截图
      Aiseesoft屏幕录像机是一款功能强大的视频/音频录制软件和快照应用程序。 它不仅可以帮助您录制屏幕,捕获音频或拍摄快照,还具有许多必要的编辑功能,可以帮助您获得首选的输出文件。
      编辑录制的视频: 在录制时添加箭头,文本,线条,矩形,椭圆形等,可剪辑录制的视频/音频。 自由修剪录制的视频或音频文件,仅保存有用的部分。
      编辑捕获的快照: 轻松将您的个人标签(如新箭头,线条,文本等)放在快照上。
      更多设置: 设置更多自定义的屏幕记录方式,热键和其他输出设置。 设置视频编解码器,质量,帧速率,音频质量等。

      软件官方网站地址 https://zh-cn.aiseesoft.com/screen-recorder/

        下载权限

        查看

        • 免费下载
          评论并刷新后下载
          登录后下载

        查看演示

          0″>

        • {{attr.name}}:
        您当前的等级为


        登录后免费下载登录


        小黑屋反思中,不准下载!


        评论后刷新页面下载评论


        支付以后下载
        请先登录


        您今天的下载次数(次)用完了,请明天再来


        支付积分以后下载立即支付


        支付以后下载立即支付


        您当前的用户组不允许下载升级会员


        您已获得下载权限


        您可以每天下载资源次,今日剩余

      • Character Animator 2024 v24.0.0破解版

        Character Animator 2024 v24.0.0破解版

        软件介绍

        Adobe Character Animator 2024破解版(简称CH2024最新版)是一款动作捕获和2D角色动画人物创作软件的Adobe动画人物创作软件.Adobe Character Animator 2024中文破解版(CharacterAnimator破解版)支持实时面部追踪和语音识别,捕获摄像头人物表情动作,采用AI算法可以将任何作品转换为动画角色人物效果。

        新版变化

        Adobe Character Animator 2024 正式版2023年10月版 (24.0版) 新增功能摘要
        https://helpx.adobe.com/adobe-character-animator/using/whats-new.html

        特点描述

        by vposy, m0nkrus
        character2024破解版,character2024中文破解版
        – Character官方版改装,免激活,多国语言完整版
        – 禁用Adobe产品后台跟踪器和匿名数据日志上报程序
        – 安装程序:基于Adob​​e产品独立安装程序版本 5.7.1.1
        – 安装程序:解除 windows 10 初期版系统上安装限制(by m0nkrus)
        – 安装程序:移除原始安装程序的Adobe Desktop Common (公用库) 组件
        – 安装程序:移除原始安装程序的Adobe Creative Cloud (创意云程序) 组件
        – 安装界面:界面支持选择安装位置和界面语言,以及安装完后立即运行软件

        系统要求

        CH2022特别版安装要求:Windows 10 所有版或更高版64位
        CH2022官方版安装要求:Windows 10 v1809 或更高版64位

          下载权限

          查看

          • 免费下载
            评论并刷新后下载
            登录后下载

          查看演示

            0″>

          • {{attr.name}}:
          您当前的等级为


          登录后免费下载登录


          小黑屋反思中,不准下载!


          评论后刷新页面下载评论


          支付以后下载
          请先登录


          您今天的下载次数(次)用完了,请明天再来


          支付积分以后下载立即支付


          支付以后下载立即支付


          您当前的用户组不允许下载升级会员


          您已获得下载权限


          您可以每天下载资源次,今日剩余

        • Adobe Animate 2024 v24.0.0.305破解版

          Adobe Animate 2024 v24.0.0.305破解版

          软件介绍

          Adobe Animate 2024破解版(AN2024最新版)是一款Flash和2D动画软件动画交互设计的绘图软件.Adobe Animate 2024中文破解版加入HTML5创作工具,为网页开发者提供适应最新网页的图片,动画,音视频等素材文件支持.Animate中文版支持HTML5Canvas,WebGL,并且能通过可扩展架构支持SVG在内任何动画格式。

          新版变化

          Adobe Animate 2024正式版2023年10月版(24.0) 新增功能摘要
          https://helpx.adobe.com/cn/animate/using/whats-new.html

          特点描述

          by vposy, m0nkrus
          animate2024中文版,animate2024破解版
          – 官方版改装,免激活处理,多国语言完整版
          – 禁用Adobe产品后台跟踪器和匿名数据日志上报程序
          – 安装程序:基于Adob​​e产品独立安装程序版本 5.7.1.1
          – 安装程序:解除 windows 10 初期版系统上安装限制(by m0nkrus)
          – 安装程序:移除原始安装程序的Adobe Desktop Common (公用库) 组件
          – 安装程序:移除原始安装程序的Adobe Creative Cloud (创意云程序) 组件
          – 安装界面:界面支持选择安装位置和界面语言,以及安装完后立即运行软件

          系统要求

          AN2022特别版的要求:Windows 10 所有版及更高版64位
          AN2022安装程序要求:Windows 10 20H2 或更高版64位
          AN2021/AN2020安装程序要求:Windows 10 v1809 或更高版64位
          AN2019/AN2018最低运行要求:Windows 7 x64, Windows 10 x64

            下载权限

            查看

            • 免费下载
              评论并刷新后下载
              登录后下载

            查看演示

              0″>

            • {{attr.name}}:
            您当前的等级为


            登录后免费下载登录


            小黑屋反思中,不准下载!


            评论后刷新页面下载评论


            支付以后下载
            请先登录


            您今天的下载次数(次)用完了,请明天再来


            支付积分以后下载立即支付


            支付以后下载立即支付


            您当前的用户组不允许下载升级会员


            您已获得下载权限


            您可以每天下载资源次,今日剩余

          • Adobe Audition 2024 v24.0.0.46.0破解版

            Adobe Audition 2024 v24.0.0.46.0破解版

            软件介绍

            Adobe Audition,简称“AU”音频录制、编辑和混合软件。Audition是业界最佳的数字音频编辑软件,专业声音剪辑软件,强大的音轨处理软件。具有音频录制、音频编辑音频混合、音频降噪、设计音效、多轨混音、母带处理、现场调音、编辑视频音轨、音频转码等功能,支持频谱编辑工具自动语音对齐、降噪工具和自动响度纠正,支持多音轨多声道音频及多种音频特效与音频格式,提高音频质量和音频编辑整体效率。

            特性

            Adobe Audition 2024 正式版2023年10月版(24.0) 新增功能
            https://helpx.adobe.com/audition/using/whats-new.html

            特点描述

            by vposy, m0nkrus
            au2024破解版,audition2024中文破解版
            – 官方版改装,免激活处理,多国语言完整版
            – 禁用Adobe产品后台跟踪器和匿名数据日志上报程序
            – 安装程序:基于Adob​​e产品独立安装程序版本 5.7.1.1
            – 安装程序:解除 windows 10 初期版系统上安装限制(by m0nkrus)
            – 安装程序:移除原始安装程序的Adobe Desktop Common (公用库) 组件
            – 安装程序:移除原始安装程序的Adobe Creative Cloud (创意云程序) 组件
            – 安装界面:界面支持选择安装位置和界面语言,以及安装完后立即运行软件

            系统要求

            AU2022特别版的要求:Windows 10 所有版及更高版64位
            AU2022安装程序要求:Windows 10 2004 或更高版64位
            AU2021安装程序要求:Windows 10 1809 或更高版64位
            AU2020软件运行要求:Windows 7 或更高版64位

              下载权限

              查看

              • 免费下载
                评论并刷新后下载
                登录后下载

              查看演示

                0″>

              • {{attr.name}}:
              您当前的等级为


              登录后免费下载登录


              小黑屋反思中,不准下载!


              评论后刷新页面下载评论


              支付以后下载
              请先登录


              您今天的下载次数(次)用完了,请明天再来


              支付积分以后下载立即支付


              支付以后下载立即支付


              您当前的用户组不允许下载升级会员


              您已获得下载权限


              您可以每天下载资源次,今日剩余

            • Adobe Premiere Pro 2024 v24.0.0破解版

              Adobe Premiere Pro 2024 v24.0.0破解版

              软件介绍

              Adobe Premiere Pro 2024破解版(简称PR)是一款专业的视频编辑软件及后期视频剪辑软件.Adobe Premiere Pro中文破解版可以在RGB和YUV色彩空间以高达32位色彩分辨率对4K超清视频及360/VR视频编辑,支持VST音频插件和5.1环绕声音轨,可以导入和导出QuickTime或DirectShow,支持所有音频及视频编码格式。

              新版变化

              Adobe Premiere Pro 2024 正式版2023年10月版(24.0)
              https://helpx.adobe.com/premiere-pro/kb/fixed-issues.html

              新增功能摘要 | Premiere Pro 最新版本
              https://helpx.adobe.com/cn/premiere-pro/using/whats-new.html

              特点描述

              by vposy, m0nkrus
              pr2023破解版,premiere2024中文破解版
              – 官方版改装,免激活处理,多国语言完整版
              – 更新软件主屏幕(欢迎使用)UXP组件至 5.5.0.54
              – 移除软件主屏幕的已经授权/试用到期的通知提示
              – 禁用Adobe产品后台跟踪器和匿名数据日志上报程序
              – 安装程序:基于Adob​​e产品独立安装程序版本 5.7.1.1
              – 安装程序:解除 windows 10 初期版系统上安装限制(by m0nkrus)
              – 安装程序:移除原始安装程序的Adobe Desktop Common (公用库) 组件
              – 安装程序:移除原始安装程序的Adobe Creative Cloud (创意云程序) 组件
              – 安装界面:界面支持选择安装位置和界面语言,以及安装完后立即运行软件
              – 安装界面:在安装过程中,安装程序界面加入了“新版特性功能的动态展示”
              – Adob​​e CCX Process (Adobe产品数据辅助) 模块组件版本更新到 最新版
              – Adobe CC Library (Adobe产品库) 模块组件版本更新到 最新版

              系统要求

              PR2022特别版的要求:DirectX 12, Windows 10 所有版及更高版64位
              PR2021最低系统要求:DirectX 12, Windows 10 2004 及更高版64位
              PR2020最低系统要求:DirectX 12, Windows 10 1809 及更高版64位
              PR2019安装程序要求:DirectX 12, Windows 10 及更高版64位
              PR2019软件运行要求:DirectX 12, Windows 7 及更高版64位
              PR2018最低系统要求:DirectX 9C, Windows 7 及更高版64位

                下载权限

                查看

                • 免费下载
                  评论并刷新后下载
                  登录后下载

                查看演示

                  0″>

                • {{attr.name}}:
                您当前的等级为


                登录后免费下载登录


                小黑屋反思中,不准下载!


                评论后刷新页面下载评论


                支付以后下载
                请先登录


                您今天的下载次数(次)用完了,请明天再来


                支付积分以后下载立即支付


                支付以后下载立即支付


                您当前的用户组不允许下载升级会员


                您已获得下载权限


                您可以每天下载资源次,今日剩余