mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-21 21:36:26 -08:00
this code actually sucks ass
god bless anyone who reads this 1.2.1 i'll need to clean this shit up lmao
This commit is contained in:
parent
0aad03c50e
commit
3ef9eeaf4c
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command":"npx tsc\nnode ./out/index.js\ndel ./server_out/* -Recurse",
|
||||
"command":"npx tsc\nnode ./out/index.js\ndel ./out/* -Recurse",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
|
|
|
@ -17,10 +17,11 @@ TOKEN=KILL-YOURSELF.NOW
|
|||
- [X] 1.1.2 fix file cloning with binary data
|
||||
- [X] 1.1.3 display current version on pages
|
||||
- [X] 1.1.4 serve /assets as static files & make /server endpoint
|
||||
- [ ] 1.2.0 add simple moderation tools
|
||||
- [ ] 1.2.1 prevent cloning of local/private ip addresses
|
||||
- [ ] 1.3.0 allow custom file ids
|
||||
- [ ] 1.4.0 accounts??? maybe?? (this probably won't happen)
|
||||
- [X] 1.2.0 add file parameters section + custom ids
|
||||
- [ ] 1.2.1 clean up this shitty code
|
||||
- [ ] 1.2.2 add id locks, allowing you to set a key for a file that allows you to overwrite the file in the future
|
||||
- [ ] 1.2.3 prevent cloning of local/private ip addresses
|
||||
- [ ] 1.3.0 add simple moderation tools
|
||||
- [ ] 2.0.0 rewrite using theUnfunny's code as a base/rewrite using monofile-core
|
||||
|
||||
also todo: monofile-core (written in eris)
|
||||
|
|
30
assets/script/clone_file.js
Normal file
30
assets/script/clone_file.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
document.getElementById("uploadButton").addEventListener("click",() => {
|
||||
let ask = prompt("Input a URL to clone.")
|
||||
|
||||
if (ask) {
|
||||
let opt = getOptionsForUploading()
|
||||
updateBtnTxt("Requesting clone. Please wait.")
|
||||
|
||||
let xmlhttp = new XMLHttpRequest()
|
||||
|
||||
xmlhttp.addEventListener("error",function(e) {
|
||||
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
xmlhttp.addEventListener("load",function() {
|
||||
if (xmlhttp.status == 200) {
|
||||
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
||||
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
||||
} else {
|
||||
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
||||
}
|
||||
})
|
||||
|
||||
xmlhttp.open("POST","/clone")
|
||||
xmlhttp.send(JSON.stringify({
|
||||
url: ask,
|
||||
...opt
|
||||
}))
|
||||
}
|
||||
})
|
37
assets/script/upload_file.js
Normal file
37
assets/script/upload_file.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
let FileUpload = document.createElement("input")
|
||||
FileUpload.setAttribute("type","file")
|
||||
|
||||
document.getElementById("uploadButton").addEventListener("click",() => FileUpload.click())
|
||||
|
||||
FileUpload.addEventListener("input",() => {
|
||||
if (FileUpload.files[0]) {
|
||||
let opt = getOptionsForUploading()
|
||||
let file = FileUpload.files[0]
|
||||
|
||||
updateBtnTxt("Uploading file. This may take a while, so stay put.")
|
||||
|
||||
let xmlhttp = new XMLHttpRequest()
|
||||
|
||||
xmlhttp.addEventListener("error",function(e) {
|
||||
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
xmlhttp.addEventListener("load",function() {
|
||||
if (xmlhttp.status == 200) {
|
||||
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
||||
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
||||
} else {
|
||||
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
||||
}
|
||||
})
|
||||
|
||||
let fd = new FormData()
|
||||
fd.append('file',file)
|
||||
|
||||
xmlhttp.open("POST","/upload")
|
||||
xmlhttp.setRequestHeader("monofile-upload-id",opt.uploadId)
|
||||
xmlhttp.send(fd)
|
||||
|
||||
}
|
||||
})
|
|
@ -37,31 +37,70 @@
|
|||
left:50%;
|
||||
transform:translate(-50%,0);
|
||||
}
|
||||
#uploadButton {
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-color: #66AAFF;
|
||||
|
||||
button {
|
||||
color:black;
|
||||
font-weight:bold;
|
||||
border:none;
|
||||
position:absolute;
|
||||
left:0px;
|
||||
top:0px;
|
||||
font-size:20px;
|
||||
}
|
||||
#uploadButton:hover {
|
||||
|
||||
button:hover {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
#uploadButton {
|
||||
width:calc( 100% - 50px );
|
||||
height:100%;
|
||||
background-color: #66AAFF;
|
||||
left:0px;
|
||||
top:0px;
|
||||
}
|
||||
|
||||
#optionsButton {
|
||||
width:50px;
|
||||
height:100%;
|
||||
background-color: #AAAAAA;
|
||||
left:calc( 100% - 50px );
|
||||
top:0px;
|
||||
font-size:15px;
|
||||
}
|
||||
|
||||
.note {
|
||||
padding:5px;
|
||||
position:relative;
|
||||
width:calc( 100% - 60px );
|
||||
width:calc( 100% - 62px );
|
||||
left:25px;
|
||||
border:1px solid #AAAAAAFF;
|
||||
border-radius: 8px;
|
||||
background-color: #AAAAAA66;
|
||||
}
|
||||
|
||||
/* this is horrible css lmao */
|
||||
|
||||
#options > input {
|
||||
font-family:monospace;
|
||||
width:250px;
|
||||
font-size:14px;
|
||||
border: 1px solid #777777;
|
||||
background-color:#AAAAAA;
|
||||
outline:none;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#options {
|
||||
height:30px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
#customId {
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:50%;
|
||||
transform:translate(-50%,-50%)
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 450px) {
|
||||
#content {
|
||||
position:fixed;
|
||||
|
@ -92,53 +131,41 @@
|
|||
</ul>
|
||||
</div>
|
||||
<div style="width:100%;height:25px"></div>
|
||||
<div id="btnContainer"><button id="uploadButton">Upload file</button></div>
|
||||
<div id="btnContainer">
|
||||
<button id="uploadButton">$UploadButtonText</button>
|
||||
<button id="optionsButton">• • •</button>
|
||||
</div>
|
||||
<div id="options" class="note" style="border-radius:0px;">
|
||||
<input id="customId" autocomplete="off" placeholder = "custom id (30char, no spaces)" maxlength="30">
|
||||
</div>
|
||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">
|
||||
Max filesize on instance: $MaxInstanceFilesize
|
||||
</p>
|
||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;font-size:12px;color:gray;">made by nbitzz — <a style="color:gray;font-family:monospace;font-size:12px;" href="https://github.com/nbitzz/monofile">github</a> — <a style="color:gray;font-family:monospace;font-size:12px;" href="/clone">clone from url...</a></p>
|
||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;font-size:12px;color:gray;">made by nbitzz — <a style="color:gray;font-family:monospace;font-size:12px;" href="https://github.com/nbitzz/monofile">github</a> — <a style="color:gray;font-family:monospace;font-size:12px;" href="$otherPath">$otherText</a></p>
|
||||
<div style="width:100%;height:25px"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<!-- bad thing to do but i'm being rushed -->
|
||||
|
||||
<script>
|
||||
let updateBtnTxt = (btntxt) => {document.getElementById("btnContainer").innerHTML = `<div class="note" style="width:calc( 100% - 10px );height:calc( 100% - 10px );position:absolute;left:0px;top:0px;"><p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">${btntxt}</p></div>`}
|
||||
let uploading = false
|
||||
const updateBtnTxt = (btntxt) => {document.getElementById("btnContainer").innerHTML = `<div class="note" style="width:calc( 100% - 10px );height:calc( 100% - 10px );position:absolute;left:0px;top:0px;"><p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">${btntxt}</p></div>`}
|
||||
const getOptionsForUploading = () => {
|
||||
uploading = true
|
||||
document.getElementById("options").style.display = "none"
|
||||
|
||||
let FileUpload = document.createElement("input")
|
||||
FileUpload.setAttribute("type","file")
|
||||
|
||||
document.getElementById("uploadButton").addEventListener("click",() => FileUpload.click())
|
||||
|
||||
FileUpload.addEventListener("input",() => {
|
||||
if (FileUpload.files[0]) {
|
||||
let file = FileUpload.files[0]
|
||||
|
||||
updateBtnTxt("Uploading file. This may take a while, so stay put.")
|
||||
|
||||
let xmlhttp = new XMLHttpRequest()
|
||||
|
||||
xmlhttp.addEventListener("error",function(e) {
|
||||
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
xmlhttp.addEventListener("load",function() {
|
||||
if (xmlhttp.status == 200) {
|
||||
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
||||
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
||||
} else {
|
||||
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
||||
return {
|
||||
uploadId: document.getElementById("customId").value
|
||||
}
|
||||
})
|
||||
|
||||
let fd = new FormData()
|
||||
fd.append('file',file)
|
||||
|
||||
xmlhttp.open("POST","/upload")
|
||||
xmlhttp.send(fd)
|
||||
|
||||
}
|
||||
|
||||
document.getElementById("optionsButton").addEventListener("click",() => {
|
||||
let display = document.getElementById("options").style.display
|
||||
if (!uploading) document.getElementById("options").style.display = !display || display == "none" ? "block" : "none"
|
||||
})
|
||||
</script>
|
||||
|
||||
<script src="/static/script/$Handler.js"></script>
|
||||
|
||||
</html>
|
135
pages/clone.html
135
pages/clone.html
|
@ -1,135 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>monofile</title>
|
||||
|
||||
<meta name="og:site_name" content="$Version">
|
||||
<meta name="application-name" content="monofile">
|
||||
<meta name="description" content="Discord-based filesharing">
|
||||
|
||||
<style>
|
||||
|
||||
* {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
h1,h2 {
|
||||
text-align:center;
|
||||
}
|
||||
#content {
|
||||
position:fixed;
|
||||
left:50%;
|
||||
top:50%;
|
||||
transform:translate(-50%,-50%);
|
||||
background-color:white;
|
||||
width:450px;
|
||||
/*height:100%;*/
|
||||
}
|
||||
body {
|
||||
background-color: darkgray;
|
||||
}
|
||||
#btnContainer {
|
||||
width:calc( 100% - 50px );
|
||||
height:50px;
|
||||
position:relative;
|
||||
left:50%;
|
||||
transform:translate(-50%,0);
|
||||
}
|
||||
#uploadButton {
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-color: #66AAFF;
|
||||
color:black;
|
||||
font-weight:bold;
|
||||
border:none;
|
||||
position:absolute;
|
||||
left:0px;
|
||||
top:0px;
|
||||
font-size:20px;
|
||||
}
|
||||
#uploadButton:hover {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
.note {
|
||||
padding:5px;
|
||||
position:relative;
|
||||
width:calc( 100% - 60px );
|
||||
left:25px;
|
||||
border:1px solid #AAAAAAFF;
|
||||
border-radius: 8px;
|
||||
background-color: #AAAAAA66;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 450px) {
|
||||
#content {
|
||||
position:fixed;
|
||||
left:0%;
|
||||
top:0%;
|
||||
transform:translate(0%,0%);
|
||||
background-color:white;
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<input type="text" id="CopyTB" value="" readonly style="opacity:0;width:10px;height:0%;">
|
||||
<div id="content">
|
||||
<h1>
|
||||
monofile<span style="font-style:italic;font-weight:bold;font-size:16px;color:#999999"> $Version</span>
|
||||
</h1>
|
||||
<h2><em>Discord-based file sharing</em></h2>
|
||||
<div class="note" style="border-color:#FFAAAAFF;background-color:#FFAAAA66">
|
||||
Before sharing files, please remember:
|
||||
<ul>
|
||||
<li>Do NOT share sensitive information via monofile</li>
|
||||
<li>Do NOT share illegal content via monofile</li>
|
||||
<li>The owner of this instance reserves the right to remove your files</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style="width:100%;height:25px"></div>
|
||||
<div id="btnContainer"><button id="uploadButton">Input a URL</button></div>
|
||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">
|
||||
Max filesize on instance: $MaxInstanceFilesize
|
||||
</p>
|
||||
<p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;font-size:12px;color:gray;">made by nbitzz — <a style="color:gray;font-family:monospace;font-size:12px;" href="https://github.com/nbitzz/monofile">github</a> — <a style="color:gray;font-family:monospace;font-size:12px;" href="/">upload a file...</a></p>
|
||||
<div style="width:100%;height:25px"></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
let updateBtnTxt = (btntxt) => {document.getElementById("btnContainer").innerHTML = `<div class="note" style="width:calc( 100% - 10px );height:calc( 100% - 10px );position:absolute;left:0px;top:0px;"><p style="font-family:monospace;position:relative;width:calc( 100% - 50px );left:25px;text-align: center;">${btntxt}</p></div>`}
|
||||
|
||||
document.getElementById("uploadButton").addEventListener("click",() => {
|
||||
let ask = prompt("Input a URL to clone.")
|
||||
|
||||
if (ask) {
|
||||
updateBtnTxt("Requesting clone. Please wait.")
|
||||
|
||||
let xmlhttp = new XMLHttpRequest()
|
||||
|
||||
xmlhttp.addEventListener("error",function(e) {
|
||||
updateBtnTxt(`Upload failed.<br/>${e.toString()}`)
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
xmlhttp.addEventListener("load",function() {
|
||||
if (xmlhttp.status == 200) {
|
||||
document.getElementById("CopyTB").value = `https://${location.hostname}/download/${xmlhttp.responseText}`
|
||||
updateBtnTxt(`Upload complete.<br/><a style="color:blue;font-family:monospace;" href="javascript:document.getElementById('CopyTB').focus();document.getElementById('CopyTB').select();document.execCommand('copy');document.getElementById('CopyTB').blur();">Copy URL</a> <a style="color:blue;font-family:monospace;" href="javascript:prompt('This is your download URL.', document.getElementById('CopyTB').value);null">View URL</a>`)
|
||||
} else {
|
||||
updateBtnTxt(`Upload failed.<br/>${xmlhttp.responseText}`)
|
||||
}
|
||||
})
|
||||
|
||||
xmlhttp.open("POST","/clone")
|
||||
xmlhttp.send(ask)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
</html>
|
57
src/index.ts
57
src/index.ts
|
@ -1,3 +1,7 @@
|
|||
/*
|
||||
i really should split this up into different modules
|
||||
*/
|
||||
|
||||
import bodyParser from "body-parser"
|
||||
import multer, {memoryStorage} from "multer"
|
||||
import Discord, { IntentsBitField, Client } from "discord.js"
|
||||
|
@ -55,9 +59,11 @@ let uploadFile = (settings:FileUploadSettings,fBuffer:Buffer) => {
|
|||
return new Promise<string>(async (resolve,reject) => {
|
||||
if (!settings.name || !settings.mime) {reject({status:400,message:"missing name/mime"});return}
|
||||
|
||||
let uploadId = settings.uploadId || Math.random().toString().slice(2)
|
||||
let uploadId = (settings.uploadId || Math.random().toString().slice(2)).toString();
|
||||
|
||||
if (files[uploadId]) {reject({status:500,message:"please try again"});return}
|
||||
if ((uploadId.match(/[A-Za-z0-9_\-]+/)||[])[0] != uploadId || uploadId.length > 30) {reject({status:400,message:"invalid id"});return}
|
||||
|
||||
if (files[uploadId]) {reject({status:400,message:"a file with this id already exists"});return}
|
||||
if (settings.name.length > 128) {reject({status:400,message:"name too long"}); return}
|
||||
if (settings.name.length > 128) {reject({status:400,message:"mime too long"}); return}
|
||||
|
||||
|
@ -104,24 +110,45 @@ let uploadFile = (settings:FileUploadSettings,fBuffer:Buffer) => {
|
|||
}
|
||||
|
||||
app.get("/", function(req,res) {
|
||||
fs.readFile(__dirname+"/../pages/upload.html",(err,buf) => {
|
||||
fs.readFile(__dirname+"/../pages/base.html",(err,buf) => {
|
||||
if (err) {res.sendStatus(500);console.log(err);return}
|
||||
res.send(buf.toString().replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`).replace(/\$Version/g,pkg.version))
|
||||
res.send(
|
||||
buf.toString()
|
||||
.replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`)
|
||||
.replace(/\$Version/g,pkg.version)
|
||||
.replace(/\$Handler/g,"upload_file")
|
||||
.replace(/\$UploadButtonText/g,"Upload file")
|
||||
.replace(/\$otherPath/g,"/clone")
|
||||
.replace(/\$otherText/g,"clone from url...")
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
app.get("/clone", function(req,res) {
|
||||
fs.readFile(__dirname+"/../pages/clone.html",(err,buf) => {
|
||||
fs.readFile(__dirname+"/../pages/base.html",(err,buf) => {
|
||||
if (err) {res.sendStatus(500);console.log(err);return}
|
||||
res.send(buf.toString().replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`).replace(/\$Version/g,pkg.version))
|
||||
res.send(
|
||||
buf.toString()
|
||||
.replace("$MaxInstanceFilesize",`${(config.maxDiscordFileSize*config.maxDiscordFiles)/1048576}MB`)
|
||||
.replace(/\$Version/g,pkg.version)
|
||||
.replace(/\$Handler/g,"clone_file")
|
||||
.replace(/\$UploadButtonText/g,"Input a URL")
|
||||
.replace(/\$otherPath/g,"/")
|
||||
.replace(/\$otherText/g,"upload file...")
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
app.post("/upload",multerSetup.single('file'),async (req,res) => {
|
||||
if (req.file) {
|
||||
uploadFile({name:req.file.originalname,mime:req.file.mimetype},req.file.buffer)
|
||||
try {
|
||||
uploadFile({name:req.file.originalname,mime:req.file.mimetype,uploadId:req.header("monofile-upload-id")},req.file.buffer)
|
||||
.then((uID) => res.send(uID))
|
||||
.catch((stat) => {res.status(stat.status);res.send(`[err] ${stat.message}`)})
|
||||
} catch {
|
||||
res.status(400)
|
||||
res.send("[err] bad request")
|
||||
}
|
||||
} else {
|
||||
res.status(400)
|
||||
res.send("[err] bad request")
|
||||
|
@ -129,14 +156,24 @@ app.post("/upload",multerSetup.single('file'),async (req,res) => {
|
|||
})
|
||||
|
||||
app.post("/clone",(req,res) => {
|
||||
axios.get(req.body,{responseType:"arraybuffer"}).then((data:AxiosResponse) => {
|
||||
uploadFile({name:req.body.split("/")[req.body.split("/").length-1] || "generic",mime:data.headers["content-type"]},Buffer.from(data.data))
|
||||
try {
|
||||
let j = JSON.parse(req.body)
|
||||
if (!j.url) {
|
||||
res.status(400)
|
||||
res.send("[err] invalid url")
|
||||
}
|
||||
axios.get(j.url,{responseType:"arraybuffer"}).then((data:AxiosResponse) => {
|
||||
uploadFile({name:req.body.split("/")[req.body.split("/").length-1] || "generic",mime:data.headers["content-type"],uploadId:j.uploadId},Buffer.from(data.data))
|
||||
.then((uID) => res.send(uID))
|
||||
.catch((stat) => {res.status(stat.status);res.send(`[err] ${stat.message}`)})
|
||||
}).catch((err) => {
|
||||
res.status(400)
|
||||
res.send(`[err] failed to fetch data`)
|
||||
})
|
||||
} catch {
|
||||
res.status(500)
|
||||
res.send("[err] an error occured")
|
||||
}
|
||||
})
|
||||
|
||||
app.get("/download/:fileId",(req,res) => {
|
||||
|
@ -192,8 +229,6 @@ app.get("*",(req,res) => {
|
|||
ThrowError(res,404,"Page not found.")
|
||||
})
|
||||
|
||||
|
||||
|
||||
client.on("ready",() => {
|
||||
console.log("Discord OK!")
|
||||
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
hi, this is a port of nbitzz/theUnfunny@fb57d8d65f
|
||||
so the code is pretty bad
|
||||
(but let's be real, all of my code is bad lmao)
|
||||
*/
|
||||
|
||||
import { Client, SlashCommandBuilder, Routes, ChatInputCommandInteraction } from "discord.js";
|
||||
|
||||
export class SlashCommand {
|
||||
readonly builder: SlashCommandBuilder|Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">|Omit<SlashCommandBuilder, "addBooleanOption" | "addUserOption" | "addChannelOption" | "addRoleOption" | "addAttachmentOption" | "addMentionableOption" | "addStringOption" | "addIntegerOption" | "addNumberOption">
|
||||
readonly assetPath: string
|
||||
readonly type:string = "SCM.SlashCommand"
|
||||
action?: (interaction:ChatInputCommandInteraction) => Promise<any>
|
||||
|
||||
ephmeralReply?:boolean
|
||||
allowInDMs?:boolean
|
||||
|
||||
constructor(command:SlashCommandBuilder|Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">|Omit<SlashCommandBuilder, "addBooleanOption" | "addUserOption" | "addChannelOption" | "addRoleOption" | "addAttachmentOption" | "addMentionableOption" | "addStringOption" | "addIntegerOption" | "addNumberOption">) {
|
||||
this.builder = command
|
||||
this.assetPath = `${process.cwd()}/assets/commands/${command.name}/`
|
||||
}
|
||||
}
|
||||
|
||||
export class SlashCommandManager {
|
||||
private commands:SlashCommand[] = []
|
||||
private readonly client: Client
|
||||
readonly type:string = "SCM.SlashCommandManager"
|
||||
|
||||
constructor(client: Client) {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Register slash commands
|
||||
*/
|
||||
register() {
|
||||
return new Promise(async (resolve,reject) => {
|
||||
console.log("[SlashCommandManager] Registering commands...")
|
||||
|
||||
if (this.client.user) {
|
||||
this.commands.forEach((e) => {
|
||||
e.builder.setDMPermission(e.allowInDMs)
|
||||
})
|
||||
|
||||
let result = await this.client.rest.put(
|
||||
Routes.applicationCommands(this.client.user.id),
|
||||
{ body: this.commands.map(e => e.builder.toJSON()) }
|
||||
)
|
||||
|
||||
console.log(`[SlashCommandManager] Slash commands registered.`)
|
||||
resolve(result)
|
||||
} else {
|
||||
console.error("[SlashCommandManager] Not logged in")
|
||||
reject("Not logged in")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Process a command
|
||||
*/
|
||||
|
||||
call(int:ChatInputCommandInteraction) {
|
||||
let command = this.commands.find(e => e.builder.name == int.commandName)
|
||||
if (command && command.action) {
|
||||
int.deferReply({
|
||||
ephemeral:command.ephmeralReply
|
||||
}).then(() => {
|
||||
if (command && command.action) {
|
||||
command.action(int).catch((err) => {
|
||||
// error handling
|
||||
int.editReply({
|
||||
embeds:[
|
||||
{description:"Oops, something broke. Maybe try that again?",color:0xff0000}
|
||||
]
|
||||
})
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Add a slash command to the manager
|
||||
*/
|
||||
add(command:SlashCommand) {
|
||||
this.commands.push(command)
|
||||
}
|
||||
}
|
||||
|
||||
// type guard
|
||||
|
||||
export let isSlashCommand = (sc: any): sc is SlashCommand => {return sc&&sc.type=="SCM.SlashCommand"}
|
Loading…
Reference in a new issue