添加项目文件。
This commit is contained in:
14
NebulaMistWebBackstage.csproj
Normal file
14
NebulaMistWebBackstage.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MySql.Data" Version="9.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
25
NebulaMistWebBackstage.sln
Normal file
25
NebulaMistWebBackstage.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.14.36202.13 d17.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NebulaMistWebBackstage", "NebulaMistWebBackstage.csproj", "{262A3E75-8129-45E2-80B8-857674CA509A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{262A3E75-8129-45E2-80B8-857674CA509A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{262A3E75-8129-45E2-80B8-857674CA509A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{262A3E75-8129-45E2-80B8-857674CA509A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{262A3E75-8129-45E2-80B8-857674CA509A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {A1519DF8-F179-4278-B5E0-BD8F8CB526A8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
268
Program.cs
Normal file
268
Program.cs
Normal file
@ -0,0 +1,268 @@
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace NebulaMistWebBackstage
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
// 修改为你的数据库连接信息
|
||||
private const string ConnectionString = "server=127.0.0.1;port=3306;user=root;password=root;database=apidb;pooling=true;";
|
||||
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
TestDatabaseConnection(); // 测试数据库连接
|
||||
|
||||
var listener = new HttpListener();
|
||||
listener.Prefixes.Add("http://*:5678/");
|
||||
listener.Start();
|
||||
Console.WriteLine("HTTP 服务已启动,监听地址:http://*:5678");
|
||||
|
||||
while (true)
|
||||
{
|
||||
var context = await listener.GetContextAsync();
|
||||
_ = HandleRequestAsync(context);
|
||||
}
|
||||
}
|
||||
|
||||
static async Task HandleRequestAsync(HttpListenerContext context)
|
||||
{
|
||||
var request = context.Request;
|
||||
var response = context.Response;
|
||||
var clientIp = context.Request.RemoteEndPoint.Address.ToString();
|
||||
|
||||
if (request.HttpMethod == "GET")
|
||||
{
|
||||
var path = request.Url?.AbsolutePath;
|
||||
|
||||
switch (path)
|
||||
{
|
||||
case "/login":
|
||||
await HandleLoginAsync(request, response, clientIp);
|
||||
break;
|
||||
case "/addkami":
|
||||
await HandleAddKamiAsync(request, response, clientIp);
|
||||
break;
|
||||
default:
|
||||
ReturnJson(response, new { success = false, message = "路径错误" }, 404);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReturnJson(response, new { success = false, message = "方法不支持" }, 405);
|
||||
}
|
||||
}
|
||||
|
||||
static async Task HandleLoginAsync(HttpListenerRequest request, HttpListenerResponse response, string ip)
|
||||
{
|
||||
var queryParams = request.Url.Query.TrimStart('?').Split('&');
|
||||
var queryDict = new Dictionary<string, string>();
|
||||
|
||||
foreach (var pair in queryParams)
|
||||
{
|
||||
var parts = pair.Split('=');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
queryDict[parts[0]] = Uri.UnescapeDataString(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!queryDict.TryGetValue("kami", out var kami) || !queryDict.TryGetValue("hwid", out var hwid))
|
||||
{
|
||||
ReturnJson(response, new { success = false, message = "参数缺失" }, 400);
|
||||
return;
|
||||
}
|
||||
|
||||
var result = ValidateKamiAndHwid(kami, hwid, ip); // 新增 ip 参数
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case ValidationResult.NotFound:
|
||||
ReturnJson(response, new { success = false, message = "登录失败" }, 404);
|
||||
break;
|
||||
case ValidationResult.InvalidHwid:
|
||||
ReturnJson(response, new { success = false, message = "登录失败" }, 502);
|
||||
break;
|
||||
case ValidationResult.Success:
|
||||
ReturnJson(response, new { success = true, message = "登录成功" }, 200);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static async Task HandleAddKamiAsync(HttpListenerRequest request, HttpListenerResponse response, string ip)
|
||||
{
|
||||
var queryParams = request.Url.Query.TrimStart('?').Split('&');
|
||||
var queryDict = new Dictionary<string, string>();
|
||||
|
||||
foreach (var pair in queryParams)
|
||||
{
|
||||
var parts = pair.Split('=');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
queryDict[parts[0]] = Uri.UnescapeDataString(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
int count = 1;
|
||||
if (queryDict.TryGetValue("number", out var numStr))
|
||||
{
|
||||
if (!int.TryParse(numStr, out count) || count <= 0 || count > 1000)
|
||||
{
|
||||
ReturnJson(response, new { success = false, message = "number 参数无效,必须是 1~1000 之间的整数" }, 400);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var kamiList = new List<string>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string kami = GenerateRandomKami(16);
|
||||
if (AddKamiToDatabase(kami, ip))
|
||||
{
|
||||
kamiList.Add(kami);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnJson(response, new
|
||||
{
|
||||
success = true,
|
||||
message = $"{kamiList.Count} 个卡密已生成",
|
||||
kami_list = kamiList
|
||||
}, 200);
|
||||
}
|
||||
|
||||
static bool AddKamiToDatabase(string kami, string ip)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var cnm = new MySqlConnection(ConnectionString))
|
||||
{
|
||||
cnm.Open();
|
||||
string sql = "INSERT INTO users (kami, hwid, created_ip) VALUES (@kami, '', @ip)";
|
||||
using (var cmd = new MySqlCommand(sql, cnm))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@kami", kami);
|
||||
cmd.Parameters.AddWithValue("@ip", ip);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("数据库写入失败:" + ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
enum ValidationResult
|
||||
{
|
||||
NotFound,
|
||||
InvalidHwid,
|
||||
Success
|
||||
}
|
||||
|
||||
static ValidationResult ValidateKamiAndHwid(string kami, string hwid, string loginIp)
|
||||
{
|
||||
using (var conn = new MySqlConnection(ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
string sql = "SELECT hwid FROM users WHERE kami = @kami;";
|
||||
using (var cmd = new MySqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@kami", kami);
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
return ValidationResult.NotFound; // 卡密不存在
|
||||
}
|
||||
|
||||
reader.Read();
|
||||
string dbHwid = reader.IsDBNull(0) ? null : reader.GetString(0);
|
||||
reader.Close();
|
||||
|
||||
if (string.IsNullOrEmpty(dbHwid))
|
||||
{
|
||||
// 数据库中没有设置 hwid,自动写入当前传入的 hwid
|
||||
string updateSql = "UPDATE users SET hwid = @hwid, last_login_ip = @loginIp WHERE kami = @kami";
|
||||
using (var updateCmd = new MySqlCommand(updateSql, conn))
|
||||
{
|
||||
updateCmd.Parameters.AddWithValue("@kami", kami);
|
||||
updateCmd.Parameters.AddWithValue("@hwid", hwid);
|
||||
updateCmd.Parameters.AddWithValue("@loginIp", loginIp);
|
||||
updateCmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
|
||||
if (dbHwid != hwid)
|
||||
{
|
||||
return ValidationResult.InvalidHwid; // HWID 不匹配
|
||||
}
|
||||
|
||||
// 更新最近登录 IP
|
||||
string updateIpSql = "UPDATE users SET last_login_ip = @loginIp WHERE kami = @kami";
|
||||
using (var updateIpCmd = new MySqlCommand(updateIpSql, conn))
|
||||
{
|
||||
updateIpCmd.Parameters.AddWithValue("@kami", kami);
|
||||
updateIpCmd.Parameters.AddWithValue("@loginIp", loginIp);
|
||||
updateIpCmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string GenerateRandomKami(int length)
|
||||
{
|
||||
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
var random = new Random();
|
||||
return new string(Enumerable.Repeat(chars, length)
|
||||
.Select(s => s[random.Next(s.Length)]).ToArray());
|
||||
}
|
||||
|
||||
static void ReturnJson(HttpListenerResponse response, object obj, int statusCode)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(obj);
|
||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(json);
|
||||
|
||||
response.ContentType = "application/json";
|
||||
response.ContentLength64 = buffer.Length;
|
||||
response.StatusCode = statusCode;
|
||||
|
||||
// 添加 CORS 支持
|
||||
response.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||
response.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
|
||||
|
||||
using (Stream output = response.OutputStream)
|
||||
{
|
||||
output.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查数据库连接问题的代码片段
|
||||
static void TestDatabaseConnection()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var conn = new MySqlConnection(ConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
Console.WriteLine("数据库连接成功!");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("数据库连接失败:" + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// 在 Main 方法中调用测试连接的方法
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user