You've already forked pages
forked from didirus/AstralRinth
* feat: api-client module for content v0 * feat: delete unused components + modules + setting * feat: xhr uploading * feat: fs module -> api-client * feat: migrate files.vue to use tanstack * fix: mem leak + other issues * fix: build * feat: switch to monaco * fix: go back to using ace, but improve preloading + theme * fix: styling + dead attrs * feat: match figma * fix: padding * feat: files-new for ui page structure * feat: finalize files.vue * fix: lint * fix: qa * fix: dep * fix: lint * fix: lockfile merge * feat: icons on navtab * fix: surface alternating on table * fix: hover surface color --------- Signed-off-by: Calum H. <contact@cal.engineer> Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
202 lines
5.5 KiB
TypeScript
202 lines
5.5 KiB
TypeScript
import type { JWTAuth, PowerAction, Project, ServerGeneral } from '@modrinth/utils'
|
|
import { $fetch } from 'ofetch'
|
|
|
|
import { useServersFetch } from '../servers-fetch.ts'
|
|
import { ServerModule } from './base.ts'
|
|
|
|
export class GeneralModule extends ServerModule implements ServerGeneral {
|
|
server_id!: string
|
|
name!: string
|
|
owner_id!: string
|
|
net!: { ip: string; port: number; domain: string }
|
|
game!: string
|
|
backup_quota!: number
|
|
used_backup_quota!: number
|
|
status!: string
|
|
suspension_reason!: string
|
|
loader!: string
|
|
loader_version!: string
|
|
mc_version!: string
|
|
upstream!: {
|
|
kind: 'modpack' | 'mod' | 'resourcepack'
|
|
version_id: string
|
|
project_id: string
|
|
} | null
|
|
|
|
motd?: string
|
|
image?: string
|
|
project?: Project
|
|
sftp_username!: string
|
|
sftp_password!: string
|
|
sftp_host!: string
|
|
datacenter?: string
|
|
notices?: any[]
|
|
node!: { token: string; instance: string }
|
|
flows?: { intro?: boolean }
|
|
|
|
is_medal?: boolean
|
|
|
|
async fetch(): Promise<void> {
|
|
const data = await useServersFetch<ServerGeneral>(`servers/${this.serverId}`, {}, 'general')
|
|
|
|
if (data.upstream?.project_id) {
|
|
const project = await $fetch(
|
|
`https://api.modrinth.com/v2/project/${data.upstream.project_id}`,
|
|
)
|
|
data.project = project as Project
|
|
}
|
|
|
|
if (import.meta.client) {
|
|
data.image = (await this.server.processImage(data.project?.icon_url)) ?? undefined
|
|
}
|
|
|
|
// Copy data to this module
|
|
Object.assign(this, data)
|
|
}
|
|
|
|
async updateName(newName: string): Promise<void> {
|
|
await useServersFetch(`servers/${this.serverId}/name`, {
|
|
method: 'POST',
|
|
body: { name: newName },
|
|
})
|
|
}
|
|
|
|
async power(action: PowerAction): Promise<void> {
|
|
await useServersFetch(`servers/${this.serverId}/power`, {
|
|
method: 'POST',
|
|
body: { action },
|
|
})
|
|
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
await this.fetch() // Refresh this module
|
|
}
|
|
|
|
async reinstall(
|
|
loader: boolean,
|
|
projectId: string,
|
|
versionId?: string,
|
|
loaderVersionId?: string,
|
|
hardReset: boolean = false,
|
|
): Promise<void> {
|
|
const hardResetParam = hardReset ? 'true' : 'false'
|
|
if (loader) {
|
|
if (projectId.toLowerCase() === 'neoforge') {
|
|
projectId = 'NeoForge'
|
|
}
|
|
await useServersFetch(`servers/${this.serverId}/reinstall?hard=${hardResetParam}`, {
|
|
method: 'POST',
|
|
body: {
|
|
loader: projectId,
|
|
loader_version: loaderVersionId,
|
|
game_version: versionId,
|
|
},
|
|
})
|
|
} else {
|
|
await useServersFetch(`servers/${this.serverId}/reinstall?hard=${hardResetParam}`, {
|
|
method: 'POST',
|
|
body: { project_id: projectId, version_id: versionId },
|
|
})
|
|
}
|
|
}
|
|
|
|
reinstallFromMrpack(
|
|
mrpack: File,
|
|
hardReset: boolean = false,
|
|
): {
|
|
promise: Promise<void>
|
|
onProgress: (cb: (p: { loaded: number; total: number; progress: number }) => void) => void
|
|
} {
|
|
const hardResetParam = hardReset ? 'true' : 'false'
|
|
|
|
const progressSubject = new EventTarget()
|
|
|
|
const uploadPromise = (async () => {
|
|
try {
|
|
const auth = await useServersFetch<JWTAuth>(`servers/${this.serverId}/reinstallFromMrpack`)
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
const xhr = new XMLHttpRequest()
|
|
|
|
xhr.upload.addEventListener('progress', (e) => {
|
|
if (e.lengthComputable) {
|
|
progressSubject.dispatchEvent(
|
|
new CustomEvent('progress', {
|
|
detail: {
|
|
loaded: e.loaded,
|
|
total: e.total,
|
|
progress: (e.loaded / e.total) * 100,
|
|
},
|
|
}),
|
|
)
|
|
}
|
|
})
|
|
|
|
xhr.onload = () =>
|
|
xhr.status >= 200 && xhr.status < 300
|
|
? resolve()
|
|
: reject(new Error(`[pyroservers] XHR error status: ${xhr.status}`))
|
|
|
|
xhr.onerror = () => reject(new Error('[pyroservers] .mrpack upload failed'))
|
|
xhr.onabort = () => reject(new Error('[pyroservers] .mrpack upload cancelled'))
|
|
xhr.ontimeout = () => reject(new Error('[pyroservers] .mrpack upload timed out'))
|
|
xhr.timeout = 30 * 60 * 1000
|
|
|
|
xhr.open('POST', `https://${auth.url}/reinstallMrpackMultiparted?hard=${hardResetParam}`)
|
|
xhr.setRequestHeader('Authorization', `Bearer ${auth.token}`)
|
|
|
|
const formData = new FormData()
|
|
formData.append('file', mrpack)
|
|
xhr.send(formData)
|
|
})
|
|
} catch (err) {
|
|
console.error('Error reinstalling from mrpack:', err)
|
|
throw err
|
|
}
|
|
})()
|
|
|
|
return {
|
|
promise: uploadPromise,
|
|
onProgress: (cb: (p: { loaded: number; total: number; progress: number }) => void) =>
|
|
progressSubject.addEventListener('progress', ((e: CustomEvent) =>
|
|
cb(e.detail)) as EventListener),
|
|
}
|
|
}
|
|
|
|
async suspend(status: boolean): Promise<void> {
|
|
await useServersFetch(`servers/${this.serverId}/suspend`, {
|
|
method: 'POST',
|
|
body: { suspended: status },
|
|
})
|
|
}
|
|
|
|
async endIntro(): Promise<void> {
|
|
await useServersFetch(`servers/${this.serverId}/flows/intro`, {
|
|
method: 'DELETE',
|
|
version: 1,
|
|
})
|
|
await this.fetch() // Refresh this module
|
|
}
|
|
|
|
async setMotd(motd: string): Promise<void> {
|
|
try {
|
|
const props = (await this.server.fetchConfigFile('ServerProperties')) as any
|
|
if (props) {
|
|
props.motd = motd
|
|
const newProps = this.server.constructServerProperties(props)
|
|
const octetStream = new Blob([newProps], { type: 'application/octet-stream' })
|
|
const auth = await useServersFetch<JWTAuth>(`servers/${this.serverId}/fs`)
|
|
|
|
await useServersFetch(`/update?path=/server.properties`, {
|
|
method: 'PUT',
|
|
contentType: 'application/octet-stream',
|
|
body: octetStream,
|
|
override: auth,
|
|
})
|
|
}
|
|
} catch {
|
|
console.error(
|
|
'[Modrinth Hosting] [General] Failed to set MOTD due to lack of server properties file.',
|
|
)
|
|
}
|
|
}
|
|
}
|