31 Commits

Author SHA1 Message Date
zs-yg
9e5e290da5 删除镜像站 2025-11-22 20:36:32 +08:00
zs-yg
59b7c84310 添加日志和修改文本输出 2025-11-22 20:03:12 +08:00
zs-yg
306a7bb309 添加查看jre 2025-11-22 19:51:40 +08:00
zs-yg
62713817e1 添加镜像仓库 2025-11-22 18:38:15 +08:00
zs-yg
1870b066fc 添加镜像仓库 2025-11-22 18:33:00 +08:00
zs-yg
7d74c603b8 添加镜像仓库 2025-11-22 18:29:18 +08:00
zs-yg
aea0742092 添加镜像仓库 2025-11-22 18:28:24 +08:00
zs-yg
295791b4f2 添加pre2和pre1 2025-11-22 18:10:37 +08:00
zs-yg
ff0cf01100 添加一键删除打包文件夹至构建脚本 2025-11-21 19:13:38 +08:00
zs-yg
b88c7507aa 添加7z一键压缩至构建脚本 2025-11-21 19:12:18 +08:00
zs-yg
969fcdff6e 修复下载jre的已知问题 2025-11-20 21:08:01 +08:00
zs-yg
3831c0ae0a 修改打包命令 2025-11-16 18:38:36 +08:00
zs-yg
5acb70c5d2 添加一键下载jre的功能 2025-11-16 18:26:18 +08:00
zs-yg
ddc6aa4e95 添加jre25链接 2025-11-15 13:05:15 +08:00
zs-yg
487212c6eb 添加jre链接 2025-11-15 12:59:36 +08:00
zs-yg
b0cd76dbc1 删除jre链接 2025-11-15 12:50:45 +08:00
zs-yg
73c32eac51 添加jre链接 2025-11-15 11:47:37 +08:00
zs-yg
3350b1798e 添加4个新快照 2025-11-14 19:26:12 +08:00
zs-yg
ddc0d1d9e0 修改README.md 2025-11-13 21:10:45 +08:00
zs-yg
adaa360265 修改README.md 2025-11-13 21:09:09 +08:00
zs-yg
e2219d5042 修改README.md 2025-11-13 21:08:00 +08:00
zs-yg
8982aa9bcc 添加日志系统和gitignore 2025-11-09 14:48:42 +08:00
zs-yg
0b6f66304b 添加构建脚本 2025-11-09 08:27:54 +08:00
zsyg
d325676293 修改下载逻辑 2025-10-31 21:27:35 +08:00
zsyg
a8069c60b9 Fix formatting issues in README.md 2025-10-29 20:46:51 +08:00
zsyg
fbc4776eb8 Fix formatting issues in README.md 2025-10-29 20:44:47 +08:00
zsyg
9d87fd4bfb 修改README.md 2025-10-27 21:16:16 +08:00
zsyg
f46d169224 修改README.md 2025-10-27 21:14:31 +08:00
zsyg
866aa24686 Add files via upload 2025-10-27 21:12:10 +08:00
zsyg
453bf59eaa Add files via upload 2025-10-27 21:11:38 +08:00
zsyg
1d0f4d1631 Add files via upload 2025-10-27 21:10:25 +08:00
13 changed files with 616 additions and 21 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
bin/
obj/
logs/
profiles/
jre/
setup/

View File

@@ -1,6 +1,9 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using MCSJ.Tools; using MCSJ.Tools;
using MCSJ.Tools.LogSystem;
using MCSJ.Tools.JreDownload;
using MCSJ.Tools.ViewJre;
namespace MCSJ namespace MCSJ
{ {
@@ -8,33 +11,70 @@ namespace MCSJ
{ {
static async Task Main(string[] args) static async Task Main(string[] args)
{ {
// 验证日志目录
string logDir = LogCreator.GetLogDirectory();
Console.WriteLine($"日志目录: {logDir}");
LogMain.Debug($"日志文件: {LogCreator.GetLogFilePath()}");
LogMain.Info("MC服务器启动工具启动");
var httpClient = new HttpClient {
Timeout = TimeSpan.FromMinutes(5),
DefaultRequestHeaders = { { "User-Agent", "MCSJ-JRE-Downloader" } }
};
var versionManager = new VersionManager(); var versionManager = new VersionManager();
var downloadService = new DownloadService(versionManager); var downloadService = new DownloadService(versionManager);
var jreViewer = new JreViewer();
LogMain.Debug("服务初始化完成");
while (true) while (true)
{ {
Console.WriteLine("MC服务器下载工具"); Console.WriteLine("MC服务器启动工具");
Console.WriteLine("1. 显示所有版本"); Console.WriteLine("1. 显示所有服务器版本");
Console.WriteLine("2. 下载指定版本"); Console.WriteLine("2. 下载指定服务器版本");
Console.WriteLine("3. 退出"); Console.WriteLine("3. 下载JRE");
Console.WriteLine("4. 查看已安装的JRE");
Console.WriteLine("5. 退出");
Console.Write("请选择操作: "); Console.Write("请选择操作: ");
var input = Console.ReadLine(); var input = Console.ReadLine();
LogMain.Debug($"用户选择操作: {input}");
switch (input) switch (input)
{ {
case "1": case "1":
versionManager.DisplayAllVersions(); versionManager.DisplayAllVersions();
LogMain.Info("显示所有版本列表");
break; break;
case "2": case "2":
Console.Write("请输入要下载的版本名称: "); Console.Write("请输入要下载的版本名称: ");
var version = Console.ReadLine(); var version = Console.ReadLine();
LogMain.Info($"开始下载版本: {version}");
await downloadService.DownloadVersion(version); await downloadService.DownloadVersion(version);
LogMain.Info($"版本下载完成: {version}");
break; break;
case "3": case "3":
Console.Write("请输入要下载的JRE版本(jre8,jre11,jre17/21/25): ");
var jreVersion = Console.ReadLine();
if (string.IsNullOrWhiteSpace(jreVersion))
{
Console.WriteLine("JRE版本不能为空");
continue;
}
LogMain.Info($"开始下载JRE: {jreVersion}");
var jreDownloadService = new JreDownloadService(httpClient);
await jreDownloadService.DownloadAndSetupJre(jreVersion);
LogMain.Info($"JRE下载完成: {jreVersion}");
break;
case "4":
jreViewer.DisplayInstalledJres();
LogMain.Info("显示已安装的JRE列表");
break;
case "5":
LogMain.Info("程序正常退出");
return; return;
default: default:
Console.WriteLine("无效输入,请重新选择"); Console.WriteLine("无效输入,请重新选择");
LogMain.Warn($"无效的用户输入: {input}");
break; break;
} }

View File

@@ -1,2 +1,63 @@
# MCSJ # MCSJ 服务器管理工具
windows的命令行mc开服工具
MCSJ 是一个开源的 Minecraft 服务器管理工具,旨在为用户提供极致便捷的服务器搭建与管理体验。
## 主要功能
- 一键下载 server.jar
- 一键生成启动脚本
- 一键启动服务器
- 一键下载 Java 环境
- 一些有趣实用的辅助功能
> 更多辅助功能请下载体验。
## 下载地址
[123网盘链接](https://www.123865.com/s/msALTd-L610d)
[github releases](https://github.com/zs-yg/MCSJ/releases)
## 开发环境
- Windows 10
- Visual Studio Code
- .net 8.0
## 运行环境
- Windows 10
- .net 8.0 runtime
## 运行方式
1. 下载并解压 MCSJ 压缩包。
2. 双击运行 MCSJ.exe 启动程序。
3. 或者命令行输入MCSJ.exe 启动程序。可以查看是否需要安装运行时
## 官方镜像仓库
[gitee镜像仓库](https://gitee.com/chr_super/mcsj)
## 关于
MCSJ 项目由 [zs-yg](https://github.com/zs-yg) 开发,欢迎提交 issue 和 PR。
[discord](https://discord.gg/4mbqUzfg)
qq群:1043867176
b站号:https://space.bilibili.com/1698250734
## 开源协议
MIT协议
本项目已在 GitHub 开源,欢迎贡献代码与建议。
# 恰饭awa
不用捐款使用这个链接注册服务器就行了awa
性能不错,可以免费白嫖
服务器:https://www.rainyun.com/Nzk2NDEy_

View File

@@ -2,6 +2,7 @@ using System;
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using MCSJ.Tools.LogSystem;
namespace MCSJ.Tools namespace MCSJ.Tools
{ {
@@ -16,19 +17,54 @@ namespace MCSJ.Tools
_httpClient = new HttpClient(); _httpClient = new HttpClient();
} }
public async Task DownloadVersion(string version) public async Task DownloadVersion(string? version)
{ {
var url = _versionManager.GetDownloadUrl(version); if (string.IsNullOrWhiteSpace(version))
if (url == null)
{ {
Console.WriteLine($"版本 {version} 不存在"); Console.WriteLine("版本名称不能为空");
LogMain.Error("版本名称不能为空");
return; return;
} }
var url = _versionManager.GetDownloadUrl(version);
if (string.IsNullOrEmpty(url))
{
Console.WriteLine($"版本 {version} 不存在");
LogMain.Error($"版本 {version} 不存在");
return;
}
// 根目录 profiles 文件夹
var profilesRoot = Path.Combine(Directory.GetCurrentDirectory(), "profiles");
if (!Directory.Exists(profilesRoot))
Directory.CreateDirectory(profilesRoot);
string? targetFolder = null;
string? profilePath = null;
while (true)
{
Console.Write($"请输入存放文件夹名称(直接回车默认用版本名 '{version}'");
var input = Console.ReadLine();
targetFolder = string.IsNullOrWhiteSpace(input) ? version : input;
profilePath = Path.Combine(profilesRoot, targetFolder);
if (!Directory.Exists(profilePath))
break;
Console.WriteLine($"文件夹 '{targetFolder}' 已存在,请重新输入(直接回车则取消下载):");
LogMain.Warn($"文件夹 '{targetFolder}' 已存在,请重新输入(直接回车则取消下载):");
}
if (Directory.Exists(profilePath))
{
Console.WriteLine("下载已取消。");
LogMain.Info("下载已取消。");
return;
}
Directory.CreateDirectory(profilePath);
string jarPath = Path.Combine(profilePath, "server.jar");
try try
{ {
Console.WriteLine($"开始下载 {version}..."); Console.WriteLine($"开始下载 {version} 到 {profilePath} ...");
LogMain.Info($"开始下载 {version} 到 {profilePath} ...");
var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
@@ -38,7 +74,7 @@ namespace MCSJ.Tools
var isMoreToRead = true; var isMoreToRead = true;
using (var stream = await response.Content.ReadAsStreamAsync()) using (var stream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream($"{version}.jar", FileMode.Create, FileAccess.Write)) using (var fileStream = new FileStream(jarPath, FileMode.Create, FileAccess.Write))
{ {
while (isMoreToRead) while (isMoreToRead)
{ {
@@ -50,7 +86,6 @@ namespace MCSJ.Tools
else else
{ {
await fileStream.WriteAsync(buffer, 0, read); await fileStream.WriteAsync(buffer, 0, read);
downloadedBytes += read; downloadedBytes += read;
if (totalBytes > 0) if (totalBytes > 0)
{ {
@@ -60,12 +95,13 @@ namespace MCSJ.Tools
} }
} }
} }
Console.WriteLine($"\n{version} 下载完成! 文件已保存到 {jarPath}");
Console.WriteLine($"\n{version} 下载完成!"); LogMain.Info($"{version} 下载完成! 文件已保存到 {jarPath}");
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"下载失败: {ex.Message}"); Console.WriteLine($"下载失败: {ex.Message}");
LogMain.Error($"下载失败: {ex.Message}");
} }
} }
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using MCSJ.Tools.LogSystem;
namespace MCSJ.Tools namespace MCSJ.Tools
{ {
@@ -19,6 +20,7 @@ namespace MCSJ.Tools
{ {
var filePath = Path.Combine("resources", "serverlist.txt"); var filePath = Path.Combine("resources", "serverlist.txt");
Console.WriteLine($"尝试从路径加载版本列表: {Path.GetFullPath(filePath)}"); Console.WriteLine($"尝试从路径加载版本列表: {Path.GetFullPath(filePath)}");
LogMain.Info($"尝试从路径加载版本列表: {Path.GetFullPath(filePath)}");
if (!File.Exists(filePath)) if (!File.Exists(filePath))
{ {
@@ -42,7 +44,8 @@ namespace MCSJ.Tools
if (string.IsNullOrEmpty(version) || string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(version) || string.IsNullOrEmpty(url))
{ {
Console.WriteLine($"忽略无效条目: {rawLine} (版本或URL为空)"); Console.WriteLine($"忽略无效条目: {rawLine} (版本或URL为空)");
LogMain.Warn($"忽略无效条目: {rawLine} (版本或URL为空)");
continue; continue;
} }
@@ -51,6 +54,7 @@ namespace MCSJ.Tools
else else
{ {
Console.WriteLine($"忽略无效条目: {rawLine} (缺少冒号分隔或格式不正确)"); Console.WriteLine($"忽略无效条目: {rawLine} (缺少冒号分隔或格式不正确)");
LogMain.Warn($"忽略无效条目: {rawLine} (缺少冒号分隔或格式不正确)");
} }
} }
@@ -60,25 +64,37 @@ namespace MCSJ.Tools
} }
Console.WriteLine($"成功加载 {_versions.Count} 个版本"); Console.WriteLine($"成功加载 {_versions.Count} 个版本");
LogMain.Info($"成功加载 {_versions.Count} 个版本");
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"加载版本列表失败: {ex.Message}"); Console.WriteLine($"加载版本列表失败: {ex.Message}");
Console.WriteLine($"当前工作目录: {Directory.GetCurrentDirectory()}"); Console.WriteLine($"当前工作目录: {Directory.GetCurrentDirectory()}");
Console.WriteLine("请确保serverlist.txt每行格式为: 版本名:下载URL (版本名可以包含空格),支持以#开头的注释"); Console.WriteLine("请确保serverlist.txt每行格式为: 版本名:下载URL (版本名可以包含空格),支持以#开头的注释");
LogMain.Error($"加载版本列表失败: {ex.Message}");
LogMain.Error($"当前工作目录: {Directory.GetCurrentDirectory()}");
} }
} }
public void DisplayAllVersions() public void DisplayAllVersions()
{ {
Console.WriteLine("可用版本列表:"); var filePath = Path.Combine("resources", "serverlist.txt");
if (!File.Exists(filePath))
{
Console.WriteLine("版本列表文件不存在");
LogMain.Error("版本列表文件不存在");
return;
}
Console.WriteLine("可用版本列表:");
LogMain.Info("可用版本列表:");
foreach (var version in _versions.Keys) foreach (var version in _versions.Keys)
{ {
Console.WriteLine(version); Console.WriteLine(version);
} }
} }
public string GetDownloadUrl(string version) public string? GetDownloadUrl(string version)
{ {
return _versions.TryGetValue(version, out var url) ? url : null; return _versions.TryGetValue(version, out var url) ? url : null;
} }

View File

@@ -0,0 +1,61 @@
using System;
using System.IO;
using MCSJ.Tools.LogSystem;
namespace MCSJ.Tools.JreDownload
{
public class JreDownloadProgress : IProgress<(long bytesReceived, long totalBytesToReceive, int progressPercentage)>
{
public void Report((long bytesReceived, long totalBytesToReceive, int progressPercentage) value)
{
// 保存当前控制台颜色
var originalColor = Console.ForegroundColor;
try
{
// 计算下载百分比
int percentage = value.progressPercentage;
// 格式化文件大小使用MB单位
string received = FormatFileSizeMB(value.bytesReceived);
string total = FormatFileSizeMB(value.totalBytesToReceive);
// 创建进度条
string progressBar = CreateProgressBar(percentage);
// 显示进度信息(仅进度条部分为绿色)
Console.Write("\r下载进度: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.Write($"{progressBar}");
Console.ForegroundColor = originalColor;
Console.Write($" {percentage}% [{FormatFileSizeMB(value.bytesReceived)} / {FormatFileSizeMB(value.totalBytesToReceive)}]");
// 下载完成时换行
if (percentage == 100)
{
Console.WriteLine();
LogMain.Info("JRE下载完成");
}
}
finally
{
// 恢复原始控制台颜色
Console.ForegroundColor = originalColor;
}
}
private string CreateProgressBar(int percentage)
{
int width = 20; // 进度条宽度
int progress = percentage * width / 100;
return $"[{new string('#', progress)}{new string('-', width - progress)}]";
}
private string FormatFileSizeMB(long bytes)
{
double mb = bytes / (1024.0 * 1024.0);
return $"{mb:0.##} MB";
}
}
}

View File

@@ -0,0 +1,230 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO.Compression;
using MCSJ.Tools.LogSystem;
namespace MCSJ.Tools.JreDownload
{
public class JreDownloadService
{
private readonly HttpClient _httpClient;
private const string JreListPath = "resources/jrelist.txt";
private const string JreRootFolder = "jre";
private const string SetupFolder = "setup";
public JreDownloadService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task DownloadAndSetupJre(string version)
{
// 0. 检查是否已存在该版本
if (CheckJreExists(version))
{
Console.WriteLine($"JRE {version} 已存在,无需重复下载");
LogMain.Info($"JRE {version} 已存在,无需重复下载");
return;
}
// 1. 读取jrelist.txt获取下载链接
var downloadUrl = GetDownloadUrl(version);
if (string.IsNullOrEmpty(downloadUrl))
{
Console.WriteLine($"找不到版本 {version} 的下载链接");
LogMain.Error($"找不到版本 {version} 的下载链接");
return;
}
// 2. 下载压缩包
var progress = new JreDownloadProgress();
var tempZipPath = await DownloadJreZip(downloadUrl, version, progress);
if (string.IsNullOrEmpty(tempZipPath))
{
Console.WriteLine("下载失败");
LogMain.Error("下载失败");
return;
}
// 3. 解压到jre文件夹
var jreFolder = Path.Combine(JreRootFolder, version);
if (!ExtractJre(tempZipPath, jreFolder))
{
Console.WriteLine("解压失败");
LogMain.Error("解压失败");
return;
}
// 4. 查找java.exe和javaw.exe
var javaExePath = FindJavaExe(jreFolder, "java.exe");
var javawExePath = FindJavaExe(jreFolder, "javaw.exe");
if (javaExePath == null || javawExePath == null)
{
Console.WriteLine("找不到java.exe或javaw.exe");
LogMain.Error("找不到java.exe或javaw.exe");
return;
}
// 5. 生成jre.toml
CreateJreToml(version, javaExePath, javawExePath);
// 6. 清理临时文件
File.Delete(tempZipPath);
Console.WriteLine($"JRE {version} 安装完成");
LogMain.Info($"JRE {version} 安装完成");
}
private string? GetDownloadUrl(string version)
{
if (string.IsNullOrWhiteSpace(version))
return null;
if (!File.Exists(JreListPath))
return null;
var lines = File.ReadAllLines(JreListPath);
return lines.FirstOrDefault(l => l.StartsWith(version + ":"))?.Split(':').LastOrDefault();
}
private async Task<string?> DownloadJreZip(string url, string version, IProgress<(long, long, int)>? progress = null)
{
var tempPath = Path.GetTempFileName();
try
{
Console.WriteLine($"开始下载 JRE {version}...");
// 确保URL是绝对路径自动补全https协议头
if (!url.StartsWith("http:") && !url.StartsWith("https:"))
{
url = "https:" + url;
}
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
Console.WriteLine($"无效的下载URL: {url}");
LogMain.Error($"无效的下载URL: {url}");
return null;
}
Console.WriteLine($"正在准备下载 {url}...");
LogMain.Info($"正在准备下载 {url}...");
var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
var totalBytes = response.Content.Headers.ContentLength ?? 0;
Console.WriteLine($"文件总大小: {totalBytes} 字节");
LogMain.Info($"文件总大小: {totalBytes} 字节");
long bytesRead = 0;
var lastReportTime = DateTime.MinValue;
Console.WriteLine("开始下载...");
LogMain.Info("开始下载...");
using (var stream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(tempPath, FileMode.Create))
{
var buffer = new byte[8192];
int bytesReadThisPass;
while ((bytesReadThisPass = await stream.ReadAsync(buffer)) != 0)
{
await fileStream.WriteAsync(buffer.AsMemory(0, bytesReadThisPass));
bytesRead += bytesReadThisPass;
// 限制进度报告频率,避免过多控制台输出
if (DateTime.Now - lastReportTime > TimeSpan.FromMilliseconds(100) || bytesRead == totalBytes)
{
int progressPercentage = totalBytes > 0 ? (int)(bytesRead * 100 / totalBytes) : 0;
Console.WriteLine($"报告进度: {bytesRead}/{totalBytes} ({progressPercentage}%)");
progress?.Report((bytesRead, totalBytes, progressPercentage));
lastReportTime = DateTime.Now;
}
}
}
return tempPath;
}
catch (Exception ex)
{
Console.WriteLine($"下载失败: {ex.Message}");
LogMain.Error($"下载失败: {ex.Message}");
return null;
}
}
private bool ExtractJre(string zipPath, string targetFolder)
{
try
{
if (Directory.Exists(targetFolder))
Directory.Delete(targetFolder, true);
Directory.CreateDirectory(targetFolder);
ZipFile.ExtractToDirectory(zipPath, targetFolder);
return true;
}
catch (Exception ex)
{
Console.WriteLine($"解压失败: {ex.Message}");
LogMain.Error($"解压失败: {ex.Message}");
return false;
}
}
private string? FindJavaExe(string folder, string exeName)
{
if (string.IsNullOrWhiteSpace(folder) || string.IsNullOrWhiteSpace(exeName))
return null;
if (!Directory.Exists(folder))
return null;
return Directory.GetFiles(folder, exeName, SearchOption.AllDirectories).FirstOrDefault();
}
private bool CheckJreExists(string version)
{
var tomlPath = Path.Combine(SetupFolder, "jre.toml");
if (!File.Exists(tomlPath))
return false;
try
{
var content = File.ReadAllText(tomlPath);
return content.Contains($"[jre.{version}]");
}
catch
{
return false;
}
}
private void CreateJreToml(string version, string javaExePath, string javawExePath)
{
if (!Directory.Exists(SetupFolder))
Directory.CreateDirectory(SetupFolder);
var tomlPath = Path.Combine(SetupFolder, "jre.toml");
var content = $@"[jre.{version}]
java_path = '{javaExePath}'
javaw_path = '{javawExePath}'
";
if (File.Exists(tomlPath))
{
var existingContent = File.ReadAllText(tomlPath);
if (!existingContent.Contains($"[jre.{version}]"))
{
File.AppendAllText(tomlPath, content);
}
}
else
{
File.WriteAllText(tomlPath, content);
}
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.IO;
namespace MCSJ.Tools.LogSystem
{
public static class LogCreator
{
public static string GenerateLogFileName()
{
DateTime now = DateTime.Now;
return $"{now:yyyy-MM-dd-HH-mm-ss}.log";
}
public static string GetLogDirectory()
{
string logDir = Path.Combine(Directory.GetCurrentDirectory(), "logs");
if (!Directory.Exists(logDir))
{
Directory.CreateDirectory(logDir);
}
return logDir;
}
public static string GetLogFilePath()
{
return Path.Combine(GetLogDirectory(), GenerateLogFileName());
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.IO;
using System.Threading;
namespace MCSJ.Tools.LogSystem
{
public static class LogMain
{
private static readonly object _lock = new object();
public enum LogLevel
{
DEBUG,
INFO,
WARN,
ERROR,
FATAL
}
public static void Log(LogLevel level, string message)
{
string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{level}] {message}";
string logPath = LogCreator.GetLogFilePath();
lock (_lock)
{
File.AppendAllText(logPath, logEntry + Environment.NewLine);
}
}
public static void Debug(string message) => Log(LogLevel.DEBUG, message);
public static void Info(string message) => Log(LogLevel.INFO, message);
public static void Warn(string message) => Log(LogLevel.WARN, message);
public static void Error(string message) => Log(LogLevel.ERROR, message);
public static void Fatal(string message) => Log(LogLevel.FATAL, message);
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.IO;
using System.Linq;
using MCSJ.Tools.LogSystem;
namespace MCSJ.Tools.ViewJre
{
public class JreViewer
{
private const string SetupFolder = "setup";
private const string JreTomlFile = "jre.toml";
public void DisplayInstalledJres()
{
var tomlPath = Path.Combine(SetupFolder, JreTomlFile);
if (!File.Exists(tomlPath))
{
Console.WriteLine("没有安装任何JRE");
LogMain.Info("没有安装任何JRE");
return;
}
try
{
var content = File.ReadAllText(tomlPath);
var versions = content.Split('\n')
.Where(line => line.StartsWith("[jre."))
.Select(line => line.Split('.')[1].Split(']')[0].Trim()) // 精确提取版本号
.ToList();
if (versions.Count == 0)
{
Console.WriteLine("没有安装任何JRE");
LogMain.Info("没有安装任何JRE");
return;
}
Console.WriteLine("已安装的JRE版本:");
LogMain.Info("已安装的JRE版本:");
foreach (var version in versions)
{
Console.WriteLine(version); // 直接输出版本号,不带前缀
}
}
catch (Exception ex)
{
Console.WriteLine($"读取JRE列表失败: {ex.Message}");
LogMain.Error($"读取JRE列表失败: {ex.Message}");
}
}
}
}

15
build.bat Normal file
View File

@@ -0,0 +1,15 @@
dotnet publish MCSJ.csproj -c Release -r win-x86 --self-contained false /p:Optimize=true /p:DebugType=None
dotnet publish MCSJ.csproj -c Release -r win-x64 --self-contained false /p:Optimize=true /p:DebugType=None
cd bin\Release\net8.0
ren win-x64 MCSJ-x64
ren win-x86 MCSJ-x86
rmdir /s /q MCSJ-x64\publish
rmdir /s /q MCSJ-x86\publish
7z a -t7z MCSJ-x64.7z MCSJ-x64
7z a -t7z MCSJ-x86.7z MCSJ-x86
7z a -tzip MCSJ-x64.zip MCSJ-x64
7z a -tzip MCSJ-x86.zip MCSJ-x86
7z a -ttar MCSJ-x64.tar MCSJ-x64
7z a -ttar MCSJ-x86.tar MCSJ-x86
rmdir /s /q MCSJ-x64
rmdir /s /q MCSJ-x86

5
resources/jrelist.txt Normal file
View File

@@ -0,0 +1,5 @@
jre8:https://pan.tenire.com/down.php/2dd2a856cdb549dce5b557026e20b36a.zip
jre11:https://pan.tenire.com/down.php/3ec613e667f35e364d921aeb0315272a.zip
jre17:https://pan.tenire.com/down.php/f28009799fca1c62f4c37a5ab4759db3.zip
jre21:https://pan.tenire.com/down.php/253e308ecfce3be809f2e85d6513791d.zip
jre25:https://pan.tenire.com/down.php/e3ae0f146ce3fa1d27a805f86b138058.zip

View File

@@ -1,3 +1,9 @@
1.21.11-pre2:https://piston-data.mojang.com/v1/objects/7f997b55094aa7754f25173aafef657449f02bec/server.jar
1.21.11-pre1:https://piston-data.mojang.com/v1/objects/1087f90b4d73209318d87aa8deecfaae24861004/server.jar
25w46a:https://piston-data.mojang.com/v1/objects/e61a72ec98fae895ef3e80b05269ae343c42fc0b/server.jar
25w45a:https://piston-data.mojang.com/v1/objects/4c0fe96ca002d7049226a740194c8d7114bd5059/server.jar
25w44a:https://piston-data.mojang.com/v1/objects/1ade1ebd6affbfed6dbfb2ce8864cf19efed07ba/server.jar
25w43a:https://piston-data.mojang.com/v1/objects/dac322a1091905430e2a6ade129a4915552455d0/server.jar
25w42a:https://piston-data.mojang.com/v1/objects/d9c6cfd4ba84f5080206259d2563f75796f14470/server.jar 25w42a:https://piston-data.mojang.com/v1/objects/d9c6cfd4ba84f5080206259d2563f75796f14470/server.jar
25w41a:https://piston-data.mojang.com/v1/objects/804aefaf397b417479e89144834e277ebde2ce71/server.jar 25w41a:https://piston-data.mojang.com/v1/objects/804aefaf397b417479e89144834e277ebde2ce71/server.jar
1.21.10:https://piston-data.mojang.com/v1/objects/95495a7f485eedd84ce928cef5e223b757d2f764/server.jar 1.21.10:https://piston-data.mojang.com/v1/objects/95495a7f485eedd84ce928cef5e223b757d2f764/server.jar
@@ -735,8 +741,8 @@
13w38b:https://launcher.mojang.com/v1/objects/82588f79a6a61c4c4289a9dc60b7b7b3fedaead9/server.jar 13w38b:https://launcher.mojang.com/v1/objects/82588f79a6a61c4c4289a9dc60b7b7b3fedaead9/server.jar
13w38a:https://launcher.mojang.com/v1/objects/627585cdb9386e7f05cdfb8f092e5a303d4fd5f3/server.jar 13w38a:https://launcher.mojang.com/v1/objects/627585cdb9386e7f05cdfb8f092e5a303d4fd5f3/server.jar
1.6.4:https://launcher.mojang.com/v1/objects/050f93c1f3fe9e2052398f7bd6aca10c63d64a87/server.jar 1.6.4:https://launcher.mojang.com/v1/objects/050f93c1f3fe9e2052398f7bd6aca10c63d64a87/server.jar
1.6.3:https://launcher.mojang.com/v1/objects/5a4c69bdf7c4a9aa9580096805d8497ba7721e05/server.jar
13w37b:https://launcher.mojang.com/v1/objects/f6322a6791bbeabac94cbaa1cf9b779ad88b120f/server.jar 13w37b:https://launcher.mojang.com/v1/objects/f6322a6791bbeabac94cbaa1cf9b779ad88b120f/server.jar
1.6.3:https://launcher.mojang.com/v1/objects/5a4c69bdf7c4a9aa9580096805d8497ba7721e05/server.jar
13w37a:https://launcher.mojang.com/v1/objects/c3d3d936394b35f20b871b140f5a8e6079822e51/server.jar 13w37a:https://launcher.mojang.com/v1/objects/c3d3d936394b35f20b871b140f5a8e6079822e51/server.jar
13w36b:https://launcher.mojang.com/v1/objects/2b6cdcd2df82ca8f04c1c2c7d77faf4cd25151ea/server.jar 13w36b:https://launcher.mojang.com/v1/objects/2b6cdcd2df82ca8f04c1c2c7d77faf4cd25151ea/server.jar
13w36a:https://launcher.mojang.com/v1/objects/8453f031175bac1a92db000befd14f70c8df8fb7/server.jar 13w36a:https://launcher.mojang.com/v1/objects/8453f031175bac1a92db000befd14f70c8df8fb7/server.jar
@@ -765,8 +771,8 @@
1.5.1:https://launcher.mojang.com/v1/objects/d07c71ee2767dabb79fb32dad8162e1b854d5324/server.jar 1.5.1:https://launcher.mojang.com/v1/objects/d07c71ee2767dabb79fb32dad8162e1b854d5324/server.jar
1.5:https://launcher.mojang.com/v1/objects/aedad5159ef56d69c5bcf77ed141f53430af43c3/server.jar 1.5:https://launcher.mojang.com/v1/objects/aedad5159ef56d69c5bcf77ed141f53430af43c3/server.jar
1.4.7:https://launcher.mojang.com/v1/objects/2f0ec8efddd2f2c674c77be9ddb370b727dec676/server.jar 1.4.7:https://launcher.mojang.com/v1/objects/2f0ec8efddd2f2c674c77be9ddb370b727dec676/server.jar
1.4.6:https://launcher.mojang.com/v1/objects/a0aeb5709af5f2c3058c1cf0dc6b110a7a61278c/server.jar
1.4.5:https://launcher.mojang.com/v1/objects/c12fd88a8233d2c517dbc8196ba2ae855f4d36ea/server.jar 1.4.5:https://launcher.mojang.com/v1/objects/c12fd88a8233d2c517dbc8196ba2ae855f4d36ea/server.jar
1.4.6:https://launcher.mojang.com/v1/objects/a0aeb5709af5f2c3058c1cf0dc6b110a7a61278c/server.jar
1.4.4:https://launcher.mojang.com/v1/objects/4215dcadb706508bf9d6d64209a0080b9cee9e71/server.jar 1.4.4:https://launcher.mojang.com/v1/objects/4215dcadb706508bf9d6d64209a0080b9cee9e71/server.jar
1.4.3:https://launcher.mojang.com/v1/objects/9be68adf6e80721975df12f2445fa24617328d18/server.jar 1.4.3:https://launcher.mojang.com/v1/objects/9be68adf6e80721975df12f2445fa24617328d18/server.jar
1.4.2:https://launcher.mojang.com/v1/objects/5be700523a729bb78ef99206fb480a63dcd09825/server.jar 1.4.2:https://launcher.mojang.com/v1/objects/5be700523a729bb78ef99206fb480a63dcd09825/server.jar