From 80fbdb47d671234ea42139f6e0cd7b9f3887ad8c Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 02:19:26 +0800 Subject: [PATCH 01/12] Fix: Pal HP not full --- src/palworld_pal_editor/core/pal_entity.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/palworld_pal_editor/core/pal_entity.py b/src/palworld_pal_editor/core/pal_entity.py index 798d24f..a891dcd 100644 --- a/src/palworld_pal_editor/core/pal_entity.py +++ b/src/palworld_pal_editor/core/pal_entity.py @@ -157,6 +157,7 @@ def CharacterID(self, value: str) -> None: self.heal_pal() self.clear_worker_sick() # self.MaxHP = self.ComputedMaxHP + self.HP = self.ComputedMaxHP @property def _RawSpecieKey(self) -> Optional[str]: @@ -283,6 +284,7 @@ def IsTower(self, value: bool) -> None: else: self.CharacterID = f"GYM_{self._RawSpecieKey}" # self.MaxHP = self.ComputedMaxHP + self.HP = self.ComputedMaxHP @property def _IsBOSS(self) -> bool: @@ -323,6 +325,7 @@ def IsBOSS(self, value: bool) -> None: self._IsBOSS = value # Update MaxHP # self.MaxHP = self.ComputedMaxHP + self.HP = self.ComputedMaxHP @property def IsRarePal(self) -> Optional[bool]: @@ -380,6 +383,7 @@ def Level(self, value: int) -> None: self.Exp = DataProvider.get_level_xp(self.Level) # Update MaxHP # self.MaxHP = self.ComputedMaxHP + self.HP = self.ComputedMaxHP # Learn Attacks self.learn_attacks() @@ -418,6 +422,7 @@ def Rank(self, rank: PalRank | int) -> None: PalObjects.set_BaseType(self._pal_param["Rank"], pal_rank.value) # self.MaxHP = self.ComputedMaxHP + self.HP = self.ComputedMaxHP if self.Rank == PalRank.Rank0: self._pal_param.pop("Rank", None) @@ -444,6 +449,7 @@ def Rank_CraftSpeed(self) -> Optional[int]: def Rank_HP(self, rank: int) -> None: self._set_soul_rank('Rank_HP', rank) # self.MaxHP = self.ComputedMaxHP + self.HP = self.ComputedMaxHP @Rank_Attack.setter @LOGGER.change_logger('Rank_Attack') @@ -577,6 +583,7 @@ def add_PassiveSkillList(self, skill: str) -> bool: LOGGER.info(f"Added {DataProvider.get_passive_i18n(skill)[0]} to PassiveSkillList") # Update MaxHP, but no such skill atm. # self.MaxHP = self.ComputedMaxHP + # self.HP = self.ComputedMaxHP return True @LOGGER.change_logger('PassiveSkillList') @@ -715,6 +722,7 @@ def Talent_Defense(self) -> Optional[int]: def Talent_HP(self, value: int): self._set_iv("Talent_HP", value) # self.MaxHP = self.ComputedMaxHP + self.HP = self.ComputedMaxHP @Talent_Melee.setter @LOGGER.change_logger("Talent_Melee") @@ -839,8 +847,7 @@ def heal_pal(self): self._pal_param.pop("PhysicalHealth", None) # if not self.MaxHP: # self.MaxHP = self.ComputedMaxHP - self.HP = int(self.ComputedMaxHP * 0.9) - + self.HP = self.ComputedMaxHP @property def FoodWithStatusEffect(self) -> Optional[str]: From 9b0138cf6dcffea5b868a9b8d615ff7194bf7edb Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 11:51:08 +0800 Subject: [PATCH 02/12] Update PyPi build script --- MANIFEST.in | 2 ++ README.cn.md | 2 +- README.md | 2 ++ pypi_publish.sh | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100755 pypi_publish.sh diff --git a/MANIFEST.in b/MANIFEST.in index b7b09e0..ea25914 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,7 @@ +include src/palworld_pal_editor/assets/* include src/palworld_pal_editor/assets/data/* include src/palworld_pal_editor/assets/icons/elements/* include src/palworld_pal_editor/assets/icons/pals/* +include src/palworld_pal_editor/webui/* include src/palworld_pal_editor/webui/assets/* include src/palworld_pal_editor/webui/icons/* \ No newline at end of file diff --git a/README.cn.md b/README.cn.md index 6c91695..e33417d 100644 --- a/README.cn.md +++ b/README.cn.md @@ -25,7 +25,7 @@ ### 幻兽帕鲁 帕鲁 编辑器 - + > [!NOTE] > **本工具目前只支持Steam,如果你使用的是Xbox Game Pass版本,可以参考一下两个工具来转换存档格式:** diff --git a/README.md b/README.md index 9218a86..1a7de2a 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ ### A Palworld Pal Editor developed by _connlost with ❤️ + + ~~(yeah i am just too lazy to change github username)~~ > [!NOTE] diff --git a/pypi_publish.sh b/pypi_publish.sh new file mode 100755 index 0000000..960b427 --- /dev/null +++ b/pypi_publish.sh @@ -0,0 +1,52 @@ +if which npm > /dev/null; then + NPM_CMD=npm +else + echo "Node is not installed." +fi + +cd "./frontend/palworld-pal-editor-webui" +${NPM_CMD} install +${NPM_CMD} run build +cd "../../" +rm -r "./src/palworld_pal_editor/webui" +mv "./frontend/palworld-pal-editor-webui/dist" "./src/palworld_pal_editor/webui" + +# Check for Python 3.x and set the appropriate command +if which python3 > /dev/null; then + PYTHON_CMD=python3 +elif which python > /dev/null; then + PYTHON_CMD=python +else + echo "Python is not installed." + exit 1 +fi + +# Extract the Python version +PYTHON_VERSION=$(${PYTHON_CMD} --version | awk '{print $2}') +PYTHON_MAJOR_VERSION=$(echo ${PYTHON_VERSION} | cut -d. -f1) +PYTHON_MINOR_VERSION=$(echo ${PYTHON_VERSION} | cut -d. -f2) + +# Check if Python version is 3.11 or newer +if [ "${PYTHON_MAJOR_VERSION}" -lt 3 ] || { [ "${PYTHON_MAJOR_VERSION}" -eq 3 ] && [ "${PYTHON_MINOR_VERSION}" -lt 11 ]; }; then + echo "Python version 3.11 or newer is required." + exit 1 +fi + +echo "Using ${PYTHON_CMD} (version ${PYTHON_VERSION})" + +# Create a virtual environment named 'venv' (skip if already created) +${PYTHON_CMD} -m venv venv + +# Activate the virtual environment +source venv/bin/activate + +# Install packages from requirements.txt +pip install -r requirements.txt + +pip install twine +pip install --upgrade build + +rm -r "./dist" + +python -m build +python -m twine upload dist/* \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 03261f5..fd45de8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ keywords = ["palworld", "editor", "pal"] license = {file = "LICENSE"} requires-python = ">=3.11" readme = "README.md" -version = "0.4.1" +version = "0.4.1.post2" dependencies = [ "setuptools==69.1.0", "palworld_save_tools==0.19.0", From 246e505265a158be4df48a4cfd79e56e9a90a91c Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 11:51:34 +0800 Subject: [PATCH 03/12] Better File Picker Error Handling --- .../src/stores/paleditor.js | 8 ++-- .../src/views/EntryView.vue | 2 +- src/palworld_pal_editor/api/save.py | 37 +++++++++++++------ 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/frontend/palworld-pal-editor-webui/src/stores/paleditor.js b/frontend/palworld-pal-editor-webui/src/stores/paleditor.js index b058109..6d109b1 100644 --- a/frontend/palworld-pal-editor-webui/src/stores/paleditor.js +++ b/frontend/palworld-pal-editor-webui/src/stores/paleditor.js @@ -275,7 +275,7 @@ export const usePalEditorStore = defineStore("paleditor", () => { const I18n = ref(localStorage.getItem("PAL_I18n")); const PAL_GAME_SAVE_PATH = ref(localStorage.getItem("PAL_GAME_SAVE_PATH")); const HAS_PASSWORD = ref(false); - const IS_GUI = ref(false) + const FilePickerAvailable = ref(false) const PAL_WRITE_BACK_PATH = ref(""); // auth @@ -437,7 +437,7 @@ export const usePalEditorStore = defineStore("paleditor", () => { PAL_GAME_SAVE_PATH.value = response.data.Path; } HAS_PASSWORD.value = response.data.HasPassword; - IS_GUI.value = response.data.Mode == "gui" + FilePickerAvailable.value = response.data.FilePickerAvailable // console.log(I18n.value, PAL_GAME_SAVE_PATH.value, HAS_PASSWORD.value, IS_GUI.value); } else if (response.status == 2) { alert("Unauthorized Access, Please Login. "); @@ -451,7 +451,7 @@ export const usePalEditorStore = defineStore("paleditor", () => { } async function show_file_picker() { - if (!IS_GUI.value) { + if (!FilePickerAvailable.value) { alert("This only works in GUI mode!") return; } @@ -1172,7 +1172,7 @@ export const usePalEditorStore = defineStore("paleditor", () => { IS_LOCKED, HAS_PASSWORD, - IS_GUI, + FilePickerAvailable, HAS_WORKING_PAL_FLAG, BASE_PAL_BTN_CLK_FLAG, diff --git a/frontend/palworld-pal-editor-webui/src/views/EntryView.vue b/frontend/palworld-pal-editor-webui/src/views/EntryView.vue index a0981f3..605d920 100644 --- a/frontend/palworld-pal-editor-webui/src/views/EntryView.vue +++ b/frontend/palworld-pal-editor-webui/src/views/EntryView.vue @@ -27,7 +27,7 @@ const palStore = usePalEditorStore() - + diff --git a/src/palworld_pal_editor/api/save.py b/src/palworld_pal_editor/api/save.py index 8170900..3f8fff9 100644 --- a/src/palworld_pal_editor/api/save.py +++ b/src/palworld_pal_editor/api/save.py @@ -12,13 +12,22 @@ @save_blueprint.route("/fetch_config", methods=["GET"]) def fetch_config(): + tk_status = False + if Config.mode == "gui": + try: + import tkinter as tk + tk_status = True + except: + trace = traceback.format_exc() + LOGGER.error(f"Hiding File Picker Since It Will Not Work: {trace}") + return reply( 0, { "I18n": Config.i18n, "Path": Config.path, "HasPassword": Config.password != None, - "Mode": Config.mode + "FilePickerAvailable": Config.mode == "gui" and tk_status }, ) @@ -156,13 +165,19 @@ def show_file_picker(): LOGGER.warning(msg) return reply(1, msg=msg) - import tkinter as tk - from tkinter import filedialog - - root = tk.Tk() - root.withdraw() - root.attributes('-topmost', True) - folder_selected = filedialog.askdirectory(parent=root) - root.destroy() - LOGGER.info(f"File picker result: {folder_selected}") - return reply(0, {"path": folder_selected}) \ No newline at end of file + try: + import tkinter as tk + from tkinter import filedialog + + root = tk.Tk() + root.withdraw() + root.attributes('-topmost', True) + folder_selected = filedialog.askdirectory(parent=root) + root.destroy() + LOGGER.info(f"File picker result: {folder_selected}") + return reply(0, {"path": folder_selected}) + except: + trace = traceback.format_exc() + LOGGER.error(f"Failed Open File Picker: {trace}") + LOGGER.error(f"Please Manually Type in the Path.") + return reply(1, msg="Failed open file picker (check log for detail), please manually type in the path.") \ No newline at end of file From 2c39c0e92810198dc81c7264ccee073061632a68 Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 12:38:08 +0800 Subject: [PATCH 04/12] update readme --- README.cn.md | 22 +++++++++++++++------- README.md | 23 ++++++++++++++++------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/README.cn.md b/README.cn.md index e33417d..9f07891 100644 --- a/README.cn.md +++ b/README.cn.md @@ -1,15 +1,21 @@ # Palworld Pal Editor -

+

English | 简体中文 -

+

-GitHub Repo Stars   -GitHub Repo Downloads   -Discord Server   -Python   -Vue.js   +GitHub Repo Stars  +GitHub Release +GitHub Repo Downloads  +

+

+Python  +PyPI - Version  +PyPI - Downloads  +

+

+Discord Server 

## 支持的语言 @@ -28,6 +34,8 @@ > [!NOTE] +> Steam 本地游戏存档文件夹: `%localappdata%\Pal\Saved\SaveGames` +> > **本工具目前只支持Steam,如果你使用的是Xbox Game Pass版本,可以参考一下两个工具来转换存档格式:** > > - [XGP-save-extractor (XGP -> Steam)](https://github.com/windwq/XGP-save-extractor) diff --git a/README.md b/README.md index 1a7de2a..af1dd4d 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,23 @@ # Palworld Pal Editor -

+

English | 简体中文 -

+

-GitHub Repo Stars   -GitHub Repo Downloads   -Discord Server   -Python   -Vue.js   +GitHub Repo Stars  +GitHub Release +GitHub Repo Downloads  +

+

+Python  +PyPI - Version  +PyPI - Downloads 

+

+Discord Server  +

+ ## Supported Language @@ -30,6 +37,8 @@ ~~(yeah i am just too lazy to change github username)~~ > [!NOTE] +> Steam Local Save Dir: `%localappdata%\Pal\Saved\SaveGames` +> > **This tool currently only supports the Steam version of Palworld, if you are playing the Xbox Game Pass version, you can look into these two tools for save format conversion:** > > - [XGP-save-extractor (XGP -> Steam)](https://github.com/windwq/XGP-save-extractor) From 4229001e1c83707668f49f615a88e59c7fb315d0 Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 13:08:28 +0800 Subject: [PATCH 05/12] flask: set mime type --- src/palworld_pal_editor/webui.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/palworld_pal_editor/webui.py b/src/palworld_pal_editor/webui.py index 797700a..b958dac 100644 --- a/src/palworld_pal_editor/webui.py +++ b/src/palworld_pal_editor/webui.py @@ -9,7 +9,13 @@ from palworld_pal_editor.config import ASSETS_PATH, Config from palworld_pal_editor.api import * from palworld_pal_editor.utils import LOGGER +import mimetypes +# attempt to fix MIME TYPE error for some user +mimetypes.add_type('application/javascript', '.js') +mimetypes.add_type('text/css', '.css') +mimetypes.add_type('image/png', '.png') +mimetypes.add_type('text/html', '.html') app = Flask(__name__, static_folder=ASSETS_PATH / "webui", static_url_path='/') app.register_blueprint(player_blueprint, url_prefix='/api/player') From 290339c2bdba770160ad786b4e02d3cde1fe7529 Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 13:13:25 +0800 Subject: [PATCH 06/12] flask: return index.html when unknown path is received --- src/palworld_pal_editor/webui.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/palworld_pal_editor/webui.py b/src/palworld_pal_editor/webui.py index b958dac..5fff057 100644 --- a/src/palworld_pal_editor/webui.py +++ b/src/palworld_pal_editor/webui.py @@ -44,14 +44,13 @@ def serve_image(icon_type, filename): @app.route('/', defaults={'path': ''}) -@app.route('/') +@app.route('/') def serve(path): static_folder_path = Path(app.static_folder) target_path = static_folder_path / path if path != "" and target_path.exists(): return send_from_directory(str(static_folder_path), path) - else: - return send_from_directory(str(static_folder_path), 'index.html') + return send_from_directory(str(static_folder_path), 'index.html') @app.route('/api/ready') def ready(): From 467fa6b8e59258065907c862754134fe440501e5 Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 13:15:53 +0800 Subject: [PATCH 07/12] [hotfixes 0.4.2] misc fixes --- pyproject.toml | 2 +- src/palworld_pal_editor/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fd45de8..963cfc4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ keywords = ["palworld", "editor", "pal"] license = {file = "LICENSE"} requires-python = ">=3.11" readme = "README.md" -version = "0.4.1.post2" +version = "0.4.2" dependencies = [ "setuptools==69.1.0", "palworld_save_tools==0.19.0", diff --git a/src/palworld_pal_editor/config.py b/src/palworld_pal_editor/config.py index 8b8f399..3c6379d 100644 --- a/src/palworld_pal_editor/config.py +++ b/src/palworld_pal_editor/config.py @@ -11,7 +11,7 @@ else: ASSETS_PATH = Path(__file__).parent -VERSION = "0.4.1" +VERSION = "0.4.2" class Config: i18n: str = "en" From b8f113f0229b5acb5c0c482a14dea56a365f4d6f Mon Sep 17 00:00:00 2001 From: connlost <4348524953.h@gmail.com> Date: Fri, 5 Apr 2024 23:01:01 +0800 Subject: [PATCH 08/12] Hide invalid pal/skills by default, add button to toggle them --- .../src/components/PalEditor.vue | 23 +++++++++++----- .../src/components/TopBar.vue | 26 ++++++++++++++++--- .../src/stores/paleditor.js | 4 ++- src/palworld_pal_editor/api/save.py | 1 + .../utils/data_provider.py | 1 + 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/frontend/palworld-pal-editor-webui/src/components/PalEditor.vue b/frontend/palworld-pal-editor-webui/src/components/PalEditor.vue index d2e8785..41f1832 100644 --- a/frontend/palworld-pal-editor-webui/src/components/PalEditor.vue +++ b/frontend/palworld-pal-editor-webui/src/components/PalEditor.vue @@ -21,6 +21,16 @@ function formatString(input) { return formatted; } +function filterInvalid(list) { + return list.filter(item => { + if (palStore.HIDE_INVALID_OPTIONS) { + // return !(item.Invalid || item.IsHuman) + return !item.Invalid + } + return true + }) +} +