破解对象: 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);
破解成功效果图:
希望永远不要再破这样的插件,真是浪费好多时间, 不得不佩服作者防破能力.