435 lines
16 KiB
C#
435 lines
16 KiB
C#
using System;
|
|
using System.Net;
|
|
using KKdBaseLib;
|
|
using KKdMainLib.IO;
|
|
|
|
namespace KKdMainLib
|
|
{
|
|
public struct DataBank : IDisposable
|
|
{
|
|
private int i;
|
|
private Stream s;
|
|
|
|
public bool pvListPDA;
|
|
public PvList[] pvList;
|
|
public PsrData[] psrData;
|
|
|
|
private const string d = ".";
|
|
private const string c = ",";
|
|
|
|
public bool Success { get; private set; }
|
|
|
|
public void DBReader(string file)
|
|
{
|
|
pvListPDA = false;
|
|
Success = false;
|
|
if (!File.Exists(file)) return;
|
|
string text = File.ReadAllText(file);
|
|
while (text.Contains("%")) text = WebUtility.UrlDecode(text);
|
|
string[] array = text.Split(',');
|
|
|
|
pvList = null;
|
|
psrData = null;
|
|
if (file.Contains("psrData") && array.Length % 13 == 0)
|
|
{
|
|
psrData = new PsrData[array.Length / 13];
|
|
for (i = 0; i < psrData.Length; i++) psrData[i].SetValue(array, i);
|
|
Success = true;
|
|
}
|
|
else if (file.Contains("psrData")) Success = true;
|
|
else if (file.Contains("PvList") && (array.Length % 7 == 0 || array.Length % 6 == 0))
|
|
{
|
|
if (array[2] != "0" && array[2] != "1")
|
|
{
|
|
pvListPDA = true;
|
|
pvList = new PvList[array.Length / 6];
|
|
for (i = 0; i < pvList.Length; i++) pvList[i].SetValue(array, i, true);
|
|
}
|
|
else
|
|
{
|
|
pvList = new PvList[array.Length / 7];
|
|
for (i = 0; i < pvList.Length; i++) pvList[i].SetValue(array, i, false);
|
|
}
|
|
Success = true;
|
|
}
|
|
else if (file.Contains("PvList")) Success = true;
|
|
}
|
|
|
|
public byte[] DBWriter(string file)
|
|
{
|
|
if (!Success) return null;
|
|
|
|
s = File.OpenWriter();
|
|
if (file.Contains("psrData"))
|
|
{
|
|
if (psrData != null && psrData.Length > 0)
|
|
for (i = 0; i < psrData.Length; i++)
|
|
if (psrData[i].PV_ID == 92)
|
|
s.W(psrData[i].ToString() + c);
|
|
else
|
|
s.W(psrData[i].ToString() + c);
|
|
}
|
|
else if (file.Contains("PvList"))
|
|
{
|
|
if (pvList != null && pvList.Length > 0)
|
|
{
|
|
for (i = 0; i < pvList.Length - 1; i++)
|
|
s.W(UrlEncode(pvList[i].ToString(pvListPDA) + c));
|
|
s.W(UrlEncode(pvList[i].ToString(pvListPDA)));
|
|
}
|
|
else s.W("%2A%2A%2A");
|
|
}
|
|
|
|
return s.ToArray(true);
|
|
}
|
|
|
|
public void DBWriter(string file, uint num2)
|
|
{
|
|
if (!Success) return;
|
|
|
|
byte[] data = DBWriter(file);
|
|
if (data == null) return;
|
|
|
|
ushort num = DCC.CalculateChecksum(data);
|
|
File.WriteAllBytes(file + "_" + num + "_" + num2 + ".dat", data);
|
|
}
|
|
|
|
public void MsgPackReader(string file, bool json)
|
|
{
|
|
pvListPDA = false;
|
|
Success = false;
|
|
MsgPack msgPack = file.ReadMPAllAtOnce(json);
|
|
bool compact = msgPack.RB("Compact");
|
|
|
|
psrData = null;
|
|
pvList = null;
|
|
if (file.Contains("psrData"))
|
|
{
|
|
MsgPack psrData;
|
|
if ((psrData = msgPack["psrData", true]).NotNull)
|
|
{
|
|
this.psrData = new PsrData[psrData.Array.Length];
|
|
for (i = 0; i < this.psrData.Length; i++)
|
|
this.psrData[i].SetValue(psrData[i]);
|
|
}
|
|
Success = true;
|
|
psrData.Dispose();
|
|
}
|
|
else if (file.Contains("PvList"))
|
|
{
|
|
MsgPack pvList;
|
|
if ((pvList = msgPack["PvList", true]).NotNull)
|
|
{
|
|
this.pvList = new PvList[pvList.Array.Length];
|
|
for (i = 0; i < this.pvList.Length; i++)
|
|
this.pvList[i].SetValue(pvList[i], compact);
|
|
}
|
|
else if ((pvList = msgPack["PvListPDA", true]).NotNull)
|
|
{
|
|
pvListPDA = true;
|
|
this.pvList = new PvList[pvList.Array.Length];
|
|
for (i = 0; i < this.pvList.Length; i++)
|
|
this.pvList[i].SetValue(pvList[i], compact);
|
|
}
|
|
Success = true;
|
|
pvList.Dispose();
|
|
}
|
|
|
|
msgPack.Dispose();
|
|
}
|
|
|
|
public void MsgPackWriter(string file, bool json)
|
|
{
|
|
if (!Success) return;
|
|
MsgPack msgPack = MsgPack.New;
|
|
|
|
if (file.Contains("psrData"))
|
|
{
|
|
if (psrData != null)
|
|
{
|
|
MsgPack psrData = new MsgPack(this.psrData.Length, "psrData");
|
|
for (i = 0; i < this.psrData.Length; i++) psrData[i] = this.psrData[i].WriteMP();
|
|
msgPack.Add(psrData);
|
|
}
|
|
else msgPack.Add(new MsgPack("psrData", null));
|
|
}
|
|
else if (file.Contains("PvList"))
|
|
{
|
|
if (pvList != null)
|
|
{msgPack.Add("Compact", true);
|
|
|
|
MsgPack PvList = new MsgPack(pvList.Length, pvListPDA ? "PvListPDA" : "PvList");
|
|
for (i = 0; i < pvList.Length; i++) PvList[i] = pvList[i].WriteMP();
|
|
msgPack.Add(PvList);
|
|
}
|
|
else msgPack.Add(new MsgPack(pvListPDA ? "PvListPDA" : "PvList", null));
|
|
}
|
|
msgPack.Write(file, false, json).Dispose();
|
|
}
|
|
|
|
public static string UrlEncode(string value) =>
|
|
WebUtility.UrlEncode(value).Replace("+", "%20").Replace("!", "%21").Replace("*", "%2A");
|
|
|
|
private bool disposed;
|
|
public void Dispose()
|
|
{ if (!disposed) { if (s != null) s.D(); s = null; psrData = null;
|
|
pvList = null; pvListPDA = false; Success = false; disposed = true; } }
|
|
|
|
public struct PsrData
|
|
{
|
|
public Player p1;
|
|
public Player p2;
|
|
public Player p3;
|
|
public int PV_ID;
|
|
|
|
public void SetValue(string[] data, int i = 0)
|
|
{
|
|
p1.SetValue(data, i, 0);
|
|
p2.SetValue(data, i, 1);
|
|
p3.SetValue(data, i, 2);
|
|
PV_ID = int.Parse(data[i * 13 + 12]);
|
|
}
|
|
|
|
public void SetValue(MsgPack msg)
|
|
{
|
|
int? id = msg.RnI32("PV_ID");
|
|
if (id != null) PV_ID = (int)id;
|
|
else { id = msg.RnI32("ID"); if (id != null) PV_ID = (int)id; }
|
|
|
|
MsgPack temp;
|
|
if ((temp = msg["P1"]).NotNull) p1.SetValue(temp);
|
|
if ((temp = msg["P2"]).NotNull) p2.SetValue(temp);
|
|
if ((temp = msg["P3"]).NotNull) p3.SetValue(temp);
|
|
temp.Dispose();
|
|
}
|
|
|
|
public MsgPack WriteMP() =>
|
|
MsgPack.New.Add("PV_ID", PV_ID).Add(p1.WriteMP("P1"))
|
|
.Add(p2.WriteMP("P2")).Add(p3.WriteMP("P3"));
|
|
|
|
public override string ToString() =>
|
|
UrlEncode($"{p1},{p2},{p3},{PV_ID}");
|
|
}
|
|
|
|
public struct Player
|
|
{
|
|
public string Name;
|
|
public string NameExtra;
|
|
public int Score;
|
|
public int ScoreExtra;
|
|
public Difficulty Diff;
|
|
public bool HasExtra => NameExtra != null;
|
|
|
|
public void SetValue(string[] data, int i = 0, int offset = 0)
|
|
{
|
|
string[] array = data[i * 13 + offset * 4].Split('.');
|
|
Score = int.Parse(array[0]);
|
|
if (array.Length > 1) ScoreExtra = int.Parse(array[1]);
|
|
string text = "";
|
|
for (int j = 0; j < data[i * 13 + 1 + offset * 4].Length; j++)
|
|
{
|
|
text += data[i * 13 + 1 + offset * 4][j].ToString();
|
|
if (text.EndsWith("xxx"))
|
|
{
|
|
Name = text.Remove(text.Length - 3);
|
|
text = "";
|
|
}
|
|
}
|
|
if (array.Length == 1) Name = text;
|
|
else NameExtra = text;
|
|
if (int.TryParse(data[i * 13 + 2 + offset * 4], out int Diff))
|
|
this.Diff = (Difficulty)Diff;
|
|
else
|
|
Enum.TryParse(data[i * 13 + 2 + offset * 4], out this.Diff);
|
|
}
|
|
|
|
public void SetValue(MsgPack msg)
|
|
{
|
|
Diff = (Difficulty)msg.RI32("Diff");
|
|
Name = msg.RS ( "Name");
|
|
NameExtra = msg.RS ( "NameExtra");
|
|
Score = msg.RI32("Score");
|
|
ScoreExtra = msg.RI32("ScoreExtra");
|
|
|
|
if (Name == null)
|
|
{
|
|
Name = msg.RS ( "Name0");
|
|
NameExtra = msg.RS ( "Name1");
|
|
Score = msg.RI32("Score0");
|
|
ScoreExtra = msg.RI32("Score1");
|
|
}
|
|
}
|
|
|
|
public MsgPack WriteMP(string name) =>
|
|
HasExtra ? new MsgPack(name).Add("Diff", (int)Diff).Add("Name", Name)
|
|
.Add("NameExtra", NameExtra).Add("Score", Score).Add("ScoreExtra", ScoreExtra) :
|
|
new MsgPack(name).Add("Diff", (int)Diff).Add("Name" , Name) .Add("Score" , Score);
|
|
|
|
public override string ToString() =>
|
|
Score + (HasExtra ? (d + ScoreExtra) : "") + c + UrlEncode(Name) +
|
|
(HasExtra ? ("xxx" + UrlEncode(NameExtra)) : "") + c +
|
|
(int)Diff + c + (HasExtra ? "0.1" : "0");
|
|
}
|
|
|
|
public struct PvList
|
|
{
|
|
public int PV_ID;
|
|
public int Version;
|
|
public int Edition;
|
|
public Date AdvDemoStart;
|
|
public Date AdvDemoEnd;
|
|
public Date StartShow;
|
|
public Date EndShow;
|
|
|
|
public void SetValue(string[] data, int i = 0, bool pda = false)
|
|
{
|
|
if (pda)
|
|
{
|
|
PV_ID = int.Parse(data[i * 6]);
|
|
Version = int.Parse(data[i * 6 + 1]);
|
|
AdvDemoStart.SV(data[i * 6 + 2]);
|
|
AdvDemoEnd.SV(data[i * 6 + 3]);
|
|
StartShow.SV(data[i * 6 + 4]);
|
|
EndShow.SV(data[i * 6 + 5]);
|
|
}
|
|
else
|
|
{
|
|
PV_ID = int.Parse(data[i * 7]);
|
|
Version = int.Parse(data[i * 7 + 1]);
|
|
Edition = int.Parse(data[i * 7 + 2]);
|
|
AdvDemoStart.SV(data[i * 7 + 3]);
|
|
AdvDemoEnd .SV(data[i * 7 + 4]);
|
|
StartShow .SV(data[i * 7 + 5]);
|
|
EndShow .SV(data[i * 7 + 6]);
|
|
}
|
|
}
|
|
|
|
public void SetValue(MsgPack msg, bool Compact)
|
|
{
|
|
Version = 1;
|
|
Edition = 0;
|
|
|
|
int? id = msg.RnI32("PV_ID");
|
|
if (id != null) PV_ID = id.Value; else { id = msg.RnI32("ID"); if (id != null) PV_ID = id.Value; }
|
|
bool? enable = msg.RnB("Enable"); if (enable != null) Version = enable.Value ? 1 : 0;
|
|
bool? extra = msg.RnB("Extra" ); if (extra != null) Edition = extra .Value ? 1 : 0;
|
|
int? version = msg.RnI32("Version"); if (version != null) Version = version.Value;
|
|
int? edition = msg.RnI32("Edition"); if (edition != null) Edition = edition.Value;
|
|
if (Compact)
|
|
{
|
|
AdvDemoStart.SV(msg.RnI32("AdvDemoStart"), true);
|
|
AdvDemoEnd .SV(msg.RnI32("AdvDemoEnd" ), false);
|
|
StartShow .SV(msg.RnI32("StartShow" ), false);
|
|
EndShow .SV(msg.RnI32( "EndShow" ), true);
|
|
return;
|
|
}
|
|
|
|
MsgPack temp;
|
|
if ((temp = msg["AdvDemoStart", true]).NotNull) AdvDemoStart.SV(temp, true);
|
|
if ((temp = msg["AdvDemoEnd" , true]).NotNull) AdvDemoEnd .SV(temp, false);
|
|
if ((temp = msg["StartShow" , true]).NotNull) StartShow .SV(temp, false);
|
|
if ((temp = msg[ "EndShow" , true]).NotNull) EndShow .SV(temp, true);
|
|
temp.Dispose();
|
|
}
|
|
|
|
public MsgPack WriteMP()
|
|
{
|
|
MsgPack msgPack = MsgPack.New.Add("ID" , PV_ID );
|
|
if (Version != 1) msgPack.Add("Version", Version);
|
|
if (Edition != 0) msgPack.Add("Edition", Edition);
|
|
if (AdvDemoStart.WU) msgPack.Add("AdvDemoStart", AdvDemoStart.Int);
|
|
if (AdvDemoEnd .WL) msgPack.Add("AdvDemoEnd" , AdvDemoEnd .Int);
|
|
if (StartShow .WL) msgPack.Add("StartShow" , StartShow .Int);
|
|
if ( EndShow .WU) msgPack.Add( "EndShow" , EndShow .Int);
|
|
return msgPack;
|
|
}
|
|
|
|
public string ToString(bool pda) => !pda
|
|
? UrlEncode($"{PV_ID},{Version},{Edition},{AdvDemoStart},{AdvDemoEnd},{StartShow},{EndShow}")
|
|
: UrlEncode($"{PV_ID},{Version},{AdvDemoStart},{AdvDemoEnd},{StartShow},{EndShow}");
|
|
}
|
|
|
|
public struct Date
|
|
{
|
|
private int year;
|
|
private int month;
|
|
private int day;
|
|
|
|
public int Year { get => year; set { year = value; CheckDate(); } }
|
|
public int Month { get => month; set { month = value; CheckDate(); } }
|
|
public int Day { get => day; set { day = value; CheckDate(); } }
|
|
|
|
public bool WU => Year != 2029 || Month != 1 || Day != 1;
|
|
public bool WL => Year != 2000 || Month != 1 || Day != 1;
|
|
|
|
public void SDL() => Year = 2000;
|
|
public void SDU() => Year = 2029;
|
|
|
|
public void SV(string data)
|
|
{
|
|
string[] array = data.Split('-');
|
|
if (array.Length == 3)
|
|
{
|
|
Year = int.Parse(array[0]);
|
|
Month = int.Parse(array[1]);
|
|
Day = int.Parse(array[2]);
|
|
}
|
|
}
|
|
|
|
public void SV(int? ymd, bool setDefaultUpper)
|
|
{
|
|
if (!setDefaultUpper) SDL();
|
|
else SDU();
|
|
if (ymd != null)
|
|
{
|
|
year = ymd.Value / 10000;
|
|
month = ymd.Value / 100 % 100;
|
|
day = ymd.Value % 100;
|
|
CheckDate();
|
|
}
|
|
}
|
|
|
|
public void SV(MsgPack msg, bool setDefaultUpper)
|
|
{
|
|
if (!setDefaultUpper) SDL();
|
|
else SDU();
|
|
int? Year = msg.RnI32( "Year");
|
|
int? Month = msg.RnI32("Month");
|
|
int? Day = msg.RnI32( "Day");
|
|
if ( Year != null) year = Year.Value;
|
|
if (Month != null) month = Month.Value;
|
|
if ( Day != null) day = Day.Value;
|
|
CheckDate();
|
|
}
|
|
|
|
public int Int => (Year * 100 + Month) * 100 + Day;
|
|
|
|
private void CheckDate()
|
|
{
|
|
if (year < 2000) { year = 2000; month = 1; day = 1; return; }
|
|
if (year >= 2029) { year = 2029; month = 1; day = 1; return; }
|
|
if (month < 1) month = 1;
|
|
else if (month > 12) month = 12;
|
|
if (day < 1) day = 1;
|
|
else if (day > 31 && (month == 1 || month == 3 || month == 5 ||
|
|
month == 7 || month == 8 || month == 10 || month == 12)) day = 31;
|
|
else if (day > 30 && (month == 4 || month == 6 ||
|
|
month == 9 || month == 11)) day = 30;
|
|
else if (day > 29 && month == 2 && year % 4 == 0) day = 29;
|
|
else if (day > 28 && month == 2 && year % 4 != 0) day = 28;
|
|
}
|
|
|
|
public override string ToString() =>
|
|
$"{Year:d4}-{Month:d2}-{Day:d2}";
|
|
}
|
|
|
|
public enum Difficulty
|
|
{
|
|
Easy = 0,
|
|
Normal = 1,
|
|
Hard = 2,
|
|
Extreme = 3,
|
|
}
|
|
}
|
|
}
|