new
This commit is contained in:
125
Testcaonimabi/LoadPluginsApiController.cs
Normal file
125
Testcaonimabi/LoadPluginsApiController.cs
Normal file
@ -0,0 +1,125 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Testcaonimabi.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("/api/load-plugins")]
|
||||
public class LoadPluginsApiController : ControllerBase
|
||||
{
|
||||
private const string RegKeyPath = @"Software\Nebulamist";
|
||||
private const string KamiValueName = "Kami";
|
||||
private const string HwidValueName = "Hwid";
|
||||
|
||||
private const string PLUGIN_LIST_URL = "https://gitee.com/livelyxuan/nebulamist/raw/master/ver.txt";
|
||||
private const string DEPENDENCIES_LIST_URL = "https://gitee.com/livelyxuan/nebulamist/raw/master/dep.txt ";
|
||||
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public LoadPluginsApiController(IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
string kami = ReadRegistryValue(KamiValueName);
|
||||
string hwid = ReadRegistryValue(HwidValueName);
|
||||
|
||||
if (string.IsNullOrEmpty(kami) || string.IsNullOrEmpty(hwid))
|
||||
{
|
||||
return Ok(new { success = false, message = "δ<>ҵ<EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" });
|
||||
}
|
||||
|
||||
bool isValid = await ValidateKamiAsync(kami, hwid);
|
||||
if (!isValid)
|
||||
{
|
||||
return Ok(new { success = false, message = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤ʧ<D6A4><CAA7>" });
|
||||
}
|
||||
|
||||
await DownloadPluginsAsync();
|
||||
|
||||
return Ok(new { success = true, message = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, new { success = false, message = "<22><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadRegistryValue(string valueName)
|
||||
{
|
||||
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegKeyPath))
|
||||
{
|
||||
return key?.GetValue(valueName) as string;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> ValidateKamiAsync(string kami, string hwid)
|
||||
{
|
||||
var client = _httpClientFactory.CreateClient();
|
||||
var url = $"http://127.0.0.1:5678/login?kami={Uri.EscapeDataString(kami)}&hwid={Uri.EscapeDataString(hwid)}";
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await response.Content.ReadFromJsonAsync<ApiResponse>();
|
||||
return json?.Success == true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task DownloadPluginsAsync()
|
||||
{
|
||||
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
var pluginsDir = Path.Combine(appData, "EXILED", "Plugins");
|
||||
var dependenciesDir = Path.Combine(pluginsDir, "dependencies");
|
||||
|
||||
Directory.CreateDirectory(pluginsDir);
|
||||
Directory.CreateDirectory(dependenciesDir);
|
||||
|
||||
var client = _httpClientFactory.CreateClient();
|
||||
|
||||
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD>б<EFBFBD>
|
||||
var pluginList = await client.GetStringAsync(PLUGIN_LIST_URL);
|
||||
var lines = pluginList.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (lines.Length < 2)
|
||||
throw new Exception("<22><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>");
|
||||
|
||||
var pluginUrl = lines[1];
|
||||
var pluginName = Path.GetFileName(new Uri(pluginUrl).LocalPath);
|
||||
var pluginPath = Path.Combine(pluginsDir, pluginName);
|
||||
|
||||
var pluginBytes = await client.GetByteArrayAsync(pluginUrl);
|
||||
await System.IO.File.WriteAllBytesAsync(pluginPath, pluginBytes);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||||
var dependenciesList = await client.GetStringAsync(DEPENDENCIES_LIST_URL);
|
||||
var dependencyUrls = dependenciesList.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (var depUrl in dependencyUrls)
|
||||
{
|
||||
var depName = Path.GetFileName(new Uri(depUrl).LocalPath);
|
||||
var depPath = Path.Combine(dependenciesDir, depName);
|
||||
|
||||
var depBytes = await client.GetByteArrayAsync(depUrl);
|
||||
await System.IO.File.WriteAllBytesAsync(depPath, depBytes);
|
||||
}
|
||||
}
|
||||
|
||||
private class ApiResponse
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Testcaonimabi/Pages/Dashboard.cshtml
Normal file
105
Testcaonimabi/Pages/Dashboard.cshtml
Normal file
@ -0,0 +1,105 @@
|
||||
@page
|
||||
@model Testcaonimabi.Pages.DashboardModel
|
||||
@{
|
||||
Layout = null;
|
||||
ViewData["Title"] = "仪表盘";
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>@ViewData["Title"]</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg, #4e54c8, #8f94fb);
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dashboard-card {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 16px;
|
||||
padding: 40px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.status {
|
||||
margin-top: 20px;
|
||||
font-size: 14px;
|
||||
color: #ccc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="dashboard-card">
|
||||
<h2>✅ 欢迎使用 Nebulamist</h2>
|
||||
<button onclick="loadPlugins()">加载插件</button>
|
||||
<div class="status" id="status">等待操作...</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function loadPlugins() {
|
||||
const status = document.getElementById('status');
|
||||
status.textContent = '正在验证注册表...';
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/load-plugins');
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
status.textContent = data.message || '插件加载完成!';
|
||||
} else {
|
||||
status.textContent = '验证失败,即将跳转登录页...';
|
||||
setTimeout(() => {
|
||||
window.location.href = '/Index';
|
||||
}, 1500);
|
||||
}
|
||||
} catch (err) {
|
||||
status.textContent = '请求失败: ' + err.message;
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
71
Testcaonimabi/Pages/Dashboard.cshtml.cs
Normal file
71
Testcaonimabi/Pages/Dashboard.cshtml.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Win32;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Testcaonimabi.Pages
|
||||
{
|
||||
public class DashboardModel : PageModel
|
||||
{
|
||||
private const string RegKeyPath = @"Software\Nebulamist";
|
||||
private const string KamiValueName = "Kami";
|
||||
private const string HwidValueName = "Hwid";
|
||||
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public DashboardModel(IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnGet()
|
||||
{
|
||||
string kami = ReadRegistryValue(KamiValueName);
|
||||
string hwid = ReadRegistryValue(HwidValueName);
|
||||
|
||||
if (string.IsNullOrEmpty(kami) || string.IsNullOrEmpty(hwid))
|
||||
{
|
||||
return RedirectToPage("/Index");
|
||||
}
|
||||
|
||||
bool isValid = await ValidateKamiAsync(kami, hwid);
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
return RedirectToPage("/Index");
|
||||
}
|
||||
|
||||
return Page();
|
||||
}
|
||||
|
||||
private string ReadRegistryValue(string valueName)
|
||||
{
|
||||
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegKeyPath))
|
||||
{
|
||||
return key?.GetValue(valueName) as string;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> ValidateKamiAsync(string kami, string hwid)
|
||||
{
|
||||
var client = _httpClientFactory.CreateClient();
|
||||
var url = $"http://127.0.0.1:5678/login?kami={Uri.EscapeDataString(kami)}&hwid={Uri.EscapeDataString(hwid)}";
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await response.Content.ReadFromJsonAsync<ApiResponse>();
|
||||
return json?.Success == true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class ApiResponse
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
@page
|
||||
@model ErrorModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
@ -1,28 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Testcaonimabi.Pages
|
||||
{
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
[IgnoreAntiforgeryToken]
|
||||
public class ErrorModel : PageModel
|
||||
{
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
|
||||
private readonly ILogger<ErrorModel> _logger;
|
||||
|
||||
public ErrorModel(ILogger<ErrorModel> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,10 +1,154 @@
|
||||
@page
|
||||
@model IndexModel
|
||||
@{
|
||||
ViewData["Title"] = "Home page";
|
||||
Layout = null; // 隐藏默认布局(Home / Privacy 等链接)
|
||||
ViewData["Title"] = "卡密登录";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">你好</h1>
|
||||
<p>您的机器码 @IndexModel.HwidOK</p>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>@ViewData["Title"]</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg, #4e54c8, #8f94fb);
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 16px;
|
||||
padding: 40px 30px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 12px 15px;
|
||||
margin: 15px 0;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
outline: none;
|
||||
font-size: 16px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
input[type="text"]:focus {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
box-shadow: 0 0 8px rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 20px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #a8e6cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #ffaaa5;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="login-card">
|
||||
<h2>卡密登录</h2>
|
||||
<input type="text" id="kamiInput" placeholder="请输入卡密" />
|
||||
<button onclick="login()">登录</button>
|
||||
<div class="result" id="resultMessage"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 混淆变量名,增加阅读难度
|
||||
const _k = 'kamiInput';
|
||||
const _r = 'resultMessage';
|
||||
const _s = 'success';
|
||||
const _e = 'error';
|
||||
|
||||
function login() {
|
||||
const k = document.getElementById(_k).value.trim();
|
||||
const hwid = '@IndexModel.HwidOK';
|
||||
const resultDiv = document.getElementById(_r);
|
||||
|
||||
if (!k) {
|
||||
resultDiv.textContent = '卡密不能为空';
|
||||
resultDiv.className = 'result ' + _e;
|
||||
return;
|
||||
}
|
||||
|
||||
const url = `http://127.0.0.1:5678/login?kami=${encodeURIComponent(k)}&hwid=${encodeURIComponent(hwid)}`;
|
||||
|
||||
fetch(url)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error('网络异常');
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data[_s]) {
|
||||
resultDiv.textContent = data.message || '登录成功';
|
||||
resultDiv.className = 'result ' + _s;
|
||||
setTimeout(() => {
|
||||
window.location.href = `/LoginSuccessModel?kami=${encodeURIComponent(k)}`; // 登录成功后跳转页面
|
||||
|
||||
}, 1500);
|
||||
} else {
|
||||
resultDiv.textContent = data.message || '登录失败';
|
||||
resultDiv.className = 'result ' + _e;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
resultDiv.textContent = '请求失败,请检查网络或重试';
|
||||
resultDiv.className = 'result ' + _e;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,24 +1,81 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Win32;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Testcaonimabi.Pages
|
||||
{
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
public static string HwidOK { get; private set; }
|
||||
private readonly ILogger<IndexModel> _logger;
|
||||
private const string RegKeyPath = @"Software\Nebulamist";
|
||||
private const string KamiValueName = "Kami";
|
||||
private const string HwidValueName = "Hwid";
|
||||
|
||||
public IndexModel(ILogger<IndexModel> logger)
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public IndexModel(IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void OnGet()
|
||||
public static string HwidOK { get; private set; }
|
||||
public async Task<IActionResult> OnGet()
|
||||
{
|
||||
// <20><>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ kami <20><> hwid
|
||||
string kami = ReadRegistryValue(KamiValueName);
|
||||
string hwid = ReadRegistryValue(HwidValueName);
|
||||
HwidOK = Melody.Start.Start.Hwid;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF>ܺ<EFBFBD> hwid<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>¼
|
||||
if (!string.IsNullOrEmpty(kami) && !string.IsNullOrEmpty(hwid))
|
||||
{
|
||||
bool isValid = await ValidateKamiAsync(kami, hwid);
|
||||
|
||||
if (isValid)
|
||||
{
|
||||
// <20><>֤<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>DZ<EFBFBD><C7B1><EFBFBD>
|
||||
return RedirectToPage("/Dashboard");
|
||||
}
|
||||
}
|
||||
|
||||
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD>ʾ<EFBFBD><CABE>¼ҳ<C2BC><D2B3>
|
||||
return Page();
|
||||
}
|
||||
|
||||
private string ReadRegistryValue(string valueName)
|
||||
{
|
||||
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegKeyPath))
|
||||
{
|
||||
return key?.GetValue(valueName) as string;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> ValidateKamiAsync(string kami, string hwid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = _httpClientFactory.CreateClient();
|
||||
var url = $"http://127.0.0.1:5678/login?kami={Uri.EscapeDataString(kami)}&hwid={Uri.EscapeDataString(hwid)}";
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var json = await response.Content.ReadFromJsonAsync<ApiResponse>();
|
||||
return json?.Success == true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class ApiResponse
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Testcaonimabi/Pages/LoginSuccessModel.cshtml
Normal file
82
Testcaonimabi/Pages/LoginSuccessModel.cshtml
Normal file
@ -0,0 +1,82 @@
|
||||
@page
|
||||
@model Testcaonimabi.Pages.LoginSuccessModel
|
||||
@{
|
||||
Layout = null; // 不使用默认布局
|
||||
ViewData["Title"] = "验证已完成";
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>@ViewData["Title"]</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg, #4e54c8, #8f94fb);
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.success-box {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 16px;
|
||||
padding: 40px;
|
||||
max-width: 400px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.success-box h1 {
|
||||
font-size: 28px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.success-box p {
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.countdown {
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
color: #a8e6cf;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="success-box">
|
||||
<h1>✅ 验证已完成</h1>
|
||||
<p>卡密:<strong>@ViewData["Kami"]</strong></p>
|
||||
<p>即将跳转到仪表盘...</p>
|
||||
<div class="countdown" id="countdown">3 秒后跳转</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let timeLeft = 10;
|
||||
const countdown = document.getElementById('countdown');
|
||||
|
||||
const timer = setInterval(() => {
|
||||
timeLeft--;
|
||||
if (timeLeft <= 0) {
|
||||
clearInterval(timer);
|
||||
window.location.href = '/Dashboard';
|
||||
} else {
|
||||
countdown.textContent = `${timeLeft} 秒后跳转`;
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
27
Testcaonimabi/Pages/LoginSuccessModel.cshtml.cs
Normal file
27
Testcaonimabi/Pages/LoginSuccessModel.cshtml.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Testcaonimabi.Pages
|
||||
{
|
||||
public class LoginSuccessModel : PageModel
|
||||
{
|
||||
[BindProperty(SupportsGet = true)]
|
||||
public string Kami { get; set; }
|
||||
|
||||
public IActionResult OnGet()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Kami))
|
||||
{
|
||||
return Page(); // <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
}
|
||||
|
||||
// ִ<><D6B4><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
VerifyOK.OK(Kami);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> ViewData <20><>ҳ<EFBFBD><D2B3>ʹ<EFBFBD><CAB9>
|
||||
ViewData["Kami"] = Kami;
|
||||
|
||||
return Page();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
@page
|
||||
@model PrivacyModel
|
||||
@{
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
}
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
|
||||
<p>Use this page to detail your site's privacy policy.</p>
|
||||
@ -1,20 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace Testcaonimabi.Pages
|
||||
{
|
||||
public class PrivacyModel : PageModel
|
||||
{
|
||||
private readonly ILogger<PrivacyModel> _logger;
|
||||
|
||||
public PrivacyModel(ILogger<PrivacyModel> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -8,7 +8,8 @@ var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
|
||||
builder.Services.AddHttpClient();
|
||||
builder.Services.AddControllers(); // <20><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> API
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
@ -21,7 +22,7 @@ if (!app.Environment.IsDevelopment())
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.MapControllers(); //
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Hardware.Info;
|
||||
using Microsoft.Win32;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
@ -25,6 +26,8 @@ static class Mysql
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -33,8 +36,8 @@ static class Mysql
|
||||
|
||||
static class Start
|
||||
{
|
||||
private const string RegKeyPath = @"Software\hwid";
|
||||
private const string RegValueName = "hwid";
|
||||
private const string RegKeyPath = @"Software\Nebulamist";
|
||||
private const string RegValueName = "Hwid";
|
||||
|
||||
// AES 密钥和 IV(请自行更换为安全的值)
|
||||
private static readonly byte[] AesKey = Encoding.UTF8.GetBytes("NipjYde7wp4iCFW7Mfdw0PwdHR4CURpQ");
|
||||
@ -54,7 +57,7 @@ static class Start
|
||||
//Console.WriteLine("硬盘序列号: " + diskSerial);
|
||||
|
||||
// 拼接 HWID
|
||||
string hwid = $"CPU ID{cpuId}|Motherboard:{motherboardSerial}|Bios:{biosUuid}|Disk:{diskSerial}128Code:{ReadRegistryValue()}";
|
||||
string hwid = $"32Code:{ReadRegistryValue()}";
|
||||
byte[] hwidBytes = Encoding.UTF8.GetBytes(hwid);
|
||||
string hwidHex = BitConverter.ToString(hwidBytes).Replace("-", "");
|
||||
|
||||
@ -70,7 +73,7 @@ static class Start
|
||||
|
||||
if (!string.IsNullOrEmpty(existingFingerprint))
|
||||
{
|
||||
Console.WriteLine("随机128位字符(来自注册表): " + existingFingerprint);
|
||||
//Console.WriteLine("随机32位字符(来自注册表): " + existingFingerprint);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,10 +83,15 @@ static class Start
|
||||
|
||||
// 写入注册表
|
||||
WriteRegistryValue(random128);
|
||||
//Console.WriteLine("指纹已写入注册表:HKEY_CURRENT_USER\\" + RegKeyPath);
|
||||
}
|
||||
Console.WriteLine("检测到程序第一次打开 请重新启动");
|
||||
//重启程序
|
||||
Environment.Exit(2333);
|
||||
|
||||
static string GetCpuId()
|
||||
|
||||
//Console.WriteLine("指纹已写入注册表:HKEY_CURRENT_USER\\" + RegKeyPath);
|
||||
}
|
||||
|
||||
static string GetCpuId()
|
||||
{
|
||||
var info = new HardwareInfo();
|
||||
info.RefreshAll();
|
||||
|
||||
29
Testcaonimabi/VerifyOK.cs
Normal file
29
Testcaonimabi/VerifyOK.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
|
||||
namespace Testcaonimabi
|
||||
{
|
||||
public class VerifyOK
|
||||
{
|
||||
private const string RegKeyPath = @"Software\Nebulamist";
|
||||
private const string KamiValueName = "Kami";
|
||||
|
||||
public static void OK(string kami)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 打开或创建注册表项
|
||||
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(RegKeyPath))
|
||||
{
|
||||
// 设置卡密值
|
||||
key.SetValue(KamiValueName, kami, RegistryValueKind.String);
|
||||
Console.WriteLine($"✅ 卡密已保存到注册表: {kami}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ 保存卡密到注册表失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user