9月20日更新:C#版本完成,具有最简单的错误处理和图形界面(雾草这个只有字的窗口也能叫图形?)
程序很简单,本地一个文件记录本地版本,服务器端有个文件记录最新版本,如果服务器版本高于本地版本,就会自动下载相应的tar更新包,并自动解压,解压后再执行install.bat来完成更新的安装。
当然如果没有找到本地版本的记录文件,就会从服务器上下载一份完整的纯净客户端,然后再按补丁顺序依次安装。
C++的下载文件通过tools文件夹下的wget来实现,解压tar包则是靠的tar来完成。
C#的则是交给HttpWebRequest,HttpWebResponse和SharpZipLib来完成。
代码写得相当随意,基本上想到哪里写到哪里,而且也没有任何错误处理……不要打我最近网络赛和codeforces好多的
顺便求不吐槽英语……
以后会更新错误处理、本地包的安装和图形界面。
[点击此处下载C++版本]
[点击此处下载C#版本]
源码就丢这里一份吧:
#include#include #include const size_t STRINGLENGTH = 512; const char *HttpVersion = "http://zh.server309.dimension.moe/minecraft/LastVersion.txt"; const char *localVersionFile = "version.txt"; const char *basePackage = "http://zh.server309.dimension.moe/minecraft/base.tar"; bool exist(const char *path); void download(const char *url, const char *fileName); int main() { //检查游戏是否已经下载完成 if (!exist(localVersionFile)) { //如果用户不想下载,直接退出好了 puts("Couldn\'t find any game files. \nDo you want to Download it NOW [Y/n]"); if (toupper(getchar()) != 'Y') { puts("Aborting..."); return 0; } //下载完整的纯净版游戏 download(basePackage, "base.tar"); //下载完了,解压呗 puts("Download base package finished. Now installing it. It may take a few minutes..."); system("tools\\tar xf base.tar"); } //Now we are sure that we have the base game files. we just need to //check if there's any update for mods and configure files //First, we need to get the newest version of game on server. download(HttpVersion, "tools\\ServerVerion.txt"); FILE *serverVersion, *localVersion; int Sversion, Lversion; serverVersion = fopen("tools\\ServerVerion.txt", "rb"); fscanf(serverVersion, "1.%d.0", &Sversion); fclose(serverVersion); localVersion = fopen("version.txt", "rb"); fscanf(localVersion, "1.%d.0", &Lversion); fclose(localVersion); //check if we are up-to-date. if (Lversion == Sversion) { //the version is the same. puts("Your game is up-to-date!\nJust click mclauncher and enjoy it!"); system("pause"); return 0; } else { //we need to update the game, step-by-step accoding to the version. printf("We need to update some files to play the game.\n" "Local game version: 1.%d.0\n" "Server game version: 1.%d.0\n", Lversion, Sversion ); for (int i = Lversion; i < Sversion; i++) { printf("Updating 1.%d.0 to 1.%d.0... ", i, i + 1); char updatePackage[STRINGLENGTH]; //Download update package. sprintf(updatePackage, "http://zh.server309.dimension.moe/minecraft/update-%d.tar", i + 1); download(updatePackage, "update.tar"); //decompress the package. system("tools\\tar xf update.tar"); //call the update script to install the update package. system("\"update\\install.bat\""); //remove the packages system("del update.tar"); system("del /F /A /Q update"); localVersion = fopen("version.txt", "rb+"); fprintf(localVersion, "1.%d.0", i + 1); fclose(localVersion); puts("finished!"); } } system("pause"); return 0; } void download(const char *url, const char *fileName) { char command[STRINGLENGTH]; sprintf(command, "tools\\wget -O %s %s > tools\\logs\\wget.log", fileName, url); system(command); } bool exist(const char *path) { FILE *fp = fopen(path, "r"); if (!fp) return false; else { fclose(fp); return true; } }
C#版本源码:
using System; using System.Windows.Forms; using System.IO; using System.Net; using System.Threading; using ICSharpCode.SharpZipLib.Tar; using System.Text; namespace Updater { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void download(string url, string fileName) { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; HttpWebResponse response = request.GetResponse() as HttpWebResponse; Stream responseStream = response.GetResponseStream(); Stream stream = new FileStream(fileName, FileMode.Create); byte[] buffer = new byte[1024]; int size = responseStream.Read(buffer, 0, (int)buffer.Length); while (size > 0) { stream.Write(buffer, 0, size); size = responseStream.Read(buffer, 0, (int)buffer.Length); } stream.Close(); responseStream.Close(); } public void DeleteFolder(string deleteDirectory) { if (Directory.Exists(deleteDirectory)) { foreach (string deleteFile in Directory.GetFileSystemEntries(deleteDirectory)) { if (File.Exists(deleteFile)) File.Delete(deleteFile); else DeleteFolder(deleteFile); } Directory.Delete(deleteDirectory); } } private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; Thread th = new Thread(main); th.IsBackground = true; th.Start(); } private void main() { textBox1.Text = "Minecraft Updater 1.1\r\n"; textBox1.Text += "检测是否已下载游戏\r\n"; if (!File.Exists("Version.txt")) { textBox1.Text += "未找到本地游戏,开始下载。这可能需要一段时间……\r\n"; try { if (File.Exists("base.tar")) textBox1.Text += "找到本地离线安装包,跳过下载\r\n"; else download("http://zh.server309.dimension.moe/minecraft/base.tar", "base.tar"); } catch (Exception ex) { textBox1.Text += "发生错误:" + ex.Message + "\r\n程序已终止!"; MessageBox.Show("发生错误,在下载纯净版客户端:" + ex.Message + "\r\n程序已终止!"); Application.Exit(); } textBox1.Text += "下载纯净版完成,开始解压缩……\r\n"; try { TarArchive package = TarArchive.CreateInputTarArchive(File.OpenRead("base.tar")); package.ExtractContents(Environment.CurrentDirectory); package.Close(); } catch (Exception ex) { textBox1.Text += "发生错误:" + ex.Message + "\r\n程序已终止!"; MessageBox.Show("发生错误,在解压缩纯净版客户端:" + ex.Message + "\r\n程序已终止!"); Application.Exit(); } textBox1.Text += "解压缩完成,进入检查更新阶段……\r\n"; File.Delete("base.tar"); } textBox1.Text += "获取服务器端最新版本号……\r\n"; string serverVersion, localVersion; try { HttpWebRequest request = WebRequest.Create("http://zh.server309.dimension.moe/minecraft/LastVersion.txt") as HttpWebRequest; request.Method = "GET"; HttpWebResponse response = request.GetResponse() as HttpWebResponse; var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8); serverVersion = reader.ReadToEnd(); textBox1.Text += "服务器端版本为:" + serverVersion + "\r\n"; textBox1.Text += "获取本地版本号……\r\n"; StreamReader sr = new StreamReader("Version.txt", Encoding.Default); localVersion = sr.ReadLine(); textBox1.Text += "本地版本为:" + localVersion + "\r\n"; if (localVersion == serverVersion) { textBox1.Text += "本地游戏已是最新版,无需安装更新。\r\n"; return; } string[] SVersion = serverVersion.Split('.'); string[] LVersion = localVersion.Split('.'); for (int i = Convert.ToInt32(LVersion[1]); i != Convert.ToInt32(SVersion[1]); i++) { textBox1.Text += "正在下载自1." + i + ".0至1." + (i + 1) + ".0的更新……\r\n"; string updatePackageName = "http://zh.server309.dimension.moe/minecraft/update-" + (i + 1) + ".tar"; download(updatePackageName, "upgrade.tar"); textBox1.Text += "正在解压更新……\r\n"; TarArchive package = TarArchive.CreateInputTarArchive(File.OpenRead("upgrade.tar")); package.ExtractContents(Environment.CurrentDirectory); package.Close(); textBox1.Text += "正在安装更新\r\n"; System.Diagnostics.Process process = new System.Diagnostics.Process(); process.StartInfo.CreateNoWindow = false; process.StartInfo.FileName = "update\\install.bat"; process.Start(); StreamWriter sw = new StreamWriter(File.OpenWrite("Version.txt"), Encoding.Default); sw.WriteLine("1." + (i + 1) + ".0"); Thread.Sleep(500); textBox1.Text += "清理更新文件\r\n"; DeleteFolder("update"); File.Delete("upgrade.tar"); } textBox1.Text += "全部更新安装完成,可以开始游戏了。\r\n"; } catch (Exception ex) { textBox1.Text += "发生错误:" + ex.Message + "\r\n程序已终止!"; MessageBox.Show("发生错误,在更新本地客户端:" + ex.Message + "\r\n程序已终止!"); Application.Exit(); } } } }