HLauncher — Лаунчер Hytale [2.1.1]

  • Автор темыbobobo
  • Дата начала
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

1.4.6 Hotfix

Исправлена корректная загрузка локализации при обновлении игры.
Исправлено уведомление ошибки, о несуществующей ошибке.
Переехали на новый сервер, скорость скачивания через "Прокси" должна работать у всех и в несколько раз быстрее.

Посмотреть подробности об этом обновлении...
 
F
Кто-то знает можно ли как-то уменьшить пинг на серверах? Просто с 3 друзьями пытались поиграть и у каждого в мире пинг красный возможно есть какое-то решение
 
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

1.4.7

Стабильная версия лаунчера 1.4.7 вышла из стадии бета-тестирования.
• Добавлена 4-я цифра для критических патчей.
• Переработана вся система работы с путями.
• Обнаружена критическая ошибка в игре, при работе с путями. Интегрировали свою уникальную систему виртуализации в лаунчер, при её активации - игра будет гарантированно работать, игнорируя проблемные пути и символы. (Удачи другим лаунчерам сделать подобное 😆)
• Добавлена виртуализация для запуска локального сервера.
• Исправлено...

Посмотреть подробности об этом обновлении...
 
ymka
@Chernyash, на сколько я понял, у вас виртуализация, это обычный mklink. В этом нет ничего необычного вроде.
 
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

1.5.0

• Переписана вся логика лаунчера, исправлены все старые проблемы с установкой, скачиванием и запуском.
• Ускорена работа скачивания, функция докачивания файлов при проблемах.
• Ускорена работа патчей (снова).
• Ускорена проверка ресурсов игры при запуске.Исправлены все проблемы с русификацией.
• Добавили кнопку "Исправить клиент" в настройки, если игра сломалась.
• Наш новый надёжный патч, теперь не обязательно обновлять лаунчер при выходе новой версии игры.
• Изменили дизайн, сделали его...

Посмотреть подробности об этом обновлении...
 
bobobo
JavaScript:
#[cfg(windows)]
use std::ffi::OsStr;
#[cfg(windows)]
use std::os::windows::ffi::OsStrExt;
#[cfg(windows)]
use std::ptr;
#[cfg(windows)]
use winapi::um::fileapi::GetLogicalDrives;
#[cfg(windows)]
use winapi::shared::minwindef::DWORD;
#[cfg(windows)]
use winapi::um::winnt::LPCWSTR;

#[cfg(windows)]
extern "system" {
    fn DefineDosDeviceW(
        dwFlags: DWORD,
        lpDeviceName: LPCWSTR,
        lpTargetPath: LPCWSTR,
    ) -> i32;
}

#[cfg(windows)]
const DDD_REMOVE_DEFINITION: u32 = 0x00000002;

#[cfg(windows)]
pub fn find_available_drive_letter() -> Result<char, String> {
    let drives = unsafe { GetLogicalDrives() };
    let mut occupied = Vec::new();
   
    for i in 0..26 {
        let bit = 1 << i;
        if (drives & bit) != 0 {
            let letter = (b'A' + i as u8) as char;
            occupied.push(letter);
        }
    }
   
    eprintln!("[VIRTUALIZATION] Occupied drive letters: {:?}", occupied);
   
    let preferred = ['Z', 'Y', 'X', 'W', 'V', 'U', 'T', 'S', 'R', 'Q', 'P', 'O', 'N', 'M', 'L', 'K', 'J', 'I', 'H', 'G', 'F', 'E', 'D'];
   
    for &letter in preferred.iter() {
        let bit = 1 << (letter as u8 - b'A');
        if (drives & bit) == 0 {
            eprintln!("[VIRTUALIZATION] Found available drive letter: {}", letter);
            return Ok(letter);
        }
    }
   
    Err("Нет свободных букв дисков. Отключите ненужные диски (сетевые, USB, виртуальные) в Проводнике и попробуйте снова.".to_string())
}

#[cfg(not(windows))]
pub fn find_available_drive_letter() -> Result<char, String> {
    Err("Path virtualization is only available on Windows".to_string())
}

#[cfg(windows)]
fn to_wide_string(s: &str) -> Vec<u16> {
    OsStr::new(s)
        .encode_wide()
        .chain(Some(0))
        .collect()
}

#[cfg(windows)]
pub fn create_virtual_drive(drive_letter: char, target_path: &str) -> Result<(), String> {
    use std::path::Path;
   
    let drive_str = format!("{}:", drive_letter);
    let drive_wide = to_wide_string(&drive_str);
    let target_wide = to_wide_string(target_path);
   
    eprintln!("[VIRTUALIZATION] Creating virtual drive {} -> {}", drive_str, target_path);
   
    let target_path_obj = Path::new(target_path);
    if !target_path_obj.exists() {
        eprintln!("[VIRTUALIZATION] ERROR: Target path does not exist: {}", target_path);
        return Err(format!("Target path does not exist: {}", target_path));
    }
   
    if !target_path_obj.is_dir() {
        eprintln!("[VIRTUALIZATION] ERROR: Target path is not a directory: {}", target_path);
        return Err(format!("Target path is not a directory: {}", target_path));
    }
   
    eprintln!("[VIRTUALIZATION] Target path validated, calling DefineDosDeviceW...");
   
    let result = unsafe {
        DefineDosDeviceW(
            0,
            drive_wide.as_ptr(),
            target_wide.as_ptr(),
        )
    };
   
    if result == 0 {
        let error = unsafe { winapi::um::errhandlingapi::GetLastError() };
        eprintln!("[VIRTUALIZATION] DefineDosDeviceW failed with error code: {}", error);
        eprintln!("[VIRTUALIZATION] Drive: {}, Target: {}", drive_str, target_path);
        eprintln!("[VIRTUALIZATION] Target path exists: {}, is_dir: {}", target_path_obj.exists(), target_path_obj.is_dir());
        return Err(format!("Failed to create virtual drive: Windows error {} (check if path is valid and drive letter free)", error));
    }
   
    eprintln!("[VIRTUALIZATION] Virtual drive {} created successfully", drive_str);
    Ok(())
}

#[cfg(not(windows))]
pub fn create_virtual_drive(_drive_letter: char, _target_path: &str) -> Result<(), String> {
    Err("Path virtualization is only available on Windows".to_string())
}

#[cfg(windows)]
pub fn remove_virtual_drive(drive_letter: char) -> Result<(), String> {
    let drive_str = format!("{}:", drive_letter);
    let drive_wide = to_wide_string(&drive_str);
   
    eprintln!("[VIRTUALIZATION] Removing virtual drive {}", drive_str);
   
    let result = unsafe {
        DefineDosDeviceW(
            DDD_REMOVE_DEFINITION,
            drive_wide.as_ptr(),
            ptr::null(),
        )
    };
   
    if result == 0 {
        let error = unsafe { winapi::um::errhandlingapi::GetLastError() };
        return Err(format!("Failed to remove virtual drive: Windows error {}", error));
    }
   
    eprintln!("[VIRTUALIZATION] Virtual drive {} removed successfully", drive_str);
    Ok(())
}

#[cfg(not(windows))]
pub fn remove_virtual_drive(_drive_letter: char) -> Result<(), String> {
    Err("Path virtualization is only available on Windows".to_string())
}

pub fn get_virtual_path(drive_letter: char, relative_path: &str) -> String {
    if relative_path.is_empty() {
        format!("{}:\\", drive_letter)
    } else {
        let normalized = relative_path.trim_start_matches('\\').trim_start_matches('/');
        format!("{}:\\{}", drive_letter, normalized.replace('/', "\\"))
    }
}

JavaScript:
#[tauri::command]
#[cfg(windows)]
async fn setup_path_virtualization(target_path: String) -> Result<String, String> {
    use crate::virtualization;
    use crate::config::Config;
    
    eprintln!("[VIRTUALIZATION] setup_path_virtualization called with target_path: {}", target_path);
    
    let drive_letter = virtualization::find_available_drive_letter().map_err(|e| {
        eprintln!("[VIRTUALIZATION] ERROR: {}", e);
        e
    })?;
    
    eprintln!("[VIRTUALIZATION] Found available drive letter: {}", drive_letter);
    
    virtualization::create_virtual_drive(drive_letter, &target_path).map_err(|e| {
        eprintln!("[VIRTUALIZATION] ERROR in create_virtual_drive: {}", e);
        e
    })?;
    
    eprintln!("[VIRTUALIZATION] Loading config to save virtualization settings...");
    let mut config = Config::load().await.map_err(|e| {
        eprintln!("[VIRTUALIZATION] ERROR loading config: {}", e);
        format!("Failed to load config: {}", e)
    })?;
    
    config.path_virtualization_enabled = true;
    config.virtual_drive_letter = Some(format!("{}", drive_letter));
    config.virtual_drive_target = Some(target_path.clone());
    
    eprintln!("[VIRTUALIZATION] Saving config with virtualization enabled...");
    config.save().await.map_err(|e| {
        eprintln!("[VIRTUALIZATION] ERROR saving config: {}", e);
        format!("Failed to save config: {}", e)
    })?;
    
    eprintln!("[VIRTUALIZATION] setup_path_virtualization completed successfully, drive: {}:", drive_letter);
    Ok(format!("{}:", drive_letter))
}
 
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

Маленький, но важный 1.5.1

По вашим просьбам, вернули вам выбор старых релизов игры.
Исправили редкую ошибку создания портативной версии, напоминаем что её создать можно вручную, прописав в названии лаунчера слово "portable".

Посмотреть подробности об этом обновлении...
 
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

1.5.2

• Исправлено множество редких ошибок во время обновления игры.
• Исправлена неправильная логика IO патчинга игры, процесс ускорен.
• Исправлена ошибка сохранения версии при обновлениях, заменены индексы на их названия.
• Исправлена ошибка, когда лончер мог скачать битый файл со смещением.
• Исправлено множество внутренних исключений в работе с файлами.
• Исправлено зависание интерфейса при работе с большими файлами.
• Ускорены все проверки клиента игры, сильно ускорен её запуск.
• Переписана...

Посмотреть подробности об этом обновлении...
 
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

1.5.3 Hotfix

• Добавлены флаги запуска локального сервера, автоматический пресет настроек.
• Перенесена папка всех данных сервера в %appdata%\HLauncher\ServerData для безопасного хранения миров и данных локального сервера.
• Исправлена установка игры, если путь файлов сверх пределов длинный.
• Исправлено отображение выбранной версии в углу.
• Исправлено отображение иконки и цвета текста на отключенных кнопках.

Посмотреть подробности об этом обновлении...
 
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

1.5.4 - 1.5.7

1.5.4:

• Система аккаунтов
• Исправление ошибки 403
• Изменен сервер скачивания
• Добавлена новая система обработки скинов в Hytale
• Множество маленьких улучшений

1.5.7:

• Исправлено растягивание картинки в Splash Screen
• Уменьшен вес лаунчера на ~0.6 мб
• Другие улучшения.... о которых мы забыли

Посмотреть подробности об этом обновлении...
 
Chernyash
Chernyash обновил ресурс Лаунчер Hytale новой записью:

2.0.1

Новый дизайн и кастомизация.
Новый патч под новые версии игры.
Новый производительный локальный сервер.
Учли пожелания наших пользователей, добавили красивые темы на выбор, сильно освежили весь дизайн лаунчера.
Нормальная локализация.
Проект почищен, удалены мусорные библиотеки и файлы.
Множество маленьких исправлений для Windows 10.
Исправлены проблемы с масштабированием в Windows 11.
Тысячи мелких правок и исправлений незначительных внутренних ошибок в угоду оптимизации.
Исправлена...

Посмотреть подробности об этом обновлении...
 
Chernyash
Chernyash обновил ресурс HLauncher — Лаунчер Hytale новой записью:

2.1.1

Исправлена редкая ошибка отрисовки компонентов GDI+
Исправлено наслоение уведомлений и их высота.
Исправлена смена языка в Changelog.
Исправлены некоторые кривые скругления.
Исправлены мелкие утечки памяти и ресурсов.
Исправлена редкая ошибка, когда лаунчер открывался свёрнутым.
Добавлено начальное обучение для новых пользователей.
Добавлена локализация, где она отсутствовала.
Добавлена параллельная загрузка файлов.
Добавлена генерация ников по стандарту.
Добавлена возможность...

Посмотреть подробности об этом обновлении...
 
ВерхНиз