From 480c20f0cf50f6d8e8407af62ffb5f39a96622a4 Mon Sep 17 00:00:00 2001 From: tkashkin Date: Sat, 22 Jun 2019 07:11:51 +0300 Subject: [PATCH] Games merging tweaks Update Humble Trove parsing (#32) --- src/data/adapters/GamesAdapter.vala | 5 ++- src/data/db/tables/Merges.vala | 52 ++++++++--------------- src/data/sources/humble/Trove.vala | 66 ++++++++++++++++------------- 3 files changed, 58 insertions(+), 65 deletions(-) diff --git a/src/data/adapters/GamesAdapter.vala b/src/data/adapters/GamesAdapter.vala index 05105deb..9506a88c 100644 --- a/src/data/adapters/GamesAdapter.vala +++ b/src/data/adapters/GamesAdapter.vala @@ -428,15 +428,18 @@ namespace GameHub.Data.Adapters { if(Game.is_equal(game, game2) || game2 is Sources.GOG.GOGGame.DLC) return; + if(Tables.Merges.is_game_merged(game) || Tables.Merges.is_game_merged(game2) || Tables.Merges.is_game_merged_as_primary(game2)) return; + bool name_match_exact = game.normalized_name.casefold() == game2.normalized_name.casefold(); bool name_match_fuzzy_prefix = game.source != src && (Utils.strip_name(game.name, ":", true).casefold().has_prefix(game2.normalized_name.casefold() + ":") || Utils.strip_name(game2.name, ":", true).casefold().has_prefix(game.normalized_name.casefold() + ":")); if(name_match_exact || name_match_fuzzy_prefix) { - Tables.Merges.add(game, game2); debug("[Merge] Merging '%s' (%s) with '%s' (%s)", game.name, game.full_id, game2.name, game2.full_id); + Tables.Merges.add(game, game2); remove(game2); + game.update_status(); } } diff --git a/src/data/db/tables/Merges.vala b/src/data/db/tables/Merges.vala index ace0fd10..eaec67b3 100644 --- a/src/data/db/tables/Merges.vala +++ b/src/data/db/tables/Merges.vala @@ -64,7 +64,7 @@ namespace GameHub.Data.DB.Tables Statement s; - int res = db.prepare_v2("SELECT rowid, * FROM `merges` WHERE `merge` LIKE ? OR `merge` LIKE ?", -1, out s); + int res = db.prepare_v2("SELECT rowid, * FROM `merges` WHERE `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ?", -1, out s); if(res != Sqlite.OK) { @@ -72,8 +72,12 @@ namespace GameHub.Data.DB.Tables return false; } - s.bind_text(1, @"%$(first.full_id)%"); - s.bind_text(2, @"%$(second.full_id)%"); + s.bind_text(1, @"$(first.full_id)|%"); + s.bind_text(2, @"%|$(first.full_id)|%"); + s.bind_text(3, @"%|$(first.full_id)"); + s.bind_text(4, @"$(second.full_id)|%"); + s.bind_text(5, @"%|$(second.full_id)|%"); + s.bind_text(6, @"%|$(second.full_id)"); int64? row = null; int merge_var = 1; @@ -98,39 +102,19 @@ namespace GameHub.Data.DB.Tables return false; } - string new_merge = ""; - - var games = new ArrayList(Game.is_equal); - games.add(first); - games.add(second); + string[] games = {}; if(old_merge != null) { foreach(var gameid in old_merge.split("|")) { - var gparts = gameid.split(":"); - var gsrc = gparts[0]; - var gid = gparts[1]; - - if(gsrc == null || gid == null) continue; - - var game = Games.get(gsrc, gid); - - if(game != null && !games.contains(game)) games.add(game); + if(!(gameid in games)) games += gameid; } } - foreach(var src in GameSources) - { - foreach(var game in games) - { - if(game.source.id == src.id) - { - if(new_merge != "") new_merge += "|"; - new_merge += game.full_id; - } - } - } + if(!(first.full_id in games)) games += first.full_id; + if(!(second.full_id in games)) games += second.full_id; + var new_merge = string.joinv("|", games); s.bind_text(merge_var, new_merge); res = s.step(); @@ -161,13 +145,14 @@ namespace GameHub.Data.DB.Tables s.bind_text(1, @"$(game.full_id)|%"); - if((res = s.step()) == Sqlite.ROW) + ArrayList? games = null; + while((res = s.step()) == Sqlite.ROW) { - var games = new ArrayList(Game.is_equal); var merge = s.column_text(0); - if(merge != null) { + if(games == null) games = new ArrayList(Game.is_equal); + foreach(var gameid in merge.split("|")) { var gparts = gameid.split(":"); @@ -181,11 +166,8 @@ namespace GameHub.Data.DB.Tables if(g != null && !games.contains(g) && !Game.is_equal(game, g)) games.add(g); } } - - return games; } - - return null; + return games; } public static Game? get_primary(Game game) diff --git a/src/data/sources/humble/Trove.vala b/src/data/sources/humble/Trove.vala index 93ea66ea..38a216dc 100644 --- a/src/data/sources/humble/Trove.vala +++ b/src/data/sources/humble/Trove.vala @@ -91,38 +91,46 @@ namespace GameHub.Data.Sources.Humble if(trove_json != null) { var trove_root_node = Parser.parse_json(trove_json); - var trove_root = Parser.json_object(trove_root_node, { "displayItemData" }); - - if(trove_root != null) + if(trove_root_node.get_node_type() == Json.NodeType.OBJECT) { - trove_root.foreach_member((trove_root_obj, key, node) => { - if(key == TROVE_INTRO_ID) return; - - var obj = node.get_object(); - var downloads = obj.get_object_member("downloads"); - - downloads.foreach_member((downloads_obj, dl_os, dl_node) => { - var dl_obj = dl_node.get_object(); - var dl_name = dl_obj.get_string_member("machine_name"); - var dl_id = dl_obj.get_object_member("url").get_string_member("web"); - dl_obj.set_string_member("download_identifier", dl_id); - dl_obj.get_object_member("url").set_string_member("web", "humble-trove-unsigned://" + dl_name + "/_gh_dl_/" + dl_id); - }); - - var game = new HumbleGame(this, Trove.FAKE_ORDER, node); - - if(game.platforms.size == 0) return; - bool is_new_game = !_games.contains(game); - if(is_new_game && (!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(game))) + var trove_root = trove_root_node.get_object(); + if(trove_root != null) + { + var products = trove_root.has_member("standardProducts") ? trove_root.get_array_member("standardProducts") : null; + if(products != null) { - _games.add(game); - if(game_loaded != null) - { - game_loaded(game, false); - } + products.foreach_element((array, index, node) => { + var obj = node.get_object(); + var key = obj.get_string_member("machine_name"); + + if(key == TROVE_INTRO_ID) return; + + var downloads = obj.get_object_member("downloads"); + + downloads.foreach_member((downloads_obj, dl_os, dl_node) => { + var dl_obj = dl_node.get_object(); + var dl_name = dl_obj.get_string_member("machine_name"); + var dl_id = dl_obj.get_object_member("url").get_string_member("web"); + dl_obj.set_string_member("download_identifier", dl_id); + dl_obj.get_object_member("url").set_string_member("web", "humble-trove-unsigned://" + dl_name + "/_gh_dl_/" + dl_id); + }); + + var game = new HumbleGame(this, Trove.FAKE_ORDER, node); + + if(game.platforms.size == 0) return; + bool is_new_game = !_games.contains(game); + if(is_new_game && (!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(game))) + { + _games.add(game); + if(game_loaded != null) + { + game_loaded(game, false); + } + } + if(is_new_game) games_count++; + }); } - if(is_new_game) games_count++; - }); + } } }