feat:大部分功能完成
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import websocket from "ws";
|
import websocket, { WebSocketServer } from "ws";
|
||||||
import { yauzl_promise } from "./utils/yauzl.promise.js";
|
import { yauzl_promise } from "./utils/yauzl.promise.js";
|
||||||
import { pipeline } from "node:stream/promises";
|
import { pipeline } from "node:stream/promises";
|
||||||
import { platform, what_platform } from "./platform/index.js";
|
import { platform, what_platform } from "./platform/index.js";
|
||||||
|
import { DeEarth } from "./utils/DeEarth.js";
|
||||||
|
import { mlsetup } from "./modloader/index.js";
|
||||||
|
import { console } from "node:inspector";
|
||||||
|
|
||||||
interface Iinfo{
|
interface Iinfo{
|
||||||
name:string
|
name:string
|
||||||
@@ -10,23 +13,45 @@ interface Iinfo{
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Dex {
|
export class Dex {
|
||||||
ws: websocket;
|
wsx!: WebSocketServer;
|
||||||
in: any;
|
in: any;
|
||||||
constructor(ws: websocket) {
|
ws!: websocket;
|
||||||
this.ws = ws;
|
constructor(ws: WebSocketServer) {
|
||||||
|
this.wsx = ws;
|
||||||
|
this.wsx.on('connection',(e)=>{
|
||||||
|
this.ws = e
|
||||||
|
})
|
||||||
this.in = {}
|
this.in = {}
|
||||||
|
console.log(this.ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Main(buffer: Buffer) {
|
public async Main(buffer: Buffer) {
|
||||||
|
const first = new Date().getTime()
|
||||||
const info = await this._getinfo(buffer)
|
const info = await this._getinfo(buffer)
|
||||||
const plat = what_platform(info)
|
const plat = what_platform(info)
|
||||||
const mpname = this.in.name
|
const mpname = this.in.name
|
||||||
|
const unpath = `./instance/${mpname}`
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this._unzip(buffer,mpname),
|
this._unzip(buffer,mpname),
|
||||||
platform(plat).downloadfile(this.in,`./instance/${mpname}`)
|
await platform(plat).downloadfile(this.in,unpath,this.ws)
|
||||||
])
|
]) // 解压和下载
|
||||||
this.ws.send(JSON.stringify({ status: "changed", result: undefined })); //改变状态
|
this.ws.send(JSON.stringify({
|
||||||
|
status: "changed",
|
||||||
|
result: undefined
|
||||||
|
})); //改变状态
|
||||||
|
await new DeEarth(`${unpath}/mods`,`./.rubbish/${mpname}`).Main()
|
||||||
|
this.ws.send(JSON.stringify({
|
||||||
|
status: "changed",
|
||||||
|
result: undefined
|
||||||
|
})); //改变状态(DeEarth筛选模组完毕)
|
||||||
|
const mlinfo = await platform(plat).getinfo(this.in)
|
||||||
|
await mlsetup(mlinfo.loader,mlinfo.minecraft,mlinfo.loader_version,unpath) //安装服务端
|
||||||
|
const latest = new Date().getTime()
|
||||||
|
console.log(latest - first)
|
||||||
|
this.ws.send(JSON.stringify({
|
||||||
|
status: "finish",
|
||||||
|
result: latest - first
|
||||||
|
}))
|
||||||
//await this._unzip(buffer);
|
//await this._unzip(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,9 +59,12 @@ export class Dex {
|
|||||||
const important_name = ["manifest.json","modrinth.index.json"]
|
const important_name = ["manifest.json","modrinth.index.json"]
|
||||||
let contain:string = ""
|
let contain:string = ""
|
||||||
const zip = await yauzl_promise(buffer);
|
const zip = await yauzl_promise(buffer);
|
||||||
zip.filter(e=>important_name.includes(e.fileName)).forEach(async e=>{
|
zip.forEach(async e=>{
|
||||||
this.in = JSON.parse((await e.ReadEntry).toString())
|
if (important_name.includes(e.fileName)){
|
||||||
contain = e.fileName
|
contain = e.fileName
|
||||||
|
this.in = JSON.parse((e.ReadEntrySync).toString())
|
||||||
|
return;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
return contain;
|
return contain;
|
||||||
}
|
}
|
||||||
@@ -44,7 +72,7 @@ export class Dex {
|
|||||||
private async _unzip(buffer: Buffer,instancename:string) {
|
private async _unzip(buffer: Buffer,instancename:string) {
|
||||||
/* 解压Zip */
|
/* 解压Zip */
|
||||||
const zip = await yauzl_promise(buffer);
|
const zip = await yauzl_promise(buffer);
|
||||||
let index = 0;
|
let index = 1;
|
||||||
for await (const entry of zip) {
|
for await (const entry of zip) {
|
||||||
const ew = entry.fileName.endsWith("/");
|
const ew = entry.fileName.endsWith("/");
|
||||||
if (ew) {
|
if (ew) {
|
||||||
@@ -56,10 +84,10 @@ export class Dex {
|
|||||||
const dirPath = `./instance/${instancename}/${entry.fileName.substring(
|
const dirPath = `./instance/${instancename}/${entry.fileName.substring(
|
||||||
0,
|
0,
|
||||||
entry.fileName.lastIndexOf("/")
|
entry.fileName.lastIndexOf("/")
|
||||||
)}`;
|
).replace("overrides/","")}`;
|
||||||
await fs.promises.mkdir(dirPath, { recursive: true });
|
await fs.promises.mkdir(dirPath, { recursive: true });
|
||||||
const stream = await entry.openReadStream;
|
const stream = await entry.openReadStream;
|
||||||
const write = fs.createWriteStream(`./instance/${instancename}/${entry.fileName}`);
|
const write = fs.createWriteStream(`./instance/${instancename}/${entry.fileName.replace("overrides/","")}`);
|
||||||
await pipeline(stream, write);
|
await pipeline(stream, write);
|
||||||
}
|
}
|
||||||
this.ws.send(JSON.stringify({ status: "unzip", result: { name: entry.fileName,total: zip.length, current:index } }));
|
this.ws.send(JSON.stringify({ status: "unzip", result: { name: entry.fileName,total: zip.length, current:index } }));
|
||||||
|
|||||||
@@ -7,25 +7,27 @@ import fs from "node:fs"
|
|||||||
import { pipeline } from "node:stream/promises";
|
import { pipeline } from "node:stream/promises";
|
||||||
import { Config, IConfig } from "./utils/config.js";
|
import { Config, IConfig } from "./utils/config.js";
|
||||||
import { yauzl_promise } from "./utils/yauzl.promise.js";
|
import { yauzl_promise } from "./utils/yauzl.promise.js";
|
||||||
|
import { Dex } from "./Dex.js";
|
||||||
|
import { mlsetup } from "./modloader/index.js";
|
||||||
export class Core {
|
export class Core {
|
||||||
private config: IConfig;
|
private config: IConfig;
|
||||||
private readonly app: Application;
|
private readonly app: Application;
|
||||||
private readonly server: Server;
|
private readonly server: Server;
|
||||||
public ws!: websocket;
|
public ws!: WebSocketServer;
|
||||||
|
private wsx!: websocket;
|
||||||
private readonly upload: multer.Multer;
|
private readonly upload: multer.Multer;
|
||||||
private task: {} = {};
|
private task: {} = {};
|
||||||
|
dex: Dex;
|
||||||
constructor(config: IConfig) {
|
constructor(config: IConfig) {
|
||||||
this.config = config
|
this.config = config
|
||||||
this.app = express();
|
this.app = express();
|
||||||
this.upload = multer()
|
|
||||||
this.server = createServer(this.app);
|
this.server = createServer(this.app);
|
||||||
new WebSocketServer({ server: this.server }).on("connection", (ws) => {
|
this.upload = multer()
|
||||||
this.ws = ws;
|
this.ws = new WebSocketServer({ server: this.server })
|
||||||
|
this.ws.on("connection",(e)=>{
|
||||||
|
this.wsx = e
|
||||||
})
|
})
|
||||||
}
|
this.dex = new Dex(this.ws)
|
||||||
|
|
||||||
async DeEarthX(buffer:Buffer){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
express() {
|
express() {
|
||||||
@@ -35,7 +37,8 @@ export class Core {
|
|||||||
if (!req.file) {
|
if (!req.file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.DeEarthX(req.file.buffer)
|
this.dex.Main(req.file.buffer) //Dex
|
||||||
|
//this.dex.Main(req.file.buffer)
|
||||||
res.json({
|
res.json({
|
||||||
status:200,
|
status:200,
|
||||||
message:"task is peding"
|
message:"task is peding"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { version_compare } from "./utils/utils.js";
|
|||||||
import { Forge } from "./modloader/forge.js";
|
import { Forge } from "./modloader/forge.js";
|
||||||
import { Minecraft } from "./modloader/minecraft.js";
|
import { Minecraft } from "./modloader/minecraft.js";
|
||||||
import { Fabric } from "./modloader/fabric.js";
|
import { Fabric } from "./modloader/fabric.js";
|
||||||
|
import { NeoForge } from "./modloader/neoforge.js";
|
||||||
|
|
||||||
const core = new Core(config);
|
const core = new Core(config);
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ core.start();
|
|||||||
|
|
||||||
// }
|
// }
|
||||||
//new Forge("1.20.1","47.3.10").setup()
|
//new Forge("1.20.1","47.3.10").setup()
|
||||||
|
//await new NeoForge("1.21.1","21.1.1").setup()
|
||||||
//await new Minecraft("forge","1.20.1","0").setup()
|
//await new Minecraft("forge","1.20.1","0").setup()
|
||||||
// await new Minecraft("forge","1.16.5","0").setup()
|
// await new Minecraft("forge","1.16.5","0").setup()
|
||||||
await new Fabric("1.20.1","0.17.2").setup()
|
//await new Fabric("1.20.1","0.17.2").setup()
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import got, { Got } from "got";
|
import got, { Got } from "got";
|
||||||
import { fastdownload, xfastdownload } from "../utils/utils.js";
|
import fs from "node:fs"
|
||||||
|
import { execPromise, fastdownload, xfastdownload } from "../utils/utils.js";
|
||||||
|
|
||||||
interface ILatestLoader{
|
interface ILatestLoader{
|
||||||
url:string,
|
url:string,
|
||||||
@@ -16,9 +17,11 @@ export class Fabric{
|
|||||||
minecraft: string;
|
minecraft: string;
|
||||||
loaderVersion: string;
|
loaderVersion: string;
|
||||||
got:Got
|
got:Got
|
||||||
constructor(minecraft:string,loaderVersion:string) {
|
path: string;
|
||||||
|
constructor(minecraft:string,loaderVersion:string,path:string) {
|
||||||
this.minecraft = minecraft;
|
this.minecraft = minecraft;
|
||||||
this.loaderVersion = loaderVersion;
|
this.loaderVersion = loaderVersion;
|
||||||
|
this.path = path
|
||||||
this.got = got.extend({
|
this.got = got.extend({
|
||||||
prefixUrl:"https://bmclapi2.bangbang93.com/",
|
prefixUrl:"https://bmclapi2.bangbang93.com/",
|
||||||
headers:{
|
headers:{
|
||||||
@@ -27,8 +30,23 @@ export class Fabric{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup(){
|
async setup():Promise<void>{
|
||||||
|
await this.getLaestLoader()
|
||||||
await this.libraries()
|
await this.libraries()
|
||||||
|
await this.install()
|
||||||
|
await this.wshell()
|
||||||
|
}
|
||||||
|
|
||||||
|
async install(){
|
||||||
|
await execPromise(`java -jar fabric-installer.jar server -dir . -mcversion ${this.minecraft} -loader ${this.loaderVersion}`,{
|
||||||
|
cwd:this.path
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private async wshell(){
|
||||||
|
const cmd = `java -jar fabric-server-launch.jar`
|
||||||
|
await fs.promises.writeFile(`${this.path}/run.bat`,`@echo off\n${cmd}`) //Windows
|
||||||
|
await fs.promises.writeFile(`${this.path}/run.sh`,`#!/bin/bash\n${cmd}`) //Linux
|
||||||
}
|
}
|
||||||
|
|
||||||
async libraries(){
|
async libraries(){
|
||||||
@@ -36,7 +54,7 @@ export class Fabric{
|
|||||||
const _downlist: [string,string][]= []
|
const _downlist: [string,string][]= []
|
||||||
res.libraries.forEach(e=>{
|
res.libraries.forEach(e=>{
|
||||||
const path = this.MTP(e.name)
|
const path = this.MTP(e.name)
|
||||||
_downlist.push([`https://bmclapi2.bangbang93.com/maven/${path}`,`./fabric/libraries/${path}`])
|
_downlist.push([`https://bmclapi2.bangbang93.com/maven/${path}`,`${this.path}/libraries/${path}`])
|
||||||
})
|
})
|
||||||
await xfastdownload(_downlist)
|
await xfastdownload(_downlist)
|
||||||
}
|
}
|
||||||
@@ -46,11 +64,12 @@ export class Fabric{
|
|||||||
const res = await this.got.get("fabric-meta/v2/versions/installer").json<ILatestLoader[]>()
|
const res = await this.got.get("fabric-meta/v2/versions/installer").json<ILatestLoader[]>()
|
||||||
res.forEach(e=>{
|
res.forEach(e=>{
|
||||||
if(e.stable){
|
if(e.stable){
|
||||||
downurl = `https://bmclapi2.bangbang93.com/maven/${new URL(e.url).pathname.slice(1)}`
|
//downurl = `https://bmclapi2.bangbang93.com/maven/${new URL(e.url).pathname.slice(1)}`
|
||||||
|
downurl = e.url
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
await fastdownload([downurl,`./fabric/fabric-installer.jar`])
|
await fastdownload([downurl,`${this.path}/fabric-installer.jar`])
|
||||||
}
|
}
|
||||||
|
|
||||||
private MTP(string:string){
|
private MTP(string:string){
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import got, { Got } from "got";
|
import got, { Got } from "got";
|
||||||
import fs from "node:fs"
|
import fs from "node:fs"
|
||||||
import fse from "fs-extra"
|
import fse from "fs-extra"
|
||||||
import { version_compare, xfastdownload } from "../utils/utils.js";
|
import { execPromise, fastdownload, version_compare, xfastdownload } from "../utils/utils.js";
|
||||||
import { yauzl_promise } from "../utils/yauzl.promise.js";
|
import { yauzl_promise } from "../utils/yauzl.promise.js";
|
||||||
|
import { execSync } from "node:child_process";
|
||||||
|
|
||||||
interface Iforge{
|
interface Iforge{
|
||||||
data:{
|
data:{
|
||||||
@@ -27,9 +28,11 @@ export class Forge {
|
|||||||
minecraft: string;
|
minecraft: string;
|
||||||
loaderVersion: string;
|
loaderVersion: string;
|
||||||
got: Got;
|
got: Got;
|
||||||
constructor(minecraft:string,loaderVersion:string){
|
path: string;
|
||||||
|
constructor(minecraft:string,loaderVersion:string,path:string){
|
||||||
this.minecraft = minecraft;
|
this.minecraft = minecraft;
|
||||||
this.loaderVersion = loaderVersion;
|
this.loaderVersion = loaderVersion;
|
||||||
|
this.path = path
|
||||||
this.got = got.extend({
|
this.got = got.extend({
|
||||||
prefixUrl: "https://bmclapi2.bangbang93.com",
|
prefixUrl: "https://bmclapi2.bangbang93.com",
|
||||||
headers: { "User-Agent": "DeEarthX" },
|
headers: { "User-Agent": "DeEarthX" },
|
||||||
@@ -39,6 +42,7 @@ export class Forge {
|
|||||||
async setup(){
|
async setup(){
|
||||||
await this.installer()
|
await this.installer()
|
||||||
await this.library()
|
await this.library()
|
||||||
|
await this.install()
|
||||||
if (version_compare(this.minecraft,"1.18") === -1){
|
if (version_compare(this.minecraft,"1.18") === -1){
|
||||||
await this.wshell()
|
await this.wshell()
|
||||||
}
|
}
|
||||||
@@ -46,13 +50,13 @@ export class Forge {
|
|||||||
|
|
||||||
async library(){
|
async library(){
|
||||||
const _downlist: [string,string][]= []
|
const _downlist: [string,string][]= []
|
||||||
const data = await fs.promises.readFile(`./forge/forge-${this.minecraft}-${this.loaderVersion}-installer.jar`)
|
const data = await fs.promises.readFile(`${this.path}/forge-${this.minecraft}-${this.loaderVersion}-installer.jar`)
|
||||||
const zip = await yauzl_promise(data)
|
const zip = await yauzl_promise(data)
|
||||||
for await(const entry of zip){
|
for await(const entry of zip){
|
||||||
if(entry.fileName === "version.json" || entry.fileName === "install_profile.json"){ //Libraries
|
if(entry.fileName === "version.json" || entry.fileName === "install_profile.json"){ //Libraries
|
||||||
JSON.parse((await entry.ReadEntry).toString()).libraries.forEach(async (e:any)=>{
|
JSON.parse((await entry.ReadEntry).toString()).libraries.forEach(async (e:any)=>{
|
||||||
const t = e.downloads.artifact.path
|
const t = e.downloads.artifact.path
|
||||||
_downlist.push([`https://bmclapi2.bangbang93.com/maven/${t}`,`./forge/libraries/${t}`])
|
_downlist.push([`https://bmclapi2.bangbang93.com/maven/${t}`,`${this.path}/libraries/${t}`])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if(entry.fileName === "install_profile.json"){ //MOJMAPS
|
if(entry.fileName === "install_profile.json"){ //MOJMAPS
|
||||||
@@ -61,13 +65,13 @@ export class Forge {
|
|||||||
const vjson = await this.got.get(`version/${this.minecraft}/json`).json<Iversion>()
|
const vjson = await this.got.get(`version/${this.minecraft}/json`).json<Iversion>()
|
||||||
console.log(`${new URL(vjson.downloads.server_mappings.url).pathname}`)
|
console.log(`${new URL(vjson.downloads.server_mappings.url).pathname}`)
|
||||||
const mojpath = this.MTP(json.data.MOJMAPS.server)
|
const mojpath = this.MTP(json.data.MOJMAPS.server)
|
||||||
_downlist.push([`https://bmclapi2.bangbang93.com/${new URL(vjson.downloads.server_mappings.url).pathname.slice(1)}`,`./forge/libraries/${mojpath}`])
|
_downlist.push([`https://bmclapi2.bangbang93.com/${new URL(vjson.downloads.server_mappings.url).pathname.slice(1)}`,`${this.path}/libraries/${mojpath}`])
|
||||||
/* 获取MOJMAPS */
|
/* 获取MOJMAPS */
|
||||||
|
|
||||||
/*获取MAPPING*/
|
/*获取MAPPING*/
|
||||||
const mappingobj = json.data.MAPPINGS.server
|
const mappingobj = json.data.MAPPINGS.server
|
||||||
const path = this.MTP(mappingobj.replace(":mappings@txt","@zip"))
|
const path = this.MTP(mappingobj.replace(":mappings@txt","@zip"))
|
||||||
_downlist.push([`https://bmclapi2.bangbang93.com/maven/${path}`,`./forge/libraries/${path}`])
|
_downlist.push([`https://bmclapi2.bangbang93.com/maven/${path}`,`${this.path}/libraries/${path}`])
|
||||||
/* 获取MAPPING */
|
/* 获取MAPPING */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,15 +79,19 @@ export class Forge {
|
|||||||
await xfastdownload(downlist)
|
await xfastdownload(downlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async install(){
|
||||||
|
await execPromise(`java -jar forge-${this.minecraft}-${this.loaderVersion}-installer.jar --installServer`,{cwd:this.path})
|
||||||
|
}
|
||||||
|
|
||||||
async installer(){
|
async installer(){
|
||||||
const res = (await this.got.get(`forge/download?mcversion=${this.minecraft}&version=${this.loaderVersion}&category=installer&format=jar`)).rawBody;
|
const res = (await this.got.get(`forge/download?mcversion=${this.minecraft}&version=${this.loaderVersion}&category=installer&format=jar`)).rawBody;
|
||||||
await fse.outputFile(`./forge/forge-${this.minecraft}-${this.loaderVersion}-installer.jar`,res);
|
await fse.outputFile(`${this.path}/forge-${this.minecraft}-${this.loaderVersion}-installer.jar`,res);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async wshell(){
|
private async wshell(){
|
||||||
const cmd = `java -jar forge-${this.minecraft}-${this.loaderVersion}.jar`
|
const cmd = `java -jar forge-${this.minecraft}-${this.loaderVersion}.jar`
|
||||||
await fs.promises.writeFile("./forge/run.bat",`@echo off\n${cmd}`) //Windows
|
await fs.promises.writeFile(`${this.path}/run.bat`,`@echo off\n${cmd}`) //Windows
|
||||||
await fs.promises.writeFile("./forge/run.sh",`#!/bin/bash\n${cmd}`) //Linux
|
await fs.promises.writeFile(`${this.path}/run.sh`,`#!/bin/bash\n${cmd}`) //Linux
|
||||||
}
|
}
|
||||||
|
|
||||||
private MTP(string:string){
|
private MTP(string:string){
|
||||||
|
|||||||
@@ -1,15 +1,36 @@
|
|||||||
|
import { Fabric } from "./fabric.js";
|
||||||
|
import { Forge } from "./forge.js";
|
||||||
|
import { Minecraft } from "./minecraft.js";
|
||||||
|
import { NeoForge } from "./neoforge.js";
|
||||||
|
|
||||||
interface XModloader {
|
interface XModloader {
|
||||||
setup: Promise<void>
|
setup(): Promise<void>
|
||||||
}
|
}
|
||||||
export function modloader(ml:string,mcv:string,mlv:string){
|
export function modloader(ml:string,mcv:string,mlv:string,path:string){
|
||||||
|
let modloader:XModloader
|
||||||
switch (ml) {
|
switch (ml) {
|
||||||
case "fabric":
|
case "fabric":
|
||||||
|
modloader = new Fabric(mcv,mlv,path)
|
||||||
|
break;
|
||||||
|
case "fabric-loader":
|
||||||
|
modloader = new Fabric(mcv,mlv,path)
|
||||||
break;
|
break;
|
||||||
case "forge":
|
case "forge":
|
||||||
|
modloader = new Forge(mcv,mlv,path)
|
||||||
break;
|
break;
|
||||||
case "neoforge":
|
case "neoforge":
|
||||||
|
modloader = new NeoForge(mcv,mlv,path)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
modloader = new Minecraft(ml,mcv,mlv,path)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return modloader
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function mlsetup(ml:string,mcv:string,mlv:string,path:string){
|
||||||
|
const minecraft = new Minecraft(ml,mcv,mlv,path);
|
||||||
|
console.log(ml)
|
||||||
|
await modloader(ml,mcv,mlv,path).setup()
|
||||||
|
await minecraft.setup()
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
import fs from "node:fs"
|
import fs from "node:fs"
|
||||||
|
import pa from "node:path"
|
||||||
import { fastdownload, version_compare } from "../utils/utils.js";
|
import { fastdownload, version_compare } from "../utils/utils.js";
|
||||||
import { yauzl_promise } from "../utils/yauzl.promise.js";
|
import { yauzl_promise } from "../utils/yauzl.promise.js";
|
||||||
import { pipeline } from "node:stream/promises";
|
import { pipeline } from "node:stream/promises";
|
||||||
import got from "got";
|
import got from "got";
|
||||||
|
import fsExtra from "fs-extra/esm";
|
||||||
|
|
||||||
interface ILInfo {
|
interface ILInfo {
|
||||||
libraries: {
|
libraries: {
|
||||||
@@ -18,7 +20,9 @@ export class Minecraft{
|
|||||||
loader: string;
|
loader: string;
|
||||||
minecraft: string;
|
minecraft: string;
|
||||||
loaderVersion: string;
|
loaderVersion: string;
|
||||||
constructor(loader:string,minecraft:string,lv:string){
|
path: string;
|
||||||
|
constructor(loader: string, minecraft: string, lv: string,path:string) {
|
||||||
|
this.path = path
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
this.minecraft = minecraft;
|
this.minecraft = minecraft;
|
||||||
this.loaderVersion = lv;
|
this.loaderVersion = lv;
|
||||||
@@ -29,27 +33,37 @@ export class Minecraft{
|
|||||||
case "forge":
|
case "forge":
|
||||||
await this.forge_setup();
|
await this.forge_setup();
|
||||||
break;
|
break;
|
||||||
|
case "neoforge":
|
||||||
|
await this.forge_setup();
|
||||||
|
break;
|
||||||
|
case "fabric":
|
||||||
|
await this.fabric_setup();
|
||||||
|
break;
|
||||||
|
case "fabric-loader":
|
||||||
|
await this.fabric_setup();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
await this.eula() //生成Eula.txt
|
||||||
}
|
}
|
||||||
|
|
||||||
async forge_setup() {
|
async forge_setup() {
|
||||||
if (version_compare(this.minecraft, "1.18") === 1) {
|
if (version_compare(this.minecraft, "1.18") === 1) {
|
||||||
// 1.18.x + MC依赖解压
|
// 1.18.x + MC依赖解压
|
||||||
const mcpath = `./forge/libraries/net/minecraft/server/${this.minecraft}/server-${this.minecraft}.jar`
|
const mcpath = `${this.path}/libraries/net/minecraft/server/${this.minecraft}/server-${this.minecraft}.jar`
|
||||||
await fastdownload([`https://bmclapi2.bangbang93.com/version/${this.minecraft}/server`, mcpath])
|
await fastdownload([`https://bmclapi2.bangbang93.com/version/${this.minecraft}/server`, mcpath])
|
||||||
const zip = await yauzl_promise(await fs.promises.readFile(mcpath))
|
const zip = await yauzl_promise(await fs.promises.readFile(mcpath))
|
||||||
for await (const entry of zip) {
|
for await (const entry of zip) {
|
||||||
if (entry.fileName.startsWith("META-INF/libraries/") && !entry.fileName.endsWith("/")) {
|
if (entry.fileName.startsWith("META-INF/libraries/") && !entry.fileName.endsWith("/")) {
|
||||||
console.log(entry.fileName)
|
console.log(entry.fileName)
|
||||||
const stream = await entry.openReadStream;
|
const stream = await entry.openReadStream;
|
||||||
const write = fs.createWriteStream(`./forge/libraries/${entry.fileName.replace("META-INF/libraries/","")}`);
|
const write = fs.createWriteStream(`${this.path}/libraries/${entry.fileName.replace("META-INF/libraries/", "")}`);
|
||||||
await pipeline(stream, write);
|
await pipeline(stream, write);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 1.18.x + 依赖解压
|
// 1.18.x + 依赖解压
|
||||||
} else {
|
} else {
|
||||||
//1.18.x - MC依赖下载
|
//1.18.x - MC依赖下载
|
||||||
const lowv = `./forge/minecraft_server.${this.minecraft}.jar`
|
const lowv = `${this.path}/minecraft_server.${this.minecraft}.jar`
|
||||||
const dmc = fastdownload([`https://bmclapi2.bangbang93.com/version/${this.minecraft}/server`, lowv])
|
const dmc = fastdownload([`https://bmclapi2.bangbang93.com/version/${this.minecraft}/server`, lowv])
|
||||||
const download: Promise<void> = new Promise(async (resolve) => {
|
const download: Promise<void> = new Promise(async (resolve) => {
|
||||||
console.log("并行")
|
console.log("并行")
|
||||||
@@ -61,7 +75,7 @@ export class Minecraft{
|
|||||||
.json<ILInfo>()
|
.json<ILInfo>()
|
||||||
json.libraries.forEach(async e => {
|
json.libraries.forEach(async e => {
|
||||||
const path = e.downloads.artifact.path
|
const path = e.downloads.artifact.path
|
||||||
await fastdownload([`https://bmclapi2.bangbang93.com/maven/${path}`,`./forge/libraries/${path}`])
|
await fastdownload([`https://bmclapi2.bangbang93.com/maven/${path}`, `${this.path}/libraries/${path}`])
|
||||||
})
|
})
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
@@ -69,4 +83,38 @@ export class Minecraft{
|
|||||||
//1.18.x - 依赖下载
|
//1.18.x - 依赖下载
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fabric_setup() {
|
||||||
|
const mcpath = `${this.path}/server.jar`
|
||||||
|
await fastdownload([`https://bmclapi2.bangbang93.com/version/${this.minecraft}/server`, mcpath])
|
||||||
|
// 依赖解压
|
||||||
|
const zip = await yauzl_promise(await fs.promises.readFile(mcpath))
|
||||||
|
for await (const entry of zip) {
|
||||||
|
// if (entry.fileName.startsWith("META-INF/libraries/") && entry.fileName.endsWith("/") &&entry.fileName !== "META-INF/libraries/") {
|
||||||
|
// fs.promises.mkdir(`${this.path}/libraries/${entry.fileName.replace("META-INF/libraries/", "")}`,{
|
||||||
|
// recursive:true
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
if (entry.fileName.startsWith("META-INF/libraries/") && !entry.fileName.endsWith("/")) {
|
||||||
|
// const stream = await entry.openReadStream;
|
||||||
|
// fs.promises.mkdir(pa.dirname(`${this.path}/libraries/${entry.fileName.replace("META-INF/libraries/", "")}`),{
|
||||||
|
// recursive:true
|
||||||
|
// })
|
||||||
|
// const write = fs.createWriteStream(`${this.path}/libraries/${entry.fileName.replace("META-INF/libraries/", "")}`);
|
||||||
|
// await pipeline(stream, write);
|
||||||
|
const out = entry.ReadEntrySync
|
||||||
|
await fsExtra.outputFile(`${this.path}/libraries/${entry.fileName.replace("META-INF/libraries/", "")}`,out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 依赖解压
|
||||||
|
}
|
||||||
|
|
||||||
|
async eula(){
|
||||||
|
const context = `
|
||||||
|
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://aka.ms/MinecraftEULA).
|
||||||
|
#Spawn by DeEarthX(QQgroup:559349662) Tianpao:(https://space.bilibili.com/1728953419)
|
||||||
|
eula=true
|
||||||
|
`
|
||||||
|
await fs.promises.writeFile(`${this.path}/eula.txt`,context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
import fse from "fs-extra"
|
import fse from "fs-extra"
|
||||||
import { Forge } from "./forge.js";
|
import { Forge } from "./forge.js";
|
||||||
|
|
||||||
class NeoForge extends Forge{
|
export class NeoForge extends Forge{
|
||||||
constructor(minecraft:string,loaderVersion:string){
|
constructor(minecraft:string,loaderVersion:string,path:string){
|
||||||
super(minecraft,loaderVersion); //子承父业
|
super(minecraft,loaderVersion,path); //子承父业
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup(){
|
async setup(){
|
||||||
await this.installer();
|
await this.installer();
|
||||||
await this.library();
|
await this.library();
|
||||||
|
await this.install();
|
||||||
}
|
}
|
||||||
|
|
||||||
async installer(){
|
async installer(){
|
||||||
const res = (await this.got.get(`neoforge/version/${this.loaderVersion}/download/installer.jar`)).rawBody;
|
const res = (await this.got.get(`neoforge/version/${this.loaderVersion}/download/installer.jar`)).rawBody;
|
||||||
await fse.outputFile(`./forge/forge-${this.minecraft}-${this.loaderVersion}-installer.jar`,res);
|
await fse.outputFile(`${this.path}/forge-${this.minecraft}-${this.loaderVersion}-installer.jar`,res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import got from "got";
|
import got from "got";
|
||||||
|
import { WebSocket } from "ws";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { fastdownload, Utils } from "../utils/utils.js";
|
import { Wfastdownload, Utils } from "../utils/utils.js";
|
||||||
import { modpack_info, XPlatform } from "./index.js";
|
import { modpack_info, XPlatform } from "./index.js";
|
||||||
|
|
||||||
export interface CurseForgeManifest {
|
export interface CurseForgeManifest {
|
||||||
@@ -28,7 +29,7 @@ export class CurseForge implements XPlatform {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadfile(manifest: object, path: string): Promise<void> {
|
async downloadfile(manifest: object, path: string, ws:WebSocket): Promise<void> {
|
||||||
const local_manifest = manifest as CurseForgeManifest;
|
const local_manifest = manifest as CurseForgeManifest;
|
||||||
if (local_manifest.files.length === 0){
|
if (local_manifest.files.length === 0){
|
||||||
return;
|
return;
|
||||||
@@ -70,6 +71,6 @@ export class CurseForge implements XPlatform {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
await fastdownload(tmp as unknown as [string, string]); //下载文件
|
await Wfastdownload(tmp as unknown as [string, string],ws); //下载文件
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { CurseForge } from "./curseforge.js";
|
import { CurseForge } from "./curseforge.js";
|
||||||
import { Modrinth } from "./modrinth.js";
|
import { Modrinth } from "./modrinth.js";
|
||||||
|
import { WebSocket } from "ws";
|
||||||
|
|
||||||
export interface XPlatform {
|
export interface XPlatform {
|
||||||
getinfo(manifest: object): Promise<modpack_info>;
|
getinfo(manifest: object): Promise<modpack_info>;
|
||||||
downloadfile(manifest: object,path:string): Promise<void>;
|
downloadfile(manifest: object,path:string,ws:WebSocket): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface modpack_info {
|
export interface modpack_info {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import { mr_fastdownload, Utils } from "../utils/utils.js";
|
import { WebSocket } from "ws";
|
||||||
|
import { Wfastdownload, Utils } from "../utils/utils.js";
|
||||||
import { modpack_info, XPlatform } from "./index.js";
|
import { modpack_info, XPlatform } from "./index.js";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
|
||||||
@@ -34,22 +35,22 @@ export class Modrinth implements XPlatform {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
async downloadfile(manifest: object,path:string): Promise<void> {
|
async downloadfile(manifest: object,path:string,ws:WebSocket): Promise<void> {
|
||||||
const index = manifest as ModrinthManifest;
|
const index = manifest as ModrinthManifest;
|
||||||
let tmp: [string, string, string][] = []
|
let tmp: [string, string][] = []
|
||||||
index.files.forEach(async (e: { path: string; downloads: string[]; fileSize: number;}) => {
|
index.files.forEach(async (e: { path: string; downloads: string[]; fileSize: number;}) => {
|
||||||
if (e.path.endsWith(".zip")) {
|
if (e.path.endsWith(".zip")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const url = e.downloads[0].replace("https://cdn.modrinth.com",this.utils.modrinth_Durl)
|
const url = e.downloads[0].replace("https://cdn.modrinth.com",this.utils.modrinth_Durl)
|
||||||
const unpath = join(path,e.path)
|
const unpath = join(path,e.path)
|
||||||
tmp.push([e.downloads[0],unpath,String(e.fileSize)])
|
tmp.push([e.downloads[0],unpath])
|
||||||
// if (usemirror){
|
// if (usemirror){
|
||||||
// tmp.push(["https://mod.mcimirror.top"+new URL(e.downloads[0]).pathname,unpath,String(e.fileSize)])
|
// tmp.push(["https://mod.mcimirror.top"+new URL(e.downloads[0]).pathname,unpath,String(e.fileSize)])
|
||||||
// }else{
|
// }else{
|
||||||
// tmp.push([e.downloads[0],unpath,String(e.fileSize)])
|
// tmp.push([e.downloads[0],unpath,String(e.fileSize)])
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
await mr_fastdownload(tmp as unknown as [string, string, string])
|
await Wfastdownload(tmp as unknown as [string, string],ws)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import crypto from "node:crypto"
|
|||||||
import { yauzl_promise } from "./yauzl.promise.js"
|
import { yauzl_promise } from "./yauzl.promise.js"
|
||||||
import got from "got"
|
import got from "got"
|
||||||
import { Utils } from "./utils.js"
|
import { Utils } from "./utils.js"
|
||||||
|
import pa from "node:path"
|
||||||
|
import WebSocket from "ws"
|
||||||
interface IMixins{
|
interface IMixins{
|
||||||
name: string
|
name: string
|
||||||
data: string
|
data: string
|
||||||
@@ -29,9 +31,9 @@ export class DeEarth{
|
|||||||
modspath: string
|
modspath: string
|
||||||
file: IFile[]
|
file: IFile[]
|
||||||
utils: Utils
|
utils: Utils
|
||||||
constructor(modspath:string) {
|
constructor(modspath:string,movepath:string) {
|
||||||
this.utils = new Utils();
|
this.utils = new Utils();
|
||||||
this.movepath = "./.rubbish"
|
this.movepath = movepath
|
||||||
this.modspath = modspath
|
this.modspath = modspath
|
||||||
this.file = []
|
this.file = []
|
||||||
}
|
}
|
||||||
@@ -44,8 +46,10 @@ export class DeEarth{
|
|||||||
const hash = await this.Check_Hashes()
|
const hash = await this.Check_Hashes()
|
||||||
const mixins = await this.Check_Mixins()
|
const mixins = await this.Check_Mixins()
|
||||||
const result = [...new Set(hash.concat(mixins))]
|
const result = [...new Set(hash.concat(mixins))]
|
||||||
|
console.log(result)
|
||||||
result.forEach(async e=>{
|
result.forEach(async e=>{
|
||||||
await fs.promises.rename(`${this.modspath}/${e}`,`${this.movepath}/${e}`)
|
await fs.promises.rename(`${e}`,`${this.movepath}/${e}`.replace(this.modspath,""))
|
||||||
|
//await fs.promises.rename(`${this.modspath}/${e}`,`${this.movepath}/${e}`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import got from "got";
|
|||||||
import pRetry from "p-retry";
|
import pRetry from "p-retry";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import fse from "fs-extra";
|
import fse from "fs-extra";
|
||||||
|
import { WebSocket } from "ws";
|
||||||
|
import { ExecOptions, exec} from "node:child_process";
|
||||||
|
|
||||||
export class Utils {
|
export class Utils {
|
||||||
public modrinth_url: string;
|
public modrinth_url: string;
|
||||||
@@ -47,6 +49,19 @@ export function version_compare(v1: string, v2: string) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function execPromise(cmd:string,options:ExecOptions){
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
exec(cmd,options,(err,stdout,stderr)=>{
|
||||||
|
if(err){
|
||||||
|
reject(err)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}).on('exit',(code)=>{
|
||||||
|
resolve(code)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function fastdownload(data: [string, string]) {
|
export async function fastdownload(data: [string, string]) {
|
||||||
return await pMap(
|
return await pMap(
|
||||||
[data],
|
[data],
|
||||||
@@ -95,6 +110,46 @@ export async function fastdownload(data: [string, string]) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function Wfastdownload(data: [string, string],ws:WebSocket) {
|
||||||
|
let index = 1;
|
||||||
|
return await pMap(
|
||||||
|
data,
|
||||||
|
async (e:any) => {
|
||||||
|
try {
|
||||||
|
await pRetry(
|
||||||
|
async () => {
|
||||||
|
if (!fs.existsSync(e[1])) {
|
||||||
|
await got
|
||||||
|
.get(e[0], {
|
||||||
|
responseType: "buffer",
|
||||||
|
headers: {
|
||||||
|
"user-agent": "DeEarthX",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
fse.outputFileSync(e[1], res.rawBody);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
status:"downloading",
|
||||||
|
result:{
|
||||||
|
total:data.length,
|
||||||
|
index:index,
|
||||||
|
name:e[1]
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
index++
|
||||||
|
},
|
||||||
|
{ retries: 3 }
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
//LOGGER.error({ err: e });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ concurrency: 16 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export async function xfastdownload(data: [string, string][]) {
|
export async function xfastdownload(data: [string, string][]) {
|
||||||
return await pMap(
|
return await pMap(
|
||||||
data,
|
data,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Stream from "node:stream"
|
|||||||
export interface IentryP extends yauzl.Entry {
|
export interface IentryP extends yauzl.Entry {
|
||||||
openReadStream: Promise<Stream.Readable>;
|
openReadStream: Promise<Stream.Readable>;
|
||||||
ReadEntry: Promise<Buffer>;
|
ReadEntry: Promise<Buffer>;
|
||||||
|
ReadEntrySync: Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function yauzl_promise(buffer: Buffer): Promise<IentryP[]>{
|
export async function yauzl_promise(buffer: Buffer): Promise<IentryP[]>{
|
||||||
@@ -27,7 +28,8 @@ export async function yauzl_promise(buffer: Buffer): Promise<IentryP[]>{
|
|||||||
isEncrypted: entry.isEncrypted,
|
isEncrypted: entry.isEncrypted,
|
||||||
isCompressed: entry.isCompressed,
|
isCompressed: entry.isCompressed,
|
||||||
openReadStream: _openReadStream(zip,entry),
|
openReadStream: _openReadStream(zip,entry),
|
||||||
ReadEntry: _ReadEntry(zip,entry)
|
ReadEntry: _ReadEntry(zip,entry),
|
||||||
|
ReadEntrySync: (await _ReadEntry(zip,entry))
|
||||||
}
|
}
|
||||||
entries.push(_entry)
|
entries.push(_entry)
|
||||||
if (zip.entryCount === entries.length){
|
if (zip.entryCount === entries.length){
|
||||||
|
|||||||
10
front/package-lock.json
generated
10
front/package-lock.json
generated
@@ -11,6 +11,7 @@
|
|||||||
"@ant-design/icons-vue": "^7.0.1",
|
"@ant-design/icons-vue": "^7.0.1",
|
||||||
"@tailwindcss/vite": "^4.1.13",
|
"@tailwindcss/vite": "^4.1.13",
|
||||||
"@tauri-apps/api": "^2",
|
"@tauri-apps/api": "^2",
|
||||||
|
"@tauri-apps/plugin-notification": "^2.3.1",
|
||||||
"@tauri-apps/plugin-opener": "^2",
|
"@tauri-apps/plugin-opener": "^2",
|
||||||
"@tauri-apps/plugin-store": "^2.4.0",
|
"@tauri-apps/plugin-store": "^2.4.0",
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
@@ -1376,6 +1377,15 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tauri-apps/plugin-notification": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@tauri-apps/plugin-notification/-/plugin-notification-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-7gqgfANSREKhh35fY1L4j3TUjUdePmU735FYDqRGeIf8nMXWpcx6j4FhN9/4nYz+m0mv79DCTPLqIPTySggGgg==",
|
||||||
|
"license": "MIT OR Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@tauri-apps/api": "^2.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tauri-apps/plugin-opener": {
|
"node_modules/@tauri-apps/plugin-opener": {
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/plugin-opener/-/plugin-opener-2.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@tauri-apps/plugin-opener/-/plugin-opener-2.5.0.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"@ant-design/icons-vue": "^7.0.1",
|
"@ant-design/icons-vue": "^7.0.1",
|
||||||
"@tailwindcss/vite": "^4.1.13",
|
"@tailwindcss/vite": "^4.1.13",
|
||||||
"@tauri-apps/api": "^2",
|
"@tauri-apps/api": "^2",
|
||||||
|
"@tauri-apps/plugin-notification": "^2.3.1",
|
||||||
"@tauri-apps/plugin-opener": "^2",
|
"@tauri-apps/plugin-opener": "^2",
|
||||||
"@tauri-apps/plugin-store": "^2.4.0",
|
"@tauri-apps/plugin-store": "^2.4.0",
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
up to date in 1s
|
added 1 package in 2s
|
||||||
|
|
||||||
16 packages are looking for funding
|
16 packages are looking for funding
|
||||||
run `npm fund` for details
|
run `npm fund` for details
|
||||||
|
|||||||
98
front/src-tauri/Cargo.lock
generated
98
front/src-tauri/Cargo.lock
generated
@@ -702,6 +702,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
|
"tauri-plugin-notification",
|
||||||
"tauri-plugin-opener",
|
"tauri-plugin-opener",
|
||||||
"tauri-plugin-shell",
|
"tauri-plugin-shell",
|
||||||
"tauri-plugin-store",
|
"tauri-plugin-store",
|
||||||
@@ -1964,6 +1965,18 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mac-notification-sys"
|
||||||
|
version = "0.6.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "119c8490084af61b44c9eda9d626475847a186737c0378c85e32d77c33a01cd4"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"objc2 0.6.2",
|
||||||
|
"objc2-foundation 0.3.1",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markup5ever"
|
name = "markup5ever"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
@@ -2113,6 +2126,20 @@ version = "0.1.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "notify-rust"
|
||||||
|
version = "4.11.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6442248665a5aa2514e794af3b39661a8e73033b1cc5e59899e1276117ee4400"
|
||||||
|
dependencies = [
|
||||||
|
"futures-lite",
|
||||||
|
"log",
|
||||||
|
"mac-notification-sys",
|
||||||
|
"serde",
|
||||||
|
"tauri-winrt-notification",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -2677,7 +2704,7 @@ checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"indexmap 2.11.1",
|
"indexmap 2.11.1",
|
||||||
"quick-xml",
|
"quick-xml 0.38.3",
|
||||||
"serde",
|
"serde",
|
||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
@@ -2806,6 +2833,15 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.37.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-xml"
|
name = "quick-xml"
|
||||||
version = "0.38.3"
|
version = "0.38.3"
|
||||||
@@ -2855,6 +2891,16 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||||
|
dependencies = [
|
||||||
|
"rand_chacha 0.9.0",
|
||||||
|
"rand_core 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@@ -2875,6 +2921,16 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@@ -2893,6 +2949,15 @@ dependencies = [
|
|||||||
"getrandom 0.2.16",
|
"getrandom 0.2.16",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_hc"
|
name = "rand_hc"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -3757,6 +3822,25 @@ dependencies = [
|
|||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-notification"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2fbc86b929b5376ab84b25c060f966d146b2fbd59b6af8264027b343c82c219"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"notify-rust",
|
||||||
|
"rand 0.9.2",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"thiserror 2.0.16",
|
||||||
|
"time",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-opener"
|
name = "tauri-plugin-opener"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -3916,6 +4000,18 @@ dependencies = [
|
|||||||
"toml 0.9.5",
|
"toml 0.9.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-winrt-notification"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
|
||||||
|
dependencies = [
|
||||||
|
"quick-xml 0.37.5",
|
||||||
|
"thiserror 2.0.16",
|
||||||
|
"windows",
|
||||||
|
"windows-version",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.22.0"
|
version = "3.22.0"
|
||||||
|
|||||||
@@ -25,4 +25,5 @@ serde_json = "1"
|
|||||||
open = "5.3.2"
|
open = "5.3.2"
|
||||||
tauri-plugin-store = "2"
|
tauri-plugin-store = "2"
|
||||||
tauri-plugin-shell = "2"
|
tauri-plugin-shell = "2"
|
||||||
|
tauri-plugin-notification = "2"
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"args": true
|
"args": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"notification:default"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@ fn open_url(url: &str) {
|
|||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_notification::init())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.plugin(tauri_plugin_store::Builder::new().build())
|
.plugin(tauri_plugin_store::Builder::new().build())
|
||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
|
|||||||
@@ -3,9 +3,14 @@ import { nextTick, ref, VNodeRef } from 'vue';
|
|||||||
import { InboxOutlined } from '@ant-design/icons-vue';
|
import { InboxOutlined } from '@ant-design/icons-vue';
|
||||||
import { message, StepsProps } from 'ant-design-vue';
|
import { message, StepsProps } from 'ant-design-vue';
|
||||||
import type { UploadFile, UploadChangeParam, Upload } from 'ant-design-vue';
|
import type { UploadFile, UploadChangeParam, Upload } from 'ant-design-vue';
|
||||||
|
import {
|
||||||
|
isPermissionGranted,
|
||||||
|
requestPermission,
|
||||||
|
sendNotification,
|
||||||
|
} from '@tauri-apps/plugin-notification';
|
||||||
interface IWSM {
|
interface IWSM {
|
||||||
status: "unzip"|"pending"|"changed",
|
status: "unzip"|"finish"|"changed"|"downloading",
|
||||||
result: string
|
result: any
|
||||||
}
|
}
|
||||||
/* 进度显示区 */
|
/* 进度显示区 */
|
||||||
const disp_steps = ref(true);
|
const disp_steps = ref(true);
|
||||||
@@ -64,30 +69,61 @@ function reactFL() {
|
|||||||
/* 获取文件区 */
|
/* 获取文件区 */
|
||||||
//shell.Command.create('core',['start']).spawn()
|
//shell.Command.create('core',['start']).spawn()
|
||||||
function runDeEarthX(data: Blob) {
|
function runDeEarthX(data: Blob) {
|
||||||
console.log(data)
|
//console.log(data)
|
||||||
const fd = new FormData();
|
const fd = new FormData();
|
||||||
fd.append('file', data);
|
fd.append('file', data);
|
||||||
console.log(fd.getAll('file'))
|
console.log(fd.getAll('file'))
|
||||||
fetch('http://localhost:37019/start',{
|
fetch('http://localhost:37019/start',{
|
||||||
method:'POST',
|
method:'POST',
|
||||||
body:fd
|
body:fd
|
||||||
}).then(async res=>res.json()).then(res=>{
|
}).then(async res=>res.json()).then(()=>{
|
||||||
prews(res)
|
prews()
|
||||||
})
|
})
|
||||||
// shell.Command.create('core',['start',new BigUint64Array(data).toString()]).stdout.on('data',(data)=>{
|
// shell.Command.create('core',['start',new BigUint64Array(data).toString()]).stdout.on('data',(data)=>{
|
||||||
// console.log(data)
|
// console.log(data)
|
||||||
// })
|
// })
|
||||||
reactFL()
|
reactFL()
|
||||||
}
|
}
|
||||||
|
const prog = ref({status:"active",percent:0,display:true})
|
||||||
function prews(res: object){
|
const dprog = ref({status:"active",percent:0,display:true})
|
||||||
|
function prews(){
|
||||||
const ws = new WebSocket('ws://localhost:37019/')
|
const ws = new WebSocket('ws://localhost:37019/')
|
||||||
|
// ws.addEventListener('message',(wsm)=>{
|
||||||
|
// const _data = JSON.parse(wsm.data) as IWSM
|
||||||
|
// if (_data.status === "changed") {
|
||||||
|
// setyps_current.value ++;
|
||||||
|
// }
|
||||||
|
// logs.value.push({message:_data.result})
|
||||||
|
// })
|
||||||
ws.addEventListener('message',(wsm)=>{
|
ws.addEventListener('message',(wsm)=>{
|
||||||
const _data = JSON.parse(wsm.data) as IWSM
|
const _data = JSON.parse(wsm.data) as IWSM
|
||||||
if (_data.status === "changed") {
|
//console.log(_data)
|
||||||
|
if (_data.status === "changed") { //状态更改
|
||||||
setyps_current.value ++;
|
setyps_current.value ++;
|
||||||
}
|
}
|
||||||
logs.value.push({message:_data.result})
|
if (_data.status === "unzip"){ //解压ZIP
|
||||||
|
prog.value.percent = Math.round(((_data.result.current / _data.result.total) * 100))
|
||||||
|
if (_data.result.current === _data.result.total){
|
||||||
|
prog.value.status = "succees"
|
||||||
|
setTimeout(()=>{
|
||||||
|
prog.value.display = false;
|
||||||
|
},2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_data.status === "downloading"){ //下载文件
|
||||||
|
dprog.value.percent = Math.round((_data.result.index / _data.result.total) * 100)
|
||||||
|
if(dprog.value.percent === 100){
|
||||||
|
dprog.value.status = "succees"
|
||||||
|
setTimeout(()=>{
|
||||||
|
dprog.value.display = false;
|
||||||
|
},2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_data.status === "finish"){
|
||||||
|
const time = Math.round(_data.result / 1000 / 1000)
|
||||||
|
setyps_current.value ++;
|
||||||
|
sendNotification({ title: 'DeEarthX V3', body: `服务端制作完成!共用时${time}秒!` });
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +163,20 @@ logContainer.value.scrollTop = logContainer.value.scrollHeight;
|
|||||||
class="tw:fixed tw:bottom-2 tw:ml-4 tw:w-272 tw:h-16 tw:flex tw:justify-center tw:items-center tw:text-sm">
|
class="tw:fixed tw:bottom-2 tw:ml-4 tw:w-272 tw:h-16 tw:flex tw:justify-center tw:items-center tw:text-sm">
|
||||||
<a-steps :current="setyps_current" :items="setps_items" />
|
<a-steps :current="setyps_current" :items="setps_items" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="disp_steps" ref="logContainer" class="tw:absolute tw:right-2 tw:bottom-20 tw:h-96 tw:w-56 tw:bg-gray-200 tw:rounded-xl tw:container tw:overflow-y-auto">
|
<!-- <div class="tw:absolute tw:bottom-20 tw:right-2 tw:h-16 tw:w-16">
|
||||||
<div v-for="log in logs" class="tw:mt-2 tw:last:mb-0">
|
|
||||||
<span class="tw:text-blue-500">{{ log.message }}</span>
|
</div> -->
|
||||||
|
<div v-if="disp_steps" ref="logContainer" class="tw:absolute tw:right-2 tw:bottom-20 tw:h-80 tw:w-56 tw:rounded-xl tw:container tw:overflow-y-auto">
|
||||||
|
<a-card title="制作进度" :bordered="true">
|
||||||
|
<div v-if="prog.display">
|
||||||
|
<h1>解压进度</h1>
|
||||||
|
<a-progress :percent="prog.percent" :status="prog.status" size="small" />
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="dprog.display">
|
||||||
|
<h1>下载进度</h1>
|
||||||
|
<a-progress :percent="dprog.percent" :status="dprog.status" size="small" />
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user