mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-01 14:02:18 +02:00
migrate unlink discord to pokerogue-api
This commit is contained in:
parent
70f78d1060
commit
8ac7ad4221
@ -1,4 +1,4 @@
|
|||||||
VITE_BYPASS_LOGIN=0
|
VITE_BYPASS_LOGIN=0 # TODO: revert to `1`
|
||||||
VITE_BYPASS_TUTORIAL=0
|
VITE_BYPASS_TUTORIAL=0
|
||||||
VITE_SERVER_URL=http://localhost:8001
|
VITE_SERVER_URL=http://localhost:8001
|
||||||
VITE_DISCORD_CLIENT_ID=1234567890
|
VITE_DISCORD_CLIENT_ID=1234567890
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { bypassLogin } from "./battle-scene";
|
import { bypassLogin } from "./battle-scene";
|
||||||
import { pokerogueApi } from "./plugins/api/pokerogue-api";
|
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
||||||
import * as Utils from "./utils";
|
import * as Utils from "./utils";
|
||||||
|
|
||||||
export interface UserInfo {
|
export interface UserInfo {
|
||||||
|
74
src/plugins/api/api.ts
Normal file
74
src/plugins/api/api.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { SESSION_ID_COOKIE_NAME } from "#app/constants";
|
||||||
|
import { getCookie } from "#app/utils";
|
||||||
|
|
||||||
|
type DataType = "json" | "form-urlencoded";
|
||||||
|
|
||||||
|
export abstract class Api {
|
||||||
|
//#region Fields
|
||||||
|
|
||||||
|
protected readonly base: string;
|
||||||
|
|
||||||
|
//#region Public
|
||||||
|
|
||||||
|
constructor(base: string) {
|
||||||
|
this.base = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region Protected
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a GET request.
|
||||||
|
* @param path The path to send the request to.
|
||||||
|
*/
|
||||||
|
protected async doGet(path: string) {
|
||||||
|
return this.doFetch(path, { method: "GET" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a POST request.
|
||||||
|
* @param path THe path to send the request to.
|
||||||
|
* @param bodyData The body-data to send.
|
||||||
|
* @param dataType The data-type of the {@linkcode bodyData}.
|
||||||
|
*/
|
||||||
|
protected async doPost<D = undefined>(path: string, bodyData?: D, dataType: DataType = "json") {
|
||||||
|
let body: string | undefined = undefined;
|
||||||
|
const headers: HeadersInit = {};
|
||||||
|
|
||||||
|
if (bodyData) {
|
||||||
|
if (dataType === "json") {
|
||||||
|
body = typeof bodyData === "string" ? bodyData : JSON.stringify(bodyData);
|
||||||
|
headers["Content-Type"] = "application/json";
|
||||||
|
} else if (dataType === "form-urlencoded") {
|
||||||
|
if (bodyData instanceof Object) {
|
||||||
|
body = new URLSearchParams(Object.entries<any>(bodyData).map(([k, v]) => [k, v.toString()])).toString();
|
||||||
|
} else {
|
||||||
|
console.warn("Could not add body data to form-urlencoded!", bodyData);
|
||||||
|
}
|
||||||
|
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
||||||
|
} else {
|
||||||
|
console.warn(`Unsupported data type: ${dataType}`);
|
||||||
|
body = String(bodyData);
|
||||||
|
headers["Content-Type"] = "text/plain";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.doFetch(path, { method: "POST", body, headers });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generic request helper.
|
||||||
|
* @param path The path to send the request to.
|
||||||
|
* @param config The request {@linkcode RequestInit | Configuration}.
|
||||||
|
*/
|
||||||
|
protected async doFetch(path: string, config: RequestInit): Promise<Response> {
|
||||||
|
config.headers = {
|
||||||
|
...config.headers,
|
||||||
|
Authorization: getCookie(SESSION_ID_COOKIE_NAME),
|
||||||
|
"Content-Type": config.headers?.["Content-Type"] ?? "application/json",
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`Sending ${config.method ?? "GET"} request to: `, this.base + path, config);
|
||||||
|
|
||||||
|
return await fetch(this.base + path, config);
|
||||||
|
}
|
||||||
|
}
|
4
src/plugins/api/models/LinkAccountToDiscordId.ts
Normal file
4
src/plugins/api/models/LinkAccountToDiscordId.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface LinkAccountToDiscordIdRequest {
|
||||||
|
username: string;
|
||||||
|
discordId: string;
|
||||||
|
}
|
27
src/plugins/api/pokerogue-admin-api.ts
Normal file
27
src/plugins/api/pokerogue-admin-api.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Api } from "#app/plugins/api/api";
|
||||||
|
import type { LinkAccountToDiscordIdRequest } from "#app/plugins/api/models/LinkAccountToDiscordId";
|
||||||
|
|
||||||
|
export class PokerogueAdminApi extends Api {
|
||||||
|
/**
|
||||||
|
* Links an account to a discord id.
|
||||||
|
* @param linkData The {@linkcode LinkAccountToDiscordIdRequest} to send
|
||||||
|
* @returns `true` if successful, `false` if not
|
||||||
|
*/
|
||||||
|
public async linkAccountToDiscordId(linkData: LinkAccountToDiscordIdRequest) {
|
||||||
|
try {
|
||||||
|
const linkArr = Object.entries(linkData).map(([key, value]) => [key, String(value)]);
|
||||||
|
const params = new URLSearchParams(linkArr);
|
||||||
|
const response = await this.doPost("/admin/account/discord-link", params, "form-urlencoded");
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.warn("Could not link account with discord!", response.status, response.statusText);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn("Could not link account with discord!", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,29 @@
|
|||||||
import type { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api";
|
import type { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api";
|
||||||
import { loggedInUser } from "#app/account";
|
import { loggedInUser } from "#app/account";
|
||||||
import { MAX_INT_ATTR_VALUE, SESSION_ID_COOKIE_NAME } from "#app/constants";
|
import { MAX_INT_ATTR_VALUE, SESSION_ID_COOKIE_NAME } from "#app/constants";
|
||||||
|
import { Api } from "#app/plugins/api/api";
|
||||||
|
import type { AccountInfoResponse } from "#app/plugins/api/models/AccountInfo";
|
||||||
|
import type { AccountLoginRequest, AccountLoginResponse } from "#app/plugins/api/models/AccountLogin";
|
||||||
|
import type { TitleStatsResponse } from "#app/plugins/api/models/TitleStats";
|
||||||
|
import type { UpdateAllSavedataRequest } from "#app/plugins/api/models/UpdateAllSavedata";
|
||||||
|
import type { UpdateSessionSavedataRequest } from "#app/plugins/api/models/UpdateSessionSavedata";
|
||||||
|
import type { UpdateSystemSavedataRequest } from "#app/plugins/api/models/UpdateSystemSavedata";
|
||||||
|
import type { VerifySavedataResponse } from "#app/plugins/api/models/VerifySavedata";
|
||||||
import type { SessionSaveData } from "#app/system/game-data";
|
import type { SessionSaveData } from "#app/system/game-data";
|
||||||
import type { RankingEntry, ScoreboardCategory } from "#app/ui/daily-run-scoreboard";
|
import type { RankingEntry, ScoreboardCategory } from "#app/ui/daily-run-scoreboard";
|
||||||
import { getCookie, removeCookie, setCookie } from "#app/utils";
|
import { removeCookie, setCookie } from "#app/utils";
|
||||||
import type { AccountInfoResponse } from "./models/AccountInfo";
|
import { PokerogueAdminApi } from "#app/plugins/api/pokerogue-admin-api";
|
||||||
import type { AccountLoginRequest, AccountLoginResponse } from "./models/AccountLogin";
|
|
||||||
import type { TitleStatsResponse } from "./models/TitleStats";
|
|
||||||
import type { UpdateAllSavedataRequest } from "./models/UpdateAllSavedata";
|
|
||||||
import type { UpdateSessionSavedataRequest } from "./models/UpdateSessionSavedata";
|
|
||||||
import type { UpdateSystemSavedataRequest } from "./models/UpdateSystemSavedata";
|
|
||||||
import type { VerifySavedataResponse } from "./models/VerifySavedata";
|
|
||||||
|
|
||||||
type DataType = "json" | "form-urlencoded";
|
export class PokerogueApi extends Api {
|
||||||
|
|
||||||
export class PokerogueApi {
|
|
||||||
//#region Fields
|
//#region Fields
|
||||||
|
|
||||||
private readonly base: string;
|
public readonly admin: PokerogueAdminApi;
|
||||||
|
|
||||||
//#region Public
|
//#region Public
|
||||||
|
|
||||||
constructor(base: string) {
|
constructor(base: string) {
|
||||||
this.base = base;
|
super(base);
|
||||||
|
this.admin = new PokerogueAdminApi(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -370,61 +371,26 @@ export class PokerogueApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region Private
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a GET request.
|
* Unlink the currently logged in user from Discord.
|
||||||
* @param path The path to send the request to.
|
* @returns `true` if unlinking was successful, `false` if not
|
||||||
*/
|
*/
|
||||||
private async doGet(path: string) {
|
public async unlinkDiscord() {
|
||||||
return this.doFetch(path, { method: "GET" });
|
try {
|
||||||
}
|
const response = await this.doPost("/unlink/discord");
|
||||||
|
if (response.ok) {
|
||||||
/**
|
return true;
|
||||||
* Send a POST request.
|
|
||||||
* @param path THe path to send the request to.
|
|
||||||
* @param bodyData The body-data to send.
|
|
||||||
* @param dataType The data-type of the {@linkcode bodyData}.
|
|
||||||
*/
|
|
||||||
private async doPost<D>(path: string, bodyData: D, dataType: DataType = "json") {
|
|
||||||
let body: string = "";
|
|
||||||
const headers: HeadersInit = {};
|
|
||||||
|
|
||||||
if (dataType === "json") {
|
|
||||||
body = typeof bodyData === "string" ? bodyData : JSON.stringify(bodyData);
|
|
||||||
headers["Content-Type"] = "application/json";
|
|
||||||
} else if (dataType === "form-urlencoded") {
|
|
||||||
if (bodyData instanceof Object) {
|
|
||||||
body = new URLSearchParams(Object.entries<any>(bodyData).map(([k, v]) => [k, v.toString()])).toString();
|
|
||||||
} else {
|
} else {
|
||||||
console.warn("Could not add body data to form-urlencoded!", bodyData);
|
console.warn(`Unlink failed (${response.status}: ${response.statusText})`);
|
||||||
}
|
}
|
||||||
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
} catch (err) {
|
||||||
} else {
|
console.warn("Could not unlink discord!", err);
|
||||||
console.warn(`Unsupported data type: ${dataType}`);
|
|
||||||
body = String(bodyData);
|
|
||||||
headers["Content-Type"] = "text/plain";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.doFetch(path, { method: "POST", body, headers });
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//#region Private
|
||||||
* A generic request helper.
|
|
||||||
* @param path The path to send the request to.
|
|
||||||
* @param config The request {@linkcode RequestInit | Configuration}.
|
|
||||||
*/
|
|
||||||
private async doFetch(path: string, config: RequestInit): Promise<Response> {
|
|
||||||
config.headers = {
|
|
||||||
...config.headers,
|
|
||||||
Authorization: getCookie(SESSION_ID_COOKIE_NAME),
|
|
||||||
"Content-Type": config.headers?.["Content-Type"] ?? "application/json",
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log(`Sending ${config.method ?? "GET"} request to: `, this.base + path, config);
|
|
||||||
|
|
||||||
return await fetch(this.base + path, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async isLocalMode(): Promise<boolean> {
|
private async isLocalMode(): Promise<boolean> {
|
||||||
return (
|
return (
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { ModalConfig } from "./modal-ui-handler";
|
import { ModalConfig } from "./modal-ui-handler";
|
||||||
import { Mode } from "./ui";
|
import { Mode } from "./ui";
|
||||||
import * as Utils from "../utils";
|
|
||||||
import { FormModalUiHandler } from "./form-modal-ui-handler";
|
import { FormModalUiHandler } from "./form-modal-ui-handler";
|
||||||
import { Button } from "#app/enums/buttons";
|
import { Button } from "#app/enums/buttons";
|
||||||
|
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
||||||
|
|
||||||
export default class AdminUiHandler extends FormModalUiHandler {
|
export default class AdminUiHandler extends FormModalUiHandler {
|
||||||
|
|
||||||
@ -61,17 +61,14 @@ export default class AdminUiHandler extends FormModalUiHandler {
|
|||||||
if (!this.inputs[1].text) {
|
if (!this.inputs[1].text) {
|
||||||
return onFail("Discord Id is required");
|
return onFail("Discord Id is required");
|
||||||
}
|
}
|
||||||
Utils.apiPost("admin/account/discord-link", `username=${encodeURIComponent(this.inputs[0].text)}&discordId=${encodeURIComponent(this.inputs[1].text)}`, "application/x-www-form-urlencoded", true)
|
const [ usernameInput, discordIdInput ] = this.inputs;
|
||||||
.then(response => {
|
pokerogueApi.admin.linkAccountToDiscordId({ username: usernameInput.text, discordId: discordIdInput.text })
|
||||||
if (!response.ok) {
|
.then(isSuccess => {
|
||||||
console.error(response);
|
if (isSuccess) {
|
||||||
|
usernameInput.setText("");
|
||||||
|
discordIdInput.setText("");
|
||||||
}
|
}
|
||||||
this.inputs[0].setText("");
|
|
||||||
this.inputs[1].setText("");
|
|
||||||
this.scene.ui.revertMode();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
this.scene.ui.revertMode();
|
this.scene.ui.revertMode();
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
|
@ -514,10 +514,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
window.open(discordUrl, "_self");
|
window.open(discordUrl, "_self");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Utils.apiPost("/auth/discord/logout", undefined, undefined, true).then(res => {
|
pokerogueApi.unlinkDiscord().then(_isSuccess => {
|
||||||
if (!res.ok) {
|
|
||||||
console.error(`Unlink failed (${res.status}: ${res.statusText})`);
|
|
||||||
}
|
|
||||||
updateUserInfo().then(() => this.scene.reset(true, true));
|
updateUserInfo().then(() => this.scene.reset(true, true));
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { MoneyFormat } from "#enums/money-format";
|
import { MoneyFormat } from "#enums/money-format";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { pokerogueApi } from "./plugins/api/pokerogue-api";
|
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
||||||
|
|
||||||
export type nil = null | undefined;
|
export type nil = null | undefined;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user