downloader works.
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user