diff --git a/serverfiles/baks/backup_db.py b/serverfiles/baks/backup_db.py new file mode 100644 index 000000000..2c62c8224 --- /dev/null +++ b/serverfiles/baks/backup_db.py @@ -0,0 +1,196 @@ +#### @martysama0134 backup scripts #### +### Inside /etc/crontab paste: +## for automatic backups every hour: +# 0 * * * * root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_db.py dump +## for automatic clean of backups older than 7 days every week: +# 0 0 * * 1 root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_db.py wclean + +import os +import re +import shutil +import subprocess +import sys +import logging +from datetime import datetime, timedelta +import platform + +from subprocess import check_output as sp_co, call as sp_call, CalledProcessError as sp_CalledProcessError +def fShell(szCmd, bRet=False): + try: + if bRet: + return sp_co(szCmd, shell=True)[:-1] # remove final \n + else: + return sp_call(szCmd, shell=True) + except sp_CalledProcessError: + return -1 + +def SlashFix(pathname): + if platform.system() in ("FreeBSD", "Linux"): + return pathname.replace("\\", "/") + elif platform.system()=="Windows": + return pathname.replace("/", "\\") + return pathname + +def SymLinkCreate(src, dst, is_file): + src = SlashFix(src) + dst = SlashFix(dst) + if platform.system() == "FreeBSD": + fShell(f"ln -Ffnsw {src} {dst}") + elif platform.system() == "Linux": + fShell(f"ln -Ffns {src} {dst}") + elif platform.system() == "Windows": + if is_file: + fShell(f"mklink {dst} {src}") + else: + fShell(f"mklink /D {dst} {src}") + +def IsWindows(): return platform.system()=="Windows" +def cecho(text): print(text) if IsWindows() else print("\033[36m" + text + "\033[0m") + +DATE = datetime.now().strftime("%Y%m%d-%H%M%S") + +OUTPATH = "db" +MY_LOGF = os.path.join(OUTPATH, "log.txt") + +MYSQLDUMP = "/usr/local/bin/mysqldump" +if IsWindows(): + MYSQLDUMP = "mysqldump" + +MY_HOST = "localhost" +MY_USER = "root" +MY_PASS = "password" +PREFIX = "srv1_" +DATABASES = [ + "mysql", + PREFIX+"account", + PREFIX+"common", + PREFIX+"player", + PREFIX+"log", +] + +# Determine MySQL version +def process_flags(FLAGS): + global mysql_version + mysql_version = subprocess.check_output(["mysql", "--version"]).decode("utf-8").split()[4] + if mysql_version.startswith("8."): + FLAGS.append("--set-gtid-purged=OFF") + elif mysql_version.startswith("5.7"): + FLAGS.append("--set-gtid-purged=OFF") + elif mysql_version.startswith("5.6"): + FLAGS.append("--set-gtid-purged=OFF") + elif "MariaDB" in mysql_version: + pass + else: + logging.error(f"Unknown MySQL version: {mysql_version}") + +def delete_old_backups(): + for entry in os.listdir(OUTPATH): + # Check if entry is a directory and matches the format "YYYYmmdd-HHMMSS" + if os.path.isdir(os.path.join(OUTPATH, entry)) and re.match(r'\d{8}-\d{6}', entry): + shutil.rmtree(os.path.join(OUTPATH, entry)) + logging.info(f"Deleted old backup: {entry}") + +def delete_1week_old_backups(): + for entry in os.listdir(OUTPATH): + # Check if entry is a directory and matches the format "YYYYmmdd-HHMMSS" + if os.path.isdir(os.path.join(OUTPATH, entry)) and re.match(r'\d{8}-\d{6}', entry): + try: + # Convert the directory name to datetime format + backup_date = datetime.strptime(entry, "%Y%m%d-%H%M%S") + # Delete the directory if it's older than a certain threshold + if datetime.now() - backup_date > timedelta(days=7): + shutil.rmtree(os.path.join(OUTPATH, entry)) + logging.info(f"Deleted old backup: {entry}") + except ValueError: + # Skip directories that do not match the expected format + continue + +def init_logging(): + logging.basicConfig(filename=MY_LOGF, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setLevel(logging.INFO) + console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') + console_handler.setFormatter(console_formatter) + logging.getLogger('').addHandler(console_handler) + +def dump(): + """Save backups""" + os.makedirs(os.path.join(OUTPATH, DATE), exist_ok=True) + for db in DATABASES: + logging.info(f"Dumping {DATE}/{db}.sql.gz...") + FLAGS = [] + process_flags(FLAGS) + if db==PREFIX+"log": + FLAGS.append("--no-data") + command = f"{MYSQLDUMP} {' '.join(FLAGS)} -u {MY_USER} -p{MY_PASS} -h {MY_HOST} {db} | gzip -9 > {OUTPATH}/{DATE}/{db}.sql.gz" + subprocess.run(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + # create symlink + SymLinkCreate(f"{DATE}/{db}.sql.gz", f"{OUTPATH}/{db}.sql.gz", is_file=True) + +def recovery(): + """Recovery backups""" + for db in DATABASES: + logging.info(f"Recovering {db}.sql.gz...") + command = f"gunzip < {OUTPATH}/{db}.sql.gz | mysql -u {MY_USER} -p{MY_PASS} -h {MY_HOST} {db}" + subprocess.run(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + +def clean(): + """Delete all the backups""" + delete_old_backups() + +def lclean(): + """Delete the log file""" + if os.path.exists(MY_LOGF): + os.remove(MY_LOGF) + +def wclean(): + """Delete the backups older than 1 week""" + delete_1week_old_backups() + +def cleanall(): + """Delete all the backups and logs""" + clean() + lclean() + +actions = { + "dump": dump, + "recovery": recovery, + "clean": clean, + "lclean": lclean, + "wclean": wclean, + "cleanall": cleanall +} + +# Execute the appropriate function based on user input +if __name__ == "__main__": + if not os.path.exists(OUTPATH): + os.makedirs(OUTPATH) + + init_logging() + + if len(sys.argv) < 2: + print("Available actions:") + for action in actions.keys(): + print(" {}".format(action)) + + ret = input('Enter an action: ').split() + if not ret: + cecho('No argument provided. Quitting.') + sys.exit() + + action = ret[0] + commands = ret[1:] if len(ret) >= 2 else [] + else: + action = sys.argv[1] + commands = sys.argv[2:] if len(sys.argv) >= 3 else [] + # print(" ".join(sys.argv[1:])) + + commands = " ".join(commands) + + selected_action = actions.get(action) + if selected_action: + logging.info(f"Started action {action}") + selected_action() + logging.info(f"Stopped action {action}") + else: + print("Invalid action. Please choose one of: {}".format(", ".join(actions.keys()))) diff --git a/serverfiles/baks/backup_dbrev.py b/serverfiles/baks/backup_dbrev.py new file mode 100644 index 000000000..1320b2cb0 --- /dev/null +++ b/serverfiles/baks/backup_dbrev.py @@ -0,0 +1,156 @@ +#### @martysama0134 backup scripts #### +### Inside /etc/crontab paste: +## for automatic backups every hour: +# 0 * * * * root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_dbrev.py dump + +import os +import re +import shutil +import subprocess +import sys +import logging +from datetime import datetime, timedelta +import platform + +def IsWindows(): return platform.system()=="Windows" +def cecho(text): print(text) if IsWindows() else print("\033[36m" + text + "\033[0m") + +OUTPATH = "dbrev" +MY_LOGF = os.path.join(OUTPATH, "log.txt") + +MYSQLDUMP = "/usr/local/bin/mysqldump" +if IsWindows(): + MYSQLDUMP = "mysqldump" + +MY_HOST = "localhost" +MY_USER = "root" +MY_PASS = "password" +PREFIX = "srv1_" +DATABASES = [ + "mysql", + PREFIX+"account", + PREFIX+"common", + PREFIX+"player", + PREFIX+"log", +] +TABLES = { + PREFIX+"account" : "block_exception GameTime GameTimeIP iptocountry string", + PREFIX+"common" : "", + PREFIX+"player" : "banword item_attr item_attr_rare item_proto land mob_proto object_proto refine_proto shop shop_item skill_proto string", +} + +# Determine MySQL version +def process_flags(FLAGS): + global mysql_version + mysql_version = subprocess.check_output(["mysql", "--version"]).decode("utf-8").split()[4] + if mysql_version.startswith("8."): + FLAGS.append("--set-gtid-purged=OFF") + elif mysql_version.startswith("5.7"): + FLAGS.append("--set-gtid-purged=OFF") + elif mysql_version.startswith("5.6"): + FLAGS.append("--set-gtid-purged=OFF") + elif "MariaDB" in mysql_version: + pass + else: + logging.error(f"Unknown MySQL version: {mysql_version}") + +def delete_old_backups(): + for entry in os.listdir(OUTPATH): + # Check if entry is a file and matches the format "*.sql" + if os.path.isfile(os.path.join(OUTPATH, entry)) and re.match(r'.*\.sql$', entry): + os.remove(os.path.join(OUTPATH, entry)) + logging.info(f"Deleted old backup: {entry}") + +def init_logging(): + logging.basicConfig(filename=MY_LOGF, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setLevel(logging.INFO) + console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') + console_handler.setFormatter(console_formatter) + logging.getLogger('').addHandler(console_handler) + +def dump(): + """Save backups""" + os.makedirs(OUTPATH, exist_ok=True) + + for db in DATABASES: + logging.info(f"Dumping {db}-schema.sql...") + FLAGS = ["--no-data","--skip-extended-insert","--skip-dump-date"] + process_flags(FLAGS) + command = f"{MYSQLDUMP} {' '.join(FLAGS)} -u {MY_USER} -p{MY_PASS} -h {MY_HOST} {db} > {OUTPATH}/{db}-schema.sql" + subprocess.run(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + + for db, tables in TABLES.items(): + logging.info(f"Dumping {db}-data.sql...") + FLAGS = ["--no-create-info","--skip-extended-insert","--skip-dump-date"] + process_flags(FLAGS) + command = f"{MYSQLDUMP} {' '.join(FLAGS)} -u {MY_USER} -p{MY_PASS} -h {MY_HOST} {db} {tables} > {OUTPATH}/{db}-data.sql" + subprocess.run(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + +def recovery(): + """Recovery backups""" + for db in DATABASES: + logging.info(f"Recovering {db}-schema.sql...") + command = f"mysql -u {MY_USER} -p{MY_PASS} -h {MY_HOST} {db} 2>> {MY_LOGF} < {OUTPATH}/{db}-schema.sql" + subprocess.run(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + + for db, tables in TABLES.items(): + logging.info(f"Recovering {db}-data.sql...") + command = f"mysql -u {MY_USER} -p{MY_PASS} -h {MY_HOST} {db} 2>> {MY_LOGF} < {OUTPATH}/{db}-data.sql" + subprocess.run(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + +def clean(): + """Delete all the backups""" + delete_old_backups() + +def lclean(): + """Delete the log file""" + if os.path.exists(MY_LOGF): + os.remove(MY_LOGF) + +def cleanall(): + """Delete all the backups and logs""" + clean() + lclean() + +actions = { + "dump": dump, + "recovery": recovery, + "clean": clean, + "lclean": lclean, + "cleanall": cleanall, +} + +# Execute the appropriate function based on user input +if __name__ == "__main__": + if not os.path.exists(OUTPATH): + os.makedirs(OUTPATH) + + init_logging() + + if len(sys.argv) < 2: + print("Available actions:") + for action in actions.keys(): + print(" {}".format(action)) + + ret = input('Enter an action: ').split() + if not ret: + cecho('No argument provided. Quitting.') + sys.exit() + + action = ret[0] + commands = ret[1:] if len(ret) >= 2 else [] + else: + action = sys.argv[1] + commands = sys.argv[2:] if len(sys.argv) >= 3 else [] + # print(" ".join(sys.argv[1:])) + + commands = " ".join(commands) + + selected_action = actions.get(action) + if selected_action: + logging.info(f"Started action {action}") + selected_action() + logging.info(f"Stopped action {action}") + else: + print("Invalid action. Please choose one of: {}".format(", ".join(actions.keys()))) diff --git a/serverfiles/baks/backup_fs.py b/serverfiles/baks/backup_fs.py new file mode 100644 index 000000000..9f9dd270d --- /dev/null +++ b/serverfiles/baks/backup_fs.py @@ -0,0 +1,172 @@ +#### @martysama0134 backup scripts #### +### Inside /etc/crontab paste: +## for automatic backups every hour: +# 0 * * * * root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_fs.py dump +## for automatic clean of backups older than 7 days every week: +# 0 0 * * 1 root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_fs.py wclean + +import os +import re +import shutil +import subprocess +import sys +import logging +from datetime import datetime, timedelta +import platform + +from subprocess import check_output as sp_co, call as sp_call, CalledProcessError as sp_CalledProcessError +def fShell(szCmd, bRet=False): + try: + if bRet: + return sp_co(szCmd, shell=True)[:-1] # remove final \n + else: + return sp_call(szCmd, shell=True) + except sp_CalledProcessError: + return -1 + +def SlashFix(pathname): + if platform.system() in ("FreeBSD", "Linux"): + return pathname.replace("\\", "/") + elif platform.system()=="Windows": + return pathname.replace("/", "\\") + return pathname + +def SymLinkCreate(src, dst, is_file): + src = SlashFix(src) + dst = SlashFix(dst) + if platform.system() == "FreeBSD": + fShell(f"ln -Ffnsw {src} {dst}") + elif platform.system() == "Linux": + fShell(f"ln -Ffns {src} {dst}") + elif platform.system() == "Windows": + if is_file: + fShell(f"mklink {dst} {src}") + else: + fShell(f"mklink /D {dst} {src}") + +def IsWindows(): return platform.system()=="Windows" +def cecho(text): print(text) if IsWindows() else print("\033[36m" + text + "\033[0m") + +DATE = datetime.now().strftime("%Y%m%d-%H%M%S") +PYBIN = "python3" +if IsWindows(): + PYBIN = 'python' + +BASEPATH = os.getcwd() +SVFPATH = os.path.join(BASEPATH, "..") +MAINPATH = os.path.join(SVFPATH, "main") + +OUTPATH = "fs" +MY_LOGF = os.path.join(OUTPATH, "log.txt") + +def delete_old_backups(): + for entry in os.listdir(OUTPATH): + # Check if entry is a directory and matches the format "YYYYmmdd-HHMMSS" + if os.path.isdir(os.path.join(OUTPATH, entry)) and re.match(r'\d{8}-\d{6}', entry): + shutil.rmtree(os.path.join(OUTPATH, entry)) + logging.info(f"Deleted old backup: {entry}") + +def delete_1week_old_backups(): + for entry in os.listdir(OUTPATH): + # Check if entry is a directory and matches the format "YYYYmmdd-HHMMSS" + if os.path.isdir(os.path.join(OUTPATH, entry)) and re.match(r'\d{8}-\d{6}', entry): + try: + # Convert the directory name to datetime format + backup_date = datetime.strptime(entry, "%Y%m%d-%H%M%S") + # Delete the directory if it's older than a certain threshold + if datetime.now() - backup_date > timedelta(days=7): + shutil.rmtree(os.path.join(OUTPATH, entry)) + logging.info(f"Deleted old backup: {entry}") + except ValueError: + # Skip directories that do not match the expected format + continue + +def init_logging(): + logging.basicConfig(filename=MY_LOGF, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setLevel(logging.INFO) + console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') + console_handler.setFormatter(console_formatter) + logging.getLogger('').addHandler(console_handler) + +def dump(): + """Save backups""" + os.makedirs(os.path.join(OUTPATH, DATE), exist_ok=True) + + # clear fs logs + os.chdir(MAINPATH) + logging.info(f"Clearing the logs...") + subprocess.run(f"{PYBIN} clear.py", shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + + os.chdir(BASEPATH) + logging.info(f"Dumping {DATE}/mt2.tgz...") + subprocess.run(f"tar -czf {OUTPATH}/{DATE}/mt2.tgz -C {SVFPATH} main", shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + + # create symlink + SymLinkCreate(f"{DATE}/mt2.tgz", f"{OUTPATH}/mt2.tgz", is_file=True) + +def recovery(): + """Recovery backups""" + logging.info(f"Recovering mt2.tgz...") + subprocess.run(f"tar -xzf {OUTPATH}/mt2.tgz -C {SVFPATH}", shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + +def clean(): + """Delete all the backups""" + delete_old_backups() + +def lclean(): + """Delete the log file""" + if os.path.exists(MY_LOGF): + os.remove(MY_LOGF) + +def wclean(): + """Delete the backups older than 1 week""" + delete_1week_old_backups() + +def cleanall(): + """Delete all the backups and logs""" + clean() + lclean() + +actions = { + "dump": dump, + "recovery": recovery, + "clean": clean, + "lclean": lclean, + "wclean": wclean, + "cleanall": cleanall +} + +# Execute the appropriate function based on user input +if __name__ == "__main__": + if not os.path.exists(OUTPATH): + os.makedirs(OUTPATH) + + init_logging() + + if len(sys.argv) < 2: + print("Available actions:") + for action in actions.keys(): + print(" {}".format(action)) + + ret = input('Enter an action: ').split() + if not ret: + cecho('No argument provided. Quitting.') + sys.exit() + + action = ret[0] + commands = ret[1:] if len(ret) >= 2 else [] + else: + action = sys.argv[1] + commands = sys.argv[2:] if len(sys.argv) >= 3 else [] + # print(" ".join(sys.argv[1:])) + + commands = " ".join(commands) + + selected_action = actions.get(action) + if selected_action: + logging.info(f"Started action {action}") + selected_action() + logging.info(f"Stopped action {action}") + else: + print("Invalid action. Please choose one of: {}".format(", ".join(actions.keys()))) diff --git a/serverfiles/baks/db/Makefile b/serverfiles/baks/db/Makefile deleted file mode 100644 index b5fb1afb8..000000000 --- a/serverfiles/baks/db/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -#### @martysama0134 backup scripts #### -### Inside /etc/crontab paste: -## for automatic backups every hour: -# 0 * * * * root make -C /home/serverfiles/baks/db dump -## for automatic clean of backups older than 7 days every week: -# 0 0 * * 1 root make -C /home/serverfiles/baks/db wclean - -DATE != date +%Y%m%d-%H%M%S - -MY_HOST = localhost -MY_USER = root -MY_PASS = your_password -MY_LOGF = log.txt -PREFIX = srv1_ -OUTPATH = . - -all: - @echo "available all, dump, recovery, clean, lclean, wclean, cleanall" - @echo "TEST: -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) > $(PREFIX)$(DATE).sql" - -dump: - @echo "### dump begin $(DATE)" >> $(MY_LOGF) - @mkdir $(DATE)/ - @/usr/local/bin/mysqldump -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)account | gzip -9 > $(OUTPATH)/$(DATE)/$(PREFIX)account.sql.gz 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)common | gzip -9 > $(OUTPATH)/$(DATE)/$(PREFIX)common.sql.gz 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)player | gzip -9 > $(OUTPATH)/$(DATE)/$(PREFIX)player.sql.gz 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump --no-data -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)log | gzip -9 > $(OUTPATH)/$(DATE)/$(PREFIX)log.sql.gz 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) mysql | gzip -9 > $(OUTPATH)/$(DATE)/mysql.sql.gz 2>> $(MY_LOGF) - @echo "### dump end $(DATE)" >> $(MY_LOGF) - -recovery: - @echo "### recovery begin $(DATE)" >> $(MY_LOGF) - @gunzip < mysql.sql.gz | mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) mysql 2>> $(MY_LOGF) - @gunzip < $(PREFIX)account.sql.gz | mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)account 2>> $(MY_LOGF) - @gunzip < $(PREFIX)common.sql.gz | mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)common 2>> $(MY_LOGF) - @gunzip < $(PREFIX)player.sql.gz | mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)player 2>> $(MY_LOGF) - @gunzip < $(PREFIX)log.sql.gz | mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)log 2>> $(MY_LOGF) - @echo "### recovery end $(DATE)" >> $(MY_LOGF) - -clean: - @find $(OUTPATH) ! -name Makefile ! -name $(OUTPATH) -exec rm -rf {} + - -lclean: - @cat /dev/null > $(MY_LOGF) - -wclean: - @echo "### clean week begin $(DATE)" >> $(MY_LOGF) - @find $(OUTPATH) ! -name Makefile ! -name $(OUTPATH) -type d -mtime +7 -print -exec rm -rf {} + >> $(MY_LOGF) - @echo "### clean week end $(DATE)" >> $(MY_LOGF) - -cleanall: clean lclean - @echo "### clean all done $(DATE)" >> $(MY_LOGF) - - - diff --git a/serverfiles/baks/dbrev/Makefile b/serverfiles/baks/dbrev/Makefile deleted file mode 100644 index 572d9161a..000000000 --- a/serverfiles/baks/dbrev/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -#### @martysama0134 backup scripts #### -### Inside /etc/crontab paste: -## for automatic backups every hour: -# 0 * * * * root make -C /home/metin2/baks/db-rev dump - -DATE != date +%Y%m%d-%H%M%S - -MY_HOST = localhost -MY_USER = root -MY_PASS = password -MY_LOGF = /dev/null #log.txt -PREFIX = srv1_ -ACCOUNT_TABLES = block_exception GameTime GameTimeIP iptocountry string -PLAYER_TABLES = banword item_attr item_attr_rare item_proto land mob_proto object_proto refine_proto shop shop_item skill_proto string -OUTPATH = . - -all: - @echo "available all, dump, recovery, clean, lclean, cleanall" - @echo "TEST: -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) > $(PREFIX)$(DATE).sql" - -dump: - @echo "### dump begin $(DATE)" >> $(MY_LOGF) - @### struct only - @/usr/local/bin/mysqldump --no-data --skip-extended-insert --skip-dump-date -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)account > $(OUTPATH)/$(PREFIX)account-schema.sql 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump --no-data --skip-extended-insert --skip-dump-date -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)common > $(OUTPATH)/$(PREFIX)common-schema.sql 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump --no-data --skip-extended-insert --skip-dump-date -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)player > $(OUTPATH)/$(PREFIX)player-schema.sql 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump --no-data --skip-extended-insert --skip-dump-date -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)log > $(OUTPATH)/$(PREFIX)log-schema.sql 2>> $(MY_LOGF) - @### data only - @/usr/local/bin/mysqldump --no-create-info --skip-extended-insert --skip-dump-date -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)account $(ACCOUNT_TABLES) > $(OUTPATH)/$(PREFIX)common-data.sql 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump --no-create-info --skip-extended-insert --skip-dump-date -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)common > $(OUTPATH)/$(PREFIX)common-data.sql 2>> $(MY_LOGF) - @/usr/local/bin/mysqldump --no-create-info --skip-extended-insert --skip-dump-date -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)player $(PLAYER_TABLES) > $(OUTPATH)/$(PREFIX)player-data.sql 2>> $(MY_LOGF) - @echo "### dump end $(DATE)" >> $(MY_LOGF) - -recovery: - @echo "### recovery begin $(DATE)" >> $(MY_LOGF) - @# schema - @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)account 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)account-schema.sql - @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)common 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)common-schema.sql - @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)log 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)log-schema.sql - @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)player 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)player-schema.sql - @# data - @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)account 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)account-data.sql - @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)common 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)common-data.sql - @# @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)log 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)log-data.sql - @mysql -u $(MY_USER) -p$(MY_PASS) -h $(MY_HOST) $(PREFIX)player 2>> $(MY_LOGF) < $(OUTPATH)/$(PREFIX)player-data.sql - @echo "### recovery end $(DATE)" >> $(MY_LOGF) - -clean: - @rm -f $(OUTPATH)/*.sql - -lclean: - @cat /dev/null > $(MY_LOGF) - -cleanall: clean lclean - @echo "### clean all done $(DATE)" >> $(MY_LOGF) diff --git a/serverfiles/baks/fs/Makefile b/serverfiles/baks/fs/Makefile deleted file mode 100644 index 4b559ae25..000000000 --- a/serverfiles/baks/fs/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -#### @martysama0134 backup scripts #### -## Inside /etc/crontab paste: (for automatic backups every hour) -# 0 * * * * root make -C /home/serverfiles/baks/fs dump -## for automatic clean of backups older than 7 days every week: -# 0 0 * * 1 root make -C /home/serverfiles/baks/fs wclean - -DATE != date +%Y%m%d-%H%M%S - -CURPATH != pwd -PATH = ../../ -FOLD = main -PATH2 = $(PATH)$(FOLD) -OUTPATH = . - -all: - @echo "available all, dump, recovery and clean" - -dump: - @cd $(PATH)$(FOLD) && python clear.py - @cd $(CURPATH) && cd $(PATH) && tar -czf mt2_$(DATE).tgz $(FOLD) - @mv $(PATH)mt2_$(DATE).tgz $(OUTPATH) - @echo "backup di $(PATH2) finito" - -recovery: - @tar -xzf mt2.tgz -C $(PATH) - @echo "recovery di $(PATH2) finito" - -clean: - @rm -f $(OUTPATH)/*.tgz - -lclean: - @cat /dev/null > $(MY_LOGF) - -wclean: - @echo "### clean week begin $(DATE)" >> $(MY_LOGF) - @find $(OUTPATH) -name "*.tgz" -type f -mtime +7 -print -delete >> $(MY_LOGF) - @echo "### clean week end $(DATE)" >> $(MY_LOGF) diff --git a/serverfiles/main/README-ADMIN-PANEL.txt b/serverfiles/main/README-ADMIN-PANEL.txt index e3f311590..fd4f80349 100644 --- a/serverfiles/main/README-ADMIN-PANEL.txt +++ b/serverfiles/main/README-ADMIN-PANEL.txt @@ -19,9 +19,7 @@ python admin_panel.py start # via name as input python admin_panel.py - -# and also... via sh -python admin_panel.py +start ### List of the admin_panel.sh options: diff --git a/serverfiles/main/README-MAIN.txt b/serverfiles/main/README-MAIN.txt index 226e58f22..7bd2b0eba 100644 --- a/serverfiles/main/README-MAIN.txt +++ b/serverfiles/main/README-MAIN.txt @@ -15,26 +15,26 @@ MY_PASS = password OUTPATH = . # output folder by default (.=current) -## Other things +### DB BACKUPS +## Setup the DB backup: # Make manual backups -cd baks/db/ -make dump +cd baks/ +python backup_db.py dump # Clean all the backups -cd baks/db/ -make clean +cd baks/ +python backup_db.py clean # Setup automatic backups every hour pasting this inside the system file /etc/crontab (the path must be correct!) -0 * * * * root make -C /home/metin2/baks/db dump +0 * * * * root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_db.py dump # Setup automatic backups cleaning every week pasting this inside the system file /etc/crontab (the path must be correct!) -0 0 * * 1 root make -C /home/metin2/baks/db wclean +0 0 * * 1 root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_db.py wclean ## Recovery from backup -cd baks/db/ -# rename the specific backups as account.sql.gz common.sql.gz log.sql.gz player.sql.gz inside the folder -make recovery +cd baks/ +python backup_db.py recovery ### FS BACKUPS @@ -46,23 +46,22 @@ OUTPATH = . #output folder by default (.=current) # Make manual backups -cd baks/fs/ -make dump +cd baks/ +python backup_fs.py dump # Clean all the backups -cd baks/fs/ -make clean +cd baks/ +python backup_fs.py clean # Setup automatic backups every hour pasting this inside the system file /etc/crontab (the path must be correct!) -0 * * * * root make -C /home/metin2/baks/fs dump +0 * * * * root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_fs.py dump # Setup automatic backups cleaning every week pasting this inside the system file /etc/crontab (the path must be correct!) -0 0 * * 1 root make -C /home/metin2/baks/fs wclean +0 0 * * 1 root cd /home/metin2/baks/ && /usr/local/bin/python3 backup_fs.py wclean ## Recovery from backup -cd baks/fs/ -# rename the specific backup as mt2.tgz inside the folder -make recovery +cd baks/ +python backup_fs.py recovery ### How to generate the server structure: @@ -86,6 +85,11 @@ python admin_panel.py stop ## To clear the logs: python admin_panel.py clear +## To force stop the server: (kill -9) +python admin_panel.py stop --level 9 +python admin_panel.py stop -l 9 +python admin_panel.py stop -l9 + ### Additional notes: diff --git a/serverfiles/main/admin_panel.py b/serverfiles/main/admin_panel.py index fb2b4a802..7ffad9f4a 100644 --- a/serverfiles/main/admin_panel.py +++ b/serverfiles/main/admin_panel.py @@ -3,7 +3,7 @@ import os import sys import subprocess -from gen import IsWindows +from gen import IsWindows,SymLinkCreate def fecho(text): print(text) if IsWindows() else print("\033[35m" + text + "\033[0m") def _fecho(text): print(text) if IsWindows() else print("\033[4;35m" + text + "\033[0m") @@ -48,186 +48,198 @@ def delete_symlink(filepath): except FileNotFoundError: pass -v_base = os.getcwd() -v_mt2f = v_base -v_bakf = os.path.join(v_base, '..', 'baks') -v_dbf = os.path.join(v_bakf, 'db') -v_dbrevf = os.path.join(v_bakf, 'dbrev') -v_fsf = os.path.join(v_bakf, 'fs') -v_foldername = 'srv1' -v_localename = 'germany' -v_bin = 'python3' -if IsWindows(): - v_bin = 'python' +if __name__ == "__main__": + v_base = os.getcwd() + v_mt2f = v_base + v_bakf = os.path.join(v_base, '..', 'baks') + v_foldername = 'srv1' + v_localename = 'germany' + v_bin = 'python3' + if IsWindows(): + v_bin = 'python' -r_echo(".:. AdminPanel .:.") -gecho("What do you want to do?") -recho("1. Start (start)") -recho("1i. Start Interactive (starti)") -recho("111. Restart (restart)") -recho("111a. Restart+Daemon (restartall)") -recho("111b. Restart+Gen+Quest (fullrestart)") -recho("2. Stop (stop|close)") -recho("2i. Stop Interactive (stopi|closei)") -recho("3. Clean (clean|clear)") -recho("33. Clean All (cleanall|clearall)") -recho("4. Backup mysql/db (bak1|db|db_backup)") -recho("4b. Backup mysql no user-data (dbrev)") -recho("5. Backup game/fs (bak2|fs|fs_backup)") -recho("666. Generate (gen)") -recho("777. Compile Quests (quest)") -recho("888. Game Symlink (symlink)") -recho("999. Search (search)") -_yecho("1a. Start+Daemon (startall)") -_yecho("2a. Stop+Daemon (stopall|closeall)") -_recho("0. Quit (quit)") + r_echo(".:. AdminPanel .:.") + gecho("What do you want to do?") + recho("1. Start (start)") + recho("1i. Start Interactive (starti)") + recho("111. Restart (restart)") + recho("111a. Restart+Daemon (restartall)") + recho("111b. Restart+Gen+Quest (fullrestart)") + recho("2. Stop (stop|close)") + recho("2i. Stop Interactive (stopi|closei)") + recho("3. Clean (clean|clear)") + recho("33. Clean All (cleanall|clearall)") + recho("4. Backup mysql/db (bak1|db|db_backup)") + recho("4b. Backup mysql no user-data (dbrev)") + recho("5. Backup game/fs (bak2|fs|fs_backup)") + recho("666. Generate (gen)") + recho("777. Compile Quests (quest)") + recho("888. Game Symlink (symlink)") + recho("999. Search (search)") + _yecho("1a. Start+Daemon (startall)") + _yecho("2a. Stop+Daemon (stopall|closeall)") + _recho("0. Quit (quit)") -if len(sys.argv) < 2: - ret = input('Enter a phase: ').split() - phase = ret[0] - commands = ret[1:] if len(ret) >= 2 else [] -else: - phase = sys.argv[1] - commands = sys.argv[2:] if len(sys.argv) >= 3 else [] - # print(" ".join(sys.argv[1:])) + if len(sys.argv) < 2: + ret = input('Enter a phase: ').split() + if not ret: + cecho('No argument provided. Quitting.') + sys.exit() + phase = ret[0] + commands = ret[1:] if len(ret) >= 2 else [] + else: + phase = sys.argv[1] + commands = sys.argv[2:] if len(sys.argv) >= 3 else [] + # print(" ".join(sys.argv[1:])) -commands = " ".join(commands) + commands = " ".join(commands) -if phase in ['111', 'restart']: - os.chdir(v_mt2f) - run_command(f'{v_bin} stop.py') - run_command(f'{v_bin} start.py') - os.chdir(v_base) - cecho('restart completed') + if phase in ['111', 'restart']: + os.chdir(v_mt2f) + run_command(f'{v_bin} stop.py') + run_command(f'{v_bin} start.py') + os.chdir(v_base) + cecho('restart completed') -elif phase in ['111a', 'restartall']: - p = subprocess.run(['ps', 'afx'], stdout=subprocess.PIPE) - ps_output = p.stdout.decode() - for line in ps_output.split('\n'): - if 'python daemon_srv1.py' in line and 'grep' not in line: - pid = line.split()[0] - os.kill(pid, 9) - os.chdir(v_mt2f) - run_command(f'{v_bin} stop.py') - run_command(f'{v_bin} start.py') - os.system(f'{v_bin} daemon_srv1.py &') - # subprocess.Popen(["python", "daemon_srv1.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=False, preexec_fn=os.setsid) - os.chdir(v_base) - cecho('restartall completed') + elif phase in ['111a', 'restartall']: + p = subprocess.run(['ps', 'afx'], stdout=subprocess.PIPE) + ps_output = p.stdout.decode() + for line in ps_output.split('\n'): + if f'{v_bin} daemon_srv1.py' in line and 'grep' not in line: + pid = line.split()[0] + os.kill(pid, 9) + os.chdir(v_mt2f) + run_command(f'{v_bin} stop.py') + run_command(f'{v_bin} start.py') + os.system(f'{v_bin} daemon_srv1.py &') -elif phase in ['111b', 'fullrestart']: - os.chdir(v_mt2f) - run_command(f'{v_bin} admin_panel.py clear') - run_command(f'{v_bin} admin_panel.py gen') - run_command(f'{v_bin} admin_panel.py quest') - run_command(f'{v_bin} admin_panel.py restart') - os.chdir(v_base) - cecho('restart completed') + os.chdir(v_base) + cecho('restartall completed') -elif phase in ['1', 'start']: - os.chdir(v_mt2f) - run_command(f'{v_bin} start.py {commands}') - os.chdir(v_base) - cecho('start completed') + elif phase in ['111b', 'fullrestart']: + os.chdir(v_mt2f) + run_command(f'{v_bin} admin_panel.py clear') + run_command(f'{v_bin} admin_panel.py gen') + run_command(f'{v_bin} admin_panel.py quest') + run_command(f'{v_bin} admin_panel.py restart') + os.chdir(v_base) + cecho('restart completed') -elif phase in ['1i', 'starti']: - os.chdir(v_mt2f) - run_command(f'{v_bin} start.py --prompt') - os.chdir(v_base) - cecho('starti completed') + elif phase in ['1', 'start']: + os.chdir(v_mt2f) + run_command(f'{v_bin} start.py {commands}') + os.chdir(v_base) + cecho('start completed') -elif phase in ['1a', 'startall']: - os.chdir(v_mt2f) - os.system(f'{v_bin} daemon_srv1.py &') - # subprocess.Popen(["python", "daemon_srv1.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=False, preexec_fn=os.setsid) - os.chdir(v_base) - cecho('startall completed') + elif phase in ['1i', 'starti']: + os.chdir(v_mt2f) + run_command(f'{v_bin} start.py --prompt') + os.chdir(v_base) + cecho('starti completed') -elif phase in ['2', 'stop', 'close']: - os.chdir(v_mt2f) - run_command(f'{v_bin} stop.py {commands}') - os.chdir(v_base) - cecho('stop completed') + elif phase in ['1a', 'startall']: + os.chdir(v_mt2f) + os.system(f'{v_bin} daemon_srv1.py &') + os.chdir(v_base) + cecho('startall completed') -elif phase in ['2i', 'stopi', 'closei']: - os.chdir(v_mt2f) - run_command(f'{v_bin} stop.py --prompt') - os.chdir(v_base) - cecho('stopi completed') + elif phase in ['2', 'stop', 'close']: + os.chdir(v_mt2f) + run_command(f'{v_bin} stop.py {commands}') + os.chdir(v_base) + cecho('stop completed') -elif phase in ['2a', 'stopall', 'closeall']: - p = subprocess.run(['ps', 'afx'], stdout=subprocess.PIPE) - ps_output = p.stdout.decode() - for line in ps_output.split('\n'): - if 'daemon_srv1.py' in line and 'grep' not in line: - pid = int(line.split()[0]) - print(f"Killing process {pid}") - os.kill(pid, 9) - os.chdir(v_mt2f) - run_command(f'{v_bin} stop.py') - os.chdir(v_base) - cecho('stopall completed') + elif phase in ['2i', 'stopi', 'closei']: + os.chdir(v_mt2f) + run_command(f'{v_bin} stop.py --prompt') + os.chdir(v_base) + cecho('stopi completed') -elif phase in ['3', 'clean', 'clear']: - os.chdir(v_mt2f) - run_command(f'{v_bin} clear.py') - os.chdir(v_base) - cecho('clean completed') + elif phase in ['2a', 'stopall', 'closeall']: + p = subprocess.run(['ps', 'afx'], stdout=subprocess.PIPE) + ps_output = p.stdout.decode() + for line in ps_output.split('\n'): + if 'daemon_srv1.py' in line and 'grep' not in line: + pid = int(line.split()[0]) + print(f"Killing process {pid}") + os.kill(pid, 9) + os.chdir(v_mt2f) + run_command(f'{v_bin} stop.py') + os.chdir(v_base) + cecho('stopall completed') -elif phase in ['33', 'cleanall', 'clearall']: - os.chdir(v_mt2f) - response = input("Are you sure you want to delete the backups as well? [Ny] ") - if response.lower() == 'y': + elif phase in ['3', 'clean', 'clear']: + os.chdir(v_mt2f) run_command(f'{v_bin} clear.py') os.chdir(v_base) - run_command(f'make -C {v_dbf} clean') - run_command(f'make -C {v_fsf} clean') - cecho('cleanall completed') + cecho('clean completed') + + elif phase in ['33', 'cleanall', 'clearall']: + os.chdir(v_mt2f) + response = input("Are you sure you want to delete the backups as well? [Ny] ") + if response.lower() == 'y': + run_command(f'{v_bin} clear.py') + os.chdir(v_bakf) + run_command(f'{v_bin} backup_db.py clean') + run_command(f'{v_bin} backup_fs.py clean') + os.chdir(v_base) + cecho('cleanall completed') + else: + cecho('cleanall cancelled') + + elif phase in ['4', 'bak1', 'db', 'db_backup']: + os.chdir(v_bakf) + run_command(f'{v_bin} backup_db.py dump') + os.chdir(v_base) + cecho('bak db completed') + + elif phase in ['4b','dbrev', 'dbrev_backup']: + os.chdir(v_bakf) + run_command(f'{v_bin} backup_dbrev.py dump') + os.chdir(v_base) + cecho('bak dbrev completed') + + elif phase in ['5', 'bak2', 'fs', 'fs_backup']: + os.chdir(v_bakf) + run_command(f'{v_bin} backup_fs.py dump') + os.chdir(v_base) + cecho('bak fs completed') + + elif phase in ['666', 'gen']: + os.chdir(v_mt2f) + run_command(f'{v_bin} gen.py') + os.chdir(v_base) + cecho('gen completed') + + elif phase in ['777', 'quest']: + os.chdir(os.path.join(v_mt2f, v_foldername, 'share', 'locale', v_localename, 'quest')) + if not IsWindows(): + run_command('chmod u+x qc') + run_command(f'{v_bin} pre_qc.py -ac') + os.chdir(v_base) + cecho('quest completed') + + elif phase in ['888', 'symlink']: + os.chdir(os.path.join(v_mt2f, v_foldername, 'share', 'bin')) + if IsWindows(): + delete_symlink('game.exe') + delete_symlink('db.exe') + os.system(r'mklink game.exe "..\..\..\..\..\source-server\Srcs\Server\game\bin\release\game.exe"') + os.system(r'mklink db.exe "..\..\..\..\..\source-server\Srcs\Server\db\bin\release\db.exe"') + else: + delete_symlink('game') + delete_symlink('db') + run_command('ln -s /home/source-server/Srcs/Server/game/game_symlink game') + run_command('ln -s /home/source-server/Srcs/Server/db/db_symlink db') + cecho('symlink completed') + + elif phase in ['999', 'search']: + search_for_port_in_configs(v_base) + + elif phase in ['0', 'quit']: + abio('.:|:.') + sys.exit() + else: - cecho('cleanall cancelled') - -elif phase in ['4', 'bak1', 'db', 'db_backup']: - run_command(f'make -C {v_dbf} dump') - cecho('bak db completed') - -elif phase in ['4b','dbrev']: - run_command(f'make -C {v_dbrevf} dump') - cecho('bak dbrev completed') - -elif phase in ['5', 'bak2', 'fs', 'fs_backup']: - run_command(f'make -C {v_fsf} dump') - cecho('bak fs completed') - -elif phase in ['666', 'gen']: - os.chdir(v_mt2f) - # run_command(f'rm -rf {v_foldername}/logs {v_foldername}/auth {v_foldername}/chan {v_foldername}/db') - run_command(f'{v_bin} gen.py') - os.chdir(v_base) - cecho('gen completed') - -elif phase in ['777', 'quest']: - os.chdir(os.path.join(v_mt2f, v_foldername, 'share', 'locale', v_localename, 'quest')) - if not IsWindows(): - run_command('chmod u+x qc') - run_command(f'{v_bin} pre_qc.py -ac') - os.chdir(v_base) - cecho('quest completed') - -elif phase in ['888', 'symlink']: - os.chdir(os.path.join(v_mt2f, v_foldername, 'share', 'bin')) - delete_symlink('game') - delete_symlink('db') - run_command('ln -s /home/source-server/Srcs/Server/game/game_symlink game') - run_command('ln -s /home/source-server/Srcs/Server/db/db_symlink db') - cecho('symlink completed') - -elif phase in ['999', 'search']: - search_for_port_in_configs(v_base) - -elif phase in ['0', 'quit']: - abio('.:|:.') - sys.exit() - -else: - cecho(f'{phase} not found') + cecho(f'{phase} not found') diff --git a/serverfiles/main/gen.py b/serverfiles/main/gen.py index e69313369..96e04d5fb 100644 --- a/serverfiles/main/gen.py +++ b/serverfiles/main/gen.py @@ -10,11 +10,21 @@ import shutil import time from gen_settings import * +ENABLE_CLEAN_UP_OLD_GEN = True + portlist={} clearlist=[] startlist=[] serverinfolist=[] +#global single server rules +genConfig = {} +genConfig["all"] = {} +#for ipfw rules +udp_yes_ports=[] +tcp_yes_ports=[] +tcp_nop_ports=[] + def IsWindows(): return v_system=="Windows" @@ -81,14 +91,31 @@ def Append2File(text, file_path): def DeleteFolder(path): shutil.rmtree(path) +def CleanUpOldGen(working_path): + """Finds folders starting with 'db', 'chan', 'auth', or 'logs' in the working_path and deletes them, excluding subfolders.""" + if not os.path.exists(working_path): + return + + target_prefixes = ("db", "chan", "auth", "logs") + folders_to_delete = [] + + # Only iterate through the immediate children of working_path + for _dir in os.listdir(working_path): + if _dir.lower().startswith(target_prefixes): + folder_path = os.path.join(working_path, _dir) + folders_to_delete.append(folder_path) + + for folder_path in folders_to_delete: + DeleteFolder(folder_path) + def SymLinkCreate(src, dst, is_file): src = SlashFix(src) dst = SlashFix(dst) - if v_system=="FreeBSD": + if v_system == "FreeBSD": fShell(f"ln -Ffnsw {src} {dst}") - elif v_system=="Linux": + elif v_system == "Linux": fShell(f"ln -Ffns {src} {dst}") - elif v_system=="Windows": + elif v_system == "Windows": if is_file: fShell(f"mklink {dst} {src}") else: @@ -110,19 +137,19 @@ def WriteHostConfig(szConfFile, szGameName): Append2File(f"HOSTNAME: {szGameName}", szConfFile) def WriteChannelConfig(szConfFile, dwChannel): - if dwChannel==M2TYPE.NOCHAN: - dwChannel=1 + if dwChannel == M2TYPE.NOCHAN: + dwChannel = 1 Append2File(f"CHANNEL: {dwChannel}", szConfFile) def WriteMapConfig(szConfFile, szMapList): - if len(szMapList.split())>=32: + if len(szMapList.split()) >= 32: print(f"WARNING: MORE THAN 32 MAPS INSIDE: {szConfFile}") Append2File(f"MAP_ALLOW: {szMapList}", szConfFile) def WritePortConfig(szConfFile, wGenPort, dwType, dwPortType=None): - if dwType==M2TYPE.DB: + if dwType == M2TYPE.DB: Append2File(f"{PORT.lPORT[PORT.BIND_PORT]} = {wGenPort}", szConfFile) - elif dwType==M2TYPE.CORE or dwType==M2TYPE.AUTH: + elif dwType == M2TYPE.CORE or dwType == M2TYPE.AUTH: Append2File(f"{PORT.lPORT[dwPortType]}: {wGenPort}", szConfFile) def genWriteConfig(szConfFile, tuSubConfTable): @@ -135,8 +162,8 @@ def genWriteConfig(szConfFile, tuSubConfTable): except IndexError: print(repr(val1)) raise IndexError - #skip test server in ch1 - if DISABLE_TEST_MODE_IN_CH1 and configValue.strip()=="TEST_SERVER: 1" and "/ch1/" in szConfFile: + # skip test server in ch1 + if DISABLE_TEST_MODE_IN_CH1 and configValue.strip() == "TEST_SERVER: 1" and "/ch1/" in szConfFile: continue try: @@ -288,20 +315,19 @@ def genInitSrv(szSvr): CreateFolder("%s/%s"%(szSvr, val1)) # print "%s/%s"%(szSvr, val1) # - for val1 in ("share/conf/BANIP","share/conf/CMD","share/conf/CRC","share/conf/VERSION","share/conf/state_user_count","share/bin/db","share/bin/game"): + for val1 in ("share/conf/BANIP","share/conf/CMD","share/conf/CRC","share/conf/VERSION","share/conf/state_user_count"): + TouchFile("%s/%s" % (szSvr, val1)) + # print "%s/%s"%(szSvr, val1) + # + for val1 in ("share/bin/db","share/bin/game"): + if IsWindows(): + val1 += ".exe" TouchFile("%s/%s" % (szSvr, val1)) # print "%s/%s"%(szSvr, val1) # for val1 in ("share/conf/item_names.txt","share/conf/item_proto.txt","share/conf/mob_names.txt","share/conf/mob_proto.txt"): TouchFile("%s/%s" % (szSvr, val1)) # print "%s/%s"%(szSvr, val1) -#global single server rules -genConfig = {} -genConfig["all"] = {} -#for ipfw rules -udp_yes_ports=[] -tcp_yes_ports=[] -tcp_nop_ports=[] def genCalcParentRet(szParentName): return szParentName.count("/")*v_chanPath @@ -319,8 +345,9 @@ def genMain(oSub={}, szParentName=[]): listTmpParentName=list(szParentName) # list() to bypass variable passed by reference to value listTmpParentName.append(k1) szTmpParentName=("/".join(listTmpParentName)) - # DeleteFolder("%s" % szTmpParentName) # completely unsafe CreateFolder("%s" % szTmpParentName) + if ENABLE_CLEAN_UP_OLD_GEN: + CleanUpOldGen(szTmpParentName) # print szTmpParentName if v1["type"]==M2TYPE.DB: k1s=genConfig["active"] diff --git a/serverfiles/main/stop.py b/serverfiles/main/stop.py index 9ea8e9d84..b853867f1 100644 --- a/serverfiles/main/stop.py +++ b/serverfiles/main/stop.py @@ -125,8 +125,6 @@ if __name__ == "__main__": szWhichServ = "" szWhichChan = {} dwLevel=1 - if v_system=="Windows": - dwLevel=9 optlist, args = g_getopt(s_argv[1:],"l:ps",('level=','prompt','selective','whichserv=','whichchan=')) for o, a in optlist: if o in ('-s', '--selective'):