Add game importing via CLI
This commit is contained in:
parent
4009aa3892
commit
bf9ef30b4b
7 changed files with 114 additions and 4 deletions
|
|
@ -8,6 +8,12 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace LANCommander.Launcher.Models
|
||||
{
|
||||
public enum ImportArchiveType {
|
||||
Game,
|
||||
Redistributable,
|
||||
Server
|
||||
}
|
||||
|
||||
[Verb("RunScript", HelpText = "Run a script for a game")]
|
||||
public class RunScriptCommandLineOptions
|
||||
{
|
||||
|
|
@ -44,8 +50,18 @@ namespace LANCommander.Launcher.Models
|
|||
public Guid GameId { get; set; }
|
||||
}
|
||||
|
||||
[Verb("Import", HelpText = "Import library items from the server")]
|
||||
public class ImportCommandLineOptions { }
|
||||
[Verb("Sync", HelpText = "Sync library items from the server")]
|
||||
public class SyncCommandLineOptions { }
|
||||
|
||||
[Verb("Import", HelpText = "Upload and import an archive to the server (Admin Only)")]
|
||||
public class ImportCommandLineOptions
|
||||
{
|
||||
[Option("Path", HelpText = "Path to the archive file", Required = true)]
|
||||
public string Path { get; set; }
|
||||
|
||||
[Option("Type", HelpText = "The type of archive to import", Required = true)]
|
||||
public ImportArchiveType Type { get; set; }
|
||||
}
|
||||
|
||||
[Verb("Login", HelpText = "Login to a LANCommander server")]
|
||||
public class LoginCommandLineOptions
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace LANCommander.Launcher.Services
|
|||
RunScriptCommandLineOptions,
|
||||
InstallCommandLineOptions,
|
||||
UninstallCommandLineOptions,
|
||||
ImportCommandLineOptions,
|
||||
SyncCommandLineOptions,
|
||||
LoginCommandLineOptions,
|
||||
LogoutCommandLineOptions,
|
||||
ChangeAliasCommandLineOptions
|
||||
|
|
@ -45,6 +45,7 @@ namespace LANCommander.Launcher.Services
|
|||
await result.WithParsedAsync<RunScriptCommandLineOptions>(RunScript);
|
||||
await result.WithParsedAsync<InstallCommandLineOptions>(Install);
|
||||
await result.WithParsedAsync<UninstallCommandLineOptions>(Uninstall);
|
||||
await result.WithParsedAsync<SyncCommandLineOptions>(Sync);
|
||||
await result.WithParsedAsync<ImportCommandLineOptions>(Import);
|
||||
await result.WithParsedAsync<LoginCommandLineOptions>(Login);
|
||||
await result.WithParsedAsync<LogoutCommandLineOptions>(Logout);
|
||||
|
|
@ -120,7 +121,7 @@ namespace LANCommander.Launcher.Services
|
|||
}
|
||||
}
|
||||
|
||||
private async Task Import(ImportCommandLineOptions options)
|
||||
private async Task Sync(SyncCommandLineOptions options)
|
||||
{
|
||||
Console.WriteLine("Importing games from server...");
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using RestSharp;
|
|||
using RestSharp.Interceptors;
|
||||
using Semver;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
|
|
@ -312,6 +313,41 @@ namespace LANCommander.SDK
|
|||
return response;
|
||||
}
|
||||
|
||||
internal async Task<Guid> ChunkedUploadRequestAsync(string fileName, Stream stream, bool ignoreVersion = false)
|
||||
{
|
||||
var maxChunkSize = 1024 * 1024 * 50;
|
||||
var initResponse = await PostRequestAsync<UploadInitResponse>("/Upload/Init", ignoreVersion);
|
||||
|
||||
var buffer = new byte[maxChunkSize];
|
||||
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
var chunkRequest = new UploadChunkRequest();
|
||||
|
||||
chunkRequest.Start = stream.Position;
|
||||
|
||||
if (stream.Position + maxChunkSize > stream.Length)
|
||||
{
|
||||
var bytes = stream.Length - stream.Position;
|
||||
|
||||
buffer = new byte[bytes];
|
||||
|
||||
await stream.ReadAsync(buffer, 0, (int)(stream.Length - stream.Position));
|
||||
}
|
||||
else
|
||||
await stream.ReadAsync(buffer, 0, maxChunkSize);
|
||||
|
||||
chunkRequest.End = stream.Position;
|
||||
chunkRequest.Total = stream.Length;
|
||||
chunkRequest.File = buffer;
|
||||
chunkRequest.Key = initResponse.Key;
|
||||
|
||||
await PostRequestAsync<object>("/Upload/Chunk", chunkRequest, ignoreVersion);
|
||||
}
|
||||
|
||||
return initResponse.Key;
|
||||
}
|
||||
|
||||
public async Task<AuthToken> AuthenticateAsync(string username, string password, bool ignoreVersion = false)
|
||||
{
|
||||
var request = new RestRequest("/api/Auth", Method.Post);
|
||||
|
|
|
|||
|
|
@ -614,6 +614,17 @@ namespace LANCommander.SDK
|
|||
Reader?.Cancel();
|
||||
}
|
||||
|
||||
public async Task ImportAsync(string archivePath)
|
||||
{
|
||||
using (var fs = new FileStream(archivePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
var objectKey = await Client.ChunkedUploadRequestAsync("", fs);
|
||||
|
||||
if (objectKey != Guid.Empty)
|
||||
await Client.PostRequestAsync<object>($"/api/Games/Import/{objectKey}");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetMetadataDirectoryPath(string installDirectory, Guid gameId)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(installDirectory))
|
||||
|
|
|
|||
17
LANCommander.SDK/Models/UploadChunkRequest.cs
Normal file
17
LANCommander.SDK/Models/UploadChunkRequest.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LANCommander.SDK.Models
|
||||
{
|
||||
internal class UploadChunkRequest
|
||||
{
|
||||
internal byte[] File { get; set; }
|
||||
internal long Start { get; set; }
|
||||
internal long End { get; set; }
|
||||
internal long Total { get; set; }
|
||||
internal Guid Key { get; set; }
|
||||
}
|
||||
}
|
||||
13
LANCommander.SDK/Models/UploadInitResponse.cs
Normal file
13
LANCommander.SDK/Models/UploadInitResponse.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LANCommander.SDK.Models
|
||||
{
|
||||
internal class UploadInitResponse
|
||||
{
|
||||
public Guid Key { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -110,5 +110,21 @@ namespace LANCommander.Server.Controllers.Api
|
|||
|
||||
return File(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read), "application/octet-stream", $"{game.Title.SanitizeFilename()}.zip");
|
||||
}
|
||||
|
||||
[Authorize(Roles = "Administrator")]
|
||||
[HttpPost("Import/{objectKey}")]
|
||||
public async Task<IActionResult> Import(Guid objectKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
var game = await GameService.Import(objectKey);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue