Allow clients to allocate keys from the server
This commit is contained in:
parent
a0e15514e3
commit
6863417736
9 changed files with 198 additions and 31 deletions
|
@ -8,6 +8,7 @@ using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -129,5 +130,55 @@ namespace LANCommander.PlaynitePlugin
|
||||||
{
|
{
|
||||||
return DownloadRequest($"/api/Archives/Download/{id}", progressHandler, completeHandler);
|
return DownloadRequest($"/api/Archives/Download/{id}", progressHandler, completeHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetKey(Guid id)
|
||||||
|
{
|
||||||
|
var macAddress = GetMacAddress();
|
||||||
|
|
||||||
|
var request = new KeyRequest()
|
||||||
|
{
|
||||||
|
GameId = id,
|
||||||
|
MacAddress = macAddress,
|
||||||
|
ComputerName = Environment.MachineName,
|
||||||
|
IpAddress = GetIpAddress(),
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = PostRequest<Key>($"/api/Keys/Get", request);
|
||||||
|
|
||||||
|
return response.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetNewKey(Guid id)
|
||||||
|
{
|
||||||
|
var macAddress = GetMacAddress();
|
||||||
|
|
||||||
|
var request = new KeyRequest()
|
||||||
|
{
|
||||||
|
GameId = id,
|
||||||
|
MacAddress = macAddress,
|
||||||
|
ComputerName = Environment.MachineName,
|
||||||
|
IpAddress = GetIpAddress(),
|
||||||
|
};
|
||||||
|
|
||||||
|
var response = PostRequest<Key>($"/api/Keys/Allocate/{id}", request);
|
||||||
|
|
||||||
|
if (response == null)
|
||||||
|
return String.Empty;
|
||||||
|
|
||||||
|
return response.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetMacAddress()
|
||||||
|
{
|
||||||
|
return NetworkInterface.GetAllNetworkInterfaces()
|
||||||
|
.Where(nic => nic.OperationalStatus == OperationalStatus.Up && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
|
||||||
|
.Select(nic => nic.GetPhysicalAddress().ToString())
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetIpAddress()
|
||||||
|
{
|
||||||
|
return Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
@ -171,7 +172,22 @@ namespace LANCommander.PlaynitePlugin
|
||||||
Description = "Change Game Key",
|
Description = "Change Game Key",
|
||||||
Action = (keyChangeArgs) =>
|
Action = (keyChangeArgs) =>
|
||||||
{
|
{
|
||||||
PowerShellRuntime.RunScript(keyChangeArgs.Games.First(), SDK.Enums.ScriptType.KeyChange);
|
Guid gameId;
|
||||||
|
|
||||||
|
if (Guid.TryParse(keyChangeArgs.Games.First().GameId, out gameId))
|
||||||
|
{
|
||||||
|
// NUKIEEEE
|
||||||
|
var newKey = LANCommander.GetNewKey(gameId);
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(newKey))
|
||||||
|
PlayniteApi.Dialogs.ShowErrorMessage("There are no more keys available on the server.", "No Keys Available");
|
||||||
|
else
|
||||||
|
PowerShellRuntime.RunScript(keyChangeArgs.Games.First(), SDK.Enums.ScriptType.KeyChange, $@"""{newKey}""");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayniteApi.Dialogs.ShowErrorMessage("This game could not be found on the server. Your game may be corrupted.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,27 +13,35 @@ namespace LANCommander.PlaynitePlugin
|
||||||
{
|
{
|
||||||
internal class PowerShellRuntime
|
internal class PowerShellRuntime
|
||||||
{
|
{
|
||||||
public void RunScript(string path)
|
public void RunScript(string path, string arguments = null)
|
||||||
{
|
{
|
||||||
var process = new Process();
|
var process = new Process();
|
||||||
process.StartInfo.FileName = "powershell.exe";
|
process.StartInfo.FileName = "powershell.exe";
|
||||||
process.StartInfo.Arguments = $@"-File ""{path}""";
|
process.StartInfo.Arguments = $@"-File ""{path}""";
|
||||||
|
|
||||||
|
if (arguments != null)
|
||||||
|
process.StartInfo.Arguments += " " + arguments;
|
||||||
|
|
||||||
process.Start();
|
process.Start();
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunScriptAsAdmin(string path)
|
public void RunScriptAsAdmin(string path, string arguments = null)
|
||||||
{
|
{
|
||||||
var process = new Process();
|
var process = new Process();
|
||||||
process.StartInfo.FileName = "powershell.exe";
|
process.StartInfo.FileName = "powershell.exe";
|
||||||
process.StartInfo.UseShellExecute = true;
|
process.StartInfo.UseShellExecute = true;
|
||||||
process.StartInfo.Verb = "runas";
|
process.StartInfo.Verb = "runas";
|
||||||
process.StartInfo.Arguments = $@"-ExecutionPolicy Unrestricted -File ""{path}""";
|
process.StartInfo.Arguments = $@"-ExecutionPolicy Unrestricted -File ""{path}""";
|
||||||
|
|
||||||
|
if (arguments != null)
|
||||||
|
process.StartInfo.Arguments += " " + arguments;
|
||||||
|
|
||||||
process.Start();
|
process.Start();
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunScript(Game game, ScriptType type)
|
public void RunScript(Game game, ScriptType type, string arguments = null)
|
||||||
{
|
{
|
||||||
var path = GetScriptFilePath(game, type);
|
var path = GetScriptFilePath(game, type);
|
||||||
|
|
||||||
|
@ -42,9 +50,9 @@ namespace LANCommander.PlaynitePlugin
|
||||||
var contents = File.ReadAllText(path);
|
var contents = File.ReadAllText(path);
|
||||||
|
|
||||||
if (contents.StartsWith("# Requires Admin"))
|
if (contents.StartsWith("# Requires Admin"))
|
||||||
RunScriptAsAdmin(path);
|
RunScriptAsAdmin(path, arguments);
|
||||||
else
|
else
|
||||||
RunScript(path);
|
RunScript(path, arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace LANCommander.PlaynitePlugin.Views
|
||||||
|
|
||||||
private void TextBox_KeyDown(object sender, KeyEventArgs e)
|
private void TextBox_KeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Key == Key.Enter || e.Key == Key.Return)
|
if (e.Key == System.Windows.Input.Key.Enter || e.Key == System.Windows.Input.Key.Return)
|
||||||
{
|
{
|
||||||
Authenticate();
|
Authenticate();
|
||||||
}
|
}
|
||||||
|
|
21
LANCommander.SDK/Models/Key.cs
Normal file
21
LANCommander.SDK/Models/Key.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LANCommander.SDK.Models
|
||||||
|
{
|
||||||
|
public class Key : BaseModel
|
||||||
|
{
|
||||||
|
public string Value { get; set; }
|
||||||
|
public virtual Game Game { get; set; }
|
||||||
|
public KeyAllocationMethod AllocationMethod { get; set; }
|
||||||
|
public string ClaimedByMacAddress { get; set; }
|
||||||
|
public string ClaimedByIpv4Address { get; set; }
|
||||||
|
public string ClaimedByComputerName { get; set; }
|
||||||
|
public DateTime? ClaimedOn { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum KeyAllocationMethod
|
||||||
|
{
|
||||||
|
UserAccount,
|
||||||
|
MacAddress
|
||||||
|
}
|
||||||
|
}
|
14
LANCommander.SDK/Models/KeyRequest.cs
Normal file
14
LANCommander.SDK/Models/KeyRequest.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace LANCommander.SDK.Models
|
||||||
|
{
|
||||||
|
public class KeyRequest
|
||||||
|
{
|
||||||
|
public Guid GameId { get; set; }
|
||||||
|
public string MacAddress { get; set; }
|
||||||
|
public string IpAddress { get; set; }
|
||||||
|
public string ComputerName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
49
LANCommander/Controllers/Api/KeysController.cs
Normal file
49
LANCommander/Controllers/Api/KeysController.cs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
using LANCommander.Data;
|
||||||
|
using LANCommander.Data.Models;
|
||||||
|
using LANCommander.Extensions;
|
||||||
|
using LANCommander.SDK.Models;
|
||||||
|
using LANCommander.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace LANCommander.Controllers.Api
|
||||||
|
{
|
||||||
|
[Authorize(AuthenticationSchemes = "Bearer")]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class KeysController : ControllerBase
|
||||||
|
{
|
||||||
|
private KeyService KeyService;
|
||||||
|
|
||||||
|
public KeysController(KeyService keyService)
|
||||||
|
{
|
||||||
|
KeyService = keyService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public Data.Models.Key Get(KeyRequest keyRequest)
|
||||||
|
{
|
||||||
|
return KeyService.Get(k => k.AllocationMethod == Data.Models.KeyAllocationMethod.MacAddress && k.ClaimedByMacAddress == keyRequest.MacAddress).First();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("Allocate/{id}")]
|
||||||
|
public async Task<Data.Models.Key> Allocate(Guid id, KeyRequest keyRequest)
|
||||||
|
{
|
||||||
|
var existing = KeyService.Get(k => k.Game.Id == id && k.AllocationMethod == Data.Models.KeyAllocationMethod.MacAddress && keyRequest.MacAddress == keyRequest.MacAddress).FirstOrDefault();
|
||||||
|
|
||||||
|
if (existing != null)
|
||||||
|
await KeyService.Release(existing.Id);
|
||||||
|
|
||||||
|
var availableKey = KeyService.Get(k =>
|
||||||
|
(k.AllocationMethod == Data.Models.KeyAllocationMethod.MacAddress && String.IsNullOrWhiteSpace(k.ClaimedByMacAddress))
|
||||||
|
||
|
||||||
|
(k.AllocationMethod == Data.Models.KeyAllocationMethod.UserAccount && k.ClaimedByUser == null))
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (availableKey == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return await KeyService.Allocate(availableKey, keyRequest.MacAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ using LANCommander.Data;
|
||||||
using LANCommander.Data.Models;
|
using LANCommander.Data.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using LANCommander.Models;
|
using LANCommander.Models;
|
||||||
|
using LANCommander.Services;
|
||||||
|
|
||||||
namespace LANCommander.Controllers
|
namespace LANCommander.Controllers
|
||||||
{
|
{
|
||||||
|
@ -16,10 +17,12 @@ namespace LANCommander.Controllers
|
||||||
public class KeysController : Controller
|
public class KeysController : Controller
|
||||||
{
|
{
|
||||||
private readonly DatabaseContext Context;
|
private readonly DatabaseContext Context;
|
||||||
|
private readonly KeyService KeyService;
|
||||||
|
|
||||||
public KeysController(DatabaseContext context)
|
public KeysController(DatabaseContext context, KeyService keyService)
|
||||||
{
|
{
|
||||||
Context = context;
|
Context = context;
|
||||||
|
KeyService = keyService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Details(Guid? id)
|
public async Task<IActionResult> Details(Guid? id)
|
||||||
|
@ -94,32 +97,14 @@ namespace LANCommander.Controllers
|
||||||
|
|
||||||
public async Task<IActionResult> Release(Guid id)
|
public async Task<IActionResult> Release(Guid id)
|
||||||
{
|
{
|
||||||
using (var repo = new Repository<Key>(Context, HttpContext))
|
var existing = await KeyService.Get(id);
|
||||||
{
|
|
||||||
var key = await repo.Find(id);
|
|
||||||
|
|
||||||
if (key == null)
|
if (existing == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
switch (key.AllocationMethod)
|
await KeyService.Release(id);
|
||||||
{
|
|
||||||
case KeyAllocationMethod.UserAccount:
|
|
||||||
key.ClaimedByUser = null;
|
|
||||||
key.ClaimedOn = null;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KeyAllocationMethod.MacAddress:
|
return RedirectToAction("Details", "Keys", new { id = existing.Game.Id });
|
||||||
key.ClaimedByMacAddress = "";
|
|
||||||
key.ClaimedOn = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
repo.Update(key);
|
|
||||||
|
|
||||||
await repo.SaveChanges();
|
|
||||||
|
|
||||||
return RedirectToAction("Details", "Keys", new { id = key.Game.Id });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,5 +28,28 @@ namespace LANCommander.Services
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Release(Guid id)
|
||||||
|
{
|
||||||
|
var key = await Get(id);
|
||||||
|
|
||||||
|
if (key == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (key.AllocationMethod)
|
||||||
|
{
|
||||||
|
case KeyAllocationMethod.UserAccount:
|
||||||
|
key.ClaimedByUser = null;
|
||||||
|
key.ClaimedOn = null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyAllocationMethod.MacAddress:
|
||||||
|
key.ClaimedByMacAddress = "";
|
||||||
|
key.ClaimedOn = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Update(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue