diff --git a/GlobalTerminalService/GTServer5.cs b/GlobalTerminalService/GTServer5.cs index 4770f1fc..354565c5 100644 --- a/GlobalTerminalService/GTServer5.cs +++ b/GlobalTerminalService/GTServer5.cs @@ -147,8 +147,12 @@ namespace PkmnFoundations.GlobalTerminalService BattleVideoRankings5 type = (BattleVideoRankings5)BitConverter.ToUInt32(data, 0x140); ushort species = BitConverter.ToUInt16(data, 0x144); BattleVideoMetagames5 meta = (BattleVideoMetagames5)data[0x146]; + // Byte 148 contains a magic number related to the searched metagame. - // I don't think there's any need to verify it here. + // If 0, disable metagame search. Metagame being 00 is insufficient + // since that value could mean Battle Subway Single. + if (data[0x148] == 0x00) meta = BattleVideoMetagames5.SearchNone; + byte country = data[0x14a]; byte region = data[0x14b]; diff --git a/library/Data/DataMysql.cs b/library/Data/DataMysql.cs index 095b2d75..fa9c5470 100644 --- a/library/Data/DataMysql.cs +++ b/library/Data/DataMysql.cs @@ -874,14 +874,15 @@ namespace PkmnFoundations.Data if (record.SerialNumber == 0) { long key = (long)tran.ExecuteScalar("INSERT INTO TerminalBattleVideos4 " + - "(pid, Header, Data, md5, TimeAdded, ParseVersion, TrainerName, " + + "(pid, Header, Data, md5, TimeAdded, ParseVersion, Streak, TrainerName, " + "Metagame, Country, Region) " + "VALUES (@pid, @header, @data, unhex(md5(CONCAT(@header, @data))), " + - "UTC_TIMESTAMP(), 1, @trainer, @metagame, @country, @region); " + + "UTC_TIMESTAMP(), 1, @streak, @trainer, @metagame, @country, @region); " + "SELECT LAST_INSERT_ID()", new MySqlParameter("@pid", record.PID), new MySqlParameter("@header", record.Header.Data), new MySqlParameter("@data", record.Data), + new MySqlParameter("@streak", record.Header.Streak), new MySqlParameter("@trainer", record.Header.TrainerName), new MySqlParameter("@metagame", (byte)record.Header.Metagame), new MySqlParameter("@country", (byte)record.Header.Country), @@ -905,15 +906,18 @@ namespace PkmnFoundations.Data ulong key = (ulong)BattleVideoHeader4.SerialToKey(record.SerialNumber); int rows = tran.ExecuteNonQuery("INSERT INTO TerminalBattleVideos4 " + - "(id, pid, SerialNumber, Header, Data, md5, TimeAdded, ParseVersion, TrainerName, " + + "(id, pid, SerialNumber, Header, Data, md5, TimeAdded, " + + "ParseVersion, Streak, TrainerName, " + "Metagame, Country, Region) " + - "VALUES (@key, @pid, @serial, @header, @data, unhex(md5(CONCAT(@header, @data))), " + - "UTC_TIMESTAMP(), 1, @trainer, @metagame, @country, @region)", + "VALUES (@key, @pid, @serial, @header, @data, " + + "unhex(md5(CONCAT(@header, @data))), " + + "UTC_TIMESTAMP(), 1, @streak, @trainer, @metagame, @country, @region)", new MySqlParameter("@key", key), new MySqlParameter("@pid", record.PID), new MySqlParameter("@serial", record.SerialNumber), new MySqlParameter("@header", record.Header.Data), new MySqlParameter("@data", record.Data), + new MySqlParameter("@streak", record.Header.Streak), new MySqlParameter("@trainer", record.Header.TrainerName), new MySqlParameter("@metagame", (byte)record.Header.Metagame), new MySqlParameter("@country", (byte)record.Header.Country), @@ -1009,7 +1013,7 @@ namespace PkmnFoundations.Data List results = new List(count); MySqlDataReader reader = (MySqlDataReader)db.ExecuteReader("SELECT pid, " + "SerialNumber, Header FROM TerminalBattleVideos4" + where + - " ORDER BY TimeAdded DESC LIMIT @count", + " ORDER BY TimeAdded DESC, id DESC LIMIT @count", _params.ToArray()); while (reader.Read()) { @@ -1184,14 +1188,15 @@ namespace PkmnFoundations.Data if (record.SerialNumber == 0) { long key = (long)tran.ExecuteScalar("INSERT INTO TerminalBattleVideos5 " + - "(pid, Header, Data, md5, TimeAdded, ParseVersion, TrainerName, " + + "(pid, Header, Data, md5, TimeAdded, ParseVersion, Streak, TrainerName, " + "Metagame, Country, Region) " + "VALUES (@pid, @header, @data, unhex(md5(CONCAT(@header, @data))), " + - "UTC_TIMESTAMP(), 1, @trainer, @metagame, @country, @region); " + + "UTC_TIMESTAMP(), 1, @streak, @trainer, @metagame, @country, @region); " + "SELECT LAST_INSERT_ID()", new MySqlParameter("@pid", record.PID), new MySqlParameter("@header", record.Header.Data), new MySqlParameter("@data", record.Data), + new MySqlParameter("@streak", record.Header.Streak), new MySqlParameter("@trainer", record.Header.TrainerName), new MySqlParameter("@metagame", (byte)record.Header.Metagame), new MySqlParameter("@country", (byte)record.Header.Country), @@ -1215,15 +1220,18 @@ namespace PkmnFoundations.Data ulong key = (ulong)BattleVideoHeader4.SerialToKey(record.SerialNumber); int rows = tran.ExecuteNonQuery("INSERT INTO TerminalBattleVideos5 " + - "(id, pid, SerialNumber, Header, Data, md5, TimeAdded, ParseVersion, TrainerName, " + + "(id, pid, SerialNumber, Header, Data, md5, TimeAdded, " + + "ParseVersion, Streak, TrainerName, " + "Metagame, Country, Region) " + - "VALUES (@key, @pid, @serial, @header, @data, unhex(md5(CONCAT(@header, @data))), " + - "UTC_TIMESTAMP(), 1, @trainer, @metagame, @country, @region)", + "VALUES (@key, @pid, @serial, @header, @data, " + + "unhex(md5(CONCAT(@header, @data))), " + + "UTC_TIMESTAMP(), 1, @streak, @trainer, @metagame, @country, @region)", new MySqlParameter("@key", key), new MySqlParameter("@pid", record.PID), new MySqlParameter("@serial", record.SerialNumber), new MySqlParameter("@header", record.Header.Data), new MySqlParameter("@data", record.Data), + new MySqlParameter("@streak", record.Header.Streak), new MySqlParameter("@trainer", record.Header.TrainerName), new MySqlParameter("@metagame", (byte)record.Header.Metagame), new MySqlParameter("@country", (byte)record.Header.Country), @@ -1267,6 +1275,7 @@ namespace PkmnFoundations.Data { List _params = new List(); String where = ""; + String sort = ""; bool hasSearch = false; if (ranking == BattleVideoRankings5.None) @@ -1288,15 +1297,32 @@ namespace PkmnFoundations.Data hasSearch = true; } - // todo: find out if there are ranged searches on GenV too. - /* - if (metagame == BattleVideoMetagames4.SearchColosseumSingleNoRestrictions) - metagame = BattleVideoMetagames4.ColosseumSingleNoRestrictions; - if (metagame == BattleVideoMetagames4.SearchColosseumDoubleNoRestrictions) - metagame = BattleVideoMetagames4.ColosseumDoubleNoRestrictions; - * */ - - if (metagame != BattleVideoMetagames5.None) + if (metagame == BattleVideoMetagames5.RandomMatchupSingle) + { + where += (hasSearch ? " AND " : " WHERE ") + "Metagame IN (40, 104)"; + hasSearch = true; + } + else if (metagame == BattleVideoMetagames5.RandomMatchupDouble) + { + where += (hasSearch ? " AND " : " WHERE ") + "Metagame IN (41, 105)"; + hasSearch = true; + } + else if (metagame == BattleVideoMetagames5.RandomMatchupTriple) + { + where += (hasSearch ? " AND " : " WHERE ") + "Metagame IN (42, 106)"; + hasSearch = true; + } + else if (metagame == BattleVideoMetagames5.RandomMatchupRotation) + { + where += (hasSearch ? " AND " : " WHERE ") + "Metagame IN (43, 107)"; + hasSearch = true; + } + else if (metagame == BattleVideoMetagames5.SearchBattleCompetition) + { + where += (hasSearch ? " AND " : " WHERE ") + "Metagame BETWEEN 56 AND 59"; + hasSearch = true; + } + else if (metagame != BattleVideoMetagames5.SearchNone) { where += (hasSearch ? " AND " : " WHERE ") + "Metagame = @metagame"; _params.Add(new MySqlParameter("@metagame", (byte)metagame)); @@ -1315,6 +1341,23 @@ namespace PkmnFoundations.Data where += (hasSearch ? " AND " : " WHERE ") + "Region = @region"; _params.Add(new MySqlParameter("@region", region)); } + + sort = " ORDER BY TimeAdded DESC, id DESC"; + } + else if (ranking == BattleVideoRankings5.LinkBattles) + { + // todo: sort by .. something. + where = " WHERE NOT (Metagame BETWEEN 0 AND 4)"; + sort = " ORDER BY Streak DESC, TimeAdded DESC, id DESC"; + } + else if (ranking == BattleVideoRankings5.SubwayBattles) + { + where = " WHERE Metagame BETWEEN 0 AND 4"; + sort = " ORDER BY TimeAdded DESC, id DESC"; + } + else + { + sort = " ORDER BY TimeAdded DESC, id DESC"; } _params.Add(new MySqlParameter("@count", count)); @@ -1324,7 +1367,7 @@ namespace PkmnFoundations.Data List results = new List(count); MySqlDataReader reader = (MySqlDataReader)db.ExecuteReader("SELECT pid, " + "SerialNumber, Header FROM TerminalBattleVideos5" + where + - " ORDER BY TimeAdded DESC LIMIT @count", + sort + " LIMIT @count", _params.ToArray()); while (reader.Read()) { diff --git a/library/Structures/BattleVideoHeader4.cs b/library/Structures/BattleVideoHeader4.cs index 41ce69a0..4a19aecb 100644 --- a/library/Structures/BattleVideoHeader4.cs +++ b/library/Structures/BattleVideoHeader4.cs @@ -25,6 +25,14 @@ namespace PkmnFoundations.Structures public long SerialNumber; public byte[] Data; + public ushort Streak + { + get + { + return BitConverter.ToUInt16(Data, 0xa4); + } + } + public ushort[] Party { get diff --git a/library/Structures/BattleVideoHeader5.cs b/library/Structures/BattleVideoHeader5.cs index 0ffecb5a..6a490c6a 100644 --- a/library/Structures/BattleVideoHeader5.cs +++ b/library/Structures/BattleVideoHeader5.cs @@ -25,6 +25,14 @@ namespace PkmnFoundations.Structures public long SerialNumber; public byte[] Data; + public ushort Streak + { + get + { + return BitConverter.ToUInt16(Data, 0xa4); + } + } + public ushort[] Party { get @@ -80,17 +88,16 @@ namespace PkmnFoundations.Structures public enum BattleVideoMetagames5 : byte { - None = 0x00, - ColosseumSingleNoLauncher = 0x18, - ColosseumSingleLauncher = 0x98, ColosseumDoubleNoLauncher = 0x19, - ColosseumDoubleLauncher = 0x99, ColosseumTripleNoLauncher = 0x1a, - ColosseumTripleLauncher = 0x9a, ColosseumRotationNoLauncher = 0x1b, - ColosseumRotationLauncher = 0x9b, ColosseumMultiNoLauncher = 0x1c, + + ColosseumSingleLauncher = 0x98, + ColosseumDoubleLauncher = 0x99, + ColosseumTripleLauncher = 0x9a, + ColosseumRotationLauncher = 0x9b, ColosseumMultiLauncher = 0x9c, BattleSubwaySingle = 0x00, @@ -103,7 +110,23 @@ namespace PkmnFoundations.Structures RandomMatchupRotation = 0x2b, RandomMatchupLauncher = 0xaa, - BattleCompetition = 0x38, + RatingSingle = 0x68, + RatingDouble = 0x69, + RatingTriple = 0x6a, + RatingRotation = 0x6b, + + BattleCompetitionSingle = 0x38, + BattleCompetitionDouble = 0x39, + BattleCompetitionTriple = 0x3a, + BattleCompetitionRotation = 0x3b, + + SearchBattleCompetition = 0x38, + // This is not a legal value in either a search or a record. + // I'm using it to indicate that no search is being done + // (byte 0x148 in the search is 0). + // Otherwise, the value 00 collides with Battle Subway Single + // which is a legitimate search. + SearchNone = 0xff, } public enum BattleVideoRankings5 : uint