629 lines
15 KiB
TypeScript
629 lines
15 KiB
TypeScript
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 || 'Не удалось загрузить плащ');
|
||
}
|
||
}
|