From 3bf49ee7d4458c51bafdb5581c288fbd0f71d532 Mon Sep 17 00:00:00 2001
From: Chris Xiong <chirs241097@gmail.com>
Date: Sat, 9 Sep 2023 23:10:03 -0400
Subject: Support the new dump format with locked attribute.

---
 mapman/src/library.cpp   | 22 +++++++++++++---------
 mapman/src/mapdump.cpp   | 10 ++++++++--
 mapman/src/mapdump.hpp   |  1 +
 mapman/src/sliceview.cpp |  1 +
 4 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/mapman/src/library.cpp b/mapman/src/library.cpp
index 2361441..4a51272 100644
--- a/mapman/src/library.cpp
+++ b/mapman/src/library.cpp
@@ -5,7 +5,7 @@
 #include <filesystem>
 #include <sqlite3.h>
 
-const int MAPDB_VERSION = 1;
+const int MAPDB_VERSION = 2;
 
 map_library::map_library() : db(nullptr) {}
 
@@ -45,18 +45,20 @@ void map_library::set_map(const map_t &map)
     sqlite3_stmt *st = nullptr;
     if (has_map(map.id))
     {
-        sqlite3_prepare_v2(db, "update maps set custom_name = ?, data = ? where id = ?;", -1, &st, 0);
+        sqlite3_prepare_v2(db, "update maps set custom_name = ?, locked = ?, data = ? where id = ?;", -1, &st, 0);
         sqlite3_bind_text(st, 1, map.custom_name.c_str(), map.custom_name.length(), SQLITE_STATIC);
-        sqlite3_bind_blob(st, 2, map.map_data.data(), map.map_data.size(), SQLITE_STATIC);
-        sqlite3_bind_int(st, 3, map.id);
+        sqlite3_bind_int(st, 2, map.locked);
+        sqlite3_bind_blob(st, 3, map.map_data.data(), map.map_data.size(), SQLITE_STATIC);
+        sqlite3_bind_int(st, 4, map.id);
         sqlite3_step(st);
     }
     else
     {
-        sqlite3_prepare_v2(db, "insert into maps (id, custom_name, data) values(?, ?, ?);", -1, &st, 0);
+        sqlite3_prepare_v2(db, "insert into maps (id, custom_name, locked, data) values(?, ?, ?, ?);", -1, &st, 0);
         sqlite3_bind_int(st, 1, map.id);
         sqlite3_bind_text(st, 2, map.custom_name.c_str(), map.custom_name.length(), SQLITE_STATIC);
-        sqlite3_bind_blob(st, 3, map.map_data.data(), map.map_data.size(), SQLITE_STATIC);
+        sqlite3_bind_int(st, 3, map.locked);
+        sqlite3_bind_blob(st, 4, map.map_data.data(), map.map_data.size(), SQLITE_STATIC);
         sqlite3_step(st);
     }
     sqlite3_finalize(st);
@@ -65,13 +67,14 @@ void map_library::set_map(const map_t &map)
 map_t map_library::get_map(int id) const
 {
     sqlite3_stmt *st = nullptr;
-    sqlite3_prepare_v2(db, "select custom_name, data from maps where id = ?;", -1, &st, 0);
+    sqlite3_prepare_v2(db, "select custom_name, locked, data from maps where id = ?;", -1, &st, 0);
     sqlite3_bind_int(st, 1, id);
-    map_t ret{id, std::string(), map_data_t()};
+    map_t ret{id, std::string(), false, map_data_t()};
     if (sqlite3_step(st) == SQLITE_ROW)
     {
         ret.custom_name = std::string((char*)sqlite3_column_text(st, 0));
-        memcpy(ret.map_data.data(), sqlite3_column_blob(st, 1), ret.map_data.size());
+        ret.locked = sqlite3_column_int(st, 1) ? true : false;
+        memcpy(ret.map_data.data(), sqlite3_column_blob(st, 2), ret.map_data.size());
     }
     sqlite3_finalize(st);
     return ret;
@@ -298,6 +301,7 @@ void map_library::init_db()
         create table maps(
             id integer primary key,
             custom_name text,
+            locked integer,
             data blob
         );
     )sql", nullptr, nullptr, nullptr);
diff --git a/mapman/src/mapdump.cpp b/mapman/src/mapdump.cpp
index 6d8fbcc..af32a0f 100644
--- a/mapman/src/mapdump.cpp
+++ b/mapman/src/mapdump.cpp
@@ -1,13 +1,16 @@
 #include "mapdump.hpp"
 
+#include <algorithm>
+
 #include <zlib.h>
 
 bool load_dump(gzFile f, map_t &d)
 {
-    map_t ret;
     if (gzread(f, &d.id, 4) < 4) return false;
     int name_len;
     if (gzread(f, &name_len, 4) < 4) return false;
+    d.locked = ((name_len & 0xf0000000) != 0);
+    name_len &= 0x7fffffff;
     if (name_len)
     {
         char *name = new char[name_len];
@@ -16,7 +19,7 @@ bool load_dump(gzFile f, map_t &d)
             delete[] name;
             return false;
         }
-        d.custom_name = std::string(name);
+        d.custom_name = std::string(name, name_len);
         delete[] name;
     } else d.custom_name = std::string();
     if (gzread(f, d.map_data.data(), 128 * 128) < 128 * 128)
@@ -48,5 +51,8 @@ std::vector<int> load_tally(const char *fn)
         gzread(f, &t, 4);
         ret.push_back(t);
     }
+    std::sort(ret.begin(), ret.end());
+    auto uend = std::unique(ret.begin(), ret.end());
+    ret.erase(uend, ret.end());
     return ret;
 }
diff --git a/mapman/src/mapdump.hpp b/mapman/src/mapdump.hpp
index aa771e6..50f90ec 100644
--- a/mapman/src/mapdump.hpp
+++ b/mapman/src/mapdump.hpp
@@ -12,6 +12,7 @@ struct map_t
 {
     int id;
     std::string custom_name;
+    bool locked;
     map_data_t map_data;
 };
 
diff --git a/mapman/src/sliceview.cpp b/mapman/src/sliceview.cpp
index 1dc385b..c0dc3a7 100644
--- a/mapman/src/sliceview.cpp
+++ b/mapman/src/sliceview.cpp
@@ -91,6 +91,7 @@ void slice_view::refresh()
         map_t map = l->get_map(id);
         QPixmap pm = pixmap_of_map_data(map.map_data);
         QString text = QString("(%1)").arg(id);
+        if (map.locked) text.append(" [L]");
         if (map.custom_name.length()) text = QString::fromStdString(map.custom_name) + " " + text;
         QStandardItem *itm = new QStandardItem(QIcon(pm), text);
         itm->setData(QVariant(id));
-- 
cgit v1.2.3