downloader works.

This commit is contained in:
Chris Forbes
2010-01-16 20:26:51 +13:00
parent e134773a24
commit cff25cf9cc
5 changed files with 100 additions and 17 deletions

View File

@@ -28,6 +28,7 @@ namespace OpenRA.Server
/* file server state */ /* file server state */
public int NextChunk = 0; public int NextChunk = 0;
public int NumChunks = 0; public int NumChunks = 0;
public int RemainingBytes = 0;
public Stream Stream = null; public Stream Stream = null;
} }

View File

@@ -6,6 +6,7 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using System.Security.Cryptography;
namespace OpenRA.Server namespace OpenRA.Server
{ {
@@ -18,8 +19,11 @@ namespace OpenRA.Server
static Session lobbyInfo = new Session(); static Session lobbyInfo = new Session();
static bool GameStarted = false; static bool GameStarted = false;
const int DownloadChunkInterval = 200000; const int DownloadChunkInterval = 20000;
const int DownloadChunkSize = 4096; const int DownloadChunkSize = 16384;
static readonly string[] packages = { };
//static readonly string[] packages = { "testpkg.mix" };
public static void Main(string[] args) public static void Main(string[] args)
{ {
@@ -171,7 +175,7 @@ namespace OpenRA.Server
{ {
try try
{ {
var data = c.Stream.Read(DownloadChunkSize); var data = c.Stream.Read(Math.Min(DownloadChunkSize, c.RemainingBytes));
if (data.Length != 0) if (data.Length != 0)
{ {
var chunk = new Chunk var chunk = new Chunk
@@ -186,11 +190,14 @@ namespace OpenRA.Server
FieldSaver.Save(chunk).Nodes.WriteToString()).Serialize()); FieldSaver.Save(chunk).Nodes.WriteToString()).Serialize());
} }
if (data.Length < DownloadChunkSize) c.RemainingBytes -= data.Length;
if (c.RemainingBytes == 0)
{ {
GetClient(c).State = Session.ClientState.NotReady; GetClient(c).State = Session.ClientState.NotReady;
c.Stream.Dispose(); c.Stream.Dispose();
c.Stream = null; c.Stream = null;
SyncLobbyInfo();
} }
} }
catch (Exception e) { DropClient(c, e); } catch (Exception e) { DropClient(c, e); }
@@ -392,16 +399,19 @@ namespace OpenRA.Server
client.State = Session.ClientState.Downloading; client.State = Session.ClientState.Downloading;
var filename = so.Data.Split(':')[0]; var filename = so.Data.Split(':')[0];
// todo: validate that the SHA1 they asked for matches what we've got.
var length = (int) new FileInfo(filename).Length;
conn.NextChunk = 0;
conn.NumChunks = (length + DownloadChunkSize - 1) / DownloadChunkSize;
if (conn.Stream != null) if (conn.Stream != null)
conn.Stream.Dispose(); conn.Stream.Dispose();
conn.Stream = File.OpenRead(filename); conn.Stream = File.OpenRead(filename);
// todo: validate that the SHA1 they asked for matches what we've got.
var length = (int) new FileInfo(filename).Length;
conn.NextChunk = 0;
conn.NumChunks = (length + DownloadChunkSize - 1) / DownloadChunkSize;
conn.RemainingBytes = length;
SyncLobbyInfo();
} }
break; break;
} }
@@ -447,9 +457,23 @@ namespace OpenRA.Server
Console.WriteLine("Server emptied out; doing a bit of housekeeping to prepare for next game.."); Console.WriteLine("Server emptied out; doing a bit of housekeeping to prepare for next game..");
inFlightFrames.Clear(); inFlightFrames.Clear();
lobbyInfo = new Session(); lobbyInfo = new Session();
lobbyInfo.GlobalSettings.Packages =
packages.Select(a => "{0}:{1}".F(a, CalculateSHA1(a))).ToArray();
foreach( var p in lobbyInfo.GlobalSettings.Packages )
Console.WriteLine("Package: `{0}`", p);
GameStarted = false; GameStarted = false;
} }
static string CalculateSHA1(string filename)
{
using (var csp = SHA1.Create())
return new string(csp.ComputeHash(File.ReadAllBytes(filename))
.SelectMany(a => a.ToString("x2")).ToArray());
}
static void SyncLobbyInfo() static void SyncLobbyInfo()
{ {
var clientData = lobbyInfo.Clients.ToDictionary( var clientData = lobbyInfo.Clients.ToDictionary(

View File

@@ -146,6 +146,8 @@ namespace OpenRa.Game
public void Draw() public void Draw()
{ {
DrawDownloadBar();
if (!Game.orderManager.GameStarted) if (!Game.orderManager.GameStarted)
{ {
DrawLobby(); DrawLobby();
@@ -184,6 +186,36 @@ namespace OpenRa.Game
DrawOptionsMenu(); DrawOptionsMenu();
} }
public void DrawDownloadBar()
{
if (PackageDownloader.IsIdle())
return;
var r = new Rectangle((Game.viewport.Width - 400) / 2, Game.viewport.Height - 110, 400, 100);
DrawDialogBackground(r, optionsSprites, true);
DrawCentered("Downloading: {0} (+{1} more)".F(
PackageDownloader.CurrentPackage.Split(':')[0],
PackageDownloader.RemainingPackages),
new int2( Game.viewport.Width /2, Game.viewport.Height - 90),
Color.White);
DrawDialogBackground(new Rectangle(r.Left + 30, r.Top + 50, r.Width - 60, 20),
panelSprites, false);
var x1 = r.Left + 35;
var x2 = r.Right - 35;
var x = float2.Lerp(x1, x2, PackageDownloader.Fraction);
for (var y = r.Top + 55; y < r.Top + 65; y++)
lineRenderer.DrawLine(
new float2(x1, y) + Game.viewport.Location,
new float2(x, y) + Game.viewport.Location,
Color.White, Color.White);
lineRenderer.Flush();
}
public void DrawLobby() public void DrawLobby()
{ {
var w = 800; var w = 800;
@@ -199,17 +231,17 @@ namespace OpenRa.Game
panelSprites, false); panelSprites, false);
renderer.DrawText2("Name", new int2(r.Left + 30, r.Top + 50), Color.White); renderer.DrawText2("Name", new int2(r.Left + 30, r.Top + 50), Color.White);
renderer.DrawText2("Color", new int2(r.Left + 250, r.Top + 50), Color.White); renderer.DrawText2("Color", new int2(r.Left + 230, r.Top + 50), Color.White);
renderer.DrawText2("Faction", new int2(r.Left + 320, r.Top + 50), Color.White); renderer.DrawText2("Faction", new int2(r.Left + 300, r.Top + 50), Color.White);
renderer.DrawText2("Status", new int2(r.Left + 390, r.Top + 50), Color.White); renderer.DrawText2("Status", new int2(r.Left + 370, r.Top + 50), Color.White);
var y = r.Top + 80; var y = r.Top + 80;
foreach (var client in Game.LobbyInfo.Clients) foreach (var client in Game.LobbyInfo.Clients)
{ {
renderer.DrawText(client.Name, new int2(r.Left + 30, y), Color.White); renderer.DrawText(client.Name, new int2(r.Left + 30, y), Color.White);
renderer.DrawText(((PaletteType)client.Palette).ToString(), new int2(r.Left + 250, y), Color.White); renderer.DrawText(((PaletteType)client.Palette).ToString(), new int2(r.Left + 230, y), Color.White);
renderer.DrawText(((Race)client.Race).ToString(), new int2(r.Left + 320, y), Color.White); renderer.DrawText(((Race)client.Race).ToString(), new int2(r.Left + 300, y), Color.White);
renderer.DrawText(client.State.ToString(), new int2(r.Left + 390, y), Color.White); renderer.DrawText(client.State.ToString(), new int2(r.Left + 370, y), Color.White);
y += 30; y += 30;
} }

View File

@@ -53,9 +53,11 @@ namespace OpenRa.Game
public static Minimap minimap; public static Minimap minimap;
public static Session LobbyInfo = new Session(); public static Session LobbyInfo = new Session();
public static int2[] SpawnPoints; public static int2[] SpawnPoints;
static bool changePending;
public static void ChangeMap(string mapName) public static void ChangeMap(string mapName)
{ {
Game.changePending = false;
Game.mapName = mapName; Game.mapName = mapName;
SheetBuilder.Initialize(renderer); SheetBuilder.Initialize(renderer);
SpriteSheetBuilder.Initialize(); SpriteSheetBuilder.Initialize();
@@ -170,6 +172,12 @@ namespace OpenRa.Game
public static void Tick() public static void Tick()
{ {
if (changePending && PackageDownloader.IsIdle())
{
ChangeMap(LobbyInfo.GlobalSettings.Map);
return;
}
int t = Environment.TickCount; int t = Environment.TickCount;
int dt = t - lastTime; int dt = t - lastTime;
if (dt >= Settings.Timestep) if (dt >= Settings.Timestep)
@@ -392,7 +400,10 @@ namespace OpenRa.Game
PackageDownloader.SetPackageList(LobbyInfo.GlobalSettings.Packages); PackageDownloader.SetPackageList(LobbyInfo.GlobalSettings.Packages);
if (!PackageDownloader.IsIdle()) if (!PackageDownloader.IsIdle())
{
changePending = true;
return; return;
}
if (mapName != LobbyInfo.GlobalSettings.Map) if (mapName != LobbyInfo.GlobalSettings.Map)
{ {

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using OpenRa.FileFormats; using OpenRa.FileFormats;
using System.Drawing;
namespace OpenRa.Game namespace OpenRa.Game
{ {
@@ -14,6 +15,11 @@ namespace OpenRa.Game
static string currentPackage = null; static string currentPackage = null;
static MemoryStream content = null; static MemoryStream content = null;
public static string CurrentPackage { get { return currentPackage; } }
public static int RemainingPackages { get { return missingPackages.Count; } }
public static float Fraction { get; private set; }
public static int DownloadedBytes { get { return (int)content.Length; } }
public static void SetPackageList(string[] packages) public static void SetPackageList(string[] packages)
{ {
allPackages = packages; allPackages = packages;
@@ -21,6 +27,8 @@ namespace OpenRa.Game
if (currentPackage == null || !missingPackages.Contains(currentPackage)) if (currentPackage == null || !missingPackages.Contains(currentPackage))
BeginDownload(); BeginDownload();
else
missingPackages.Remove(currentPackage);
} }
class Chunk { public int Index = 0; public int Count = 0; public string Data = ""; } class Chunk { public int Index = 0; public int Count = 0; public string Data = ""; }
@@ -32,6 +40,8 @@ namespace OpenRa.Game
var bytes = Convert.FromBase64String(c.Data); var bytes = Convert.FromBase64String(c.Data);
content.Write(bytes, 0, bytes.Length); content.Write(bytes, 0, bytes.Length);
Fraction = (float)c.Index / c.Count;
if (c.Index == c.Count - 1) if (c.Index == c.Count - 1)
EndDownload(); EndDownload();
} }
@@ -49,9 +59,12 @@ namespace OpenRa.Game
content = new MemoryStream(); content = new MemoryStream();
Game.chat.AddLine(Color.White, "Debug", "Requesting package: {0}".F(currentPackage));
Game.controller.AddOrder( Game.controller.AddOrder(
new Order("RequestFile", null, null, int2.Zero, currentPackage) new Order("RequestFile", Game.LocalPlayer.PlayerActor, null, int2.Zero, currentPackage) { IsImmediate = true });
{ IsImmediate = true });
Fraction = 0f;
} }
static void EndDownload() static void EndDownload()
@@ -63,6 +76,8 @@ namespace OpenRa.Game
if (CalculateSHA1(parts[0]) != parts[1]) if (CalculateSHA1(parts[0]) != parts[1])
throw new InvalidOperationException("Broken download"); throw new InvalidOperationException("Broken download");
Game.chat.AddLine(Color.White, "Debug", "Finished receiving package: {0}".F(currentPackage));
currentPackage = null; currentPackage = null;
BeginDownload(); BeginDownload();