Files
NebulaMistWebBackstage/Program.cs
MelodyMaster 92efe27ce9 new
2025-07-17 17:00:39 +08:00

270 lines
9.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.Prefixes.Add("http://server.xn--9iqx4j49srgt.xyz: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 方法中调用测试连接的方法
}
}