diff --git a/README.md b/README.md index 05a04b7..f1bd451 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,15 @@ Ex. * This is a directory of toggleable modules. See the note below. * `TestServer-1.12.2.png` Server icon file. +#### Setting the Server Icon + +You can set the server icon in two ways. + +1. __*(Preferred)*__ Place your server icon in the root server directory as shown in the example above. Only jpg and png files will be looked at. The name of the file does not matter. +2. Paste the **full** URL to your server icon in the servermeta.json for your server. It is highly recommended to only use files that are hosted on your own servers. + +The value in servermeta.json will always be used so long as it is not empty and is a [valid url](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL). If it is empty or an [invalid url](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL), then the first method will be used. + #### Toggleable Modules If a directory represents a toggleable mod, it will have three subdirectories. You must filter your files into these three. @@ -279,6 +288,7 @@ Sample: "version": "1.0.0", "name": "Test (Minecraft 1.12.2)", "description": "Test Running Minecraft 1.12.2 (Forge v14.23.5.2854)", + "icon": "How to set the server icon: https://github.com/dscalzi/Nebula#setting-the-server-icon", "address": "localhost:25565", "discord": { "shortId": "1.12.2 Test Server", diff --git a/src/model/nebula/ServerMeta.ts b/src/model/nebula/ServerMeta.ts index 1ecb03d..3566288 100644 --- a/src/model/nebula/ServerMeta.ts +++ b/src/model/nebula/ServerMeta.ts @@ -24,6 +24,7 @@ export function getDefaultServerMeta(id: string, version: string, options?: Serv version: options?.version ?? '1.0.0', name: `${id} (Minecraft ${version})`, description: `${id} Running Minecraft ${version}`, + icon: 'How to set the server icon: https://github.com/dscalzi/Nebula#setting-the-server-icon', address: 'localhost:25565', discord: { shortId: '', @@ -57,6 +58,7 @@ export interface ServerMeta { version: Server['version'] name: Server['name'] description: Server['description'] + icon?: Server['icon'] address: Server['address'] discord?: Server['discord'] mainServer: Server['mainServer'] diff --git a/src/structure/spec_model/Server.struct.ts b/src/structure/spec_model/Server.struct.ts index a1df2d3..6529c77 100644 --- a/src/structure/spec_model/Server.struct.ts +++ b/src/structure/spec_model/Server.struct.ts @@ -10,6 +10,7 @@ import { MiscFileStructure } from './module/File.struct.js' import { LibraryStructure } from './module/Library.struct.js' import { MinecraftVersion } from '../../util/MinecraftVersion.js' import { addSchemaToObject, SchemaTypes } from '../../util/SchemaUtil.js' +import { isValidUrl } from '../../util/StringUtils.js' export interface CreateServerResult { forgeModContainer?: string @@ -123,26 +124,36 @@ export class ServerStructure extends BaseModelStructure { continue } - let iconUrl: string = null! - - // Resolve server icon - const subFiles = await readdir(absoluteServerRoot) - for (const subFile of subFiles) { - const caseInsensitive = subFile.toLowerCase() - if (caseInsensitive.endsWith('.jpg') || caseInsensitive.endsWith('.png')) { - iconUrl = new URL(join(relativeServerRoot, subFile), this.baseUrl).toString() - } - } - - if (!iconUrl) { - this.logger.warn(`No icon file found for server ${file}.`) - } - // Read server meta const serverMeta = JSON.parse(await readFile(resolvePath(absoluteServerRoot, this.SERVER_META_FILE), 'utf-8')) as ServerMeta const minecraftVersion = new MinecraftVersion(match[2]) const untrackedFiles: UntrackedFilesOption[] = serverMeta.untrackedFiles || [] + let iconUrl: string = null! + + // Resolve server icon + + if(serverMeta.meta.icon && isValidUrl(serverMeta.meta.icon)) { + // Use the url they gave us. + iconUrl = serverMeta.meta.icon + } else { + + this.logger.info('Server icon is either not set or not a valid URL.') + this.logger.info(`Looking for an icon file at ${absoluteServerRoot}`) + + const subFiles = await readdir(absoluteServerRoot) + for (const subFile of subFiles) { + const caseInsensitive = subFile.toLowerCase() + if (caseInsensitive.endsWith('.jpg') || caseInsensitive.endsWith('.png')) { + iconUrl = new URL(join(relativeServerRoot, subFile), this.baseUrl).toString() + } + } + + if (!iconUrl) { + this.logger.warn(`No icon file found for server ${file}.`) + } + } + const modules: Module[] = [] if(serverMeta.forge) { diff --git a/src/util/StringUtils.ts b/src/util/StringUtils.ts index 84ec76d..0536c03 100644 --- a/src/util/StringUtils.ts +++ b/src/util/StringUtils.ts @@ -4,3 +4,12 @@ export function capitalize(str: string): string { } return str.charAt(0).toUpperCase() + str.slice(1) } + +export function isValidUrl(candidate: string): boolean { + try { + new URL(candidate) + return true + } catch (err) { + return false + } +}