270 lines
9.9 KiB
C#
270 lines
9.9 KiB
C#
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 方法中调用测试连接的方法
|
||
}
|
||
}
|