diff --git a/index.js b/index.js new file mode 100644 index 0000000..d6bff9b --- /dev/null +++ b/index.js @@ -0,0 +1,119 @@ +const express = require('express'); +const fs = require('fs'); +const path = require('path'); +const crypto = require('crypto'); + + +const port = 443; + +var app = express(); + +const cache = { + +}; + +app.use("/files", express.static("projects")); + +function get_indexes(project_id) { + if (cache[project_id]) { + let indexes = ""; + for (let path in cache[project_id]) { + indexes += `${path} ${cache[project_id][path]}\n`; + } + return indexes.trim(); + } + else if (fs.existsSync(path.join(__dirname, "projects", project_id))) { + let files = fs.readdirSync(path.join(__dirname, "projects", project_id)); + let indexes = ""; + cache[project_id] = {}; + for (let file of files) { + let fileContents = fs.readFileSync(path.join(__dirname, "projects", project_id, file)); + let hash = crypto.createHash("md5"); + hash.update(fileContents); + cache[project_id][file] = hash.digest('hex'); + indexes += `${file} ${cache[project_id][file]}\n`; + } + return indexes.trim(); + } + else { + return undefined; + } +} + +app.get("/indexes/:project(\\w+)", (req, res) => { + let project_id = req.params['project']; + + let indexes = get_indexes(project_id); + + if (indexes != undefined) { + res.send(indexes); + } + else { + res.sendStatus(404); + } +}); + +app.use("/updates", express.text()); + +function diff(current, checked) { + let lines_current = current.split('\n').map(l => l.trim()); + let lines_checked = checked.split('\n').map(l => l.trim()); + let filenames_checked = lines_checked.map(l => l.split(" ")[0]); + + console.log(lines_current, lines_checked); + let result = ""; + + for (let line of lines_current) { + if (line.length != 0) { + let split = line.split(" "); + console.log(`split: ${split}`); + let index = filenames_checked.indexOf(split[0]); + console.log(`index: ${index}`); + if (index == -1) { + result += `${split[0]} download\n`; + continue; + } + let filename = filenames_checked[index]; + let hash = lines_checked[index].split(" ")[1].trim(); + console.log(`expected: ${split[0]} hash ${split[1]} found: ${filename} hash ${hash}`); + if (split[0] != filename || split[1] != hash) { + result += `${split[0]} download\n`; + } + console.log(`popping line ${index}, current: ${lines_checked}`); + lines_checked.splice(index, 1); + console.log(`result: ${lines_checked}`); + } + } + + // now take care of the rest. + if (Array.isArray(lines_checked)) { + for (let line of lines_checked) { + console.log(`delete line ${line}`); + result += `${line.split(" ")[0]} delete\n`; + } + } + else { + // only 1 file left! + result += `${lines_checked.split(" ")[0]} delete\n`; + } + + return result; +} + +app.post("/updates/:project(\\w+)", (req, res) => { + let project_id = req.params['project']; + const body = req.body.replace(/\r/, ""); + let indexes = get_indexes(project_id); + let difference = diff(indexes, body); + + if (difference.length > 0) { + res.send(difference); + } + else { + res.sendStatus(204); + } +}); + +app.listen(port, () => { + console.log(`listening on ${port}`); +}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..2a5ba1e --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "lua-serve", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "repository": { + "type": "git", + "url": "git@ssh.gitdab.com:jane/lua-serve" + }, + "author": "jane ", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "express": "^4.17.1" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..0cb2dc1 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,394 @@ +dependencies: + express: 4.17.1 +lockfileVersion: 5.2 +packages: + /accepts/1.3.7: + dependencies: + mime-types: 2.1.31 + negotiator: 0.6.2 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + /array-flatten/1.1.1: + dev: false + resolution: + integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + /body-parser/1.19.0: + dependencies: + bytes: 3.1.0 + content-type: 1.0.4 + debug: 2.6.9 + depd: 1.1.2 + http-errors: 1.7.2 + iconv-lite: 0.4.24 + on-finished: 2.3.0 + qs: 6.7.0 + raw-body: 2.4.0 + type-is: 1.6.18 + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + /bytes/3.1.0: + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + /content-disposition/0.5.3: + dependencies: + safe-buffer: 5.1.2 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + /content-type/1.0.4: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + /cookie-signature/1.0.6: + dev: false + resolution: + integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + /cookie/0.4.0: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + /debug/2.6.9: + dependencies: + ms: 2.0.0 + dev: false + resolution: + integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + /depd/1.1.2: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + /destroy/1.0.4: + dev: false + resolution: + integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + /ee-first/1.1.1: + dev: false + resolution: + integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + /encodeurl/1.0.2: + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + /escape-html/1.0.3: + dev: false + resolution: + integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + /etag/1.8.1: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + /express/4.17.1: + dependencies: + accepts: 1.3.7 + array-flatten: 1.1.1 + body-parser: 1.19.0 + content-disposition: 0.5.3 + content-type: 1.0.4 + cookie: 0.4.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 1.1.2 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.1.2 + fresh: 0.5.2 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.3.0 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.7.0 + range-parser: 1.2.1 + safe-buffer: 5.1.2 + send: 0.17.1 + serve-static: 1.14.1 + setprototypeof: 1.1.1 + statuses: 1.5.0 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + dev: false + engines: + node: '>= 0.10.0' + resolution: + integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + /finalhandler/1.1.2: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + /forwarded/0.2.0: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + /fresh/0.5.2: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + /http-errors/1.7.2: + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.1 + statuses: 1.5.0 + toidentifier: 1.0.0 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + /http-errors/1.7.3: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.1.1 + statuses: 1.5.0 + toidentifier: 1.0.0 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + /iconv-lite/0.4.24: + dependencies: + safer-buffer: 2.1.2 + dev: false + engines: + node: '>=0.10.0' + resolution: + integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + /inherits/2.0.3: + dev: false + resolution: + integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + /inherits/2.0.4: + dev: false + resolution: + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + /ipaddr.js/1.9.1: + dev: false + engines: + node: '>= 0.10' + resolution: + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + /media-typer/0.3.0: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + /merge-descriptors/1.0.1: + dev: false + resolution: + integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + /methods/1.1.2: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + /mime-db/1.48.0: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== + /mime-types/2.1.31: + dependencies: + mime-db: 1.48.0 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== + /mime/1.6.0: + dev: false + engines: + node: '>=4' + hasBin: true + resolution: + integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + /ms/2.0.0: + dev: false + resolution: + integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + /ms/2.1.1: + dev: false + resolution: + integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + /negotiator/0.6.2: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + /on-finished/2.3.0: + dependencies: + ee-first: 1.1.1 + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + /parseurl/1.3.3: + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + /path-to-regexp/0.1.7: + dev: false + resolution: + integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + /proxy-addr/2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: false + engines: + node: '>= 0.10' + resolution: + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + /qs/6.7.0: + dev: false + engines: + node: '>=0.6' + resolution: + integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + /range-parser/1.2.1: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + /raw-body/2.4.0: + dependencies: + bytes: 3.1.0 + http-errors: 1.7.2 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + /safe-buffer/5.1.2: + dev: false + resolution: + integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + /safer-buffer/2.1.2: + dev: false + resolution: + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + /send/0.17.1: + dependencies: + debug: 2.6.9 + depd: 1.1.2 + destroy: 1.0.4 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 1.7.3 + mime: 1.6.0 + ms: 2.1.1 + on-finished: 2.3.0 + range-parser: 1.2.1 + statuses: 1.5.0 + dev: false + engines: + node: '>= 0.8.0' + resolution: + integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + /serve-static/1.14.1: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.17.1 + dev: false + engines: + node: '>= 0.8.0' + resolution: + integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + /setprototypeof/1.1.1: + dev: false + resolution: + integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + /statuses/1.5.0: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + /toidentifier/1.0.0: + dev: false + engines: + node: '>=0.6' + resolution: + integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + /type-is/1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.31 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + /unpipe/1.0.0: + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + /utils-merge/1.0.1: + dev: false + engines: + node: '>= 0.4.0' + resolution: + integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + /vary/1.1.2: + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +specifiers: + express: ^4.17.1 diff --git a/projects/updater/install.lua b/projects/updater/install.lua new file mode 100644 index 0000000..9197824 --- /dev/null +++ b/projects/updater/install.lua @@ -0,0 +1,40 @@ +args = {...} + +path = "bin/" +if not fs.exists(path) then + fs.makeDir(path) +end +temp = "temp/" +if not fs.exists(temp) then + fs.makeDir(temp) +end + +if #args > 0 then + programToInstall = args[1] +end +if #args > 1 then + customPath = shell.resolve(args[2]) +end + +function arrayAppend(array, value) + array[#array + 1] = value +end + +function finishInstall(files) + for key, file in ipairs(files) do + if customPath ~= nil then + fs.move(temp .. file, customPath .. "/" .. file) + else + fs.move(temp .. binary, path .. binary) + end + end + + if customPath ~= nil then + program = "shell.run(" .. customPath .. "/run.lua)" + file = fs.open(path .. programToInstall .. "/run.lua") + file.write(program) + file.close() + end + + fs.delete(temp) +end diff --git a/projects/updater/update.lua b/projects/updater/update.lua new file mode 100644 index 0000000..bfe699d --- /dev/null +++ b/projects/updater/update.lua @@ -0,0 +1 @@ +print('fuck') \ No newline at end of file