import os import re directory = r"d:\Projects\ichni Official\Assets\Scripts\Game" skip_dir = r"d:\Projects\ichni Official\Assets\Scripts\Game\BeatmapEditor" # Skip if there's any Editor specific directory. But user said "Game文件夹". def clean_file(filepath): # Do not process BM format classes if they contain definitions of SaveBM or something, but realistically BM classes use ExecuteBM. # The user instruction: "把没有实际作用的SaveBM和ConvertToBM的函数剔除" try: with open(filepath, 'r', encoding='utf-8') as f: lines = f.readlines() except Exception as e: print("Error reading", filepath, e) return out_lines = [] i = 0 changed = False deleting_method = False brace_depth = 0 has_seen_open_brace = False while i < len(lines): line = lines[i] if not deleting_method: # We look for SaveBM or ConvertToBM declarations. # E.g. `public override void SaveBM()` or `public FlexibleFloat_BM ConvertToBM()` if re.search(r'\bvoid\s+SaveBM\s*\(', line) or re.search(r'\b\w+_BM\b\s+ConvertToBM\s*\(', line) or re.search(r'\bBaseElement_BM\b\s+ConvertToBM\s*\(', line) or re.search(r'\bFlexible[a-zA-Z]*_BM\b\s+ConvertToBM\s*\(', line) or "public void SaveBM()" in line or "public override void SaveBM()" in line or "ConvertToBM()" in line: # if there is a doc comment before this line, we'd ideally remove it too. # Let's remove the previous lines if they are '///' or '[Button]' idx = len(out_lines) - 1 while idx >= 0: prev_line = out_lines[idx].strip() if prev_line.startswith('///') or prev_line.startswith('[') or prev_line == "": out_lines.pop(idx) idx -= 1 else: break deleting_method = True brace_depth = 0 has_seen_open_brace = False if '{' in line: brace_depth += line.count('{') has_seen_open_brace = True if '}' in line: brace_depth -= line.count('}') if brace_depth == 0 and has_seen_open_brace: deleting_method = False # Check for one-liner interface without braces if ';' in line and not has_seen_open_brace: deleting_method = False changed = True i += 1 continue else: if '{' in line: brace_depth += line.count('{') has_seen_open_brace = True if '}' in line: brace_depth -= line.count('}') if brace_depth <= 0 and has_seen_open_brace: deleting_method = False i += 1 continue out_lines.append(line) i += 1 if not changed: return text = "".join(out_lines) # Remove empty partial classes # e.g. public partial class TrackTotalTimeChange { } text = re.sub(r'(public|protected|private)?\s*partial\s+class\s+\w+\s*\{[\s\n]*\}', '', text) # Remove empty Region blocks text = re.sub(r'#region\s+\[存档转换\]\s*Beatmap Data Conversion[\s\n]*#endregion', '', text) # Clean up excess newlines text = re.sub(r'\n\s*\n\s*\n', '\n\n', text) with open(filepath, 'w', encoding='utf-8') as f: f.write(text) print("Cleaned:", filepath) for root, dirs, files in os.walk(directory): for file in files: if file.endswith('.cs'): filepath = os.path.join(root, file) # Do not touch files in Base/Beatmap if they are definitions of the BM format themselves, unless they have ConvertToBM which they dont clean_file(filepath)