mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-04-03 16:15:04 -05:00
Show if playing online even for games that don't set a description
This commit is contained in:
parent
4736fe55d4
commit
0839ff520b
|
|
@ -5,7 +5,8 @@ import fetch from 'node-fetch';
|
|||
import { CurrentUser, Friend, Presence, PresenceState } from '../../api/znc-types.js';
|
||||
import ZncApi from '../../api/znc.js';
|
||||
import type { Arguments as ParentArguments } from '../nso.js';
|
||||
import { ArgumentsCamelCase, Argv, getDiscordPresence, getInactiveDiscordPresence, getToken, initStorage, SavedToken, YargsArguments } from '../../util.js';
|
||||
import { ArgumentsCamelCase, Argv, getToken, initStorage, SavedToken, YargsArguments } from '../../util.js';
|
||||
import { getDiscordPresence, getInactiveDiscordPresence } from '../../discord/util.js';
|
||||
import { ZncNotifications } from './notify.js';
|
||||
import ZncProxyApi from '../../api/znc-proxy.js';
|
||||
|
||||
|
|
@ -188,8 +189,8 @@ class ZncDiscordPresence extends ZncNotifications {
|
|||
|
||||
const fc = this.argv.friendCode === '' || this.argv.friendCode === '-' ? friendcode : this.forceFriendCode;
|
||||
const discordpresence = 'name' in presence.game ?
|
||||
getDiscordPresence(presence.game, fc) :
|
||||
getInactiveDiscordPresence(fc);
|
||||
getDiscordPresence(presence.state, presence.game, fc) :
|
||||
getInactiveDiscordPresence(presence.state, presence.logoutAt, fc);
|
||||
|
||||
if (this.rpc && this.rpc.id !== discordpresence.id) {
|
||||
const client = this.rpc.client;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ export const defaultTitle: Title = {
|
|||
id: '0000000000000000',
|
||||
client: '950883021165330493',
|
||||
titleName: true,
|
||||
showPlayingOnline: true,
|
||||
};
|
||||
|
||||
const titles: Title[] = [
|
||||
|
|
@ -12,18 +13,21 @@ const titles: Title[] = [
|
|||
id: '0100f8f0000a2000',
|
||||
client: '950886725398429726',
|
||||
largeImageKey: '0100f8f0000a2000',
|
||||
showPlayingOnline: true,
|
||||
},
|
||||
{
|
||||
// Splatoon 2 [The Americas]
|
||||
id: '01003bc0000a0000',
|
||||
client: '950886725398429726',
|
||||
largeImageKey: '0100f8f0000a2000',
|
||||
showPlayingOnline: true,
|
||||
},
|
||||
{
|
||||
// Splatoon 2 [Japan]
|
||||
id: '01003c700009c000',
|
||||
client: '950886725398429726',
|
||||
largeImageKey: '01003c700009c000',
|
||||
showPlayingOnline: true,
|
||||
},
|
||||
|
||||
{
|
||||
93
src/discord/util.ts
Normal file
93
src/discord/util.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import DiscordRPC from 'discord-rpc';
|
||||
import { CurrentUser, Game, PresenceState } from '../api/znc-types.js';
|
||||
import titles, { defaultTitle } from './titles.js';
|
||||
import { getTitleIdFromEcUrl, hrduration } from '../util.js';
|
||||
|
||||
export function getDiscordPresence(
|
||||
state: PresenceState, game: Game,
|
||||
friendcode?: CurrentUser['links']['friendCode']
|
||||
): DiscordPresence {
|
||||
const titleid = getTitleIdFromEcUrl(game.shopUri);
|
||||
const title = titles.find(t => t.id === titleid) || defaultTitle;
|
||||
|
||||
const text = [];
|
||||
|
||||
if (title.titleName === true) text.push(game.name);
|
||||
else if (title.titleName) text.push(title.titleName);
|
||||
|
||||
if (game.sysDescription) text.push(game.sysDescription);
|
||||
else if (state === PresenceState.PLAYING && title.showPlayingOnline === true) text.push('Playing online');
|
||||
else if (state === PresenceState.PLAYING && title.showPlayingOnline) text.push(title.showPlayingOnline as string);
|
||||
|
||||
if (game.totalPlayTime >= 60) {
|
||||
text.push('Played for ' + hrduration(game.totalPlayTime) +
|
||||
' since ' + (game.firstPlayedAt ? new Date(game.firstPlayedAt * 1000).toLocaleDateString('en-GB') : 'now'));
|
||||
}
|
||||
|
||||
const activity: DiscordRPC.Presence = {
|
||||
details: text[0],
|
||||
state: text[1],
|
||||
largeImageKey: title.largeImageKey ?? game.imageUri,
|
||||
largeImageText: friendcode ? 'SW-' + friendcode.id : undefined,
|
||||
smallImageKey: title.smallImageKey,
|
||||
buttons: game.shopUri ? [
|
||||
{
|
||||
label: 'Nintendo eShop',
|
||||
url: game.shopUri,
|
||||
},
|
||||
] : [],
|
||||
};
|
||||
|
||||
title.callback?.call(null, activity, game);
|
||||
|
||||
return {
|
||||
id: title.client || defaultTitle.client,
|
||||
title: titleid,
|
||||
activity,
|
||||
showTimestamp: title.showTimestamp,
|
||||
};
|
||||
}
|
||||
|
||||
export function getInactiveDiscordPresence(
|
||||
state: PresenceState, logoutAt: number,
|
||||
friendcode?: CurrentUser['links']['friendCode']
|
||||
): DiscordPresence {
|
||||
return {
|
||||
id: defaultTitle.client,
|
||||
title: null,
|
||||
activity: {
|
||||
state: 'Not playing',
|
||||
largeImageKey: 'nintendoswitch',
|
||||
largeImageText: friendcode ? 'SW-' + friendcode.id : undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export interface DiscordPresence {
|
||||
id: string;
|
||||
title: string | null;
|
||||
activity: DiscordRPC.Presence;
|
||||
showTimestamp?: boolean;
|
||||
}
|
||||
|
||||
export function getTitleConfiguration(game: Game, id: string) {
|
||||
return titles.find(title => {
|
||||
if (title.id !== id) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export interface Title {
|
||||
/** Lowercase hexadecimal title ID */
|
||||
id: string;
|
||||
/** Discord client ID */
|
||||
client: string;
|
||||
|
||||
titleName?: string | boolean;
|
||||
largeImageKey?: string;
|
||||
smallImageKey?: string;
|
||||
showTimestamp?: boolean;
|
||||
/** Show "Playing online" if playing online and the game doesn't set activity details */
|
||||
showPlayingOnline?: string | boolean;
|
||||
}
|
||||
79
src/util.ts
79
src/util.ts
|
|
@ -2,14 +2,12 @@ import * as path from 'path';
|
|||
import * as yargs from 'yargs';
|
||||
import type * as yargstypes from '../node_modules/@types/yargs/index.js';
|
||||
import createDebug from 'debug';
|
||||
import DiscordRPC from 'discord-rpc';
|
||||
import persist from 'node-persist';
|
||||
import getPaths from 'env-paths';
|
||||
import { FlapgApiResponse } from './api/f.js';
|
||||
import { NintendoAccountToken, NintendoAccountUser } from './api/na.js';
|
||||
import { AccountLogin, CurrentUser, Game } from './api/znc-types.js';
|
||||
import { AccountLogin } from './api/znc-types.js';
|
||||
import ZncApi from './api/znc.js';
|
||||
import titles, { defaultTitle } from './titles.js';
|
||||
import ZncProxyApi from './api/znc-proxy.js';
|
||||
import MoonApi from './api/moon.js';
|
||||
|
||||
|
|
@ -50,6 +48,14 @@ export async function initStorage(dir: string) {
|
|||
return storage;
|
||||
}
|
||||
|
||||
export async function getToken(storage: persist.LocalStorage, token: string, proxy_url: string): Promise<{
|
||||
nso: ZncProxyApi;
|
||||
data: SavedToken;
|
||||
}>
|
||||
export async function getToken(storage: persist.LocalStorage, token: string, proxy_url?: string): Promise<{
|
||||
nso: ZncApi;
|
||||
data: SavedToken;
|
||||
}>
|
||||
export async function getToken(storage: persist.LocalStorage, token: string, proxy_url?: string) {
|
||||
if (!token) {
|
||||
console.error('No token set. Set a Nintendo Account session token using the `--token` option or by running `nxapi nso token`.');
|
||||
|
|
@ -127,73 +133,6 @@ export function getTitleIdFromEcUrl(url: string) {
|
|||
return match?.[1] ?? null;
|
||||
}
|
||||
|
||||
export function getDiscordPresence(game: Game, friendcode?: CurrentUser['links']['friendCode']): DiscordPresence {
|
||||
const titleid = getTitleIdFromEcUrl(game.shopUri);
|
||||
const title = titles.find(t => t.id === titleid) || defaultTitle;
|
||||
|
||||
const text = [];
|
||||
|
||||
if (title.titleName === true) text.push(game.name);
|
||||
else if (title.titleName) text.push(title.titleName);
|
||||
|
||||
if (game.sysDescription) text.push(game.sysDescription);
|
||||
|
||||
if (game.totalPlayTime >= 60) {
|
||||
text.push('Played for ' + hrduration(game.totalPlayTime) +
|
||||
' since ' + (game.firstPlayedAt ? new Date(game.firstPlayedAt * 1000).toLocaleDateString('en-GB') : 'now'));
|
||||
}
|
||||
|
||||
return {
|
||||
id: title.client || defaultTitle.client,
|
||||
title: titleid,
|
||||
activity: {
|
||||
details: text[0],
|
||||
state: text[1],
|
||||
largeImageKey: title.largeImageKey ?? game.imageUri,
|
||||
largeImageText: friendcode ? 'SW-' + friendcode.id : undefined,
|
||||
smallImageKey: title.smallImageKey,
|
||||
buttons: game.shopUri ? [
|
||||
{
|
||||
label: 'Nintendo eShop',
|
||||
url: game.shopUri,
|
||||
},
|
||||
] : [],
|
||||
},
|
||||
showTimestamp: title.showTimestamp,
|
||||
};
|
||||
}
|
||||
|
||||
export function getInactiveDiscordPresence(friendcode?: CurrentUser['links']['friendCode']): DiscordPresence {
|
||||
return {
|
||||
id: defaultTitle.client,
|
||||
title: null,
|
||||
activity: {
|
||||
state: 'Not playing',
|
||||
largeImageKey: 'nintendoswitch',
|
||||
largeImageText: friendcode ? 'SW-' + friendcode.id : undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export interface DiscordPresence {
|
||||
id: string;
|
||||
title: string | null;
|
||||
activity: DiscordRPC.Presence;
|
||||
showTimestamp?: boolean;
|
||||
}
|
||||
|
||||
export interface Title {
|
||||
/** Lowercase hexadecimal title ID */
|
||||
id: string;
|
||||
/** Discord client ID */
|
||||
client: string;
|
||||
|
||||
titleName?: string | true;
|
||||
largeImageKey?: string;
|
||||
smallImageKey?: string;
|
||||
showTimestamp?: boolean;
|
||||
}
|
||||
|
||||
export function hrduration(duration: number, short = false) {
|
||||
const hours = Math.floor(duration / 60);
|
||||
const minutes = duration - (hours * 60);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user