From 7d817ec180ee2401b84e5df2dabc2ff987caff07 Mon Sep 17 00:00:00 2001 From: Greg Edwards Date: Wed, 18 Jun 2014 22:24:47 -0400 Subject: [PATCH] Implemented box upload. --- GlobalTerminalService/GTServer4.cs | 45 +++++++++++++++++++ library/Data/DataAbstract.cs | 3 +- library/Data/DataMysql.cs | 71 ++++++++++++++++++++++++++++++ library/Library.csproj | 1 + library/Structures/BoxRecord4.cs | 45 +++++++++++++++++++ 5 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 library/Structures/BoxRecord4.cs diff --git a/GlobalTerminalService/GTServer4.cs b/GlobalTerminalService/GTServer4.cs index 2603ed77..f64fa516 100644 --- a/GlobalTerminalService/GTServer4.cs +++ b/GlobalTerminalService/GTServer4.cs @@ -56,10 +56,55 @@ namespace PkmnFoundations.GlobalTerminalService { case RequestTypes4.BoxUpload: { + if (data.Length != 0x360) + { + response.Write(new byte[] { 0x02, 0x00 }, 0, 2); + break; + } + + int pid = BitConverter.ToInt32(data, 8); + BoxLabels4 label = (BoxLabels4)BitConverter.ToInt32(data, 0x140); + byte[] boxData = new byte[0x21c]; + Array.Copy(data, 0x144, boxData, 0, 0x21c); + BoxRecord4 record = new BoxRecord4(pid, label, 0, boxData); + long serial = DataAbstract.Instance.BoxUpload4(record); + + if (serial == 0) + { + Console.WriteLine("Uploaded box already in server."); + response.Write(new byte[] { 0x02, 0x00 }, 0, 2); + break; + } + + Console.WriteLine("Box uploaded successfully."); + response.Write(new byte[] { 0x00, 0x00 }, 0, 2); // result code (0 for OK) + response.Write(BitConverter.GetBytes(serial), 0, 8); } break; case RequestTypes4.BoxSearch: { + if (data.Length != 0x14c) + { + response.Write(new byte[] { 0x02, 0x00 }, 0, 2); + break; + } + + // todo: validate or log some of this? + BoxLabels4 label = (BoxLabels4)BitConverter.ToInt32(data, 0x144); + + BoxRecord4[] results = DataAbstract.Instance.BoxSearch4(label, 20); + response.Write(new byte[] { 0x00, 0x00 }, 0, 2); // result code (0 for OK) + response.Write(BitConverter.GetBytes(results.Length), 0, 4); + + foreach (BoxRecord4 result in results) + { + response.Write(BitConverter.GetBytes(result.PID), 0, 4); + response.Write(BitConverter.GetBytes((int)result.Label), 0, 4); + response.Write(BitConverter.GetBytes(result.SerialNumber), 0, 8); + response.Write(result.Data, 0, 0x21c); + } + Console.WriteLine("Retrieved {0} boxes.", results.Length); + } break; case RequestTypes4.DressupUpload: diff --git a/library/Data/DataAbstract.cs b/library/Data/DataAbstract.cs index 5f592144..5da17f4d 100644 --- a/library/Data/DataAbstract.cs +++ b/library/Data/DataAbstract.cs @@ -84,7 +84,8 @@ namespace PkmnFoundations.Data public abstract long DressupUpload4(DressupRecord4 record); public abstract DressupRecord4[] DressupSearch4(ushort species, int count); - + public abstract long BoxUpload4(BoxRecord4 record); + public abstract BoxRecord4[] BoxSearch4(BoxLabels4 label, int count); #endregion diff --git a/library/Data/DataMysql.cs b/library/Data/DataMysql.cs index 19e6805a..d765eace 100644 --- a/library/Data/DataMysql.cs +++ b/library/Data/DataMysql.cs @@ -784,6 +784,77 @@ namespace PkmnFoundations.Data return new DressupRecord4(reader.GetInt32(0), reader.GetInt64(1), data); } + public override long BoxUpload4(BoxRecord4 record) + { + if (record.Data.Length != 540) throw new ArgumentException("Box data must be 540 bytes."); + using (MySqlConnection db = CreateConnection()) + { + db.Open(); + using (MySqlTransaction tran = db.BeginTransaction()) + { + long exists = (long)tran.ExecuteScalar("SELECT EXISTS(SELECT * FROM TerminalBoxes4 WHERE Data = @data)", new MySqlParameter("@data", record.Data)); + if (exists != 0) return 0; + + if (record.SerialNumber == 0) + { + long serial = (long)tran.ExecuteScalar("INSERT INTO TerminalBoxes4 (pid, " + + "Data, TimeAdded, ParseVersion, Label) VALUES (@pid, @data, " + + "UTC_TIMESTAMP(), 1, @label); SELECT LAST_INSERT_ID()", + new MySqlParameter("@pid", record.PID), + new MySqlParameter("@data", record.Data), + new MySqlParameter("@label", (int)record.Label)); + tran.Commit(); + return serial; + } + else + { + int rows = tran.ExecuteNonQuery("INSERT INTO TerminalBoxes4 (pid, SerialNumber, " + + "Data, TimeAdded, ParseVersion, Label) VALUES (@pid, @serial, @data, " + + "UTC_TIMESTAMP(), 1, @label); SELECT LAST_INSERT_ID()", + new MySqlParameter("@pid", record.PID), + new MySqlParameter("@serial", record.SerialNumber), + new MySqlParameter("@data", record.Data), + new MySqlParameter("@label", (int)record.Label)); + tran.Commit(); + + return rows > 0 ? record.SerialNumber : 0; + } + } + } + } + + public override BoxRecord4[] BoxSearch4(BoxLabels4 label, int count) + { + using (MySqlConnection db = CreateConnection()) + { + db.Open(); + + List results = new List(count); + MySqlDataReader reader = (MySqlDataReader)db.ExecuteReader("SELECT pid, " + + "Label, SerialNumber, Data FROM TerminalBoxes4 WHERE Label = @label " + + "ORDER BY TimeAdded DESC LIMIT @count", + new MySqlParameter("@label", (int)label), + new MySqlParameter("@count", count)); + while (reader.Read()) + { + results.Add(Box4FromReader(reader)); + } + + reader.Close(); + db.Close(); + return results.ToArray(); + } + } + + private BoxRecord4 Box4FromReader(MySqlDataReader reader) + { + byte[] data = new byte[540]; + reader.GetBytes(3, 0, data, 0, 540); + + return new BoxRecord4(reader.GetInt32(0), (BoxLabels4)reader.GetInt32(1), reader.GetInt64(2), data); + } + + #endregion } } diff --git a/library/Library.csproj b/library/Library.csproj index 31229d8d..e2a2e211 100644 --- a/library/Library.csproj +++ b/library/Library.csproj @@ -53,6 +53,7 @@ + diff --git a/library/Structures/BoxRecord4.cs b/library/Structures/BoxRecord4.cs new file mode 100644 index 00000000..87171fa6 --- /dev/null +++ b/library/Structures/BoxRecord4.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace PkmnFoundations.Structures +{ + public class BoxRecord4 + { + public BoxRecord4() + { + } + + public BoxRecord4(int pid, BoxLabels4 label, long serial_number, byte[] data) + { + if (data.Length != 540) throw new ArgumentException("Box data must be 540 bytes."); + + PID = pid; + Label = label; + SerialNumber = serial_number; + Data = data; + } + + // todo: encapsulate these so calculated fields are always correct + public int PID; + public BoxLabels4 Label; + public long SerialNumber; + public byte[] Data; + + public BoxRecord4 Clone() + { + return new BoxRecord4(PID, Label, SerialNumber, Data.ToArray()); + } + } + + public enum BoxLabels4 : int + { + Favorite = 0x00, + Cool = 0x01, + Cute = 0x02, + Suggested = 0x03, + Fun = 0x04, + Select = 0x05 + } +}