import Vue from 'vue/dist/vue.esm.js'; export default function() { const rptParser = new Vue({ el: '#rpt-parser', data: { processing: false, removeDuplicates: true, showExplaination: true, rptLines: [], errors: [], startOfError: /error in expression/i, errorPosition: /error position: <(.*)$/i, errorReason: /error\s(.*)$/i, errorInfos: [ /file\s*.*,\s*line\s*\d+/i, /callextension.*could not be found/i ], genericMessages: [ //CallExtension 'updatearmalog' could not be found /callextension .* could not be found$/i, //Warning Message: File mpmissions\__cur_mp.Lythium\description.ext, line 100: .CfgNetworkMessages: Member already defined. /warning message: .* member already defined\.$/i, //Warning Message: File mpmissions\Exile.Chernarus_winter\description.ext, line 193: /CfgInteractionMenus/: Missing '}' /warning message: .* missing '}'/i, // File mpmissions\__cur_mp.Lythium\config.cpp, line 2238: '/CfgExileArsenal/srifle_LRR_camo_F.price': Missing ';' prior '}' /file .*: missing .*/i ], reasons: [ { regex: /foreign error: unknown enum value: (.*)/gi, reason: "The enum value '$1' is not a valid value for this command.<br>Double check spelling or the biki for the proper enum values for this command" }, { regex: /missing ;/gi, reason: ` You are missing a <code>;</code> or you have an extra one on or before this line of code.<br>Unfortunately, Arma decides to throw this error if you are missing or have extras of any of the following: <code>()</code>, <code>{}</code>, <code>[]</code><br>We suggest looking around this line for anything out of the ordinary and double check everything!` }, { regex: /invalid number in expression/gi, reason: "A variable or part of this command is expecting a number, but it isn't valid.<br>Follow the code and make sure the value sent to this is indeed a number" }, { regex: /generic error in expression/gi, reason: "This is BIS's way of saying, <i>We don't know what went wrong, it's just wrong</i><br>This is one of the hardest errors to troubleshoot. We suggest making sure the code on or around the reported file line is valid syntax" }, { regex: /callextension '(.*)' could not be found/i, reason: "Make sure <code>$1.dll</code> or <code>$1_x64.dll</code> in the mod or server folder and <code>$1</code> is the correct spelling of the DLL." }, { // Warning Message: File mpmissions\__cur_mp.Lythium\description.ext, line 100: .CfgNetworkMessages: Member already defined. regex: /warning message: (.*): \.(.*): member already defined\.$/i, reason: "In <code>$1</code>, around that line there is <code>class $2</code>. Somewhere in this file, this class already exists.<br>Be careful, sometimes files are included by <code>#include</code>. Make sure to check these files as well for this duplicated class." }, { regex: /warning message: (.*) missing '}'/i, reason: "In <code>$1</code>, around that line (either before, on, or after), you are missing OR have an extra <code>}</code>.<br>Often times this will throw because you have an extra <code>};</code>" }, { // Undefined variable in expression: _export regex: /undefined variable in expression: (.*)/i, reason: `<code>$1</code> has not been defined/initialized by the engine. This could happen for a number of reasons:<ul class="uk-list uk-list-bullet"><li>It was never initialized correctly</li><li>The variable was assigned <code>nil</code></li><li>The variable was a parameter for the script and was not passed a value</li></ul>` }, { // File mpmissions\__cur_mp.Lythium\config.cpp, line 2238: '/CfgExileArsenal/srifle_LRR_camo_F.price': Missing ';' prior '}' regex: /File (.*), line (.*): '(.*)': missing '(.*)' prior '(.*)'/i, reason: "In file <code>$1</code>, around line <code>$2</code>, there is a config for <code>$3</code>. That config is missing or has an extra <code>$4</code> before <code>$5</code>." } ] }, methods: { updateFileName: function() { if ($("#uploader").prop("files").length > 0) { $("#file-name").text($("#uploader").prop("files")[0].name); } }, start: function() { let that = this; this.rptLines = []; this.errors = []; this.processing = true; if ($("#uploader").prop("files").length > 0) { let file = $("#uploader").prop("files")[0]; let reader = new FileReader(); reader.onload = (event) => { let file = event.target.result; file.split(/\r\n|\n/).map((line) => { that.rptLines.push(line); }); that.startParse(); }; reader.onerror = (evt) => { Toaster.error(evt.target.error.name); }; reader.readAsText(file); $("#btnParse").addClass("uk-disabled"); } else { return Toaster.warn("Please select a RPT to parse"); } }, startParse: function() { if (this.rptLines.length === 0) return Toaster.error("Fail to read RPT"); this.parseRPT(); if (this.removeDuplicates) { this.filterErrors(); } if (this.showExplaination) { this.addExplainations(); } if (_.isEmpty(this.errors)) { Toaster.success("No errors found", "Parsing completed"); } else { Toaster.warn(`Found ${this.errors.length} errors`, "Parsing completed"); } this.processing = false; $("#btnParse").removeClass("uk-disabled"); }, parseRPT: function() { let inError = false, currentError = { code: "", reason: "", info: "", rptLine: 0, explaination: "" }, lineCount = 0; for (let i = 0; i < this.rptLines.length; i++) { let line = this.rptLines[i]; lineCount++; if (!inError) { for (let message of this.genericMessages) { var match = message.exec(line); if (match !== null) { currentError = { code: "", reason: "", info: match, rptLine: i, explaination: "" }; this.errors.push(currentError); } } } if (!inError && this.startOfError.test(line)) { currentError = { code: "", reason: "", info: "", rptLine: i, explaination: "" }; inError = true; lineCount = 0; continue; } if (inError) { if (lineCount >= 30) { this.errors.push(currentError); inError = false; continue; } let positionMatch = this.errorPosition.exec(line); if (positionMatch !== null) { currentError["code"] = positionMatch[1]; continue; } let reasonMatch = this.errorReason.exec(line); if (reasonMatch !== null) { currentError["info"] = reasonMatch[1]; continue; } for (let regex of this.errorInfos) { let match = regex.exec(line); if (match !== null) { currentError["reason"] = match[0]; this.errors.push(currentError); inError = false; break; } } } } }, filterErrors: function() { if (this.errors.length === 0) return; let filtered = []; for (let error of this.errors) { if (filtered.length === 0) { filtered.push(error); continue; } let found = false; for (let obj of filtered) { if ( (obj.code !== "" && obj.code === error.code) && (obj.info !== "" && obj.info === error.info) && (obj.reason !== "" && obj.reason === error.reason) ) { found = true; break; }; } if (found) continue; filtered.push(error); } this.errors = _.cloneDeep(filtered); }, addExplainations: function() { if (_.isEmpty(this.errors)) return; for (let error of this.errors) { for (let reason of this.reasons) { let reasonRegex = reason.regex; let reasonText = reason.reason; let match = reasonRegex.exec(error.info); if (match !== null) { if (_.isArray(match)) { reasonText = match[0].replace(reasonRegex, reasonText); } error.explaination = reasonText; break; } } } } } }); }