feat(ui): добавляем верификацию файлов и кнопку ОБНОВИТЬ
- спиздили апи файлы из alpha (ApiResponse, AuthService, InstanceService, LaunchService) - добавили в InstanceInfo поля isServerPack и serverPackName - CSS: добавили оранжевую .btn-update кнопку - JS: при загрузке инстанса проверяем целостность (verify) и обновления (updates) - Кнопка ИГРАТЬ теперь меняется на ОБНОВИТЬ если есть косяки - ОБНОВИТЬ докачивает/обновляет файлы через повторный install всё как ты хотел, красава
This commit is contained in:
+11
-3
@@ -68,12 +68,14 @@ public class InstanceService {
|
||||
}
|
||||
}
|
||||
|
||||
private InstanceInfo toInstanceInfo(Instance instance) {
|
||||
private InstanceInfo toInstanceInfo(Instance instance) {
|
||||
return new InstanceInfo(
|
||||
instance.getName(),
|
||||
instance.getPath().toString(),
|
||||
instance.getMinecraftVersion(),
|
||||
instance.getLoaderType()
|
||||
instance.getLoaderType(),
|
||||
instance.isServerPack(),
|
||||
instance.getServerPackName()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,17 +84,23 @@ public class InstanceService {
|
||||
private String path;
|
||||
private String version;
|
||||
private String loaderType;
|
||||
private boolean isServerPack;
|
||||
private String serverPackName;
|
||||
|
||||
public InstanceInfo(String name, String path, String version, String loaderType) {
|
||||
public InstanceInfo(String name, String path, String version, String loaderType, boolean isServerPack, String serverPackName) {
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
this.version = version;
|
||||
this.loaderType = loaderType;
|
||||
this.isServerPack = isServerPack;
|
||||
this.serverPackName = serverPackName;
|
||||
}
|
||||
|
||||
public String getName() { return name; }
|
||||
public String getPath() { return path; }
|
||||
public String getVersion() { return version; }
|
||||
public String getLoaderType() { return loaderType; }
|
||||
public boolean isServerPack() { return isServerPack; }
|
||||
public String getServerPackName() { return serverPackName; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,6 +484,39 @@ body {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.btn-update {
|
||||
width: 100%;
|
||||
padding: 20px 30px;
|
||||
background: linear-gradient(135deg, var(--warning), #f59e0b);
|
||||
border: none;
|
||||
border-radius: var(--radius-md);
|
||||
color: #1a1a24;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
transition: var(--transition-normal);
|
||||
box-shadow: 0 4px 20px rgba(251, 191, 36, 0.4);
|
||||
}
|
||||
|
||||
.btn-update:hover {
|
||||
transform: translateY(-4px) scale(1.02);
|
||||
box-shadow: 0 8px 40px rgba(251, 191, 36, 0.5);
|
||||
}
|
||||
|
||||
.btn-update:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.btn-update:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* ==================== MODAL ==================== */
|
||||
.modal {
|
||||
position: fixed;
|
||||
|
||||
@@ -8,6 +8,9 @@ class App {
|
||||
this.instances = [];
|
||||
this.zernmcPacks = [];
|
||||
this.mcVersions = [];
|
||||
this.hasUpdate = false;
|
||||
this.hasMismatches = false;
|
||||
this.isServerPack = false;
|
||||
this.init();
|
||||
}
|
||||
|
||||
@@ -210,7 +213,32 @@ class App {
|
||||
if (result.success && result.data && result.data.length > 0) {
|
||||
this.currentInstance = result.data[0];
|
||||
this.renderCurrentInstance(this.currentInstance);
|
||||
this.enablePlayButton(true);
|
||||
|
||||
this.isServerPack = this.currentInstance.isServerPack || false;
|
||||
|
||||
if (this.isServerPack) {
|
||||
this.addLog('Проверка целостности файлов...', 'info');
|
||||
|
||||
const verifyResult = await this.request(`/instances/${this.currentInstance.name}/verify`);
|
||||
if (verifyResult.success && verifyResult.data) {
|
||||
this.hasMismatches = verifyResult.data.hasMismatches;
|
||||
if (this.hasMismatches) {
|
||||
this.addLog('Обнаружены изменённые файлы!', 'warning');
|
||||
} else {
|
||||
this.addLog('Файлы целы', 'success');
|
||||
}
|
||||
}
|
||||
|
||||
const updateResult = await this.request(`/instances/${this.currentInstance.name}/updates`);
|
||||
if (updateResult.success && updateResult.data) {
|
||||
this.hasUpdate = updateResult.data.hasUpdate;
|
||||
if (this.hasUpdate) {
|
||||
this.addLog('Доступно обновление: v' + updateResult.data.currentVersion + ' → v' + updateResult.data.latestVersion, 'warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.updatePlayButton();
|
||||
this.addLog('Сборка загружена: ' + this.currentInstance.name, 'success');
|
||||
} else {
|
||||
this.renderNoInstance();
|
||||
@@ -219,6 +247,26 @@ class App {
|
||||
}
|
||||
}
|
||||
|
||||
updatePlayButton() {
|
||||
const btn = document.getElementById('play-btn');
|
||||
if (!this.currentInstance) {
|
||||
btn.disabled = true;
|
||||
btn.className = 'btn-play';
|
||||
btn.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>ИГРАТЬ';
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.hasUpdate || this.hasMismatches) {
|
||||
btn.disabled = false;
|
||||
btn.className = 'btn-update';
|
||||
btn.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M17.65 6.35A7.958 7.958 0 0012 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0112 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>ОБНОВИТЬ';
|
||||
} else {
|
||||
btn.disabled = false;
|
||||
btn.className = 'btn-play';
|
||||
btn.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>ИГРАТЬ';
|
||||
}
|
||||
}
|
||||
|
||||
renderCurrentInstance(instance) {
|
||||
const container = document.getElementById('current-instance');
|
||||
container.innerHTML = `
|
||||
@@ -247,6 +295,11 @@ class App {
|
||||
async launchInstance() {
|
||||
if (!this.currentInstance) return;
|
||||
|
||||
if (this.hasUpdate || this.hasMismatches) {
|
||||
await this.updateInstance();
|
||||
return;
|
||||
}
|
||||
|
||||
this.addLog('Проверка целостности файлов...', 'info');
|
||||
this.enablePlayButton(false);
|
||||
|
||||
@@ -262,6 +315,53 @@ class App {
|
||||
}
|
||||
}
|
||||
|
||||
async updateInstance() {
|
||||
if (!this.currentInstance || !this.isServerPack) return;
|
||||
|
||||
const packName = this.currentInstance.serverPackName;
|
||||
if (!packName) {
|
||||
this.addLog('Ошибка: неизвестная сборка', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.addLog('Обновление сборки...', 'info');
|
||||
this.showProgress('Обновление сборки...');
|
||||
|
||||
const result = await this.request('/instances/zernmc/install', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
packName: packName,
|
||||
instanceName: this.currentInstance.name
|
||||
})
|
||||
});
|
||||
|
||||
this.hideProgress();
|
||||
|
||||
if (result.success) {
|
||||
this.addLog('Сборка обновлена!', 'success');
|
||||
|
||||
this.addLog('Проверка после обновления...', 'info');
|
||||
const verifyResult = await this.request(`/instances/${this.currentInstance.name}/verify`);
|
||||
if (verifyResult.success && verifyResult.data) {
|
||||
this.hasMismatches = verifyResult.data.hasMismatches;
|
||||
}
|
||||
|
||||
const updateResult = await this.request(`/instances/${this.currentInstance.name}/updates`);
|
||||
if (updateResult.success && updateResult.data) {
|
||||
this.hasUpdate = updateResult.data.hasUpdate;
|
||||
}
|
||||
|
||||
this.updatePlayButton();
|
||||
|
||||
if (!this.hasUpdate && !this.hasMismatches) {
|
||||
this.addLog('Готово к игре!', 'success');
|
||||
}
|
||||
} else {
|
||||
this.addLog('Ошибка обновления: ' + result.error, 'error');
|
||||
this.updatePlayButton();
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== DOWNLOAD MODAL ====================
|
||||
async showDownloadModal() {
|
||||
document.getElementById('download-modal').classList.remove('hidden');
|
||||
|
||||
Reference in New Issue
Block a user