Skip to content

Commit

Permalink
Merge pull request #99 from fa0311/develop-v5
Browse files Browse the repository at this point in the history
v5.2.0
  • Loading branch information
fa0311 authored Sep 11, 2023
2 parents a036b6b + 6dcc937 commit 0737032
Show file tree
Hide file tree
Showing 15 changed files with 283 additions and 107 deletions.
58 changes: 38 additions & 20 deletions DMMGamePlayerFastLauncher/DMMGamePlayerFastLauncher.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import argparse
import logging
import os
import sys
import time

import customtkinter as ctk
import i18n
Expand All @@ -16,38 +18,54 @@


def loder(master: LanchLauncher):
DataPathConfig.ACCOUNT.mkdir(exist_ok=True, parents=True)
DataPathConfig.ACCOUNT_SHORTCUT.mkdir(exist_ok=True, parents=True)
DataPathConfig.SHORTCUT.mkdir(exist_ok=True, parents=True)
DataPathConfig.SCHTASKS.mkdir(exist_ok=True, parents=True)

config_loder()
i18n.load_path.append(str(AssetsPathConfig.I18N))
i18n.set("locale", AppConfig.DATA.lang.get())

if AppConfig.DATA.debug_window.get() and not logging.getLogger().hasHandlers():
handlers = []

if AppConfig.DATA.output_logfile.get() and not any([isinstance(x, logging.FileHandler) for x in logging.getLogger().handlers]):
DataPathConfig.LOG.mkdir(exist_ok=True, parents=True)
handler = logging.FileHandler(DataPathConfig.LOG.joinpath(f"{time.strftime('%Y%m%d%H%M%S')}.log"), encoding="utf-8")
handlers.append(handler)

if AppConfig.DATA.debug_window.get() and not any([isinstance(x, LoggingHandler) for x in logging.getLogger().handlers]):
handler = LoggingHandler(TkinkerLogger(master).create().box, scheme=StyleScheme)
handler.setFormatter(ColoredFormatter("[%(levelname)s] [%(asctime)s] %(message)s"))
logging.basicConfig(level=logging.DEBUG, handlers=[handler])

logging.debug("==================================================")
logging.debug("===== DMMGamePlayerFastLauncher Environment =====")
logging.debug("==================================================")
logging.debug(Env.dump())
logging.debug(AppConfig.DATA.to_dict())
logging.debug(AppConfig.DEVICE.to_dict())
logging.debug(DataPathConfig.dump())
logging.debug(AssetsPathConfig.dump())
logging.debug(UrlConfig.dump())
logging.debug(SchtasksConfig.dump())
logging.debug("==================================================")
logging.debug("==================================================")
logging.debug("==================================================")
handlers.append(handler)

if not any([isinstance(x, logging.StreamHandler) for x in logging.getLogger().handlers]):
handler = logging.StreamHandler()
handler.setFormatter(ColoredFormatter("[%(levelname)s] [%(asctime)s] %(message)s"))
handlers.append(handler)

logging.basicConfig(level=logging.DEBUG, handlers=handlers)

logging.debug("==================================================")
logging.debug("===== DMMGamePlayerFastLauncher Environment =====")
logging.debug("==================================================")
logging.debug(Env.dump())
logging.debug(AppConfig.DATA.to_dict())
logging.debug(AppConfig.DEVICE.to_dict())
logging.debug(DataPathConfig.dump())
logging.debug(AssetsPathConfig.dump())
logging.debug(UrlConfig.dump())
logging.debug(SchtasksConfig.dump())
logging.debug(sys.argv)
logging.debug("==================================================")
logging.debug("==================================================")
logging.debug("==================================================")

if AppConfig.DATA.proxy_http.get() != "":
os.environ["HTTP_PROXY"] = AppConfig.DATA.proxy_http.get()
if AppConfig.DATA.proxy_https.get() != "":
os.environ["HTTPS_PROXY"] = AppConfig.DATA.proxy_https.get()

DataPathConfig.ACCOUNT.mkdir(exist_ok=True)
DataPathConfig.SHORTCUT.mkdir(exist_ok=True)
DataPathConfig.SCHTASKS.mkdir(exist_ok=True)

ctk.set_default_color_theme(str(AssetsPathConfig.THEMES.joinpath(AppConfig.DATA.theme.get()).with_suffix(".json")))
ctk.set_appearance_mode(AppConfig.DATA.appearance_mode.get())

Expand Down
10 changes: 8 additions & 2 deletions DMMGamePlayerFastLauncher/component/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,15 @@ def no(self):


class CTkProgressWindow(CTkToplevel):
label: CTkLabel
progress: CTkProgressBar
now: int
max: int

def __init__(self, master: Misc, now: int = 0, max: int = 1):
super().__init__(master)
self.geometry("300x100")
self.label = CTkLabel(self, text="0.00%", justify=ctk.LEFT, anchor=ctk.W)
self.progress = CTkProgressBar(self, width=300)

self.deiconify()
Expand All @@ -260,15 +262,19 @@ def __init__(self, master: Misc, now: int = 0, max: int = 1):
self.max = max

def create(self):
CTkLabel(self, text=i18n.t("app.component.download")).pack(side=ctk.TOP, fill=ctk.X, expand=True, padx=10, pady=10)
self.progress.pack(expand=True, fill="x", padx=10, pady=10)
CTkLabel(self, text=i18n.t("app.component.download")).pack(fill=ctk.X, expand=True, padx=10, pady=(10, 0))
self.label.pack(fill=ctk.X, expand=True, padx=10, pady=0)
self.progress.pack(fill=ctk.X, expand=True, padx=10, pady=(0, 10))

self.progress.set(self.now / self.max)
return self

def add(self, value: int):
self.now += value
self.progress.set(self.now / self.max)
self.label.configure(text=f"{(self.now / self.max * 100):.2f}%")

def set(self, value: int):
self.now = value
self.progress.set(self.now / self.max)
self.label.configure(text=f"{(self.now / self.max * 100):.2f}%")
1 change: 1 addition & 0 deletions DMMGamePlayerFastLauncher/component/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def __init__(self, master):
self.title("Log")
self.geometry("600x300")
self.box = CTkTextbox(self, height=30)
self.protocol("WM_DELETE_WINDOW", lambda: self.withdraw())

def create(self):
self.box.pack(fill=ctk.BOTH, padx=10, pady=(0, 10), expand=True)
Expand Down
42 changes: 30 additions & 12 deletions DMMGamePlayerFastLauncher/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from lib.thread import threading_wrapper
from lib.toast import ErrorWindow
from models.setting_data import AppConfig
from models.shortcut_data import ShortcutData
from models.shortcut_data import LauncherShortcutData, ShortcutData
from static.config import DataPathConfig
from static.env import Env
from tab.home import HomeTab
Expand Down Expand Up @@ -78,7 +78,7 @@ def launch(self, id: str):

if response["data"]["latest_version"] != game["detail"]["version"]:
if data.auto_update.get():
download = session.download(response["data"]["file_list_url"], game_path.parent)
download = session.download(response["data"]["file_list_url"], game_file)
box = CTkProgressWindow(self).create()
for progress, file in download:
box.set(progress)
Expand All @@ -88,11 +88,11 @@ def launch(self, id: str):

dmm_args = response["data"]["execute_args"].split(" ") + data.game_args.get().split(" ")

process = ProcessManager.run([str(game_path.absolute())] + dmm_args)
process = ProcessManager.run([str(game_path.relative_to(game_file))] + dmm_args, cwd=str(game_file))
assert process.stdout is not None

for line in process.stdout:
text = line.decode("utf-8").strip()
logging.debug(text)
logging.debug(decode(line))


class LanchLauncher(CTk):
Expand Down Expand Up @@ -122,26 +122,44 @@ def thread(self, id: str):
raise

def launch(self, id: str):
path = DataPathConfig.ACCOUNT.joinpath(id).with_suffix(".bytes")
path = DataPathConfig.ACCOUNT_SHORTCUT.joinpath(id).with_suffix(".json")
with open(path, "r", encoding="utf-8") as f:
data = LauncherShortcutData.from_dict(json.load(f))

account_path = DataPathConfig.ACCOUNT.joinpath(data.account_path.get()).with_suffix(".bytes")

with DgpSessionWrap() as session:
session.read_bytes(str(path))
session.read_bytes(str(account_path))
if session.cookies.get("login_secure_id", **session.cookies_kwargs) is None:
raise Exception(i18n.t("app.launch.export_error"))
session.write()

dgp = AppConfig.DATA.dmm_game_player_program_folder.get_path().joinpath("DMMGamePlayer.exe").absolute()
process = ProcessManager().run([str(dgp)])
dgp = AppConfig.DATA.dmm_game_player_program_folder.get_path()

dmm_args = data.dgp_args.get().split(" ")
process = ProcessManager.run(["DMMGamePlayer.exe"] + dmm_args, cwd=str(dgp.absolute()))

assert process.stdout is not None
for line in process.stdout:
text = line.decode("utf-8").strip()
logging.debug(text)
logging.debug(decode(line))

with DgpSessionWrap() as session:
session.read()
if session.cookies.get("login_secure_id", **session.cookies_kwargs) is None:
raise Exception(i18n.t("app.launch.import_error"))
session.write_bytes(str(path))
session.write_bytes(str(account_path))

session.cookies.clear()
session.write()


def decode(s: bytes) -> str:
try:
return s.decode("utf-8").strip()
except Exception:
pass
try:
return s.decode("cp932").strip()
except Exception:
pass
return str(s)
3 changes: 3 additions & 0 deletions DMMGamePlayerFastLauncher/lib/DGPSessionV2.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ def download_save(file: dict):
f.write(content)
return file["size"], file

if data["data"]["page"] > 1:
raise Exception("Not supported multiple pages")

size = sum([x["size"] for x in data["data"]["file_list"]])
download_size = 0

Expand Down
6 changes: 3 additions & 3 deletions DMMGamePlayerFastLauncher/lib/process_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ def admin_check() -> bool:
return False

@staticmethod
def run(args: list[str]) -> subprocess.Popen[bytes]:
logging.info(args)
return subprocess.Popen(args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def run(args: list[str], cwd: Optional[str] = None) -> subprocess.Popen:
logging.info({"cwd": cwd, "args": args})
return subprocess.Popen(args, cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

@staticmethod
def run_ps(args: str) -> int:
Expand Down
1 change: 1 addition & 0 deletions DMMGamePlayerFastLauncher/models/setting_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class SettingData(VariableBase):
appearance_mode: StringVar = field(default_factory=lambda: StringVar(value="dark"))
window_scaling: DoubleVar = field(default_factory=lambda: DoubleVar(value=1.0))
debug_window: BooleanVar = field(default_factory=lambda: BooleanVar(value=False))
output_logfile: BooleanVar = field(default_factory=lambda: BooleanVar(value=False))

def update(self):
DgpSessionV2.DGP5_PATH = self.dmm_game_player_program_folder.get_path()
Expand Down
6 changes: 6 additions & 0 deletions DMMGamePlayerFastLauncher/models/shortcut_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ class ShortcutData(VariableBase):
game_args: StringVar = field(default_factory=StringVar)
auto_update: BooleanVar = field(default_factory=lambda: BooleanVar(value=True))
game_type: StringVar = field(default_factory=lambda: StringVar(value="GCL"))


@dataclass
class LauncherShortcutData(VariableBase):
account_path: PathVar = field(default_factory=PathVar)
dgp_args: StringVar = field(default_factory=StringVar)
2 changes: 2 additions & 0 deletions DMMGamePlayerFastLauncher/static/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
class DataPathConfig(Dump):
DATA = Path("data")
ACCOUNT = DATA.joinpath("account")
ACCOUNT_SHORTCUT = DATA.joinpath("account_shortcut")
SHORTCUT = DATA.joinpath("shortcut")
LOG = DATA.joinpath("log")
APP_CONFIG = DATA.joinpath("config.json")
SCHTASKS = DATA.joinpath("schtasks")
DEVICE = DATA.joinpath("device.json")
Expand Down
2 changes: 1 addition & 1 deletion DMMGamePlayerFastLauncher/static/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


class Env(Dump):
VERSION = "v5.1.2"
VERSION = "v5.2.0"
RELEASE_VERSION = requests.get(UrlConfig.RELEASE_API).json().get("tag_name", VERSION)

DEVELOP: bool = os.environ.get("ENV") == "DEVELOP"
Expand Down
2 changes: 1 addition & 1 deletion DMMGamePlayerFastLauncher/tab/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def select_callback(self, value: str):

children_destroy(self)
self.create()
self.toast.info(i18n.t("app.account.auth_success"))
self.toast.info(i18n.t("app.account.device_list_success"))

@error_toast
def delete_callback(self, id: str):
Expand Down
1 change: 1 addition & 0 deletions DMMGamePlayerFastLauncher/tab/setting.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def create(self):

PaddingComponent(self, height=5).create()
CheckBoxComponent(self, text=i18n.t("app.setting.debug_window"), variable=self.data.debug_window).create()
CheckBoxComponent(self, text=i18n.t("app.setting.output_logfile"), variable=self.data.output_logfile).create()

PaddingComponent(self, height=5).create()
CTkButton(self, text=i18n.t("app.setting.save"), command=self.save_callback).pack(fill=ctk.X, pady=10)
Expand Down
Loading

0 comments on commit 0737032

Please sign in to comment.