Commit 799c5ec7 authored by JoyJ's avatar JoyJ

添加项目文件。

parent 413217fb

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardCodeSearcher", "CardCodeSearcher\CardCodeSearcher.csproj", "{98B2D9D2-FBE2-4E56-BB6E-9C0180726995}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{98B2D9D2-FBE2-4E56-BB6E-9C0180726995}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98B2D9D2-FBE2-4E56-BB6E-9C0180726995}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98B2D9D2-FBE2-4E56-BB6E-9C0180726995}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98B2D9D2-FBE2-4E56-BB6E-9C0180726995}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {948ED233-C0D9-4D5E-A5F4-D574891F1A78}
EndGlobalSection
EndGlobal
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace CardCodeSearcher
{
public class CardCodeSearcher
{
static void Main(string[] args)
{
args = new string[1] { "input.txt" };
if (args.Length == 0)
{
Console.WriteLine("Usage: cardcodesearcher.exe file1 file2 file3...");
return;
}
if (File.Exists("output.csv"))
{
File.Delete("output.csv");
}
foreach(string file in args)
{
Console.WriteLine($"Processing: {file}");
if (File.Exists(file))
{
using var fs = File.OpenRead(file);
using var sr = new StreamReader(fs);
for(string? line = sr.ReadLine(); line != null; line = sr.ReadLine())
{
line = line.Trim();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine($"Searching: {line}");
Console.WriteLine("Searching From ygocdb...");
string name = GetJPNameFromYgoCdb(line);
int id = GetIdFromYgoCdb(line);
var encoding = new System.Text.UTF8Encoding(true);
if (id > 0 && id < 100000000)
{
File.AppendAllLines("output.csv", new string[1] { $"{line},{name},{id}"}, encoding);
}
else
{
if (!string.IsNullOrEmpty(name))
{
Console.WriteLine("Searching From starbox...");
id = GetIdFromStarbox(name);
if (id < 0)
{
Console.WriteLine("Searching From dorasuta...");
id = GetIdFromDorasuta(name);
}
File.AppendAllLines("output.csv", new string[1] { $"{line},{name},{id}" }, encoding);
}
}
}
}
}
}
}
static string GetJPNameFromYgoCdb(string card, bool ignoreSBC = false)
{
Thread.Sleep(1500);
string url = $"https://ygocdb.com/api/v0/?search={card}";
string? json = HttpGet(url);
if (json == null)
{
return "";
}
JsonSerializerOptions opt = new JsonSerializerOptions();
opt.IncludeFields = true;
YgoCdbSearchResult? result = JsonSerializer.Deserialize<YgoCdbSearchResult>(json,opt);
if (result == null || result.result == null)
{
return "";
}
foreach (YgoCdbCard c in result.result)
{
if ((c.cn_name == card || c.cnocg_n == card) && c.jp_name != null)
{
return c.jp_name;
}
}
if (!ignoreSBC)
{
string sbcCard = FromSBC(card);
if (sbcCard != card)
{
string name = GetJPNameFromYgoCdb(sbcCard, true);
if (name != "")
{
return name;
}
}
sbcCard = ToSBC(card);
if (sbcCard != card)
{
string name = GetJPNameFromYgoCdb(sbcCard, true);
if (name != "")
{
return name;
}
}
}
return "";
}
static int GetIdFromYgoCdb(string card, bool ignoreSBC = false)
{
Thread.Sleep(1500);
string url = $"https://ygocdb.com/api/v0/?search={card}";
string? json = HttpGet(url);
if (json == null)
{
return -1;
}
JsonSerializerOptions opt = new JsonSerializerOptions();
opt.IncludeFields = true;
YgoCdbSearchResult? result = JsonSerializer.Deserialize<YgoCdbSearchResult>(json,opt);
if (result == null || result.result == null)
{
return -1;
}
foreach (YgoCdbCard c in result.result)
{
if (c.jp_name == card)
{
return c.id;
}
}
if (!ignoreSBC)
{
string sbcCard = FromSBC(card);
if (sbcCard != card)
{
int id = GetIdFromYgoCdb(sbcCard, true);
if (id > 0)
{
return id;
}
}
sbcCard = ToSBC(card);
if (sbcCard != card)
{
int id = GetIdFromYgoCdb(sbcCard, true);
if (id > 0)
{
return id;
}
}
}
return -1;
}
public class YgoCdbCardText
{
public string? types;
public string? pdesc;
public string? desc;
}
public class YgoCdbSearchResult
{
public List<YgoCdbCard>? result;
public int next;
}
public class YgoCdbCard
{
public int id;
public int cid;
public string? jp_name;
public string? cn_name;
public string? cnocg_n;
public YgoCdbCardText? text;
}
private int GetCardIdWithoutRealId(string name)
{
switch (name)
{
case "オベリスクの巨神兵":
return 10000001;
case "ラーの翼神竜":
case "ラーの翼神竜(使用不可)":
return 10000010;
case "オシリスの天空竜":
return 10000020;
case "光の創造神 ホルアクティ":
return 10000040;
case "ラーの翼神竜-球体形":
return 10000080;
case "ラーの翼神竜-不死鳥":
return 10000090;
default:
return -1;
}
}
static int GetIdFromStarbox(string name)
{
//https://tcgkakaku.e-starbox.com/yg/detail_search?exec=1&title=%E9%AD%94%E7%AB%9C%E5%B0%86%E3%83%87%E3%82%A3%E3%82%A2%E3%83%9C%E3%83%AA%E3%82%AB
string url = $"https://tcgkakaku.e-starbox.com/yg/detail_search?exec=1&title={name}";
string? code = HttpGet(url);
//https://tcgkakaku.e-starbox.com/yg/card_list?no=VJMP%2FJP221
Regex regex = new Regex(@"card_list\?no\=([A-Z\%0-9]+)\""\>([^\<]+)\<\/a\>");
Regex regex2 = new Regex(@"パスワード:\<\/span\>([0-9]{4,8})");
if (code == null)
{
return -1;
}
var matches = regex.Matches(code);
if (matches.Count() == 0)
{
return -1;
}
foreach(Match m in matches)
{
if (m.Groups[2].Value != name && m.Groups[2].Value != ToSBC(name) && m.Groups[2].Value != FromSBC(name))
{
continue;
}
url = "https://tcgkakaku.e-starbox.com/yg/card_list?no=" + m.Groups[1].Value;
code = HttpGet(url);
if (code == null)
{
return -1;
}
var match2 = regex2.Match(code);
if (match2.Success)
{
int result;
if (int.TryParse(match2.Groups[1].Value, out result))
{
return result;
}
}
}
return -1;
}
private int GetIdFromOurocg(string card, bool ignoreSBC = false)
{
int page = 0;
while (true)
{
Thread.Sleep(1500);
page++;
string? content = HttpGet($"https://www.ourocg.cn/search/{card}/{page}");
Regex regex = new Regex(@"window.__STORE__ = ([^\n]+);\n");
if (content == null)
{
return -1;
}
if (!regex.IsMatch(content))
{
break;
}
JsonSerializerOptions opt = new JsonSerializerOptions();
opt.IncludeFields = true;
OurocgSearchResult? result = JsonSerializer.Deserialize<OurocgSearchResult>(regex.Match(content).Groups[1].Value,opt);
if (result == null || result.cards==null|| result.meta==null)
{
return -1;
}
if (result.cards.Count == 0 || result.meta.count == 0)
{
break;
}
foreach (OurocgSearchResultCard resultCard in result.cards)
{
if (resultCard.name_ja == card && resultCard.password != null)
{
return int.Parse(resultCard.password);
}
}
}
if (!ignoreSBC)
{
string sbcCard = FromSBC(card);
if (sbcCard != card)
{
int id = this.GetIdFromOurocg(sbcCard, true);
if (id > 0)
{
return id;
}
}
sbcCard = ToSBC(card);
if (sbcCard != card)
{
int id = this.GetIdFromOurocg(sbcCard, true);
if (id > 0)
{
return id;
}
}
}
return -1;
}
public class OurocgSearchResult
{
public OurocgSearchResultMeta? meta;
public List<OurocgSearchResultCard>? cards;
}
public class OurocgSearchResultCard
{
public string? id;
public string? hash_id;
public string? password;
public string? name;
public string? name_ja;
public string? name_en;
public string? locale;
public string? type_st;
public string? type_val;
public string? img_url;
public string? level;
public string? attribute;
public string? race;
public string? atk;
public string? def;
public string? pend_l;
public string? pend_r;
public string? link;
public string? link_arrow;
public string? name_nw;
public string? desc;
public string? desc_nw;
public string? rare;
public string? package;
public string? href;
}
public class OurocgSearchResultMeta
{
public string? keyword;
public int count;
public int total_page;
public int cur_page;
public OurocgSearchResultSuggest? suggest;
public string? title;
public string? page_type;
}
public class OurocgSearchResultSuggest
{
public string? text;
public List<string>? keywords;
}
static int GetIdFromDorasuta(string name)
{
//https://dorasuta.jp/yugioh-jp/product-list?kw=%E4%BC%9D%E6%89%BF%E3%81%AE%E5%A4%A7%E5%BE%A1%E5%B7%AB
string url = $"https://dorasuta.jp/yugioh-jp/product-list?kw={name}";
string? code = HttpGet(url);
//https://dorasuta.jp/yugioh-jp/product?pid=415118
Regex regex = new Regex(@"product\?pid\=[0-9]+");
Regex regex2 = new Regex(@"T([0-9]{4,8})");
if (code == null)
{
return -1;
}
Match match = regex.Match(code);
if (match.Success)
{
Thread.Sleep(5000); //TRY to bypass Cloudflare
code = HttpGet("https://dorasuta.jp/yugioh-jp/" + match.Value);
if (code == null)
{
return -1;
}
var match2 = regex2.Match(code);
if (match2.Success)
{
int result;
if (int.TryParse(match2.Groups[1].Value, out result))
{
return result;
}
}
}
return -1;
}
public static string ToSBC(string input)
{
// 半角转全角:
char[] c = input.ToCharArray();
for (int i = 0; i < c.Length; i++)
{
if (c[i] == ' ' || c[i] == '.') //Space or . is ignored
{
continue;
}
if (c[i] < 127)
{
c[i] = (char)(c[i] + 65248);
}
}
return new string(c);
}
public static string FromSBC(string input)
{
// 全角转半角:
char[] c = input.ToCharArray();
for (int i = 0; i < c.Length; i++)
{
if (c[i] == '-' || c[i] == '=' || c[i] == '<' || c[i] == '>')
{
continue;
}
if (c[i] == 12288)
{
c[i] = (char)32;
continue;
}
if (c[i] >= 65248 && c[i] < 127 + 65248)
{
c[i] = (char)(c[i] - 65248);
}
}
return new string(c);
}
static string? HttpGet(string url)
{
for (int tried = 0; tried < 10; tried++)
{
try
{
HttpClient httpClient = new HttpClient();
var req = httpClient.Send(new HttpRequestMessage(HttpMethod.Get,url));
using var stream = req.Content.ReadAsStream();
using var sr = new StreamReader(stream);
var result = sr.ReadToEnd();
return result;
}
catch
{
Thread.Sleep(7000);
continue;
}
}
return null;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment