Skip to content

Commit

Permalink
Implement Client#stw (fnbrjs#742)
Browse files Browse the repository at this point in the history
* Implement Client#stw

* rename methods

* Refactor Playlist Enum

* fix
  • Loading branch information
tnfAngel authored Dec 8, 2023
1 parent 4b2f937 commit 16c7e04
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 109 deletions.
53 changes: 20 additions & 33 deletions enums/Enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ export interface IPlatformEnum {
PLAYSTATION_5: IPlatform;
}

export interface PlaylistEnum {
SOLO: 'playlist_defaultsolo';
DUO: 'playlist_defaultduo';
TRIOS: 'playlist_trios';
SQUAD: 'playlist_defaultsquad';
CREATIVE: 'playlist_playgroundv2';
LEGO: 'playlist_juno';
ROCKET_RACING: 'playlist_delmar';
FESTIVAL: 'playlist_sparksrhythm';
}

export interface IPresenceOnlineTypeEnum {
ONLINE: IPresenceOnlineType;
CHAT: IPresenceOnlineType;
Expand Down Expand Up @@ -133,39 +144,15 @@ export const Platform: Readonly<IPlatformEnum> = Object.freeze({
PLAYSTATION_5: 'PS5',
});

export const Playlist = Object.freeze({
SOLO: {
playlistName: 'Playlist_DefaultSolo',
tournamentId: '',
eventWindowId: '',
linkId: {
mnemonic: 'playlist_defaultsolo',
},
},
DUO: {
playlistName: 'Playlist_DefaultDuo',
tournamentId: '',
eventWindowId: '',
linkId: {
mnemonic: 'playlist_defaultduo',
},
},
SQUAD: {
playlistName: 'Playlist_DefaultSquad',
tournamentId: '',
eventWindowId: '',
linkId: {
mnemonic: 'playlist_defaultsquad',
},
},
CREATIVE: {
playlistName: 'Playlist_PlaygroundV2',
tournamentId: '',
eventWindowId: '',
linkId: {
mnemonic: 'playlist_playgroundv2',
},
},
export const Playlist : Readonly<PlaylistEnum> = Object.freeze({
SOLO: 'playlist_defaultsolo',
DUO: 'playlist_defaultduo',
TRIOS: 'playlist_trios',
SQUAD: 'playlist_defaultsquad',
CREATIVE: 'playlist_playgroundv2',
LEGO: 'playlist_juno',
ROCKET_RACING: 'playlist_delmar',
FESTIVAL: 'playlist_sparksrhythm',
});

export const Language = Object.freeze({
Expand Down
85 changes: 9 additions & 76 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ import PartyPermissionError from './exceptions/PartyPermissionError';
import SentPartyJoinRequest from './structures/party/SentPartyJoinRequest';
import RadioStation from './structures/RadioStation';
import CreativeIslandNotFoundError from './exceptions/CreativeIslandNotFoundError';
import STWProfile from './structures/stw/STWProfile';
import Stats from './structures/Stats';
import NewsMessage from './structures/NewsMessage';
import STWNewsMessage from './structures/stw/STWNewsMessage';
import EventTimeoutError from './exceptions/EventTimeoutError';
import FortniteServerStatus from './structures/FortniteServerStatus';
import EpicgamesServerStatus from './structures/EpicgamesServerStatus';
Expand All @@ -35,14 +33,15 @@ import { AuthSessionStoreKey } from '../resources/enums';
import EpicgamesAPIError from './exceptions/EpicgamesAPIError';
import UserManager from './managers/UserManager';
import FriendManager from './managers/FriendManager';
import STWManager from './managers/STWManager';
import type { PresenceShow } from 'stanza/Constants';
import type {
BlurlStreamData, CreativeIslandData,
BlurlStreamMasterPlaylistData, CreativeDiscoveryPanel,
} from '../resources/httpResponses';
import type {
ClientOptions, ClientConfig, ClientEvents, PartyConfig, Schema,
Region, BlurlStream, STWWorldInfoData, Language, PartyData,
Region, BlurlStream, Language, PartyData,
PartySchema, PresenceOnlineType, BRAccountLevelData,
} from '../resources/structs';

Expand Down Expand Up @@ -122,6 +121,11 @@ class Client extends EventEmitter {
*/
public lastPartyMemberMeta?: Schema;

/**
* Fortnite: Save The World manager
*/
public stw: STWManager;

/**
* @param config The client's configuration options
*/
Expand Down Expand Up @@ -203,6 +207,8 @@ class Client extends EventEmitter {
this.party = undefined;
this.tournaments = new TournamentManager(this);
this.lastPartyMemberMeta = this.config.defaultPartyMemberMeta;

this.stw = new STWManager(this);
}

// Events
Expand Down Expand Up @@ -1213,79 +1219,6 @@ class Client extends EventEmitter {

return creativeDiscovery;
}

/* -------------------------------------------------------------------------- */
/* FORTNITE SAVE THE WORLD */
/* -------------------------------------------------------------------------- */

/**
* Fetches the Save The World profile for a players
* @param user The id or display name of the user
* @throws {UserNotFoundError} The user wasn't found
* @throws {EpicgamesAPIError}
*/
public async getSTWProfile(user: string) {
const resolvedUser = await this.user.fetch(user);
if (!resolvedUser) throw new UserNotFoundError(user);

let queryProfileResponse;
try {
queryProfileResponse = await this.http.epicgamesRequest({
method: 'POST',
url: `${Endpoints.MCP}/${resolvedUser.id}/public/QueryPublicProfile?profileId=campaign`,
headers: {
'Content-Type': 'application/json',
},
data: {},
}, AuthSessionStoreKey.Fortnite);
} catch (e) {
if (e instanceof EpicgamesAPIError && e.code === 'errors.com.epicgames.modules.profiles.profile_not_found') {
throw new UserNotFoundError(user);
}

throw e;
}

return new STWProfile(this, queryProfileResponse.profileChanges[0].profile, resolvedUser);
}

/**
* Fetches the current Save The World news
* @param language The language of the news
* @throws {EpicgamesAPIError}
*/
public async getSTWNews(language = this.config.language): Promise<STWNewsMessage[]> {
const newsResponse = await this.http.epicgamesRequest({
method: 'GET',
url: `${Endpoints.BR_NEWS}/savetheworldnews?lang=${language}`,
headers: {
'Accept-Language': language,
},
}, AuthSessionStoreKey.Fortnite);

return newsResponse.news.messages.map((m: any) => new STWNewsMessage(this, m));
}

/**
* Fetches the current Save The World world info
* @param language The language of the world info
* @throws {EpicgamesAPIError}
*/
public async getSTWWorldInfo(language = this.config.language): Promise<STWWorldInfoData> {
const worldInfoResponse = await this.http.epicgamesRequest({
method: 'GET',
url: Endpoints.STW_WORLD_INFO,
headers: {
'Accept-Language': language,
},
}, AuthSessionStoreKey.Fortnite);

return {
theaters: worldInfoResponse.theaters,
missions: worldInfoResponse.missions,
missionAlerts: worldInfoResponse.missionAlerts,
};
}
}

export default Client;
84 changes: 84 additions & 0 deletions src/managers/STWManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import Base from '../Base';
import UserNotFoundError from '../exceptions/UserNotFoundError';
import Endpoints from '../../resources/Endpoints';
import { AuthSessionStoreKey } from '../../resources/enums';
import EpicgamesAPIError from '../exceptions/EpicgamesAPIError';
import STWProfile from '../structures/stw/STWProfile';
import STWNewsMessage from '../structures/stw/STWNewsMessage';
import type { STWWorldInfoData } from '../../resources/structs';

/**
* Represents the client's STW manager
*/
class STWManager extends Base {
/**
* Fetches the Save The World profile for a players
* @param user The id or display name of the user
* @throws {UserNotFoundError} The user wasn't found
* @throws {EpicgamesAPIError}
*/
public async getProfile(user: string) {
const resolvedUser = await this.client.user.fetch(user);
if (!resolvedUser) throw new UserNotFoundError(user);

let queryProfileResponse;
try {
queryProfileResponse = await this.client.http.epicgamesRequest({
method: 'POST',
url: `${Endpoints.MCP}/${resolvedUser.id}/public/QueryPublicProfile?profileId=campaign`,
headers: {
'Content-Type': 'application/json',
},
data: {},
}, AuthSessionStoreKey.Fortnite);
} catch (e) {
if (e instanceof EpicgamesAPIError && e.code === 'errors.com.epicgames.modules.profiles.profile_not_found') {
throw new UserNotFoundError(user);
}

throw e;
}

return new STWProfile(this.client, queryProfileResponse.profileChanges[0].profile, resolvedUser);
}

/**
* Fetches the current Save The World news
* @param language The language of the news
* @throws {EpicgamesAPIError}
*/
public async getNews(language = this.client.config.language): Promise<STWNewsMessage[]> {
const newsResponse = await this.client.http.epicgamesRequest({
method: 'GET',
url: `${Endpoints.BR_NEWS}/savetheworldnews?lang=${language}`,
headers: {
'Accept-Language': language,
},
}, AuthSessionStoreKey.Fortnite);

return newsResponse.news.messages.map((m: any) => new STWNewsMessage(this.client, m));
}

/**
* Fetches the current Save The World world info
* @param language The language of the world info
* @throws {EpicgamesAPIError}
*/
public async getWorldInfo(language = this.client.config.language): Promise<STWWorldInfoData> {
const worldInfoResponse = await this.client.http.epicgamesRequest({
method: 'GET',
url: Endpoints.STW_WORLD_INFO,
headers: {
'Accept-Language': language,
},
}, AuthSessionStoreKey.Fortnite);

return {
theaters: worldInfoResponse.theaters,
missions: worldInfoResponse.missions,
missionAlerts: worldInfoResponse.missionAlerts,
};
}
}

export default STWManager;

0 comments on commit 16c7e04

Please sign in to comment.