ModEnc is currently in Maintenance Mode: Changes could occur at any given moment, without advance warning.

Difference between revisions of "Rules.ini"

From ModEnc
Jump to: navigation, search
m (Python 3)
 
(27 intermediate revisions by 12 users not shown)
Line 1: Line 1:
The rules.ini (rulesmd.ini for [[Yuri's Revenge|YR]]) is the core file of C&C Modding. As indicated by the name, it includes the "rules" of the game, i.e. the properties of every object, weapon, warhead, etc. in the game. This is the main file you're editing when you're modding any C&C from [[Red Alert|RA]] to [[Yuri's Revenge|YR]]. For [[Generals]] and everything else basing on the [[SAGE]] [[engine]], the INI-system was changed to a more complex, wide-spread one.<br><br>
+
The rules.ini (naming variations for expansions) is the core file of C&C modding. As indicated by the name, it contains the "rules" of the game &ndash; the properties of every object, weapon, warhead, etc. in the game. For any C&C game from {{Ra}} to {{Yr}}, this is the main modification file. For [[Generals]] and everything else based on the [[SAGE]] [[engine]], the INI-system is more complex and wide-spread.
  
Keep in mind, though, that there are two sides of the medal: On one hand, you can edit almost everything in the game from the rules.ini, on the other hand, if you can't change something in the rules, you can't change it anywhere. There's a 99,9% chance that it's [[hardcoded]]. (Except, of course, it's [[art]]-related. Then you still have a chance ;))<br><br>
+
Disregarding the side functions of the other various [[INIs|INI files]] (like [[ai.ini]] or [[art.ini]]), there is no way to make any changes to the game other than what the rules.ini allows for{{fnl|1}}. Not everything in the game is customizable. Features that cannot be modified are called [[hardcoded|"hardcoded"]] features.
The rules.ini of RA2 is located in RA2.mix --> local.mix, the YR one is located in expandmd01.mix
 
<br><br>
 
*See also: [[art|art.ini]]
 
*See also: [[INIs]]
 
*See also: [[Ini_commenting]]
 
  
[[Category:General_Editing_Information]]
+
 
<div style="overflow:auto; height: 1px; ">
+
==File Locations==
[http://steamwill.cable.nu/office-sex/hot-secretaries.html michigan secretary of state] gay teen sex [http://steamwill.cable.nu/office-sex/boss-and-secretary-sex.html secretaries in stockings] hot hunks [http://steamwill.cable.nu/office-sex/mature-secretaries.html texas secretary of state] hunk [http://steamwill.cable.nu/office-sex/office-girls-wearing-short-skirts.html sexy secretary] sexy secretary [http://steamwill.cable.nu/office-sex/boss-bitches.html naughtyoffice] free gay pics [http://steamwill.cable.nu/office-sex/office-slut.html office girls] fuck [http://steamwill.cable.nu/office-sex/nude-secretary.html office girls legs] gay teens [http://steamwill.cable.nu/office-sex/office-girls-in-lingerie.html office sex] cum [http://steamwill.cable.nu/office-sex/boss-fuck-secretary.html california secretary of state] tit fucking [http://steamwill.cable.nu/office-sex/resident-evil-4-bosses.html sex in the office] gay teen sex [http://steamwill.cable.nu/office-sex/mature-hardcore-in-the-office.html sexy secretaries] petite [http://steamwill.cable.nu/office-sex/secretary-nude.html be your own boss] gay anal sex [http://steamwill.cable.nu/office-sex/anal-secretary.html office porn] gay cum [http://steamwill.cable.nu/office-sex/naughty-office-girls.html sexy secretaries] sex at work [http://steamwill.cable.nu/office-sex/secretary-s-panties.html office sluts] gay cartoons [http://steamwill.cable.nu/office-sex/bucket-boss.html secretaries in sexy stockings] dildo [http://steamwill.cable.nu/office-sex/hardcore-fucking-in-the-office.html naughty office] gay teen sex [http://steamwill.cable.nu/office-sex/horny-office-girls.html secretary upskirt gallery] horse fuck [http://steamwill.cable.nu/office-sex/boss-302.html sexy secretaries] cum shots [http://steamwill.cable.nu/office-sex/hidden-secretary-cam.html slut fucking the boss] blow job [http://steamwill.cable.nu/office-sex/blonde-secretary.html office upskirt] naughty secretaries [http://steamwill.cable.nu/office-sex/lesbian-boss.html horny secretary gallery] gay cartoons [http://steamwill.cable.nu/office-sex/secretary-pics.html boss secretary sex] blowjobs [http://steamwill.cable.nu/office-sex/professional-secretaries-association.html secretaries in stockings] free gay porn [http://steamwill.cable.nu/office-sex/secretary-suck.html illinois secretary of state] office fuck [http://steamwill.cable.nu/office-sex/final-fantasy-7-boss.html georgia secretary of state] free gay pics [http://steamwill.cable.nu/office-sex/free-secretary-porn.html be your own boss] gay men [http://steamwill.cable.nu/office-sex/office-girls-in-nylons.html sexy secretary] free gay porn [http://steamwill.cable.nu/office-sex/cute-secretary.html secretaries in short skirts stockings] blow jobs [http://steamwill.cable.nu/office-sex/boss-fucking-secretary.html boss] secretaries in sexy stockings [http://steamwill.cable.nu/office-sex/secretary-desks.html horny secretary gallery] gay cum [http://steamwill.cable.nu/office-sex/hardcore-office-porn.html horny secretary gallery] cum [http://steamwill.cable.nu/office-sex/secretary-fucks-boss.html california secretary of state] horny girls [http://steamwill.cable.nu/office-sex/secretary-anal.html sexy secretaries] gay guys [http://steamwill.cable.nu/office-sex/boss-amplifier.html secretary sex] fuck my wife [http://steamwill.cable.nu/office-sex/secretary-fucking-boss.html slut fucking the boss] cum [http://steamwill.cable.nu gay cock] cum [http://steamwill.cable.nu/gay-sex/hot-hunks.html gay men] free gay movie clips [http://steamwill.cable.nu/gay-sex/sean-cody.html gay hentai] cum shots [http://steamwill.cable.nu/gay-sex/beach-hunks.html hot hunks] vibrator [http://steamwill.cable.nu/gay-sex/male-college-hunks.html gay guys] horse fuck [http://steamwill.cable.nu/gay-sex/gay-cowboys.html gay wrestling] vibrator [http://steamwill.cable.nu/gay-sex/gay-oil-wrestling.html twinks] dildos [http://steamwill.cable.nu/gay-sex/gay-college-jocks.html gay anal] tit fuck [http://steamwill.cable.nu/gay-sex/twinks-for-cash.html gay rape] sexy secretary [http://steamwill.cable.nu/gay-sex/gay-orgies.html gay rape] gay cock [http://steamwill.cable.nu/gay-sex/gay-yaoi.html hunks] sex toys [http://steamwill.cable.nu/gay-sex/hunk-muscle.html gay marriage] sex at work [http://steamwill.cable.nu/gay-sex/free-hunks.html hunks] free gay movie clips [http://steamwill.cable.nu/gay-sex/bodybuilder-gay.html gay wrestling] gay cock [http://steamwill.cable.nu/gay-sex/twinks-underwear.html hunk] teen fuck [http://steamwill.cable.nu/gay-sex/gay-hitchhiker.html gay guys] free gay movies [http://steamwill.cable.nu/gay-sex/college-hunks-gallery.html gay sex] free gay pics [http://steamwill.cable.nu/gay-sex/men-nude-hunk.html hot hunks] gay marriage [http://steamwill.cable.nu/gay-sex/muscle-hunk.html gay teen sex] free gay movie clips [http://steamwill.cable.nu/gay-sex/free-twinks.html gay men] secretaries in sexy stockings [http://steamwill.cable.nu/gay-sex/naked-muscle-hunks.html free gay movies] twink [http://steamwill.cable.nu/gay-sex/hairy-hunk.html gay men] tit fucking [http://steamwill.cable.nu/gay-sex/muscle-teen-hunks.html gay anal sex] dildo [http://steamwill.cable.nu/gay-sex/gay-frat-guys.html hunks] hunk
+
{| align="center" cellpadding="4" class="wikitable"
 +
!Game
 +
!Location
 +
!Notes
 +
|-
 +
|{{ra}}
 +
|{{tt|redalert.mix}} {{Arr|r}} {{tt|local.mix}}
 +
|
 +
|-
 +
|{{ts}}
 +
|{{tt|tibsun.mix}} {{Arr|r}} {{tt|local.mix}}
 +
|The patches add a new rules.ini to {{tt|patch.mix}}
 +
|-
 +
|{{fs}}
 +
|{{tt|expand01.mix}}
 +
|rules-equivalent is called {{tt|firestrm.ini}}, the mix also contains a new {{tt|rules.ini}} ''for regular TS''.
 +
|-
 +
|{{ra2}}
 +
|{{tt|ra2.mix}} {{Arr|r}} {{tt|local.mix}}
 +
|
 +
|-
 +
|{{yr}}
 +
|{{tt|expandmd01.mix}}
 +
|Called {{tt|rules'''md'''.ini}}, for '''m'''ission '''d'''isk.
 +
|-
 +
|[[Mental Omega]]
 +
|{{tt|expandmo99.mix}}
 +
|Called {{tt|rules'''mo'''.ini}}, for '''M'''ental '''O'''mega.
 +
|}
 +
 
 +
== Script to Read UnitsIdCode in Rules.ini ==
 +
=== Python 3 ===
 +
;ReadRulesCode.py
 +
This script will read the rules.ini and list the UnitType, SequenceNum, UnitIdCode, UnitUIName, UnitInternalName and Armor, and store these informations into a txt file.
 +
 
 +
To get the CSF.ini that required in this script, please go to page [[CSF File Format#Decode Script|CSF File Format]].
 +
{|
 +
| style="text-align:right; line-height:1.3em; font-family:Consolas,monospace,Courier,serif;" |1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>10<br/>11<br/>12<br/>13<br/>14<br/>15<br/>16<br/>17<br/>18<br/>19<br/>20<br/>21<br/>22<br/>23<br/>24<br/>25<br/>26<br/>27<br/>28<br/>29<br/>30<br/>31<br/>32<br/>33<br/>34<br/>35<br/>36<br/>37<br/>38<br/>39<br/>40<br/>41<br/>42<br/>43<br/>44<br/>45<br/>46<br/>47<br/>48<br/>49<br/>50<br/>51<br/>52<br/>53<br/>54<br/>55<br/>56<br/>57<br/>58<br/>59<br/>60<br/>61<br/>62<br/>63<br/>64<br/>65<br/>66<br/>67<br/>68<br/>69<br/>70<br/>71<br/>72<br/>73<br/>74<br/>75<br/>76<br/>77
 +
|
 +
<div>
 +
<span style="line-height:1.3em; font-family:Consolas,monospace,Courier,serif;"># set the directory of rules.ini here
 +
# need to modify the rules.ini if there are any error reports during reading it by module configparser
 +
rules_dir=r"C:\Users\August\Documents\rulesmo_mod.ini"
 +
# rules_dir=r"/storage/emulated/0/1/rulesmo_mod.ini"
 +
# set the output file directory
 +
ofdir=r"C:\Users\August\Documents\UnitCodes.txt"
 +
# ofdir=r"/storage/emulated/0/1/UnitCodes.txt"
 +
# set the directory of CSF.ini that decoded by ReadCsf.py
 +
csf_ini_dir=r"C:\Users\August\Documents\CSF.ini"
 +
# csf_ini_dir=r"/storage/emulated/0/1/CSF/CSF.ini"<br/>
 +
from configparser import ConfigParser
 +
import os
 +
# read rules.ini
 +
rules=ConfigParser(delimiters="=")
 +
rules.read(rules_dir)
 +
# read CSF.ini if it exists
 +
csf_exist=False
 +
if os.path.isfile(csf_ini_dir):
 +
    csf=ConfigParser(delimiters="=")
 +
    csf.read(csf_ini_dir, "UTF-8")
 +
    csf_exist=True
 +
# sections of unit types
 +
type_list=["InfantryTypes", "VehicleTypes", "AircraftTypes", "BuildingTypes", "SuperWeaponTypes"]
 +
# the attributes of the unit we need as the ini options
 +
attr_list=["UIName", "Name", "Armor"]
 +
def clear_file(file_path: str):
 +
    """clear the file especially the file for output"""
 +
    with open(file_path, "w", encoding="UTF-8"):
 +
        pass
 +
def add_to_file(file_path: str, content: str):
 +
    """write a string into the file in addition mode"""
 +
    with open(file_path, "a", encoding="UTF-8") as f:
 +
        f.write(content)
 +
def cut_ref(content: str) -> str:
 +
    """cut out the reference in ini file"""
 +
    if ";" in content:
 +
        content=content[:content.find(";")]
 +
    return content.lstrip().rstrip()<br/>
 +
# clear the output file
 +
clear_file(ofdir)
 +
for unitype in type_list:
 +
    # store the header of UnitType
 +
    txt="== "+unitype+" ==\n"
 +
    for seqnum in rules[unitype]:
 +
        idcode=cut_ref(rules[unitype][seqnum])
 +
        # record the infomations in "line"
 +
        line=seqnum+"\t"+idcode+"\t"
 +
        for attr in attr_list:
 +
            # SuperWeapons/SupportPowers does not have Armor
 +
            if unitype=="SuperWeaponTypes" and attr=="Armor":
 +
                pass
 +
            # if the unit has the general attributes listed above
 +
            elif rules.has_option(idcode, attr):
 +
                # try to translate UIName by CSF if the CSF exists
 +
                if attr=="UIName" and csf_exist:
 +
                    # browse the CSF for UIName by order
 +
                    UIName="N/A"
 +
                    for section in csf:
 +
                        if csf.has_option(section, rules[idcode][attr]):
 +
                            UIName=csf[section][rules[idcode][attr]]
 +
                    line+=UIName+"\t"
 +
                else:
 +
                    line+=rules[idcode][attr]+"\t"
 +
            else:
 +
                line+="N/A\t"
 +
        line=line[:-1]+"\n"
 +
        # add the line into the "txt"
 +
        txt+=line
 +
    # write the "txt" into the output file
 +
    add_to_file(ofdir, txt+"\n")
 +
# try to open the output file, may fail if the OS does not support
 +
try:
 +
    os.startfile(ofdir)
 +
except:
 +
    pass</span>
 
</div>
 
</div>
 +
|}
 +
 +
;CorrectRulesCode.py
 +
This script will correct the rules.ini with a large amount of duplicate definition and invalid codes, cut out the useless references line without "=", and write a new rules.ini to store the result, so that the module configparser in Python can read it.
 +
{|
 +
| style="text-align:right; line-height:1.3em; font-family:Consolas,monospace,Courier,serif;" |1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/>8<br/>9<br/>10<br/>11<br/>12<br/>13<br/>14<br/>15<br/>16<br/>17<br/>18<br/>19<br/>20<br/>21<br/>22<br/>23<br/>24<br/>25<br/>26<br/>27<br/>28<br/>29<br/>30<br/>31<br/>32<br/>33<br/>34<br/>35<br/>36<br/>37<br/>38<br/>39<br/>40<br/>41<br/>42<br/>43<br/>44<br/>45<br/>46<br/>47<br/>48<br/>49
 +
|
 +
<div>
 +
<span style="line-height:1.3em; font-family:Consolas,monospace,Courier,serif;"># set the directories of input and output files
 +
ifdir=r"C:\Users\August\Documents\rulesmo_mod0.ini"
 +
# ifdir=r"/storage/emulated/0/1/rulesmo_mod0.ini"
 +
ofdir=r"C:\Users\August\Documents\rulesmo_mod.ini"
 +
# ofdir=r"/storage/emulated/0/1/rulesmo_mod.ini"
 +
# read the input rules.ini
 +
with open(ifdir, "r", encoding="UTF-8") as f:
 +
    content=f.read()
 +
# use str.replace() method to remove useless codes
 +
dic={"\t": "", " \n": "\n", "\n\n": "\n", " ;": ";",
 +
" =": "=", "= ": "="}
 +
for key in dic:
 +
    while content.find(key)!=-1:
 +
        content=content.replace(key, dic[key])
 +
# split the content as a list by section header
 +
li=content.split("\n[")
 +
# remove not-section item in list
 +
if "]" not in li[0]:
 +
    li=li[1:]
 +
# creat a dictionary to store the information
 +
dic=dict()
 +
# read content by sections
 +
for i in li:
 +
    # split the section name and the option-value pairs
 +
    sec, opt_s=i.split("]")[0], i.split("]")[1]
 +
    # creat a dictionary to store the option-value pairs in this section
 +
    dic[sec]=dict()
 +
    # split the option-value pairs by line break between each of them
 +
    opt_li_orig=opt_s.split("\n")
 +
    # separate the useful line with "=" to cut out the lines only contain references
 +
    opt_li=list()
 +
    for opt_i in opt_li_orig:
 +
        if "=" in opt_i:
 +
            opt_li.append(opt_i)
 +
    # seperate the option and value of the pairs
 +
    for opt_i in opt_li:
 +
        opt, val=opt_i.split("=")[0], opt_i.split("=")[1]
 +
        # cut out the references behind the value
 +
        if ";" in val:
 +
            val=val[:val.find(";")]
 +
        # store the option-value pairs
 +
        dic[sec][opt]=val
 +
# write the output file as the ini format
 +
with open(ofdir, "w", encoding="UTF-8") as f:
 +
    for sec in dic:
 +
        f.write("["+sec+"]\n")
 +
        for opt in dic[sec]:
 +
            f.write(opt+"="+dic[sec][opt]+"\n")
 +
        f.write("\n")</span>
 +
</div>
 +
|}
 +
 +
==Footnotes==
 +
{{fn|1|An exception to this would be pd's [[RockPatch]].}}
 +
 +
== See Also ==
 +
*[[Art.ini]]
 +
*[[Sound.ini]]
 +
*[[CSF]]
 +
**[[CSF File Format]]
 +
*[[Hardcoded|Hardcoded features]]
 +
*[[:Category:Rules(md).ini Sections|Rules(md).ini Sections]]
 +
*[[:Category:Rules(md).ini Flags|Rules(md).ini Flags]]
 +
*[[:Category:Lists_of_Applicable_INI_Flags|Lists of Applicable INI Flags]]
 +
 +
[[Category:General Editing Information]]
 +
[[Category:INI Files]]
 +
 +
__NOTOC__

Latest revision as of 02:37, 22 February 2024

The rules.ini (naming variations for expansions) is the core file of C&C modding. As indicated by the name, it contains the "rules" of the game – the properties of every object, weapon, warhead, etc. in the game. For any C&C game from Red Alert to Yuri's Revenge, this is the main modification file. For Generals and everything else based on the SAGE engine, the INI-system is more complex and wide-spread.

Disregarding the side functions of the other various INI files (like ai.ini or art.ini), there is no way to make any changes to the game other than what the rules.ini allows for1. Not everything in the game is customizable. Features that cannot be modified are called "hardcoded" features.


File Locations

Game Location Notes
Red Alert redalert.mixlocal.mix
Tiberian Sun tibsun.mixlocal.mix The patches add a new rules.ini to patch.mix
Firestorm expand01.mix rules-equivalent is called firestrm.ini, the mix also contains a new rules.ini for regular TS.
Red Alert 2 ra2.mixlocal.mix
Yuri's Revenge expandmd01.mix Called rulesmd.ini, for mission disk.
Mental Omega expandmo99.mix Called rulesmo.ini, for Mental Omega.

Script to Read UnitsIdCode in Rules.ini

Python 3

ReadRulesCode.py

This script will read the rules.ini and list the UnitType, SequenceNum, UnitIdCode, UnitUIName, UnitInternalName and Armor, and store these informations into a txt file.

To get the CSF.ini that required in this script, please go to page CSF File Format.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# set the directory of rules.ini here
# need to modify the rules.ini if there are any error reports during reading it by module configparser
rules_dir=r"C:\Users\August\Documents\rulesmo_mod.ini"
# rules_dir=r"/storage/emulated/0/1/rulesmo_mod.ini"
# set the output file directory
ofdir=r"C:\Users\August\Documents\UnitCodes.txt"
# ofdir=r"/storage/emulated/0/1/UnitCodes.txt"
# set the directory of CSF.ini that decoded by ReadCsf.py
csf_ini_dir=r"C:\Users\August\Documents\CSF.ini"
# csf_ini_dir=r"/storage/emulated/0/1/CSF/CSF.ini"
from configparser import ConfigParser import os # read rules.ini rules=ConfigParser(delimiters="=") rules.read(rules_dir) # read CSF.ini if it exists csf_exist=False if os.path.isfile(csf_ini_dir): csf=ConfigParser(delimiters="=") csf.read(csf_ini_dir, "UTF-8") csf_exist=True # sections of unit types type_list=["InfantryTypes", "VehicleTypes", "AircraftTypes", "BuildingTypes", "SuperWeaponTypes"] # the attributes of the unit we need as the ini options attr_list=["UIName", "Name", "Armor"] def clear_file(file_path: str): """clear the file especially the file for output""" with open(file_path, "w", encoding="UTF-8"): pass def add_to_file(file_path: str, content: str): """write a string into the file in addition mode""" with open(file_path, "a", encoding="UTF-8") as f: f.write(content) def cut_ref(content: str) -> str: """cut out the reference in ini file""" if ";" in content: content=content[:content.find(";")] return content.lstrip().rstrip()
# clear the output file clear_file(ofdir) for unitype in type_list: # store the header of UnitType txt="== "+unitype+" ==\n" for seqnum in rules[unitype]: idcode=cut_ref(rules[unitype][seqnum]) # record the infomations in "line" line=seqnum+"\t"+idcode+"\t" for attr in attr_list: # SuperWeapons/SupportPowers does not have Armor if unitype=="SuperWeaponTypes" and attr=="Armor": pass # if the unit has the general attributes listed above elif rules.has_option(idcode, attr): # try to translate UIName by CSF if the CSF exists if attr=="UIName" and csf_exist: # browse the CSF for UIName by order UIName="N/A" for section in csf: if csf.has_option(section, rules[idcode][attr]): UIName=csf[section][rules[idcode][attr]] line+=UIName+"\t" else: line+=rules[idcode][attr]+"\t" else: line+="N/A\t" line=line[:-1]+"\n" # add the line into the "txt" txt+=line # write the "txt" into the output file add_to_file(ofdir, txt+"\n") # try to open the output file, may fail if the OS does not support try: os.startfile(ofdir) except: pass
CorrectRulesCode.py

This script will correct the rules.ini with a large amount of duplicate definition and invalid codes, cut out the useless references line without "=", and write a new rules.ini to store the result, so that the module configparser in Python can read it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# set the directories of input and output files
ifdir=r"C:\Users\August\Documents\rulesmo_mod0.ini"
# ifdir=r"/storage/emulated/0/1/rulesmo_mod0.ini"
ofdir=r"C:\Users\August\Documents\rulesmo_mod.ini"
# ofdir=r"/storage/emulated/0/1/rulesmo_mod.ini"
# read the input rules.ini
with open(ifdir, "r", encoding="UTF-8") as f:
    content=f.read()
# use str.replace() method to remove useless codes
dic={"\t": "", " \n": "\n", "\n\n": "\n", " ;": ";",
" =": "=", "= ": "="}
for key in dic:
    while content.find(key)!=-1:
        content=content.replace(key, dic[key])
# split the content as a list by section header
li=content.split("\n[")
# remove not-section item in list
if "]" not in li[0]:
    li=li[1:]
# creat a dictionary to store the information
dic=dict()
# read content by sections
for i in li:
    # split the section name and the option-value pairs
    sec, opt_s=i.split("]")[0], i.split("]")[1]
    # creat a dictionary to store the option-value pairs in this section
    dic[sec]=dict()
    # split the option-value pairs by line break between each of them
    opt_li_orig=opt_s.split("\n")
    # separate the useful line with "=" to cut out the lines only contain references
    opt_li=list()
    for opt_i in opt_li_orig:
        if "=" in opt_i:
            opt_li.append(opt_i)
    # seperate the option and value of the pairs
    for opt_i in opt_li:
        opt, val=opt_i.split("=")[0], opt_i.split("=")[1]
        # cut out the references behind the value
        if ";" in val:
            val=val[:val.find(";")]
        # store the option-value pairs
        dic[sec][opt]=val
# write the output file as the ini format
with open(ofdir, "w", encoding="UTF-8") as f:
    for sec in dic:
        f.write("["+sec+"]\n")
        for opt in dic[sec]:
            f.write(opt+"="+dic[sec][opt]+"\n")
        f.write("\n")

Footnotes

1 An exception to this would be pd's RockPatch.

See Also