Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const window = {
};

export const api = {
ws: 'ws://127.0.0.1:1370/ws',
grpc: 'http://127.0.0.1:1371',
web: 'http://127.0.0.1:1370',
publicKey,
};
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/semver": "^7.5.8",
"@types/ws": "^8.5.11",
"@typescript-eslint/eslint-plugin": "^7.17.0",
"@typescript-eslint/parser": "^7.17.0",
"cross-env": "^7.0.3",
Expand All @@ -57,8 +56,8 @@
"yaml": "^2.5.0"
},
"dependencies": {
"@aurora-launcher/api": "^0.4.0",
"@aurora-launcher/core": "^0.23.0",
"@aurora-launcher/proto": "^0.1.0",
"@aurora-launcher/core": "^0.24.0",
"@freshgum/typedi": "^0.7.2",
"@xhayper/discord-rpc": "^1.1.4",
"bufferutil": "^4.0.8",
Expand All @@ -67,6 +66,7 @@
"electron-store": "^10.0.0",
"electron-updater": "^6.3.9",
"minestat-es": "^2.1.0",
"nice-grpc": "^2.1.9",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.25.1",
Expand Down
24 changes: 12 additions & 12 deletions public.pem
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA419gbQ3vU7GUwpmfwKVS
zN74Im+PlCzQHpxv5DXti1mZzyIxX/v8O3CcOMf9H/wFJY7PTT1AwDUOni7IBOob
W6hd4uqSe9t3gtlbxeIwG7OvyxKuoFbE/MzvhqFXjwHH/ktQ90x7GgFJuIvVZm62
aLodDL+4uLblsA02WnS3jLa7qMxA/HyKscEUhCell7xkaWBHmhN8mO4OjC/RYxNm
QfpbZXfJQ1QyTnN3ADEv3yVba1n5I3jKXpSNajvvQYxLNmAJ2IcRgbYrIQUywsyB
nzpn0OXBOGtWSFsszzSZC3jPegIGSTytGT+8VAPCsXRX44iIxFTTq7C3bfscAthK
I9O97ZNmITIJjIYWjj8g7j/rmdbm4v/uSGUoIwOphZUVcB5oRRyVQkuGs46ewJUU
fJTQpmI0m0o+0ciCfcwVbD9AF0y9kNoGLnEVsF4EZC9vOMZwSTbKJ9gInyfW38CW
zbISitGvF8jAFln4czsn6XA0dW6D058dPnS3jre0b9bySWSIxNJvGA5rYzoMSCKm
tLpCBzWi6m0Y0wZcPf7CxzPxcMu+rMz2Sv3ipgbpc/3qNde4QQV8/ahPGfQt0Y9t
g0xbZJdE/Fuurys2ENUU6Mn7D0HsopW1PlOmX19RGTOjlUh5sAsoIvF190iJ1AvJ
0sM2T80SWgTVJos2BGzQd6cCAwEAAQ==
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvSAz+5fnRI5T33QskbLn
PKI8N4WO8Go++VrIilP623jspLZh1ewnGtjRQAN2/5Dw0zZ7649zobQxwwq4lWoV
tYPK8i/Oi8JTJKa/Nr0ClJQjKx1vbQa7CyeV/yZY33ng7X6hSwgw2uxBHiosun/v
EJizF57f6z63ACWHEOJ25ANMZ4/IX0ge8Gv3Ij1qPHif4j/5zYuFkIoaxPW8brEO
+grIkMA7vn91R9jW7bifQROKmuo7cgURt6sM5F/2H9cT+QWxjb0Twqb4dkHa7XHn
A53RZNM+EXpwAfNW+Dl91NLyhLdwzldFGLfCw3cVFxJVdyF6MurQMmsRyL30tnly
BKC1ItZ9KrLC1ga5Jv1Q81d3bIr6lwJ0iBiuyKiua0ob6EUy7bl02xaYqAsVx6qL
JBYqy9BNzE5iqomp3hL9lgy2MkvnqEACvGFs+R7vz5KAoPMutieP1fWR1hX2swam
Ye68qRKiOW32nJ6qJiXmlUXMG030rUkZc8Q8Vxlbl3vtJ1EvtIG3NuBYGEa08ck9
3Q9eTk4/UgFSY4Qefuui8Ee/TUFnoPr9ZygExZLNuTJBJpxv52ER43H1LqdMbZyo
etaZW1ERxAJEiuu7NkSU0ZOZT28FA7uV/t7vnoQLnKW7IxfYq1fMRmbnTH/0ctpG
99LxVYxGtKWSLUU+DCJlFEECAwEAAQ==
-----END PUBLIC KEY-----
88 changes: 62 additions & 26 deletions src/main/api/APIManager.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,82 @@
import { AuroraAPI } from '@aurora-launcher/api';
import * as proto from "@aurora-launcher/proto";
import { createChannel, createClient, Metadata, Status, ClientError } from 'nice-grpc';
import { api as apiConfig } from '@config';
import { Service } from '@freshgum/typedi';

import { publicDecrypt, publicEncrypt } from 'crypto';
import { LogHelper } from '../helpers/LogHelper';

@Service([])
export class APIManager {
private api = new AuroraAPI(apiConfig.ws || 'ws://localhost:1370', {
onClose: () => setTimeout(() => this.initConnection(), 2000),
});
private client = createClient(
proto.AuroraLauncherServiceDefinition,
createChannel(apiConfig.grpc),
);
private token = '0';

public async initConnection() {
const tokenOrig = (await this.client.getToken({})).token;
const { publicKey } = apiConfig;
if (!publicKey) {
LogHelper.fatal('Verify public key required');
}

async initConnection() {
try {
await this.api.connect();
this.#onConnectListeners.forEach((listener) => listener());
} catch (error) {
const decryptedToken = publicDecrypt(
publicKey,
Buffer.from(tokenOrig, 'hex'),
);
this.token = publicEncrypt(publicKey, decryptedToken).toString('hex');
}
catch(error) {
LogHelper.error(error);
}
}

#onConnectListeners: (() => void)[] = [];
onConnect(listener: () => void) {
this.#onConnectListeners.push(listener);
}

public auth(login: string, password: string) {
return this.api.auth(login, password);
}

public getServers() {
return this.api.getServers();
public async auth(login: string, password: string) {
try {
return await this.client.auth({login, password}, {metadata: Metadata({Authorization: this.token})});
} catch(error) {
if (error instanceof ClientError && error.code == Status.UNAUTHENTICATED) {
await this.initConnection();
return await this.client.auth({login, password}, {metadata: Metadata({Authorization: this.token})});
}
throw error;
}
}

public getProfile(uuid: string) {
return this.api.getProfile(uuid);
public async getServers() {
try {
return await this.client.getServers({}, {metadata: Metadata({Authorization: this.token})});
} catch(error) {
if (error instanceof ClientError && error.code == Status.UNAUTHENTICATED) {
await this.initConnection();
return await this.client.getServers({}, {metadata: Metadata({Authorization: this.token})});
}
throw error;
}
}

public getUpdates(dir: string) {
return this.api.getUpdates(dir);
public async getProfile(uuid: string) {
try {
return await this.client.getProfile({uuid}, {metadata: Metadata({Authorization: this.token})});
} catch(error) {
if (error instanceof ClientError && error.code == Status.UNAUTHENTICATED) {
await this.initConnection();
return await this.client.getProfile({uuid}, {metadata: Metadata({Authorization: this.token})});
}
throw error;
}
}

public verify(stage: number, token?: string) {
return this.api.verify(stage, token);
public async getUpdates(dir: string) {
try {
return await this.client.getUpdates({dir}, {metadata: Metadata({Authorization: this.token})});
} catch(error) {
if (error instanceof ClientError && error.code == Status.UNAUTHENTICATED) {
await this.initConnection();
return await this.client.getUpdates({dir}, {metadata: Metadata({Authorization: this.token})});
}
throw error;
}
}
}
41 changes: 0 additions & 41 deletions src/main/api/VerifyService.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/main/core/DiscordRPC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ export class DiscordRPC implements IHandleable {
const server = this.gameService.getServer();

if (!userArgs) throw new Error('Auth requierd');
if (!server) throw new Error('No information about the server');
if (!server?.serverInfo) throw new Error('No information about the server');

const total = text
.replace('{nickname}', userArgs.username)
.replace('{server}', server.title);
.replace('{server}', server.serverInfo?.title);
return total;
}

Expand Down
6 changes: 1 addition & 5 deletions src/main/core/Launcher.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Service } from '@freshgum/typedi';

import { APIManager } from '../api/APIManager';
import { VerifyService } from '../api/VerifyService';
import { LogHelper } from '../helpers/LogHelper';
import { StorageHelper } from '../helpers/StorageHelper';
import { LoginScene } from '../scenes/Login';
Expand All @@ -15,7 +14,6 @@ import { LauncherWindow } from './LauncherWindow';
LauncherWindow,
APIManager,
DiscordRPC,
VerifyService,
LoginScene,
ServersListScene,
ServerPanelScene,
Expand All @@ -26,7 +24,6 @@ export class Launcher {
private window: LauncherWindow,
private apiManager: APIManager,
private discordRPC: DiscordRPC,
private verifyService: VerifyService,

private loginScene: LoginScene,
private serversListScene: ServersListScene,
Expand All @@ -39,15 +36,14 @@ export class Launcher {
async init() {
StorageHelper.createMissing();

await this.apiManager.initConnection();
this.apiManager.initConnection();

this.loginScene.initHandlers();
this.settingsScene.initHandlers();
this.serversListScene.initHandlers();
this.serverPanelScene.initHandlers();
this.discordRPC.initHandlers();

this.verifyService.init();
this.window.createWindow();
LogHelper.info('Launcher started');
this.discordRPC.start();
Expand Down
19 changes: 5 additions & 14 deletions src/main/game/Starter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,22 +191,13 @@ export class Starter {

if (settings.autoConnect) {
if (gte(clientVersion, '1.20.0')) {
if ('hostname' in server)
gameArgs.push(
'--quickPlayMultiplayer',
server.hostname,
);
else
gameArgs.push(
'--quickPlayMultiplayer',
`${server.ip}:${server.port}`,
);
if (server.serverInfo?.hostname !== undefined) gameArgs.push('--quickPlayMultiplayer', server.serverInfo.hostname);
else gameArgs.push('--quickPlayMultiplayer', server.serverInfo.ip + ':' + server.serverInfo.port.toString());
} else {
if ('hostname' in server)
gameArgs.push('--server', server.hostname);
if (server.serverInfo?.hostname !== undefined) gameArgs.push('--server', server.serverInfo.hostname);
else {
gameArgs.push('--server', server.ip);
gameArgs.push('--port', server.port.toString());
gameArgs.push('--server', server.serverInfo.ip);
gameArgs.push('--port', server.serverInfo.port.toString());
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/game/Updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export class Updater {
async validateGameFiles(clientArgs: Profile): Promise<HashedFile[]> {
this.gameWindow.sendToConsole('Load client files');

const hashes = await this.api.getUpdates(clientArgs.clientDir);
const hashes = (await this.api.getUpdates(clientArgs.clientDir)).hashedFile;
if (!hashes) throw new Error('Client not found');

hashes.sort((a, b) => b.size - a.size);
Expand Down
6 changes: 3 additions & 3 deletions src/main/scenes/ServersList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ export class ServersListScene implements IHandleable {
}

async pingServer(server: Server) {
if ('hostname' in server) {
if (server.serverInfo?.hostname) {
return fetchServerInfo({
hostname: `_minecraft._tcp.${server.hostname}`,
hostname: `_minecraft._tcp.${server.serverInfo.hostname}`,
});
}
return fetchServerInfo({ address: server.ip, port: server.port });
return fetchServerInfo({ address: server.serverInfo.ip, port: server.serverInfo.port });
}
}
3 changes: 2 additions & 1 deletion src/preload/components/ServersListScene.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Server } from '@aurora-launcher/core';
import { ServersResponse } from '@aurora-launcher/proto';
import { ipcRenderer } from 'electron';
import { ServerInfo } from 'minestat-es';

import { EVENTS } from '../../common/channels';

export default class ServersListScene {
static getServers(): Promise<Server[]> {
static getServers(): Promise<ServersResponse> {
return ipcRenderer.invoke(EVENTS.SCENES.SERVERS_LIST.GET_SERVERS);
}

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/runtime/components/ServerButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function ServerButton({ onClick, server }: ServerButtonProps) {

return (
<button className={classes.button} onClick={onClick}>
<span className={classes.title}>{server.title}</span>
<span className={classes.title}>{server.serverInfo?.title}</span>
<span className={classes.online}>
{online} / {max}
</span>
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/runtime/scenes/ServerPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default function ServerPanel() {
return (
<div className={classes.window}>
<div className={classes.info}>
<div className={classes.title}>{selectedServer?.title}</div>
<div className={classes.title}>{selectedServer?.serverInfo?.title}</div>
<div className={classes.status}>
<div className={classes.gamers}>
Игроков
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/runtime/scenes/ServersList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Server } from '@aurora-launcher/core';
import { Server } from '@aurora-launcher/proto';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

Expand All @@ -23,7 +23,7 @@ export default function ServersList() {
showTitlebarLogoutBtn();
showTitlebarSettingsBtn();
resetTitlebarTitleText();
launcherAPI.scenes.serversList.getServers().then(setServers);
launcherAPI.scenes.serversList.getServers().then(servers => setServers(servers.servers));
launcherAPI.rpc.updateActivity('default');
}, []);

Expand Down
9 changes: 5 additions & 4 deletions upload-release.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { request } from 'undici'
import { request, FormData } from 'undici'
import { parse } from 'yaml'
import { api, window } from './config'
import { readFileSync, readdirSync } from 'fs'
import { readFileSync, readdirSync, openAsBlob } from 'fs'
import { basename, join } from 'path'
import { publicDecrypt, publicEncrypt } from 'crypto';
import { build } from 'electron-builder';
Expand All @@ -24,15 +24,16 @@ console.info('Uploading versions completed!!!')


async function upload(path:string){
const formData = new FormData()
formData.set(basename(path), await openAsBlob(path))

const {
statusCode,
body
} = await request(new URL (`/release/upload?encryptedToken=${publicEncrypt(api.publicKey, globalToken).toString("hex")}` , api.web),
{
method: 'POST',
body: readFileSync(path),
headers: ['content-disposition', basename(path), 'content-type', 'buffer']
body: formData,
}
)

Expand Down