--- softchat.py.ocv	2021-01-29 22:40:20.000000000 +0100
+++ softchat.py	2021-01-29 23:08:06.000000000 +0100
@@ -7,6 +7,7 @@
 import json
 import zlib
 import random
+import pprint
 import logging
 import argparse
 import colorsys
@@ -456,45 +457,48 @@
         info(f"loading {fn}")
         with open(fn, "r", encoding="utf-8") as f:
             jd2 = json.load(f)
+            jd2 = [x for x in jd2 if x.get("action_type", None) == "add_chat_item"]
+            jd2 = [x for x in jd2 if x.get("author", {}).get("id", None) is not None]
             for m in jd2:
-                key = f"{m['timestamp']}\n{m['author_id']}"
+                key = f"{m['timestamp']}\n{m['author']['id']}"
                 if key not in seen:
                     seen.add(key)
                     jd.append(m)
 
+    use_018 = "; please use softchat v0.18 or older if your chat json was created with a chat_replay_downloader from before 2021-01-29-something"
+    use_017 = "; please use softchat v0.17 or older if your chat json was created with a really old chat_replay_downloader"
+    if not jd:
+        raise Exception("no messages were loaded" + use_018)
+
     # jd.sort(key=operator.attrgetter("timestamp"))
     jd.sort(key=lambda x: x["timestamp"])
     unix_ofs = None
     for x in jd:
         unix = x["timestamp"] / 1_000_000.0
-        t = x.get("video_offset_time_msec", 0)
-        if t >= 10_000:
-            video = t / 1000.0
+        t = x.get("time_in_seconds", 0)
+        if t >= 10:
+            video = t
             unix_ofs = unix - video
             break
 
     if unix_ofs is None:
-        raise Exception(
-            "could not find video_offset_time_msec in json, please use softchat v0.17 or older if your chat json was created with a really old chat_replay_downloader"
-        )
+        raise Exception("could not find time_in_seconds in json" + use_017);
 
     debug(f"unixtime offset = {unix_ofs:.3f}")
     debug("adding video offset to all messages")
     n_interp = 0
     for x in jd:
         unix = x["timestamp"] / 1_000_000.0
-        t = x.get("video_offset_time_msec", None)
+        t = x.get("time_in_seconds", None)
         if t is None:
             n_interp += 1
             sec = unix - unix_ofs
             isec = int(sec)
-            x["video_offset_time_msec"] = 1000 * sec
+            x["time_in_seconds"] = sec
             x["time_text"] = f"{isec // 60}:{isec % 60:02d}"
-            x["time_in_seconds"] = isec
-        elif t >= 10_000 and "amount" not in x:
-            video = t / 1000.0
+        elif t >= 10 and "amount" not in x:
+            video = t
             new_ofs = unix - video
-            # print(f"{unix:.3f}, {video:.3f}, {x['time_text']}, {x['time_in_seconds']}")
             diff = abs(new_ofs - unix_ofs)
             if diff >= 10:
                 print(repr(x))
@@ -506,14 +510,19 @@
 
             unix_ofs = new_ofs
 
-    jd.sort(key=lambda x: [x["video_offset_time_msec"], x["author_id"]])
+    jd.sort(key=lambda x: [x["time_in_seconds"], x["author"]["id"]])
     info("{} msgs total, {} amended".format(len(jd), n_interp))
 
     # find all dupe msgs from [author-id, message-text]
     dupes = {}
     seen = set()
     for m in jd:
-        key = f"{m['author_id']}\n{m['message']}"
+        try:
+            mtxt = m.get("message", "--") or "--"
+            key = f"{m['author']['id']}\n{mtxt}"
+        except:
+            raise Exception(pprint.pformat(m))
+
         if key not in seen:
             seen.add(key)
             continue
@@ -530,7 +539,7 @@
         vf = []
         for m1, m2 in zip(v, v[1:]):
             if m2["timestamp"] - m1["timestamp"] < 10_000_000:
-                droplist.add(f"{m['timestamp']}\n{m['author_id']}")
+                droplist.add(f"{m['timestamp']}\n{m['author']['id']}")
                 for m in [m1, m2]:
                     if m not in vf:
                         vf.append(m)
@@ -547,7 +556,7 @@
 
     jd2 = []
     for m in jd:
-        key = f"{m['timestamp']}\n{m['author_id']}"
+        key = f"{m['timestamp']}\n{m['author']['id']}"
         if key not in droplist:
             jd2.append(m)
 
@@ -603,13 +612,13 @@
     for msg in jd:
         # break  # opt
 
-        uid = msg["author_id"]
+        uid = msg["author"]["id"]
         try:
-            nick = msg["author"]
+            nick = msg["author"]["name"]
         except:
             # warn(repr(msg))
             # raise
-            msg["author"] = nick = uid
+            msg["author"]["name"] = nick = uid
 
         # in case names change mid-stream
         pair = f"{nick}\n{uid}"
@@ -626,9 +635,6 @@
         except:
             nick_list[nick] = [uid]
 
-        # if nick == "McDoogle":
-        #    print(f"{nick} {uid} {msg['message']}")
-
     info(f"tagged {len(nick_dupes)} dupes:")
     for k, v in sorted(nick_list.items(), key=lambda x: [-len(x[1]), x[0]])[:20]:
         info(f"  {len(v)}x {k}")
@@ -637,22 +643,16 @@
     info(f"converting")
     last_msg = None
     for n_msg, msg in enumerate(jd):
-        txt = msg["message"] or "--"
-        cmp_msg = f"{msg['author_id']}\n{txt}"
+        txt = msg.get("message", "--") or "--"
+        cmp_msg = f"{msg['author']['id']}\n{txt}"
         if last_msg == cmp_msg:
             continue
 
         last_msg = cmp_msg
 
-        try:
-            t_fsec = msg["video_offset_time_msec"] / 1000.0
-            t_isec = msg["time_in_seconds"]
-            t_hms = msg["time_text"]
-        except:
-            # rip was made using a chat_replay_downloader.py from before 2020-11-01
-            t_fsec = msg["time_in_seconds"]
-            t_hms = msg["time_text"].split(".")[0]
-            t_isec = int(t_fsec)
+        t_fsec = msg["time_in_seconds"]
+        t_isec = int(t_fsec)
+        t_hms = msg["time_text"]
 
         if t_hms.startswith("-") or t_isec < 0 or t_isec > 4096 * 4096:
             continue
@@ -667,7 +667,7 @@
 
         if int(t_fsec) != t_isec or t_isec != t_isec2:
             # at some point, someone observed a difference between time_text
-            # and video_offset_time_msec, so please let me have a look at
+            # and time_in_seconds, so please let me have a look at
             # your chatlog json if you end up here
             raise Exception(
                 f"time drift [{t_fsec}] [{t_isec}] [{t_isec2}] [{t_hms}]\n  (pls provide this chat-rip to ed)"
@@ -752,13 +752,13 @@
                 )
             )
 
-        nick = msg["author"]
+        nick = msg["author"]["name"]
         if nick in nick_dupes:
-            nick += f"  ({msg['author_id']})"
+            nick += f"  ({msg['author']['id']})"
 
         o = {
             "nick": nick,
-            "uid": msg["author_id"],
+            "uid": msg["author"]["id"],
             "t0": t_fsec,
             "sx": sx,
             "sy": sy,
@@ -767,7 +767,7 @@
 
         if "amount" in msg:
             o["shrimp"] = msg["amount"]
-            o["color"] = msg["body_color"]["hex"][1:][:-2]  # "#1de9b6ff"
+            o["color"] = msg["body_background_colour"][1:][:-2]  # "#1de9b6ff"
 
         if "badges" in msg:
             o["badges"] = msg["badges"]
