mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-04-26 02:29:59 -05:00
With the approaching games, PKM sprites are a different size from the 3DS era (as already hinted by LGPE, which has 56x68). It'll be a little easier to manage with this portion of the library walled off from the rest of the codebase. Eventually the net46 target will use fody or something to merge in these extra dependency dll's automatically to not disturb the usual exe/dll experience.
102 lines
3.5 KiB
C#
102 lines
3.5 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using PKHeX.Core;
|
|
|
|
namespace PKHeX.Drawing
|
|
{
|
|
public static class QRDecode
|
|
{
|
|
// QR Utility
|
|
private const string DecodeAPI = "http://api.qrserver.com/v1/read-qr-code/?fileurl=";
|
|
|
|
public static QRDecodeMsg GetQRData(string address, out byte[] result)
|
|
{
|
|
result = Array.Empty<byte>();
|
|
// Fetch data from QR code...
|
|
|
|
if (!address.StartsWith("http"))
|
|
return QRDecodeMsg.BadPath;
|
|
|
|
string webURL = DecodeAPI + WebUtility.UrlEncode(address);
|
|
string data;
|
|
try
|
|
{
|
|
data = NetUtil.GetStringFromURL(webURL);
|
|
if (data.Contains("could not find"))
|
|
return QRDecodeMsg.BadImage;
|
|
|
|
if (data.Contains("filetype not supported"))
|
|
return QRDecodeMsg.BadType;
|
|
}
|
|
catch { return QRDecodeMsg.BadConnection; }
|
|
|
|
// Quickly convert the json response to a data string
|
|
try
|
|
{
|
|
result = DecodeQRJson(data);
|
|
return QRDecodeMsg.Success;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.WriteLine(e.Message);
|
|
return QRDecodeMsg.BadConversion;
|
|
}
|
|
}
|
|
|
|
private static byte[] DecodeQRJson(string data)
|
|
{
|
|
const string cap = "\",\"error\":null}]}]";
|
|
const string intro = "[{\"type\":\"qrcode\",\"symbol\":[{\"seq\":0,\"data\":\"";
|
|
const string qrcode = "nQR-Code:";
|
|
if (!data.StartsWith(intro))
|
|
throw new FormatException();
|
|
|
|
string pkstr = data.Substring(intro.Length);
|
|
if (pkstr.Contains(qrcode)) // Remove multiple QR codes in same image
|
|
pkstr = pkstr.Substring(0, pkstr.IndexOf(qrcode, StringComparison.Ordinal));
|
|
pkstr = pkstr.Substring(0, pkstr.IndexOf(cap, StringComparison.Ordinal)); // Trim outro
|
|
|
|
if (!pkstr.StartsWith("http") && !pkstr.StartsWith("null")) // G7
|
|
{
|
|
string fstr = Regex.Unescape(pkstr);
|
|
byte[] raw = Encoding.Unicode.GetBytes(fstr);
|
|
// Remove 00 interstitials and retrieve from offset 0x30, take PK7 Stored Size (always)
|
|
return raw.Where((_, i) => i % 2 == 0).Skip(0x30).Take(0xE8).ToArray();
|
|
}
|
|
// All except G7
|
|
pkstr = pkstr.Substring(pkstr.IndexOf('#') + 1); // Trim URL
|
|
pkstr = pkstr.Replace("\\", string.Empty); // Rectify response
|
|
|
|
return Convert.FromBase64String(pkstr);
|
|
}
|
|
|
|
public static string ConvertMsg(this QRDecodeMsg msg)
|
|
{
|
|
return msg switch
|
|
{
|
|
QRDecodeMsg.Success => string.Empty,
|
|
QRDecodeMsg.BadPath => MessageStrings.MsgQRUrlFailPath,
|
|
QRDecodeMsg.BadImage => MessageStrings.MsgQRUrlFailImage,
|
|
QRDecodeMsg.BadType => MessageStrings.MsgQRUrlFailType,
|
|
QRDecodeMsg.BadConnection => MessageStrings.MsgQRUrlFailConnection,
|
|
QRDecodeMsg.BadConversion => MessageStrings.MsgQRUrlFailConvert,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(msg), msg, null)
|
|
};
|
|
}
|
|
}
|
|
|
|
public enum QRDecodeMsg
|
|
{
|
|
Success,
|
|
BadPath,
|
|
BadImage,
|
|
BadType,
|
|
BadConnection,
|
|
BadConversion,
|
|
}
|
|
}
|