удаление модов
This commit is contained in:
		
							
								
								
									
										75
									
								
								hlna.py
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								hlna.py
									
									
									
									
									
								
							@@ -17,9 +17,9 @@ from rcon.source import Client
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
home_dir = Path.home()
 | 
					home_dir = Path.home()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
logging.basicConfig(stream=sys.stderr, level=logging.CRITICAL)
 | 
					logging.basicConfig(stream=sys.stderr, level=logging.CRITICAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UnpackException(Exception):
 | 
					class UnpackException(Exception):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,10 +59,12 @@ def path_server():
 | 
				
			|||||||
        yaml_create(game := "path_server", dir_server)
 | 
					        yaml_create(game := "path_server", dir_server)
 | 
				
			||||||
    return dir_server
 | 
					    return dir_server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@click.group()
 | 
					@click.group()
 | 
				
			||||||
def hlna():
 | 
					def hlna():
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def unpack(src, dst):
 | 
					def unpack(src, dst):
 | 
				
			||||||
    with open(src, 'rb') as f:
 | 
					    with open(src, 'rb') as f:
 | 
				
			||||||
        sigver = struct.unpack('q', f.read(8))[0]
 | 
					        sigver = struct.unpack('q', f.read(8))[0]
 | 
				
			||||||
@@ -73,13 +75,14 @@ def unpack(src, dst):
 | 
				
			|||||||
        size_packed = struct.unpack('q', packed)[0]
 | 
					        size_packed = struct.unpack('q', packed)[0]
 | 
				
			||||||
        size_unpacked = struct.unpack('q', unpacked)[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 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.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 = []
 | 
					                compression_index = []
 | 
				
			||||||
                size_indexed = 0
 | 
					                size_indexed = 0
 | 
				
			||||||
                while size_indexed < size_unpacked:
 | 
					                while size_indexed < size_unpacked:
 | 
				
			||||||
@@ -89,26 +92,27 @@ def unpack(src, dst):
 | 
				
			|||||||
                    uncompressed = struct.unpack('q', raw_uncompressed)[0]
 | 
					                    uncompressed = struct.unpack('q', raw_uncompressed)[0]
 | 
				
			||||||
                    compression_index.append((compressed, uncompressed))
 | 
					                    compression_index.append((compressed, uncompressed))
 | 
				
			||||||
                    size_indexed += 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:
 | 
					                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."
 | 
					                    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)
 | 
					                    logging.critical(msg)
 | 
				
			||||||
                    raise CorruptUnpackException(msg)
 | 
					                    raise CorruptUnpackException(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                #Read the actual archive data
 | 
					                # Read the actual archive data
 | 
				
			||||||
                data = b''
 | 
					                data = b''
 | 
				
			||||||
                read_data = 0
 | 
					                read_data = 0
 | 
				
			||||||
                for compressed, uncompressed in compression_index:
 | 
					                for compressed, uncompressed in compression_index:
 | 
				
			||||||
                    compressed_data = f.read(compressed)
 | 
					                    compressed_data = f.read(compressed)
 | 
				
			||||||
                    uncompressed_data = zlib.decompress(compressed_data)
 | 
					                    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:
 | 
					                    if len(uncompressed_data) == uncompressed:
 | 
				
			||||||
                        data += uncompressed_data
 | 
					                        data += uncompressed_data
 | 
				
			||||||
                        read_data += 1
 | 
					                        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):
 | 
					                        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)}"
 | 
					                            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)
 | 
					                            logging.critical(msg)
 | 
				
			||||||
@@ -126,7 +130,7 @@ def unpack(src, dst):
 | 
				
			|||||||
            logging.critical(msg)
 | 
					            logging.critical(msg)
 | 
				
			||||||
            raise SignatureUnpackException(msg)
 | 
					            raise SignatureUnpackException(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #Write the extracted data to disk
 | 
					    # Write the extracted data to disk
 | 
				
			||||||
    with open(dst, 'wb') as f:
 | 
					    with open(dst, 'wb') as f:
 | 
				
			||||||
        f.write(data)
 | 
					        f.write(data)
 | 
				
			||||||
    logging.info("Archive has been extracted.")
 | 
					    logging.info("Archive has been extracted.")
 | 
				
			||||||
@@ -338,7 +342,9 @@ def config_ark(list_config=list_config):
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            listen_server = True
 | 
					            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():
 | 
					def config_7daystodie():
 | 
				
			||||||
@@ -361,8 +367,10 @@ def xml_parser():
 | 
				
			|||||||
    print("Я не умею парсить))")
 | 
					    print("Я не умею парсить))")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def yaml_create(game, dir_server="", cluster_server="", map_s="", name_server="", port_server="", query_port="", rcon_enabled="", rcon_port="",
 | 
					def yaml_create(game, dir_server="", cluster_server="", map_s="", name_server="", port_server="", query_port="",
 | 
				
			||||||
                adminpassword_server="", password_server="", max_players="", id_mods_ark="", cluster_id="", cluster_dir_override="", listen_server=""):
 | 
					                rcon_enabled="", rcon_port="",
 | 
				
			||||||
 | 
					                adminpassword_server="", password_server="", max_players="", id_mods_ark="", cluster_id="",
 | 
				
			||||||
 | 
					                cluster_dir_override="", listen_server=""):
 | 
				
			||||||
    if game == "ARK":
 | 
					    if game == "ARK":
 | 
				
			||||||
        print_line(dir_maps_ark)
 | 
					        print_line(dir_maps_ark)
 | 
				
			||||||
        print_line(name_server)
 | 
					        print_line(name_server)
 | 
				
			||||||
@@ -444,7 +452,8 @@ WantedBy=default.target
 | 
				
			|||||||
@hlna.command(help='Для скачивания и установки модов')
 | 
					@hlna.command(help='Для скачивания и установки модов')
 | 
				
			||||||
@click.option('-g', help="Название игры для запуска. (ark, 7days")
 | 
					@click.option('-g', help="Название игры для запуска. (ark, 7days")
 | 
				
			||||||
@click.option('-m', default='all', help="Название карты для запуска или all для запуска все карт")
 | 
					@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":
 | 
					    if g == "ark":
 | 
				
			||||||
        id_game_workshop = "346110"
 | 
					        id_game_workshop = "346110"
 | 
				
			||||||
        if not os.path.isdir(dir_workshop_ark):
 | 
					        if not os.path.isdir(dir_workshop_ark):
 | 
				
			||||||
@@ -452,15 +461,18 @@ def modinstall(g, m):
 | 
				
			|||||||
        id_mods_ark = input("""Укажите id модов через запятую
 | 
					        id_mods_ark = input("""Укажите id модов через запятую
 | 
				
			||||||
:""").split(",")
 | 
					:""").split(",")
 | 
				
			||||||
        for id_mod in id_mods_ark:
 | 
					        for id_mod in id_mods_ark:
 | 
				
			||||||
            os.system(f"steamcmd +login anonymous +workshop_download_item {id_game_workshop} {id_mod} +quit")
 | 
					            dir_ark_mods = f"{dir_mods_ark}/{id_mod}"
 | 
				
			||||||
            modextract(id_mod, id_game_workshop)
 | 
					            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):
 | 
					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_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
 | 
					    dir_extract = dir_ark_mods
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if id_mod == "111111111":
 | 
					    if id_mod == "111111111":
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -483,7 +495,8 @@ def modextract(id_mod, id_game_workshop):
 | 
				
			|||||||
    os.system(f"rm -rf {dir_ark_mods}")
 | 
					    os.system(f"rm -rf {dir_ark_mods}")
 | 
				
			||||||
    os.system(f"mv -f {dir_steam_workshop} {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 = re.search(r'<div class="workshopItemTitle">(.+)</div>', modname)
 | 
				
			||||||
    modname = modname and modname.group(1)
 | 
					    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:
 | 
					    with open(f"{dir_extract}/mod.info", "rb") as modinfo:
 | 
				
			||||||
        data = modinfo.read()
 | 
					        data = modinfo.read()
 | 
				
			||||||
        mapnamelen = struct.unpack_from("<L", data, 0)[0]
 | 
					        mapnamelen = struct.unpack_from("<L", data, 0)[0]
 | 
				
			||||||
        mapname = data[4:mapnamelen+3]
 | 
					        mapname = data[4:mapnamelen + 3]
 | 
				
			||||||
        nummaps = struct.unpack_from("<L", data, mapnamelen+4)[0]
 | 
					        nummaps = struct.unpack_from("<L", data, mapnamelen + 4)[0]
 | 
				
			||||||
        pos = mapnamelen + 8
 | 
					        pos = mapnamelen + 8
 | 
				
			||||||
        modname = (modname.encode() or mapname.decode()) + b'\x00'
 | 
					        modname = (modname.encode() or mapname.decode()) + b'\x00'
 | 
				
			||||||
        modnamelen = len(modname)
 | 
					        modnamelen = len(modname)
 | 
				
			||||||
@@ -504,10 +517,11 @@ def modextract(id_mod, id_game_workshop):
 | 
				
			|||||||
        with open(f"{dir_ark_mods}.mod", "wb") as mod:
 | 
					        with open(f"{dir_ark_mods}.mod", "wb") as mod:
 | 
				
			||||||
            print(type(modnamelen))
 | 
					            print(type(modnamelen))
 | 
				
			||||||
            print(type(modpathlen))
 | 
					            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):
 | 
					            for mapnum in range(nummaps):
 | 
				
			||||||
                mapfilelen = struct.unpack_from("<L", data, pos)[0]
 | 
					                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))
 | 
					                mod.write(struct.pack("<L%ds" % mapfilelen, mapfilelen, mapfile))
 | 
				
			||||||
                pos = pos + 4 + mapfilelen
 | 
					                pos = pos + 4 + mapfilelen
 | 
				
			||||||
            mod.write(b"\x33\xFF\x22\xFF\x02\x00\x00\x00\x01")
 | 
					            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)
 | 
					            os.makedirs(dir_ark_mods)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ hlna.command()
 | 
					@hlna.command()
 | 
				
			||||||
@ click.option("-m", required=True, help="Название Сервера")
 | 
					@click.option("-m", required=True, help="Название Сервера")
 | 
				
			||||||
@ click.option("-e/-d", default=True, help="-e активировать карты, -d деактивировать")
 | 
					@click.option("-e/-d", default=True, help="-e активировать карты, -d деактивировать")
 | 
				
			||||||
def enablemap(m, e):
 | 
					def enablemap(m, e):
 | 
				
			||||||
    """Включение/выключение карт"""
 | 
					    """Включение/выключение карт"""
 | 
				
			||||||
    m = m.split(",")
 | 
					    m = m.split(",")
 | 
				
			||||||
@@ -663,7 +677,7 @@ def start_stop(action, g, m, list_config=list_config):
 | 
				
			|||||||
        for ns, v in dict_mapname.items():
 | 
					        for ns, v in dict_mapname.items():
 | 
				
			||||||
            if v in m:
 | 
					            if v in m:
 | 
				
			||||||
                names_serverstart.append(ns)
 | 
					                names_serverstart.append(ns)
 | 
				
			||||||
        if list_config != []: #Перенести выше для проверки наличия конфигов
 | 
					        if list_config != []:  # Перенести выше для проверки наличия конфигов
 | 
				
			||||||
            if m == "all":
 | 
					            if m == "all":
 | 
				
			||||||
                names_serverstart = dict_allmapname
 | 
					                names_serverstart = dict_allmapname
 | 
				
			||||||
                print(f"Выполняется для карт(-ы) {names_serverstart}")
 | 
					                print(f"Выполняется для карт(-ы) {names_serverstart}")
 | 
				
			||||||
@@ -671,7 +685,8 @@ def start_stop(action, g, m, list_config=list_config):
 | 
				
			|||||||
                names_serverstart = choose_map(names_serverstart)
 | 
					                names_serverstart = choose_map(names_serverstart)
 | 
				
			||||||
            for i in names_serverstart:
 | 
					            for i in names_serverstart:
 | 
				
			||||||
                data = read_yaml(i, game="ARK")
 | 
					                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")
 | 
					                x = os.system(f"systemctl --user {action} ark_{data['SessionName'].lower()}.service")
 | 
				
			||||||
                print_line(y)
 | 
					                print_line(y)
 | 
				
			||||||
                if x == 0:
 | 
					                if x == 0:
 | 
				
			||||||
@@ -763,7 +778,6 @@ else:
 | 
				
			|||||||
        print_line(data['path_server'])
 | 
					        print_line(data['path_server'])
 | 
				
			||||||
        dir_server = data['path_server']
 | 
					        dir_server = data['path_server']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
dir_unit = f"{home_dir}/.config/systemd/user/"
 | 
					dir_unit = f"{home_dir}/.config/systemd/user/"
 | 
				
			||||||
dir_logs = f"{dir_config}logs/"
 | 
					dir_logs = f"{dir_config}logs/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -783,6 +797,5 @@ create_dir(dir_unit)
 | 
				
			|||||||
create_dir(dir_config)
 | 
					create_dir(dir_config)
 | 
				
			||||||
create_dir(dir_logs)
 | 
					create_dir(dir_logs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    hlna()
 | 
					    hlna()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user