This repository has been archived on 2025-09-03. You can view files and clone it, but cannot push or open issues or pull requests.
iceys-server-modpack-manager/main.js

293 lines
7.9 KiB
JavaScript

const express=require('express'),
app = express(),
fs=require('fs'),
path=require('path'),
JSZip = require('jszip'),
webdir=path.join(process.cwd(),"src","web"),
readline = require('readline'),
consoleinput = readline.createInterface({
input: process.stdin,
output: process.stdout
});
////////
//time format function because it just has to be complicated
function changeTimezone(date, ianatz) {
// suppose the date is 12:00 UTC
let invdate = new Date(date.toLocaleString('en-US', {
timeZone: ianatz
}));
// then invdate will be 07:00 in Toronto
// and the diff is 5 hours
let diff = date.getTime() - invdate.getTime();
// so 12:00 in Toronto is 17:00 UTC
return new Date(date.getTime() - diff); // needs to substract
}
//get config
if(fs.existsSync(path.join(process.cwd(),"src","config.json"))){
config=JSON.parse(fs.readFileSync(path.join(process.cwd(),"src","config.json")))
} else {
console.log("ERROR: config does not exist!");
process.exit()
}
function server_to_client_sync(modpack){
let mod_list={client_mods:[],server_mods:[],diff:{add:[],remove:[]}}
mod_list.server_mods=fs.readdirSync(path.join(modpack.server_folder,"mods"))
mod_list.client_mods=fs.readdirSync(path.join(modpack.client_folder,"mods"))
mod_list.server_mods.forEach(mods=>{
let match=false
mod_list.client_mods.forEach(cmods=>{
if(mods==cmods){
match=true
}
})
modpack.server_ignore_filter.forEach(igmods=>{
if(mods==igmods){
match=true
}
})
if(match==false){
mod_list.diff.add.push(mods)
}
})
mod_list.client_mods.forEach(mods=>{
let match=false
mod_list.server_mods.forEach(cmods=>{
if(mods==cmods){
match=true
}
})
modpack.client_ignore_filter.forEach(igmods=>{
if(mods==igmods){
match=true
}
})
if(match==false){
mod_list.diff.remove.push(mods)
}
})
console.log(mod_list.diff);
mod_list.diff.remove.forEach(remove_mods=>{
fs.unlink(path.join(modpack.client_folder,"mods",remove_mods),(err)=>{console.log(err);})
})
mod_list.diff.add.forEach(add_mods=>{
fs.copyFileSync(path.join(modpack.server_folder,"mods",add_mods),path.join(modpack.client_folder,"mods",add_mods))
})
mod_list={}
}
//does both client and server folder exist on same machine? and is said modpack active? sync it!
config.modpacks.forEach(modpacks=>{
if(modpacks.active==true&&modpacks.server_folder&&modpacks.client_folder){
server_to_client_sync(modpacks)
}
})
//zip de file
config.modpacks.forEach(modpacks=>{
if(modpacks.active==true&&modpacks.compile_zip==true){
try {
let zip = new JSZip();
let zip_path=path.join("src","zip_managed",modpacks.name+".zip")
if(fs.existsSync(zip_path)){
fs.unlinkSync(zip_path)
}
if(fs.existsSync(path.join("src","web","modpacks",modpacks.name+".zip"))&&modpacks.move_zip_to_server==true){
fs.unlinkSync(path.join("src","web","modpacks",modpacks.name+".zip"))
}
let mod_com_list=fs.readdirSync(path.join(modpacks.zip_folder,"mods"))
mod_com_list.forEach(mod_name=>{
let ignore_file=false
modpacks.zip_ignore_filter.forEach(igmods=>{
if(mod_name==igmods){
ignore_file=true
}
})
if(ignore_file==false){
const pdfData = fs.readFileSync(path.join(modpacks.zip_folder,"mods",mod_name));
zip.file(mod_name, pdfData);
}
})
zip.generateNodeStream({ type: 'nodebuffer', streamFiles: true })
.pipe(fs.createWriteStream(zip_path))
.on('finish', function () {
console.log(modpacks.name+".zip written.");
move_file_to_web(modpacks)
});
} catch (err) {
console.error(err)
}
}
});
//move to web
function move_file_to_web(modpacks){
if(modpacks.move_zip_to_server==true){
console.log(modpacks.name+".zip moved to server folder");
fs.renameSync(path.join("src","zip_managed",modpacks.name+".zip"),path.join("src","web","modpacks",modpacks.name+".zip"))
}
}
//run webserver
if(config.use_webserver==true){
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.text());
app.use(function(req,res,next){
server_log = function server_log(str){
let newDate=changeTimezone(new Date(),"US/Central");
let date={
day:(newDate.getMonth()+1)+" "+newDate.getDate()+" "+newDate.getFullYear(),
time:newDate.getHours()+":"+newDate.getMinutes()+":"+newDate.getSeconds()
}
let logfile=path.resolve("src","logs",date.day+".txt")
let content="--"+date.time+": "+"hostname: "+req.socket.remoteAddress+" url: "+req.url+"\n"+str+"\n"
console.log(content)
fs.writeFile(logfile,content,{flag:'a+'},err=>{if(err){server_log(err)}})
}
next();
})
app.use(function(req,res,next){
req.checkdir = function checkdir(des_dir,curr_dir){
let isdir=path.resolve(webdir,curr_dir.replace(/^\//g,"")).includes(path.join(webdir,des_dir))
if(isdir==false){
server_log("out of dir at: "+curr_dir)
res.send("access denied")
}
return isdir
}
next();
});
app.get("/modpacks/*",function(req,res){
req.url=req.url.replace(/%20/g," ");
if(req.checkdir("modpacks",req.url)==true){
res.sendFile(path.join(webdir,req.url))
}
});
app.get("/modpacklist",function(req,res){
res.send(fs.readdirSync(path.join(webdir,"modpacks")))
})
if(config.enable_client_server_sync==true){
app.post("/clientS_comparemods",function(req,res){
let modpack_exist=false
config.modpacks.forEach(modpacks=>{
if(modpacks.name==req.body.modpack){
modpack_exist=true
}
})
if(modpack_exist==true){
config.modpacks.forEach(modpacks=>{
if(modpacks.name==req.body.modpack){
if(modpacks.active==true&&modpacks.use_client_sync==true){
let mod_list={client_mods:[],server_mods:[],diff:{add:[],remove:[]}}
mod_list.server_mods=fs.readdirSync(path.join(modpacks.client_sync_folder,"mods"))
mod_list.client_mods=req.body.mods
mod_list.server_mods.forEach(mods=>{
let match=false
mod_list.client_mods.forEach(cmods=>{
if(mods==cmods){
match=true
}
})
modpacks.client_sync_ignore_filter.forEach(igmods=>{
if(mods==igmods){
match=true
}
})
if(match==false){
mod_list.diff.add.push(mods)
}
})
mod_list.client_mods.forEach(mods=>{
let match=false
mod_list.server_mods.forEach(cmods=>{
if(mods==cmods){
match=true
modpacks.client_sync_ignore_filter.forEach(igmods=>{
if(mods==igmods){
match=false
}
})
}
})
if(match==false){
mod_list.diff.remove.push(mods)
}
})
res.send(JSON.stringify(mod_list.diff))
} else {
res.send(JSON.stringify({error:"modpack does not exist"}))
}
}
})
} else {
res.send(JSON.stringify({error:"modpack does not exist"}))
}
})
app.post("/clientS_getmods",function(req,res){
let modpack_exist=false
config.modpacks.forEach(modpacks=>{
if(modpacks.name==req.body.modpack){
modpack_exist=true
}
})
if(modpack_exist==true){
config.modpacks.forEach(modpacks=>{
if(modpacks.name==req.body.modpack){
if(modpacks.active==true&&modpacks.use_client_sync==true){
res.sendFile(path.join(modpacks.client_sync_folder,"mods",req.body.mod))
} else {
res.send(JSON.stringify({error:"modpack does not exist"}))
}
}
});
}
});
} else {
app.post("/clientS_comparemods",function(req,res){
res.send(JSON.stringify({error:"sync is not enabled"}))
});
app.post("/clientS_getmods",function(req,res){
res.send(JSON.stringify({error:"sync is not enabled"}))
});
}
app.get("/*",function(req,res){
res.sendFile(path.join(process.cwd(),"src","web","index.html"))
})
let port=config.server_port
app.listen(port,'0.0.0.0', () => {
console.log(`Example app listening at http://localhost:${port}`)
});
}