diff --git a/public/icons/discord/artgame.jpg b/public/icons/discord/artgame.jpg new file mode 100644 index 0000000..83dc7d9 Binary files /dev/null and b/public/icons/discord/artgame.jpg differ diff --git a/public/icons/discord/artgame2.jpg b/public/icons/discord/artgame2.jpg new file mode 100644 index 0000000..22d852f Binary files /dev/null and b/public/icons/discord/artgame2.jpg differ diff --git a/public/icons/discord/artgame3.jpg b/public/icons/discord/artgame3.jpg new file mode 100644 index 0000000..c64368a Binary files /dev/null and b/public/icons/discord/artgame3.jpg differ diff --git a/public/icons/discord/beidougame.jpg b/public/icons/discord/beidougame.jpg new file mode 100644 index 0000000..c3c2993 Binary files /dev/null and b/public/icons/discord/beidougame.jpg differ diff --git a/public/icons/discord/game.png b/public/icons/discord/game.png new file mode 100644 index 0000000..4f9140e Binary files /dev/null and b/public/icons/discord/game.png differ diff --git a/public/icons/discord/gi-icon.png b/public/icons/discord/gi-icon.png new file mode 100644 index 0000000..09daed0 Binary files /dev/null and b/public/icons/discord/gi-icon.png differ diff --git a/public/icons/discord/kleegame.png b/public/icons/discord/kleegame.png new file mode 100644 index 0000000..571d154 Binary files /dev/null and b/public/icons/discord/kleegame.png differ diff --git a/public/icons/discord/kleegame2.jpg b/public/icons/discord/kleegame2.jpg new file mode 100644 index 0000000..53e8908 Binary files /dev/null and b/public/icons/discord/kleegame2.jpg differ diff --git a/public/icons/discord/liyuegame.jpg b/public/icons/discord/liyuegame.jpg new file mode 100644 index 0000000..5895ad0 Binary files /dev/null and b/public/icons/discord/liyuegame.jpg differ diff --git a/public/locales/de-de.yaml b/public/locales/de-de.yaml index fa3f397..272d4ab 100644 --- a/public/locales/de-de.yaml +++ b/public/locales/de-de.yaml @@ -44,8 +44,15 @@ settings: light: Hell dark: Dunkel - discord: Discord RPC - dxvks: DXVK + # Discord RPC + discord: + title: Discord RPC + settings: + title: Discord RPC settings + items: + timer: Display spent time + in-launcher: In-launcher text + in-game: In-game text # Verberssungen enhancements: diff --git a/public/locales/en-us.yaml b/public/locales/en-us.yaml index 2dcccdc..cef8509 100644 --- a/public/locales/en-us.yaml +++ b/public/locales/en-us.yaml @@ -44,8 +44,15 @@ settings: light: Light dark: Dark - discord: Discord RPC - dxvks: DXVK + # Discord RPC + discord: + title: Discord RPC + settings: + title: Discord RPC settings + items: + timer: Display spent time + in-launcher: In-launcher text + in-game: In-game text # Enhancements enhancements: diff --git a/public/locales/ru-ru.yaml b/public/locales/ru-ru.yaml index b385c86..d30007f 100644 --- a/public/locales/ru-ru.yaml +++ b/public/locales/ru-ru.yaml @@ -44,8 +44,15 @@ settings: light: Светлая dark: Тёмная - discord: Discord RPC - dxvks: DXVK + # Discord RPC + discord: + title: Discord RPC + settings: + title: Настройки Discord RPC + items: + timer: Отображать потраченное время + in-launcher: Текст в лаунчере + in-game: Текст в игре # Улучшения enhancements: diff --git a/src/components/DiscordSettings.svelte b/src/components/DiscordSettings.svelte new file mode 100644 index 0000000..ade0842 --- /dev/null +++ b/src/components/DiscordSettings.svelte @@ -0,0 +1,35 @@ + + +
+

{$_('settings.general.items.discord.settings.title')}

+ + + + + + + + + + + + + + +
+ {$_('settings.general.items.discord.settings.items.in-launcher')} + + console.log(value)}> +
+ {$_('settings.general.items.discord.settings.items.in-game')} + + +
+
diff --git a/src/defaultSettings.ts b/src/defaultSettings.ts index a1ef5b3..9fab555 100644 --- a/src/defaultSettings.ts +++ b/src/defaultSettings.ts @@ -81,24 +81,19 @@ promisify(async () => { * RPC settings */ fields: { - /** - * Launcher title - */ - title: 'An Anime Game Launcher', - /** * Small messages after title */ - state: { - /** - * Message showed when you're in game - */ - 'in-launcher': 'Playing the game', - + states: { /** * Message showed when you're in launcher */ - 'in-game': 'Preparing to launch' + 'in-launcher': 'Preparing to launch', + + /** + * Message showed when you're in game + */ + 'in-game': 'Playing the game' }, /** diff --git a/src/sass/components.sass b/src/sass/components.sass index df6e9c6..cd9e981 100644 --- a/src/sass/components.sass +++ b/src/sass/components.sass @@ -4,6 +4,7 @@ @import "components/selectionBox" @import "components/dropdownCheckboxes" @import "components/selectionList" +@import "components/table" @mixin themable($theme-name, $theme-map) body[data-theme=#{$theme-name}] diff --git a/src/sass/components/table.sass b/src/sass/components/table.sass new file mode 100644 index 0000000..3057fc5 --- /dev/null +++ b/src/sass/components/table.sass @@ -0,0 +1,65 @@ +@use "sass:map" + +@mixin themable($theme-name, $theme-map) + body[data-theme=#{$theme-name}] + table.table + width: calc(100% - 24px) + + margin-left: 12px + + border-spacing: 0 + + $cell-height: 40px + $padding-v: 4px + $padding-h: 8px + + tr + height: $cell-height + + cursor: pointer + + &:hover + background-color: map.get($theme-map, "background1") + + td input + background-color: map.get($theme-map, "background1") + + td:nth-of-type(1), + th:nth-of-type(1) + width: 40% + + th, + td + border-bottom: 1px solid map.get($theme-map, "background1") + + &:not(:last-child) + border-right: 1px solid map.get($theme-map, "background1") + + td + span + display: block + + width: calc(100% - 2 * $padding-h) + height: calc($cell-height - 2 * $padding-h) + + margin: auto + + input + display: block + + width: calc(100% - 2 * $padding-h) + height: calc($cell-height - 2 * $padding-h) + + color: map.get($theme-map, "text") + + font-size: 15px + + margin: auto + border: unset + outline: none + +@import "../themes/light" +@import "../themes/dark" + +@include themable(light, $light) +@include themable(dark, $dark) \ No newline at end of file diff --git a/src/settings.svelte b/src/settings.svelte index cf25079..97fd1d3 100644 --- a/src/settings.svelte +++ b/src/settings.svelte @@ -15,6 +15,7 @@ import Checkbox from './components/Checkbox.svelte'; import SelectionBox from './components/SelectionBox.svelte'; import DropdownCheckboxes from './components/DropdownCheckboxes.svelte'; + import DiscordSettings from './components/DiscordSettings.svelte'; import DXVKSelectionList from './components/DXVKSelectionList.svelte'; import RunnerSelectionList from './components/RunnerSelectionList.svelte'; import ShadersSelection from './components/ShadersSelection.svelte'; @@ -110,9 +111,12 @@ let dxvkRecommendable = true, runnersRecommendable = true, + discordRpcSettings = false, fpsUnlockerAvailable = true, voiceUpdateRequired = false; + Configs.get('discord.enabled').then((enabled) => discordRpcSettings = enabled as boolean); + // Auto theme switcher Configs.get('theme').then((theme) => switchTheme(theme as string)); @@ -169,7 +173,13 @@ valueChanged={switchTheme} /> - + discordRpcSettings = value} + /> + +
diff --git a/src/ts/Game.ts b/src/ts/Game.ts index 5d5d4b0..6d3369d 100644 --- a/src/ts/Game.ts +++ b/src/ts/Game.ts @@ -34,12 +34,12 @@ export default class Game public static get current(): Promise { return new Promise(async (resolve) => { - const persistentPath = `${await constants.paths.gameDataDir}/Persistent/ScriptVersion`; + // const persistentPath = `${await constants.paths.gameDataDir}/Persistent/ScriptVersion`; const globalGameManagersPath = `${await constants.paths.gameDataDir}/globalgamemanagers`; - Neutralino.filesystem.readFile(persistentPath) + /*Neutralino.filesystem.readFile(persistentPath) .then((version) => resolve(version)) - .catch(() => { + .catch(() => {*/ Neutralino.filesystem.readBinaryFile(globalGameManagersPath) .then((config: ArrayBuffer) => { const buffer = new TextDecoder('ascii').decode(new Uint8Array(config)); @@ -53,7 +53,7 @@ export default class Game resolve(version !== null ? version[1] : null); }) .catch(() => resolve(null)); - }); + // }); }); } diff --git a/src/ts/Launcher.ts b/src/ts/Launcher.ts index 6b3ead1..94bad17 100644 --- a/src/ts/Launcher.ts +++ b/src/ts/Launcher.ts @@ -105,10 +105,7 @@ export default class Launcher id: '901534333360304168', // @ts-expect-error - details: discord.fields.title, - - // @ts-expect-error - state: discord.fields.state[state], + details: discord.fields.states[state], icon: { // @ts-expect-error @@ -117,7 +114,7 @@ export default class Launcher time: { // @ts-expect-error - start: discord.fields.time ? Math.round(Date.now() / 1000) : 0 + start: discord.fields.timer ? Math.round(Date.now() / 1000) : 0 } }); diff --git a/src/ts/Patch.ts b/src/ts/Patch.ts index 76dfa80..da27c27 100644 --- a/src/ts/Patch.ts +++ b/src/ts/Patch.ts @@ -192,21 +192,20 @@ export default class Patch return new Promise(async (resolve, reject) => { const patchUri = constants.uri.patch[source]; - fetch(`${patchUri}/raw/master/${version.replaceAll('.', '')}/patch.sh`, this.fetchTimeout) - .then((patcherResponse) => { + fetch(`${patchUri}/raw/master/${version.replaceAll('.', '')}/README.txt`, this.fetchTimeout) + .then((readmeResponse) => { // Return an error if patch's server is unavailable - if (patcherResponse.status === null) + if (readmeResponse.status === null) reject(new Error(`${source} patch repository is unreachable`)); - // If [version]/patch.sh file doesn't exist - it means + // If [version]/README.txt file doesn't exist - it means // that patch repo has no [version] - else if (patcherResponse.status === 404) + else if (readmeResponse.status === 404) resolve(null); // Otherwise it should be [preparation], [testing] or [stable] else { - fetch(`${patchUri}/raw/master/${version.replaceAll('.', '')}/patch_files/unityplayer_patch.vcdiff`, this.fetchTimeout) .then((response) => { // Return an error if patch's server is unavailable @@ -228,46 +227,53 @@ export default class Patch // Otherwise it's [testing] or [stable] else { - patcherResponse.body(this.fetchTimeout) - .then((response) => { + fetch(`${patchUri}/raw/master/${version.replaceAll('.', '')}/patch.sh`, this.fetchTimeout) + .then((patcherResponse) => { // Return an error if patch's server is unavailable - if (response === '') + if (patcherResponse.status === null) reject(new Error(`${source} patch repository is unreachable`)); + + else patcherResponse.body(this.fetchTimeout) + .then((response) => { + // Return an error if patch's server is unavailable + if (response === '') + reject(new Error(`${source} patch repository is unreachable`)); - // Otherwise - let's prepare [testing] or [stable] output - else - { - // If this line is commented - then it's [stable] version - // Otherwise it's [testing] - const stableMark = '#echo "If you would like to test this patch, modify this script and remove the line below this one."'; + // Otherwise - let's prepare [testing] or [stable] output + else + { + // If this line is commented - then it's [stable] version + // Otherwise it's [testing] + const stableMark = '#echo "If you would like to test this patch, modify this script and remove the line below this one."'; - let patchInfo: PatchInfo = { - version: version, - state: response.includes(stableMark) ? 'stable' : 'testing', - applied: false, - source: source - }; + let patchInfo: PatchInfo = { + version: version, + state: response.includes(stableMark) ? 'stable' : 'testing', + applied: false, + source: source + }; - const originalPlayer = /if \[ "\${sum}" != "([a-z0-9]{32})" \]; then/mg.exec(response); + const originalPlayer = /if \[ "\${sum}" != "([a-z0-9]{32})" \]; then/mg.exec(response); - // If we could get original UnityPlayer.dll hash - then we can - // compare it with actual UnityPlayer.dll hash and say whether the patch - // was applied or not - if (originalPlayer !== null) - { - constants.paths.gameDir.then((gameDir) => { - Neutralino.filesystem.readBinaryFile(`${gameDir}/UnityPlayer.dll`) - .then((currPlayer: ArrayBuffer) => { - patchInfo.applied = md5(currPlayer) != originalPlayer[1]; + // If we could get original UnityPlayer.dll hash - then we can + // compare it with actual UnityPlayer.dll hash and say whether the patch + // was applied or not + if (originalPlayer !== null) + { + constants.paths.gameDir.then((gameDir) => { + Neutralino.filesystem.readBinaryFile(`${gameDir}/UnityPlayer.dll`) + .then((currPlayer: ArrayBuffer) => { + patchInfo.applied = md5(currPlayer) != originalPlayer[1]; - resolve(patchInfo); - }) - .catch(() => resolve(patchInfo)); - }); - } + resolve(patchInfo); + }) + .catch(() => resolve(patchInfo)); + }); + } - else resolve(patchInfo); - } + else resolve(patchInfo); + } + }); }); } }); diff --git a/src/ts/launcher/State.ts b/src/ts/launcher/State.ts index 7753181..ac7a9da 100644 --- a/src/ts/launcher/State.ts +++ b/src/ts/launcher/State.ts @@ -152,14 +152,20 @@ export default class State case 'test-patch-available': this.launchButton.textContent = 'Apply test patch'; + this.launchButton.classList.add('button-blue'); + this.launchButton.setAttribute('aria-label', 'This game version has an anti-cheat patch, but it is in the testing phase. You can wait a few days until it is stable or apply it at your own risk'); break; case 'patch-unavailable': - // TODO: some warning message this.launchButton.textContent = 'Patch unavailable'; + this.launchButton.classList.add('button-blue'); + this.launchButton.setAttribute('disabled', ''); + + this.launchButton.setAttribute('aria-label', 'This game version has no anti-cheat patch. Please, wait a few days before there will be a test or stable version'); + break; } } @@ -293,13 +299,19 @@ export default class State { const patch = await Patch.latest; - if (!patch.applied) + // If the latest game version is, for example, 2.3.0 + // and the patch is 2.4.0 preparation, it means that + // 2.4.0 will be released soon, but since it's still not released + // we shouldn't show something about it to user and just let him play the game + if (gameLatest.game.latest.version === patch.version && !patch.applied) { state = patch.state == 'preparation' ? 'patch-unavailable' : (patch.state == 'testing' ? 'test-patch-available' : 'patch-available'); } + // Patch is more important than game pre-downloading + // because otherwise we will not be able to play the game else if (gameLatest.pre_download_game && !await Game.isUpdatePredownloaded()) state = 'game-pre-installation-available'; diff --git a/src/ts/launcher/states/Install.ts b/src/ts/launcher/states/Install.ts index 52cd178..d328b25 100644 --- a/src/ts/launcher/states/Install.ts +++ b/src/ts/launcher/states/Install.ts @@ -45,6 +45,8 @@ export default (launcher: Launcher): Promise => { showPercents: true, showTotals: true }); + + launcher.progressBar?.show(); }); stream?.unpackProgress((current: number, total: number, difference: number) => { diff --git a/src/ts/launcher/states/InstallVoice.ts b/src/ts/launcher/states/InstallVoice.ts index bc595ab..a666bca 100644 --- a/src/ts/launcher/states/InstallVoice.ts +++ b/src/ts/launcher/states/InstallVoice.ts @@ -71,6 +71,8 @@ export default (launcher: Launcher): Promise => { showPercents: true, showTotals: true }); + + launcher.progressBar?.show(); }); stream?.unpackProgress((current: number, total: number, difference: number) => {