From f7e533506c9b11beff9f6ac133b5d8a98773cb09 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Mon, 22 Jun 2026 19:53:34 -0400 Subject: [PATCH 01/38] export button --- prefabs/map_info_container.tscn | 15 +++- scripts/map/MapParser.cs | 71 ++++++++++++++++++ scripts/ui/menu/play/MapInfoContainer.cs | 17 +++++ user/skins/default/ui/buttons/export.png | Bin 0 -> 2246 bytes .../default/ui/buttons/export.png.import | 40 ++++++++++ 5 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 user/skins/default/ui/buttons/export.png create mode 100644 user/skins/default/ui/buttons/export.png.import diff --git a/prefabs/map_info_container.tscn b/prefabs/map_info_container.tscn index 98ccc0ce..b6d30a81 100644 --- a/prefabs/map_info_container.tscn +++ b/prefabs/map_info_container.tscn @@ -6,6 +6,7 @@ [ext_resource type="Theme" uid="uid://dhuhu3mmaew1a" path="res://themes/theme.tres" id="4_4d08m"] [ext_resource type="Script" uid="uid://c1235cyjfh4rl" path="res://scripts/ui/LinkPopupButton.cs" id="4_dccrs"] [ext_resource type="Texture2D" uid="uid://7px5v8ikildx" path="res://user/skins/default/ui/buttons/favorite.png" id="5_1m5pv"] +[ext_resource type="Texture2D" uid="uid://dkpbociv8fgfd" path="res://user/skins/default/ui/buttons/export.png" id="5_g02bu"] [ext_resource type="Script" uid="uid://dy45uerqy0yd7" path="res://scripts/ui/FlatPreview.cs" id="5_svokg"] [ext_resource type="Texture2D" uid="uid://degvlg4p0if70" path="res://user/skins/default/ui/buttons/add_video.png" id="6_g02bu"] [ext_resource type="Texture2D" uid="uid://cgxbwx4f28lt2" path="res://user/skins/default/ui/buttons/copy.png" id="7_oibm8"] @@ -175,7 +176,7 @@ outline_color = Color(0, 0, 0, 1) shadow_size = 4 shadow_color = Color(0, 0, 0, 1) -[node name="MapInfoContainer" type="Panel" unique_id=150923669 node_paths=PackedStringArray("info", "dim", "coverBackground", "cover", "infoSubholder", "mainLabel", "extraLabel", "artistLink", "favoriteButton", "videoButton", "videoDialog", "copyButton", "copyDialog", "deleteButton", "actions", "preview", "speedHolder", "speedPresets", "playHolder", "startButton", "leaderboard", "lbScrollContainer", "lbContainer", "lbExpand", "lbHide")] +[node name="MapInfoContainer" type="Panel" unique_id=150923669 node_paths=PackedStringArray("info", "dim", "coverBackground", "cover", "infoSubholder", "mainLabel", "extraLabel", "artistLink", "exportButton", "favoriteButton", "videoButton", "videoDialog", "copyButton", "copyDialog", "deleteButton", "actions", "preview", "speedHolder", "speedPresets", "playHolder", "startButton", "leaderboard", "lbScrollContainer", "lbContainer", "lbExpand", "lbHide")] anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -193,6 +194,7 @@ infoSubholder = NodePath("Info/ScrollContainer/HBoxContainer") mainLabel = NodePath("Info/ScrollContainer/HBoxContainer/Subholder/Main") extraLabel = NodePath("Info/ScrollContainer/HBoxContainer/Subholder/Extra") artistLink = NodePath("Info/ScrollContainer/HBoxContainer/Background/ArtistLink") +exportButton = NodePath("Info/ScrollContainer/HBoxContainer/Subholder/Buttons/Export") favoriteButton = NodePath("Info/ScrollContainer/HBoxContainer/Subholder/Buttons/Favorite") videoButton = NodePath("Info/ScrollContainer/HBoxContainer/Subholder/Buttons/Video") videoDialog = NodePath("Info/ScrollContainer/HBoxContainer/Subholder/Buttons/Video/VideoDialog") @@ -357,6 +359,17 @@ grow_horizontal = 0 grow_vertical = 0 alignment = 2 +[node name="Export" type="Button" parent="Info/ScrollContainer/HBoxContainer/Subholder/Buttons" unique_id=2033571562] +layout_mode = 2 +tooltip_text = "Export (Shift+Click for .sspm export)" +focus_mode = 0 +mouse_default_cursor_shape = 2 +theme = ExtResource("4_4d08m") +theme_override_colors/font_color = Color(1, 1, 1, 1) +theme_override_constants/icon_max_width = 24 +icon = ExtResource("5_g02bu") +icon_alignment = 1 + [node name="Favorite" type="Button" parent="Info/ScrollContainer/HBoxContainer/Subholder/Buttons" unique_id=1022164792] layout_mode = 2 tooltip_text = "Favorite" diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index c1fc5f92..2459ac7d 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -67,6 +67,77 @@ await Task.Run(() => if (notify) ToastNotification.Notify($"Finished importing {files.Length} map(s)"); } + public static void ExportEncode(Map map) + { + string exportPath = $"{Constants.USER_FOLDER}/export/"; + string exportFilePath = Path.Combine(exportPath, $"{map.Name}.phxm"); + + if (!Directory.Exists(exportPath)) Directory.CreateDirectory(exportPath); + + /* + uint32; ms + 1 byte; quantum + 1 byte OR int32; x + 1 byte OR int32; y + */ + + using var ms = new MemoryStream(); + using (var archive = new ZipArchive(ms, ZipArchiveMode.Create)) + { + var metadata = archive.CreateEntry("metadata.json", CompressionLevel.NoCompression); + using (var writer = new StreamWriter(metadata.Open())) + writer.Write(map.EncodeMeta()); + var objects = archive.CreateEntry("objects.phxmo", CompressionLevel.NoCompression); + using (var objs = objects.Open()) + { + using BinaryWriter bw = new BinaryWriter(objs); + bw.Write((uint)12); + bw.Write((uint)map.Notes.Length); + foreach (var note in map.Notes) + { + bool quantum = (int)note.X != note.X || (int)note.Y != note.Y || note.X < -1 || note.X > 1 || note.Y < -1 || note.Y > 1; + bw.Write((uint)note.Millisecond); + bw.Write(Convert.ToByte(quantum)); + if (quantum) + { + bw.Write((float)note.X); + bw.Write((float)note.Y); + } + else + { + bw.Write((byte)(note.X + 1)); + bw.Write((byte)(note.Y + 1)); + } + } + bw.Write(0); // timing point count + bw.Write(0); // brightness count + bw.Write(0); // contrast count + bw.Write(0); // saturation count + bw.Write(0); // blur count + bw.Write(0); // fov count + bw.Write(0); // tint count + bw.Write(0); // position count + bw.Write(0); // rotation count + bw.Write(0); // ar factor count + bw.Write(0); // text count + } + + void addAsset(string name, byte[] buffer) + { + var asset = archive.CreateEntry(name, CompressionLevel.NoCompression); + using var stream = asset.Open(); + stream.Write(buffer, 0, buffer.Length); + } + + if (map.AudioBuffer != null) addAsset($"audio.{map.AudioExt}", map.AudioBuffer); + if (map.CoverBuffer != null) addAsset($"cover.png", map.CoverBuffer); + if (map.VideoBuffer != null) addAsset($"video.mp4", map.VideoBuffer); + } + + map.Hash = Convert.ToHexString(MD5.HashData(ms.ToArray())).ToLower(); + File.WriteAllBytes(exportFilePath, ms.ToArray()); + } + public static void Encode(Map map, bool logBenchmark = false) { double start = Time.GetTicksUsec(); diff --git a/scripts/ui/menu/play/MapInfoContainer.cs b/scripts/ui/menu/play/MapInfoContainer.cs index 8611ee9b..364a2afb 100644 --- a/scripts/ui/menu/play/MapInfoContainer.cs +++ b/scripts/ui/menu/play/MapInfoContainer.cs @@ -44,6 +44,9 @@ public partial class MapInfoContainer : Panel, ISkinnable private LinkPopupButton artistLink; private string artistLinkFormat; + [Export] + private Button exportButton; + [Export] private Button favoriteButton; @@ -123,6 +126,20 @@ public override void _Ready() artistLinkFormat = artistLink.Text; outlineMaterial = info.GetNode("Outline").Material as ShaderMaterial; + exportButton.Pressed += () => + { + string exportPath = $"{Constants.USER_FOLDER}/export/"; + string exportFilePath = Path.Combine(exportPath, $"{Map.Name}.phxm"); + + _ = ToastNotification.Notify($"Exporting to {exportFilePath}", 1); + MapParser.ExportEncode(Map); + + _ = ToastNotification.Notify($"Done! Opening export folder...", 0); + + OS.ShellShowInFileManager($"{Constants.USER_FOLDER}/export/"); + + }; + favoriteButton.Pressed += () => { Map.Favorite = !Map.Favorite; diff --git a/user/skins/default/ui/buttons/export.png b/user/skins/default/ui/buttons/export.png new file mode 100644 index 0000000000000000000000000000000000000000..4004e8ad74d05657e3b55a416af3d5608a3721e4 GIT binary patch literal 2246 zcmV;%2s!tOP)fUg_-YhzkAL-=iGD8IoBtpL>1rza4&$*0WbhO58!k) z1_Cmm3hjO=Wl~CMODQcWWxtg2ST)9iDtz>VQp!HL7><%2QuM|l=9GOjLqkA zp|Usx;O79|1H5gOvjO}Gz?T6GS8{N^3NxS?z)t{t1c09x=I7_#8-BkZ;c(dfozLeN z#1TLw67k+O0sI=kR{@MwYJh=Cbqrt^fM)>Q;}L)U{CQlzejSeEprxe+2M!!?3BP># zGH%?s;WA~%jvZ)gYvbcV03RdI06YRmIiTog!%Z10s$I;Z(#MkQpd|nZM z9DrWV!HRNrMimC|B!Ew<*>h)|IvxszvOb^hn{{<{FElhXWb5ne5sSsJY11Zb-n$QhgVU#9CuO6u@@?d_m2cOTg8uS7DkabX|W& zO8HYw)8=EbSkUM5fsInYR$pK5@9OHBGYsRo+1c3>*=!aA0|S_vn)3ROD<(Xm9H%wM zfQMBhBV3X1@9ziod}e0mdBZTCJ$m$LmiOxFT>dOVEEaQ#>g?>CmQsG-vaFZ+Zf|d| z+gA}2z7F92wZ?#V1NahvP5i?FU%7GxoJHHVPf97D=<4b!$n$dO?CcztQXaP~>o;UV zUtb@Y=-u9`B%yW9Fu-w~U5?|lQq;N3aarSfZ&}t$Qp#_2cXuaC?X$bPyO*==IL;~d z#Z`n$CBNY~&OXO+=wqynRbYI4{8BodzLrX*+Q!DlTxTW{iM#~h@t&TZ(Utbw)6;Y9 z^y$-&Tb30|rBWZJVQg-0X1mbX*f^+GiRw#0DwXO_CX-L4(`l~d*B!_C8G!HJ4)Gqk zySw`w$9c?goL{l;OeXWUWHR}5DwP^9$Jj+VI_c=>u%@P_Ue4$94@fERGfnf`Jv}{F zQ6?NacI>=qnvb&YTrT&}ow*nI#Rlv^uTK!gS06o6MseD}Qo9#Brz!iJ$VkZ?K>0|4IOb_Bre zatsja!;IG62VlzzK76x*TwDPI?f~$aGP%BU0Dh-JZfA-oQY?A!ivWJ99F1}iPd$_Q ze7@uvaP}`%wx;Mn-(PuG5orTPfdVT!FqwLqh`^8ykxsq4)T-vS-f~Gk|*jXfg5J#L)35 z2RNuw8IVjSU54KdMn@Oi5C&QH?IVdUs8U}8@J|4*c?|f3^5+^wiP3hNchymK9R{}?in5)#;#qA)VW}4?u0N+^RVMM1^HCF zu4~+gREzj>LDMv;Y1$iV3w>^OcGlfY5w>l&=(>KV$mjEibzS!tM`y#~@Lx4e`xiC{ zG)?Obg+hPeZyHv@Fbw`aBn-o7HcivV;3Qih5RmbBygb%#4S_TTgF(}ylagQmcz{2=&@>qk2m}iMHxh!upi3Kl z6T*`OQS4w8J1`p!UhvhUk&sM}FUph_F=3;@qpO&BS%vz5H3xwjhd_-(pvECk;}EEE z2-G+PY8(PJ4uKknK#fD7#vxGS5U6no)Hnjge^x6Fz}g}1#TlSvq=s!tnQYlnOj~h= zDX=sc;zdp>iEK7IJ25dKhlhuK{8npgtK7PE>s+N7;6;RpLVbYaIBrDPjgBnj@+uw^ z%x1G^GMUV9Hk;ka|6^lgZ`rnec1a$utYAElw6PI|D7a-=7B4b5N>L1l!#*Z7D>jma zyyL6sboxQVFqo1v)9LidBS(%fg-n)BJ~JSs!AR z=bk<8fv%t`O|J*=3sqZFl@pe?iOm2$u1=k>O2n;XWx5qoKA>8V%ExI`MIU}I_0Ixsl_6&K`^TOm^m_m=*tY#3AE17y zijIJ?1?%1(u=IXth;<$=ehc8_qC-=OL}I5p)JTyjl$LDYzMU2n>k%||oOPDUQ1=!7 z$m2Jfrm<{p@u@MzgvZno73%*+0#*1$0N>LzZRD26<`Rhn*UF>n@B?cGqe}PJi~bkG zR)oK)>WyB}G;Ma-bAyS6+8R3Mw1&Ht4OmH~Xtluc(}2^-qvG@M<-De8|KsET7wCM! UJ(hhl+W-In07*qoM6N<$f>lyHaR2}S literal 0 HcmV?d00001 diff --git a/user/skins/default/ui/buttons/export.png.import b/user/skins/default/ui/buttons/export.png.import new file mode 100644 index 00000000..33dbb9a9 --- /dev/null +++ b/user/skins/default/ui/buttons/export.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dkpbociv8fgfd" +path="res://.godot/imported/export.png-9d48d4339a04990c70115e465c24c745.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://user/skins/default/ui/buttons/export.png" +dest_files=["res://.godot/imported/export.png-9d48d4339a04990c70115e465c24c745.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 From 417556e8292b92e810b5f84495a8efd58ea7dcc6 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Mon, 22 Jun 2026 19:54:01 -0400 Subject: [PATCH 02/38] redundant --- prefabs/map_info_container.tscn | 1 + 1 file changed, 1 insertion(+) diff --git a/prefabs/map_info_container.tscn b/prefabs/map_info_container.tscn index b6d30a81..7dc3c47d 100644 --- a/prefabs/map_info_container.tscn +++ b/prefabs/map_info_container.tscn @@ -403,6 +403,7 @@ filters = PackedStringArray("*.mp4") use_native_dialog = true [node name="Copy" type="Button" parent="Info/ScrollContainer/HBoxContainer/Subholder/Buttons" unique_id=2053076461] +visible = false layout_mode = 2 tooltip_text = "Copy" focus_mode = 0 From 83beff5f42758b28705021beddeff4ed36d28c10 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Mon, 22 Jun 2026 19:54:09 -0400 Subject: [PATCH 03/38] dddssdfdffdffdffdffdfdf --- scripts/map/MapParser.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 2459ac7d..fdb42377 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -74,13 +74,6 @@ public static void ExportEncode(Map map) if (!Directory.Exists(exportPath)) Directory.CreateDirectory(exportPath); - /* - uint32; ms - 1 byte; quantum - 1 byte OR int32; x - 1 byte OR int32; y - */ - using var ms = new MemoryStream(); using (var archive = new ZipArchive(ms, ZipArchiveMode.Create)) { From 6a82546be83dc3b32290f48f3405003d5c2e8209 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Mon, 22 Jun 2026 21:05:14 -0400 Subject: [PATCH 04/38] bye collection --- scripts/map/MapCache.cs | 6 +++--- scripts/map/MapParser.cs | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index ac1d6929..ccac8681 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -164,7 +164,7 @@ private static void addNonCachedFiles(string[] files) { var map = MapParser.Decode(file); map.Collection = file.GetBaseDir().Split("/")[^1]; - map.FilePath = $"{Constants.USER_FOLDER}/maps/{map.Collection}/{map.Name}.{Constants.DEFAULT_MAP_EXT}"; + map.FilePath = $"{Constants.USER_FOLDER}/maps/{map.Name}.{Constants.DEFAULT_MAP_EXT}"; map.Hash = GetMd5Checksum(file); File.Move(file, map.FilePath); InsertMap(map); @@ -206,8 +206,8 @@ public static int InsertMap(Map map) return -1; } - string newPath = Path.Combine(MapUtil.MapsFolder, map.Collection, map.Name); - string existingPath = Path.Combine(MapUtil.MapsFolder, map.Collection, existing?.FilePath ?? updated.FilePath); + string newPath = Path.Combine(MapUtil.MapsFolder, map.Name); + string existingPath = Path.Combine(MapUtil.MapsFolder, existing?.FilePath ?? updated.FilePath); if (existingPath != newPath) { diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index fdb42377..7d2c1bff 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -135,9 +135,7 @@ public static void Encode(Map map, bool logBenchmark = false) { double start = Time.GetTicksUsec(); - map.Collection = $"default"; - - string mapDirectory = $"{Constants.USER_FOLDER}/maps/{map.Collection}"; + string mapDirectory = $"{Constants.USER_FOLDER}/maps"; string mapFilePath = Path.Combine(mapDirectory, $"{map.Name}.{Constants.DEFAULT_MAP_EXT}"); if (!Directory.Exists(mapDirectory)) Directory.CreateDirectory(mapDirectory); From fa3c268de46f5fbbdc5329f092085bef63b0c6d9 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Mon, 22 Jun 2026 21:05:51 -0400 Subject: [PATCH 05/38] selects file now --- scripts/ui/menu/play/MapInfoContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ui/menu/play/MapInfoContainer.cs b/scripts/ui/menu/play/MapInfoContainer.cs index 364a2afb..e146a2b6 100644 --- a/scripts/ui/menu/play/MapInfoContainer.cs +++ b/scripts/ui/menu/play/MapInfoContainer.cs @@ -134,9 +134,9 @@ public override void _Ready() _ = ToastNotification.Notify($"Exporting to {exportFilePath}", 1); MapParser.ExportEncode(Map); - _ = ToastNotification.Notify($"Done! Opening export folder...", 0); + _ = ToastNotification.Notify($"Done! Opening export...", 0); - OS.ShellShowInFileManager($"{Constants.USER_FOLDER}/export/"); + OS.ShellShowInFileManager(exportFilePath); }; From 37b4c3e4783e5013fa51ae0a354a6bbdd5977261 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 23 Jun 2026 14:08:43 -0400 Subject: [PATCH 06/38] easy --- scripts/util/Misc.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/scripts/util/Misc.cs b/scripts/util/Misc.cs index 38a1716c..19368c09 100644 --- a/scripts/util/Misc.cs +++ b/scripts/util/Misc.cs @@ -1,4 +1,8 @@ +using System; using System.Globalization; +using System.IO; +using System.Security.Cryptography; +using System.Text; using Godot; namespace Util; @@ -61,6 +65,24 @@ public static void CopyProperties(Node node, Node reference) } } + public static byte[] HashFiles(string[] paths) + { + using var md5 = MD5.Create(); + + foreach (var path in paths) // we do not need to order the paths since it will always be the same -fog + { + byte[] filePathBytes = Encoding.UTF8.GetBytes(path); + byte[] fileData = File.ReadAllBytes(path); + + md5.TransformBlock(filePathBytes, 0, filePathBytes.Length, null, 0); + md5.TransformBlock(fileData, 0, fileData.Length, null, 0); + } + + md5.TransformFinalBlock(Array.Empty(), 0 ,0); + + return md5.Hash; + } + public static void CopyReference(Node node, Node reference) { CopyProperties(node, reference); From 0fada8188d8d8430559a3af76ae8431c61ab5daa Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 23 Jun 2026 17:29:32 -0400 Subject: [PATCH 07/38] useless --- scripts/util/Misc.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/util/Misc.cs b/scripts/util/Misc.cs index 19368c09..510bfa2c 100644 --- a/scripts/util/Misc.cs +++ b/scripts/util/Misc.cs @@ -71,10 +71,7 @@ public static byte[] HashFiles(string[] paths) foreach (var path in paths) // we do not need to order the paths since it will always be the same -fog { - byte[] filePathBytes = Encoding.UTF8.GetBytes(path); byte[] fileData = File.ReadAllBytes(path); - - md5.TransformBlock(filePathBytes, 0, filePathBytes.Length, null, 0); md5.TransformBlock(fileData, 0, fileData.Length, null, 0); } From ce211679f2962649d0627aff0697385e5d4c5d78 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 23 Jun 2026 17:29:41 -0400 Subject: [PATCH 08/38] deprecated --- scripts/ui/menu/play/MapInfoContainer.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/ui/menu/play/MapInfoContainer.cs b/scripts/ui/menu/play/MapInfoContainer.cs index e146a2b6..2e11feae 100644 --- a/scripts/ui/menu/play/MapInfoContainer.cs +++ b/scripts/ui/menu/play/MapInfoContainer.cs @@ -161,17 +161,17 @@ public override void _Ready() // MapManager.InsertVideo(Map, file); //}; - copyButton.Pressed += () => - { - copyDialog.Popup(); + // copyButton.Pressed += () => + // { + // copyDialog.Popup(); - }; + // }; - copyDialog.FileSelected += (path) => - { - File.Copy(Map.FilePath, path); - _ = ToastNotification.Notify($"Copied to {path}"); - }; + // copyDialog.FileSelected += (path) => + // { + // File.Copy(Map.FolderPath, path); + // _ = ToastNotification.Notify($"Copied to {path}"); + // }; deleteButton.Pressed += () => { From 068693c43ba7a7085742d3dfb72cccc4362f1aa5 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 23 Jun 2026 17:30:28 -0400 Subject: [PATCH 09/38] adjust to map.cs change --- scripts/SoundManager.cs | 4 ++-- scripts/game/managers/ReplayManager.cs | 12 ++++++++---- scripts/game/ui/PlaytestOverlay.cs | 2 +- scripts/map/Map.cs | 17 +++++++++++------ scripts/map/Replay.cs | 2 +- scripts/scenes/Game.cs | 4 ++-- scripts/scenes/Results.cs | 2 +- 7 files changed, 26 insertions(+), 17 deletions(-) diff --git a/scripts/SoundManager.cs b/scripts/SoundManager.cs index 9eb59133..f0ecf4eb 100644 --- a/scripts/SoundManager.cs +++ b/scripts/SoundManager.cs @@ -221,7 +221,7 @@ public static void PlayJukebox(Map map, bool setRichPresence = true) JukeboxIndex = MapManager.Maps.FindIndex(x => x.Id == map.Id); - Song.Stream = Util.Audio.LoadFromFile($"{MapUtil.MapsCacheFolder}/{map.Name}/audio.{map.AudioExt}"); + Song.Stream = Util.Audio.LoadFromFile($"{MapUtil.MapsFolder}/{map.Name}/audio.{map.AudioExt}"); Song.Play(); Instance.JukeboxPlayed?.Invoke(map); @@ -280,7 +280,7 @@ public static void StartMapSelectionPlayback(Map map, bool setRichPresence = tru } } - Song.Stream = Util.Audio.LoadFromFile($"{MapUtil.MapsCacheFolder}/{map.Name}/audio.{map.AudioExt}"); + Song.Stream = Util.Audio.LoadFromFile($"{MapUtil.MapsFolder}/{map.Name}/audio.{map.AudioExt}"); Song.Play(0); Instance.JukeboxPlayed?.Invoke(map); diff --git a/scripts/game/managers/ReplayManager.cs b/scripts/game/managers/ReplayManager.cs index 42166b59..631e5332 100644 --- a/scripts/game/managers/ReplayManager.cs +++ b/scripts/game/managers/ReplayManager.cs @@ -1,4 +1,7 @@ using System; +using System.IO; + +// using System.IO; using System.Linq; using System.Security.Cryptography; using Godot; @@ -28,7 +31,7 @@ public enum Mode public string ReplayPath; public Vector2 CursorPosition { get; private set; } - private FileAccess file; + private Godot.FileAccess file; private ulong statusOffset, frameCountOffset; public void NewReplay(Attempt attempt) @@ -39,7 +42,7 @@ public void NewReplay(Attempt attempt) ReplayPath = $"{Constants.USER_FOLDER}/replays/{attempt.ID}.phxr"; - file = FileAccess.Open(ReplayPath, FileAccess.ModeFlags.Write); + file = Godot.FileAccess.Open(ReplayPath, Godot.FileAccess.ModeFlags.Write); file.StoreString("phxr"); // sig file.Store8(1); // replay file version @@ -69,7 +72,8 @@ public void NewReplay(Attempt attempt) } string serializedMods = string.Join("_", mods); - string mapName = attempt.Map.FilePath.GetFile().GetBaseName(); + // string mapName = attempt.Map.FilePath.GetFile().GetBaseName(); + string mapName = Path.GetDirectoryName(attempt.Map.FolderPath); string player = "You"; void storeSizedString(string data) @@ -126,7 +130,7 @@ public void SaveReplay(Attempt attempt) file.Close(); // open replay to store hash - file = FileAccess.Open($"{Constants.USER_FOLDER}/replays/{attempt.ID}.phxr", FileAccess.ModeFlags.ReadWrite); + file = Godot.FileAccess.Open($"{Constants.USER_FOLDER}/replays/{attempt.ID}.phxr", Godot.FileAccess.ModeFlags.ReadWrite); ulong length = file.GetLength(); byte[] hash = SHA256.HashData(file.GetBuffer((long)length)); file.StoreBuffer(hash); diff --git a/scripts/game/ui/PlaytestOverlay.cs b/scripts/game/ui/PlaytestOverlay.cs index b6917758..1b6102dc 100644 --- a/scripts/game/ui/PlaytestOverlay.cs +++ b/scripts/game/ui/PlaytestOverlay.cs @@ -74,7 +74,7 @@ public void UpdatePlaytestOverlay(bool show) speedValue = speedDouble; } - var map = MapParser.Decode(oldAttempt.Map.FilePath, Rhythia.AudioFilePath); + var map = MapParser.Decode(oldAttempt.Map.FolderPath, Rhythia.AudioFilePath); Game.Attempt = new(map, speedValue, GetStartFrom(startFromEdit) * 1000, Rhythia.TempCam, Rhythia.TempMods); SceneManager.ReloadCurrentScene(); diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs index 15c8c76f..118b97a0 100644 --- a/scripts/map/Map.cs +++ b/scripts/map/Map.cs @@ -17,15 +17,20 @@ public partial class Map : RefCounted public int Id { get; set; } public string Name { get; set; } = string.Empty; + public DateTime LastModifiedMetadata { get; set; } + public DateTime LastModifiedNotes { get; set; } - public string Hash { get; set; } + /// + /// The hash of the metadata.json, then the objects.phxmo in order + /// + public string MetadataObjectHash { get; set; } public string Collection { get; set; } = string.Empty; [Ignore] public MapSet MapSet { get; set; } - public string FilePath { get; set; } = string.Empty; + public string FolderPath { get; set; } = string.Empty; public bool Favorite { get; set; } @@ -86,7 +91,7 @@ public Note[] TryParseNotes() { try { - notes = MapParser.DecodePHXMO($"{MapUtil.MapsCacheFolder}/{Name}/objects.phxmo"); + notes = MapParser.DecodePHXMO($"{MapUtil.MapsFolder}/{Name}/objects.phxmo"); return notes; } catch @@ -97,7 +102,7 @@ public Note[] TryParseNotes() private Texture2D getCover() { - string path = $"{MapUtil.MapsCacheFolder}/{Name}"; + string path = $"{MapUtil.MapsFolder}/{Name}"; if (cover == DefaultCover && File.Exists($"{path}/cover.png")) { @@ -115,9 +120,9 @@ private Texture2D getCover() public Map() { } - public Map(string filePath, Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") + public Map(string folderPath, Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") { - FilePath = filePath; + FolderPath = folderPath; Ephemeral = ephemeral; Artist = (artist ?? "").StripEscapes(); ArtistLink = artistLink; diff --git a/scripts/map/Replay.cs b/scripts/map/Replay.cs index 6da741ea..a2764ed6 100644 --- a/scripts/map/Replay.cs +++ b/scripts/map/Replay.cs @@ -168,7 +168,7 @@ public Replay(string path) MapID = FileBuffer.GetString((int)FileBuffer.GetUInt32()); MapNoteCount = FileBuffer.GetUInt64(); - MapFilePath = $"{Constants.USER_FOLDER}/maps/default/{MapID}.phxm"; + MapFilePath = $"{Constants.USER_FOLDER}/maps/{MapID}.phxm"; if (!File.Exists(MapFilePath)) { diff --git a/scripts/scenes/Game.cs b/scripts/scenes/Game.cs index 5858faaa..a507e2e6 100644 --- a/scripts/scenes/Game.cs +++ b/scripts/scenes/Game.cs @@ -170,7 +170,7 @@ public static void Play(Map map, double speed, double startFrom, CameraMode came StartQueued = true; - var parsedMap = MapParser.Decode(map.FilePath, Rhythia.AudioFilePath); + var parsedMap = MapParser.Decode(map.FolderPath, Rhythia.AudioFilePath); Attempt = new(parsedMap, speed, startFrom, cameraMode, mods, players, replays); if (!Attempt.IsReplay) @@ -189,7 +189,7 @@ public void Restart() Runner.Stop(false); var oldAttempt = Attempt; - var map = MapParser.Decode(oldAttempt.Map.FilePath, Rhythia.AudioFilePath); + var map = MapParser.Decode(oldAttempt.Map.FolderPath, Rhythia.AudioFilePath); Attempt = new(map, oldAttempt.Speed, oldAttempt.StartFrom, oldAttempt.CameraMode, oldAttempt.Modifiers, oldAttempt.Players, oldAttempt.Replays); SceneManager.ReloadCurrentScene(); diff --git a/scripts/scenes/Results.cs b/scripts/scenes/Results.cs index e775065f..916e4664 100644 --- a/scripts/scenes/Results.cs +++ b/scripts/scenes/Results.cs @@ -173,7 +173,7 @@ public void Replay() { var attempt = Game.Attempt; - Map map = MapParser.Decode(attempt.Map.FilePath); + Map map = MapParser.Decode(attempt.Map.FolderPath); map.Ephemeral = attempt.Map.Ephemeral; SoundManager.Song.Stop(); From 9de2b082cbb4e60b201364272c5af175d11cf615 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 23 Jun 2026 17:30:51 -0400 Subject: [PATCH 10/38] map folder cache --- scripts/map/MapCache.cs | 257 +++++++++++++++++++++++------------- scripts/map/MapManager.cs | 18 +-- scripts/map/MapParser.cs | 268 +++++++++++++++++++++++++------------- 3 files changed, 354 insertions(+), 189 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index ccac8681..7f4e5df8 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -1,11 +1,13 @@ -using System; +using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; using System.IO; using System.IO.Compression; using System.Linq; using System.Security.Cryptography; using System.Threading.Tasks; using Godot; +using Octokit; using Util; public static class MapCache @@ -28,12 +30,24 @@ public static void Load(bool fullSync) try { - string[] files = Directory.GetFiles(MapUtil.MapsFolder, $"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories); + // string[] files = Directory.GetFiles(MapUtil.MapsFolder, $"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories); + + // List mapsList = Directory + // .GetFiles(MapUtil.MapsFolder, $"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories) + // .Concat(Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories)) + // .ToList(); + + // Map files go first since they will be encoded to folders after they get parsed in MapParser.cs + List mapsList = Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories) + .Concat(Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories)) + .ToList(); + + string[] toParseMaps = mapsList.ToArray(); if (fullSync) { - syncFiles(files); - addNonCachedFiles(files); + syncFiles(toParseMaps); + addNonCachedFiles(toParseMaps); OnFilesSyncFinished?.Invoke(FilesSynced.Value); FilesToSync.Value = 0; @@ -48,35 +62,39 @@ public static void Load(bool fullSync) } } - private static void syncFiles(string[] files) + private static void syncFiles(string[] toParseMaps) { var maps = FetchAll(); FilesToSync.Value = maps.Count; FilesSynced.Value = 0; - for (int i = 0; i < files.Length; i++) + for (int i = 0; i < toParseMaps.Length; i++) { - files[i] = BackSlashToForwardSlash(files[i]); + toParseMaps[i] = BackSlashToForwardSlash(toParseMaps[i]); } - var filesHashSet = files.ToHashSet(); + var mapsHashSet = toParseMaps.ToHashSet(); foreach (var map in maps) { - string filePath = BackSlashToForwardSlash(map.FilePath); + string mapPath = BackSlashToForwardSlash(map.FolderPath); - if (filesHashSet.Contains(filePath)) + // Checks if the map is actually inside the maps folder + if (mapsHashSet.Contains(mapPath)) { - string checksum = GetMd5Checksum(filePath); + string checksum = GetMd5Checksum(mapPath); + DateTime metadataModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "metadata.json")); + DateTime objectModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "objects.phxmo")); - if (map.Hash == checksum) - { - if (!Directory.Exists($"{MapUtil.MapsCacheFolder}/{map.Name}")) - { - InsertIntoMapCacheFolder(map); - } + GD.Print($"{Path.Combine(mapPath, "metadata.json")} = {metadataModifiedDate}"); + bool metadataCheck = metadataModifiedDate == map.LastModifiedMetadata; + bool objectsCheck = objectModifiedDate == map.LastModifiedNotes; + + if (map.MetadataObjectHash == checksum || metadataCheck || objectsCheck) + { + GD.Print("skip"); FilesSynced.Value += 1; continue; } @@ -85,75 +103,124 @@ private static void syncFiles(string[] files) try { - newMap = MapParser.Decode(filePath, null, false, true); + newMap = MapParser.Decode(mapPath, null, false, true); } catch (Exception ex) { Logger.Error(ex); - File.Delete(filePath); + if (File.Exists(mapPath)) + { + File.Delete(mapPath); + } + else if (Directory.Exists(mapPath)) + { + Directory.Delete(mapPath, true); + } DatabaseService.Connection.Delete(map); FilesSynced.Value += 1; continue; } + newMap.LastModifiedMetadata = metadataModifiedDate; + newMap.LastModifiedNotes = objectModifiedDate; + newMap.Id = map.Id; - newMap.Hash = checksum; + newMap.MetadataObjectHash = checksum; DatabaseService.Connection.Update(newMap); - InsertIntoMapCacheFolder(map); + // InsertIntoMapCacheFolder(map); Logger.Log($"Updated cached map: {newMap.Name}"); - FilesSynced.Value += 1; continue; } else { - removeCacheFolder(map); + // removeCacheFolder(map); + try + { + Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); + } + catch + { + return; + } DatabaseService.Connection.Delete(map); - Logger.Log($"Removed {filePath} from the cache, as it no longer exists."); + Logger.Log($"Removed {mapPath} from the cache, as it no longer exists."); FilesSynced.Value += 1; } } } - public static void InsertIntoMapCacheFolder(Map map) - { - string path = $"{MapUtil.MapsCacheFolder}/{map.Name}"; - using var stream = File.OpenRead(map.FilePath); - var archive = new ZipArchive(stream); - - if (Directory.Exists(path)) - { - Directory.Delete(path, true); - } - - archive.ExtractToDirectory(path, true); - } - - private static void removeCacheFolder(Map map) - { - try - { - Directory.Delete($"{MapUtil.MapsCacheFolder}/{map.Name}", true); - } - catch - { - return; - } - } - - private static void addNonCachedFiles(string[] files) + // public static void InsertIntoMapCacheFolder(Map map) + // { + // string path = $"{MapUtil.MapsCacheFolder}/{map.Name}"; + + // // for phxm shit i guess + // if (File.Exists(map.FolderPath)) + // { + // using var stream = File.OpenRead(map.FolderPath); + // var archive = new ZipArchive(stream); + + // if (Directory.Exists(path)) + // { + // Directory.Delete(path, true); + // } + + // archive.ExtractToDirectory(path, true); + // } + // else if (Directory.Exists(map.FolderPath)) + // { + // GD.Print("PATH PATH PATH!!!"); + // if (Directory.Exists(path)) + // { + // Directory.Delete(path, true); + // } + + // Directory.CreateDirectory(path); + + // foreach (string file in Directory.GetFiles(map.FolderPath)) + // { + // string destFile = Path.Combine(path, Path.GetFileName(file)); + // File.Copy(file, destFile, overwrite: true); + // } + // } + + // // using var stream = File.OpenRead(map.FilePath); + // // var archive = new ZipArchive(stream); + + // // if (Directory.Exists(path)) + // // { + // // Directory.Delete(path, true); + // // } + + // // archive.ExtractToDirectory(path, true); + + // } + + // private static void removeCacheFolder(Map map) + // { + // try + // { + // Directory.Delete($"{MapUtil.MapsCacheFolder}/{map.Name}", true); + // } + // catch + // { + // return; + // } + // } + + private static void addNonCachedFiles(string[] toParseMaps) { var maps = FetchAll(); HashSet hashSet = new(); - maps.ForEach(map => hashSet.Add(map.FilePath)); + maps.ForEach(map => hashSet.Add(map.FolderPath)); - foreach (string file in files) + foreach (string toParseMap in toParseMaps) { - if (hashSet.Contains(BackSlashToForwardSlash(file))) + if (hashSet.Contains(BackSlashToForwardSlash(toParseMap))) { continue; } @@ -162,16 +229,16 @@ private static void addNonCachedFiles(string[] files) try { - var map = MapParser.Decode(file); - map.Collection = file.GetBaseDir().Split("/")[^1]; - map.FilePath = $"{Constants.USER_FOLDER}/maps/{map.Name}.{Constants.DEFAULT_MAP_EXT}"; - map.Hash = GetMd5Checksum(file); - File.Move(file, map.FilePath); + var map = MapParser.Decode(toParseMap); + // var map = !Directory.Exists(file) ? MapParser.Decode(file) : MapParser.DecodeFolder(file); + map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; + // map.FilePath = !Directory.Exists(map.FilePath) ? $"{Constants.USER_FOLDER}/maps/{map.Name}.{Constants.DEFAULT_MAP_EXT}" : $"{Constants.USER_FOLDER}/maps/{map.Name}"; + map.MetadataObjectHash = GetMd5Checksum(toParseMap); InsertMap(map); } catch { - File.Delete(file); + Directory.Delete(toParseMap, true); Logger.Log($"Failed to add map non-cached map"); } @@ -181,7 +248,7 @@ private static void addNonCachedFiles(string[] files) public static int InsertMap(Map map) { - var existing = DatabaseService.Connection.Find(x => x.Hash == x.Hash); + var existing = DatabaseService.Connection.Find(x => x.MetadataObjectHash == map.MetadataObjectHash); var updated = DatabaseService.Connection.Find(x => x.Name == map.Name); try @@ -194,9 +261,8 @@ public static int InsertMap(Map map) } DatabaseService.Connection.Insert(map); - InsertIntoMapCacheFolder(map); - return DatabaseService.Connection.Get(x => x.Hash == map.Hash).Id; + return DatabaseService.Connection.Get(x => x.MetadataObjectHash == map.MetadataObjectHash).Id; } catch (Exception e) { @@ -207,11 +273,11 @@ public static int InsertMap(Map map) } string newPath = Path.Combine(MapUtil.MapsFolder, map.Name); - string existingPath = Path.Combine(MapUtil.MapsFolder, existing?.FilePath ?? updated.FilePath); + string existingPath = Path.Combine(MapUtil.MapsFolder, existing?.FolderPath ?? updated.FolderPath); if (existingPath != newPath) { - File.Delete(newPath); + Directory.Delete(newPath, true); return -1; } @@ -224,7 +290,6 @@ public static void UpdateMap(Map map) try { DatabaseService.Connection.Update(map); - InsertIntoMapCacheFolder(map); } catch (Exception e) { @@ -253,7 +318,7 @@ public static void OrderAndSetMaps() { foreach (var map in maps) { - string path = $"{MapUtil.MapsCacheFolder}/{map.Name}"; + string path = $"{MapUtil.MapsFolder}/{map.Name}"; if (map.Cover == Map.DefaultCover && File.Exists($"{path}/cover.png")) { @@ -298,39 +363,45 @@ public static void OrderAndSetMaps() MapManager.Maps = sortedMaps; } - public static List ConvertToMapSets(IEnumerable maps) - { - var groupedMaps = maps - .GroupBy(u => u.Collection) - .Select(x => x.ToList()) - .ToList(); + // public static List ConvertToMapSets(IEnumerable maps) + // { + // var groupedMaps = maps + // .GroupBy(u => u.Collection) + // .Select(x => x.ToList()) + // .ToList(); - var mapSets = new List(); + // var mapSets = new List(); - foreach (var mapSet in groupedMaps) - { - var set = new MapSet() - { - Directory = mapSet.First().Collection, - Maps = mapSet - }; + // foreach (var mapSet in groupedMaps) + // { + // var set = new MapSet() + // { + // Directory = mapSet.First().Collection, + // Maps = mapSet + // }; - set.Maps.ForEach(x => x.MapSet = set); - mapSets.Add(set); - } + // set.Maps.ForEach(x => x.MapSet = set); + // mapSets.Add(set); + // } - return mapSets; - } + // return mapSets; + // } public static string GetMd5Checksum(string path) { - using (var md5 = MD5.Create()) - { - using (var stream = File.OpenRead(path)) - { - return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty).ToLower(); - } - } + string metadataPath = Path.Combine(path, "metadata.json"); + string objectsPath = Path.Combine(path, "objects.phxmo"); + byte[] hash = Misc.HashFiles([metadataPath, objectsPath]); + + return BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); + + // using (var md5 = MD5.Create()) + // { + // using (var stream = File.OpenRead(path)) + // { + // return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty).ToLower(); + // } + // } } public static List FetchAll() => DatabaseService.Connection.Table().ToList(); diff --git a/scripts/map/MapManager.cs b/scripts/map/MapManager.cs index df690414..6d5c0d5e 100644 --- a/scripts/map/MapManager.cs +++ b/scripts/map/MapManager.cs @@ -58,35 +58,35 @@ public static void InsertVideo(Map map, string path) map.VideoBuffer = videoBuffer; - var oldmap = MapParser.Decode(map.FilePath); + var oldmap = MapParser.Decode(map.FolderPath); map.Mappers = map.CachedMappers.Split("_"); map.AudioBuffer = oldmap.AudioBuffer; map.CoverBuffer = oldmap.CoverBuffer; - File.Delete(map.FilePath); + Directory.Delete(map.FolderPath); MapParser.Encode(map); - map.Hash = MapCache.GetMd5Checksum(map.FilePath); + map.FolderPath = MapCache.GetMd5Checksum(map.FolderPath); Update(map); } public static void RemoveVideo(Map map) { - _ = Godot.FileAccess.Open(map.FilePath, Godot.FileAccess.ModeFlags.Read); + _ = Godot.FileAccess.Open(map.FolderPath, Godot.FileAccess.ModeFlags.Read); map.VideoBuffer = null; - var oldmap = MapParser.Decode(map.FilePath); + var oldmap = MapParser.Decode(map.FolderPath); map.Mappers = map.PrettyMappers.Split(" "); map.AudioBuffer = oldmap.AudioBuffer; map.CoverBuffer = oldmap.CoverBuffer; - File.Delete(map.FilePath); + File.Delete(map.FolderPath); MapParser.Encode(map); - map.Hash = MapCache.GetMd5Checksum(map.FilePath); + map.MetadataObjectHash = MapCache.GetMd5Checksum(map.FolderPath); Update(map); } @@ -96,11 +96,11 @@ public static void Delete(Map map) { try { - File.Delete(map.FilePath); + File.Delete(map.FolderPath); } catch { - if (File.Exists(map.FilePath)) + if (File.Exists(map.FolderPath)) { Logger.Error("Unable to delete map"); return; diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 7d2c1bff..572ef7b9 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Godot; using Godot.Collections; +using Util; public partial class MapParser : Node { @@ -27,7 +28,7 @@ public static async Task BulkImport(string[] files, bool notify = false) { if (files.Length == 0 || files == null) return; - if (notify) ToastNotification.Notify($"Importing {files.Length} map(s)"); + if (notify) _ = ToastNotification.Notify($"Importing {files.Length} map(s)"); await Task.Run(() => { @@ -64,7 +65,7 @@ await Task.Run(() => }); SoundManager.UpdateJukeboxQueue(); - if (notify) ToastNotification.Notify($"Finished importing {files.Length} map(s)"); + if (notify) _ = ToastNotification.Notify($"Finished importing {files.Length} map(s)"); } public static void ExportEncode(Map map) @@ -127,7 +128,6 @@ void addAsset(string name, byte[] buffer) if (map.VideoBuffer != null) addAsset($"video.mp4", map.VideoBuffer); } - map.Hash = Convert.ToHexString(MD5.HashData(ms.ToArray())).ToLower(); File.WriteAllBytes(exportFilePath, ms.ToArray()); } @@ -136,9 +136,11 @@ public static void Encode(Map map, bool logBenchmark = false) double start = Time.GetTicksUsec(); string mapDirectory = $"{Constants.USER_FOLDER}/maps"; - string mapFilePath = Path.Combine(mapDirectory, $"{map.Name}.{Constants.DEFAULT_MAP_EXT}"); + string mapFolderPath = Path.Combine(mapDirectory, $"{map.Name}"); + // string mapFilePath = Path.Combine(mapDirectory, $"{map.Name}.{Constants.DEFAULT_MAP_EXT}"); if (!Directory.Exists(mapDirectory)) Directory.CreateDirectory(mapDirectory); + if (!Directory.Exists(mapFolderPath)) Directory.CreateDirectory(mapFolderPath); /* uint32; ms @@ -147,63 +149,65 @@ public static void Encode(Map map, bool logBenchmark = false) 1 byte OR int32; y */ - using var ms = new MemoryStream(); - using (var archive = new ZipArchive(ms, ZipArchiveMode.Create)) + File.WriteAllText(Path.Combine(mapFolderPath, "metadata.json"), map.EncodeMeta()); + + using var stream = File.Create(Path.Combine(mapFolderPath, "objects.phxmo")); + using BinaryWriter bw = new BinaryWriter(stream); + + bw.Write((uint)12); + bw.Write((uint)map.Notes.Length); + foreach (var note in map.Notes) { - var metadata = archive.CreateEntry("metadata.json", CompressionLevel.NoCompression); - using (var writer = new StreamWriter(metadata.Open())) - writer.Write(map.EncodeMeta()); - var objects = archive.CreateEntry("objects.phxmo", CompressionLevel.NoCompression); - using (var objs = objects.Open()) + bool quantum = (int)note.X != note.X || (int)note.Y != note.Y || note.X < -1 || note.X > 1 || note.Y < -1 || note.Y > 1; + bw.Write((uint)note.Millisecond); + bw.Write(Convert.ToByte(quantum)); + if (quantum) { - using BinaryWriter bw = new BinaryWriter(objs); - bw.Write((uint)12); - bw.Write((uint)map.Notes.Length); - foreach (var note in map.Notes) - { - bool quantum = (int)note.X != note.X || (int)note.Y != note.Y || note.X < -1 || note.X > 1 || note.Y < -1 || note.Y > 1; - bw.Write((uint)note.Millisecond); - bw.Write(Convert.ToByte(quantum)); - if (quantum) - { - bw.Write((float)note.X); - bw.Write((float)note.Y); - } - else - { - bw.Write((byte)(note.X + 1)); - bw.Write((byte)(note.Y + 1)); - } - } - bw.Write(0); // timing point count - bw.Write(0); // brightness count - bw.Write(0); // contrast count - bw.Write(0); // saturation count - bw.Write(0); // blur count - bw.Write(0); // fov count - bw.Write(0); // tint count - bw.Write(0); // position count - bw.Write(0); // rotation count - bw.Write(0); // ar factor count - bw.Write(0); // text count + bw.Write((float)note.X); + bw.Write((float)note.Y); } - - void addAsset(string name, byte[] buffer) + else { - var asset = archive.CreateEntry(name, CompressionLevel.NoCompression); - using var stream = asset.Open(); - stream.Write(buffer, 0, buffer.Length); + bw.Write((byte)(note.X + 1)); + bw.Write((byte)(note.Y + 1)); } + } - if (map.AudioBuffer != null) addAsset($"audio.{map.AudioExt}", map.AudioBuffer); - if (map.CoverBuffer != null) addAsset($"cover.png", map.CoverBuffer); - if (map.VideoBuffer != null) addAsset($"video.mp4", map.VideoBuffer); + bw.Write(0); // timing point count + bw.Write(0); // brightness count + bw.Write(0); // contrast count + bw.Write(0); // saturation count + bw.Write(0); // blur count + bw.Write(0); // fov count + bw.Write(0); // tint count + bw.Write(0); // position count + bw.Write(0); // rotation count + bw.Write(0); // ar factor count + bw.Write(0); // text count + + void addAsset(string name, byte[] buffer) + { + // var asset = archive.CreateEntry(name, CompressionLevel.NoCompression); + // using var stream = asset.Open(); + // stream.Write(buffer, 0, buffer.Length); + + string assetPath = Path.Combine(mapFolderPath, name); + File.WriteAllBytes(assetPath, buffer); } - map.Hash = Convert.ToHexString(MD5.HashData(ms.ToArray())).ToLower(); - File.WriteAllBytes(mapFilePath, ms.ToArray()); - map.FilePath = mapFilePath; - MapCache.InsertMap(map); + if (map.AudioBuffer != null) addAsset($"audio.{map.AudioExt}", map.AudioBuffer); + if (map.CoverBuffer != null) addAsset($"cover.png", map.CoverBuffer); + if (map.VideoBuffer != null) addAsset($"video.mp4", map.VideoBuffer); + + byte[] hash = Misc.HashFiles([Path.Combine(mapFolderPath, "metadata.json"), Path.Combine(mapFolderPath, "objects.phxmo")]); + + map.MetadataObjectHash = BitConverter.ToString(hash).Replace("-", "").ToLower(); + + map.LastModifiedMetadata = File.GetLastWriteTime(Path.Combine(mapFolderPath, "metadata.json")); + map.LastModifiedNotes = File.GetLastWriteTime(Path.Combine(mapFolderPath, "objects.phxmo")); + + map.FolderPath = mapFolderPath; + // need to do map caching stuff here if (logBenchmark) { @@ -213,34 +217,47 @@ void addAsset(string name, byte[] buffer) public static Map Decode(string path, string audio = null, bool logBenchmark = false, bool save = false) { - if (!File.Exists(path)) + // if (!File.Exists(path)) + // { + // ToastNotification.Notify($"Invalid file path", 2); + // throw Logger.Error($"Invalid file path ({path})"); + // } + + // Extract any .phxm files or encode other formats if needed + if (File.Exists(path)) { - ToastNotification.Notify($"Invalid file path", 2); - throw Logger.Error($"Invalid file path ({path})"); - } + string ext = path.GetExtension(); + double start = Time.GetTicksUsec(); - string ext = path.GetExtension(); - double start = Time.GetTicksUsec(); + if (!IsValidExt(ext)) + { + _ = ToastNotification.Notify("Unsupported file format", 1); + throw Logger.Error($"Unsupported file format ({ext})"); + } + + Map map = ext switch + { + "phxm" => PHXM(path), + "sspm" => SSPM(path), + "txt" => SSMapV1(path, audio), + "rhm" => RHM(path), + _ => new() + }; - if (!IsValidExt(ext)) + if (logBenchmark) Logger.Log($"DECODING {ext.ToUpper()}: {(Time.GetTicksUsec() - start) / 1000}ms"); + if (save) Encode(map); + + return map; + } + else if (Directory.Exists(path)) { - ToastNotification.Notify("Unsupported file format", 1); - throw Logger.Error($"Unsupported file format ({ext})"); + return PHXMFolder(path); } - - Map map = ext switch + else { - "phxm" => PHXM(path), - "sspm" => SSPM(path), - "txt" => SSMapV1(path, audio), - "rhm" => RHM(path), - _ => new() - }; - - if (logBenchmark) Logger.Log($"DECODING {ext.ToUpper()}: {(Time.GetTicksUsec() - start) / 1000}ms"); - if (save) Encode(map); - - return map; + _ = ToastNotification.Notify($"Invalid file path", 2); + throw Logger.Error($"Invalid file path ({path})"); + } } public static Map SSMapV1(string path, string audioPath = null) { @@ -314,7 +331,7 @@ public static Map SSPM(string path) } catch (Exception exception) { - ToastNotification.Notify($"SSPM file corrupted", 2); + _ = ToastNotification.Notify($"SSPM file corrupted", 2); Logger.Error(exception); throw; } @@ -604,42 +621,41 @@ private static Map sspmV2(FileParser file, string path = null) return map; } - public static Map PHXM(string path) + public static Map PHXMFolder(string path) { Map map; try { - var file = ZipFile.OpenRead(path); + GD.Print($"{path}/metadata.json"); + string metadataString = File.ReadAllText($"{path}/metadata.json"); + var metadata = (Dictionary)Json.ParseString(metadataString); + + byte[] objectsBuffer = File.ReadAllBytes($"{path}/objects.phxmo"); - byte[] metaBuffer = getZipEntryBuffer(file, "metadata.json"); - byte[] objectsBuffer = getZipEntryBuffer(file, "objects.phxmo"); byte[] audioBuffer = null; byte[] coverBuffer = null; byte[] videoBuffer = null; - var metadata = (Dictionary)Json.ParseString(Encoding.UTF8.GetString(metaBuffer)); FileParser objects = new(objectsBuffer); if ((bool)metadata["HasAudio"]) { - audioBuffer = getZipEntryBuffer(file, $"audio.{metadata["AudioExt"]}"); + audioBuffer = File.ReadAllBytes($"{path}/audio.{metadata["AudioExt"]}"); } if ((bool)metadata["HasCover"]) { - coverBuffer = getZipEntryBuffer(file, "cover.png"); + coverBuffer = File.ReadAllBytes($"{path}/cover.png"); } if ((bool)metadata["HasVideo"]) { - videoBuffer = getZipEntryBuffer(file, "video.mp4"); + videoBuffer = File.ReadAllBytes($"{path}/video.mp4"); } var notes = DecodePHXMO(objectsBuffer); - file.Dispose(); - // temp metadata.TryGetValue("ArtistLink", out Variant artistLink); metadata.TryGetValue("ArtistPlatform", out Variant artistPlatform); @@ -665,14 +681,92 @@ public static Map PHXM(string path) } catch (Exception exception) { - ToastNotification.Notify($"PHXM file corrupted", 2); + _ = ToastNotification.Notify($"PHXM folder corrupted", 2); Logger.Error(exception); throw; } + GD.Print(map.Title); + return map; } + public static Map PHXM(string path) + { + + string mapDirectory = $"{Constants.USER_FOLDER}/maps"; + + // try + // { + // var file = ZipFile.OpenRead(path); + + // byte[] metaBuffer = getZipEntryBuffer(file, "metadata.json"); + // byte[] objectsBuffer = getZipEntryBuffer(file, "objects.phxmo"); + // byte[] audioBuffer = null; + // byte[] coverBuffer = null; + // byte[] videoBuffer = null; + + // var metadata = (Dictionary)Json.ParseString(Encoding.UTF8.GetString(metaBuffer)); + // FileParser objects = new(objectsBuffer); + + // if ((bool)metadata["HasAudio"]) + // { + // audioBuffer = getZipEntryBuffer(file, $"audio.{metadata["AudioExt"]}"); + // } + + // if ((bool)metadata["HasCover"]) + // { + // coverBuffer = getZipEntryBuffer(file, "cover.png"); + // } + + // if ((bool)metadata["HasVideo"]) + // { + // videoBuffer = getZipEntryBuffer(file, "video.mp4"); + // } + + // var notes = DecodePHXMO(objectsBuffer); + + // file.Dispose(); + + // // temp + // metadata.TryGetValue("ArtistLink", out Variant artistLink); + // metadata.TryGetValue("ArtistPlatform", out Variant artistPlatform); + + // map = new( + // path, + // notes, + // (string)metadata["ID"], + // (string)metadata["Artist"], + // (string)metadata["Title"], + // 0, + // (string[])metadata["Mappers"], + // (int)metadata["Difficulty"], + // (string)metadata["DifficultyName"], + // (int)metadata["Length"], + // audioBuffer, + // coverBuffer, + // videoBuffer, + // false, + // (string)artistLink ?? "", + // (string)artistPlatform ?? "" + // ); + // } + // catch (Exception exception) + // { + // ToastNotification.Notify($"PHXM file corrupted", 2); + // Logger.Error(exception); + // throw; + // } + + string extractedFolderName = Path.GetFileNameWithoutExtension(path); + string extractedFolderPath = Path.Combine(mapDirectory, extractedFolderName); + + ZipFile.ExtractToDirectory(path, extractedFolderPath); + File.Delete(path); + + return PHXMFolder(extractedFolderPath); + } + public static Note[] DecodePHXMO(string path) { FileParser objects = new(path); From f00c7f0f2cc7ea7b8f94c604f1377599c688dbeb Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 23 Jun 2026 22:52:12 -0400 Subject: [PATCH 11/38] fix .phxm extract --- scripts/map/MapCache.cs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 7f4e5df8..480f79ba 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -46,6 +46,7 @@ public static void Load(bool fullSync) if (fullSync) { + GD.Print("full"); syncFiles(toParseMaps); addNonCachedFiles(toParseMaps); @@ -65,6 +66,7 @@ public static void Load(bool fullSync) private static void syncFiles(string[] toParseMaps) { var maps = FetchAll(); + GD.Print("fetched"); FilesToSync.Value = maps.Count; FilesSynced.Value = 0; @@ -78,19 +80,27 @@ private static void syncFiles(string[] toParseMaps) foreach (var map in maps) { + GD.Print($"mapdb = {map.Title}"); + string mapPath = BackSlashToForwardSlash(map.FolderPath); + GD.Print($"HASHSET: {mapsHashSet}, {mapPath}"); + // Checks if the map is actually inside the maps folder if (mapsHashSet.Contains(mapPath)) { + GD.Print("1"); string checksum = GetMd5Checksum(mapPath); + GD.Print($"2: {mapPath}"); DateTime metadataModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "metadata.json")); DateTime objectModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "objects.phxmo")); + GD.Print("3"); GD.Print($"{Path.Combine(mapPath, "metadata.json")} = {metadataModifiedDate}"); bool metadataCheck = metadataModifiedDate == map.LastModifiedMetadata; bool objectsCheck = objectModifiedDate == map.LastModifiedNotes; + GD.Print("4"); if (map.MetadataObjectHash == checksum || metadataCheck || objectsCheck) { @@ -98,12 +108,16 @@ private static void syncFiles(string[] toParseMaps) FilesSynced.Value += 1; continue; } + GD.Print("5"); Map newMap; + GD.Print("dfdsjlkfdjsf"); + try { newMap = MapParser.Decode(mapPath, null, false, true); + GD.Print($"NEW MAPTITLE: {newMap.Title}"); } catch (Exception ex) { @@ -137,14 +151,13 @@ private static void syncFiles(string[] toParseMaps) else { // removeCacheFolder(map); - try + GD.Print("MAP NOT FOUND!"); + + if (Directory.Exists($"{MapUtil.MapsFolder}/{map.Name}")) { Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); } - catch - { - return; - } + DatabaseService.Connection.Delete(map); Logger.Log($"Removed {mapPath} from the cache, as it no longer exists."); @@ -229,11 +242,15 @@ private static void addNonCachedFiles(string[] toParseMaps) try { + GD.Print("new map!"); var map = MapParser.Decode(toParseMap); + GD.Print($"map decoded!: {map.Name}"); // var map = !Directory.Exists(file) ? MapParser.Decode(file) : MapParser.DecodeFolder(file); map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; + GD.Print($"folder pathed! hashing: {toParseMap}"); // map.FilePath = !Directory.Exists(map.FilePath) ? $"{Constants.USER_FOLDER}/maps/{map.Name}.{Constants.DEFAULT_MAP_EXT}" : $"{Constants.USER_FOLDER}/maps/{map.Name}"; - map.MetadataObjectHash = GetMd5Checksum(toParseMap); + map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); + GD.Print("inserting"); InsertMap(map); } catch @@ -248,9 +265,12 @@ private static void addNonCachedFiles(string[] toParseMaps) public static int InsertMap(Map map) { + GD.Print("insert received!"); var existing = DatabaseService.Connection.Find(x => x.MetadataObjectHash == map.MetadataObjectHash); var updated = DatabaseService.Connection.Find(x => x.Name == map.Name); + GD.Print($"existing: {existing}, updated: {updated}"); + try { if (updated != null && existing != null) @@ -389,9 +409,13 @@ public static void OrderAndSetMaps() public static string GetMd5Checksum(string path) { + GD.Print($"hi from hash! path: {path}"); string metadataPath = Path.Combine(path, "metadata.json"); + GD.Print("meta hash!"); string objectsPath = Path.Combine(path, "objects.phxmo"); + GD.Print("objects hash!"); byte[] hash = Misc.HashFiles([metadataPath, objectsPath]); + GD.Print("returning hash!"); return BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); From c85a6da94434f1eda38d5f6637f0522da164ae41 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 23 Jun 2026 22:52:32 -0400 Subject: [PATCH 12/38] more debug YAY!!!! --- scripts/map/MapParser.cs | 6 ++++-- scripts/util/Misc.cs | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 572ef7b9..5b91a12e 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -26,6 +26,9 @@ public override void _Ready() public static async Task BulkImport(string[] files, bool notify = false) { + + GD.Print("HELLO FROM BULK!"); + if (files.Length == 0 || files == null) return; if (notify) _ = ToastNotification.Notify($"Importing {files.Length} map(s)"); @@ -627,7 +630,6 @@ public static Map PHXMFolder(string path) try { - GD.Print($"{path}/metadata.json"); string metadataString = File.ReadAllText($"{path}/metadata.json"); var metadata = (Dictionary)Json.ParseString(metadataString); @@ -686,7 +688,7 @@ public static Map PHXMFolder(string path) throw; } - GD.Print(map.Title); + GD.Print($"HI FROM DECODER! Heres the name: {map.Name}"); return map; } diff --git a/scripts/util/Misc.cs b/scripts/util/Misc.cs index 510bfa2c..d8602b2a 100644 --- a/scripts/util/Misc.cs +++ b/scripts/util/Misc.cs @@ -67,16 +67,29 @@ public static void CopyProperties(Node node, Node reference) public static byte[] HashFiles(string[] paths) { + GD.Print("hi from hashfiles"); using var md5 = MD5.Create(); + GD.Print($"created hash, heres the paths! {paths[0]}"); - foreach (var path in paths) // we do not need to order the paths since it will always be the same -fog + foreach (string path in paths) // we do not need to order the paths since it will always be the same -fog { + GD.Print($"HASH PRINT!: {path}"); + GD.Print($"Exists: {File.Exists(path)}"); + + var info = new FileInfo(path); + GD.Print($"Length: {info.Length}"); byte[] fileData = File.ReadAllBytes(path); + GD.Print($"Read {fileData.Length} bytes"); md5.TransformBlock(fileData, 0, fileData.Length, null, 0); + GD.Print("Transformed"); } + GD.Print("final hash"); + md5.TransformFinalBlock(Array.Empty(), 0 ,0); + GD.Print("returning final hash"); + return md5.Hash; } From bfd70207b42c2efb87f6deea5dcdded13713c435 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Thu, 25 Jun 2026 06:01:53 -0400 Subject: [PATCH 13/38] fix --- scripts/map/MapManager.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/map/MapManager.cs b/scripts/map/MapManager.cs index 6d5c0d5e..e9986566 100644 --- a/scripts/map/MapManager.cs +++ b/scripts/map/MapManager.cs @@ -39,9 +39,14 @@ public static void Select(Map map) Selected.Value = GetMapById(map.Id); } + // public static Map GetMapById(int id) + // { + // return Maps.Where(x => x.Id == id).First(); + // } + public static Map GetMapById(int id) { - return Maps.Where(x => x.Id == id).First(); + return Maps.FirstOrDefault(x => x.Id == id); } public static void Update(Map map) From a79487a8dc4968dd25531bef283e135e31272fa4 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Fri, 26 Jun 2026 00:44:32 -0400 Subject: [PATCH 14/38] yeah! --- scripts/map/Map.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs index 118b97a0..afbb3638 100644 --- a/scripts/map/Map.cs +++ b/scripts/map/Map.cs @@ -17,8 +17,8 @@ public partial class Map : RefCounted public int Id { get; set; } public string Name { get; set; } = string.Empty; - public DateTime LastModifiedMetadata { get; set; } - public DateTime LastModifiedNotes { get; set; } + public string LastModifiedMetadata { get; set; } + public string LastModifiedNotes { get; set; } /// /// The hash of the metadata.json, then the objects.phxmo in order @@ -120,10 +120,13 @@ private Texture2D getCover() public Map() { } - public Map(string folderPath, Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") + public Map(string folderPath, string metadataObjHash = "", string lastModifiedMetadata = "", string lastModifiedNotes = "", Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") { FolderPath = folderPath; Ephemeral = ephemeral; + MetadataObjectHash = metadataObjHash; + LastModifiedMetadata = lastModifiedMetadata; + LastModifiedNotes = lastModifiedNotes; Artist = (artist ?? "").StripEscapes(); ArtistLink = artistLink; ArtistPlatform = artistPlatform; From 775379e024c945385b2893b1179103d0e2bbbe5c Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Fri, 26 Jun 2026 00:45:24 -0400 Subject: [PATCH 15/38] small optimization --- scripts/map/MapCache.cs | 60 +++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 480f79ba..ccbe4d4b 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.IO; using System.IO.Compression; @@ -46,7 +47,6 @@ public static void Load(bool fullSync) if (fullSync) { - GD.Print("full"); syncFiles(toParseMaps); addNonCachedFiles(toParseMaps); @@ -66,7 +66,6 @@ public static void Load(bool fullSync) private static void syncFiles(string[] toParseMaps) { var maps = FetchAll(); - GD.Print("fetched"); FilesToSync.Value = maps.Count; FilesSynced.Value = 0; @@ -80,44 +79,49 @@ private static void syncFiles(string[] toParseMaps) foreach (var map in maps) { - GD.Print($"mapdb = {map.Title}"); string mapPath = BackSlashToForwardSlash(map.FolderPath); - GD.Print($"HASHSET: {mapsHashSet}, {mapPath}"); - // Checks if the map is actually inside the maps folder if (mapsHashSet.Contains(mapPath)) { - GD.Print("1"); - string checksum = GetMd5Checksum(mapPath); - GD.Print($"2: {mapPath}"); DateTime metadataModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "metadata.json")); DateTime objectModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "objects.phxmo")); - GD.Print("3"); - GD.Print($"{Path.Combine(mapPath, "metadata.json")} = {metadataModifiedDate}"); + // i have to convert to string since sqlite doesnt support DateTime c# conversion + // PLUS, theres like seconds or something and it doesnt catch that soooooo + string metadataResult = metadataModifiedDate.ToString(); + string notesResult = objectModifiedDate.ToString(); + + bool metadataCheck = map.LastModifiedMetadata == metadataResult; + bool objectsCheck = map.LastModifiedNotes == notesResult; - bool metadataCheck = metadataModifiedDate == map.LastModifiedMetadata; - bool objectsCheck = objectModifiedDate == map.LastModifiedNotes; - GD.Print("4"); + // GD.Print($"{Path.Combine(mapPath, "metadata.json")} = {map.LastModifiedMetadata},{metadataCheck}"); + // GD.Print($"{Path.Combine(mapPath, "metadata.json")} = {metadataResult},{objectsCheck}"); - if (map.MetadataObjectHash == checksum || metadataCheck || objectsCheck) + // last modified is faster and lowkey more important -fog + if (metadataCheck || objectsCheck) { GD.Print("skip"); - FilesSynced.Value += 1; + FilesSynced.Value++; continue; } - GD.Print("5"); - Map newMap; + // we will do checksum checking after if last modified dates dont match + // this code shouldn't be reached unless the dates dont match + string checksum = GetMd5Checksum(mapPath); + if (map.MetadataObjectHash == checksum) + { + GD.Print("skip, but with hash"); + FilesSynced.Value++; + continue; + } - GD.Print("dfdsjlkfdjsf"); + Map newMap; try { newMap = MapParser.Decode(mapPath, null, false, true); - GD.Print($"NEW MAPTITLE: {newMap.Title}"); } catch (Exception ex) { @@ -136,8 +140,8 @@ private static void syncFiles(string[] toParseMaps) continue; } - newMap.LastModifiedMetadata = metadataModifiedDate; - newMap.LastModifiedNotes = objectModifiedDate; + newMap.LastModifiedMetadata = metadataModifiedDate.ToString(); + newMap.LastModifiedNotes = objectModifiedDate.ToString(); newMap.Id = map.Id; newMap.MetadataObjectHash = checksum; @@ -150,9 +154,6 @@ private static void syncFiles(string[] toParseMaps) } else { - // removeCacheFolder(map); - GD.Print("MAP NOT FOUND!"); - if (Directory.Exists($"{MapUtil.MapsFolder}/{map.Name}")) { Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); @@ -242,15 +243,11 @@ private static void addNonCachedFiles(string[] toParseMaps) try { - GD.Print("new map!"); var map = MapParser.Decode(toParseMap); - GD.Print($"map decoded!: {map.Name}"); // var map = !Directory.Exists(file) ? MapParser.Decode(file) : MapParser.DecodeFolder(file); map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; - GD.Print($"folder pathed! hashing: {toParseMap}"); // map.FilePath = !Directory.Exists(map.FilePath) ? $"{Constants.USER_FOLDER}/maps/{map.Name}.{Constants.DEFAULT_MAP_EXT}" : $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); - GD.Print("inserting"); InsertMap(map); } catch @@ -265,12 +262,9 @@ private static void addNonCachedFiles(string[] toParseMaps) public static int InsertMap(Map map) { - GD.Print("insert received!"); var existing = DatabaseService.Connection.Find(x => x.MetadataObjectHash == map.MetadataObjectHash); var updated = DatabaseService.Connection.Find(x => x.Name == map.Name); - GD.Print($"existing: {existing}, updated: {updated}"); - try { if (updated != null && existing != null) @@ -409,13 +403,9 @@ public static void OrderAndSetMaps() public static string GetMd5Checksum(string path) { - GD.Print($"hi from hash! path: {path}"); string metadataPath = Path.Combine(path, "metadata.json"); - GD.Print("meta hash!"); string objectsPath = Path.Combine(path, "objects.phxmo"); - GD.Print("objects hash!"); byte[] hash = Misc.HashFiles([metadataPath, objectsPath]); - GD.Print("returning hash!"); return BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); From f88717bc64d346c984c500a81f4b5dce2a6cfba5 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Fri, 26 Jun 2026 00:45:53 -0400 Subject: [PATCH 16/38] cleanup + fix --- scripts/map/MapParser.cs | 94 +++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 5b91a12e..1580425f 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -26,9 +26,6 @@ public override void _Ready() public static async Task BulkImport(string[] files, bool notify = false) { - - GD.Print("HELLO FROM BULK!"); - if (files.Length == 0 || files == null) return; if (notify) _ = ToastNotification.Notify($"Importing {files.Length} map(s)"); @@ -155,38 +152,40 @@ public static void Encode(Map map, bool logBenchmark = false) File.WriteAllText(Path.Combine(mapFolderPath, "metadata.json"), map.EncodeMeta()); using var stream = File.Create(Path.Combine(mapFolderPath, "objects.phxmo")); - using BinaryWriter bw = new BinaryWriter(stream); - - bw.Write((uint)12); - bw.Write((uint)map.Notes.Length); - foreach (var note in map.Notes) + // using BinaryWriter bw = new BinaryWriter(stream); + using (var bw = new BinaryWriter(stream)) { - bool quantum = (int)note.X != note.X || (int)note.Y != note.Y || note.X < -1 || note.X > 1 || note.Y < -1 || note.Y > 1; - bw.Write((uint)note.Millisecond); - bw.Write(Convert.ToByte(quantum)); - if (quantum) - { - bw.Write((float)note.X); - bw.Write((float)note.Y); - } - else - { - bw.Write((byte)(note.X + 1)); - bw.Write((byte)(note.Y + 1)); + bw.Write((uint)12); + bw.Write((uint)map.Notes.Length); + foreach (var note in map.Notes) + { + bool quantum = (int)note.X != note.X || (int)note.Y != note.Y || note.X < -1 || note.X > 1 || note.Y < -1 || note.Y > 1; + bw.Write((uint)note.Millisecond); + bw.Write(Convert.ToByte(quantum)); + if (quantum) + { + bw.Write((float)note.X); + bw.Write((float)note.Y); + } + else + { + bw.Write((byte)(note.X + 1)); + bw.Write((byte)(note.Y + 1)); + } } - } - bw.Write(0); // timing point count - bw.Write(0); // brightness count - bw.Write(0); // contrast count - bw.Write(0); // saturation count - bw.Write(0); // blur count - bw.Write(0); // fov count - bw.Write(0); // tint count - bw.Write(0); // position count - bw.Write(0); // rotation count - bw.Write(0); // ar factor count - bw.Write(0); // text count + bw.Write(0); // timing point count + bw.Write(0); // brightness count + bw.Write(0); // contrast count + bw.Write(0); // saturation count + bw.Write(0); // blur count + bw.Write(0); // fov count + bw.Write(0); // tint count + bw.Write(0); // position count + bw.Write(0); // rotation count + bw.Write(0); // ar factor count + bw.Write(0); // text count + } void addAsset(string name, byte[] buffer) { @@ -206,8 +205,11 @@ void addAsset(string name, byte[] buffer) map.MetadataObjectHash = BitConverter.ToString(hash).Replace("-", "").ToLower(); - map.LastModifiedMetadata = File.GetLastWriteTime(Path.Combine(mapFolderPath, "metadata.json")); - map.LastModifiedNotes = File.GetLastWriteTime(Path.Combine(mapFolderPath, "objects.phxmo")); + + DateTime metadataModified = File.GetLastWriteTime(Path.Combine(mapFolderPath, "metadata.json")); + DateTime objectsModified = File.GetLastWriteTime(Path.Combine(mapFolderPath, "objects.phxmo")); + map.LastModifiedMetadata = metadataModified.ToString(); + map.LastModifiedNotes = objectsModified.ToString(); map.FolderPath = mapFolderPath; // need to do map caching stuff here @@ -290,7 +292,7 @@ public static Map SSMapV1(string path, string audioPath = null) audio.Close(); } - map = new(path, notes, null, "", name, audioBuffer: audioBuffer); + map = new(path, "", "", "", notes, null, "", name, audioBuffer: audioBuffer); } catch (Exception exception) { @@ -458,7 +460,7 @@ private static Map sspmV1(FileParser file, string path = null) notes[i].Index = i; } - map = new(path ?? $"{Constants.USER_FOLDER}/maps/{song}_temp.sspm", notes, id, artist, song, 0, mappers, difficulty, null, (int)mapLength, audioBuffer, coverBuffer); + map = new(path ?? $"{Constants.USER_FOLDER}/maps/{song}_temp.sspm", "", "", "", notes, id, artist, song, 0, mappers, difficulty, null, (int)mapLength, audioBuffer, coverBuffer); } catch (Exception exception) { @@ -612,7 +614,7 @@ private static Map sspmV2(FileParser file, string path = null) notes[i].Index = i; } - map = new(path, notes, id, artist, song, 0, mappers, difficulty, difficultyName, (int)mapLength, audioBuffer, coverBuffer); + map = new(path, "", "", "", notes, id, artist, song, 0, mappers, difficulty, difficultyName, (int)mapLength, audioBuffer, coverBuffer); } catch (Exception exception) { @@ -639,7 +641,7 @@ public static Map PHXMFolder(string path) byte[] coverBuffer = null; byte[] videoBuffer = null; - FileParser objects = new(objectsBuffer); + // FileParser objects = new(objectsBuffer); if ((bool)metadata["HasAudio"]) { @@ -662,8 +664,19 @@ public static Map PHXMFolder(string path) metadata.TryGetValue("ArtistLink", out Variant artistLink); metadata.TryGetValue("ArtistPlatform", out Variant artistPlatform); + + + byte[] hash = Misc.HashFiles([Path.Combine(path, "metadata.json"), Path.Combine(path, "objects.phxmo")]); + + DateTime metadataModified = File.GetLastWriteTime(Path.Combine(path, "metadata.json")); + DateTime objectsModified = File.GetLastWriteTime(Path.Combine(path, "objects.phxmo")); + + map = new( path, + BitConverter.ToString(hash).Replace("-", "").ToLower(), + metadataModified.ToString(), + objectsModified.ToString(), notes, (string)metadata["ID"], (string)metadata["Artist"], @@ -687,8 +700,6 @@ public static Map PHXMFolder(string path) Logger.Error(exception); throw; } - - GD.Print($"HI FROM DECODER! Heres the name: {map.Name}"); return map; } @@ -856,6 +867,9 @@ public static Map RHM(string path) map = new( path, + "", + "", + "", notes, null, artist ?? "", From e60c1aa0f5134e0f42089d5faf5057815df80bee Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Fri, 26 Jun 2026 00:46:05 -0400 Subject: [PATCH 17/38] cleanupppppp --- scripts/map/MapManager.cs | 6 +----- scripts/util/Misc.cs | 13 ------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/scripts/map/MapManager.cs b/scripts/map/MapManager.cs index e9986566..7f09461c 100644 --- a/scripts/map/MapManager.cs +++ b/scripts/map/MapManager.cs @@ -39,13 +39,9 @@ public static void Select(Map map) Selected.Value = GetMapById(map.Id); } - // public static Map GetMapById(int id) - // { - // return Maps.Where(x => x.Id == id).First(); - // } - public static Map GetMapById(int id) { + // return Maps.Where(x => x.Id == id).First(); return Maps.FirstOrDefault(x => x.Id == id); } diff --git a/scripts/util/Misc.cs b/scripts/util/Misc.cs index d8602b2a..3f882c06 100644 --- a/scripts/util/Misc.cs +++ b/scripts/util/Misc.cs @@ -67,29 +67,16 @@ public static void CopyProperties(Node node, Node reference) public static byte[] HashFiles(string[] paths) { - GD.Print("hi from hashfiles"); using var md5 = MD5.Create(); - GD.Print($"created hash, heres the paths! {paths[0]}"); foreach (string path in paths) // we do not need to order the paths since it will always be the same -fog { - GD.Print($"HASH PRINT!: {path}"); - GD.Print($"Exists: {File.Exists(path)}"); - - var info = new FileInfo(path); - GD.Print($"Length: {info.Length}"); byte[] fileData = File.ReadAllBytes(path); - GD.Print($"Read {fileData.Length} bytes"); md5.TransformBlock(fileData, 0, fileData.Length, null, 0); - GD.Print("Transformed"); } - GD.Print("final hash"); - md5.TransformFinalBlock(Array.Empty(), 0 ,0); - GD.Print("returning final hash"); - return md5.Hash; } From f036bdcce5637a77efb177e5df4f780b481c9d36 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Sun, 28 Jun 2026 02:07:42 -0400 Subject: [PATCH 18/38] its as shrimple as that --- scripts/map/MapParser.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 1580425f..cc760637 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -214,6 +214,8 @@ void addAsset(string name, byte[] buffer) map.FolderPath = mapFolderPath; // need to do map caching stuff here + MapCache.InsertMap(map); + if (logBenchmark) { Logger.Log($"ENCODING {Constants.DEFAULT_MAP_EXT.ToUpper()}: {(Time.GetTicksUsec() - start) / 1000}ms"); @@ -260,8 +262,8 @@ public static Map Decode(string path, string audio = null, bool logBenchmark = f } else { - _ = ToastNotification.Notify($"Invalid file path", 2); - throw Logger.Error($"Invalid file path ({path})"); + _ = ToastNotification.Notify($"Invalid map path", 2); + throw Logger.Error($"Invalid map path ({path})"); } } public static Map SSMapV1(string path, string audioPath = null) From 16d8de8b17fa5c872516f9c29052814a89c9aad0 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Sun, 28 Jun 2026 02:07:50 -0400 Subject: [PATCH 19/38] djfodsjfoisdfjhiosfjhoisdf --- scripts/map/MapCache.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index ccbe4d4b..58bd0a40 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -354,7 +354,6 @@ public static void OrderAndSetMaps() } }).CallDeferred(); } - } } }); From 3a1df8b004c49653b509030360913c960e82343c Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Sun, 28 Jun 2026 03:40:04 -0400 Subject: [PATCH 20/38] cleanup + fix loading --- scripts/map/MapCache.cs | 44 ++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 58bd0a40..b5f2ba04 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -79,7 +79,7 @@ private static void syncFiles(string[] toParseMaps) foreach (var map in maps) { - + string mapPath = BackSlashToForwardSlash(map.FolderPath); // Checks if the map is actually inside the maps folder @@ -96,13 +96,9 @@ private static void syncFiles(string[] toParseMaps) bool metadataCheck = map.LastModifiedMetadata == metadataResult; bool objectsCheck = map.LastModifiedNotes == notesResult; - // GD.Print($"{Path.Combine(mapPath, "metadata.json")} = {map.LastModifiedMetadata},{metadataCheck}"); - // GD.Print($"{Path.Combine(mapPath, "metadata.json")} = {metadataResult},{objectsCheck}"); - // last modified is faster and lowkey more important -fog if (metadataCheck || objectsCheck) { - GD.Print("skip"); FilesSynced.Value++; continue; } @@ -112,7 +108,6 @@ private static void syncFiles(string[] toParseMaps) string checksum = GetMd5Checksum(mapPath); if (map.MetadataObjectHash == checksum) { - GD.Print("skip, but with hash"); FilesSynced.Value++; continue; } @@ -136,7 +131,7 @@ private static void syncFiles(string[] toParseMaps) } DatabaseService.Connection.Delete(map); - FilesSynced.Value += 1; + FilesSynced.Value++; continue; } @@ -149,7 +144,7 @@ private static void syncFiles(string[] toParseMaps) DatabaseService.Connection.Update(newMap); // InsertIntoMapCacheFolder(map); Logger.Log($"Updated cached map: {newMap.Name}"); - FilesSynced.Value += 1; + FilesSynced.Value++; continue; } else @@ -232,6 +227,8 @@ private static void addNonCachedFiles(string[] toParseMaps) HashSet hashSet = new(); maps.ForEach(map => hashSet.Add(map.FolderPath)); + FilesToSync.Value = toParseMaps.Count() - maps.Count(); + foreach (string toParseMap in toParseMaps) { if (hashSet.Contains(BackSlashToForwardSlash(toParseMap))) @@ -239,14 +236,12 @@ private static void addNonCachedFiles(string[] toParseMaps) continue; } - FilesToSync.Value += 1; + // FilesToSync.Value += 1; try { var map = MapParser.Decode(toParseMap); - // var map = !Directory.Exists(file) ? MapParser.Decode(file) : MapParser.DecodeFolder(file); map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; - // map.FilePath = !Directory.Exists(map.FilePath) ? $"{Constants.USER_FOLDER}/maps/{map.Name}.{Constants.DEFAULT_MAP_EXT}" : $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); InsertMap(map); } @@ -417,6 +412,33 @@ public static string GetMd5Checksum(string path) // } } + // public static int GetMapCount(List maps, string[] mapFiles) + // { + // int map_count = 0; + + // HashSet hashSet = new(); + // maps.ForEach(map => hashSet.Add(map.FolderPath)); + + + + // foreach (string map_entry in mapFiles) + // { + // if (File.Exists(map_entry)) + // { + // map_count++; + // } + // else if (Directory.Exists(map_entry)) + // { + // if (hashSet.Contains(BackSlashToForwardSlash($"{MapUtil.MapsFolder}/{map_entry}"))) + // { + // map_count++; + // } + // } + // } + + // return map_count; + // } + public static List FetchAll() => DatabaseService.Connection.Table().ToList(); public static string BackSlashToForwardSlash(string path) => path.Replace("\\", "/"); From c9f4b6bc84d30c4496ea8032fae4692545981f04 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Sun, 28 Jun 2026 04:12:07 -0400 Subject: [PATCH 21/38] more cleanup --- scripts/map/MapCache.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index b5f2ba04..ee72206e 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -79,7 +79,7 @@ private static void syncFiles(string[] toParseMaps) foreach (var map in maps) { - + string mapPath = BackSlashToForwardSlash(map.FolderPath); // Checks if the map is actually inside the maps folder @@ -157,7 +157,7 @@ private static void syncFiles(string[] toParseMaps) DatabaseService.Connection.Delete(map); Logger.Log($"Removed {mapPath} from the cache, as it no longer exists."); - FilesSynced.Value += 1; + FilesSynced.Value++; } } } @@ -251,7 +251,7 @@ private static void addNonCachedFiles(string[] toParseMaps) Logger.Log($"Failed to add map non-cached map"); } - FilesSynced.Value += 1; + FilesSynced.Value++; } } From db3954661f94a8a09cfc73ffabb8cef9e8ec14e5 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Sun, 28 Jun 2026 12:54:25 -0400 Subject: [PATCH 22/38] fix replace map bug --- scripts/map/MapCache.cs | 106 ++++----------------------------------- scripts/map/MapParser.cs | 8 +++ 2 files changed, 18 insertions(+), 96 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index ee72206e..cba136b7 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -39,9 +39,13 @@ public static void Load(bool fullSync) // .ToList(); // Map files go first since they will be encoded to folders after they get parsed in MapParser.cs - List mapsList = Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories) - .Concat(Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories)) - .ToList(); + List mapsList = Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories) + .Concat(Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories)) + .ToList(); + + // List mapsList = Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories) + // .Concat(Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories)) + // .ToList(); string[] toParseMaps = mapsList.ToArray(); @@ -162,64 +166,6 @@ private static void syncFiles(string[] toParseMaps) } } - // public static void InsertIntoMapCacheFolder(Map map) - // { - // string path = $"{MapUtil.MapsCacheFolder}/{map.Name}"; - - // // for phxm shit i guess - // if (File.Exists(map.FolderPath)) - // { - // using var stream = File.OpenRead(map.FolderPath); - // var archive = new ZipArchive(stream); - - // if (Directory.Exists(path)) - // { - // Directory.Delete(path, true); - // } - - // archive.ExtractToDirectory(path, true); - // } - // else if (Directory.Exists(map.FolderPath)) - // { - // GD.Print("PATH PATH PATH!!!"); - // if (Directory.Exists(path)) - // { - // Directory.Delete(path, true); - // } - - // Directory.CreateDirectory(path); - - // foreach (string file in Directory.GetFiles(map.FolderPath)) - // { - // string destFile = Path.Combine(path, Path.GetFileName(file)); - // File.Copy(file, destFile, overwrite: true); - // } - // } - - // // using var stream = File.OpenRead(map.FilePath); - // // var archive = new ZipArchive(stream); - - // // if (Directory.Exists(path)) - // // { - // // Directory.Delete(path, true); - // // } - - // // archive.ExtractToDirectory(path, true); - - // } - - // private static void removeCacheFolder(Map map) - // { - // try - // { - // Directory.Delete($"{MapUtil.MapsCacheFolder}/{map.Name}", true); - // } - // catch - // { - // return; - // } - // } - private static void addNonCachedFiles(string[] toParseMaps) { var maps = FetchAll(); @@ -227,7 +173,9 @@ private static void addNonCachedFiles(string[] toParseMaps) HashSet hashSet = new(); maps.ForEach(map => hashSet.Add(map.FolderPath)); + // Maps that need to be parsed - maps in database cache FilesToSync.Value = toParseMaps.Count() - maps.Count(); + FilesSynced.Value = 0; foreach (string toParseMap in toParseMaps) { @@ -240,6 +188,7 @@ private static void addNonCachedFiles(string[] toParseMaps) try { + GD.Print($"decoding: {toParseMap}\nfilestosync: {FilesToSync.Value}, filessynced: {FilesSynced.Value}"); var map = MapParser.Decode(toParseMap); map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); @@ -402,43 +351,8 @@ public static string GetMd5Checksum(string path) byte[] hash = Misc.HashFiles([metadataPath, objectsPath]); return BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); - - // using (var md5 = MD5.Create()) - // { - // using (var stream = File.OpenRead(path)) - // { - // return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty).ToLower(); - // } - // } } - // public static int GetMapCount(List maps, string[] mapFiles) - // { - // int map_count = 0; - - // HashSet hashSet = new(); - // maps.ForEach(map => hashSet.Add(map.FolderPath)); - - - - // foreach (string map_entry in mapFiles) - // { - // if (File.Exists(map_entry)) - // { - // map_count++; - // } - // else if (Directory.Exists(map_entry)) - // { - // if (hashSet.Contains(BackSlashToForwardSlash($"{MapUtil.MapsFolder}/{map_entry}"))) - // { - // map_count++; - // } - // } - // } - - // return map_count; - // } - public static List FetchAll() => DatabaseService.Connection.Table().ToList(); public static string BackSlashToForwardSlash(string path) => path.Replace("\\", "/"); diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index cc760637..06854e67 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -630,6 +630,7 @@ private static Map sspmV2(FileParser file, string path = null) public static Map PHXMFolder(string path) { + Map map; try @@ -776,6 +777,13 @@ public static Map PHXM(string path) string extractedFolderName = Path.GetFileNameWithoutExtension(path); string extractedFolderPath = Path.Combine(mapDirectory, extractedFolderName); + if (Directory.Exists(extractedFolderPath)) + { + Directory.Delete(extractedFolderPath, true); // true = recursive + Map existingMap = DatabaseService.Connection.Table().FirstOrDefault(x => x.FolderPath == extractedFolderPath); + MapCache.RemoveMap(existingMap); + } + ZipFile.ExtractToDirectory(path, extractedFolderPath); File.Delete(path); From 8688ebf788de1cc51073e6513a77ec36bb5b08eb Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Sun, 28 Jun 2026 13:06:17 -0400 Subject: [PATCH 23/38] fix replays --- scripts/game/managers/ReplayManager.cs | 2 +- scripts/map/Replay.cs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/game/managers/ReplayManager.cs b/scripts/game/managers/ReplayManager.cs index 631e5332..ae3d0269 100644 --- a/scripts/game/managers/ReplayManager.cs +++ b/scripts/game/managers/ReplayManager.cs @@ -73,7 +73,7 @@ public void NewReplay(Attempt attempt) string serializedMods = string.Join("_", mods); // string mapName = attempt.Map.FilePath.GetFile().GetBaseName(); - string mapName = Path.GetDirectoryName(attempt.Map.FolderPath); + string mapName = Path.GetFileName(attempt.Map.FolderPath); string player = "You"; void storeSizedString(string data) diff --git a/scripts/map/Replay.cs b/scripts/map/Replay.cs index a2764ed6..4e180900 100644 --- a/scripts/map/Replay.cs +++ b/scripts/map/Replay.cs @@ -168,13 +168,14 @@ public Replay(string path) MapID = FileBuffer.GetString((int)FileBuffer.GetUInt32()); MapNoteCount = FileBuffer.GetUInt64(); - MapFilePath = $"{Constants.USER_FOLDER}/maps/{MapID}.phxm"; + MapFilePath = $"{Constants.USER_FOLDER}/maps/{MapID}"; + MapFilePath = Path.GetFileNameWithoutExtension(MapFilePath); // just in case it tries to read a .phxm file - if (!File.Exists(MapFilePath)) + if (!Directory.Exists(MapFilePath)) { Valid = false; ToastNotification.Notify("Replay map not found", 2); - Logger.Log($"Replay map not found, path: {MapFilePath}.phxm"); + Logger.Log($"Replay map not found, path: {MapFilePath}"); return; } From 7be1ba736283c22e3fee53247af0618343c4ae35 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 4 Aug 2026 17:53:47 -0400 Subject: [PATCH 24/38] i lied --- prefabs/map_info_container.tscn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prefabs/map_info_container.tscn b/prefabs/map_info_container.tscn index 7dc3c47d..23f39bb9 100644 --- a/prefabs/map_info_container.tscn +++ b/prefabs/map_info_container.tscn @@ -361,7 +361,7 @@ alignment = 2 [node name="Export" type="Button" parent="Info/ScrollContainer/HBoxContainer/Subholder/Buttons" unique_id=2033571562] layout_mode = 2 -tooltip_text = "Export (Shift+Click for .sspm export)" +tooltip_text = "Exports map into a .phxm file to share easily" focus_mode = 0 mouse_default_cursor_shape = 2 theme = ExtResource("4_4d08m") From 2d8e1141a379bed911e4fe0739e5adbe22d1fef0 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 4 Aug 2026 18:02:34 -0400 Subject: [PATCH 25/38] fix map deletion --- scripts/map/MapManager.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/map/MapManager.cs b/scripts/map/MapManager.cs index 7f09461c..d40d235a 100644 --- a/scripts/map/MapManager.cs +++ b/scripts/map/MapManager.cs @@ -97,11 +97,16 @@ public static void Delete(Map map) { try { - File.Delete(map.FolderPath); + Directory.Delete(map.FolderPath, true); + if (!Directory.Exists(map.FolderPath)) + { + Logger.Log($"{map.Title} has been deleted"); + } + } catch { - if (File.Exists(map.FolderPath)) + if (File.Exists(map.FolderPath) || Directory.Exists(map.FolderPath)) { Logger.Error("Unable to delete map"); return; From 9e124b82a2750efaf3978505dfed0e3a08661646 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 4 Aug 2026 18:06:49 -0400 Subject: [PATCH 26/38] fix legacy replays --- scripts/map/Replay.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/map/Replay.cs b/scripts/map/Replay.cs index 4e180900..0b037a00 100644 --- a/scripts/map/Replay.cs +++ b/scripts/map/Replay.cs @@ -169,7 +169,10 @@ public Replay(string path) MapNoteCount = FileBuffer.GetUInt64(); MapFilePath = $"{Constants.USER_FOLDER}/maps/{MapID}"; - MapFilePath = Path.GetFileNameWithoutExtension(MapFilePath); // just in case it tries to read a .phxm file + if (Path.GetExtension(MapFilePath).Equals(".phxm", StringComparison.OrdinalIgnoreCase)) + { + MapFilePath = Path.ChangeExtension(MapFilePath, null); // just in case it tries to read a .phxm file + } if (!Directory.Exists(MapFilePath)) { From 7b56478c7c11219cc05f04697fa04a0e909ff4ac Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 4 Aug 2026 18:13:05 -0400 Subject: [PATCH 27/38] Just in case --- scripts/map/Replay.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/map/Replay.cs b/scripts/map/Replay.cs index 0b037a00..33a659da 100644 --- a/scripts/map/Replay.cs +++ b/scripts/map/Replay.cs @@ -170,8 +170,10 @@ public Replay(string path) MapNoteCount = FileBuffer.GetUInt64(); MapFilePath = $"{Constants.USER_FOLDER}/maps/{MapID}"; if (Path.GetExtension(MapFilePath).Equals(".phxm", StringComparison.OrdinalIgnoreCase)) - { + { + Logger.Log($"Legacy Replay detected: {MapFilePath}"); MapFilePath = Path.ChangeExtension(MapFilePath, null); // just in case it tries to read a .phxm file + } if (!Directory.Exists(MapFilePath)) From 3f2de5cb7f89a70b985c68428d70656c17d0e866 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Wed, 12 Aug 2026 15:09:41 -0400 Subject: [PATCH 28/38] Big cleanup :) --- scripts/SoundManager.cs | 2 - scripts/game/managers/ReplayManager.cs | 2 - scripts/map/Map.cs | 9 ++- scripts/map/MapCache.cs | 53 +--------------- scripts/map/MapParser.cs | 84 +++----------------------- scripts/util/Misc.cs | 1 - 6 files changed, 14 insertions(+), 137 deletions(-) diff --git a/scripts/SoundManager.cs b/scripts/SoundManager.cs index f0ecf4eb..129599b4 100644 --- a/scripts/SoundManager.cs +++ b/scripts/SoundManager.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.IO; using System.Linq; using Godot; diff --git a/scripts/game/managers/ReplayManager.cs b/scripts/game/managers/ReplayManager.cs index ae3d0269..80f7205f 100644 --- a/scripts/game/managers/ReplayManager.cs +++ b/scripts/game/managers/ReplayManager.cs @@ -1,7 +1,5 @@ using System; using System.IO; - -// using System.IO; using System.Linq; using System.Security.Cryptography; using Godot; diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs index afbb3638..5181099d 100644 --- a/scripts/map/Map.cs +++ b/scripts/map/Map.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.IO; using System.Linq; using System.Text; @@ -120,13 +119,13 @@ private Texture2D getCover() public Map() { } - public Map(string folderPath, string metadataObjHash = "", string lastModifiedMetadata = "", string lastModifiedNotes = "", Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") + public Map(string folderPath, Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") { FolderPath = folderPath; Ephemeral = ephemeral; - MetadataObjectHash = metadataObjHash; - LastModifiedMetadata = lastModifiedMetadata; - LastModifiedNotes = lastModifiedNotes; + MetadataObjectHash = ""; + LastModifiedMetadata = ""; + LastModifiedNotes = ""; Artist = (artist ?? "").StripEscapes(); ArtistLink = artistLink; ArtistPlatform = artistPlatform; diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index cba136b7..3441b1f6 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -1,14 +1,9 @@ using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; using System.IO; -using System.IO.Compression; using System.Linq; -using System.Security.Cryptography; using System.Threading.Tasks; using Godot; -using Octokit; using Util; public static class MapCache @@ -31,22 +26,11 @@ public static void Load(bool fullSync) try { - // string[] files = Directory.GetFiles(MapUtil.MapsFolder, $"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories); - - // List mapsList = Directory - // .GetFiles(MapUtil.MapsFolder, $"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories) - // .Concat(Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories)) - // .ToList(); - - // Map files go first since they will be encoded to folders after they get parsed in MapParser.cs + // Map files go first since they will be encoded to folders after they get parsed in MapParser.cs -fog List mapsList = Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories) .Concat(Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories)) .ToList(); - // List mapsList = Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories) - // .Concat(Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories)) - // .ToList(); - string[] toParseMaps = mapsList.ToArray(); if (fullSync) @@ -86,29 +70,25 @@ private static void syncFiles(string[] toParseMaps) string mapPath = BackSlashToForwardSlash(map.FolderPath); - // Checks if the map is actually inside the maps folder if (mapsHashSet.Contains(mapPath)) { DateTime metadataModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "metadata.json")); DateTime objectModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "objects.phxmo")); - // i have to convert to string since sqlite doesnt support DateTime c# conversion - // PLUS, theres like seconds or something and it doesnt catch that soooooo + // Time must be converted to string because the SQLite library doesn't support DateTime types -fog string metadataResult = metadataModifiedDate.ToString(); string notesResult = objectModifiedDate.ToString(); bool metadataCheck = map.LastModifiedMetadata == metadataResult; bool objectsCheck = map.LastModifiedNotes == notesResult; - // last modified is faster and lowkey more important -fog + // Last modified comes before checksum since it is faster -fog if (metadataCheck || objectsCheck) { FilesSynced.Value++; continue; } - // we will do checksum checking after if last modified dates dont match - // this code shouldn't be reached unless the dates dont match string checksum = GetMd5Checksum(mapPath); if (map.MetadataObjectHash == checksum) { @@ -146,7 +126,6 @@ private static void syncFiles(string[] toParseMaps) newMap.MetadataObjectHash = checksum; DatabaseService.Connection.Update(newMap); - // InsertIntoMapCacheFolder(map); Logger.Log($"Updated cached map: {newMap.Name}"); FilesSynced.Value++; continue; @@ -184,8 +163,6 @@ private static void addNonCachedFiles(string[] toParseMaps) continue; } - // FilesToSync.Value += 1; - try { GD.Print($"decoding: {toParseMap}\nfilestosync: {FilesToSync.Value}, filessynced: {FilesSynced.Value}"); @@ -320,30 +297,6 @@ public static void OrderAndSetMaps() MapManager.Maps = sortedMaps; } - // public static List ConvertToMapSets(IEnumerable maps) - // { - // var groupedMaps = maps - // .GroupBy(u => u.Collection) - // .Select(x => x.ToList()) - // .ToList(); - - // var mapSets = new List(); - - // foreach (var mapSet in groupedMaps) - // { - // var set = new MapSet() - // { - // Directory = mapSet.First().Collection, - // Maps = mapSet - // }; - - // set.Maps.ForEach(x => x.MapSet = set); - // mapSets.Add(set); - // } - - // return mapSets; - // } - public static string GetMd5Checksum(string path) { string metadataPath = Path.Combine(path, "metadata.json"); diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 06854e67..a3564c82 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -2,7 +2,6 @@ using System.Collections.Concurrent; using System.IO; using System.IO.Compression; -using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using Godot; @@ -294,7 +293,7 @@ public static Map SSMapV1(string path, string audioPath = null) audio.Close(); } - map = new(path, "", "", "", notes, null, "", name, audioBuffer: audioBuffer); + map = new(path, notes, null, "", name, audioBuffer: audioBuffer); } catch (Exception exception) { @@ -462,7 +461,7 @@ private static Map sspmV1(FileParser file, string path = null) notes[i].Index = i; } - map = new(path ?? $"{Constants.USER_FOLDER}/maps/{song}_temp.sspm", "", "", "", notes, id, artist, song, 0, mappers, difficulty, null, (int)mapLength, audioBuffer, coverBuffer); + map = new(path ?? $"{Constants.USER_FOLDER}/maps/{song}_temp.sspm", notes, id, artist, song, 0, mappers, difficulty, null, (int)mapLength, audioBuffer, coverBuffer); } catch (Exception exception) { @@ -616,7 +615,7 @@ private static Map sspmV2(FileParser file, string path = null) notes[i].Index = i; } - map = new(path, "", "", "", notes, id, artist, song, 0, mappers, difficulty, difficultyName, (int)mapLength, audioBuffer, coverBuffer); + map = new(path, notes, id, artist, song, 0, mappers, difficulty, difficultyName, (int)mapLength, audioBuffer, coverBuffer); } catch (Exception exception) { @@ -644,8 +643,6 @@ public static Map PHXMFolder(string path) byte[] coverBuffer = null; byte[] videoBuffer = null; - // FileParser objects = new(objectsBuffer); - if ((bool)metadata["HasAudio"]) { audioBuffer = File.ReadAllBytes($"{path}/audio.{metadata["AudioExt"]}"); @@ -667,8 +664,6 @@ public static Map PHXMFolder(string path) metadata.TryGetValue("ArtistLink", out Variant artistLink); metadata.TryGetValue("ArtistPlatform", out Variant artistPlatform); - - byte[] hash = Misc.HashFiles([Path.Combine(path, "metadata.json"), Path.Combine(path, "objects.phxmo")]); DateTime metadataModified = File.GetLastWriteTime(Path.Combine(path, "metadata.json")); @@ -677,9 +672,6 @@ public static Map PHXMFolder(string path) map = new( path, - BitConverter.ToString(hash).Replace("-", "").ToLower(), - metadataModified.ToString(), - objectsModified.ToString(), notes, (string)metadata["ID"], (string)metadata["Artist"], @@ -696,6 +688,9 @@ public static Map PHXMFolder(string path) (string)artistLink ?? "", (string)artistPlatform ?? "" ); + map.MetadataObjectHash = BitConverter.ToString(hash).Replace("-", "").ToLower(); + map.LastModifiedMetadata = metadataModified.ToString(); + map.LastModifiedNotes = objectsModified.ToString(); } catch (Exception exception) { @@ -712,74 +707,12 @@ public static Map PHXM(string path) string mapDirectory = $"{Constants.USER_FOLDER}/maps"; - // try - // { - // var file = ZipFile.OpenRead(path); - - // byte[] metaBuffer = getZipEntryBuffer(file, "metadata.json"); - // byte[] objectsBuffer = getZipEntryBuffer(file, "objects.phxmo"); - // byte[] audioBuffer = null; - // byte[] coverBuffer = null; - // byte[] videoBuffer = null; - - // var metadata = (Dictionary)Json.ParseString(Encoding.UTF8.GetString(metaBuffer)); - // FileParser objects = new(objectsBuffer); - - // if ((bool)metadata["HasAudio"]) - // { - // audioBuffer = getZipEntryBuffer(file, $"audio.{metadata["AudioExt"]}"); - // } - - // if ((bool)metadata["HasCover"]) - // { - // coverBuffer = getZipEntryBuffer(file, "cover.png"); - // } - - // if ((bool)metadata["HasVideo"]) - // { - // videoBuffer = getZipEntryBuffer(file, "video.mp4"); - // } - - // var notes = DecodePHXMO(objectsBuffer); - - // file.Dispose(); - - // // temp - // metadata.TryGetValue("ArtistLink", out Variant artistLink); - // metadata.TryGetValue("ArtistPlatform", out Variant artistPlatform); - - // map = new( - // path, - // notes, - // (string)metadata["ID"], - // (string)metadata["Artist"], - // (string)metadata["Title"], - // 0, - // (string[])metadata["Mappers"], - // (int)metadata["Difficulty"], - // (string)metadata["DifficultyName"], - // (int)metadata["Length"], - // audioBuffer, - // coverBuffer, - // videoBuffer, - // false, - // (string)artistLink ?? "", - // (string)artistPlatform ?? "" - // ); - // } - // catch (Exception exception) - // { - // ToastNotification.Notify($"PHXM file corrupted", 2); - // Logger.Error(exception); - // throw; - // } - string extractedFolderName = Path.GetFileNameWithoutExtension(path); string extractedFolderPath = Path.Combine(mapDirectory, extractedFolderName); if (Directory.Exists(extractedFolderPath)) { - Directory.Delete(extractedFolderPath, true); // true = recursive + Directory.Delete(extractedFolderPath, true); Map existingMap = DatabaseService.Connection.Table().FirstOrDefault(x => x.FolderPath == extractedFolderPath); MapCache.RemoveMap(existingMap); } @@ -877,9 +810,6 @@ public static Map RHM(string path) map = new( path, - "", - "", - "", notes, null, artist ?? "", diff --git a/scripts/util/Misc.cs b/scripts/util/Misc.cs index 3f882c06..a8c84d92 100644 --- a/scripts/util/Misc.cs +++ b/scripts/util/Misc.cs @@ -2,7 +2,6 @@ using System.Globalization; using System.IO; using System.Security.Cryptography; -using System.Text; using Godot; namespace Util; From 16e50d6d9fda33f1e7fbcaf8d61e902d2710d7ac Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 18 Aug 2026 00:56:22 -0400 Subject: [PATCH 29/38] delete if not in maps folder --- scripts/map/Map.cs | 7 ++++--- scripts/map/MapParser.cs | 28 +++++++++++++++++++--------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs index 5181099d..6f0c2895 100644 --- a/scripts/map/Map.cs +++ b/scripts/map/Map.cs @@ -152,6 +152,7 @@ public Map(string folderPath, Note[] data = null, string id = null, string artis public string EncodeMeta() { + string path = $"{MapUtil.MapsFolder}/{Name}"; return Json.Stringify(new Godot.Collections.Dictionary() { ["ID"] = Name, @@ -164,9 +165,9 @@ public string EncodeMeta() ["Difficulty"] = Difficulty, ["DifficultyName"] = DifficultyName, ["Length"] = Length, - ["HasAudio"] = AudioBuffer != null, - ["HasCover"] = CoverBuffer != null, - ["HasVideo"] = VideoBuffer != null, + ["HasAudio"] = AudioBuffer != null && File.Exists($"{path}/audio.{AudioExt}"), + ["HasCover"] = CoverBuffer != null && File.Exists($"{path}/cover.png"), + ["HasVideo"] = VideoBuffer != null && File.Exists($"{path}/video.mp4"), ["AudioExt"] = AudioExt }, "\t"); } diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index a3564c82..79103cd9 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -69,8 +69,15 @@ await Task.Run(() => public static void ExportEncode(Map map) { + /* + The reason we re-decode it is because the cut down map cache's map list does not + have the buffers to save time and memory. So if we decode it, we can get the + buffers without having to deal with other annoying shit + */ + Map decodedMap = Decode(map.FolderPath); + string exportPath = $"{Constants.USER_FOLDER}/export/"; - string exportFilePath = Path.Combine(exportPath, $"{map.Name}.phxm"); + string exportFilePath = Path.Combine(exportPath, $"{decodedMap.Name}.phxm"); if (!Directory.Exists(exportPath)) Directory.CreateDirectory(exportPath); @@ -79,14 +86,14 @@ public static void ExportEncode(Map map) { var metadata = archive.CreateEntry("metadata.json", CompressionLevel.NoCompression); using (var writer = new StreamWriter(metadata.Open())) - writer.Write(map.EncodeMeta()); + writer.Write(decodedMap.EncodeMeta()); var objects = archive.CreateEntry("objects.phxmo", CompressionLevel.NoCompression); using (var objs = objects.Open()) { using BinaryWriter bw = new BinaryWriter(objs); bw.Write((uint)12); - bw.Write((uint)map.Notes.Length); - foreach (var note in map.Notes) + bw.Write((uint)decodedMap.Notes.Length); + foreach (var note in decodedMap.Notes) { bool quantum = (int)note.X != note.X || (int)note.Y != note.Y || note.X < -1 || note.X > 1 || note.Y < -1 || note.Y > 1; bw.Write((uint)note.Millisecond); @@ -122,9 +129,9 @@ void addAsset(string name, byte[] buffer) stream.Write(buffer, 0, buffer.Length); } - if (map.AudioBuffer != null) addAsset($"audio.{map.AudioExt}", map.AudioBuffer); - if (map.CoverBuffer != null) addAsset($"cover.png", map.CoverBuffer); - if (map.VideoBuffer != null) addAsset($"video.mp4", map.VideoBuffer); + if (decodedMap.AudioBuffer != null) addAsset($"audio.{decodedMap.AudioExt}", decodedMap.AudioBuffer); + if (decodedMap.CoverBuffer != null) addAsset($"cover.png", decodedMap.CoverBuffer); + if (decodedMap.VideoBuffer != null) addAsset($"video.mp4", decodedMap.VideoBuffer); } File.WriteAllBytes(exportFilePath, ms.ToArray()); @@ -211,7 +218,6 @@ void addAsset(string name, byte[] buffer) map.LastModifiedNotes = objectsModified.ToString(); map.FolderPath = mapFolderPath; - // need to do map caching stuff here MapCache.InsertMap(map); @@ -710,6 +716,7 @@ public static Map PHXM(string path) string extractedFolderName = Path.GetFileNameWithoutExtension(path); string extractedFolderPath = Path.Combine(mapDirectory, extractedFolderName); + // If the map you are extacting already exists if (Directory.Exists(extractedFolderPath)) { Directory.Delete(extractedFolderPath, true); @@ -718,7 +725,10 @@ public static Map PHXM(string path) } ZipFile.ExtractToDirectory(path, extractedFolderPath); - File.Delete(path); + if (Path.GetDirectoryName(Path.GetFullPath(path)) == Path.GetFullPath(mapDirectory)) + { + File.Delete(path); + } return PHXMFolder(extractedFolderPath); } From f13e6780a724684425e9052f5f76763994b20595 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 18 Aug 2026 01:00:01 -0400 Subject: [PATCH 30/38] :) --- scripts/map/MapParser.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 79103cd9..248834d2 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -73,6 +73,8 @@ public static void ExportEncode(Map map) The reason we re-decode it is because the cut down map cache's map list does not have the buffers to save time and memory. So if we decode it, we can get the buffers without having to deal with other annoying shit + + -fog */ Map decodedMap = Decode(map.FolderPath); From e936e483da8221ef4e206f744348bbcfbf83f2cf Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 18 Aug 2026 01:05:17 -0400 Subject: [PATCH 31/38] HI !!!!!!!!! :) --- scripts/map/MapParser.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 248834d2..60a5d17f 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -695,14 +695,19 @@ public static Map PHXMFolder(string path) false, (string)artistLink ?? "", (string)artistPlatform ?? "" - ); - map.MetadataObjectHash = BitConverter.ToString(hash).Replace("-", "").ToLower(); - map.LastModifiedMetadata = metadataModified.ToString(); - map.LastModifiedNotes = objectsModified.ToString(); + ) + { + MetadataObjectHash = BitConverter.ToString(hash).Replace("-", "").ToLower(), + LastModifiedMetadata = metadataModified.ToString(), + LastModifiedNotes = objectsModified.ToString() + }; + // map.MetadataObjectHash = BitConverter.ToString(hash).Replace("-", "").ToLower(); + // map.LastModifiedMetadata = metadataModified.ToString(); + // map.LastModifiedNotes = objectsModified.ToString(); } catch (Exception exception) { - _ = ToastNotification.Notify($"PHXM folder corrupted", 2); + _ = ToastNotification.Notify($"{Path.GetFileNameWithoutExtension(path)} is not the proper format!", 2); Logger.Error(exception); throw; } From 71030a4084a7cf9062c205e991dcb3a94d26988e Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 18 Aug 2026 17:21:50 -0400 Subject: [PATCH 32/38] clean up --- scripts/game/managers/ReplayManager.cs | 1 - scripts/map/MapCache.cs | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/scripts/game/managers/ReplayManager.cs b/scripts/game/managers/ReplayManager.cs index 80f7205f..b72dc992 100644 --- a/scripts/game/managers/ReplayManager.cs +++ b/scripts/game/managers/ReplayManager.cs @@ -70,7 +70,6 @@ public void NewReplay(Attempt attempt) } string serializedMods = string.Join("_", mods); - // string mapName = attempt.Map.FilePath.GetFile().GetBaseName(); string mapName = Path.GetFileName(attempt.Map.FolderPath); string player = "You"; diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 3441b1f6..42f700c3 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -26,7 +26,7 @@ public static void Load(bool fullSync) try { - // Map files go first since they will be encoded to folders after they get parsed in MapParser.cs -fog + // Map files (.phxm, .sspm, etc) go first since they will be encoded to folders after they get parsed in MapParser.cs -fog List mapsList = Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories) .Concat(Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories)) .ToList(); @@ -64,6 +64,7 @@ private static void syncFiles(string[] toParseMaps) } var mapsHashSet = toParseMaps.ToHashSet(); + int deletedMapInt = 0; foreach (var map in maps) { @@ -138,11 +139,17 @@ private static void syncFiles(string[] toParseMaps) } DatabaseService.Connection.Delete(map); - Logger.Log($"Removed {mapPath} from the cache, as it no longer exists."); + deletedMapInt++; + // Logger.Log($"Removed {mapPath} from the cache, as it no longer exists."); FilesSynced.Value++; } } + + if (deletedMapInt > 0) + { + Logger.Log($"Removed {deletedMapInt} maps from the cache."); + } } private static void addNonCachedFiles(string[] toParseMaps) @@ -156,6 +163,8 @@ private static void addNonCachedFiles(string[] toParseMaps) FilesToSync.Value = toParseMaps.Count() - maps.Count(); FilesSynced.Value = 0; + Logger.Log($"Decoding {toParseMaps.Length} maps\nFiles To Sync: {FilesToSync.Value}"); + foreach (string toParseMap in toParseMaps) { if (hashSet.Contains(BackSlashToForwardSlash(toParseMap))) @@ -165,7 +174,6 @@ private static void addNonCachedFiles(string[] toParseMaps) try { - GD.Print($"decoding: {toParseMap}\nfilestosync: {FilesToSync.Value}, filessynced: {FilesSynced.Value}"); var map = MapParser.Decode(toParseMap); map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); @@ -179,6 +187,8 @@ private static void addNonCachedFiles(string[] toParseMaps) FilesSynced.Value++; } + + Logger.Log($"Files Synced: {FilesSynced.Value}"); } public static int InsertMap(Map map) From 3ab1e83d45dd68a846efa02ac013814ed7716dc5 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Tue, 18 Aug 2026 18:18:51 -0400 Subject: [PATCH 33/38] favorite conversion --- scripts/map/Map.cs | 3 +++ scripts/map/MapCache.cs | 45 +++++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs index 6f0c2895..14ce34fc 100644 --- a/scripts/map/Map.cs +++ b/scripts/map/Map.cs @@ -16,6 +16,7 @@ public partial class Map : RefCounted public int Id { get; set; } public string Name { get; set; } = string.Empty; + public int? CacheVersion { get; set; } public string LastModifiedMetadata { get; set; } public string LastModifiedNotes { get; set; } @@ -121,6 +122,8 @@ public Map() { } public Map(string folderPath, Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") { + CacheVersion = 2; + FolderPath = folderPath; Ephemeral = ephemeral; MetadataObjectHash = ""; diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 42f700c3..3ae02a0c 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -11,6 +11,8 @@ public static class MapCache public static Bindable FilesToSync = new(0); public static Bindable FilesSynced = new(0); public static event Action OnFilesSyncFinished; + public static bool OldCacheFormat = false; + public static List MapsToBeFavorited = new(); public static void Initialize() { @@ -54,6 +56,12 @@ public static void Load(bool fullSync) private static void syncFiles(string[] toParseMaps) { var maps = FetchAll(); + + if (maps[0].CacheVersion is null || maps[0].CacheVersion <= 1) + { + OldCacheFormat = true; + Logger.Log("Old map cache detected! Re-converting..."); + } FilesToSync.Value = maps.Count; FilesSynced.Value = 0; @@ -64,13 +72,25 @@ private static void syncFiles(string[] toParseMaps) } var mapsHashSet = toParseMaps.ToHashSet(); + + // Debug Variables that will be printed in case of problems int deletedMapInt = 0; + int convertedMaps = 0; + // The new cache re-writes it from scratch with a new format, so we will need to store these foreach (var map in maps) { - string mapPath = BackSlashToForwardSlash(map.FolderPath); + // Store it in a public list to add it later when we re-parse the maps + if (OldCacheFormat) + { + if (map.Favorite == true) + { + MapsToBeFavorited.Add(map.Name); + } + } + if (mapsHashSet.Contains(mapPath)) { DateTime metadataModifiedDate = File.GetLastWriteTime(Path.Combine(mapPath, "metadata.json")); @@ -133,11 +153,11 @@ private static void syncFiles(string[] toParseMaps) } else { - if (Directory.Exists($"{MapUtil.MapsFolder}/{map.Name}")) - { - Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); - } - + // if (Directory.Exists($"{MapUtil.MapsFolder}/{map.Name}")) + // { + // Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); + // } + DatabaseService.Connection.Delete(map); deletedMapInt++; // Logger.Log($"Removed {mapPath} from the cache, as it no longer exists."); @@ -150,6 +170,10 @@ private static void syncFiles(string[] toParseMaps) { Logger.Log($"Removed {deletedMapInt} maps from the cache."); } + if (convertedMaps > 0) + { + Logger.Log($"Converted {convertedMaps} maps from the old cache."); + } } private static void addNonCachedFiles(string[] toParseMaps) @@ -177,6 +201,15 @@ private static void addNonCachedFiles(string[] toParseMaps) var map = MapParser.Decode(toParseMap); map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); + + if (OldCacheFormat) + { + if (MapsToBeFavorited.Contains(map.Name)) + { + map.Favorite = true; + } + } + InsertMap(map); } catch From 3baf2945751682b2a5f7f9242714d31d5fc7924c Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Wed, 19 Aug 2026 00:50:38 -0400 Subject: [PATCH 34/38] fix annoying default map bug !!! --- scripts/map/MapCache.cs | 36 +++++++++++++++++++++++++----------- scripts/map/MapParser.cs | 6 ++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 3ae02a0c..3edc4c24 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -56,11 +56,14 @@ public static void Load(bool fullSync) private static void syncFiles(string[] toParseMaps) { var maps = FetchAll(); - - if (maps[0].CacheVersion is null || maps[0].CacheVersion <= 1) + + if (maps.Count > 0) { - OldCacheFormat = true; - Logger.Log("Old map cache detected! Re-converting..."); + if (maps[0].CacheVersion is null || maps[0].CacheVersion <= 1) + { + OldCacheFormat = true; + Logger.Log("Old map cache detected! Re-converting..."); + } } FilesToSync.Value = maps.Count; @@ -77,16 +80,15 @@ private static void syncFiles(string[] toParseMaps) int deletedMapInt = 0; int convertedMaps = 0; - // The new cache re-writes it from scratch with a new format, so we will need to store these foreach (var map in maps) { string mapPath = BackSlashToForwardSlash(map.FolderPath); - // Store it in a public list to add it later when we re-parse the maps if (OldCacheFormat) { if (map.Favorite == true) { + // The new cache re-writes it from scratch with a new format, so we will need to store these for later MapsToBeFavorited.Add(map.Name); } } @@ -153,10 +155,14 @@ private static void syncFiles(string[] toParseMaps) } else { - // if (Directory.Exists($"{MapUtil.MapsFolder}/{map.Name}")) - // { - // Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); - // } + if (Directory.Exists($"{MapUtil.MapsFolder}/{map.Name}")) + { + // Check if valid map + if (!File.Exists($"{MapUtil.MapsFolder}/{map.Name}/metadata.json") || !File.Exists($"{MapUtil.MapsFolder}/{map.Name}/objects.phxmo")) + { + Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); + } + } DatabaseService.Connection.Delete(map); deletedMapInt++; @@ -187,10 +193,16 @@ private static void addNonCachedFiles(string[] toParseMaps) FilesToSync.Value = toParseMaps.Count() - maps.Count(); FilesSynced.Value = 0; + if (toParseMaps.Contains($"{Constants.USER_FOLDER}/maps/default")) + { + FilesToSync.Value--; + } + Logger.Log($"Decoding {toParseMaps.Length} maps\nFiles To Sync: {FilesToSync.Value}"); foreach (string toParseMap in toParseMaps) { + // If the map path already exists in the map cache, skip it if (hashSet.Contains(BackSlashToForwardSlash(toParseMap))) { continue; @@ -199,6 +211,8 @@ private static void addNonCachedFiles(string[] toParseMaps) try { var map = MapParser.Decode(toParseMap); + if (map is null) continue; + map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); @@ -215,7 +229,7 @@ private static void addNonCachedFiles(string[] toParseMaps) catch { Directory.Delete(toParseMap, true); - Logger.Log($"Failed to add map non-cached map"); + Logger.Log($"Failed to add map non-cached map {toParseMap}"); } FilesSynced.Value++; diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 60a5d17f..2065c186 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -638,6 +638,12 @@ private static Map sspmV2(FileParser file, string path = null) public static Map PHXMFolder(string path) { + // First check if this is a proper phxm map + if (!File.Exists($"{path}/metadata.json") || !File.Exists($"{path}/objects.phxmo")) + { + return null; + } + Map map; try From 9af55c5e72a685ceeabce7936e994a47f8e07094 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Wed, 19 Aug 2026 00:58:52 -0400 Subject: [PATCH 35/38] fix extracted files not getting deleted in maps folder --- scripts/map/MapParser.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 2065c186..a51640b4 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -738,7 +738,11 @@ public static Map PHXM(string path) } ZipFile.ExtractToDirectory(path, extractedFolderPath); - if (Path.GetDirectoryName(Path.GetFullPath(path)) == Path.GetFullPath(mapDirectory)) + + string fullPath = Path.GetFullPath(path); + string fullMapDirectory = Path.GetFullPath(mapDirectory); + string relativePath = Path.GetRelativePath(fullMapDirectory, fullPath); + if (!relativePath.StartsWith("..") && !Path.IsPathRooted(relativePath)) { File.Delete(path); } From d3390ccb49c230c922af5302180c3f0708455980 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Wed, 19 Aug 2026 00:59:05 -0400 Subject: [PATCH 36/38] lets keep corrupted stuff for the future --- scripts/map/MapCache.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 3edc4c24..535a348f 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -211,7 +211,12 @@ private static void addNonCachedFiles(string[] toParseMaps) try { var map = MapParser.Decode(toParseMap); - if (map is null) continue; + if (map is null) + { + // Directory.Delete(toParseMap, true); + Logger.Log($"Failed to add map non-cached map {toParseMap}"); + continue; + } map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); @@ -226,10 +231,11 @@ private static void addNonCachedFiles(string[] toParseMaps) InsertMap(map); } - catch + catch (Exception exception) { - Directory.Delete(toParseMap, true); + // Directory.Delete(toParseMap, true); Logger.Log($"Failed to add map non-cached map {toParseMap}"); + Logger.Error(exception); } FilesSynced.Value++; From fb0cc22e2532d3f813d057ce0c1a5f81c510e964 Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Thu, 20 Aug 2026 20:45:01 -0400 Subject: [PATCH 37/38] resident evil 5 --- scripts/map/MapCache.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index 535a348f..a3a45b3c 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -40,6 +40,12 @@ public static void Load(bool fullSync) syncFiles(toParseMaps); addNonCachedFiles(toParseMaps); + // Old caching format used to just extract .phxm files, essentially doubling your game size + if (OldCacheFormat && Directory.Exists($"{Constants.USER_FOLDER}/cache/maps")) + { + Directory.Delete($"{Constants.USER_FOLDER}/cache/maps", true); + } + OnFilesSyncFinished?.Invoke(FilesSynced.Value); FilesToSync.Value = 0; FilesSynced.Value = 0; @@ -84,13 +90,10 @@ private static void syncFiles(string[] toParseMaps) { string mapPath = BackSlashToForwardSlash(map.FolderPath); - if (OldCacheFormat) + if (OldCacheFormat && map.Favorite) { - if (map.Favorite == true) - { - // The new cache re-writes it from scratch with a new format, so we will need to store these for later - MapsToBeFavorited.Add(map.Name); - } + // The new cache re-writes it from scratch with a new format, so we will need to store these for later + MapsToBeFavorited.Add(map.Name); } if (mapsHashSet.Contains(mapPath)) @@ -193,6 +196,7 @@ private static void addNonCachedFiles(string[] toParseMaps) FilesToSync.Value = toParseMaps.Count() - maps.Count(); FilesSynced.Value = 0; + // For Old Cache version if (toParseMaps.Contains($"{Constants.USER_FOLDER}/maps/default")) { FilesToSync.Value--; From 588c09d00423f3bbad6d1799e0f7e969906d966b Mon Sep 17 00:00:00 2001 From: fogsaturate Date: Thu, 20 Aug 2026 20:56:24 -0400 Subject: [PATCH 38/38] dotnet format --- scripts/map/Map.cs | 2 +- scripts/map/MapCache.cs | 10 +++++----- scripts/map/MapManager.cs | 2 +- scripts/map/MapParser.cs | 6 +++--- scripts/map/Replay.cs | 4 ++-- scripts/util/Misc.cs | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs index 14ce34fc..15218a27 100644 --- a/scripts/map/Map.cs +++ b/scripts/map/Map.cs @@ -123,7 +123,7 @@ public Map() { } public Map(string folderPath, Note[] data = null, string id = null, string artist = "", string title = "", float rating = 0, string[] mappers = null, int difficulty = 0, string difficultyName = null, int? length = null, byte[] audioBuffer = null, byte[] coverBuffer = null, byte[] videoBuffer = null, bool ephemeral = false, string artistLink = "", string artistPlatform = "") { CacheVersion = 2; - + FolderPath = folderPath; Ephemeral = ephemeral; MetadataObjectHash = ""; diff --git a/scripts/map/MapCache.cs b/scripts/map/MapCache.cs index a3a45b3c..82376533 100644 --- a/scripts/map/MapCache.cs +++ b/scripts/map/MapCache.cs @@ -29,7 +29,7 @@ public static void Load(bool fullSync) try { // Map files (.phxm, .sspm, etc) go first since they will be encoded to folders after they get parsed in MapParser.cs -fog - List mapsList = Directory.GetFiles(MapUtil.MapsFolder,$"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories) + List mapsList = Directory.GetFiles(MapUtil.MapsFolder, $"*.{Constants.DEFAULT_MAP_EXT}", SearchOption.AllDirectories) .Concat(Directory.GetDirectories(MapUtil.MapsFolder, "*", SearchOption.AllDirectories)) .ToList(); @@ -45,7 +45,7 @@ public static void Load(bool fullSync) { Directory.Delete($"{Constants.USER_FOLDER}/cache/maps", true); } - + OnFilesSyncFinished?.Invoke(FilesSynced.Value); FilesToSync.Value = 0; FilesSynced.Value = 0; @@ -166,7 +166,7 @@ private static void syncFiles(string[] toParseMaps) Directory.Delete($"{MapUtil.MapsFolder}/{map.Name}", true); } } - + DatabaseService.Connection.Delete(map); deletedMapInt++; // Logger.Log($"Removed {mapPath} from the cache, as it no longer exists."); @@ -221,7 +221,7 @@ private static void addNonCachedFiles(string[] toParseMaps) Logger.Log($"Failed to add map non-cached map {toParseMap}"); continue; } - + map.FolderPath = $"{Constants.USER_FOLDER}/maps/{map.Name}"; map.MetadataObjectHash = GetMd5Checksum(map.FolderPath); @@ -232,7 +232,7 @@ private static void addNonCachedFiles(string[] toParseMaps) map.Favorite = true; } } - + InsertMap(map); } catch (Exception exception) diff --git a/scripts/map/MapManager.cs b/scripts/map/MapManager.cs index d40d235a..3ea6f210 100644 --- a/scripts/map/MapManager.cs +++ b/scripts/map/MapManager.cs @@ -41,7 +41,7 @@ public static void Select(Map map) public static Map GetMapById(int id) { - // return Maps.Where(x => x.Id == id).First(); + // return Maps.Where(x => x.Id == id).First(); return Maps.FirstOrDefault(x => x.Id == id); } diff --git a/scripts/map/MapParser.cs b/scripts/map/MapParser.cs index 9878b779..f1a2b326 100644 --- a/scripts/map/MapParser.cs +++ b/scripts/map/MapParser.cs @@ -77,7 +77,7 @@ buffers without having to deal with other annoying shit -fog */ Map decodedMap = Decode(map.FolderPath); - + string exportPath = $"{Constants.USER_FOLDER}/export/"; string exportFilePath = Path.Combine(exportPath, $"{decodedMap.Name}.phxm"); @@ -262,7 +262,7 @@ public static Map Decode(string path, string audio = null, bool logBenchmark = f if (save) Encode(map); return map; - } + } else if (Directory.Exists(path)) { return PHXMFolder(path); @@ -717,7 +717,7 @@ public static Map PHXMFolder(string path) Logger.Error(exception); throw; } - + return map; } diff --git a/scripts/map/Replay.cs b/scripts/map/Replay.cs index 33a659da..6c43d734 100644 --- a/scripts/map/Replay.cs +++ b/scripts/map/Replay.cs @@ -170,10 +170,10 @@ public Replay(string path) MapNoteCount = FileBuffer.GetUInt64(); MapFilePath = $"{Constants.USER_FOLDER}/maps/{MapID}"; if (Path.GetExtension(MapFilePath).Equals(".phxm", StringComparison.OrdinalIgnoreCase)) - { + { Logger.Log($"Legacy Replay detected: {MapFilePath}"); MapFilePath = Path.ChangeExtension(MapFilePath, null); // just in case it tries to read a .phxm file - + } if (!Directory.Exists(MapFilePath)) diff --git a/scripts/util/Misc.cs b/scripts/util/Misc.cs index a8c84d92..9c81a0e3 100644 --- a/scripts/util/Misc.cs +++ b/scripts/util/Misc.cs @@ -74,7 +74,7 @@ public static byte[] HashFiles(string[] paths) md5.TransformBlock(fileData, 0, fileData.Length, null, 0); } - md5.TransformFinalBlock(Array.Empty(), 0 ,0); + md5.TransformFinalBlock(Array.Empty(), 0, 0); return md5.Hash; }