удаление модов

This commit is contained in:
Евгений Храмов 2023-05-14 21:57:51 +03:00
parent 779c15d301
commit 9eb8987989

79
hlna.py

@ -17,9 +17,9 @@ from rcon.source import Client
home_dir = Path.home()
logging.basicConfig(stream=sys.stderr, level=logging.CRITICAL)
class UnpackException(Exception):
pass
@ -59,10 +59,12 @@ def path_server():
yaml_create(game := "path_server", dir_server)
return dir_server
@click.group()
def hlna():
pass
def unpack(src, dst):
with open(src, 'rb') as f:
sigver = struct.unpack('q', f.read(8))[0]
@ -73,13 +75,14 @@ def unpack(src, dst):
size_packed = struct.unpack('q', packed)[0]
size_unpacked = struct.unpack('q', unpacked)[0]
#Verify the integrity of the Archive Header
# Verify the integrity of the Archive Header
if sigver == 2653586369:
if isinstance(size_unpacked_chunk, int) and isinstance(size_packed , int) and isinstance(size_unpacked , int):
if isinstance(size_unpacked_chunk, int) and isinstance(size_packed, int) and isinstance(size_unpacked, int):
logging.info("Archive is valid.")
logging.debug(f"Archive header size information. Unpacked Chunk: {size_unpacked_chunk}({unpacked_chunk}) Full Packed: {size_packed}({packed}) Full Unpacked: {size_unpacked}({unpacked})")
logging.debug(
f"Archive header size information. Unpacked Chunk: {size_unpacked_chunk}({unpacked_chunk}) Full Packed: {size_packed}({packed}) Full Unpacked: {size_unpacked}({unpacked})")
#Obtain the Archive Compression Index
# Obtain the Archive Compression Index
compression_index = []
size_indexed = 0
while size_indexed < size_unpacked:
@ -89,26 +92,27 @@ def unpack(src, dst):
uncompressed = struct.unpack('q', raw_uncompressed)[0]
compression_index.append((compressed, uncompressed))
size_indexed += uncompressed
logging.debug(f"{len(compression_index)}: {size_indexed}/{size_unpacked} ({compressed}/{uncompressed}) - {raw_compressed} - {raw_uncompressed}")
logging.debug(
f"{len(compression_index)}: {size_indexed}/{size_unpacked} ({compressed}/{uncompressed}) - {raw_compressed} - {raw_uncompressed}")
if size_unpacked != size_indexed:
msg = f"Header-Index mismatch. Header indicates it should only have {size_unpacked} bytes when uncompressed but the index indicates {size_indexed} bytes."
logging.critical(msg)
raise CorruptUnpackException(msg)
#Read the actual archive data
# Read the actual archive data
data = b''
read_data = 0
for compressed, uncompressed in compression_index:
compressed_data = f.read(compressed)
uncompressed_data = zlib.decompress(compressed_data)
#Verify the size of the data is consistent with the archives index
# Verify the size of the data is consistent with the archives index
if len(uncompressed_data) == uncompressed:
data += uncompressed_data
read_data += 1
#Verify there is only one partial chunk
# Verify there is only one partial chunk
if len(uncompressed_data) != size_unpacked_chunk and read_data != len(compression_index):
msg = f"Index contains more than one partial chunk: was {len(uncompressed_data)} when the full chunk size is {size_unpacked_chunk}, chunk {read_data}/{len(compression_index)}"
logging.critical(msg)
@ -126,7 +130,7 @@ def unpack(src, dst):
logging.critical(msg)
raise SignatureUnpackException(msg)
#Write the extracted data to disk
# Write the extracted data to disk
with open(dst, 'wb') as f:
f.write(data)
logging.info("Archive has been extracted.")
@ -338,7 +342,9 @@ def config_ark(list_config=list_config):
else:
listen_server = True
yaml_create(game := "ARK", dir_server := "", cluster_server, map_s, list_config[-1], port_server, query_port, rcon_enabled, rcon_port, adminpassword_server, password_server, max_players, cluster_id, cluster_dir_override, listen_server)
yaml_create(game := "ARK", dir_server := "", cluster_server, map_s, list_config[-1], port_server, query_port,
rcon_enabled, rcon_port, adminpassword_server, password_server, max_players, cluster_id,
cluster_dir_override, listen_server)
def config_7daystodie():
@ -361,8 +367,10 @@ def xml_parser():
print("Я не умею парсить))")
def yaml_create(game, dir_server="", cluster_server="", map_s="", name_server="", port_server="", query_port="", rcon_enabled="", rcon_port="",
adminpassword_server="", password_server="", max_players="", id_mods_ark="", cluster_id="", cluster_dir_override="", listen_server=""):
def yaml_create(game, dir_server="", cluster_server="", map_s="", name_server="", port_server="", query_port="",
rcon_enabled="", rcon_port="",
adminpassword_server="", password_server="", max_players="", id_mods_ark="", cluster_id="",
cluster_dir_override="", listen_server=""):
if game == "ARK":
print_line(dir_maps_ark)
print_line(name_server)
@ -444,7 +452,8 @@ WantedBy=default.target
@hlna.command(help='Для скачивания и установки модов')
@click.option('-g', help="Название игры для запуска. (ark, 7days")
@click.option('-m', default='all', help="Название карты для запуска или all для запуска все карт")
def modinstall(g, m):
@click.option("-i/-u", default=True, help="-i установить моды, -u удалить моды")
def mod(g, m, i):
if g == "ark":
id_game_workshop = "346110"
if not os.path.isdir(dir_workshop_ark):
@ -452,15 +461,18 @@ def modinstall(g, m):
id_mods_ark = input("""Укажите id модов через запятую
:""").split(",")
for id_mod in id_mods_ark:
os.system(f"steamcmd +login anonymous +workshop_download_item {id_game_workshop} {id_mod} +quit")
modextract(id_mod, id_game_workshop)
def modextract(id_mod, id_game_workshop):
dir_steam_workshop = f"{dir_workshop_ark}/content/{id_game_workshop}/{id_mod}/WindowsNoEditor"
dir_ark_mods = f"{dir_mods_ark}/{id_mod}"
dir_extract = dir_ark_mods
if i:
os.system(f"steamcmd +login anonymous +workshop_download_item {id_game_workshop} {id_mod} +quit")
modextract(id_mod, id_game_workshop, dir_ark_mods)
else:
os.system(f"rm -rf {dir_ark_mods}")
os.system(f"rm {dir_mods_ark}/{id_mod}.mod")
def modextract(id_mod, id_game_workshop, dir_ark_mods):
dir_steam_workshop = f"{dir_workshop_ark}/content/{id_game_workshop}/{id_mod}/WindowsNoEditor"
dir_extract = dir_ark_mods
if id_mod == "111111111":
return
@ -483,7 +495,8 @@ def modextract(id_mod, id_game_workshop):
os.system(f"rm -rf {dir_ark_mods}")
os.system(f"mv -f {dir_steam_workshop} {dir_ark_mods}")
modname = subprocess.check_output(['curl', '-s', 'https://steamcommunity.com/sharedfiles/filedetails/?id={}'.format(id_mod)]).decode('utf-8')
modname = subprocess.check_output(
['curl', '-s', 'https://steamcommunity.com/sharedfiles/filedetails/?id={}'.format(id_mod)]).decode('utf-8')
modname = re.search(r'<div class="workshopItemTitle">(.+)</div>', modname)
modname = modname and modname.group(1)
@ -494,8 +507,8 @@ def modextract(id_mod, id_game_workshop):
with open(f"{dir_extract}/mod.info", "rb") as modinfo:
data = modinfo.read()
mapnamelen = struct.unpack_from("<L", data, 0)[0]
mapname = data[4:mapnamelen+3]
nummaps = struct.unpack_from("<L", data, mapnamelen+4)[0]
mapname = data[4:mapnamelen + 3]
nummaps = struct.unpack_from("<L", data, mapnamelen + 4)[0]
pos = mapnamelen + 8
modname = (modname.encode() or mapname.decode()) + b'\x00'
modnamelen = len(modname)
@ -504,10 +517,11 @@ def modextract(id_mod, id_game_workshop):
with open(f"{dir_ark_mods}.mod", "wb") as mod:
print(type(modnamelen))
print(type(modpathlen))
mod.write(struct.pack('<LLL{}sL{}sL'.format(modnamelen, modpathlen), int(id_mod), 0, modnamelen, modname, modpathlen, modpath, nummaps))
mod.write(struct.pack('<LLL{}sL{}sL'.format(modnamelen, modpathlen), int(id_mod), 0, modnamelen, modname,
modpathlen, modpath, nummaps))
for mapnum in range(nummaps):
mapfilelen = struct.unpack_from("<L", data, pos)[0]
mapfile = data[mapnamelen+12:mapnamelen+12+mapfilelen]
mapfile = data[mapnamelen + 12:mapnamelen + 12 + mapfilelen]
mod.write(struct.pack("<L%ds" % mapfilelen, mapfilelen, mapfile))
pos = pos + 4 + mapfilelen
mod.write(b"\x33\xFF\x22\xFF\x02\x00\x00\x00\x01")
@ -525,9 +539,9 @@ def modextract(id_mod, id_game_workshop):
os.makedirs(dir_ark_mods)
@ hlna.command()
@ click.option("-m", required=True, help="Название Сервера")
@ click.option("-e/-d", default=True, help="-e активировать карты, -d деактивировать")
@hlna.command()
@click.option("-m", required=True, help="Название Сервера")
@click.option("-e/-d", default=True, help="-e активировать карты, -d деактивировать")
def enablemap(m, e):
"""Включение/выключение карт"""
m = m.split(",")
@ -663,7 +677,7 @@ def start_stop(action, g, m, list_config=list_config):
for ns, v in dict_mapname.items():
if v in m:
names_serverstart.append(ns)
if list_config != []: #Перенести выше для проверки наличия конфигов
if list_config != []: # Перенести выше для проверки наличия конфигов
if m == "all":
names_serverstart = dict_allmapname
print(f"Выполняется для карт(-ы) {names_serverstart}")
@ -671,7 +685,8 @@ def start_stop(action, g, m, list_config=list_config):
names_serverstart = choose_map(names_serverstart)
for i in names_serverstart:
data = read_yaml(i, game="ARK")
y = os.system(f"~/git/hln-a/hlna.py rcon SaveWorld -m {i}") if action == "restart" or action == "stop" else ""
y = os.system(
f"~/git/hln-a/hlna.py rcon SaveWorld -m {i}") if action == "restart" or action == "stop" else ""
x = os.system(f"systemctl --user {action} ark_{data['SessionName'].lower()}.service")
print_line(y)
if x == 0:
@ -763,7 +778,6 @@ else:
print_line(data['path_server'])
dir_server = data['path_server']
dir_unit = f"{home_dir}/.config/systemd/user/"
dir_logs = f"{dir_config}logs/"
@ -783,6 +797,5 @@ create_dir(dir_unit)
create_dir(dir_config)
create_dir(dir_logs)
if __name__ == '__main__':
hlna()