diff --git a/OpenRa.FileFormats/Session.cs b/OpenRa.FileFormats/Session.cs
index e378d876e5..1d0ddd45bc 100644
--- a/OpenRa.FileFormats/Session.cs
+++ b/OpenRa.FileFormats/Session.cs
@@ -30,7 +30,7 @@ namespace OpenRa.FileFormats
public class Global
{
public string Map = "scm12ea.ini";
- public string[] Mods = {}; // filename:sha1 pairs.
+ public string[] Packages = {}; // filename:sha1 pairs.
public int OrderLatency = 3;
}
}
diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs
index 814c9524d1..75a4c7ed86 100644
--- a/OpenRa.Game/Game.cs
+++ b/OpenRa.Game/Game.cs
@@ -382,20 +382,24 @@ namespace OpenRa.Game
// todo: if we don't have all the resources, we don't want to do this yet.
+ if (Game.orderManager.FramesAhead != LobbyInfo.GlobalSettings.OrderLatency
+ && !Game.orderManager.GameStarted)
+ {
+ Game.orderManager.FramesAhead = LobbyInfo.GlobalSettings.OrderLatency;
+ Game.chat.AddLine(Color.White, "Server",
+ "Order lag is now {0} frames.".F(LobbyInfo.GlobalSettings.OrderLatency));
+ }
+
+ PackageDownloader.SetPackageList(LobbyInfo.GlobalSettings.Packages);
+ if (!PackageDownloader.IsIdle())
+ return;
+
if (mapName != LobbyInfo.GlobalSettings.Map)
{
chat.AddLine(Color.White, "Debug",
"Map change {0} -> {1}".F(mapName, session.GlobalSettings.Map));
ChangeMap(LobbyInfo.GlobalSettings.Map);
}
-
- if (Game.orderManager.FramesAhead != LobbyInfo.GlobalSettings.OrderLatency
- && !Game.orderManager.GameStarted)
- {
- Game.orderManager.FramesAhead = LobbyInfo.GlobalSettings.OrderLatency;
- Game.chat.AddLine(Color.White, "Server",
- "Order lag is now {0} frames.".F(LobbyInfo.GlobalSettings.OrderLatency));
- }
}
public static void StartGame()
diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj
index d3c6ee66cf..f6c2dd173a 100644
--- a/OpenRa.Game/OpenRa.Game.csproj
+++ b/OpenRa.Game/OpenRa.Game.csproj
@@ -117,6 +117,7 @@
+
diff --git a/OpenRa.Game/Orders/UnitOrders.cs b/OpenRa.Game/Orders/UnitOrders.cs
index 1a23ff7f8e..92c2110aad 100644
--- a/OpenRa.Game/Orders/UnitOrders.cs
+++ b/OpenRa.Game/Orders/UnitOrders.cs
@@ -60,6 +60,11 @@ namespace OpenRa.Game.Orders
Game.SyncLobbyInfo(order.TargetString);
break;
}
+ case "FileChunk":
+ {
+ PackageDownloader.ReceiveChunk(order.TargetString);
+ break;
+ }
default:
{
diff --git a/OpenRa.Game/PackageDownloader.cs b/OpenRa.Game/PackageDownloader.cs
new file mode 100644
index 0000000000..3e79ba3459
--- /dev/null
+++ b/OpenRa.Game/PackageDownloader.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenRa.FileFormats;
+using System.IO;
+using System.Security.Cryptography;
+
+namespace OpenRa.Game
+{
+ static class PackageDownloader
+ {
+ static string[] allPackages = { };
+ static List missingPackages = new List();
+ static string currentPackage = null;
+ static MemoryStream content = null;
+
+ public static void SetPackageList(string[] packages)
+ {
+ allPackages = packages;
+ missingPackages = allPackages.Where(p => !HavePackage(p)).ToList();
+
+ if (currentPackage == null || !missingPackages.Contains(currentPackage))
+ BeginDownload();
+ }
+
+ public static void ReceiveChunk(string data)
+ {
+
+ }
+
+ static void BeginDownload()
+ {
+ if (missingPackages.Count == 0)
+ { // we're finished downloading resources!
+ currentPackage = null;
+ return;
+ }
+
+ currentPackage = missingPackages[0];
+ missingPackages.RemoveAt(0);
+
+ content = new MemoryStream();
+ }
+
+ static void EndDownload()
+ {
+ File.WriteAllBytes(currentPackage.Split(':')[0], content.ToArray());
+ currentPackage = null;
+
+ BeginDownload();
+ }
+
+ public static bool IsIdle()
+ {
+ return currentPackage == null
+ && missingPackages.Count == 0;
+ }
+
+ static bool HavePackage(string p)
+ {
+ var parts = p.Split(':');
+ return File.Exists(parts[0]) && CalculateSHA1(parts[0]) == parts[1];
+ }
+
+ public static string CalculateSHA1(string filename)
+ {
+ using (var csp = SHA1.Create())
+ return new string(csp.ComputeHash(File.ReadAllBytes(filename))
+ .SelectMany(a => a.ToString("x2")).ToArray());
+ }
+ }
+}