Opened 16 months ago

Last modified 13 months ago

#6688 new defect

Fix player owned entities that should belong to gaia

Reported by: Langbart Owned by:
Priority: Should Have Milestone: Alpha 27
Component: Maps Keywords:
Cc: Patch: Phab:D4123

Description

description

  • entities commonly associated with Gaia should not be owned by a player, such as
    • trees
    • mines
    • wild animals
    • ruins
    • ...
  • certain domestic animals should remain with the owner
    • goat
    • pig
    • sheep
    • camel_trainable
    • cattle_cow
    • cattle_sanga
    • cattle_zebu

example to reproduce

  • start the skirmishes/sahyadri_buttes_5p map as player 5, notice you own a crocodile

searching for more cases

ripgrep

# navigate to map folder
cd ~/0ad/binaries/data/mods/public/maps
# search
rg --stats --glob "*.xml" --multiline \
"<Template>(?!(skirmish|structures|units|campaigns|trigger|territory|gaia/fauna_(goat|pig|sheep|camel_trainable|cattle_cow|cattle_sanga|cattle_zebu))).*</Template>\s+<Player>[1-8]"

scenarios/tropical_island.xml
1770:           <Template>gaia/rock/tropical_large</Template>
1771:           <Player>1</Player>
1776:           <Template>gaia/rock/tropical_large</Template>
1777:           <Player>1</Player>

skirmishes/miletus_peninsula_2p.xml
32277:          <Template>vision_revealers/50_meters</Template>
32278:          <Player>2</Player>
...

# 386 matches
# 772 matched lines
# 19 files contained matches
# 151 files searched
# 32515 bytes printed
# 90011843 bytes searched
# 0.357958 seconds spent searching
# 0.234346 seconds

related irc conversation

  • IRC 0ad-dev (8/Jun/21)
    09:05 < Langbart> Stan Were some changes made to the map "Sahyadri Buttes", I have a tiger and a crocodile that belong to a player. Both appear in the player color and not in the GAIA color. 
    ...
    09:21 <@Stan> <Template>((?!skirmish|structures|units|campaigns|gaia/fauna_goat|trigger|territory|gaia/fauna_sheep).).*</Template>\n\t+<player>[1-5]<
    ...
    09:28 < Langbart> Stan  You mean the tiger is just a mistake?
    09:29 <@Stan> Along with 447 other mistakes in all maps
    09:29 <@Stan> + 132 if you count goats and sheeps
    09:32 <@Stan> Langbart, https://code.wildfiregames.com/D4123
    

optional

  • include a check for wrongly owned entities into the python script checkrefs.py

Attachments (1)

croc.png (182.8 KB ) - added by Langbart 16 months ago.

Download all attachments as: .zip

Change History (3)

by Langbart, 16 months ago

Attachment: croc.png added

comment:1 by Stan, 15 months ago

In 27543:

Fix trees, rocks, fish, and crocodiles having incorrect owners.
Refs #6688
Refs D4123

in reply to:  description comment:2 by Langbart, 13 months ago

Replying to Langbart:

optional

  • include a check for wrongly owned entities into the python script checkrefs.py

AI script

  • python script created with phind.com through a ~1hr chat
  • options were added when asked, as well as the use of certain modules
  • if the script was slow with large .xml files, the AI changed it to be more performant
  • it actually works, tested on 0ad, delenda_est, community_maps_2 and macedonia_0ad.
Line 
1import os
2import argparse
3import re
4from glob import glob
5from logging import WARNING, getLogger, StreamHandler, INFO, Formatter, DEBUG
6
7def setup_logging(level):
8 logger = getLogger()
9 logger.setLevel(level)
10 handler = StreamHandler()
11 handler.setFormatter(Formatter('%(levelname)s - %(message)s'))
12 logger.addHandler(handler)
13 return logger
14
15def process_file(file_path, fix_non_zero, logger, quiet):
16 issues_count = 0
17 exclude_tags = [
18 "campaigns",
19 "gaia/fauna_camel_trainable",
20 "gaia/fauna_cattle_cow",
21 "gaia/fauna_cattle_sanga",
22 "gaia/fauna_cattle_zebu",
23 "gaia/fauna_goat",
24 "gaia/fauna_pig",
25 "gaia/fauna_sheep",
26 "gaia/ruins",
27 "skirmish",
28 "structures",
29 "territory",
30 "trigger",
31 "units",
32 "vision_revealers",
33 ]
34
35 player_pattern = re.compile(r'<Player>([^<]+)</Player>')
36 template_pattern = re.compile(r'<Template>([^<]+)</Template>')
37
38 with open(file_path, 'r', encoding='utf-8') as f:
39 temp_file_path = file_path + ".tmp"
40 with open(temp_file_path, 'w', encoding='utf-8') as temp_f:
41 prev_template = None
42 for line_number, line in enumerate(f, start=1):
43
44 template_match = template_pattern.search(line)
45 player_match = player_pattern.search(line)
46
47 if template_match:
48 prev_template = template_match.group(1)
49
50 if player_match and prev_template and not any(tag in prev_template for tag in exclude_tags) and "0" not in player_match.group(1):
51 issues_count += 1
52 if fix_non_zero:
53 modified_line = player_pattern.sub('<Player>0</Player>', line)
54 temp_f.write(modified_line)
55 if not quiet:
56 logger.warning(f"Fixed non-zero player value with 0 in file {file_path} on line {line_number}")
57 else:
58 if not quiet:
59 logger.warning(f"Non-zero player value found in file {file_path} on line {line_number}: {player_match.group(1)}")
60 temp_f.write(line)
61 else:
62 temp_f.write(line)
63
64 if fix_non_zero:
65 os.replace(temp_file_path, file_path)
66 else:
67 os.remove(temp_file_path)
68
69 return issues_count
70
71def main():
72 parser = argparse.ArgumentParser(description="Find and fix non-zero player values in XML files.")
73 parser.add_argument("directory", help="Directory containing the XML files.")
74 parser.add_argument("-f", "--fix", action="store_true", help="Fix non-zero player values with 0.")
75 parser.add_argument("-s", "--stats", action="store_true", help="Show a summary of files checked and issues found.")
76 parser.add_argument("-q", "--quiet", action="store_true", help="Suppress warning messages.")
77 args = parser.parse_args()
78
79 log_level = WARNING if args.fix else INFO
80 if args.quiet:
81 log_level = WARNING
82 logger = setup_logging(log_level)
83
84 files_checked = 0
85 total_issues = 0
86
87 # Define the patterns to search for XML files in skirmishes and scenarios subdirectories
88 patterns = ['**/maps/skirmishes/*.xml', '**/maps/scenarios/*.xml']
89
90 for pattern in patterns:
91 for file_path in glob(os.path.join(args.directory, pattern), recursive=True):
92 issues_count = process_file(file_path, args.fix, logger, args.quiet)
93 files_checked += 1
94 total_issues += issues_count
95
96 if args.stats:
97 print(f"Summary:")
98 print(f"Files checked: {files_checked}")
99 print(f"Total issues found: {total_issues}")
100
101if __name__ == "__main__":
102 main()
  • save the code in a document (script.py) and run it on a directory, e.g. delenda_est
    python script.py . 
    # ...
    # WARNING - Non-zero player value found in file ./maps/scenarios/noba_village.xml on line 1523: 1
    
  • fix all issues, don't print individual lines and prints stats
    python script.py . --fix --quiet --stats
    # Summary:
    # Files checked: 126
    # Total issues found: 759
    
Note: See TracTickets for help on using tickets.