Skip to content

Commit bc99ba5

Browse files
committed
feat: New ingame overlay
1 parent d47cec4 commit bc99ba5

File tree

19 files changed

+1515
-107
lines changed

19 files changed

+1515
-107
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
**/static/**/*
22

33
packages/server/assets/homepage.js
4+
packages/server/assets/ingame.js
45
packages/server/assets/vue.js

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ config.ini
99
tosu.exe
1010
_version.js
1111
**/tosu/gameOverlay/
12+
**/tosu/game-overlay/
1213
logs/
1314
settings/

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Features
4646
- [x] All _**Gamemodes**_ are supported
4747
- [x] Gosumemory _**compatible**_ api
4848
- [X] Brand _**new api**_ for websocket
49-
- [x] _**In-game**_ overlay (based on gosumemory closed overlay injection)
49+
- [x] _**In-game**_ overlay, allow adding multiple overlays (pp counters)
5050
- [x] _**Available**_ websocket data:
5151
- Settings
5252
- Gameplay data
@@ -67,8 +67,8 @@ Features
6767

6868
In-game overlay
6969
---
70-
- To enable it, you need to edit `tosu.env`, and turn on `ENABLE_GOSU_OVERLAY=true` (make it equal `true`)
71-
- Tutorial: [link](https://github.com/tosuapp/tosu/wiki/How-to-enable-ingame-overlay)
70+
- To enable it, you need to edit `tosu.env`, and turn on `ENABLE_INGAME_OVERLAY=true` (make it equal `true`)
71+
- Tutorial: TBA
7272
---
7373

7474

packages/common/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ export * from './utils/config';
77
export * from './utils/unzip';
88
export * from './utils/directories';
99
export * from './utils/json';
10-
export * from './utils/gosu';
10+
export * from './utils/ingame';
1111
export * from './utils/countryCodes';

packages/common/utils/config.ts

+22-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import fs from 'fs';
33
import path from 'path';
44

55
import { getProgramPath } from './directories';
6-
import { checkGameOverlayConfig } from './gosu';
6+
import { checkGameOverlayConfig } from './ingame';
77
import { wLogger } from './logger';
88

99
const configPath = path.join(getProgramPath(), 'tsosu.env');
@@ -34,8 +34,8 @@ PRECISE_DATA_POLL_RATE=100
3434
# Shows !mp commands (messages starting with '!mp') in tournament manager chat (hidden by default)
3535
SHOW_MP_COMMANDS=false
3636
37-
# Enables/disables the in-game gosumemory overlay (!!!I AM NOT RESPONSIBLE FOR USING IT!!!).
38-
ENABLE_GOSU_OVERLAY=false
37+
# Enables/disables the in-game overlay (!!!I AM NOT RESPONSIBLE FOR USING IT!!!).
38+
ENABLE_INGAME_OVERLAY=false
3939
4040
# WARNING: EVERYTHING BELOW IS NOT TO BE TOUCHED UNNECESSARILY.
4141
@@ -77,6 +77,7 @@ export const config = {
7777
serverPort: Number(process.env.SERVER_PORT || '24050'),
7878
staticFolderPath: process.env.STATIC_FOLDER_PATH || './static',
7979
enableGosuOverlay: (process.env.ENABLE_GOSU_OVERLAY || '') === 'true',
80+
enableIngameOverlay: (process.env.ENABLE_INGAME_OVERLAY || '') === 'true',
8081
allowedIPs: process.env.ALLOWED_IPS || '',
8182
timestamp: 0,
8283
currentVersion: '',
@@ -132,9 +133,9 @@ export const updateConfigFile = () => {
132133
fs.appendFileSync(configPath, '\nSTATIC_FOLDER_PATH=./static', 'utf8');
133134
}
134135

135-
if (!process.env.ENABLE_GOSU_OVERLAY) {
136-
newOptions += 'ENABLE_GOSU_OVERLAY, ';
137-
fs.appendFileSync(configPath, '\nENABLE_GOSU_OVERLAY=false', 'utf8');
136+
if (!process.env.ENABLE_INGAME_OVERLAY) {
137+
newOptions += 'ENABLE_INGAME_OVERLAY, ';
138+
fs.appendFileSync(configPath, '\nENABLE_INGAME_OVERLAY=false', 'utf8');
138139
}
139140

140141
if (!process.env.ENABLE_AUTOUPDATE) {
@@ -204,7 +205,8 @@ export const refreshConfig = (httpServer: any, refresh: boolean) => {
204205
}
205206

206207
const enableAutoUpdate = (parsed.ENABLE_AUTOUPDATE || '') === 'true';
207-
const openDashboardOnStartup = (parsed.OPEN_DASHBOARD || '') === 'true';
208+
const openDashboardOnStartup =
209+
(parsed.OPEN_DASHBOARD_ON_STARTUP || '') === 'true';
208210
const debugLogging = (parsed.DEBUG_LOG || '') === 'true';
209211
const serverIP = parsed.SERVER_IP || '127.0.0.1';
210212
const serverPort = Number(parsed.SERVER_PORT || '24050');
@@ -217,6 +219,7 @@ export const refreshConfig = (httpServer: any, refresh: boolean) => {
217219
const showMpCommands = (parsed.SHOW_MP_COMMANDS || '') === 'true';
218220
const staticFolderPath = parsed.STATIC_FOLDER_PATH || './static';
219221
const enableGosuOverlay = (parsed.ENABLE_GOSU_OVERLAY || '') === 'true';
222+
const enableIngameOverlay = (parsed.ENABLE_INGAME_OVERLAY || '') === 'true';
220223
const allowedIPs = parsed.ALLOWED_IPS || '';
221224

222225
// determine whether config actually was updated or not
@@ -230,7 +233,7 @@ export const refreshConfig = (httpServer: any, refresh: boolean) => {
230233
config.preciseDataPollRate !== preciseDataPollRate ||
231234
config.showMpCommands !== showMpCommands ||
232235
config.staticFolderPath !== staticFolderPath ||
233-
config.enableGosuOverlay !== enableGosuOverlay ||
236+
config.enableIngameOverlay !== enableIngameOverlay ||
234237
config.serverIP !== serverIP ||
235238
config.serverPort !== serverPort ||
236239
config.allowedIPs !== allowedIPs;
@@ -259,13 +262,21 @@ export const refreshConfig = (httpServer: any, refresh: boolean) => {
259262
);
260263
if (
261264
osuInstances.length === 1 &&
262-
enableGosuOverlay === true &&
265+
enableIngameOverlay === true &&
263266
updated === true
264267
) {
265268
osuInstances[0].injectGameOverlay();
266269
}
267270

268-
config.enableGosuOverlay = enableGosuOverlay;
271+
if (enableGosuOverlay === true) {
272+
wLogger.warn(
273+
'\n\n\n',
274+
'Gosu Ingame-overlay removed, please use new one, you can https://osuck.link/tosu-ingame',
275+
'\n\n\n'
276+
);
277+
}
278+
279+
config.enableIngameOverlay = enableIngameOverlay;
269280

270281
config.enableAutoUpdate = enableAutoUpdate;
271282
config.openDashboardOnStartup = openDashboardOnStartup;
@@ -292,7 +303,7 @@ export const writeConfig = (httpServer: any, options: any) => {
292303
text += `CALCULATE_PP=${options.CALCULATE_PP ?? config.calculatePP}\n\n`;
293304
text += `ENABLE_AUTOUPDATE=${options.ENABLE_AUTOUPDATE ?? config.enableAutoUpdate}\n`;
294305
text += `OPEN_DASHBOARD_ON_STARTUP=${options.OPEN_DASHBOARD_ON_STARTUP ?? config.openDashboardOnStartup}\n\n`;
295-
text += `ENABLE_GOSU_OVERLAY=${options.ENABLE_GOSU_OVERLAY ?? config.enableGosuOverlay}\n`;
306+
text += `ENABLE_INGAME_OVERLAY=${options.ENABLE_INGAME_OVERLAY ?? config.enableIngameOverlay}\n`;
296307
text += `ENABLE_KEY_OVERLAY=${options.ENABLE_KEY_OVERLAY ?? config.enableKeyOverlay}\n\n`;
297308
text += `ALLOWED_IPS=${options.ALLOWED_IPS ?? config.allowedIPs}\n\n`;
298309
text += `POLL_RATE=${options.POLL_RATE ?? config.pollRate}\n`;

packages/common/utils/gosu.ts

-21
This file was deleted.

packages/common/utils/ingame.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import fs from 'fs';
2+
3+
import { getSettingsPath } from './directories';
4+
5+
export const checkGameOverlayConfig = () => {
6+
const newestConfigPath = getSettingsPath('__ingame__');
7+
if (fs.existsSync(newestConfigPath)) return;
8+
9+
fs.writeFileSync(newestConfigPath, '{}', 'utf8');
10+
};

packages/game-overlay/src/index.ts

+17-39
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,73 @@
11
import {
22
checkGameOverlayConfig,
3+
config,
34
downloadFile,
45
getProgramPath,
56
unzip,
67
wLogger
78
} from '@tosu/common';
89
import { execFile } from 'node:child_process';
9-
import { existsSync, readFileSync } from 'node:fs';
10+
import { existsSync } from 'node:fs';
1011
import { mkdir, rm } from 'node:fs/promises';
1112
import path from 'node:path';
1213
import { Process } from 'tsprocess/dist/process';
1314

14-
const configPath = path.join(getProgramPath(), 'config.ini');
15-
const checkGosuConfig = (p: Process, checking?: boolean) => {
16-
if (!existsSync(configPath)) return null;
17-
18-
const read = readFileSync(configPath, 'utf8');
19-
const parseURL = /^overlayURL[ ]*=[ ]*(.*)$/m.exec(read);
20-
if (!parseURL || !parseURL?.[1]) {
21-
setTimeout(() => {
22-
checkGosuConfig(p, true);
23-
}, 1000);
24-
return false;
25-
}
26-
27-
if (checking) injectGameOverlay(p);
28-
return true;
29-
};
30-
3115
export const injectGameOverlay = async (p: Process) => {
3216
try {
3317
if (process.platform !== 'win32') {
3418
wLogger.error(
35-
'[gosu-overlay] Ingame overlay can run only under windows, sorry linux/darwin user!'
19+
'[ingame-overlay] Ingame overlay can run only under windows, sorry linux/darwin user!'
3620
);
3721
return;
3822
}
3923

40-
// Check for DEPRECATED GOSU CONFIG, due its needed to read [GameOverlay] section from original configuration
4124
checkGameOverlayConfig();
4225

43-
const gameOverlayPath = path.join(getProgramPath(), 'gameOverlay');
26+
const gameOverlayPath = path.join(getProgramPath(), 'game-overlay');
4427
if (!existsSync(gameOverlayPath)) {
4528
const archivePath = path.join(
4629
gameOverlayPath,
47-
'gosu-gameoverlay.zip'
30+
'tosu-gameoverlay.zip'
4831
);
4932

5033
await mkdir(gameOverlayPath);
5134
await downloadFile(
52-
'https://dl.kotworks.cyou/gosu-gameoverlay.zip',
35+
'https://nocfdl.kotworks.cyou/tosu-overlay-alpha.zip',
5336
archivePath
5437
);
5538

5639
await unzip(archivePath, gameOverlayPath);
5740
await rm(archivePath);
5841
}
5942

60-
if (!existsSync(path.join(gameOverlayPath, 'gosumemoryoverlay.dll'))) {
61-
wLogger.info(
62-
'[gosu-overlay] Please delete gameOverlay folder, and restart program!'
63-
);
64-
return;
65-
}
66-
67-
const overlayURLstatus = checkGosuConfig(p);
68-
if (!overlayURLstatus) {
69-
wLogger.warn(
70-
'[gosu-overlay] Specify overlayURL for gameOverlay in config.ini'
43+
if (
44+
!existsSync(path.join(gameOverlayPath, 'tosu_overlay.dll')) &&
45+
!existsSync(path.join(gameOverlayPath, 'tosu_injector.exe'))
46+
) {
47+
wLogger.error(
48+
'[ingame-overlay] Please delete game-overlay folder, and restart program!'
7149
);
7250
return;
7351
}
7452

7553
return await new Promise((resolve, reject) => {
7654
const child = execFile(
77-
path.join(gameOverlayPath, 'a.exe'),
55+
path.join(gameOverlayPath, 'tosu_injector.exe'),
7856
[
7957
p.id.toString(),
80-
path.join(gameOverlayPath, 'gosumemoryoverlay.dll')
58+
config.serverIP,
59+
config.serverPort.toString()
8160
],
8261
{
62+
cwd: gameOverlayPath,
8363
windowsHide: true
8464
}
8565
);
8666
child.on('error', (err) => {
8767
reject(err);
8868
});
8969
child.on('exit', () => {
90-
wLogger.info(
91-
'[gosu-overlay] initialized successfully, see https://github.com/l3lackShark/gosumemory/wiki/GameOverlay for tutorial'
92-
);
70+
wLogger.warn('[ingame-overlay] initialized successfully');
9371
resolve(true);
9472
});
9573
});

packages/server/assets/homepage.js

+21-12
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ const showSettings = {
627627
},
628628
},
629629
setup(props) {
630+
const is_ingame = window.location.pathname == '/api/ingame';
630631
const settings = ref([]);
631632
for (let i = 0; i < props.settings.length; i++) {
632633
const setting = props.settings[i];
@@ -715,8 +716,10 @@ const showSettings = {
715716

716717

717718
async function updateSettings(event) {
718-
const confirmed = confirm(`Update settings?`);
719-
if (!confirmed) return;
719+
if (!is_ingame) {
720+
const confirmed = confirm(`Update settings?`);
721+
if (!confirmed) return;
722+
};
720723

721724
const element = event.target;
722725

@@ -794,9 +797,10 @@ const showSettings = {
794797

795798
function removeCommand(ind, ind2) {
796799
const item = settings.value[ind2];
797-
const confirmed = confirm(`Delete command?`);
798-
if (!confirmed) return;
799-
800+
if (!is_ingame) {
801+
const confirmed = confirm(`Delete command?`);
802+
if (!confirmed) return;
803+
};
800804

801805
item.value.splice(ind, 1);
802806
};
@@ -888,7 +892,7 @@ function startDownload(element) {
888892

889893

890894
const loadingDiv = previousImage || document.createElement('img');
891-
if (!previousImage) loadingDiv.src = 'https://cdn-icons-png.flaticon.com/128/39/39979.png';
895+
if (!previousImage) loadingDiv.src = '/assets/images/39979.png';
892896
loadingDiv.style.width = 0;
893897
loadingDiv.style.opacity = 0;
894898

@@ -902,7 +906,7 @@ function startDownload(element) {
902906

903907
setTimeout(() => {
904908
loadingDiv.style.opacity = 1;
905-
loadingDiv.style.width = loadingDiv.style.height = childrenSize.height;
909+
loadingDiv.style.width = loadingDiv.style.height = `${childrenSize.height}px`;
906910
}, 100);
907911
}, 10);
908912
};
@@ -929,7 +933,7 @@ function endDownload(element, id, text) {
929933

930934
setTimeout(() => {
931935
span.style.opacity = 1;
932-
span.style.width = spanSize.width;
936+
span.style.width = `${spanSize.width}px`;
933937
}, 100);
934938

935939

@@ -1173,7 +1177,7 @@ async function saveSettings(element) {
11731177
const DEBUG_LOG = document.querySelector('#DEBUG_LOG');
11741178
const CALCULATE_PP = document.querySelector('#CALCULATE_PP');
11751179
const ENABLE_KEY_OVERLAY = document.querySelector('#ENABLE_KEY_OVERLAY');
1176-
const ENABLE_GOSU_OVERLAY = document.querySelector('#ENABLE_GOSU_OVERLAY');
1180+
const ENABLE_INGAME_OVERLAY = document.querySelector('#ENABLE_INGAME_OVERLAY');
11771181
const POLL_RATE = document.querySelector('#POLL_RATE');
11781182
const PRECISE_DATA_POLL_RATE = document.querySelector('#PRECISE_DATA_POLL_RATE');
11791183
const SERVER_IP = document.querySelector('#SERVER_IP');
@@ -1197,7 +1201,7 @@ async function saveSettings(element) {
11971201
CALCULATE_PP: CALCULATE_PP.checked,
11981202
SHOW_MP_COMMANDS: SHOW_MP_COMMANDS.checked,
11991203
ENABLE_KEY_OVERLAY: ENABLE_KEY_OVERLAY.checked,
1200-
ENABLE_GOSU_OVERLAY: ENABLE_GOSU_OVERLAY.checked,
1204+
ENABLE_INGAME_OVERLAY: ENABLE_INGAME_OVERLAY.checked,
12011205
POLL_RATE: POLL_RATE.value,
12021206
PRECISE_DATA_POLL_RATE: PRECISE_DATA_POLL_RATE.value,
12031207
SERVER_IP: SERVER_IP.value,
@@ -1428,8 +1432,8 @@ async function startBuilderModal(element) {
14281432
};
14291433

14301434

1431-
search_bar.addEventListener('input', handleInput);
1432-
search_bar.addEventListener('keydown', handleInput);
1435+
search_bar?.addEventListener('input', handleInput);
1436+
search_bar?.addEventListener('keydown', handleInput);
14331437

14341438

14351439
window.addEventListener('click', (event) => {
@@ -1469,6 +1473,11 @@ window.addEventListener('click', (event) => {
14691473
return;
14701474
};
14711475

1476+
if (t?.classList.value.includes(' -settings')) {
1477+
loadCounterSettings(t);
1478+
return;
1479+
};
1480+
14721481
if (t?.classList.value.includes(' settings-builder-button')) {
14731482
startBuilderModal(t);
14741483
return;

packages/server/assets/homepage.min.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
2.05 KB
Loading

0 commit comments

Comments
 (0)