Page Menu
Home
Wildfire Games
Search
Configure Global Search
Log In
Paste
P291
Actor to Quality levels
Active
Public
Actions
Authored by
Stan
on Jan 5 2023, 12:24 AM.
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: © 2023 Stanislas Daniel Claude Dolcini
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
fileinput
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
):
logger
=
getLogger
(
__name__
)
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
)
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
(
"Found"
{
len
(
self
.
files
)}
file
(
s
)
.
")
else
:
self
.
logger
.
info
(
f
"No files were found."
)
class
ActorToQualityLevel
(
BaseFixer
):
def
__init__
(
self
,
vfs_root
,
verbose
=
False
):
BaseFixer
.
__init__
(
self
,
vfs_root
,
verbose
)
self
.
add_files
(
''
,
tuple
(
".xml"
))
def
process_actor
(
self
,
actorNode
):
actorNode
.
tag
=
"qualitylevels"
tag1
=
ET
.
Element
(
"actor"
)
tag1
.
attrib
[
'quality'
]
=
'low'
tag1
.
attrib
[
'inline'
]
=
''
tag2
=
ET
.
Element
(
"actor"
)
tag2
.
attrib
[
'quality'
]
=
'medium'
tag2
.
attrib
[
'inline'
]
=
''
tag3
=
ET
.
Element
(
"actor"
)
tag3
.
attrib
[
'inline'
]
=
''
tag
=
ET
.
Element
(
"inline"
)
tag
.
attrib
[
'version'
]
=
'1'
groups
=
list
()
for
group
in
reversed
(
actorNode
):
if
group
.
tag
==
'castshadow'
:
group
.
attrib
[
'minquality'
]
=
'medium'
groups
.
append
(
group
)
actorNode
.
remove
(
group
)
actorNode
.
append
(
tag1
)
actorNode
.
append
(
tag2
)
actorNode
.
append
(
tag3
)
for
group
in
reversed
(
groups
):
tag
.
append
(
group
)
actorNode
.
append
(
tag
)
meshGroup
=
ET
.
Element
(
"group"
)
meshes
=
[]
for
group
in
tag
:
if
group
.
tag
==
'group'
:
for
variant
in
group
:
cmpMesh
=
variant
.
find
(
"mesh"
)
if
cmpMesh
==
None
:
continue
meshes
.
append
(
cmpMesh
.
text
)
variant
.
remove
(
cmpMesh
)
for
mesh
in
meshes
:
file_name
=
os
.
path
.
basename
(
mesh
)
file_path
=
mesh
.
replace
(
os
.
path
.
basename
(
mesh
),
""
)
# DEFAULT
meshVariant
=
ET
.
SubElement
(
meshGroup
,
"variant"
)
meshVariant
.
attrib
[
'minquality'
]
=
'high'
meshVariant
.
attrib
[
'frequency'
]
=
'1'
meshVariant
.
attrib
[
'name'
]
=
'mesh-variant'
cmpMesh
=
ET
.
SubElement
(
meshVariant
,
"mesh"
)
cmpMesh
.
text
=
mesh
# MEDIUM
meshVariant
=
ET
.
SubElement
(
meshGroup
,
"variant"
)
meshVariant
.
attrib
[
'maxquality'
]
=
'high'
meshVariant
.
attrib
[
'minquality'
]
=
'medium'
meshVariant
.
attrib
[
'frequency'
]
=
'1'
meshVariant
.
attrib
[
'name'
]
=
'mesh-variant'
cmpMesh
=
ET
.
SubElement
(
meshVariant
,
"mesh"
)
cmpMesh
.
text
=
f
"{file_path}medium/{file_name}"
# LOW
meshVariant
=
ET
.
SubElement
(
meshGroup
,
"variant"
)
meshVariant
.
attrib
[
'maxquality'
]
=
'medium'
meshVariant
.
attrib
[
'frequency'
]
=
'1'
meshVariant
.
attrib
[
'name'
]
=
'mesh-variant'
cmpMesh
=
ET
.
SubElement
(
meshVariant
,
"mesh"
)
cmpMesh
.
text
=
f
"{file_path}low/{file_name}"
tag
.
insert
(
1
if
tag
.
find
(
'castshadow'
)
is
None
else
0
,
meshGroup
)
return
True
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'
:
continue
if
changed
:
self
.
save_xml_file
(
tree
,
root
,
file
,
False
)
count
=
count
+
1
self
.
logger
.
info
(
f
"Fixed {count} file(s)."
)
if
__name__
==
'__main__'
:
script_dir
=
"."
mod_name
=
"public"
print
(
f
"Running in {Path(script_dir) / mod_name}"
)
print
(
"Converting to quality levels..."
)
template_fixer
=
ActorToQualityLevel
(
Path
(
script_dir
)
/
mod_name
,
True
)
template_fixer
.
run
()
Event Timeline
Stan
created this paste.
Jan 5 2023, 12:24 AM
Stan
created this object with visibility "Public (No Login Required)".
Log In to Comment