Files
popa-launcher/src/renderer/api.ts
2025-07-21 10:55:55 +05:00

629 lines
15 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const API_BASE_URL = 'https://minecraft.api.popa-popa.ru';
export interface Player {
uuid: string;
username: string;
skin_url: string;
cloak_url: string;
coins: number;
is_active: boolean;
created_at: string;
}
export interface CoinsResponse {
username: string;
coins: number;
total_time_played: {
seconds: number;
formatted: string;
};
}
export interface Cape {
cape_id: string;
cape_name: string;
cape_description: string;
image_url: string;
purchased_at: string;
is_active: boolean;
}
export type CapesResponse = Cape[];
export interface StoreCape {
id: string;
name: string;
description: string;
price: number;
image_url: string;
}
export type StoreCapesResponse = StoreCape[];
export interface ApiError {
message: string;
details?: string;
}
export interface Server {
id: string;
name: string;
ip: string;
port: number;
description: string;
online_players: number;
max_players: number;
last_activity: string;
}
export interface ActiveServersResponse {
servers: Server[];
}
export interface OnlinePlayersResponse {
server: {
id: string;
name: string;
};
online_players: {
// Это массив объектов, а не один объект
username: string;
uuid: string;
online_since: string;
}[]; // Добавьте [] здесь чтобы указать, что это массив
count: number;
}
export interface MarketplaceResponse {
items: [
{
_id: string;
id: string;
material: string;
amount: number;
price: number;
seller_name: string;
server_ip: string;
display_name: string | null;
lore: string | null;
enchants: string | null;
item_data: {
slot: number;
material: string;
amount: number;
};
created_at: string;
},
];
total: number;
page: number;
pages: number;
}
export interface MarketplaceItemResponse {
_id: string;
id: string;
material: string;
amount: number;
price: number;
seller_name: string;
server_ip: string;
display_name: string | null;
lore: string | null;
enchants: string | null;
item_data: {
slot: number;
material: string;
amount: number;
};
created_at: string;
}
export interface SellItemResponse {
message: string;
}
export interface BuyItemResponse {
message: string;
}
export interface PlayerInventoryResponse {
status: string;
request_id: string;
}
export interface PlayerInventory {
status: string;
result: {
player_name: string;
server_ip: string;
inventory_data: PlayerInventoryItem[];
};
}
export interface PlayerInventoryItem {
slot: number;
material: string;
amount: number;
enchants: {
[key: string]: number;
};
}
export interface MarketplaceOperation {
id: string;
type: 'sell' | 'buy';
player_name: string;
slot_index?: number;
amount?: number;
price: number;
server_ip: string;
status: 'pending' | 'completed' | 'failed';
item_id?: string;
error?: string;
created_at: string;
item_data?: any;
}
export interface OperationsResponse {
operations: MarketplaceOperation[];
}
export interface RegisterUserResponse {
status: string;
uuid: string;
}
export interface GenerateVerificationCodeResponse {
status: string;
code: string;
}
export interface VerificationStatusResponse {
is_verified: boolean;
}
export async function getVerificationStatus(
username: string,
): Promise<VerificationStatusResponse> {
const response = await fetch(
`${API_BASE_URL}/auth/verification_status/${username}`,
);
if (!response.ok) {
throw new Error('Не удалось получить статус верификации');
}
return await response.json();
}
export async function generateVerificationCode(
username: string,
): Promise<GenerateVerificationCodeResponse> {
const response = await fetch(
`${API_BASE_URL}/auth/generate_code?username=${username}`,
{
method: 'POST',
},
);
if (!response.ok) {
throw new Error('Не удалось сгенерировать код верификации');
}
return await response.json();
}
export async function registerUser(
username: string,
password: string,
): Promise<RegisterUserResponse> {
const response = await fetch(`${API_BASE_URL}/auth/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
password,
}),
});
if (!response.ok) {
throw new Error('Не удалось зарегистрировать пользователя');
}
return await response.json();
}
export async function getPlayerInventory(
request_id: string,
): Promise<PlayerInventory> {
const response = await fetch(
`${API_BASE_URL}/api/server/inventory/${request_id}`,
);
if (!response.ok) {
throw new Error('Не удалось получить инвентарь игрока');
}
return await response.json();
}
export async function RequestPlayerInventory(
server_ip: string,
player_name: string,
): Promise<PlayerInventoryResponse> {
const response = await fetch(`${API_BASE_URL}/api/server/inventory`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
server_ip: server_ip,
player_name: player_name,
}),
});
if (!response.ok) {
throw new Error('Не удалось получить инвентарь игрока');
}
return await response.json();
}
export async function buyItem(
buyer_username: string,
item_id: string,
): Promise<{ status: string; operation_id: string; message: string }> {
const response = await fetch(
`${API_BASE_URL}/api/marketplace/items/buy/${item_id}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: buyer_username,
}),
},
);
if (!response.ok) {
const errorData = await response.json();
throw new Error(
errorData.message || errorData.detail || 'Не удалось купить предмет',
);
}
return await response.json();
}
export async function confirmMarketplaceOperation(
operation_id: string,
status: string = 'success',
error?: string,
): Promise<{ status: string }> {
const response = await fetch(
`${API_BASE_URL}/api/marketplace/operations/confirm`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
operation_id,
status,
error,
}),
},
);
if (!response.ok) {
throw new Error('Не удалось подтвердить операцию');
}
return await response.json();
}
export async function submitItemDetails(
operation_id: string,
item_data: any,
): Promise<{ status: string }> {
const response = await fetch(
`${API_BASE_URL}/api/marketplace/items/details`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
operation_id,
item_data,
}),
},
);
if (!response.ok) {
throw new Error('Не удалось отправить данные предмета');
}
return await response.json();
}
export async function sellItem(
username: string,
slot_index: number,
amount: number,
price: number,
server_ip: string,
): Promise<{ status: string; operation_id: string }> {
const response = await fetch(`${API_BASE_URL}/api/marketplace/items/sell`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
slot_index,
amount,
price,
server_ip,
}),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(
errorData.message ||
errorData.detail ||
'Не удалось выставить предмет на продажу',
);
}
return await response.json();
}
export async function fetchMarketplaceItem(
item_id: string,
): Promise<MarketplaceItemResponse> {
const response = await fetch(
`${API_BASE_URL}/api/marketplace/items/${item_id}`,
);
if (!response.ok) {
throw new Error('Не удалось получить рынок');
}
return await response.json();
}
export async function fetchMarketplace(
server_ip: string,
page: number,
limit: number,
): Promise<MarketplaceResponse> {
// Создаем URL с параметрами запроса
const url = new URL(`${API_BASE_URL}/api/marketplace/items`);
url.searchParams.append('server_ip', server_ip);
url.searchParams.append('page', page.toString());
url.searchParams.append('limit', limit.toString());
const response = await fetch(url.toString());
if (!response.ok) {
throw new Error('Не удалось получить предметы рынка');
}
return await response.json();
}
// Исправьте тип возвращаемого значения
export async function fetchActiveServers(): Promise<Server[]> {
const response = await fetch(`${API_BASE_URL}/api/pranks/servers`);
if (!response.ok) {
throw new Error('Не удалось получить активные сервера');
}
return await response.json();
}
export async function fetchOnlinePlayers(
server_id: string,
): Promise<OnlinePlayersResponse> {
const response = await fetch(
`${API_BASE_URL}/api/pranks/servers/${server_id}/players`,
);
if (!response.ok) {
throw new Error('Не удалось получить онлайн игроков');
}
return await response.json();
}
// Получение информации о игроке
export async function fetchPlayer(uuid: string): Promise<Player> {
try {
const response = await fetch(`${API_BASE_URL}/users/${uuid}`);
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Ошибка получения данных игрока');
}
return await response.json();
} catch (error) {
console.error('API ошибка:', error);
throw error;
}
}
export async function fetchCoins(username: string): Promise<CoinsResponse> {
try {
const response = await fetch(`${API_BASE_URL}/users/${username}/coins`);
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Ошибка получения данных игрока');
}
return await response.json();
} catch (error) {
console.error('API ошибка:', error);
throw error;
}
}
export async function fetchCapes(username: string): Promise<CapesResponse> {
try {
const response = await fetch(
`${API_BASE_URL}/store/user/${username}/capes`,
);
if (!response.ok) {
return []; // Если плащи не найдены, возвращаем пустой массив
}
return await response.json();
} catch (error) {
console.error('API ошибка:', error);
return []; // В случае ошибки возвращаем пустой массив
}
}
export async function purchaseCape(
username: string,
cape_id: string,
): Promise<void> {
// Создаем URL с query-параметрами
const url = new URL(`${API_BASE_URL}/store/purchase/cape`);
url.searchParams.append('username', username);
url.searchParams.append('cape_id', cape_id);
const response = await fetch(url.toString(), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
// Не нужно отправлять тело запроса
// body: JSON.stringify({
// username: username,
// cape_id: cape_id,
// }),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(
errorData.message ||
errorData.detail?.toString() ||
'Не удалось купить плащ',
);
}
}
export async function fetchCapesStore(): Promise<StoreCape[]> {
try {
const response = await fetch(`${API_BASE_URL}/store/capes`);
if (!response.ok) {
return [];
}
return await response.json();
} catch (error) {
console.error('API ошибка:', error);
return [];
}
}
export async function activateCape(
username: string,
cape_id: string,
): Promise<void> {
const response = await fetch(
`${API_BASE_URL}/store/user/${username}/capes/activate/${cape_id}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
cape_id: cape_id,
}),
},
);
if (!response.ok) {
throw new Error('Не удалось активировать плащ');
}
}
export async function deactivateCape(
username: string,
cape_id: string,
): Promise<void> {
const response = await fetch(
`${API_BASE_URL}/store/user/${username}/capes/deactivate/${cape_id}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
cape_id: cape_id,
}),
},
);
if (!response.ok) {
throw new Error('Не удалось деактивировать плащ');
}
}
// Загрузка скина
export async function uploadSkin(
username: string,
skinFile: File,
skinModel: string,
): Promise<void> {
const savedConfig = localStorage.getItem('launcher_config');
let accessToken = '';
let clientToken = '';
if (savedConfig) {
const config = JSON.parse(savedConfig);
accessToken = config.accessToken || '';
clientToken = config.clientToken || '';
}
const formData = new FormData();
formData.append('skin_file', skinFile);
formData.append('skin_model', skinModel);
formData.append('accessToken', accessToken);
formData.append('clientToken', clientToken);
const response = await fetch(`${API_BASE_URL}/user/${username}/skin`, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Не удалось загрузить скин');
}
}
// Получение токенов из локального хранилища
export function getAuthTokens(): { accessToken: string; clientToken: string } {
const savedConfig = localStorage.getItem('launcher_config');
let accessToken = '';
let clientToken = '';
if (savedConfig) {
const config = JSON.parse(savedConfig);
accessToken = config.accessToken || '';
clientToken = config.clientToken || '';
}
return { accessToken, clientToken };
}
// Загрузка плаща
export async function uploadCape(
username: string,
capeFile: File,
): Promise<void> {
const { accessToken, clientToken } = getAuthTokens();
const formData = new FormData();
formData.append('cape_file', capeFile);
formData.append('accessToken', accessToken);
formData.append('clientToken', clientToken);
const response = await fetch(`${API_BASE_URL}/user/${username}/cape`, {
method: 'POST',
body: formData,
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Не удалось загрузить плащ');
}
}