Page Menu
Home
Wildfire Games
Search
Configure Global Search
Log In
Paste
P290
A26toA27
Active
Public
Actions
Authored by
Stan
on Dec 27 2022, 6:59 PM.
Edit Paste
Archive Paste
View Raw File
Subscribe
Mute Notifications
Award Token
Flag For Later
Tags
None
Subscribers
None
#!/usr/bin/env python3
# -*- mode: python-mode; python-indent-offset: 4; -*-
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: © 2022 Stanislas Daniel Claude Dolcini
from
argparse
import
ArgumentParser
from
logging
import
getLogger
,
StreamHandler
,
INFO
,
WARNING
,
Formatter
,
Filter
from
pathlib
import
Path
from
sys
import
stdout
,
stderr
import
xml.etree.ElementTree
as
ET
import
os
import
shutil
import
json
import
fileinput
LOGGER_FIRST_INIT
=
True
class
SingleLevelFilter
(
Filter
):
def
__init__
(
self
,
passlevel
,
reject
):
self
.
passlevel
=
passlevel
self
.
reject
=
reject
def
filter
(
self
,
record
):
if
self
.
reject
:
return
(
record
.
levelno
!=
self
.
passlevel
)
else
:
return
(
record
.
levelno
==
self
.
passlevel
)
class
BaseFixer
():
def
__init__
(
self
,
vfs_root
,
verbose
=
False
):
self
.
logger
=
self
.
__init_logger
()
self
.
vfs_root
=
Path
(
vfs_root
)
self
.
verbose
=
verbose
self
.
files
=
[]
def
__init_logger
(
self
):
global
LOGGER_FIRST_INIT
logger
=
getLogger
(
__name__
)
if
LOGGER_FIRST_INIT
:
logger
.
setLevel
(
INFO
)
# create a console handler, seems nicer to Windows and for future uses
ch
=
StreamHandler
(
stdout
)
ch
.
setLevel
(
INFO
)
ch
.
setFormatter
(
Formatter
(
'
%(levelname)s
-
%(message)s
'
))
f1
=
SingleLevelFilter
(
INFO
,
False
)
ch
.
addFilter
(
f1
)
logger
.
addHandler
(
ch
)
errorch
=
StreamHandler
(
stderr
)
errorch
.
setLevel
(
WARNING
)
errorch
.
setFormatter
(
Formatter
(
'
%(levelname)s
-
%(message)s
'
))
logger
.
addHandler
(
errorch
)
LOGGER_FIRST_INIT
=
False
return
logger
def
fix_style
(
self
,
xml_path
):
changes
=
[
[
' />'
,
'/>'
],
[
"version='1.0'"
,
'version="1.0"'
],
[
"'utf-8'"
,
'"utf-8"'
]
]
for
line
in
fileinput
.
input
(
xml_path
,
inplace
=
True
):
for
change
in
changes
:
line
=
line
.
replace
(
change
[
0
],
change
[
1
])
print
(
line
,
end
=
""
)
with
open
(
xml_path
,
'a'
,
encoding
=
'utf-8'
)
as
file
:
file
.
write
(
'
\n
'
)
def
indent
(
self
,
elem
,
level
=
0
,
more_sibs
=
False
):
i
=
"
\n
"
if
level
:
i
+=
(
level
-
1
)
*
' '
num_kids
=
len
(
elem
)
if
num_kids
:
if
not
elem
.
text
or
not
elem
.
text
.
strip
():
elem
.
text
=
i
+
" "
if
level
:
elem
.
text
+=
' '
count
=
0
for
kid
in
elem
:
self
.
indent
(
kid
,
level
+
1
,
count
<
num_kids
-
1
)
count
+=
1
if
not
elem
.
tail
or
not
elem
.
tail
.
strip
():
elem
.
tail
=
i
if
more_sibs
:
elem
.
tail
+=
' '
else
:
if
level
and
(
not
elem
.
tail
or
not
elem
.
tail
.
strip
()):
elem
.
tail
=
i
if
more_sibs
:
elem
.
tail
+=
' '
def
sort
(
self
,
root
):
# sort the first layer
root
[:]
=
sorted
(
root
,
key
=
lambda
child
:
(
child
.
tag
,
child
.
get
(
'name'
)))
# sort the second layer
for
c
in
root
:
c
[:]
=
sorted
(
c
,
key
=
lambda
child
:
(
child
.
tag
,
child
.
get
(
'name'
)))
for
cp
in
c
:
cp
[:]
=
sorted
(
cp
,
key
=
lambda
child
:
(
child
.
tag
,
child
.
get
(
'name'
)))
for
scp
in
cp
:
scp
[:]
=
sorted
(
scp
,
key
=
lambda
child
:
(
child
.
tag
,
child
.
get
(
'name'
)))
def
save_xml_file
(
self
,
tree
,
root
,
xml_file
,
sort
=
True
):
if
sort
:
self
.
sort
(
root
)
self
.
indent
(
root
)
tree
.
write
(
xml_file
,
xml_declaration
=
True
,
encoding
=
'utf-8'
)
self
.
fix_style
(
xml_file
)
def
add_files
(
self
,
path
,
extensions
:
tuple
[
str
]):
self
.
files
=
[]
if
os
.
path
.
isfile
(
str
(
self
.
vfs_root
)):
self
.
files
.
append
(
self
.
vfs_root
)
elif
os
.
path
.
isdir
(
str
(
self
.
vfs_root
)):
for
root
,
_
,
files
in
os
.
walk
(
str
(
self
.
vfs_root
)):
for
name
in
files
:
file_path
=
os
.
path
.
join
(
root
,
name
)
if
os
.
path
.
isfile
(
file_path
)
and
path
in
file_path
and
name
.
endswith
(
extensions
):
self
.
files
.
append
(
file_path
)
if
self
.
verbose
:
if
len
(
self
.
files
)
>
0
:
self
.
logger
.
info
(
f
"Found {len(self.files)} file(s)."
)
else
:
self
.
logger
.
info
(
f
"No files were found."
)
class
ActorsWithMaterialsWithNoSpecMapFixer
(
BaseFixer
):
def
__init__
(
self
,
vfs_root
,
verbose
=
False
):
BaseFixer
.
__init__
(
self
,
vfs_root
,
verbose
)
self
.
add_files
(
os
.
path
.
join
(
'art'
,
'actors'
),
tuple
(
".xml"
))
self
.
changes
=
[
[
'basic_spec'
,
'no_trans_spec'
],
[
"blend_spec"
,
'basic_trans_spec'
],
[
"objectcolor_spec"
,
'objectcolor_specmap'
],
[
"playercolor_spec"
,
'player_trans_spec'
],
]
def
process_actor
(
self
,
actorNode
):
materialCmp
=
actorNode
.
find
(
'material'
)
if
materialCmp
is
not
None
:
changed
=
False
if
(
materialCmp
.
text
==
'basic_spec.xml'
or
materialCmp
.
text
==
'blend_spec.xml'
or
materialCmp
.
text
==
'objectcolor_spec.xml'
or
materialCmp
.
text
==
'playercolor_spec.xml'
):
for
group
in
actorNode
:
for
variant
in
group
:
cmpTextures
=
variant
.
find
(
'textures'
)
if
cmpTextures
is
not
None
:
found
=
False
for
texture
in
cmpTextures
:
if
texture
.
attrib
[
'name'
]
==
'specTex'
:
found
=
True
break
if
found
:
continue
tag
=
ET
.
SubElement
(
cmpTextures
,
'texture'
)
tag
.
attrib
[
'name'
]
=
'specTex'
tag
.
attrib
[
'file'
]
=
'null_white.dds'
changed
=
True
for
change
in
self
.
changes
:
materialCmp
.
text
=
materialCmp
.
text
.
replace
(
change
[
0
],
change
[
1
])
return
changed
return
False
def
run
(
self
):
count
=
0
for
file
in
self
.
files
:
tree
=
ET
.
parse
(
file
)
root
=
tree
.
getroot
()
changed
=
False
if
root
.
tag
==
'actor'
:
changed
=
self
.
process_actor
(
root
)
elif
root
.
tag
==
'qualitylevels'
:
for
actor
in
root
:
changed
|=
self
.
process_actor
(
actor
)
if
changed
:
self
.
save_xml_file
(
tree
,
root
,
file
,
False
)
count
=
count
+
1
self
.
logger
.
info
(
f
"Fixed {count} file(s)."
)
if
__name__
==
'__main__'
:
parser
=
ArgumentParser
(
description
=
'A26 to A27 converter.'
)
parser
.
add_argument
(
'-r'
,
'--root'
,
action
=
'store'
,
dest
=
'root'
,
default
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
)))
parser
.
add_argument
(
'-m'
,
'--mod'
,
action
=
'store'
,
dest
=
'mod'
,
default
=
'public'
)
parser
.
add_argument
(
'-v'
,
'--verbose'
,
action
=
'store_true'
,
default
=
False
,
help
=
"Be verbose."
)
args
=
parser
.
parse_args
()
script_dir
=
args
.
root
mod_name
=
args
.
mod
print
(
f
"Running in {Path(script_dir) / mod_name}"
)
print
(
"Fixing Actors using no specmap..."
)
template_fixer
=
ActorsWithMaterialsWithNoSpecMapFixer
(
Path
(
script_dir
)
/
mod_name
)
template_fixer
.
run
()
Event Timeline
Stan
created this paste.
Dec 27 2022, 6:59 PM
Stan
created this object with visibility "Public (No Login Required)".
Stan
mentioned this in
rP27308: Remove usages of `basic_spec` `basic_blend` `playercolor_spec` and…
.
Dec 27 2022, 7:22 PM
Stan
edited the content of this paste.
(Show Details)
Dec 27 2022, 7:34 PM
Stan
edited the content of this paste.
(Show Details)
Dec 28 2022, 11:24 AM
Log In to Comment