mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-07-03 16:40:52 -05:00
Add an option to show event data
This commit is contained in:
parent
a53eccd91e
commit
77a32e1b5e
|
|
@ -113,9 +113,9 @@ export interface WebServiceAttribute {
|
|||
}
|
||||
|
||||
/** /v1/Event/GetActiveEvent */
|
||||
export type ActiveEvent = _ActiveEvent | {};
|
||||
export type GetActiveEventResult = ActiveEvent | {};
|
||||
|
||||
export interface _ActiveEvent extends Event {
|
||||
export interface ActiveEvent extends Event {
|
||||
activateId: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import fetch from 'node-fetch';
|
|||
import { v4 as uuidgen } from 'uuid';
|
||||
import createDebug from 'debug';
|
||||
import { flapg, FlapgIid, genfc } from './f.js';
|
||||
import { AccountLogin, ActiveEvent, Announcements, CurrentUser, CurrentUserPermissions, Event, Friends, PresencePermissions, User, WebServices, WebServiceToken, ZncResponse, ZncStatus } from './znc-types.js';
|
||||
import { AccountLogin, Announcements, CurrentUser, CurrentUserPermissions, Event, Friends, GetActiveEventResult, PresencePermissions, User, WebServices, WebServiceToken, ZncResponse, ZncStatus } from './znc-types.js';
|
||||
import { getNintendoAccountToken, getNintendoAccountUser, NintendoAccountUser } from './na.js';
|
||||
import { ErrorResponse, JwtPayload } from './util.js';
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ export default class ZncApi {
|
|||
}
|
||||
|
||||
async getActiveEvent() {
|
||||
return this.fetch<ActiveEvent>('/v1/Event/GetActiveEvent', 'POST', '{"parameter":{}}');
|
||||
return this.fetch<GetActiveEventResult>('/v1/Event/GetActiveEvent', 'POST', '{"parameter":{}}');
|
||||
}
|
||||
|
||||
async getEvent(id: number) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import bodyParser from 'body-parser';
|
|||
import * as net from 'net';
|
||||
import persist from 'node-persist';
|
||||
import { v4 as uuidgen } from 'uuid';
|
||||
import { ActiveEvent, Announcement, CurrentUser, Friend, Presence, WebService } from '../../api/znc-types.js';
|
||||
import { ActiveEvent, Announcement, CurrentUser, Friend, GetActiveEventResult, Presence, WebService } from '../../api/znc-types.js';
|
||||
import ZncApi from '../../api/znc.js';
|
||||
import type { Arguments as ParentArguments } from '../nso.js';
|
||||
import { ArgumentsCamelCase, Argv, getToken, initStorage, SavedToken, YargsArguments } from '../../util.js';
|
||||
|
|
@ -268,7 +268,7 @@ export async function handler(argv: ArgumentsCamelCase<Arguments>) {
|
|||
//
|
||||
|
||||
const cached_friendsdata = new Map<string, [Friend[], number]>();
|
||||
const cached_appdata = new Map<string, [WebService[], ActiveEvent, number]>();
|
||||
const cached_appdata = new Map<string, [WebService[], GetActiveEventResult, number]>();
|
||||
|
||||
const getFriendsData: express.RequestHandler = async (req, res, next) => {
|
||||
const cache = cached_friendsdata.get(req.zncAuth!.user.id);
|
||||
|
|
|
|||
|
|
@ -198,7 +198,8 @@ export class ZncNotifications extends Loop {
|
|||
result.webservices = (await this.nso.getWebServices()).result;
|
||||
}
|
||||
if (req.includes('event')) {
|
||||
result.activeevent = (await this.nso.getActiveEvent()).result;
|
||||
const activeevent = (await this.nso.getActiveEvent()).result;
|
||||
result.activeevent = 'id' in activeevent ? activeevent : undefined;
|
||||
}
|
||||
if (req.includes('user')) {
|
||||
result.user = (await this.nso.getCurrentUser()).result;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import createDebug from 'debug';
|
|||
import persist from 'node-persist';
|
||||
import DiscordRPC from 'discord-rpc';
|
||||
import fetch from 'node-fetch';
|
||||
import { CurrentUser, Presence, PresenceState, ZncErrorResponse } from '../../api/znc-types.js';
|
||||
import { ActiveEvent, CurrentUser, 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';
|
||||
|
|
@ -29,6 +29,10 @@ export function builder(yargs: Argv<ParentArguments>) {
|
|||
describe: 'Show Discord presence if your console is online but you are not playing (only enable if you are the only user on all consoles your account exists on)',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
}).option('show-event', {
|
||||
describe: 'Show event (Online Lounge/voice chat) details - this shows the number of players in game (experimental)',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
}).option('friend-nsaid', {
|
||||
alias: ['friend-naid'],
|
||||
describe: 'Friend\'s Nintendo Switch account ID',
|
||||
|
|
@ -110,6 +114,7 @@ type Arguments = YargsArguments<ReturnType<typeof builder>>;
|
|||
|
||||
export async function handler(argv: ArgumentsCamelCase<Arguments>) {
|
||||
if (argv.presenceUrl) {
|
||||
if (argv.showEvent) throw new Error('--presence-url not compatible with --show-event');
|
||||
if (argv.friendNsaid) throw new Error('--presence-url not compatible with --friend-nsaid');
|
||||
if (argv.userNotifications) throw new Error('--presence-url not compatible with --user-notifications');
|
||||
if (argv.friendNotifications) throw new Error('--presence-url not compatible with --user-notifications');
|
||||
|
|
@ -148,6 +153,8 @@ export async function handler(argv: ArgumentsCamelCase<Arguments>) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (argv.showEvent && argv.friendNsaid) throw new Error('--show-event not compatible with --friend-nsaid');
|
||||
|
||||
const storage = await initStorage(argv.dataPath);
|
||||
|
||||
const usernsid = argv.user ?? await storage.getItem('SelectedUser');
|
||||
|
|
@ -180,11 +187,12 @@ export class ZncDiscordPresence extends ZncNotifications {
|
|||
show_friend_code = false;
|
||||
force_friend_code: CurrentUser['links']['friendCode'] | undefined = undefined;
|
||||
show_console_online = false;
|
||||
show_active_event = true;
|
||||
|
||||
constructor(
|
||||
argv: Pick<ArgumentsCamelCase<Arguments>,
|
||||
'userNotifications' | 'friendNotifications' | 'updateInterval' |
|
||||
'friendCode' | 'showInactivePresence' | 'friendNsaid'
|
||||
'friendCode' | 'showInactivePresence' | 'showEvent' | 'friendNsaid'
|
||||
>,
|
||||
storage: persist.LocalStorage,
|
||||
token: string,
|
||||
|
|
@ -199,31 +207,35 @@ export class ZncDiscordPresence extends ZncNotifications {
|
|||
{id: match[2] + '-' + match[3] + '-' + match[4], regenerable: false, regenerableAt: 0} : undefined;
|
||||
this.show_friend_code = !!this.force_friend_code || argv.friendCode === '' || argv.friendCode === '-';
|
||||
this.show_console_online = argv.showInactivePresence;
|
||||
this.show_active_event = argv.showEvent;
|
||||
|
||||
this.presence_user = argv.friendNsaid ?? data.nsoAccount.user.nsaId;
|
||||
}
|
||||
|
||||
async init() {
|
||||
const {friends, user} = await this.fetch([
|
||||
const {friends, user, activeevent} = await this.fetch([
|
||||
'announcements',
|
||||
this.presence_user ?
|
||||
this.presence_user === this.data.nsoAccount.user.nsaId ? 'user' :
|
||||
{friend: this.presence_user, presence: true} : null,
|
||||
this.presence_user && this.show_active_event ? 'event' : null,
|
||||
this.user_notifications ? 'user' : null,
|
||||
this.friend_notifications ? 'friends' : null,
|
||||
this.splatnet2_monitors.size ? 'user' : null,
|
||||
]);
|
||||
|
||||
if (this.presence_user && this.presence_user !== this.data.nsoAccount.user.nsaId) {
|
||||
const friend = friends!.find(f => f.nsaId === this.presence_user);
|
||||
if (this.presence_user) {
|
||||
if (this.presence_user !== this.data.nsoAccount.user.nsaId) {
|
||||
const friend = friends!.find(f => f.nsaId === this.presence_user);
|
||||
|
||||
if (!friend) {
|
||||
throw new Error('User "' + this.presence_user + '" is not friends with this user');
|
||||
if (!friend) {
|
||||
throw new Error('User "' + this.presence_user + '" is not friends with this user');
|
||||
}
|
||||
|
||||
await this.updatePresenceForDiscord(friend.presence);
|
||||
} else {
|
||||
await this.updatePresenceForDiscord(user!.presence, user!.links.friendCode, activeevent);
|
||||
}
|
||||
|
||||
await this.updatePresenceForDiscord(friend.presence);
|
||||
} else {
|
||||
await this.updatePresenceForDiscord(user!.presence, user!.links.friendCode);
|
||||
}
|
||||
|
||||
await this.updatePresenceForNotifications(user, friends);
|
||||
|
|
@ -238,10 +250,15 @@ export class ZncDiscordPresence extends ZncNotifications {
|
|||
|
||||
last_presence: Presence | null = null;
|
||||
friendcode: CurrentUser['links']['friendCode'] | undefined = undefined;
|
||||
last_event: ActiveEvent | undefined = undefined;
|
||||
|
||||
async updatePresenceForDiscord(presence: Presence | null, friendcode?: CurrentUser['links']['friendCode']) {
|
||||
async updatePresenceForDiscord(
|
||||
presence: Presence | null, friendcode?: CurrentUser['links']['friendCode'],
|
||||
activeevent?: ActiveEvent
|
||||
) {
|
||||
this.last_presence = presence;
|
||||
this.friendcode = friendcode;
|
||||
this.last_event = activeevent;
|
||||
|
||||
const online = presence?.state === PresenceState.ONLINE || presence?.state === PresenceState.PLAYING;
|
||||
|
||||
|
|
@ -262,6 +279,7 @@ export class ZncDiscordPresence extends ZncNotifications {
|
|||
|
||||
const presencecontext: DiscordPresenceContext = {
|
||||
friendcode: this.show_friend_code ? this.force_friend_code ?? friendcode : undefined,
|
||||
activeevent,
|
||||
znc_discord_presence: this,
|
||||
nsaid: this.presence_user!,
|
||||
};
|
||||
|
|
@ -346,26 +364,29 @@ export class ZncDiscordPresence extends ZncNotifications {
|
|||
}
|
||||
|
||||
async update() {
|
||||
const {friends, user} = await this.fetch([
|
||||
const {friends, user, activeevent} = await this.fetch([
|
||||
this.presence_user ?
|
||||
this.presence_user === this.data.nsoAccount.user.nsaId ? 'user' :
|
||||
{friend: this.presence_user, presence: true} : null,
|
||||
this.presence_user && this.show_active_event ? 'event' : null,
|
||||
this.user_notifications ? 'user' : null,
|
||||
this.friend_notifications ? 'friends' : null,
|
||||
this.splatnet2_monitors.size ? 'user' : null,
|
||||
]);
|
||||
|
||||
if (this.presence_user && this.presence_user !== this.data.nsoAccount.user.nsaId) {
|
||||
const friend = friends!.find(f => f.nsaId === this.presence_user);
|
||||
if (this.presence_user) {
|
||||
if (this.presence_user !== this.data.nsoAccount.user.nsaId) {
|
||||
const friend = friends!.find(f => f.nsaId === this.presence_user);
|
||||
|
||||
if (!friend) {
|
||||
// Is the authenticated user no longer friends with this user?
|
||||
await this.updatePresenceForDiscord(null);
|
||||
if (!friend) {
|
||||
// Is the authenticated user no longer friends with this user?
|
||||
await this.updatePresenceForDiscord(null);
|
||||
} else {
|
||||
await this.updatePresenceForDiscord(friend.presence);
|
||||
}
|
||||
} else {
|
||||
await this.updatePresenceForDiscord(friend.presence);
|
||||
await this.updatePresenceForDiscord(user!.presence, user!.links.friendCode, activeevent);
|
||||
}
|
||||
} else {
|
||||
await this.updatePresenceForDiscord(user!.presence, user!.links.friendCode);
|
||||
}
|
||||
|
||||
await this.updatePresenceForNotifications(user, friends);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ export const defaultTitle: Title = {
|
|||
client: '950883021165330493',
|
||||
titleName: true,
|
||||
showPlayingOnline: true,
|
||||
showActiveEvent: true,
|
||||
};
|
||||
|
||||
const titles: Title[] = [
|
||||
|
|
@ -14,6 +15,7 @@ const titles: Title[] = [
|
|||
client: '950886725398429726',
|
||||
largeImageKey: '0100f8f0000a2000',
|
||||
showPlayingOnline: true,
|
||||
showActiveEvent: true,
|
||||
},
|
||||
{
|
||||
// Splatoon 2 [The Americas]
|
||||
|
|
@ -21,6 +23,7 @@ const titles: Title[] = [
|
|||
client: '950886725398429726',
|
||||
largeImageKey: '0100f8f0000a2000',
|
||||
showPlayingOnline: true,
|
||||
showActiveEvent: true,
|
||||
},
|
||||
{
|
||||
// Splatoon 2 [Japan]
|
||||
|
|
@ -28,6 +31,7 @@ const titles: Title[] = [
|
|||
client: '950886725398429726',
|
||||
largeImageKey: '01003c700009c000',
|
||||
showPlayingOnline: true,
|
||||
showActiveEvent: true,
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -35,6 +39,7 @@ const titles: Title[] = [
|
|||
id: '01006a800016e000',
|
||||
client: '950894516104212490',
|
||||
largeImageKey: '01006a800016e000',
|
||||
showActiveEvent: true,
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -42,6 +47,7 @@ const titles: Title[] = [
|
|||
id: '0100152000022000',
|
||||
client: '950905573149409280',
|
||||
largeImageKey: '0100152000022000',
|
||||
showActiveEvent: true,
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import DiscordRPC from 'discord-rpc';
|
||||
import { CurrentUser, Game, PresenceState } from '../api/znc-types.js';
|
||||
import { ActiveEvent, CurrentUser, Game, PresenceState } from '../api/znc-types.js';
|
||||
import titles, { defaultTitle } from './titles.js';
|
||||
import { getTitleIdFromEcUrl, hrduration } from '../util.js';
|
||||
import { ZncDiscordPresence } from '../cli/nso/presence.js';
|
||||
|
|
@ -15,9 +15,15 @@ export function getDiscordPresence(
|
|||
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);
|
||||
const online = state === PresenceState.PLAYING;
|
||||
const members = context?.activeevent?.members.filter(m => m.isPlaying);
|
||||
const event_text = title.showActiveEvent && context?.activeevent ?
|
||||
' (' + members?.length + ' player' + (members?.length === 1 ? '' : 's') +
|
||||
')' : '';
|
||||
|
||||
if (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) {
|
||||
text.push('Played for ' + hrduration(game.totalPlayTime) +
|
||||
|
|
@ -38,6 +44,18 @@ 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',
|
||||
});
|
||||
}
|
||||
|
||||
title.callback?.call(null, activity, game, context);
|
||||
|
||||
return {
|
||||
|
|
@ -64,6 +82,7 @@ export function getInactiveDiscordPresence(
|
|||
|
||||
export interface DiscordPresenceContext {
|
||||
friendcode?: CurrentUser['links']['friendCode'];
|
||||
activeevent?: ActiveEvent;
|
||||
znc_discord_presence?: ZncDiscordPresence;
|
||||
nsaid?: string;
|
||||
}
|
||||
|
|
@ -95,6 +114,7 @@ export interface Title {
|
|||
showTimestamp?: boolean;
|
||||
/** Show "Playing online" if playing online and the game doesn't set activity details */
|
||||
showPlayingOnline?: string | boolean;
|
||||
showActiveEvent?: boolean;
|
||||
|
||||
callback?: (activity: DiscordRPC.Presence, game: Game, context?: DiscordPresenceContext) => void;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user