mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-05-19 13:20:47 +01:00
9f124e5b14
* Initial * Remove corrupt dmis * Fixup maps in TGM format4e5a32721f: maps/_templates_and_guidance/Public Event Templates/Maze_Reward_-_Copy.dmm4e5a32721f: maps/_templates_and_guidance/Templates/shelter_Medical.dmm4e5a32721f: maps/expedition_vr/aerostat/aerostat.dmm4e5a32721f: maps/expedition_vr/aerostat/aerostat_science_outpost.dmm4e5a32721f: maps/expedition_vr/beach/submaps/deadBeacon.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-crash-alt.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-crash.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-surface.dmm4e5a32721f: maps/expedition_vr/wild/tether_wild-temple.dmm4e5a32721f: maps/gateway_vr/lucky_7.dmm4e5a32721f: maps/gateway_vr/snow_outpost.dmm4e5a32721f: maps/overmap/_map.dmm4e5a32721f: maps/overmap/bearcat/bearcat.dmm4e5a32721f: maps/overmap/example_sector1.dmm4e5a32721f: maps/overmap/example_sector2.dmm4e5a32721f: maps/redgate/falls/falls.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/CaveS.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/DeadSettlers1.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/DeadSettlers2.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/DoomP.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/Lab1.dmm4e5a32721f: maps/submaps/pois_vr/aerostat/Rockybase.dmm4e5a32721f: maps/submaps/pois_vr/debris_field/debris14.dmm4e5a32721f: maps/submaps/pois_vr/debris_field/derelict.dmm4e5a32721f: maps/submaps/pois_vr/debris_field/new_escapepod_xeno.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/BlastMine1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/CaveTrench.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Cavelake.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Cliff1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/CrashedMedShuttle1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Geyser1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Geyser2.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Geyser3.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Mineshaft1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/Scave1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/SupplyDrop1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crashed_ufo.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crashed_ufo_frigate.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crystal1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crystal2.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/crystal3.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/deadBeacon.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/deadly_rabbit_vr.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/deadspy.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/digsite.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/excavation1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/lava_trench.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/prepper1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/ritual.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/spatial_anomaly.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/speakeasy_vr.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault1.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault2.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault3.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault4.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault5.dmm4e5a32721f: maps/submaps/surface_submaps/mountains/vault6.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Boathouse.dmm4e5a32721f: maps/submaps/surface_submaps/plains/BuriedTreasure.dmm4e5a32721f: maps/submaps/surface_submaps/plains/BuriedTreasure2.dmm4e5a32721f: maps/submaps/surface_submaps/plains/BuriedTreasure3.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Oldhouse.dmm4e5a32721f: maps/submaps/surface_submaps/plains/PooledR.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Rocky5.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Shakden.dmm4e5a32721f: maps/submaps/surface_submaps/plains/Thiefc.dmm4e5a32721f: maps/submaps/surface_submaps/plains/beacons.dmm4e5a32721f: maps/submaps/surface_submaps/plains/chemspill1.dmm4e5a32721f: maps/submaps/surface_submaps/plains/farm1.dmm4e5a32721f: maps/submaps/surface_submaps/plains/house1.dmm4e5a32721f: maps/submaps/surface_submaps/plains/lonehome.dmm4e5a32721f: maps/submaps/surface_submaps/plains/smol2.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Blackshuttledown.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Blueshuttledown.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Boombase.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/CaveS.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Chapel.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Cragzone1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost2.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost3.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DJOutpost4.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DecoupledEngine.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/DoomP.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Drugden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Epod3.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Epod4.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Flake.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/FrostflyNest.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/MCamp1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/MHR.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Manor1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Mudpit.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rocky1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rocky3.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rocky4.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Rockybase.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Shack1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Shelter.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Smol1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/Snowrock1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/borglab.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/butchershack.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/chasm.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/chemspill2.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/deathden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/derelictengine.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/frostoasis.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/kururakden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/spider1.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/wolfden.dmm4e5a32721f: maps/submaps/surface_submaps/wilderness/xenohive.dmm4e5a32721f: maps/tether/tether-02-surface2.dmm4e5a32721f: maps/virgo_minitest/virgo_minitest-sector-2.dmm Automatically commited by: tools\mapmerge2\fixup.py * Remove unnecessary whitespace edits from mapmerger * Cable dirs update path * Fix area var edits * Put the area over there * Ignore archive maps folder * Forgot to port multivar support too * A few changes I forgot about for hook install * restore multivar support that chomp doesn't have yet * ban those * Forgot to add code for the marker too * Couple more of these invalid cables were added in master * Update multiple_blood_effects.yml * Update multiple_blood_effects.yml * Fixup maps in TGM format612ca9cbb9: maps/tether/submaps/tether_misc.dmm Automatically commited by: tools\mapmerge2\fixup.py * Fixup now logs the map its currently checking * Final fixes? * Fixup maps in TGM format3078e5cd0a: maps/expedition_vr/beach/submaps/crashedcontainmentshuttle.dmm3078e5cd0a: maps/redgate/fantasy_dungeon.dmm3078e5cd0a: maps/submaps/pois_vr/aerostat/Rockybase.dmm3078e5cd0a: maps/submaps/surface_submaps/mountains/crashedcontainmentshuttle_vr.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/Oldhouse_vr.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/dogbase.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/greatwolfden.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/lonehome_vr.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/methlab.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/oldhotel.dmm3078e5cd0a: maps/submaps/surface_submaps/plains/priderock.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/Rockybase.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/demonpool.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/dogbase.dmm3078e5cd0a: maps/submaps/surface_submaps/wilderness/greatwolfden.dmm3078e5cd0a: maps/tether/submaps/underdark_pois/abandonded_outpost.dmm3078e5cd0a: maps/tether/submaps/underdark_pois/phoron_rat_den.dmm Automatically commited by: tools\mapmerge2\fixup.py * Fix tether_misc error * Remap reused solar farm area * Fix erroneous bearcat entries * Fix weird whitespace (most archive maps also affected but didn't bother) * misc mdb cleanup * moar * grr --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com>
166 lines
5.7 KiB
Python
166 lines
5.7 KiB
Python
import argparse
|
|
import glob
|
|
import os
|
|
import pathlib
|
|
import traceback
|
|
import yaml
|
|
|
|
from . import dmm, lint
|
|
from .error import MaplintError
|
|
from mapmerge2 import frontend
|
|
|
|
def green(text):
|
|
return "\033[32m" + str(text) + "\033[0m"
|
|
|
|
def red(text):
|
|
return "\033[31m" + str(text) + "\033[0m"
|
|
|
|
def yellow(text):
|
|
return "\033[33m" + str(text) + "\033[0m"
|
|
|
|
def process_dmm(map_filename, lints: dict[str, lint.Lint]) -> list[MaplintError]:
|
|
problems: list[MaplintError] = []
|
|
|
|
with open(map_filename, "r") as file:
|
|
try:
|
|
map_data = dmm.parse_dmm(file)
|
|
except MaplintError as error:
|
|
problems.append(error)
|
|
# No structured data to lint.
|
|
return problems
|
|
|
|
for lint_name, lint in lints.items():
|
|
try:
|
|
problems.extend(lint.run(map_data))
|
|
except KeyboardInterrupt:
|
|
raise
|
|
except Exception:
|
|
problems.append(MaplintError(
|
|
f"An exception occurred, this is either a bug in maplint or a bug in a lint. \n{traceback.format_exc()}",
|
|
lint_name,
|
|
))
|
|
|
|
return problems
|
|
|
|
def print_error(message: str, filename: str, line_number: int, github_error_style: bool):
|
|
if github_error_style:
|
|
print(f"::error file={filename},line={line_number},title=DMM Linter::{message}")
|
|
else:
|
|
print(red(f"- Error parsing {filename} (line {line_number}): {message}"))
|
|
|
|
def print_maplint_error(error: MaplintError, github_error_style: bool):
|
|
print_error(
|
|
f"{f'(in pop {error.pop_id}) ' if error.pop_id else ''}{f'(at {error.coordinates}) ' if error.coordinates else ''}{error}" + (f"\n {error.help}" if error.help is not None else ""),
|
|
error.file_name,
|
|
error.line_number,
|
|
github_error_style,
|
|
)
|
|
|
|
def print_maplint_suggestions(all_suggestions: dict[str, MaplintError], github_error_style: bool):
|
|
# being a dict, we can already assume MaplintError were de-duped based on path_suggestions
|
|
if(len(all_suggestions) == 0):
|
|
return
|
|
|
|
# sort all suggestions so its easier for the user to verify
|
|
suggestions = sorted(all_suggestions.items(), key=lambda x:str(x[1].path_suggestion))
|
|
|
|
# combine all suggestions into two strings, de-duping dm suggestions where necessary
|
|
path_suggestions = ""
|
|
dm_suggestions = ""
|
|
dm_sub_suggestions = set()
|
|
for key, failure in suggestions: # key is path_suggestion, but may as well be explicit
|
|
path_suggestions += failure.path_suggestion
|
|
if(failure.dm_sub_suggestion not in dm_sub_suggestions):
|
|
dm_sub_suggestions.add(failure.dm_sub_suggestion)
|
|
dm_suggestions += failure.dm_sub_suggestion
|
|
if(failure.dm_suggestion not in dm_sub_suggestions):
|
|
dm_suggestions += failure.dm_suggestion
|
|
|
|
if github_error_style:
|
|
print(f"::error title=DMM Linter::UpdatePath suggestions:\n{path_suggestions}")
|
|
print(f"::error title=DMM Linter::Code suggestions:\n{dm_suggestions}")
|
|
else:
|
|
print(red(f"- UpdatePath suggestions:\n{path_suggestions}"))
|
|
print(red(f"- Code suggestions:\n{dm_suggestions}"))
|
|
|
|
def main(args):
|
|
any_failed = False
|
|
github_error_style = args.github
|
|
|
|
lints: dict[str, lint.Lint] = {}
|
|
all_suggestions: dict[str, MaplintError] = {}
|
|
|
|
lint_base = pathlib.Path(__file__).parent.parent / "lints"
|
|
lint_filenames = []
|
|
if args.lints is None:
|
|
lint_filenames = lint_base.glob("*.yml")
|
|
else:
|
|
lint_filenames = [lint_base / f"{lint_name}.yml" for lint_name in args.lints]
|
|
|
|
for lint_filename in lint_filenames:
|
|
try:
|
|
lints[lint_filename] = lint.Lint(yaml.safe_load(lint_filename.read_text()))
|
|
except MaplintError as error:
|
|
print_maplint_error(error, github_error_style)
|
|
any_failed = True
|
|
except Exception:
|
|
print_error("Error loading lint file.", lint_filename, 1, github_error_style)
|
|
traceback.print_exc()
|
|
any_failed = True
|
|
|
|
default_maps_dir = os.path.join(frontend.read_settings().map_folder, '') # make sure it has a trailing slash
|
|
for map_filename in (args.maps or glob.glob(default_maps_dir + "**/*.dmm", recursive = True)):
|
|
print(map_filename, end = " ")
|
|
|
|
success = True
|
|
all_failures: list[MaplintError] = []
|
|
|
|
try:
|
|
problems = process_dmm(map_filename, lints)
|
|
if len(problems) > 0:
|
|
success = False
|
|
all_failures.extend(problems)
|
|
except KeyboardInterrupt:
|
|
raise
|
|
except Exception:
|
|
success = False
|
|
|
|
all_failures.append(MaplintError(
|
|
f"An exception occurred, this is either a bug in maplint or a bug in a lint.' {traceback.format_exc()}",
|
|
map_filename,
|
|
))
|
|
|
|
if success:
|
|
print(green("OK"))
|
|
else:
|
|
print(red("X"))
|
|
any_failed = True
|
|
|
|
for failure in all_failures:
|
|
print_maplint_error(failure, github_error_style)
|
|
|
|
# also collect any suggestions
|
|
if(failure.path_suggestion == ""):
|
|
continue
|
|
if(failure.path_suggestion not in all_suggestions):
|
|
all_suggestions[failure.path_suggestion] = failure
|
|
|
|
print_maplint_suggestions(all_suggestions, github_error_style)
|
|
|
|
if any_failed:
|
|
exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
prog = "maplint",
|
|
description = "Checks for common errors in maps.",
|
|
)
|
|
|
|
parser.add_argument("maps", nargs = "*")
|
|
parser.add_argument("--lints", nargs = "*")
|
|
parser.add_argument("--github", action='store_true')
|
|
|
|
args = parser.parse_args()
|
|
|
|
main(args)
|