Commit 308c696a authored by Chunchi Che's avatar Chunchi Che

add YgoAgent API

parent 046a9eda
Pipeline #27901 passed with stages
in 9 minutes and 38 seconds
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
"entertainWatchUrl": "wss://tiramisu.moecube.com:7923", "entertainWatchUrl": "wss://tiramisu.moecube.com:7923",
"userApi": "https://sapi.moecube.com:444/accounts/users/{username}.json", "userApi": "https://sapi.moecube.com:444/accounts/users/{username}.json",
"mdproServer": "https://rarnu.xyz:38443", "mdproServer": "https://rarnu.xyz:38443",
"agentServer": "https://t1v-n-e71fca19-w-0.tail0aad8.ts.net",
"streamInterval": 20, "streamInterval": 20,
"startDelay": 1000, "startDelay": 1000,
"ui": { "ui": {
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
"entertainWatchUrl": "wss://tiramisu.moecube.com:7923", "entertainWatchUrl": "wss://tiramisu.moecube.com:7923",
"userApi": "https://sapi.moecube.com:444/accounts/users/{username}.json", "userApi": "https://sapi.moecube.com:444/accounts/users/{username}.json",
"mdproServer": "https://rarnu.xyz:38443", "mdproServer": "https://rarnu.xyz:38443",
"agentServer": "https://t1v-n-e71fca19-w-0.tail0aad8.ts.net",
"streamInterval": 20, "streamInterval": 20,
"startDelay": 1000, "startDelay": 1000,
"ui": { "ui": {
......
...@@ -8,3 +8,15 @@ export * from "./ocgcore/ocgHelper"; ...@@ -8,3 +8,15 @@ export * from "./ocgcore/ocgHelper";
export * from "./strings"; export * from "./strings";
export * from "./superPreRelease"; export * from "./superPreRelease";
export * from "./ygoAgent"; export * from "./ygoAgent";
export async function handleHttps<T>(
resp: Response,
api: string,
): Promise<T | undefined> {
if (!resp.ok) {
console.error(`Https error from api ${api}! status: ${resp.status}`);
return undefined;
} else {
return await resp.json();
}
}
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { handleHttps } from "..";
import { MdproResp } from "./schema"; import { MdproResp } from "./schema";
import { handleHttps, mdproHeaders } from "./util"; import { mdproHeaders } from "./util";
const { mdproServer } = useConfig(); const { mdproServer } = useConfig();
const API_PATH = "/api/mdpro3/sync/single"; const API_PATH = "/api/mdpro3/sync/single";
......
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { handleHttps } from "..";
import { MdproResp } from "./schema"; import { MdproResp } from "./schema";
import { handleHttps, mdproHeaders } from "./util"; import { mdproHeaders } from "./util";
const { mdproServer } = useConfig(); const { mdproServer } = useConfig();
......
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { handleHttps } from "..";
import { MdproDeck, MdproResp } from "./schema"; import { MdproDeck, MdproResp } from "./schema";
import { handleHttps, mdproHeaders } from "./util"; import { mdproHeaders } from "./util";
const { mdproServer } = useConfig(); const { mdproServer } = useConfig();
......
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { pfetch } from "@/infra"; import { pfetch } from "@/infra";
import { handleHttps } from "..";
import { MdproDeck, MdproResp } from "./schema"; import { MdproDeck, MdproResp } from "./schema";
import { handleHttps, mdproHeaders } from "./util"; import { mdproHeaders } from "./util";
const { mdproServer } = useConfig(); const { mdproServer } = useConfig();
const API_PATH = "/api/mdpro3/sync/"; const API_PATH = "/api/mdpro3/sync/";
......
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { pfetch } from "@/infra"; import { pfetch } from "@/infra";
import { handleHttps } from "..";
import { MdproDeckLike, MdproResp } from "./schema"; import { MdproDeckLike, MdproResp } from "./schema";
import { handleHttps, mdproHeaders } from "./util"; import { mdproHeaders } from "./util";
const { mdproServer } = useConfig(); const { mdproServer } = useConfig();
const API_PATH = "api/mdpro3/deck/list"; const API_PATH = "api/mdpro3/deck/list";
......
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { handleHttps } from "..";
import { MdproResp } from "./schema"; import { MdproResp } from "./schema";
import { handleHttps, mdproHeaders } from "./util"; import { mdproHeaders } from "./util";
const { mdproServer } = useConfig(); const { mdproServer } = useConfig();
const API_PATH = "/api/mdpro3/sync/single"; const API_PATH = "/api/mdpro3/sync/single";
......
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { handleHttps } from "..";
import { MdproResp } from "./schema"; import { MdproResp } from "./schema";
import { handleHttps, mdproHeaders } from "./util"; import { mdproHeaders } from "./util";
const { mdproServer } = useConfig(); const { mdproServer } = useConfig();
const API_PATH = "/api/mdpro3/deck/public"; const API_PATH = "/api/mdpro3/deck/public";
......
...@@ -5,17 +5,3 @@ export function mdproHeaders(): Headers { ...@@ -5,17 +5,3 @@ export function mdproHeaders(): Headers {
return myHeaders; return myHeaders;
} }
export async function handleHttps<T>(
resp: Response,
api: string,
): Promise<T | undefined> {
if (!resp.ok) {
console.error(
`[Mdpro] Https error from api ${api}! status: ${resp.status}`,
);
return undefined;
} else {
return await resp.json();
}
}
export async function crateDuel() {} import { useConfig } from "@/config";
import { handleHttps } from "..";
import { agentHeader } from "./util";
const { agentServer } = useConfig();
const API_PATH = "v0/duels";
interface CreateResp {
duelId: string;
index: number;
}
export async function crateDuel(): Promise<CreateResp | undefined> {
const headers = agentHeader();
const resp = await fetch(`${agentServer}/${API_PATH}`, {
method: "POST",
headers,
redirect: "follow",
});
return await handleHttps(resp, API_PATH);
}
export async function deleteDuel() {} import { useConfig } from "@/config";
import { handleHttps } from "..";
import { agentHeader } from "./util";
const { agentServer } = useConfig();
const API_PATH = "/v0/duels";
export async function deleteDuel(duelId: string): Promise<void | undefined> {
const headers = agentHeader();
const apiPath = `${agentServer}/${API_PATH}/${duelId}`;
const resp = await fetch(apiPath, {
method: "DELETE",
headers,
redirect: "follow",
});
return await handleHttps(resp, apiPath);
}
export async function predictDuel() {} import { useConfig } from "@/config";
import { handleHttps } from "..";
import { Input, MsgResponse } from "./schema";
import { agentHeader } from "./util";
const { agentServer } = useConfig();
const apiPath = (duelId: string) => `${agentServer}/v0/duels/${duelId}/predict`;
interface PredictReq {
/**
* The index must be equal to the index from the previous response of the same duelId.
*/
index: number;
input: Input;
}
interface PredictResp {
/**
* It will be equal to the request's index + 1.
*/
index: number;
predict_results: MsgResponse;
}
export async function predictDuel(
duelId: string,
req: PredictReq,
): Promise<PredictResp | undefined> {
const headers = agentHeader();
const resp = await fetch(`${agentServer}/${apiPath(duelId)}`, {
method: "POST",
headers,
body: JSON.stringify(req),
redirect: "follow",
});
return await handleHttps(resp, apiPath(duelId));
}
/* Generated from https://1ewzpubatn.apifox.cn/api-178477939 */
export interface Input {
action_msg: ActionMsg;
cards: Card[];
global: Global;
}
export interface ActionMsg {
data: Data;
name: Name;
}
/**
* MsgSelectCard
*
* MsgSelectTribute
*
* MsgSelectSum
*
* MsgSelectIdleCmd
*
* MsgSelectChain
*
* MsgSelectPosition
*
* MsgSelectEffectYn
*
* MsgSelectYesNo
*
* MsgSelectBattleCmd
*
* MsgSelectUnselectCard
*
* MsgSelectOption
*
* MsgSelectPlace
*
* MsgSelectDisfield
*
* MsgAnnounceAttrib
*
* MsgAnnounceNumber
*/
export interface Data {
/**
* ignored
*/
cancelable?: boolean;
cards?: CardElement[];
max?: number;
min?: number;
/**
* the indices of the selected `cards`
*/
selected?: number[];
level_sum?: number;
/**
* size > 2 not supported
*/
must_cards?: MustCard[];
/**
* true not supported
*/
overflow?: boolean;
idle_cmds?: IdleCmd[];
chains?: Chain[];
forced?: boolean;
code?: number;
positions?: PositionElement[];
effect_description?: number;
location?: LocationObject;
battle_cmds?: BattleCmd[];
finishable?: boolean;
selectable_cards?: LocationObject[];
/**
* ignored
*/
selected_cards?: LocationObject[];
/**
* ignored
*/
options?: Option[];
/**
* > 1 not supported; 0 is considered as 1.
*
* != 1 not supported
*/
count?: number;
places?: Place[];
attributes?: AttributeElement[];
numbers?: number[];
[property: string]: any;
}
export enum AttributeElement {
Dark = "dark",
Divine = "divine",
Earth = "earth",
Fire = "fire",
Light = "light",
Water = "water",
Wind = "wind",
}
export interface BattleCmd {
cmd_type: BattleCmdCmdType;
data?: null | PurpleData;
}
export enum BattleCmdCmdType {
Activate = "activate",
Attack = "attack",
ToEp = "to_ep",
ToM2 = "to_m2",
}
export interface PurpleData {
card_info: CardInfo;
direct_attackable: boolean;
effect_description: number;
}
/**
* CardInfo
*/
export interface CardInfo {
code: number;
controller: Controller;
location: LocationEnum;
/**
* Start from 0
*/
sequence: number;
}
export enum Controller {
Me = "me",
Opponent = "opponent",
}
export enum LocationEnum {
Deck = "deck",
Extra = "extra",
Grave = "grave",
Hand = "hand",
Mzone = "mzone",
Removed = "removed",
Szone = "szone",
}
/**
* CardLocation
*/
export interface CardElement {
controller?: Controller;
location: LocationEnum | LocationObject;
/**
* if is overlay, this is the overlay index, starting from 0, else -1.
*/
overlay_sequence?: number;
/**
* Start from 0
*/
sequence?: number;
level?: number;
level1?: number;
/**
* ignored
*/
level2?: number;
}
/**
* CardLocation
*/
export interface LocationObject {
controller: Controller;
location: LocationEnum;
/**
* if is overlay, this is the overlay index, starting from 0, else -1.
*/
overlay_sequence: number;
/**
* Start from 0
*/
sequence: number;
}
export interface Chain {
code: number;
effect_description: number;
location: LocationObject;
}
export interface IdleCmd {
cmd_type: IdleCmdCmdType;
data?: null | FluffyData;
}
export enum IdleCmdCmdType {
Activate = "activate",
Mset = "mset",
Reposition = "reposition",
Set = "set",
SpSummon = "sp_summon",
Summon = "summon",
ToBp = "to_bp",
ToEp = "to_ep",
}
export interface FluffyData {
card_info: CardInfo;
effect_description: number;
}
export interface MustCard {
level1: number;
/**
* ignored
*/
level2: number;
location: LocationObject;
}
export interface Option {
code: number;
}
export interface Place {
controller: Controller;
location: LocationEnum;
/**
* Start from 0
*/
sequence: number;
}
export enum PositionElement {
Attack = "attack",
Defense = "defense",
Facedown = "facedown",
FacedownAttack = "facedown_attack",
FacedownDefense = "facedown_defense",
Faceup = "faceup",
FaceupAttack = "faceup_attack",
FaceupDefense = "faceup_defense",
}
export enum Name {
AnnounceAttrib = "announce_attrib",
AnnounceNumber = "announce_number",
SelectBattlecmd = "select_battlecmd",
SelectCard = "select_card",
SelectChain = "select_chain",
SelectDisfield = "select_disfield",
SelectEffectyn = "select_effectyn",
SelectIdlecmd = "select_idlecmd",
SelectOption = "select_option",
SelectPlace = "select_place",
SelectPosition = "select_position",
SelectSum = "select_sum",
SelectTribute = "select_tribute",
SelectUnselectCard = "select_unselect_card",
SelectYesno = "select_yesno",
}
/**
* Card
*/
export interface Card {
attack: number;
/**
* none for N/A or unknown or token.
*/
attribute: CardAttribute;
/**
* Card code from cards.cdb
*/
code: number;
controller: Controller;
/**
* Number of counters. If there are 2 types of counters or more, we consider only the first
* type of counter.
*/
counter: number;
defense: number;
/**
* Rank and link are also considered as level. 0 is N/A or unknown.
*/
level: number;
location: LocationEnum;
/**
* Whether the card effect is disabled or forbidden
*/
negated: boolean;
/**
* if is overlay, this is the overlay index, starting from 0, else -1.
*/
overlay_sequence: number;
/**
* If the monster is xyz material (overlay_sequence != -1), the position is faceup.
*/
position: CardPosition;
/**
* none for N/A or unknown or token.
*/
race: Race;
/**
* Sequence in ocgcore, 0 is N/A or unknown, if not, shoud start from 1. Only non-zero for
* cards in mzone, szone and grave.
*/
sequence: number;
types: Type[];
}
/**
* none for N/A or unknown or token.
*/
export enum CardAttribute {
Dark = "dark",
Divine = "divine",
Earth = "earth",
Fire = "fire",
Light = "light",
None = "none",
Water = "water",
Wind = "wind",
}
/**
* If the monster is xyz material (overlay_sequence != -1), the position is faceup.
*/
export enum CardPosition {
Attack = "attack",
Defense = "defense",
Facedown = "facedown",
FacedownAttack = "facedown_attack",
FacedownDefense = "facedown_defense",
Faceup = "faceup",
FaceupAttack = "faceup_attack",
FaceupDefense = "faceup_defense",
None = "none",
}
/**
* none for N/A or unknown or token.
*/
export enum Race {
Aqua = "aqua",
Beast = "beast",
BeastWarrior = "beast_warrior",
CreatorGod = "creator_god",
Cyberse = "cyberse",
Devine = "devine",
Dinosaur = "dinosaur",
Dragon = "dragon",
Fairy = "fairy",
Fiend = "fiend",
Fish = "fish",
Illusion = "illusion",
Insect = "insect",
Machine = "machine",
None = "none",
Plant = "plant",
Psycho = "psycho",
Pyro = "pyro",
Reptile = "reptile",
Rock = "rock",
SeaSerpent = "sea_serpent",
Spellcaster = "spellcaster",
Thunder = "thunder",
Warrior = "warrior",
Windbeast = "windbeast",
Wyrm = "wyrm",
Zombie = "zombie",
}
export enum Type {
Continuous = "continuous",
Counter = "counter",
Dual = "dual",
Effect = "effect",
Equip = "equip",
Field = "field",
Flip = "flip",
Fusion = "fusion",
Link = "link",
Monster = "monster",
Normal = "normal",
Pendulum = "pendulum",
QuickPlay = "quick_play",
Ritual = "ritual",
Special = "special",
Spell = "spell",
Spirit = "spirit",
Synchro = "synchro",
Token = "token",
Toon = "toon",
Trap = "trap",
TrapMonster = "trap_monster",
Tuner = "tuner",
Union = "union",
Xyz = "xyz",
}
/**
* Global
*/
export interface Global {
/**
* Whether me is the first player
*/
is_first: boolean;
is_my_turn: boolean;
my_lp: number;
op_lp: number;
phase: Phase;
turn: number;
}
export enum Phase {
Battle = "battle",
BattleStart = "battle_start",
BattleStep = "battle_step",
Damage = "damage",
DamageCalculation = "damage_calculation",
Draw = "draw",
End = "end",
Main1 = "main1",
Main2 = "main2",
Standby = "standby",
}
/**
* MsgResponse
*/
export interface MsgResponse {
action_probs: number[];
win_rate: number;
}
export function agentHeader(): Headers {
const myHeaders = new Headers();
myHeaders.append("User-Agent", "Apifox/1.0.0 (https://apifox.com)");
return myHeaders;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment