Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion src-tauri/src/instance/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::instance::helpers::resourcepack::{
load_resourcepack_from_dir, load_resourcepack_from_zip,
};
use crate::instance::helpers::server::{
load_servers_info_from_path, query_servers_online, GameServerInfo,
load_servers_info_from_path, query_servers_online, save_servers_to_nbt, GameServerInfo,
};
use crate::instance::helpers::world::{load_level_data_from_nbt, load_world_info_from_dir};
use crate::instance::models::misc::{
Expand Down Expand Up @@ -52,9 +52,13 @@ use crate::utils::fs::{
};
use crate::utils::image::ImageWrapper;
use lazy_static::lazy_static;
use quartz_nbt::io::Flavor;
use quartz_nbt::io::{read_nbt, write_nbt};
use quartz_nbt::{NbtCompound, NbtList, NbtTag};
use regex::{Regex, RegexBuilder};
use std::collections::HashMap;
use std::fs;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use std::time::SystemTime;
Expand Down Expand Up @@ -435,6 +439,66 @@ pub async fn retrieve_game_server_list(
Ok(game_servers)
}

#[tauri::command]
pub async fn delete_game_server(
app: AppHandle,
instance_id: String,
server_ip: String,
) -> SJMCLResult<()> {
let game_root_dir =
match get_instance_subdir_path_by_id(&app, &instance_id, &InstanceSubdirType::Root) {
Some(path) => path,
None => return Err(InstanceError::InstanceNotFoundByID.into()),
};
let servers_dat_path = game_root_dir.join("servers.dat");
let mut existing_servers = load_servers_info_from_path(&servers_dat_path).await?;
existing_servers.retain(|server| server.ip != server_ip);

save_servers_to_nbt(&servers_dat_path, &existing_servers).await?;

Ok(())
}

#[tauri::command]
pub async fn add_game_server(
app: AppHandle,
instance_id: String,
server_url: String,
server_name: String,
) -> SJMCLResult<()> {
let game_root_dir =
match get_instance_subdir_path_by_id(&app, &instance_id, &InstanceSubdirType::Root) {
Some(path) => path,
None => return Err(InstanceError::InstanceNotFoundByID.into()),
};

let servers_dat_path = game_root_dir.join("servers.dat");

let mut existing_servers = load_servers_info_from_path(&servers_dat_path).await?;
if existing_servers
.iter()
.any(|server| server.ip == server_url)
{
return Err(InstanceError::DuplicateServer.into());
}

let new_server = GameServerInfo {
ip: server_url.clone(),
name: server_name.clone(),
icon_src: String::new(),
hidden: false,
description: String::new(),
is_queried: false,
players_online: 0,
players_max: 0,
online: false,
};
existing_servers.push(new_server.clone());
save_servers_to_nbt(&servers_dat_path, &existing_servers).await?;

Ok(())
}

#[tauri::command]
pub async fn retrieve_local_mod_list(
app: AppHandle,
Expand Down
26 changes: 26 additions & 0 deletions src-tauri/src/instance/helpers/server.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use crate::error::SJMCLResult;
use mc_server_status::{McClient, McError, ServerData, ServerEdition, ServerInfo, ServerStatus};
use quartz_nbt::io::Flavor;
use quartz_nbt::io::{read_nbt, write_nbt};
use quartz_nbt::{NbtCompound, NbtList, NbtTag};
use serde::{self, Deserialize, Serialize};
use std::path::Path;
use std::path::PathBuf;
use std::time::Duration;
use tauri::async_runtime;

Expand Down Expand Up @@ -114,3 +117,26 @@ pub async fn query_servers_online(

Ok(servers)
}

pub async fn save_servers_to_nbt(path: &PathBuf, servers: &[GameServerInfo]) -> SJMCLResult<()> {
let mut root_compound = NbtCompound::new();
let mut servers_list = NbtList::new();

for server in servers {
let mut server_compound = NbtCompound::new();
server_compound.insert("ip", server.ip.clone());
server_compound.insert("name", server.name.clone());
if !server.icon_src.is_empty() {
server_compound.insert("icon", server.icon_src.clone());
}
server_compound.insert("hidden", if server.hidden { 1i8 } else { 0i8 });
servers_list.push(NbtTag::Compound(server_compound));
}
root_compound.insert("servers", NbtTag::List(servers_list));
let mut bytes = Vec::new();
quartz_nbt::io::write_nbt(&mut bytes, None, &root_compound, Flavor::Uncompressed)?;

tokio::fs::write(path, bytes).await?;

Ok(())
}
2 changes: 2 additions & 0 deletions src-tauri/src/instance/models/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ pub enum InstanceError {
ProcessorExecutionFailed,
SemaphoreAcquireFailed,
LoaderInstallerNotFound,
DuplicateServer,
FileOperationError,
}

#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ pub async fn run() {
instance::commands::retrieve_world_list,
instance::commands::retrieve_world_details,
instance::commands::retrieve_game_server_list,
instance::commands::add_game_server,
instance::commands::delete_game_server,
instance::commands::retrieve_local_mod_list,
instance::commands::retrieve_resource_pack_list,
instance::commands::retrieve_server_resource_pack_list,
Expand Down
2 changes: 2 additions & 0 deletions src/enums/service-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export enum InstanceError {
WorldNotExistError = "WORLD_NOT_EXSIT_ERROR",
LevelNotExistError = "LEVEL_NOT_EXSIT_ERROR",
LevelParseError = "LEVEL_PARSE_ERROR",
DuplicateServer = "DUPLICATE_SERVER",
FileOperationError = "FILE_OPERATION_ERROR",
}

export enum ConfigServiceError {
Expand Down
41 changes: 41 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,20 @@
}
},
"InstanceWorldsPage": {
"addServerModal": {
"header": {
"title": "Add Game Server"
},
"serverAddressRequired": "Server address is required",
"label": {
"serverAddress": "Server Address",
"serverName": "Server Name"
},
"placeholder": {
"serverAddress": "Enter server address",
"serverName": "Enter server name"
}
},
"worldList": {
"title": "Worlds",
"lastPlayedAt": "Last played",
Expand Down Expand Up @@ -1325,6 +1339,11 @@
"online": "Online",
"offline": "Offline"
},
"delete": "Delete this Server",
"deleteConfirm": {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

请与项目内现有删除 modal 的代码与翻译风格保持一致

Image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修改为deletegameserveralertdialog部分

"title": "Delete Server",
"message": "Are you sure you want to delete this server?"
},
"launch": "Play this Server"
}
},
Expand Down Expand Up @@ -2346,6 +2365,28 @@
"title": "Failed to retrieve resource pack list from servers"
}
},
"addGameServer": {
"success": "Game server added successfully",
"error": {
"title": "Failed to add game server",
"description": {
"INSTANCE_NOT_FOUND_BY_ID": "Instance ID does not exist",
"FILE_OPERATION_ERROR": "Failed to write server info",
"DUPLICATE_SERVER": "Server already exists"
}
}
},
"deleteGameServer": {
"success": "Game server deleted successfully",
"error": {
"title": "Failed to delete game server",
"description": {
"INSTANCE_NOT_FOUND_BY_ID": "Instance ID does not exist",
"FILE_OPERATION_ERROR": "Failed to write server info",
"SERVER_NOT_FOUND": "Server not found"
}
}
},
"retrieveSchematicList": {
"error": {
"title": "Failed to retrieve schematic list"
Expand Down
41 changes: 41 additions & 0 deletions src/locales/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,20 @@
}
},
"InstanceWorldsPage": {
"addServerModal": {
"header": {
"title": "添加游戏服务器"
},
"serverAddressRequired": "服务器地址不能为空",
"label": {
"serverAddress": "服务器地址",
"serverName": "服务器名称"
},
"placeholder": {
"serverAddress": "请输入服务器地址",
"serverName": "请输入服务器名称"
}
},
"worldList": {
"title": "本地世界",
"lastPlayedAt": "上次游玩于",
Expand Down Expand Up @@ -1325,6 +1339,11 @@
"online": "在线",
"offline": "离线"
},
"delete": "删除此服务器",
"deleteConfirm": {
"title": "删除服务器",
"message": "确定要删除此服务器吗?"
},
"launch": "游玩此服务器"
}
},
Expand Down Expand Up @@ -2210,6 +2229,28 @@
}
},
"instance": {
"addGameServer": {
"success": "游戏服务器添加成功",
"error": {
"title": "添加游戏服务器失败",
"description": {
"INSTANCE_NOT_FOUND_BY_ID": "实例ID不存在",
"FILE_OPERATION_ERROR": "写入服务器信息失败",
"DUPLICATE_SERVER": "服务器已存在"
}
}
},
"deleteGameServer": {
"success": "游戏服务器删除成功",
"error": {
"title": "删除游戏服务器失败",
"description": {
"INSTANCE_NOT_FOUND_BY_ID": "实例ID不存在",
"FILE_OPERATION_ERROR": "写入服务器信息失败",
"SERVER_NOT_FOUND": "服务器不存在"
}
}
},
"retrieveInstanceList": {
"error": {
"title": "获取实例列表失败",
Expand Down
Loading
Loading