Show demo title names as large image text and show the user's Nintendo Switch icon if sharing friend code

This commit is contained in:
Samuel Elliott 2022-04-21 17:58:16 +01:00
parent b508fcc072
commit d07dcabe6f
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
4 changed files with 95 additions and 86 deletions

View File

@ -3,7 +3,7 @@ import createDebug from 'debug';
import persist from 'node-persist';
import DiscordRPC from 'discord-rpc';
import fetch from 'node-fetch';
import { ActiveEvent, CurrentUser, Presence, PresenceState, ZncErrorResponse } from '../../api/znc-types.js';
import { ActiveEvent, CurrentUser, Friend, Presence, PresenceState, ZncErrorResponse } from '../../api/znc-types.js';
import ZncApi from '../../api/znc.js';
import type { Arguments as ParentArguments } from '../nso.js';
import { ArgumentsCamelCase, Argv, getToken, initStorage, LoopResult, SavedToken, YargsArguments } from '../../util.js';
@ -232,9 +232,9 @@ export class ZncDiscordPresence extends ZncNotifications {
throw new Error('User "' + this.presence_user + '" is not friends with this user');
}
await this.updatePresenceForDiscord(friend.presence);
await this.updatePresenceForDiscord(friend.presence, user);
} else {
await this.updatePresenceForDiscord(user!.presence, user!.links.friendCode, activeevent);
await this.updatePresenceForDiscord(user!.presence, user, user!.links.friendCode, activeevent);
}
}
@ -249,15 +249,19 @@ export class ZncDiscordPresence extends ZncNotifications {
i = 0;
last_presence: Presence | null = null;
friendcode: CurrentUser['links']['friendCode'] | undefined = undefined;
last_user: CurrentUser | Friend | undefined = undefined;
last_friendcode: CurrentUser['links']['friendCode'] | undefined = undefined;
last_event: ActiveEvent | undefined = undefined;
async updatePresenceForDiscord(
presence: Presence | null, friendcode?: CurrentUser['links']['friendCode'],
presence: Presence | null,
user?: CurrentUser | Friend,
friendcode?: CurrentUser['links']['friendCode'],
activeevent?: ActiveEvent
) {
this.last_presence = presence;
this.friendcode = friendcode;
this.last_user = user;
this.last_friendcode = friendcode;
this.last_event = activeevent;
const online = presence?.state === PresenceState.ONLINE || presence?.state === PresenceState.PLAYING;
@ -282,6 +286,7 @@ export class ZncDiscordPresence extends ZncNotifications {
activeevent,
znc_discord_presence: this,
nsaid: this.presence_user!,
user,
};
const discordpresence = 'name' in presence.game ?
getDiscordPresence(presence.state, presence.game, presencecontext) :
@ -382,10 +387,10 @@ export class ZncDiscordPresence extends ZncNotifications {
// Is the authenticated user no longer friends with this user?
await this.updatePresenceForDiscord(null);
} else {
await this.updatePresenceForDiscord(friend.presence);
await this.updatePresenceForDiscord(friend.presence, friend);
}
} else {
await this.updatePresenceForDiscord(user!.presence, user!.links.friendCode, activeevent);
await this.updatePresenceForDiscord(user!.presence, user, user!.links.friendCode, activeevent);
}
}

View File

@ -5,12 +5,14 @@ export const titles: Title[] = [
// Minecraft
id: '0100d71004694000',
client: '950906152391168020',
largeImageKey: '0100d71004694000',
showPlayingOnline: true,
showActiveEvent: true,
},
{
// Minecraft: Nintendo Switch Edition
id: '01006bd001e06000',
client: '950906152391168020',
largeImageKey: '01006bd001e06000',
showPlayingOnline: true,
showActiveEvent: true,
},
];

View File

@ -5,7 +5,6 @@ export const titles: Title[] = [
// Splatoon 2 [Europe]
id: '0100f8f0000a2000',
client: '950886725398429726',
largeImageKey: '0100f8f0000a2000',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -13,7 +12,6 @@ export const titles: Title[] = [
// Splatoon 2 [The Americas]
id: '01003bc0000a0000',
client: '950886725398429726',
largeImageKey: '0100f8f0000a2000',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -21,7 +19,6 @@ export const titles: Title[] = [
// Splatoon 2 [Japan]
id: '01003c700009c000',
client: '950886725398429726',
largeImageKey: '01003c700009c000',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -29,49 +26,49 @@ export const titles: Title[] = [
// Splatoon 2: Splatfest World Premiere [Europe, The Americas]
id: '01003870040fa000',
client: '950886725398429726',
titleName: 'Splatfest World Premiere',
largeImageText: 'Splatfest World Premiere',
showPlayingOnline: true,
},
{
// Splatoon 2: Special Demo [Europe]
id: '01007e200d45c000',
client: '950886725398429726',
titleName: 'Special Demo',
largeImageText: 'Special Demo',
showPlayingOnline: true,
},
{
// Splatoon 2 Special Demo [The Americas]
id: '01006bb00d45a000',
client: '950886725398429726',
titleName: 'Special Demo',
largeImageText: 'Special Demo',
showPlayingOnline: true,
},
{
// Splatoon 2 Special Demo [Japan]
id: '01009c900d458000',
client: '950886725398429726',
titleName: 'Special Demo',
largeImageText: 'Special Demo',
showPlayingOnline: true,
},
{
// Splatoon 2: Special Demo 2020 [Europe]
id: '01009240116cc000',
client: '950886725398429726',
titleName: 'Special Demo 2020',
largeImageText: 'Special Demo 2020',
showPlayingOnline: true,
},
{
// Splatoon 2 Special Demo 2020 [The Americas]
id: '01002120116c4000',
client: '950886725398429726',
titleName: 'Special Demo 2020',
largeImageText: 'Special Demo 2020',
showPlayingOnline: true,
},
{
// Splatoon 2 Special Demo 2020 [Japan]
id: '0100998011330000',
client: '950886725398429726',
titleName: 'Special Demo 2020',
largeImageText: 'Special Demo 2020',
showPlayingOnline: true,
},
@ -79,7 +76,6 @@ export const titles: Title[] = [
// Super Smash Bros. Ultimate
id: '01006a800016e000',
client: '950894516104212490',
largeImageKey: '01006a800016e000',
showActiveEvent: true,
},
@ -87,7 +83,6 @@ export const titles: Title[] = [
// Mario Kart 8 Deluxe
id: '0100152000022000',
client: '950905573149409280',
largeImageKey: '0100152000022000',
showActiveEvent: true,
},
@ -95,43 +90,37 @@ export const titles: Title[] = [
// Super Mario Odyssey
id: '0100000000010000',
client: '950905939899351050',
largeImageKey: '0100000000010000',
},
{
// Nintendo Entertainment System - Nintendo Switch Online
id: '0100d870045b6000',
client: '950907272438104064',
titleName: 'Nintendo Entertainment System',
largeImageKey: '0100d870045b6000',
largeImageText: 'Nintendo Entertainment System',
},
{
// Super Nintendo Entertainment System - Nintendo Switch Online
id: '01008d300c50c000',
client: '950907272438104064',
titleName: 'Super Nintendo Entertainment System',
largeImageKey: '01008d300c50c000',
largeImageText: 'Super Nintendo Entertainment System',
},
{
// Nintendo 64 - Nintendo Switch Online
id: '0100c9a00ece6000',
client: '950907272438104064',
titleName: 'Nintendo 64',
largeImageKey: '0100c9a00ece6000',
largeImageText: 'Nintendo 64',
},
{
// SEGA Mega Drive - Nintendo Switch Online
id: '0100b3c014bda000',
client: '950907272438104064',
titleName: 'SEGA Mega Drive',
largeImageKey: '0100b3c014bda000',
largeImageText: 'SEGA Mega Drive',
},
{
// Animal Crossing: New Horizons
id: '01006f8002326000',
client: '950908097235415079',
largeImageKey: '01006f8002326000',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -140,7 +129,6 @@ export const titles: Title[] = [
id: '0100f38011cfe000',
client: '950908097235415079',
titleName: 'Island Transfer Tool',
largeImageKey: '0100f38011cfe000',
},
{
@ -170,7 +158,7 @@ export const titles: Title[] = [
// Snipperclips - Cut it out, together! Demo
id: '0100d87002ee0000',
client: '966102704525025301',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -186,7 +174,7 @@ export const titles: Title[] = [
// ARMS Sparring Demo
id: '0100a5400ac86000',
client: '966102773642960917',
titleName: 'Sparring Demo',
largeImageText: 'Sparring Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -209,7 +197,7 @@ export const titles: Title[] = [
// Pokémon: Let's Go, Pikachu! & Pokémon: Let's Go, Eevee! Demo
id: '0100c1800d7ae000',
client: '966103072407437332',
titleName: 'Pokémon: Let\'s Go, Pikachu! & Pokémon: Let\'s Go, Eevee! Demo',
largeImageText: 'Pokémon: Let\'s Go, Pikachu! & Pokémon: Let\'s Go, Eevee! Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -241,7 +229,7 @@ export const titles: Title[] = [
// Yoshi's Crafted World Demo
id: '0100ae800c9c6000',
client: '966103360589672488',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -257,7 +245,7 @@ export const titles: Title[] = [
// Pokkén Tournament DX Demo
id: '010030d005ae6000',
client: '966103482702647326',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -273,7 +261,7 @@ export const titles: Title[] = [
// OCTOPATH TRAVELER: Prologue Demo
id: '010096000b3ea000',
client: '966147770006241340',
titleName: 'Prologue Demo',
largeImageText: 'Prologue Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -297,7 +285,7 @@ export const titles: Title[] = [
// Captain Toad: Treasure Tracker Demo
id: '01002c400b6b6000',
client: '966148067134939186',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -313,7 +301,7 @@ export const titles: Title[] = [
// // Sushi Striker: The Way of Sushido Demo
// id: '', // TODO
// client: '966148228154265661',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -329,7 +317,7 @@ export const titles: Title[] = [
// Mario Tennis Aces: Special Demo [Europe]
id: '0100f9600da78000',
client: '966148353727561738',
titleName: 'Special Demo',
largeImageText: 'Special Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -337,7 +325,7 @@ export const titles: Title[] = [
// Mario Tennis Aces Special Online Demo [The Americas]
id: '0100a4200da76000',
client: '966148353727561738',
titleName: 'Special Online Demo',
largeImageText: 'Special Online Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -368,7 +356,7 @@ export const titles: Title[] = [
// Pikmin 3 Deluxe Demo
id: '01001cb0106f8000',
client: '966148753365041173',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -384,7 +372,7 @@ export const titles: Title[] = [
// Dragon Quest Builders Demo
id: '0100c360070f6000',
client: '966148914933792838',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -432,7 +420,7 @@ export const titles: Title[] = [
// Kirby Star Allies Demo
id: '01005a70096fa000',
client: '966330020391952384',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -472,7 +460,7 @@ export const titles: Title[] = [
// // Dragon Quest Builders 2 Demo
// id: '', // TODO
// client: '966331488322871346',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -480,7 +468,7 @@ export const titles: Title[] = [
// // Dragon Quest Builders 2 Jumbo Demo
// id: '', // TODO
// client: '966331488322871346',
// titleName: 'Jumbo Demo',
// largeImageText: 'Jumbo Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -504,7 +492,7 @@ export const titles: Title[] = [
// Fitness Boxing Demo
id: '010050200d0da000',
client: '966387481375285300',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -544,7 +532,7 @@ export const titles: Title[] = [
// // Pokémon Mystery Dungeon: Rescue Team DX Demo
// id: '', // TODO
// client: '966387876520685668',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -568,7 +556,7 @@ export const titles: Title[] = [
// DAEMON X MACHINA: Prototype Missions
id: '0100bf600d83a000',
client: '966388060428320789',
titleName: 'Prototype Missions',
largeImageText: 'Prototype Missions',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -576,7 +564,7 @@ export const titles: Title[] = [
// // DAEMON X MACHINA Demo
// id: '', // TODO
// client: '966388060428320789',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -608,7 +596,7 @@ export const titles: Title[] = [
// BOXBOY! + BOXGIRL! Demo
id: '0100b7200e02e000',
client: '966388339127234592',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -640,7 +628,7 @@ export const titles: Title[] = [
// // Cadence of Hyrule - Crypt of the NecroDancer Featuring The Legend of Zelda Demo
// id: '', // TODO
// client: '966441763973763162',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -656,7 +644,7 @@ export const titles: Title[] = [
// // Dragon Quest XI S: Echoes of an Elusive Age - Definitive Edition Demo
// id: '', // TODO
// client: '966441876267864084',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -696,7 +684,7 @@ export const titles: Title[] = [
// Bravely Default II Demo
id: '0100b6801137e000',
client: '966442378095382578',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -704,7 +692,7 @@ export const titles: Title[] = [
// // Bravely Default II Demo
// id: '', // TODO - there's two demos apparently
// client: '966442378095382578',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -728,7 +716,7 @@ export const titles: Title[] = [
// 51 Worldwide Games: Local Multiplayer Guest Edition
id: '0100cd9011c04000',
client: '966442617938280526',
titleName: 'Local Multiplayer Guest Edition',
largeImageText: 'Local Multiplayer Guest Edition',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -784,7 +772,7 @@ export const titles: Title[] = [
// // Kirby Fighters 2 Demo
// id: '', // TODO
// client: '966479069287960656',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -800,7 +788,7 @@ export const titles: Title[] = [
// // Hyrule Warriors: Age of Calamity Demo
// id: '', // TODO
// client: '966479236762325013',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -816,7 +804,7 @@ export const titles: Title[] = [
// Fitness Boxing 2: Rhythm & Exercise Demo
id: '01000f50130a2000',
client: '966479353510789150',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -856,7 +844,7 @@ export const titles: Title[] = [
// Miitopia Demo
id: '01007da0140e8000',
client: '966487135194591282',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -903,7 +891,7 @@ export const titles: Title[] = [
// Game Builder Garage Demo
id: '01003b101497c000',
client: '966487590721163264',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -919,7 +907,7 @@ export const titles: Title[] = [
// // Metroid Dread Demo
// id: '', // TODO
// client: '966487674162642974',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -935,7 +923,7 @@ export const titles: Title[] = [
// WarioWare: Get It Together! Demo
id: '0100ee9015b5e000',
client: '966487765447483412',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -975,7 +963,7 @@ export const titles: Title[] = [
// Big Brain Academy: Brain vs. Brain Demo
id: '0100219016ab4000',
client: '966533636969082921',
titleName: 'Demo',
largeImageText: 'Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -991,7 +979,7 @@ export const titles: Title[] = [
// Project Triangle Strategy Debut Demo
id: '01002980140f6000',
client: '966533747023437904',
titleName: 'Project Triangle Strategy Debut Demo',
largeImageText: 'Project Triangle Strategy Debut Demo',
showPlayingOnline: true,
showActiveEvent: true,
},
@ -999,7 +987,7 @@ export const titles: Title[] = [
// // Project Triangle Strategy Prologue demo
// id: '', // TODO
// client: '966533747023437904',
// titleName: 'Prologue demo',
// largeImageText: 'Prologue demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -1015,7 +1003,7 @@ export const titles: Title[] = [
// // Kirby and the Forgotten Land Demo
// id: '', // TODO
// client: '966534055116021821',
// titleName: 'Demo',
// largeImageText: 'Demo',
// showPlayingOnline: true,
// showActiveEvent: true,
// },
@ -1031,7 +1019,7 @@ export const titles: Title[] = [
// Nintendo Switch Sports Online Play Test
id: '01000ee017182000',
client: '966534181783998474',
titleName: 'Online Play Test',
largeImageText: 'Online Play Test',
showPlayingOnline: true,
showActiveEvent: true,
},

View File

@ -1,7 +1,7 @@
import DiscordRPC from 'discord-rpc';
import { ActiveEvent, CurrentUser, Game, PresenceState } from '../api/znc-types.js';
import { ActiveEvent, CurrentUser, Friend, Game, PresenceState } from '../api/znc-types.js';
import { defaultTitle, titles } from './titles.js';
import { getTitleIdFromEcUrl, hrduration } from '../util.js';
import { getTitleIdFromEcUrl, hrduration, version } from '../util.js';
import { ZncDiscordPresence } from '../cli/nso/presence.js';
export function getDiscordPresence(
@ -21,11 +21,11 @@ export function getDiscordPresence(
' (' + members?.length + ' player' + (members?.length === 1 ? '' : 's') +
')' : '';
if (game.sysDescription) text.push(game.sysDescription + event_text);
if ((title.showDescription ?? true) && game.sysDescription) text.push(game.sysDescription + event_text);
else if (online && title.showPlayingOnline === true) text.push('Playing online' + event_text);
else if (online && title.showPlayingOnline) text.push(title.showPlayingOnline as string + event_text);
if (game.totalPlayTime >= 60) {
if ((title.showPlayTime ?? true) && game.totalPlayTime >= 60) {
text.push('Played for ' + hrduration(game.totalPlayTime) +
' since ' + (game.firstPlayedAt ? new Date(game.firstPlayedAt * 1000).toLocaleDateString('en-GB') : 'now'));
}
@ -34,8 +34,10 @@ export function getDiscordPresence(
details: text[0],
state: text[1],
largeImageKey: title.largeImageKey ?? game.imageUri,
largeImageText: context?.friendcode ? 'SW-' + context.friendcode.id : undefined,
smallImageKey: title.smallImageKey,
largeImageText: title.largeImageText ?? 'nxapi ' + version,
smallImageKey: title.smallImageKey || (context?.friendcode ? context?.user?.imageUri : undefined),
smallImageText: title.smallImageKey ? title.smallImageText :
context?.friendcode && context?.user?.imageUri ? 'SW-' + context.friendcode.id : undefined,
buttons: game.shopUri ? [
{
label: 'Nintendo eShop',
@ -44,15 +46,10 @@ export function getDiscordPresence(
] : [],
};
if (online && title.showActiveEvent && context?.activeevent?.shareUri) {
activity.buttons?.push({
label: 'Join',
url: context.activeevent.shareUri,
});
} else if (online && title.showActiveEvent) {
activity.buttons?.push({
label: 'Join via Nintendo Switch',
url: 'https://lounge.nintendo.com',
if (online && title.showActiveEvent) {
activity.buttons!.push({
label: context?.activeevent?.shareUri ? 'Join' : 'Join via Nintendo Switch',
url: context?.activeevent?.shareUri ?? 'https://lounge.nintendo.com',
});
}
@ -75,7 +72,9 @@ export function getInactiveDiscordPresence(
activity: {
state: 'Not playing',
largeImageKey: 'nintendoswitch',
largeImageText: context?.friendcode ? 'SW-' + context.friendcode.id : undefined,
largeImageText: 'nxapi ' + version,
smallImageKey: context?.friendcode ? context?.user?.imageUri : undefined,
smallImageText: context?.friendcode && context?.user?.imageUri ? 'SW-' + context.friendcode.id : undefined,
},
};
}
@ -85,6 +84,7 @@ export interface DiscordPresenceContext {
activeevent?: ActiveEvent;
znc_discord_presence?: ZncDiscordPresence;
nsaid?: string;
user?: CurrentUser | Friend;
}
export interface DiscordPresence {
@ -128,16 +128,24 @@ export interface Title {
* By default the title's icon from znc will be used. (No icons need to be uploaded to Discord.)
*/
largeImageKey?: string;
largeImageText?: string;
/**
* By default this will not be set.
*/
smallImageKey?: string;
smallImageText?: string;
/**
* Whether to show the timestamp the user started playing the title in Discord. Discord shows this as the number of minutes and seconds since the timestamp; this will be inaccurate as it may take up to a minute (by default) to detect the user's presence, so this is disabled by default.
*
* @default false
*/
showTimestamp?: boolean;
/**
* Show the activity description set by the title.
*
* @default true
*/
showDescription?: boolean;
/**
* Show "Playing online" if playing online and the game doesn't set activity details.
*
@ -150,6 +158,12 @@ export interface Title {
* @default false
*/
showActiveEvent?: boolean;
/**
* Whether to show "Played for ... since ..." in Discord.
*
* @default true
*/
showPlayTime?: boolean;
/**
* A function to call to customise the Discord activity.