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();
}
}
}
}