Skip to content

Commit

Permalink
Fix dock icon
Browse files Browse the repository at this point in the history
  • Loading branch information
GreenAppers committed Nov 30, 2024
1 parent 7a21a74 commit ca32225
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 61 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"framer-motion": "^11.5.6",
"glob": "^11.0.0",
"p-settle": "^5.1.1",
"png2icons": "^2.0.1",
"prismarine-nbt": "^2.6.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
4 changes: 1 addition & 3 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ export function App() {
</TabList>
<Spacer />
{gameAccount ? (
<Tooltip label={gameAccount.profile.name}>
<PlayerHead headSize={76} profile={gameAccount.profile} />
</Tooltip>
<PlayerHead headSize={76} profile={gameAccount.profile} />
) : (
<Button
variant="ghost"
Expand Down
2 changes: 1 addition & 1 deletion src/components/Launcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export function Launcher() {
</Text>

{getGameInstalModLoaderName(install) ===
ModLoaderName.Fabric ? (
ModLoaderName.fabric ? (
getGameInstallIsHacked(install) ? (
<Text color="red.500">[Hacked]</Text>
) : (
Expand Down
6 changes: 5 additions & 1 deletion src/components/NewGameInstall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@ export function NewGameInstall(props: {
!!newInstall?.mods?.find((x) => x.name == name)
}
onChange={(e) =>
updateNewInstallMod(name, 'fabric', e.target.checked)
updateNewInstallMod(
name,
getGameInstalModLoaderName(newInstall),
e.target.checked
)
}
>
{name}
Expand Down
20 changes: 14 additions & 6 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { z } from 'zod'

export enum ModLoaderName {
Fabric = 'Fabric',
None = 'None',
fabric = 'fabric',
forge = 'forge',
none = 'none',
}

export enum ShaderpackLoaderName {
iris = 'iris',
optifine = 'optifine',
none = 'none',
}

export const minecraftLoginResponse = z.object({
Expand Down Expand Up @@ -246,8 +253,9 @@ export const gameInstall = z.object({
path: z.string(),
uuid: z.string(),
versionManifest: mojangVersionManifest,
fabricLoaderVersion: z.optional(z.string()),
extraCommandlineArguments: z.optional(z.array(z.string())),
fabricLoaderVersion: z.optional(z.string()),
iconHash: z.optional(z.string()),
mods: z.optional(z.array(gameMod)),
shaderpacks: z.optional(z.array(gameShaderpack)),
wrapMainClass: z.optional(z.boolean()),
Expand Down Expand Up @@ -326,8 +334,8 @@ export const findVersionManifest = (
export const getGameInstalModLoaderName = (
gameInstall: Partial<GameInstall>
): ModLoaderName => {
if (gameInstall.fabricLoaderVersion) return ModLoaderName.Fabric
return ModLoaderName.None
if (gameInstall.fabricLoaderVersion) return ModLoaderName.fabric
return ModLoaderName.none
}

export const getGameInstallIsHacked = (gameInstall: Partial<GameInstall>) =>
Expand All @@ -338,7 +346,7 @@ export const setGameInstallModLoaderName = (
modLoaderName: string
): Partial<GameInstall> => {
switch (modLoaderName) {
case ModLoaderName.Fabric:
case ModLoaderName.fabric:
return { ...gameInstall, fabricLoaderVersion: 'auto' }
default:
return { ...gameInstall, fabricLoaderVersion: undefined }
Expand Down
89 changes: 89 additions & 0 deletions src/utils/icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { app } from 'electron'
import fs from 'fs'
import { glob } from 'glob'
import path from 'path'
import { BILINEAR, createICNS } from 'png2icons'
import UPNG from 'png2icons/lib/UPNG'
import Resize from 'png2icons/lib/resize3'
import { GameInstall } from '../constants'
import { checkFileExists, ensureDirectory, sha1File } from './downloader'

export const getInstallIconPath = (install: GameInstall) =>
path.join(install.path, 'icon.png')

export async function getRandomIcon() {
const icons = await glob(
path.join(app.getAppPath(), 'images', 'icons', '*.png')
)
return icons[Math.floor(Math.random() * icons.length)]
}

export function resamplePNG(
inputBuffer: Buffer,
width: number,
height: number
): Buffer {
const decoded = UPNG.decode(inputBuffer)
const input = {
width: decoded.width,
height: decoded.height,
data: new Uint8Array(UPNG.toRGBA8(decoded)[0]),
}
const output = {
width,
height,
data: new Uint8Array(width * height * 4),
}
Resize.bilinearInterpolation(input, output)
return Buffer.from(UPNG.encode([output.data], width, height, 0, [], true))
}

export async function setupIcon(install: GameInstall) {
const iconPath = getInstallIconPath(install)
if (!(await checkFileExists(iconPath))) {
await fs.promises.copyFile(
await getRandomIcon(),
getInstallIconPath(install)
)
}

const iconHash = await sha1File(iconPath)
const iconHashMatched = !!iconHash && iconHash === install.iconHash
const fancymenuAssets = path.join(
install.path,
'config',
'fancymenu',
'assets'
)
const fancymenuIcon16 = path.join(fancymenuAssets, 'icon16.png')
const fancymenuIcon32 = path.join(fancymenuAssets, 'icon32.png')
const fancymenuIconIcns = path.join(fancymenuAssets, 'icon.icns')

let iconBuffer: Buffer | undefined
if (!iconHashMatched || !(await checkFileExists(fancymenuIcon16))) {
if (!iconBuffer) iconBuffer = await fs.promises.readFile(iconPath)
await ensureDirectory(fancymenuAssets)
await fs.promises.writeFile(
fancymenuIcon16,
resamplePNG(iconBuffer, 16, 16)
)
}
if (!iconHashMatched || !(await checkFileExists(fancymenuIcon32))) {
if (!iconBuffer) iconBuffer = await fs.promises.readFile(iconPath)
await ensureDirectory(fancymenuAssets)
await fs.promises.writeFile(
fancymenuIcon32,
resamplePNG(iconBuffer, 32, 32)
)
}
if (!iconHashMatched || !(await checkFileExists(fancymenuIconIcns))) {
if (!iconBuffer) iconBuffer = await fs.promises.readFile(iconPath)
await ensureDirectory(fancymenuAssets)
const icnsBuffer = createICNS(iconBuffer, BILINEAR, 0)
if (icnsBuffer) await fs.promises.writeFile(fancymenuIconIcns, icnsBuffer)
}

if (!iconHashMatched) {
install.iconHash = iconHash
}
}
46 changes: 14 additions & 32 deletions src/utils/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import axios from 'axios'
import { spawn } from 'child_process'
import { app } from 'electron'
import fs from 'fs'
import { glob } from 'glob'
import path from 'path'
import pSettle from 'p-settle'
import readline from 'readline'
import { v4 as uuidv4 } from 'uuid'

import {
Expand All @@ -26,6 +24,7 @@ import {
downloadIfMissing,
ensureDirectory,
} from './downloader'
import { setupIcon } from './icon'
import {
allowRules,
applyArgumentsTemplate,
Expand All @@ -48,22 +47,12 @@ export const getClientJarPath = (version: string) =>
`com/mojang/minecraft/${version}/minecraft-${version}-client.jar`
)

export const getInstallIconPath = (install: GameInstall) =>
path.join(install.path, 'icon.png')

export const getMinecraftVersionJsonPath = (install: GameInstall) =>
path.join(install.path, `${install.versionManifest.id}.json`)

export const getFabricVersionJsonPath = (install: GameInstall) =>
path.join(install.path, `fabric-${install.fabricLoaderVersion}.json`)

export async function getRandomIcon() {
const icons = await glob(
path.join(app.getAppPath(), 'images', 'icons', '*.png')
)
return icons[Math.floor(Math.random() * icons.length)]
}

export async function setupFabricInstall(install: GameInstall) {
if (!(await checkFileExists(getFabricVersionJsonPath(install)))) {
const loaders = await axios.get(
Expand Down Expand Up @@ -98,13 +87,7 @@ export async function setupInstall(install: GameInstall) {
await download(install.versionManifest.url, versionDetailsFilename)
}

if (!(await checkFileExists(getInstallIconPath(install)))) {
await fs.promises.copyFile(
await getRandomIcon(),
getInstallIconPath(install)
)
}

await setupIcon(install)
if (install.fabricLoaderVersion) await setupFabricInstall(install)
}

Expand Down Expand Up @@ -182,14 +165,22 @@ export async function updateInstall(install: GameInstall) {
)
for (const [filePath, url] of Object.entries(mod.extraFiles ?? {})) {
downloadLibraries.push(() =>
downloadIfMissing(
url,
path.join(install.path, filePath)
)
downloadIfMissing(url, path.join(install.path, filePath))
)
}
}

const shaderpacksPath = path.join(install.path, 'shaderpacks')
for (const shaderpack of install.shaderpacks ?? []) {
const url = new URL(shaderpack.url)
downloadLibraries.push(() =>
downloadIfMissing(
shaderpack.url,
path.join(shaderpacksPath, path.basename(url.pathname))
)
)
}

await pSettle(downloadLibraries, { concurrency: 8 })
return versionDetails
}
Expand Down Expand Up @@ -275,15 +266,6 @@ export async function launchInstall(
// '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java',
'java',
]
switch (getOsName()) {
case 'osx':
command.push(
'-Xdock:icon=icon.png',
`-Xdock:name="EmpireUtils: ${install.name}"`,
'-XstartOnFirstThread'
)
break
}
applyArgumentsTemplate(
{ osName, osArch },
versionDetails.arguments.jvm,
Expand Down
22 changes: 4 additions & 18 deletions src/utils/mods.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GameMod, GameShaderpack } from '../constants'
import { GameMod } from '../constants'

export const defaultFabricMods = [
'fabric-api',
Expand All @@ -13,6 +13,8 @@ export const defaultFabricMods = [
'sodium',
]

export const defaultShaderpacks = ['bsl-shaders', 'photon-shader']

export const modExtras: Record<
string,
(version: string) => Record<string, string>
Expand All @@ -23,7 +25,7 @@ export const modExtras: Record<
}),
fancymenu: () => ({
'config/fancymenu/options.txt':
'https://github.com/AngleOpera/meteor-archive/blob/12c09d0c10b869477220494ba2266c61ac3ba355/default/config/fancymenu/options.txt?raw=true',
'https://github.com/AngleOpera/meteor-archive/blob/626061ca24725129e79b0edae070211aa9da3fc8/default/config/fancymenu/options.txt?raw=true',
}),
'meteor-client': () => ({
'meteor-client/macros.nbt':
Expand Down Expand Up @@ -108,19 +110,3 @@ export const modDownloads: Record<string, Record<string, Partial<GameMod>>> = {
},
},
}

export const shaders: Record<
string,
Record<string, Partial<GameShaderpack>>
> = {
bsl: {
'*': {
url: 'https://cdn.modrinth.com/data/Q1vvjJYV/versions/53F1SOEu/BSL_v8.4.zip',
},
},
photon: {
'*': {
url: 'https://cdn.modrinth.com/data/lLqFfGNs/versions/Dn4cGSpn/photon_v1.0a.zip',
},
},
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6900,6 +6900,11 @@ plist@^3.0.0, plist@^3.0.5, plist@^3.1.0:
base64-js "^1.5.1"
xmlbuilder "^15.1.1"

png2icons@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/png2icons/-/png2icons-2.0.1.tgz#09d8f10b71302e98ca178d3324bc4deff9b90124"
integrity sha512-GDEQJr8OG4e6JMp7mABtXFSEpgJa1CCpbQiAR+EjhkHJHnUL9zPPtbOrjsMD8gUbikgv3j7x404b0YJsV3aVFA==

possible-typed-array-names@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f"
Expand Down

0 comments on commit ca32225

Please sign in to comment.