Skip to content

Commit

Permalink
feat: Added compability api for StreamCompanion
Browse files Browse the repository at this point in the history
  • Loading branch information
cyperdark committed Oct 25, 2024
1 parent cee77bc commit 04cc3c6
Show file tree
Hide file tree
Showing 13 changed files with 623 additions and 9 deletions.
17 changes: 16 additions & 1 deletion packages/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { config, wLogger } from '@tosu/common';

import buildAssetsApi from './router/assets';
import buildBaseApi from './router/index';
import buildSCApi from './router/scApi';
import buildSocket from './router/socket';
import buildV1Api from './router/v1';
import buildV2Api from './router/v2';
Expand All @@ -15,6 +16,7 @@ export class Server {
app = new HttpServer();

WS_V1: Websocket;
WS_SC: Websocket;
WS_V2: Websocket;
WS_V2_PRECISE: Websocket;
WS_COMMANDS: Websocket;
Expand All @@ -32,6 +34,13 @@ export class Server {
stateFunctionName: 'getState',
onMessageCallback: handleSocketCommands
});
this.WS_SC = new Websocket({
instanceManager: this.instanceManager,
pollRateFieldName: 'pollRate',
stateFunctionName: 'getStateSC',
onMessageCallback: handleSocketCommands
});

this.WS_V2 = new Websocket({
instanceManager: this.instanceManager,
pollRateFieldName: 'pollRate',
Expand All @@ -51,20 +60,24 @@ export class Server {
onMessageCallback: handleSocketCommands
});

buildBaseApi(this);
buildAssetsApi(this);
buildV1Api(this.app);
buildSCApi(this.app);

buildV2Api(this.app);

buildSocket({
app: this.app,

WS_V1: this.WS_V1,
WS_SC: this.WS_SC,
WS_V2: this.WS_V2,
WS_V2_PRECISE: this.WS_V2_PRECISE,
WS_COMMANDS: this.WS_COMMANDS
});

buildBaseApi(this);

this.app.listen(config.serverPort, config.serverIP);
}

Expand All @@ -75,10 +88,12 @@ export class Server {

restartWS() {
if (this.WS_V1) this.WS_V1.stopLoop();
if (this.WS_SC) this.WS_SC.stopLoop();
if (this.WS_V2) this.WS_V2.stopLoop();
if (this.WS_V2_PRECISE) this.WS_V2_PRECISE.stopLoop();

if (this.WS_V1) this.WS_V1.startLoop();
if (this.WS_SC) this.WS_SC.startLoop();
if (this.WS_V2) this.WS_V2.startLoop();
if (this.WS_V2_PRECISE) this.WS_V2_PRECISE.startLoop();
}
Expand Down
19 changes: 19 additions & 0 deletions packages/server/router/scApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { HttpServer, sendJson } from '../index';
import { beatmapFileShortcut } from '../scripts/beatmapFile';

export default function buildSCApi(app: HttpServer) {
app.route('/json/sc', 'GET', (req, res) => {
const osuInstance: any = req.instanceManager.getInstance();
if (!osuInstance) {
res.statusCode = 500;
return sendJson(res, { error: 'not_ready' });
}

const json = osuInstance.getStateSC(req.instanceManager);
sendJson(res, json);
});

app.route('/backgroundImage', 'GET', (req, res) =>
beatmapFileShortcut(req, res, 'background')
);
}
13 changes: 13 additions & 0 deletions packages/server/router/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ export default function buildSocket({
app,

WS_V1,
WS_SC,
WS_V2,
WS_V2_PRECISE,
WS_COMMANDS
}: {
app: HttpServer;
WS_V1: Websocket;
WS_SC: Websocket;
WS_V2: Websocket;
WS_V2_PRECISE: Websocket;
WS_COMMANDS: Websocket;
Expand Down Expand Up @@ -50,6 +52,17 @@ export default function buildSocket({
);
}

if (parsedURL.pathname === '/tokens') {
WS_SC.socket.handleUpgrade(
request,
socket,
head,
function (ws) {
WS_SC.socket.emit('connection', ws, request);
}
);
}

if (parsedURL.pathname === '/websocket/v2') {
WS_V2.socket.handleUpgrade(
request,
Expand Down
59 changes: 59 additions & 0 deletions packages/server/scripts/beatmapFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { wLogger } from '@tosu/common';
import { ServerResponse } from 'http';
import path from 'path';

import { directoryWalker } from '../utils/directories';
import { ExtendedIncomingMessage } from '../utils/http';
import { sendJson } from '../utils/index';

export function beatmapFileShortcut(
req: ExtendedIncomingMessage,
res: ServerResponse,
beatmapFileType: 'audio' | 'background' | 'file'
) {
try {
const url = req.pathname || '/';

const osuInstance: any = req.instanceManager.getInstance();
if (!osuInstance) {
res.statusCode = 500;
return sendJson(res, { error: 'not_ready' });
}

const { global, menu } = osuInstance.getServices(['global', 'menu']);
if (
(global.gameFolder === '' && global.skinFolder === '') ||
(global.gameFolder == null && global.skinFolder == null)
) {
res.statusCode = 500;
return sendJson(res, { error: 'not_ready' });
}

const folder = path.join(global.songsFolder, menu.folder || '');
let fileName = '';

if (beatmapFileType === 'audio') fileName = menu.audioFilename;
else if (beatmapFileType === 'background')
fileName = menu.backgroundFilename;
else if (beatmapFileType === 'file') fileName = menu.filename;
else {
return sendJson(res, {
error: 'Unknown file type'
});
}

directoryWalker({
res,
baseUrl: url,
pathname: fileName || '',
folderPath: folder
});
} catch (error) {
wLogger.error((error as any).message);
wLogger.debug(error);

return sendJson(res, {
error: (error as any).message
});
}
}
2 changes: 1 addition & 1 deletion packages/server/utils/directories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getContentType } from '../index';
import { OVERLAYS_STATIC } from './homepage';

function isPathDirectory(path) {
const stat = fs.lstatSync(path);
const stat = fs.statSync(path);

if (stat) {
return stat.isDirectory();
Expand Down
4 changes: 1 addition & 3 deletions packages/server/utils/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,7 @@ export class HttpServer {
(value, key) => (req.query[key] = value)
);

const routes = (this.routes[method] || []).sort(
(a, b) => b.path.toString().length - a.path.toString().length
);
const routes = this.routes[method] || [];
for (let i = 0; i < routes.length; i++) {
const route = routes[i];
let routeExists = false;
Expand Down
151 changes: 151 additions & 0 deletions packages/tosu/src/api/types/sc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
export type ApiAnswer = scAPI | { error?: string };

export interface scAPI {
sliders: number;
mMaxBpm: number;
banchoUsername: string;
banchoId: number;
ppIfMapEndsNow: number;
mapKiaiPoints: {
startTime: number;
duration: number;
}[];
strainPpIfMapEndsNow: number;
titleRoman: string;
retries: number;
status: number;
osu_99PP: number;
maxBpm: number;
skinPath: string;
spinners: number;
rankedStatus: number;
source: string;
aimPpIfMapEndsNow: number;
backgroundImageFileName: string;
songSelectionRankingType: number;
acc: number;
mStars: number;
mapStrains: { [key: string]: number };
miss: number;
timeLeft: string;
playerHpSmooth: number;
hitErrors: number[];
sv: number;
mapArtistTitleUnicode: string;
banchoIsConnected: number;
keyOverlay: string;
mMinBpm: number;
mBpm: string;
simulatedPp: number;
sliderBreaks: number;
osu_m98PP: number;
mapBreaks: {
startTime: number;
endTime: number;
hasEffect: boolean;
}[];
tags: string;
unstableRate: number;
leaderBoardMainPlayer: string;
banchoCountry: string;
comboLeft: number;
currentMaxCombo: number;
osu_m97PP: number;
md5: string;
artistUnicode: string;
osu_m96PP: number;
osu_m90PP: number;
osu_SSPP: number;
osuIsRunning: number;
banchoStatus: number;
isBreakTime: number;
maxCombo: number;
mode: number;
previewtime: number;
mAR: number;
plays: number;
osu_m95PP: number;
accPpIfMapEndsNow: number;
mapArtistTitle: string;
songSelectionScores: string;
geki: number;
osu_98PP: number;
modsEnum: number;
diffName: string;
firstHitObjectTime: number;
songSelectionMainPlayerScore: string;
username: string;
speedPpIfMapEndsNow: number;
hp: number;
creator: string;
c50: number;
mania_m1_000_000PP: number;
liveStarRating: number;
artistRoman: string;
totalAudioTime: number;
ppIfRestFced: number;
mp3Name: string;
osu_97PP: number;
skin: string;
osu_95PP: number;
cs: number;
osu_mSSPP: number;
localTime: number;
mods: string;
bpm: number;
circles: number;
drainingtime: number;
playerHp: number;
test: string;
mapsetid: number;
osuFileName: string;
noChokePp: number;
threadid: number;
katsu: number;
osu_90PP: number;
mOD: number;
maxGrade: number;
localTimeISO: string;
c100: number;
leaderBoardPlayers: string;
mapTimingPoints: {
startTime: number;
bpm?: number;
beatLength: number;
}[];
osu_99_9PP: number;
titleUnicode: string;
osuFileLocation: string;
ar: number;
mania_1_000_000PP: number;
totaltime: number;
mHP: number;
songSelectionTotalScores: number;
dl: string;
mapid: number;
minBpm: number;
score: number;
sl: number;
convertedUnstableRate: number;
mapDiff: string;
ingameInterfaceIsEnabled: number;
mCS: number;
time: number;
rawStatus: number;
dir: string;
c300: number;
mainBpm: number;
osu_m99PP: number;
currentBpm: number;
osu_96PP: number;
combo: number;
mMainBpm: number;
grade: number;
gameMode: string;
chatIsEnabled: number;
mapPosition: string;
backgroundImageLocation: string;
starsNomod: number;
od: number;
osu_m99_9PP: number;
}
6 changes: 6 additions & 0 deletions packages/tosu/src/api/types/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface BeatmapStats {
HP: number;
SR: number;
BPM: {
realtime: number;
common: number;
min: number;
max: number;
Expand Down Expand Up @@ -83,6 +84,11 @@ interface PP {
'97': number;
'96': number;
'95': number;
'94': number;
'93': number;
'92': number;
'91': number;
'90': number;
strains: number[];
strainsAll: BeatmapStrains;
}
Expand Down
5 changes: 5 additions & 0 deletions packages/tosu/src/api/types/v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,11 @@ export interface Performance {
}

export interface Accuracy {
'90': number;
'91': number;
'92': number;
'93': number;
'94': number;
'95': number;
'96': number;
'97': number;
Expand Down
1 change: 1 addition & 0 deletions packages/tosu/src/api/utils/buildResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export const buildResult = (instanceManager: InstanceManager): ApiAnswer => {
HP: fixDecimals(beatmapPP.calculatedMapAttributes.hp),
SR: fixDecimals(beatmapPP.currAttributes.stars),
BPM: {
realtime: fixDecimals(beatmapPP.realtimeBPM),
common: fixDecimals(beatmapPP.commonBPM),
min: fixDecimals(beatmapPP.minBPM),
max: fixDecimals(beatmapPP.maxBPM)
Expand Down
Loading

0 comments on commit 04cc3c6

Please sign in to comment.