feat: add info event listener and payload for enhanced event handling
Some checks failed
AstralRinth App build / Build (x86_64-pc-windows-msvc, windows-latest) (push) Has been cancelled
AstralRinth App build / Build (x86_64-unknown-linux-gnu, ubuntu-latest) (push) Has been cancelled

- Implemented `info_listener` in `events.js` to listen for 'info' events and handle payloads.
- Added `emit_info` function in `emit.rs` to emit 'info' events with a message payload.
- Defined `InfoPayload` struct in `mod.rs` to structure the data for 'info' events.
- Integrated `emit_info` calls in the Minecraft launch logic to provide feedback on account types.
- Introduced a new offline icon in SVG format and removed outdated pirate icons from assets.
- Updated asset index to include the new offline icon and removed references to deleted icons.
This commit is contained in:
2026-01-27 20:41:55 +03:00
parent 45519f5dbb
commit 572800d9ca
10 changed files with 293 additions and 194 deletions

View File

@@ -73,7 +73,7 @@ import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
import { debugAnalytics, initAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
import { check_reachable } from '@/helpers/auth.js'
import { get_user } from '@/helpers/cache.js'
import { command_listener, warning_listener } from '@/helpers/events.js'
import { command_listener, warning_listener, info_listener } from '@/helpers/events.js'
import { useFetch } from '@/helpers/fetch.js'
import { cancelLogin, get as getCreds, login, logout } from '@/helpers/mr_auth.ts'
import { list } from '@/helpers/profile.js'
@@ -286,6 +286,15 @@ async function setupApp() {
}),
)
// [AR] Info listener
await info_listener((e) =>
addNotification({
title: 'Info',
text: e.message,
type: 'info',
}),
)
useFetch(
`https://api.modrinth.com/appCriticalAnnouncement.json?version=${version}`,
'criticalAnnouncements',

View File

@@ -1,12 +1,24 @@
<template>
<div v-if="mode !== 'isolated'" ref="button"
<div
v-if="mode !== 'isolated'"
ref="button"
class="button-base mt-2 px-3 py-2 bg-button-bg rounded-xl flex items-center gap-2"
:class="{ expanded: mode === 'expanded' }" @click="toggleMenu">
<Avatar size="36px" :src="selectedAccount ? avatarUrl : 'https://launcher-files.modrinth.com/assets/steve_head.png'
" />
:class="{ expanded: mode === 'expanded' }"
@click="toggleMenu"
>
<Avatar
size="36px"
:src="
selectedAccount ? avatarUrl : 'https://launcher-files.modrinth.com/assets/steve_head.png'
"
/>
<div class="flex flex-col w-full">
<span>
<component :is="getAccountType(selectedAccount)" v-if="selectedAccount" class="vector-icon" />
<component
:is="getAccountType(selectedAccount)"
v-if="selectedAccount"
class="vector-icon"
/>
{{ selectedAccount ? selectedAccount.profile.name : 'Select account' }}
</span>
<span class="text-secondary text-xs">Minecraft account</span>
@@ -14,32 +26,46 @@
<DropdownIcon class="w-5 h-5 shrink-0" />
</div>
<transition name="fade">
<Card v-if="showCard || mode === 'isolated'" ref="card" class="account-card"
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }">
<Card
v-if="showCard || mode === 'isolated'"
ref="card"
class="account-card"
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }"
>
<div v-if="selectedAccount" class="selected account">
<Avatar size="xs" :src="avatarUrl" />
<div>
<h4>
<component :is="getAccountType(selectedAccount)" class="vector-icon" /> {{
selectedAccount.profile.name }}
<component :is="getAccountType(selectedAccount)" class="vector-icon" />
{{ selectedAccount.profile.name }}
</h4>
<p>Selected</p>
</div>
<Button v-tooltip="'Log out'" icon-only color="raised" @click="logout(selectedAccount.profile.id)">
<Button
v-tooltip="'Log out'"
icon-only
color="raised"
@click="logout(selectedAccount.profile.id)"
>
<TrashIcon />
</Button>
</div>
<div v-else class="login-section account">
<h4>Not signed in</h4>
<Button v-tooltip="'Log via Microsoft'" :disabled="microsoftLoginDisabled" icon-only @click="login()">
<Button
v-tooltip="'Log via Microsoft'"
:disabled="microsoftLoginDisabled"
icon-only
@click="login()"
>
<MicrosoftIcon v-if="!microsoftLoginDisabled" />
<SpinnerIcon v-else class="animate-spin" />
</Button>
<Button v-tooltip="'Add offline account'" icon-only @click="showOfflineLoginModal()">
<PirateIcon />
<OfflineIcon />
</Button>
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElybyLoginModal()">
<ElyByIcon v-if="!elybyLoginDisabled" />
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElyByLoginModal()">
<ElyByIcon v-if="!elyByLoginDisabled" />
<SpinnerIcon v-else class="animate-spin" />
</Button>
</div>
@@ -63,23 +89,37 @@
<SpinnerIcon v-else class="animate-spin" />
</Button>
<Button v-tooltip="'Add offline account'" icon-only @click="showOfflineLoginModal()">
<PirateIcon />
<OfflineIcon />
</Button>
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElybyLoginModal()">
<ElyByIcon v-if="!elybyLoginDisabled" />
<Button v-tooltip="'Log via Ely.by'" icon-only @click="showElyByLoginModal()">
<ElyByIcon v-if="!elyByLoginDisabled" />
<SpinnerIcon v-else class="animate-spin" />
</Button>
</div>
</Card>
</transition>
<ModalWrapper ref="addElybyModal" class="modal" header="Authenticate with Ely.by">
<ModalWrapper ref="requestElybyTwoFactorCodeModal" class="modal"
header="Ely.by requested 2FA code for authentication">
<ModalWrapper ref="addElyByModal" class="modal" header="Authenticate with Ely.by">
<ModalWrapper
ref="requestElyByTwoFactorCodeModal"
class="modal"
header="Ely.by requested 2FA code for authentication"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="label">Enter your 2FA code</label>
<input v-model="elybyTwoFactorCode" type="text" placeholder="Your 2FA code here..." class="input" />
<input
v-model="elyByTwoFactorCode"
type="text"
placeholder="Your 2FA code here..."
class="input"
/>
<div class="mt-6 ml-auto">
<Button icon-only color="primary" class="continue-button" @click="addElybyProfile()">
<Button
:disabled="elyByLoginDisabled"
icon-only
color="primary"
class="continue-button"
@click="addElyByProfile()"
>
Continue
</Button>
</div>
@@ -87,11 +127,27 @@
</ModalWrapper>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="label">Enter your player name or email (preferred)</label>
<input v-model="elybyLogin" type="text" placeholder="Your player name or email here..." class="input" />
<input
v-model="elyByLogin"
type="text"
placeholder="Your player name or email here..."
class="input"
/>
<label class="label">Enter your password</label>
<input v-model="elybyPassword" type="password" placeholder="Your password here..." class="input" />
<input
v-model="elyByPassword"
type="password"
placeholder="Your password here..."
class="input"
/>
<div class="mt-6 ml-auto">
<Button icon-only color="primary" class="continue-button" @click="addElybyProfile()">
<Button
:disabled="elyByLoginDisabled"
icon-only
color="primary"
class="continue-button"
@click="addElyByProfile()"
>
Login
</Button>
</div>
@@ -100,7 +156,12 @@
<ModalWrapper ref="addOfflineModal" class="modal" header="Add new offline account">
<div class="flex flex-col gap-4 px-6 py-5">
<label class="label">Enter your player name</label>
<input v-model="offlinePlayerName" type="text" placeholder="Your player name here..." class="input" />
<input
v-model="offlinePlayerName"
type="text"
placeholder="Your player name here..."
class="input"
/>
<div class="mt-6 ml-auto">
<Button icon-only color="primary" class="continue-button" @click="addOfflineProfile()">
Login
@@ -108,21 +169,28 @@
</div>
</div>
</ModalWrapper>
<ModalWrapper ref="authenticationElybyErrorModal" class="modal"
header="Error while proceeding authentication event with Ely.by">
<ModalWrapper
ref="authenticationElyByErrorModal"
class="modal"
header="Error while proceeding authentication event with Ely.by"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="text-base font-medium text-red-700">
An error occurred while logging in.
</label>
<div class="mt-6 ml-auto">
<Button color="primary" class="retry-button" @click="retryAddElybyProfile">
<Button color="primary" class="retry-button" @click="retryAddElyByProfile">
Try again
</Button>
</div>
</div>
</ModalWrapper>
<ModalWrapper ref="inputElybyErrorModal" class="modal" header="Error while proceeding input event with Ely.by">
<ModalWrapper
ref="inputElyByErrorModal"
class="modal"
header="Error while proceeding input event with Ely.by"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="text-base font-medium text-red-700">
An error occurred while adding the Ely.by account. Please follow the instructions below.
@@ -134,13 +202,17 @@
</ul>
<div class="mt-6 ml-auto">
<Button color="primary" class="retry-button" @click="retryAddElybyProfile">
<Button color="primary" class="retry-button" @click="retryAddElyByProfile">
Try again
</Button>
</div>
</div>
</ModalWrapper>
<ModalWrapper ref="inputErrorModal" class="modal" header="Error while proceeding input event with offline account">
<ModalWrapper
ref="inputOfflineErrorModal"
class="modal"
header="Error while proceeding input event with offline account"
>
<div class="flex flex-col gap-4 px-6 py-5">
<label class="text-base font-medium text-red-700">
An error occurred while adding the offline account. Please follow the instructions below.
@@ -149,9 +221,10 @@
<ul class="list-disc list-inside text-sm space-y-1">
<li>Check that you have entered the correct player name.</li>
<li>
Player name must be at least {{ minOfflinePlayerNameLength }} characters long and no more than
{{ maxOfflinePlayerNameLength }} characters.
Player name must be at least {{ minOfflinePlayerNameLength }} characters long and no more
than {{ maxOfflinePlayerNameLength }} characters.
</li>
<li>Make sure your name meets the format requirement `{{ nameExp }}`</li>
</ul>
<div class="mt-6 ml-auto">
@@ -161,7 +234,7 @@
</div>
</div>
</ModalWrapper>
<ModalWrapper ref="exceptionErrorModal" class="modal" header="Unexpected error occurred">
<ModalWrapper ref="unexpectedErrorModal" class="modal" header="Unexpected error occurred">
<div class="modal-body">
<label class="label">An unexpected error has occurred. Please try again later.</label>
</div>
@@ -169,35 +242,32 @@
</template>
<script setup>
import {
DropdownIcon,
TrashIcon,
PirateIcon as Offline,
MicrosoftIcon as License,
ElyByIcon as Elyby,
MicrosoftIcon,
PirateIcon,
ElyByIcon,
SpinnerIcon
} from '@modrinth/assets'
import { Avatar, Button, Card, injectNotificationManager } from '@modrinth/ui'
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { trackEvent } from '@/helpers/analytics'
import {
elyby_auth_authenticate,
elyby_login,
get_default_user,
login as login_flow,
offline_login,
users,
remove_user,
set_default_user,
login as login_flow,
get_default_user,
users,
} from '@/helpers/auth'
import { trackEvent } from '@/helpers/analytics'
import { process_listener } from '@/helpers/events'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
import { get_available_skins } from '@/helpers/skins'
import { handleSevereError } from '@/store/error.js'
import {
DropdownIcon,
ElyByIcon,
MicrosoftIcon,
OfflineIcon,
SpinnerIcon,
TrashIcon,
} from '@modrinth/assets'
import { Avatar, Button, Card, injectNotificationManager } from '@modrinth/ui'
import { computed, onBeforeUnmount, onMounted, onUnmounted, ref } from 'vue'
const { handleError } = injectNotificationManager()
@@ -213,34 +283,36 @@ const emit = defineEmits(['change'])
const accounts = ref({})
const microsoftLoginDisabled = ref(false)
const elybyLoginDisabled = ref(false)
const elyByLoginDisabled = ref(false)
const defaultUser = ref()
// [AR] • Feature
const clientToken = "astralrinth"
const clientToken = 'astralrinth'
const addOfflineModal = ref(null)
const addElybyModal = ref(null)
const requestElybyTwoFactorCodeModal = ref(null)
const authenticationElybyErrorModal = ref(null)
const inputElybyErrorModal = ref(null)
const inputErrorModal = ref(null)
const exceptionErrorModal = ref(null)
const addElyByModal = ref(null)
const requestElyByTwoFactorCodeModal = ref(null)
const authenticationElyByErrorModal = ref(null)
const inputElyByErrorModal = ref(null)
const inputOfflineErrorModal = ref(null)
const unexpectedErrorModal = ref(null)
const offlinePlayerName = ref('')
const elybyLogin = ref('')
const elybyPassword = ref('')
const elybyTwoFactorCode = ref('')
const minOfflinePlayerNameLength = 2
const elyByLogin = ref('')
const elyByPassword = ref('')
const elyByTwoFactorCode = ref('')
const minOfflinePlayerNameLength = 3
const maxOfflinePlayerNameLength = 20
const nameExp = 'a-zA-Z0-9_'
const nameRegex = new RegExp(`^[${nameExp}]+$`)
// [AR] • Feature
function getAccountType(account) {
switch (account.account_type) {
case 'microsoft':
return License
return MicrosoftIcon
case 'pirate':
return Offline
return OfflineIcon
case 'elyby':
return Elyby
return ElyByIcon
}
}
@@ -250,30 +322,31 @@ function showOfflineLoginModal() {
}
// [AR] • Feature
function showElybyLoginModal() {
addElybyModal.value?.show()
function showElyByLoginModal() {
addElyByModal.value?.show()
}
// [AR] • Feature
function retryAddOfflineProfile() {
inputErrorModal.value?.hide()
inputOfflineErrorModal.value?.hide()
clearOfflineFields()
showOfflineLoginModal()
}
// [AR] • Feature
function retryAddElybyProfile() {
authenticationElybyErrorModal.value?.hide()
inputElybyErrorModal.value?.hide()
clearElybyFields()
showElybyLoginModal()
function retryAddElyByProfile() {
authenticationElyByErrorModal.value?.hide()
inputElyByErrorModal.value?.hide()
elyByLoginDisabled.value = false
clearElyByFields()
showElyByLoginModal()
}
// [AR] • Feature
function clearElybyFields() {
elybyLogin.value = ''
elybyPassword.value = ''
elybyTwoFactorCode.value = ''
function clearElyByFields() {
elyByLogin.value = ''
elyByPassword.value = ''
elyByTwoFactorCode.value = ''
}
// [AR] • Feature
@@ -284,11 +357,14 @@ function clearOfflineFields() {
// [AR] • Feature
async function addOfflineProfile() {
const name = offlinePlayerName.value.trim()
const isValidName = name.length >= minOfflinePlayerNameLength && name.length <= maxOfflinePlayerNameLength
const isValidName =
nameRegex.test(name) &&
name.length >= minOfflinePlayerNameLength &&
name.length <= maxOfflinePlayerNameLength
if (!isValidName) {
addOfflineModal.value?.hide()
inputErrorModal.value?.show()
inputOfflineErrorModal.value?.show()
clearOfflineFields()
return
}
@@ -302,39 +378,36 @@ async function addOfflineProfile() {
await setAccount(result)
await refreshValues()
} else {
exceptionErrorModal.value?.show()
unexpectedErrorModal.value?.show()
}
} catch (error) {
handleError(error)
exceptionErrorModal.value?.show()
unexpectedErrorModal.value?.show()
} finally {
clearOfflineFields()
}
}
// [AR] • Feature
async function addElybyProfile() {
if (!elybyLogin.value || !elybyPassword.value) {
addElybyModal.value?.hide()
inputElybyErrorModal.value?.show()
clearElybyFields()
async function addElyByProfile() {
elyByLoginDisabled.value = true
if (!elyByLogin.value || !elyByPassword.value) {
addElyByModal.value?.hide()
inputElyByErrorModal.value?.show()
clearElyByFields()
return
}
elybyLoginDisabled.value = true
const login = elybyLogin.value.trim()
let password = elybyPassword.value.trim()
const twoFactorCode = elybyTwoFactorCode.value.trim()
// Parse ely.by credential fields
const login = elyByLogin.value.trim()
let password = elyByPassword.value.trim()
const twoFactorCode = elyByTwoFactorCode.value.trim()
if (password && twoFactorCode) {
password = `${password}:${twoFactorCode}`
}
try {
const raw_result = await elyby_auth_authenticate(
login,
password,
clientToken
)
const raw_result = await elyby_auth_authenticate(login, password, clientToken)
const json_data = JSON.parse(raw_result)
@@ -346,13 +419,13 @@ async function addElybyProfile() {
json_data.error === 'ForbiddenOperationException' &&
json_data.errorMessage?.includes('two factor')
) {
requestElybyTwoFactorCodeModal.value?.show()
requestElyByTwoFactorCodeModal.value?.show()
return
}
addElybyModal.value?.hide()
requestElybyTwoFactorCodeModal.value?.hide()
authenticationElybyErrorModal.value?.show()
addElyByModal.value?.hide()
requestElyByTwoFactorCodeModal.value?.hide()
authenticationElyByErrorModal.value?.show()
return
}
@@ -362,18 +435,18 @@ async function addElybyProfile() {
const result = await elyby_login(selectedProfileId, selectedProfileName, accessToken)
addElybyModal.value?.hide()
requestElybyTwoFactorCodeModal.value?.hide()
addElyByModal.value?.hide()
requestElyByTwoFactorCodeModal.value?.hide()
clearElybyFields()
clearElyByFields()
await setAccount(result)
await refreshValues()
} catch (err) {
handleError(err)
exceptionErrorModal.value?.show()
unexpectedErrorModal.value?.show()
} finally {
elybyLoginDisabled.value = false
elyByLoginDisabled.value = false
}
}
@@ -543,7 +616,6 @@ onUnmounted(() => {
gap: 1rem;
}
.vector-icon {
width: 12px;
height: 12px;

View File

@@ -97,3 +97,8 @@ export async function warning_listener(callback) {
export async function friend_listener(callback) {
return await listen('friend', (event) => callback(event.payload))
}
// [AR] Payload for the 'info' event
export async function info_listener(callback) {
return await listen('info', (event) => callback(event.payload))
}

View File

@@ -5,7 +5,7 @@ use crate::event::{
};
#[cfg(feature = "tauri")]
use crate::event::{
LoadingPayload, ProcessPayload, ProfilePayload, WarningPayload,
LoadingPayload, ProcessPayload, ProfilePayload, WarningPayload, InfoPayload
};
use futures::prelude::*;
#[cfg(feature = "tauri")]
@@ -219,6 +219,26 @@ pub async fn emit_warning(message: &str) -> crate::Result<()> {
Ok(())
}
// This code is modified by AstralRinth
// emit_info(message)
pub async fn emit_info(message: &str) -> crate::Result<()> {
#[cfg(feature = "tauri")]
{
let event_state = crate::EventState::get()?;
event_state
.app
.emit(
"info",
InfoPayload {
message: message.to_string(),
},
)
.map_err(EventError::from)?;
}
tracing::info!("{}", message);
Ok(())
}
// emit_command(CommandPayload::Something { something })
// ie: installing a pack, opening an .mrpack, etc
// Generally used for url deep links and file opens that we want to handle in the frontend

View File

@@ -200,6 +200,13 @@ pub struct WarningPayload {
pub message: String,
}
// This code is modified by AstralRinth
#[derive(Serialize, Clone)]
#[cfg(feature = "tauri")]
pub struct InfoPayload {
pub message: String,
}
#[derive(Serialize, Clone)]
#[serde(tag = "event")]
pub enum CommandPayload {

View File

@@ -1,6 +1,6 @@
//! Logic for launching Minecraft
use crate::data::ModLoader;
use crate::event::emit::{emit_loading, init_or_edit_loading};
use crate::event::emit::{emit_loading, emit_info, init_or_edit_loading};
use crate::event::{LoadingBarId, LoadingBarType};
use crate::launcher::download::download_log_config;
use crate::launcher::io::IOError;
@@ -666,31 +666,35 @@ pub async fn launch_minecraft(
command.arg("--add-opens=jdk.internal/jdk.internal.misc=ALL-UNNAMED");
}
// [AR] Patch
// This code is modified by AstralRinth
if credentials.account_type == AccountType::Pirate.as_lowercase_str() {
if version_jar == "1.16.4" || version_jar == "1.16.5" {
let invalid_url = "https://invalid.invalid";
tracing::info!(
"[AR] • The launcher detected the launch of {} on the offline account. Applying offline multiplayer fixes.",
let _ = emit_info(&format!(
"[AR] • Detected launch of {} on the offline account. Applying 1.16.4/5 multiplayer fixes.",
version_jar
);
)
).await;
command.arg("-Dminecraft.api.env=custom");
command.arg(format!("-Dminecraft.api.auth.host={}", invalid_url));
command
.arg(format!("-Dminecraft.api.account.host={}", invalid_url));
command
.arg(format!("-Dminecraft.api.session.host={}", invalid_url));
command
.arg(format!("-Dminecraft.api.services.host={}", invalid_url));
command.arg(format!("-Dminecraft.api.account.host={}", invalid_url));
command.arg(format!("-Dminecraft.api.session.host={}", invalid_url));
command.arg(format!("-Dminecraft.api.services.host={}", invalid_url));
}
} else if credentials.account_type == AccountType::ElyBy.as_lowercase_str()
{
tracing::info!(
"[AR] • The launcher detected the launch of {} on the Ely.by account. Applying Ely.by Java Injector.",
let _ = emit_info(&format!(
"[AR] • Detected launch of {} on the Ely.by account. Loading Ely.by AuthLib Injector...",
version_jar
);
)
).await;
let path_buf = utils::get_or_download_elyby_injector().await?;
let path = path_buf.to_str().unwrap();
let _ = emit_info(&format!(
"[AR] • Launching minecraft instance with {}",
path
)
).await;
command.arg(format!("-javaagent:{}=ely.by", path));
}

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
width="800px"
height="800px"
viewBox="0 0 16 16"
version="1.1"
id="svg2"
sodipodi:docname="offline.svg"
inkscape:version="1.4.3 (0d15f75, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="0.2874782"
inkscape:cx="464.38304"
inkscape:cy="262.62861"
inkscape:window-width="1800"
inkscape:window-height="1102"
inkscape:window-x="0"
inkscape:window-y="39"
inkscape:window-maximized="1"
inkscape:current-layer="g2" />
<g
fill="#2e3436"
id="g2">
<path
d="m 8,1.992188 c -2.617188,0 -5.238281,0.933593 -7.195312,2.808593 L 0.308594,5.28125 C -0.0898438,5.660155 -0.101562,6.292969 0.277344,6.691406 0.660156,7.089844 1.292969,7.101562 1.691406,6.71875 l 0.5,-0.476562 c 3.085938,-2.953127 8.53125,-2.953127 11.617188,0 l 0.5,0.476562 c 0.398437,0.382812 1.03125,0.371094 1.414062,-0.027344 0.378906,-0.398437 0.367188,-1.031251 -0.03125,-1.410156 L 15.195312,4.80078 C 13.238281,2.925781 10.617188,1.992188 8,1.992188 Z M 7.96875,6 C 6.398438,6.011719 4.839844,6.628906 3.761719,7.8125 l -0.5,0.550781 c -0.375,0.40625 -0.347657,1.042969 0.0625,1.414063 0.410156,0.371095 1.042969,0.339845 1.414062,-0.070313 l 0.5,-0.542969 C 6.480469,7.800781 9.230469,7.671875 10.636719,9.035156 10.757812,9.011719 10.878906,9 11,9 c 0.53125,0 1.039062,0.210938 1.414062,0.585938 l 0.222657,0.222656 c 0.01172,-0.011719 0.02344,-0.019532 0.03906,-0.03125 0.40625,-0.371094 0.4375,-1.007813 0.0625,-1.414063 l -0.5,-0.550781 C 11.113279,6.582031 9.535154,5.988281 7.968748,6 Z M 8,10.000001 c -0.511719,0 -1.023438,0.195312 -1.414062,0.585938 -0.78125,0.78125 -0.78125,2.046874 0,2.828124 0.78125,0.78125 2.046874,0.78125 2.828124,0 C 9.625,13.203126 9.773438,12.960939 9.871094,12.69922 L 9.585938,12.414063 C 9.03125,11.859376 8.878906,11.046876 9.117188,10.343751 8.78125,10.117189 8.390625,10.000001 8,10.000001 Z m 0,0"
fill-opacity="0.34902"
id="path1"
style="fill:#00ff00" />
<path
d="m 11 10 c -0.265625 0 -0.519531 0.105469 -0.707031 0.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 l 1.292969 1.292969 l -1.292969 1.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 s 1.023437 0.390625 1.414062 0 l 1.292969 -1.292969 l 1.292969 1.292969 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 s 0.390625 -1.023437 0 -1.414062 l -1.292969 -1.292969 l 1.292969 -1.292969 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 s -0.519531 0.105469 -0.707031 0.292969 l -1.292969 1.292969 l -1.292969 -1.292969 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 0"
id="path2"
style="fill:#800000" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<svg height="800px" width="800px" version="1.1" id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 511.672 511.672" xml:space="preserve">
<path style="fill:#ED5564;" d="M227.674,44.901c0,0,0.047-0.031,0.141-0.109c-0.031,0.031-3.342,2.437-9.088,3.514
c-7.745,1.437-16.208-0.109-25.14-4.591c-31.386-15.771-68.175-0.968-69.721-0.344l0.016,0.062c-3.88,1.593-6.621,5.403-6.621,9.869
c0,5.887,4.771,10.649,10.657,10.649c1.694,0,3.295-0.406,4.716-1.109c4.466-1.624,30.816-10.416,51.381-0.078
c10.954,5.497,20.706,7.371,28.919,7.371c17.028,0,27.42-8.073,28.044-8.573L227.674,44.901z"/>
<g>
<path style="fill:#7F4545;" d="M234.514,31.973c-5.887,0-10.657,4.778-10.657,10.665v351.704h21.322V42.638
C245.179,36.751,240.401,31.973,234.514,31.973z"/>
<path style="fill:#7F4545;" d="M511.672,319.655c0-5.887-4.777-10.665-10.648-10.665c-1.031,0-2.016,0.156-2.951,0.422l0,0
l-0.234,0.062l0,0l-108.213,31.073l5.871,20.487l108.463-31.137l0,0C508.408,328.618,511.672,324.512,511.672,319.655z"/>
</g>
<path style="fill:#A85D5D;" d="M10.689,308.99l99.725,33.385c0,0,39.116,41.239,124.1,41.239c85,0,106.611-29.138,106.611-29.138
l85.258-24.484c9.588,160.21-122.656,149.561-122.656,149.561H115.294c-86.171-5.996-73.633-88.568-73.633-88.568l-13.187-9.728
l-4.208-18.021L0,351.635L10.689,308.99z"/>
<path style="fill:#965353;" d="M426.664,335.317c-5.871,132.337-122.938,122.905-122.938,122.905H115.294
c-57.409-3.981-71.001-41.973-73.68-66.879c-0.765,5.84-9.205,82.432,73.68,88.209h188.433
C303.727,479.553,433.004,489.968,426.664,335.317z"/>
<g>
<path style="fill:#434A54;" d="M277.166,415.594c0,5.887,4.763,10.649,10.649,10.649c5.888,0,10.649-4.763,10.649-10.649
s-4.762-10.665-10.649-10.665C281.929,404.929,277.166,409.707,277.166,415.594z"/>
<path style="fill:#434A54;" d="M234.514,415.594c0,5.887,4.778,10.649,10.665,10.649s10.657-4.763,10.657-10.649
s-4.77-10.665-10.657-10.665S234.514,409.707,234.514,415.594z"/>
<path style="fill:#434A54;" d="M191.877,415.594c0,5.887,4.771,10.649,10.657,10.649s10.665-4.763,10.665-10.649
s-4.778-10.665-10.665-10.665S191.877,409.707,191.877,415.594z"/>
<path style="fill:#434A54;" d="M149.24,415.594c0,5.887,4.771,10.649,10.657,10.649s10.657-4.763,10.657-10.649
s-4.771-10.665-10.657-10.665S149.24,409.707,149.24,415.594z"/>
<path style="fill:#434A54;" d="M99.569,330.305C114.942,207.719,74.616,95.869,74.616,95.869h260.169
c80.105,93.783,24.953,234.561,24.953,234.561C262.832,285.849,99.569,330.305,99.569,330.305z"/>
</g>
<g style="opacity:0.1;">
<path style="fill:#FFFFFF;" d="M334.785,95.869h-21.314c69.206,81.026,37.445,197.147,27.529,227.222
c6.434,2.123,12.695,4.56,18.738,7.339C359.738,330.43,414.891,189.652,334.785,95.869z"/>
</g>
<path style="fill:#E6E9ED;" d="M170.555,196.477c0-35.321,28.638-63.959,63.959-63.959c35.329,0,63.951,28.638,63.951,63.959
c0,18.941-8.213,35.961-21.299,47.672v26.952h-85.289v-26.952C178.792,232.438,170.555,215.418,170.555,196.477z"/>
<g>
<path style="fill:#434A54;" d="M250.503,196.477c0,5.887,4.778,10.665,10.665,10.665c5.888,0,10.658-4.778,10.658-10.665
s-4.771-10.665-10.658-10.665C255.282,185.812,250.503,190.59,250.503,196.477z"/>
<path style="fill:#434A54;" d="M197.21,196.477c0,5.887,4.771,10.665,10.657,10.665s10.657-4.778,10.657-10.665
s-4.771-10.665-10.657-10.665S197.21,190.59,197.21,196.477z"/>
</g>
<g>
<path style="fill:#CCD1D9;" d="M277.166,271.085c-0.016-5.871-4.777-10.649-10.673-10.649c-5.887,0-10.657,4.778-10.657,10.665
h21.33V271.085z"/>
<path style="fill:#CCD1D9;" d="M255.836,271.085c0-5.871-4.77-10.649-10.657-10.649s-10.665,4.778-10.665,10.665h21.322V271.085z" />
<path style="fill:#CCD1D9;" d="M234.514,271.085c0-5.871-4.771-10.649-10.657-10.649s-10.657,4.778-10.657,10.665h21.314V271.085z" />
<path style="fill:#CCD1D9;" d="M213.199,271.085c-0.008-5.871-4.778-10.649-10.665-10.649s-10.657,4.778-10.657,10.665h21.322
L213.199,271.085L213.199,271.085z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="10mm" height="10mm" viewBox="0 0 10 10" version="1.1" id="svg26662" inkscape:version="1.2.2 (732a01da63, 2022-12-09)" sodipodi:docname="pir.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview id="namedview26664" pagecolor="#505050" bordercolor="#eeeeee" borderopacity="1" inkscape:showpageshadow="0" inkscape:pageopacity="0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#505050" inkscape:document-units="mm" showgrid="false" inkscape:zoom="10.35098" inkscape:cx="16.375261" inkscape:cy="42.073312" inkscape:window-width="1488" inkscape:window-height="1230" inkscape:window-x="2794" inkscape:window-y="123" inkscape:window-maximized="0" inkscape:current-layer="layer1" />
<defs id="defs26659" />
<g inkscape:label="Слой 1" inkscape:groupmode="layer" id="layer1">
<path id="path26647" style="fill:#e7f9fb;fill-opacity:1;stroke:none;stroke-width:0.734686;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:5.8;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" d="M 0.953646,0 C 0.4245958,0 0,0.42377 0,0.950056 V 9.051658 C 0,9.577943 0.4245958,9.9999995 0.953646,9.9999995 H 9.044545 C 9.573595,9.9999995 10,9.577943 10,9.051658 V 0.950056 C 10,0.42377 9.573595,0 9.044545,0 Z m 4.0319653,0.680202 c 0.7122257,0 1.1971907,0.171336 1.6235677,0.587681 C 7.149602,1.795597 7.303455,2.529484 7.076165,3.503527 6.954393,4.024672 6.743646,4.411034 6.384675,4.767983 6.046182,5.105514 5.7597,5.274565 5.369942,5.364516 4.7470347,5.510152 4.177518,5.313116 3.618915,4.763985 3.260174,4.411034 3.0504322,4.028385 2.9274247,3.503527 2.6985267,2.5272 2.8504547,1.797596 3.392573,1.267883 3.8051351,0.866387 4.2970505,0.680202 4.9856113,0.680202 Z M 4.1253339,2.785916 C 3.7727965,2.786202 3.5578276,2.980097 3.5578276,3.29821 c 0,0.197035 0.074385,0.320683 0.2711164,0.455467 C 4.0618628,3.91359 4.4444125,3.833637 4.5886441,3.596619 4.6788251,3.450984 4.6839941,3.154002 4.6001321,3.01265 4.5082281,2.855593 4.3583101,2.784203 4.1277751,2.784203 Z m 1.7295441,0 c -0.20506,0 -0.404923,0.09423 -0.493868,0.26557 C 5.226026,3.311345 5.34091,3.641452 5.60714,3.779948 5.859588,3.90845 6.185962,3.822778 6.372268,3.574345 6.463308,3.45441 6.469338,3.164568 6.383758,3.033211 6.273759,2.864731 6.062581,2.784774 5.85752,2.784774 Z M 1.8659927,5.307119 c 0.00862,-5.71e-4 0.020104,0 0.03073,0 0.2179844,2.86e-4 0.5876389,0.16848 1.6846262,0.695051 C 4.3488321,6.369399 4.9972712,6.669808 5.018122,6.669808 5.038222,6.669237 5.68049,6.371113 6.440564,6.008738 7.200522,5.64465 7.88377,5.323396 7.958155,5.323396 8.14742,5.283416 8.403142,5.409066 8.509492,5.577544 8.663431,5.82598 8.604552,6.167795 8.374795,6.361404 8.316205,6.409954 6.898963,7.091579 5.226428,7.875439 2.6791977,9.069933 2.1554033,9.312944 1.9972712,9.312944 c -0.2153996,0 -0.2679571,0 -0.3915391,-0.114223 C 1.3150575,8.936006 1.3506989,8.509952 1.6827021,8.264656 1.7519171,8.213256 2.1996325,7.990519 2.6777048,7.764356 3.1557197,7.54162 3.5582872,7.334304 3.5756915,7.334304 c 0.01436,0 -0.3826933,-0.217025 -0.8872167,-0.448042 C 2.1839513,6.654959 1.7142365,6.421657 1.646802,6.369971 1.4819495,6.24718 1.4026824,6.080128 1.4026824,5.863103 c 0,-0.219881 0.09535,-0.394643 0.2731268,-0.491448 0.063758,-0.03141 0.1203366,-0.05711 0.1901261,-0.06282 z M 7.094115,7.62329 7.661622,7.905994 c 0.784456,0.383506 0.930354,0.522573 0.930354,0.881807 0,0.219881 -0.105403,0.397498 -0.280307,0.480311 -0.151641,0.06568 -0.331859,0.06853 -0.513628,0 C 7.59815,9.193862 5.819639,8.388875 5.788334,8.354036 c -0.01436,0 0.273414,-0.182758 0.639363,-0.378651 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -118,14 +118,12 @@ export const VisaIcon = _VisaIcon
export const MinecraftServerIcon = _MinecraftServerIcon
// [AR] Styles
import _PirateIcon from './icons/pirate.svg?component'
import _MicrosoftIcon from './icons/microsoft.svg?component'
import _PirateShipIcon from './icons/pirate-ship.svg?component'
import _AstralRinthLogo from './icons/astralrinth-logo.svg?component'
import _ElyByIcon from './icons/elyby-icon.svg?component'
export const PirateIcon = _PirateIcon
import _MicrosoftIcon from './icons/microsoft.svg?component'
import _OfflineIcon from './icons/offline.svg?component'
export const OfflineIcon = _OfflineIcon
export const MicrosoftIcon = _MicrosoftIcon
export const PirateShipIcon = _PirateShipIcon
export const AstralRinthLogo = _AstralRinthLogo
export const ElyByIcon = _ElyByIcon