破解對象: luaide
破解目的:學習如何破解vscode插件
破解背景:
vsscode用了這么多年,安裝了很多插件,其中luaide插件是收費的. 說實話,100塊並不貴, 我本來准備買的.
結果我想加入luaide群,問幾個插件相關問題,結果需要回答驗證碼.太扯了. 既然有7天試用,為何還要入群權限?真搞不懂
一般群我也懶得加,反正加入群,基本上是划水,沒什么軟用.
剛好之前沒有破解vscode插件經驗, 那就拿這個練手好了. 純屬破解學習用, 不做非法用途.
我破解的過程中,發現luaide作者還是很用心的, 對防破解用心了,對lua調試插件用心了,對文檔用心了, 代碼質量不錯. 這個插件不貴, 建議lua開發同學購買.
有一個用戶系統, 在線統計等功能, 這個肯定得需要一台服務器. 這些都是成本.
這個破解花了我好幾個晚上,其中有幾個晚上,由於對VScode工具的實現不熟悉,vscode插件開發流程不熟悉, 所以一直在探索,一直在走彎路.
這是我當時想問的:
插件有不完美的地方, 想調試要在main.lua中新增幾行代碼
這樣會污染源文件main.lua.可不可以不污染?
當然我本人是可以解決的這個問題的, 就是不知道luaide作者是如何想的.
方案是新增一個文件, 名字叫debug2.lua. 把需要新增的幾行代碼寫在 debug2中, 然后在require "main"
修改AppDelegate文件, 如果是DEBUG模式,就 執行 debug2文件 否則就是 main文件.
發布的時候肯定都是release模式, 所以沒有任何影響.
當然還有一個方案, 修改引擎,讓config.json 使其在 mac平台或者win平台生效. 直接修改entry字段的內容就OK
終極方案:
我覺得這個事情應該可以完全插件處理的, 包括端口啥的可以自動分配處理. 不需要使用者額外再加任何代碼.
這個得luaide插件作者來做吧, 我做的話就嚴重違法了. 即使做了,也頂多自己使用, 浪費時間,沒有啥意義.
加的幾行代碼也僅僅是拷貝, 時間上無傷大雅.
插件安裝目錄:
~/.vscode/extensions/kangping.luaide-1.1.3
當我用vscode打開這個目錄的時候, 找到了.node文件, 我以為是node項目, 用node各種版本去嘗試調試它, 一直報錯.
沒有一個nodejs版本是支持x64_69版本的. 這個就讓我很郁悶了. 只能換個思路, 直接調試vscode 編輯器. 因為插件是寄生在編輯器上的.
code 僅僅是一個shell腳本, 實質上真正調用的是 Electron可執行程序. 查了一下資料, 它是跨平台的應用框架.
和nodejs很像, 都是在v8上實現的, 所有邏輯都是js 或者 .node文件.
查找了一下Electron調試方法,發現可以調試,那太完美. 初始化的數據是 luaide.info 這個數據是加密, 在.node文件中進行解密.
從這個.node的文件邏輯中可以看到luaide原來的邏輯是啥樣的:
class Persisten_1{
getScriptValue()
initWarp()
static createNew()
}
js 層面有3個方法:[
init,
getScriptValue,
luaIdecreate
]
createNew的實現
很明顯這個是一個單例, 沒什么好說的.
其實關鍵還是在於init函數, 和getScriptValue
init 函數功能加載luaide.info文件, 然后按照換行符切割, 保存到scriptmap中
getScriptValue函數的功能是根據key值獲取腳本值, 這里有一個解密的過程, 本人懶得分析怎么解密了, 這里直接獲取結果就好.
通過斷點調試發現確實可以拿到數據. 接下來就好辦了.
在readFileSync函數包裝一層,先保存到文件. 文件名為 ${key}.js
fs.readFileSync = function (path, options) { var newPath = path.replace(/\\/g, "/"); var lastIndex = newPath.lastIndexOf("/") if(lastIndex > -1){ newPath = newPath.substring(lastIndex+1) newPath = newPath.replace(".js","") } var value = luaideIde.getScriptValue(newPath) if (!!value) { fs.writeFile(`${tempPath}/${newPath}.js`, value, { 'flag': 'w' }, function(err) { if (err) { throw err; } console.log('OK:',newPath); }); return value; }else { return readFileSync(path, options); } };
最后所有代碼都已經拿到了,效果如圖:
有了代碼,接下來想怎么玩耍就怎么玩耍了.
我發現作者真是煞費苦心啊, 防破解方面是花了大功夫了, 發現部分代碼, 是走的網絡. aes解密后,動態執行代碼.
看了一下代碼, 代碼量很多,並且質量不錯, 花100塊還是很划算的.
聲明: 本人破解的軟件, 破解的代碼, 百分百不會放到網上,全部僅供個人娛樂. 學習使用.
launch.json
// A launch configuration that launches the extension inside a new window // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 { "version": "0.2.0", "configurations": [ { "name": "Run Extension", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}" ] }, { "name": "Extension Tests", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/test/suite/index" ] } ] }
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var fs = require("fs"); function activate(context) { var fss = fs.readFileSync; fs.readFileSync = function(path, op) { return fss(path, op); }; const vscode = require("vscode"); var path = require("path"); var fileName = process.platform + "_" + process.arch + "_" + process.versions.modules + ".node"; var extensionPath = vscode.extensions.getExtension("kangping.luaide") .extensionPath; var libpath = path.join(extensionPath, "runtime", fileName); var hotlib = require(libpath); // new Function("require", "context", "hotlib", "luaIdeStart(require,context,hotlib);")(require, context,hotlib) luaIdeStart(require, context, hotlib); } function saveFiles(extensionPath, luaideIde) { let list = [ "ApiInit", "ApiUtils", "AutoLuaComment", "Base64", "BaseChildProcess", "BreakPointData", "CacheCompletionInfo", "ChangeCaseExtension", "CheckDebug", "CheckLuaDebugFile", "CommentLuaCompletionManager", "Common", "ConstInfo", "CreateFunction", "CreateMoudleFunction", "CreateNewTemplate", "CreateTemplateFile", "DCommon", "DebugCommon", "DebugReLoadFile", "DownLoad", "ExInit", "ExtensionManager", "FileCompletionItemManager", "FunctionCall", "FunctionParameter", "GVarRefNameInfo", "HttpClient", "LoadLuaScript", "LoadScriptResponse", "LoadStringTest", "LuaCheckDoEnd", "LuaCheckLuaInfos", "LuaCheckRepeat", "LuaCheckReturn", "LuaCheckUnary", "LuaChuckInfo", "LuaComment", "LuaCompletionItemControler", "LuaCompletionItemFunControler", "LuaCompletionItemGolbalControler", "LuaCompletionItemProvider", "LuaCompletionItemProviderUtils", "LuaDebug", "LuaDefinitionProvider", "LuaDocumentProvider", "LuaDocumentSymbolProvider", "LuaFileCompletionItems", "LuaFiledCompletionInfo", "LuaForLogic", "LuaFormatChildProcess", "LuaFormatParseTool", "LuaFormattingEditProvider", "LuaFuncitonCheck", "LuaFunctionParse", "LuaGolbalCompletionManager", "LuaHighlight", "LuaIdeClient", "LuaIdeConfigManager", "LuaIfLogic", "LuaInfoManager", "LuaLeftCheck", "LuaMode", "LuaParse", "LuaParseTool", "LuaParseTool1", "LuaProcess", "LuaProviderUtils", "LuaProvoderUtil", "LuaReferenceProvider", "LuaSetValue", "LuaSignatureHelpProvider", "LuaSymbolInformation", "LuaTableParse", "LuaToDoProvider", "LuaValidateBracket_G", "LuaValidateBracket_M", "LuaValidateConstValue", "LuaValidateOperator", "LuaVmTool", "LuaWhileLogic", "LuacCheck", "LuaideConsole", "LualOutlineProvider", "OpenHelper", "PBLuaCompleteManager", "PBLuaCompletionInfo", "ScopesManager", "SynchronizationCode", "TemplateManager", "TokenInfo", "TokenInfoCache", "UserInfoManager", "UserLoginCount", "UserUtils", "Utils", "extension1", "luaVmCheck", "luacheck", "luaideDebugInit", "luaideInit1", "luavm1", "nodeMachine" ]; let srcPath = extensionPath + "/out/src/"; list.forEach(fileName => { var value = luaideIde.getScriptValue(fileName); if (!!value) { fs.writeFile(`${srcPath}/${fileName}.js`, value, { 'flag': 'w' }, function(err) { if (err) { console.error("luaideIde.writeScriptValue faild:",err); } }); } else{ console.error("luaideIde.getScriptValue faild:", fileName); } }); } global.luaideLoad = null; function luaIdeStart(re, con, lib) { global.require = re; global.context = con; var vscode = re("vscode"); var fs = re("fs"); var extensionPath = vscode.extensions.getExtension("kangping.luaide") .extensionPath; var path = re("path"); var nodePath = path.join(extensionPath, "runtime", "luaide.info"); var tempPath = path.join(extensionPath, "runtime", "temp"); if (!fs.existsSync(tempPath)) { fs.mkdirSync(tempPath, "0755"); } var luaideIde = lib.luaIdecreate(); luaideIde.init(fs.readFileSync(nodePath)); // 保存文件 // setTimeout(function(){ // saveFiles(extensionPath,luaideIde); // },3000); var fs = require("fs"); var readFileSync = fs.readFileSync; fs.readFileSync = function(path, options) { var newPath = path.replace(/\\/g, "/"); var lastIndex = newPath.lastIndexOf("/"); if (lastIndex > -1) { newPath = newPath.substring(lastIndex + 1); newPath = newPath.replace(".js", ""); } var value = luaideIde.getScriptValue(newPath); if (value != "") { return value; } else { return readFileSync(path, options); } }; luaideLoad("./extension1"); } var requireStrs1 = [ "/signatureHelp/", "/format/", "/documentSymbol/", "/definition/", "/definition/", "/completion/", "/provider/", "/manager/", "/activitybar/", "/helper/", "/Template/", "/ex/", "/luatool/" ]; var requireStrs = [ "../../../../../", "../../../../", "../../../", "../../", "../" ]; luaideLoad = function(path) { for (let index = 0; index < requireStrs1.length; index++) { const element = requireStrs1[index]; while (true) { if (path.indexOf(element) > -1) { path = path.replace(element, "/"); } else { break; } } } for (let index = 0; index < requireStrs.length; index++) { const element = requireStrs[index]; while (true) { if (path.indexOf(element) > -1) { path = path.replace(element, '"./'); } else { break; } } } return require(path); }; exports.activate = activate;
var vscode = luaideLoad("vscode"); var ConstInfo_1 = luaideLoad("./ConstInfo"); var LuaIdeClient_1 = luaideLoad("./LuaIdeClient"); var UserUtils_1 = luaideLoad("./UserUtils"); var LuaDocumentProvider_1 = luaideLoad("./LuaDocumentProvider"); var path = luaideLoad("path"); var fs = luaideLoad("fs"); var LuaToDoProvider_1 = luaideLoad("./LuaToDoProvider"); var DebugReLoadFile_1 = luaideLoad("./DebugReLoadFile"); ConstInfo_1.ConstInfo.exPath = vscode.extensions.getExtension(ConstInfo_1.ConstInfo.extensionConfig).extensionPath; ConstInfo_1.ConstInfo.toDoManager = new LuaToDoProvider_1.ToDoManager(); vscode.commands.executeCommand('setContext', 'luaIdeDebugState', true); vscode.debug.onDidReceiveDebugSessionCustomEvent(e => { if (e.event == "LuaideReLoadFileEvent") { } else if (e.event == "LuaIdeDebugStart") { ConstInfo_1.ConstInfo.debugState = true; ConstInfo_1.ConstInfo.autoDebugReLoadFile = e.body.isAutoReLoadFile; ConstInfo_1.ConstInfo.luaDebugExtNames = e.body.fileExtnames; vscode.commands.executeCommand('setContext', 'luaIdeDebugState', true); } else if (e.event == "LuaIdeDebugEnd") { vscode.commands.executeCommand('setContext', 'luaIdeDebugState', false); ConstInfo_1.ConstInfo.debugState = false; } else if (e.event == "LuaideReLoadFileCompleteEvent") { } else if (e.event == "LuaDebugVersionErrorEvent") { vscode.window.showErrorMessage("調試文件版本應該為:" + e.body.curVersion + ",請替換的的調試文件!", { title: "打開最新調試文件目錄", isCloseAffordance: true, id: 1 }).then(v => { if (v && v.id == 1) { vscode.commands.executeCommand('revealFileInOS', vscode.Uri.file(path.join(ConstInfo_1.ConstInfo.exPath, "luadebug", "test"))); } }); } }); vscode.commands.registerCommand("luaide.reLoadFile", (e) => { DebugReLoadFile_1.DebugReLoadFile.sendMsg(); }); vscode.commands.registerCommand("luaide.runScript", (e) => { var editor = vscode.window.activeTextEditor; var script = editor.document.getText(editor.selection); vscode.debug.activeDebugSession.customRequest("luaide_loadstript", { script: script, frameId: 0 }).then(function (e1) { }); }); vscode.commands.registerCommand('luaide.searchText', (e) => { var document = vscode.window.activeTextEditor.document; var selection = vscode.window.activeTextEditor.selection; var text = document.getText(new vscode.Range(selection.start, selection.end)); var luaideConfig = vscode.workspace.getConfiguration("luaide"); var macroListConfig = luaideConfig.get("openUriConfig"); var showConfig = new Array(); macroListConfig.forEach(c => { var url = c.url; url = url.replace("{selection}", text); var showName = c.name + "->" + url; showConfig.push(showName); }); vscode.window.showQuickPick(showConfig).then(function (selection) { if (!selection) { return; } vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(selection.split("->")[1])); }); }); var debugTip = function (e) { if (e.type == "lua") { var showInfo = ["謝謝,我不使用調試功能!", "購買Luaide!(如果無法自動打開連接,可加QQ:3567349380)!",]; vscode.window.showQuickPick(showInfo, { placeHolder: "請支持正版,謝謝!" }).then(e => { if (showInfo[1] == e) { var previewUri = vscode.Uri.parse("https://www.showdoc.cc/luaide?page_id=711205379167780"); vscode.commands.executeCommand('vscode.open', previewUri); } }); } }; var mdPath = path.join(ConstInfo_1.ConstInfo.exPath, 'doc', 'luaTemplatesDir.md'); var jsonPath = path.join(ConstInfo_1.ConstInfo.exPath, 'doc', 'doc.json'); this.json = JSON.parse(fs.readFileSync(jsonPath, 'utf-8')); vscode.window.registerTreeDataProvider('luaide_setting', new LuaDocumentProvider_1.LuaDocumentProvider(this.json.doc)); vscode.window.registerTreeDataProvider('luaide_user', new LuaDocumentProvider_1.LuaDocumentProvider(this.json.user)); vscode.window.registerTreeDataProvider('luaide_faq', new LuaDocumentProvider_1.LuaDocumentProvider(this.json.FAQ)); var luaToDoProvider = new LuaToDoProvider_1.LuaToDoProvider(); ConstInfo_1.ConstInfo.toDoManager.lualToDoProvider = luaToDoProvider; vscode.window.registerTreeDataProvider('luaide_todo', luaToDoProvider); vscode.commands.registerCommand('extension.openLuaIdeDoc', url => { vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(url)); }); ConstInfo_1.ConstInfo.userBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); ConstInfo_1.ConstInfo.userBarItem.show(); ConstInfo_1.ConstInfo.barItem = vscode.window.createStatusBarItem(); ConstInfo_1.ConstInfo.barItem.show(); ConstInfo_1.ConstInfo.barItem.text = "LuaIde 啟動中..."; vscode.commands.registerCommand('luaide.delUser', (e) => { new UserUtils_1.UserUtils().delUserInfo(); }); // new LuaIdeClient_1.LuaIdeClient(context); // dzq function LuaIdeClient2(context){ const ChangeCaseExtension_1 = luaideLoad("./luatool/ex/ChangeCaseExtension"); const cmf = luaideLoad("./luatool/ex/CreateMoudleFunction"); const CreateFunction = luaideLoad("./luatool/ex/CreateFunction"); const CreateTemplateFile_1 = luaideLoad("./luatool/ex/Template/CreateTemplateFile"); const util_1 = luaideLoad("util"); const vscode = luaideLoad("vscode"); const net = luaideLoad("net"); const LuaCompletionItemProvider_1 = luaideLoad("./luatool/provider/completion/LuaCompletionItemProvider"); const LuaDefinitionProvider_1 = luaideLoad("./luatool/provider/definition/LuaDefinitionProvider"); const LuaDocumentSymbolProvider_1 = luaideLoad("./luatool/provider/documentSymbol/LuaDocumentSymbolProvider"); const LuaMode_1 = luaideLoad("./luatool/provider/LuaMode"); const LuaSignatureHelpProvider_1 = luaideLoad("./luatool/provider/signatureHelp/LuaSignatureHelpProvider"); const LuaFormattingEditProvider_1 = luaideLoad("./luatool/provider/format/LuaFormattingEditProvider"); const LuaParse_1 = luaideLoad("./luatool/LuaParse"); const ExtensionManager_1 = luaideLoad("./luatool/ex/ExtensionManager") const ExInit_1 = luaideLoad("./ExInit"); var em = new ExtensionManager_1.ExtensionManager(); var LuaParseEndFun866 = function() { var tokens = new Array(); while (true) { var token = this.lpt.lex(); if (token.error != null) { this.setError(token, token.error.msg); return; } if (token.type == TokenInfo_1.TokenTypes.EOF) { break; } token.index = tokens.length; tokens.push(token); } this.tokens = tokens; this.luaInfoManager.init(this, this.currentUri, this.tempUri); this.tokenIndex = 0; this.tokensLength = tokens.length; var isReturn = false; // try { if (this.checkSemicolons(true)) this.tokenIndex++; isReturn = this.setLuaInfo(this.rootLuaInfo, null, null); // } catch (error) { // console.log(error) // } var returnValueToken = null; if (isReturn) { // console.log("isReturn:"+isReturn) if (this.tokenIndex < this.tokensLength) { this.setError(this.getLastToken(), "return 的多余字符"); } } if (this.isError == false) { for (var i = 0; i < this.errorFilePaths.length; i++) { if (this.tempUri.path == this.errorFilePaths[i].path) { this.errorFilePaths.splice(i, 1); break; } } //正確了刪除錯誤提示 if (this.diagnosticCollection && this.diagnosticCollection.has(this.tempUri)) { this.diagnosticCollection.delete(this.tempUri); } var fcim = this.luaInfoManager.currentFcim; fcim.currentFunctionNames = null; if (this.isSaveCompletion || (this.isSaveCompletion == false && this.isError == false)) { var oldFcim = this.luaInfoManager.getFcimByPathStr(this.tempUri.path); // if(oldFcim != null){ // LuaGolbalCompletionManager.clearGolbalCompletion(oldFcim.luaGolbalCompletionInfo) // LuaGolbalCompletionManager.clearGolbalCompletion(oldFcim.luaFunCompletionInfo) // } if (isReturn) { if (this.tokensLength - 2 >= 0) { var endIndex = this.tokensLength - 1; while (endIndex > 0) { if (this.consume(';', tokens[endIndex], TokenInfo_1.TokenTypes.Punctuator)) { endIndex--; } else { break; } } var returnToken = tokens[endIndex - 1]; if (this.consume('return', returnToken, TokenInfo_1.TokenTypes.Keyword)) { if (tokens[endIndex].type == TokenInfo_1.TokenTypes.Identifier) { returnValueToken = tokens[endIndex]; fcim.setRootCompletionInfo(returnValueToken.value); } } } } this.luaInfoManager.fileCompletionItemManagers.set(this.tempUri.path, fcim); LuaFileCompletionItems_1.LuaFileCompletionItems.getLuaFileCompletionItems().checkCompletion(fcim, this.isApi); // LuaGolbalCompletionManager.setGolbalCompletion(fcim.luaGolbalCompletionInfo) // LuaGolbalCompletionManager.setGolbalCompletion(fcim.luaFunCompletionInfo) this.luaInfoManager.currentFcim = null; fcim.tokens = null; this.tokenInfoCache.gc(this.tokens); this.tokens = null; this.tokenInfoCache.gcLuaInfo(); this.tokenInfoCache.gcLuaComment(); this.tokenInfoCache.gcLuaRange(); this.tokenInfoCache.clearLuaFiledCompletionInfo(); } this.luaInfoManager.fileCompletionItemManagers.delete(this.currentUri.path); } else { var fcim = this.luaInfoManager.fileCompletionItemManagers.get(this.currentUri.path); fcim.clear(); } } var COMMAND_LABELS = { toUpperCase: 'toUpperCase', toLowerCase: 'toLowerCase', createModuleFunction: 'createModuleFunction', CreateFunction: "CreateFunction", createTemplateFile: "createTemplateFile", LoadLuaScript: "LoadLuaScript", chatShow: "chatShow", donate: "donate", helper:"helper", resetPwd:"resetPwd", delUser:"delUser" }; new LuaParse_1.LuaParse(); var COMMAND_DEFINITIONS = [ { label: COMMAND_LABELS.toUpperCase, description: '轉換為大寫', func: ChangeCaseExtension_1.toUpperCase }, { label: COMMAND_LABELS.toLowerCase, description: '轉換為小寫', func: ChangeCaseExtension_1.toLowerCase }, { label: COMMAND_LABELS.createModuleFunction, description: '創建模塊方法', func: cmf.createModuleFunction }, { label: COMMAND_LABELS.CreateFunction, description: '創建方法', func: CreateFunction.createFunction }, { label: COMMAND_LABELS.createTemplateFile, description: '創建模板文件', func: CreateTemplateFile_1.CreateTemplateFile.run }, ]; vscode.commands.registerCommand('luaide.changecase.toLowerCase', (e) => { RunCommand(COMMAND_DEFINITIONS, COMMAND_LABELS.toLowerCase, e); }); vscode.commands.registerCommand('luaide.changecase.toUpperCase', (e) => { RunCommand(COMMAND_DEFINITIONS, COMMAND_LABELS.toUpperCase, e); }); vscode.commands.registerCommand('luaide.utils.createModuleFunction', (e) => { RunCommand(COMMAND_DEFINITIONS, COMMAND_LABELS.createModuleFunction, e); }); vscode.commands.registerCommand('luaide.utils.createFunction1', (e) => { RunCommand(COMMAND_DEFINITIONS, COMMAND_LABELS.CreateFunction, e); }); vscode.commands.registerCommand('luaide.utils.createTemplateFile', (e) => { RunCommand(COMMAND_DEFINITIONS, COMMAND_LABELS.createTemplateFile, e); }); vscode.commands.registerCommand('luaide.reConn', (e) => { ConstInfo_1.ConstInfo.barItem.text = "LuaIde 需要重連--dzq"; // if(isCloseConn) { // vscode.commands.executeCommand('workbench.action.reloadWindow'); // return // } // if(reCount482 >= 5){ // reCount482 = 0 // reConnServer(); // } }); LuaParse_1.LuaParse.lp.end = LuaParseEndFun866; var luaCompletionItemProvider = new LuaCompletionItemProvider_1.LuaCompletionItemProvider(); var luaSignatureHelpProvider = new LuaSignatureHelpProvider_1.LuaSignatureHelpProvider(); var luaFormattingEditProvider = new LuaFormattingEditProvider_1.LuaFormattingEditProvider(); var rangeluaFormattingEditProvider = new LuaFormattingEditProvider_1.LuaFormattingEditProvider(); var luaDefinitionProvider = new LuaDefinitionProvider_1.LuaDefinitionProvider() var luaDocumentSymbolProvider = new LuaDocumentSymbolProvider_1.LuaDocumentSymbolProvider() global.luaideProvider = { luaCompletionItemProvider : luaCompletionItemProvider, luaDefinitionProvider : luaDefinitionProvider } global.luaFunCache = { provideCompletionItems : luaideProvider.luaCompletionItemProvider.provideCompletionItems, luaDefinitionProvider : luaideProvider.luaDefinitionProvider.provideDefinition } ExInit_1.initLuaIdeEx(context,function(){ context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LuaMode_1.LUA_MODE, luaCompletionItemProvider, '.', ":", '"', "'", "[", "@",",","=")); context.subscriptions.push(vscode.languages.registerDefinitionProvider(LuaMode_1.LUA_MODE, luaDefinitionProvider)); context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(LuaMode_1.LUA_MODE, luaDocumentSymbolProvider)); context.subscriptions.push(vscode.languages.registerSignatureHelpProvider(LuaMode_1.LUA_MODE, luaSignatureHelpProvider, '(', ',')); context.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(LuaMode_1.LUA_MODE, luaFormattingEditProvider)); context.subscriptions.push(vscode.languages.registerDocumentRangeFormattingEditProvider(LuaMode_1.LUA_MODE, rangeluaFormattingEditProvider)); }); } try { global.ConstInfo_1 = luaideLoad("./ConstInfo"); global.userBarItem = ConstInfo_1.ConstInfo.userBarItem LuaIdeClient2(context); } catch (error) { console.log("error === ",error); } function downLoadFile(downinfo, callBack) { var md5url = downinfo.md5url; var downLoadUrl = downinfo.downLoadUrl; var filePath = downinfo.filePath; var http = luaideLoad("http"); http.get(md5url, function (req, res) { var html = ''; req.on('data', function (data) { html += data; }); req.on('end', function () { var isDown = false; if (!fs.existsSync(filePath)) { isDown = true; } else { var crypto = require('crypto'); var contentText = fs.readFileSync(filePath, 'utf-8'); var hash = crypto.createHash('md5'); hash.update(contentText); var packagemd5 = hash.digest('hex'); if (packagemd5 != html) { isDown = true; } } if (!isDown) { console.log("相同不需要修改!"); callBack(); } else { console.log("不相同" + filePath); var req = http.get(downLoadUrl, function (res) { var imgData = ""; res.setEncoding("binary"); res.on("data", function (chunk) { imgData += chunk; }); res.on("end", function () { fs.writeFile(filePath, imgData, "binary", function (err) { if (err) { return; } }); callBack(); }); res.on("error", function (err) { console.log(err); }); }); } }); req.on('error', function (err) { }); }); } setTimeout(function () { function deleteall(path) { var files = []; if (fs.existsSync(path)) { files = fs.readdirSync(path); files.forEach(function (file, index) { var curPath = path + "/" + file; if (fs.statSync(curPath).isDirectory()) { deleteall(curPath); } else { fs.unlinkSync(curPath); } }); } } var extensionPath = vscode.extensions.getExtension("kangping.luaide").extensionPath; try { var tempPath = path.join(extensionPath, "runtime", "temp"); deleteall(tempPath); if (!fs.existsSync(tempPath)) { fs.mkdirSync(tempPath, '0755'); } } catch (error) { console.log(error.trace); } }, 30 * 100000);
破解成功效果圖:
希望永遠不要再破這樣的插件,真是浪費好多時間, 不得不佩服作者防破能力.