From b2d4bdc76edb6863dc197f06a50e7b5e7297893e Mon Sep 17 00:00:00 2001 From: Dragon Taki Date: Sat, 9 Dec 2023 06:32:44 +0800 Subject: [PATCH 01/58] Update Limit.lps --- VPet-Simulator.Windows/mod/0000_core/lang/zh-Hant/Limit.lps | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VPet-Simulator.Windows/mod/0000_core/lang/zh-Hant/Limit.lps b/VPet-Simulator.Windows/mod/0000_core/lang/zh-Hant/Limit.lps index b1ec887..b73deba 100644 --- a/VPet-Simulator.Windows/mod/0000_core/lang/zh-Hant/Limit.lps +++ b/VPet-Simulator.Windows/mod/0000_core/lang/zh-Hant/Limit.lps @@ -6,5 +6,5 @@ 明月几时有,把酒问青天。无论考的如何,作业有多少,老师怎么说,家长怎么批评,萝莉丝都为你做了巧克力花生月饼,快说谢谢萝莉丝。#明月幾時有,把酒問青天。不論考的如何,工作有多少,老師怎麼說,家長如何責備,蘿莉斯都為你做了巧克力花生月餅,快說謝謝蘿莉斯。:| 主人,sbeam秋季促销开始了哦,还有游戏大奖赛,快去给{name}去投一票吧。#主人,sbeam秋季促銷開始了哦,還有遊戲大獎賽,快去給{name}去投一票吧。:| 主人主人,{name}参加了sbeam大奖赛哦,给人家投一票喵#主人主人,{name}參加了sbeam大獎賽哦,給人家投一票喵:| -那个。。主人。。\n人家参加了sbeam大奖赛哦。能不能。。给{name}投一票呢~#那個。。主人。。\n人家參加了sbeam大獎賽哦。能不能。。給{name}投一票呢~:| -电脑里有一款《虚拟桌宠模拟器》的游戏正在参加2023的sbeam大奖赛,快来给桌宠投一票吧#電腦裡有一款《虛擬桌寵模擬器》的遊戲正在參加2023的sbeam大獎賽,快來給桌寵投一票吧:| \ No newline at end of file +那个。。主人。。\n人家参加了sbeam大奖赛哦。能不能。。给{name}投一票呢~#那個。。主人。。\n人家參加了sbeam大獎賽哦。能不能…給{name}投一票呢~:| +电脑里有一款《虚拟桌宠模拟器》的游戏正在参加2023的sbeam大奖赛,快来给桌宠投一票吧#電腦裡有一款《虛擬桌寵模擬器》的遊戲正在參加2023的sbeam大獎賽,快來給桌寵投一票吧:| From 0ebd1285aec296a672462c42e9894e61f57f67a2 Mon Sep 17 00:00:00 2001 From: ZouJin Date: Tue, 12 Dec 2023 18:52:58 +0800 Subject: [PATCH 02/58] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20mklink.bat=20?= =?UTF-8?q?=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VPet-Simulator.Windows/mklink.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VPet-Simulator.Windows/mklink.bat b/VPet-Simulator.Windows/mklink.bat index db1ffbd..b47d029 100644 --- a/VPet-Simulator.Windows/mklink.bat +++ b/VPet-Simulator.Windows/mklink.bat @@ -1,4 +1,4 @@ -chcp 65001 +chcp 65001 mklink /d "%~dp0\bin\x64\Debug\net462\mod" "%~dp0\mod" From d0fdb57699af3ca4533e9242f9c09563dc616046 Mon Sep 17 00:00:00 2001 From: Dragon Taki Date: Thu, 14 Dec 2023 03:55:14 +0800 Subject: [PATCH 03/58] Create CONTRIBUTING_zht.md --- CONTRIBUTING_zht.md | 89 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 CONTRIBUTING_zht.md diff --git a/CONTRIBUTING_zht.md b/CONTRIBUTING_zht.md new file mode 100644 index 0000000..4df40b3 --- /dev/null +++ b/CONTRIBUTING_zht.md @@ -0,0 +1,89 @@ +[简体中文](./CONTRIBUTING.md) | 繁體中文 | [English](./CONTRIBUTING_en.md) + +## 参与开发 + +欢迎参与虚拟桌宠模拟器的开发! 为保证代码可维护度和游戏性,如果想要开发新的功能,请先[邮件联系](mailto:zoujin.dev@exlb.org)或发[Issues](https://github.com/LorisYounger/VPet/issues)我想要添加的功能/玩法, 以确保该功能/玩法适用于虚拟桌宠模拟器. 以免未来提交时因不合适被拒(而造成代码浪费)
+如果是修复错误或者BUG,无需联系我,修好后直接PR即可 + +当想法通过后,您可以通过 [fork](https://github.com/LorisYounger/VPet/fork) 功能拷贝代码至自己的github以方便编写自己的代码, 编写完毕后通过[pull requests](https://github.com/LorisYounger/VPet/compare) 提交
+如果您想法没有被通过,也可以另起炉灶,写个不同版本功能的桌宠软件. 但需遵守 [Apache License 2.0](https://github.com/LorisYounger/VPet/blob/main/LICENSE) 与 [动画版权声明与授权](https://github.com/LorisYounger/VPet#%E5%8A%A8%E7%94%BB%E7%89%88%E6%9D%83%E5%A3%B0%E6%98%8E%E4%B8%8E%E6%8E%88%E6%9D%83) +注: 一般来讲, 添加新功能都可以通过编写代码插件MOD实现, 详情请参见 [VPet.Plugin.Demo](https://github.com/LorisYounger/VPet.Plugin.Demo) + +我可能会对您的提交的代码进行修改,删减等以确保该功能/玩法适用于虚拟桌宠模拟器. + +## 动画版权声明与授权 + +在github中 [桌宠动画文件](https://github.com/LorisYounger/VPet/tree/main/VPet-Simulator.Windows/mod/0000_core/pet/vup) 动画版权归 [虚拟主播模拟器制作组](https://www.exlb.net/VUP-Simulator)所有, 当使用本类库时,您可能需要自行准备动画文件,或遵循以下协议 + +### 非商用用途授权 + +* 需要向用户告知动画文件来源并提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 +* 当您完成以上要求后,您可以免费使用动画文件 + +### 商用用途授权(低于10万) + +* 第一次使用时需弹窗并醒目的向用户告知动画文件来源并提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 +* 在相应页面(用户可以快捷访问)向用户告知动画文件来源并提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 +* 当您完成以上要求后,您可以免费使用动画文件 + +### 商用用途授权(高于10万或其他) + +* 请[邮件联系](mailto:zoujin.dev@exlb.org)我 + +### 分发动画文件 + +* 需要告知以上所有授权信息 +* 需要提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 +* 分发动画文件时禁止任何付费/收费行为 + +## 桌面端部署方法 + +1. 下载本项目, 通过VisualStudio打开 `VPet.sln` 文件 +2. 在生成栏中, 选择 位数为 `x64` 和生成项目为 `Vpet-Simulator.Windows` + ![image-20230208004330895](README.assets/image-20230208004330895.png) +3. 点击启动, 如果一切正常则会报错 `缺少模组Core,无法启动桌宠` +4. 以管理员身份运行 `mklink.bat`, 这会让mod文件链接到生成位置 +5. 再次点击启动即可正常运行 + +## 软件结构 + +* **VPet-Simulator.Windows: 适用于桌面端的虚拟桌宠模拟器** + * *Function 功能性代码存放位置* + * CoreMOD Mod管理类 + * MWController 窗体控制器 + + * *WinDesign 窗口和UI设计 + * winBetterBuy 更好买窗口 + * winCGPTSetting ChatGPT 设置 + * winSetting 软件设置/MOD 窗口 + * winConsole 开发控制台 + * winGameSetting 游戏设置 + * winReport 反馈中心 + + * MainWindows 主窗体,存放和展示Core + * PetHelper 快速切换小标 +* **VPet-Simulator.Tool: 方便制作MOD的工具(eg:图片帧生成)** +* **VPet-Simulator.Core: 软件核心 方便内置到任何WPF应用程序(例如:VUP-Simulator)** + * Handle 接口与控件 + * IController 窗体控制器 (调用相关功能和设置,例如移动到侧边等) + * Function 通用功能 + * GameCore 游戏核心,包含各种数据等内容 + * GameSave 游戏存档 + * IFood 食物/物品接口 + * PetLoader 宠物图形加载器 + * Graph 图形渲染 + * IGraph 动画基本接口 + * GraphCore 动画显示核心 + * GraphHelper 动画帮助类 + * GraphInfo 动画信息 + * FoodAnimation 食物动画 支持显示前中后3层夹心动画 不一定只用于食物,只是叫这个名字 + * PNGAnimation 桌宠动态动画组件 + * Picture 桌宠静态动画组件 + * Display 显示 + * basestyle/Theme 基本风格主题 + * Main.xaml 核心显示部件 + * MainDisplay 核心显示方法 + * MainLogic 核心显示逻辑 + * ToolBar 点击人物时候的工具栏 + * MessageBar 人物说话时候的说话栏 + * WorkTimer 工作时钟 From a654f9b7008ce5c34262f4972bdebc2313a6fa1b Mon Sep 17 00:00:00 2001 From: Dragon Taki Date: Thu, 14 Dec 2023 04:16:21 +0800 Subject: [PATCH 04/58] Update CONTRIBUTING_zht.md --- CONTRIBUTING_zht.md | 58 ++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/CONTRIBUTING_zht.md b/CONTRIBUTING_zht.md index 4df40b3..9fae609 100644 --- a/CONTRIBUTING_zht.md +++ b/CONTRIBUTING_zht.md @@ -1,51 +1,51 @@ [简体中文](./CONTRIBUTING.md) | 繁體中文 | [English](./CONTRIBUTING_en.md) -## 参与开发 +## 參與開發 -欢迎参与虚拟桌宠模拟器的开发! 为保证代码可维护度和游戏性,如果想要开发新的功能,请先[邮件联系](mailto:zoujin.dev@exlb.org)或发[Issues](https://github.com/LorisYounger/VPet/issues)我想要添加的功能/玩法, 以确保该功能/玩法适用于虚拟桌宠模拟器. 以免未来提交时因不合适被拒(而造成代码浪费)
-如果是修复错误或者BUG,无需联系我,修好后直接PR即可 +歡迎參與虛擬桌寵模擬器的開發!為了保證程式碼的可維護性及遊戲性,若想要開發新的功能,請先[電子郵件聯絡](mailto:zoujin.dev@exlb.org)或提交[Issue](https://github.com/LorisYounger/VPet/issues),標題為想要新增的功能/玩法,以確保該功能/玩法適用於虛擬桌寵模擬器,以免在您完成開發後,因不適合而被拒絕(而浪費您的時間)。
+如果是修正錯誤或BUG,則不需要先行聯絡,修好後直接提交即可。 -当想法通过后,您可以通过 [fork](https://github.com/LorisYounger/VPet/fork) 功能拷贝代码至自己的github以方便编写自己的代码, 编写完毕后通过[pull requests](https://github.com/LorisYounger/VPet/compare) 提交
-如果您想法没有被通过,也可以另起炉灶,写个不同版本功能的桌宠软件. 但需遵守 [Apache License 2.0](https://github.com/LorisYounger/VPet/blob/main/LICENSE) 与 [动画版权声明与授权](https://github.com/LorisYounger/VPet#%E5%8A%A8%E7%94%BB%E7%89%88%E6%9D%83%E5%A3%B0%E6%98%8E%E4%B8%8E%E6%8E%88%E6%9D%83) -注: 一般来讲, 添加新功能都可以通过编写代码插件MOD实现, 详情请参见 [VPet.Plugin.Demo](https://github.com/LorisYounger/VPet.Plugin.Demo) +當您提供的想法被贊同後,您可以使用[Fork](https://github.com/LorisYounger/VPet/fork)功能,將專案程式碼整個複製至個人的Github上,以便撰寫自己的程式碼。撰寫完畢後,使用[Pull Requests](https://github.com/LorisYounger/VPet/compare)提交。
+若您的想法並未被同意,也可以另起爐灶,開發一個不同版本及功能的桌寵軟體。須遵守[Apache License 2.0](https://github.com/LorisYounger/VPet/blob/main/LICENSE)及[動畫版權聲明與授權](https://github.com/LorisYounger/VPet/blob/main/README_zht.md#%E5%8B%95%E7%95%AB%E7%89%88%E6%AC%8A%E8%81%B2%E6%98%8E%E8%88%87%E6%8E%88%E6%AC%8A)。
+註:一般而言,加入新功能都可以透過撰寫模組來達成,詳情請見:[VPet.Plugin.Demo](https://github.com/LorisYounger/VPet.Plugin.Demo) -我可能会对您的提交的代码进行修改,删减等以确保该功能/玩法适用于虚拟桌宠模拟器. +作者可能會修改、刪減部分您所提交的程式碼,以確保該功能/玩法適用於虛擬桌寵模擬器。 -## 动画版权声明与授权 +## 動畫版權聲明與授權 -在github中 [桌宠动画文件](https://github.com/LorisYounger/VPet/tree/main/VPet-Simulator.Windows/mod/0000_core/pet/vup) 动画版权归 [虚拟主播模拟器制作组](https://www.exlb.net/VUP-Simulator)所有, 当使用本类库时,您可能需要自行准备动画文件,或遵循以下协议 +在Github中,[桌寵動畫檔案](https://github.com/LorisYounger/VPet/tree/main/VPet-Simulator.Windows/mod/0000_core/pet/vup)之動畫版權歸[虛擬主播模擬器製作組](https://www.exlb.net/VUP-Simulator)所有,在使用本類別庫時,您可能會需要自行準備動畫檔,或遵循下列協定: -### 非商用用途授权 +### 非商業用途授權 -* 需要向用户告知动画文件来源并提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 -* 当您完成以上要求后,您可以免费使用动画文件 +* 需要向使用者告知動畫檔案的來源,並提供造訪[本頁面](https://github.com/LorisYounger/VPet)的連結 +* 當您完成上述要求後,可以免費使用動畫檔案 -### 商用用途授权(低于10万) +### 商業用途授權(低於10萬) -* 第一次使用时需弹窗并醒目的向用户告知动画文件来源并提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 -* 在相应页面(用户可以快捷访问)向用户告知动画文件来源并提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 -* 当您完成以上要求后,您可以免费使用动画文件 +* 在使用者第一次使用時,需跳出視窗,並醒目向使用者告知動畫檔案的來源,並提供造訪[本頁面](https://github.com/LorisYounger/VPet)的連結 +* 在對應的頁面上(使用者能快速造訪的),向使用者告知動畫檔案的來源,並提供造訪[本頁面](https://github.com/LorisYounger/VPet)的連結 +* 當您完成上述要求後,可以免費使用動畫檔案 -### 商用用途授权(高于10万或其他) +### 商業用途授權(高於10萬或其他) -* 请[邮件联系](mailto:zoujin.dev@exlb.org)我 +* 請[電子郵件聯絡](mailto:zoujin.dev@exlb.org)本軟體作者 -### 分发动画文件 +### 轉發動畫檔案 -* 需要告知以上所有授权信息 -* 需要提供访问 [该页面](https://github.com/LorisYounger/VPet) 的链接 -* 分发动画文件时禁止任何付费/收费行为 +* 需要告知上述所有授權資訊 +* 需要提供造訪[本頁面](https://github.com/LorisYounger/VPet)的連結 +* 轉發動畫檔案時,禁止任何付費或收費行為 -## 桌面端部署方法 +## 桌面應用程式部署方式 -1. 下载本项目, 通过VisualStudio打开 `VPet.sln` 文件 -2. 在生成栏中, 选择 位数为 `x64` 和生成项目为 `Vpet-Simulator.Windows` +1. 下載本專案,透過VisualStudio開啟`VPet.sln`檔案 +2. 在「建置」選項中,選擇位元數`x64`及建置專案`Vpet-Simulator.Windows` ![image-20230208004330895](README.assets/image-20230208004330895.png) -3. 点击启动, 如果一切正常则会报错 `缺少模组Core,无法启动桌宠` -4. 以管理员身份运行 `mklink.bat`, 这会让mod文件链接到生成位置 -5. 再次点击启动即可正常运行 +3. 點擊「開始」,若一切順利將會報錯`缺少Core模組,無法啟動桌寵` +4. 以管理員身分執行`mklink.bat`,這會讓模組檔案連結至產生的位置 +5. 再次點擊啟動即可正常執行 -## 软件结构 +## 軟體架構 * **VPet-Simulator.Windows: 适用于桌面端的虚拟桌宠模拟器** * *Function 功能性代码存放位置* From 18fdc168495c578b5a5591b876056f360463b2aa Mon Sep 17 00:00:00 2001 From: Dragon Taki Date: Thu, 14 Dec 2023 04:29:45 +0800 Subject: [PATCH 05/58] Update CONTRIBUTING_zht.md --- CONTRIBUTING_zht.md | 74 ++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/CONTRIBUTING_zht.md b/CONTRIBUTING_zht.md index 9fae609..7f0db07 100644 --- a/CONTRIBUTING_zht.md +++ b/CONTRIBUTING_zht.md @@ -47,43 +47,43 @@ ## 軟體架構 -* **VPet-Simulator.Windows: 适用于桌面端的虚拟桌宠模拟器** - * *Function 功能性代码存放位置* - * CoreMOD Mod管理类 - * MWController 窗体控制器 +* **VPet-Simulator.Windows: 適用於桌面端的虛擬桌寵模擬器** + * *Function 功能性程式碼儲存位置* + * CoreMOD 模組管理 + * MWController 視窗控制器 - * *WinDesign 窗口和UI设计 - * winBetterBuy 更好买窗口 - * winCGPTSetting ChatGPT 设置 - * winSetting 软件设置/MOD 窗口 - * winConsole 开发控制台 - * winGameSetting 游戏设置 - * winReport 反馈中心 + * *WinDesign 視窗及UI設計 + * winBetterBuy 更好買視窗 + * winCGPTSetting ChatGPT設定 + * winSetting 軟體設定、模組視窗 + * winConsole 開發控制台 + * winGameSetting 遊戲設定 + * winReport 意見回饋中心 - * MainWindows 主窗体,存放和展示Core - * PetHelper 快速切换小标 -* **VPet-Simulator.Tool: 方便制作MOD的工具(eg:图片帧生成)** -* **VPet-Simulator.Core: 软件核心 方便内置到任何WPF应用程序(例如:VUP-Simulator)** - * Handle 接口与控件 - * IController 窗体控制器 (调用相关功能和设置,例如移动到侧边等) + * MainWindows 主視窗、儲存及展示Core + * PetHelper 快速切換圖示 +* **VPet-Simulator.Tool: 方便製作模組的工具(例如:產生動態圖片)** +* **VPet-Simulator.Core: 軟體核心,方便內建至任何的WPF應用程式(例如:VUP-Simulator)** + * Handle 介面及控制項 + * IController 視窗控制(呼叫相關功能及設定,例如:移動到側邊等) * Function 通用功能 - * GameCore 游戏核心,包含各种数据等内容 - * GameSave 游戏存档 - * IFood 食物/物品接口 - * PetLoader 宠物图形加载器 - * Graph 图形渲染 - * IGraph 动画基本接口 - * GraphCore 动画显示核心 - * GraphHelper 动画帮助类 - * GraphInfo 动画信息 - * FoodAnimation 食物动画 支持显示前中后3层夹心动画 不一定只用于食物,只是叫这个名字 - * PNGAnimation 桌宠动态动画组件 - * Picture 桌宠静态动画组件 - * Display 显示 - * basestyle/Theme 基本风格主题 - * Main.xaml 核心显示部件 - * MainDisplay 核心显示方法 - * MainLogic 核心显示逻辑 - * ToolBar 点击人物时候的工具栏 - * MessageBar 人物说话时候的说话栏 - * WorkTimer 工作时钟 + * GameCore 遊戲核心,包含各種資料數據等內容 + * GameSave 遊戲存檔 + * IFood 食物及物品介面 + * PetLoader 寵物圖片載入器 + * Graph 圖形渲染 + * IGraph 動畫基本介面 + * GraphCore 動畫顯示核心 + * GraphHelper 動畫幫助 + * GraphInfo 動畫資訊 + * FoodAnimation 食物動畫,支援顯示前中後三層夾心動畫,不一定只用於食物,只是叫這個名字 + * PNGAnimation 桌寵動態動畫元件 + * Picture 桌寵靜態動畫元件 + * Display 顯示 + * basestyle/Theme 基礎風格主題 + * Main.xaml 核心顯示元件 + * MainDisplay 核心顯示方法 + * MainLogic 核心顯示邏輯 + * ToolBar 點擊人物時的工具欄 + * MessageBar 人物說話時的對話框 + * WorkTimer 運作計時器 From 18c3bed636c9d30bc857f6661dca839c19bc0193 Mon Sep 17 00:00:00 2001 From: Dragon Taki Date: Thu, 14 Dec 2023 04:31:37 +0800 Subject: [PATCH 06/58] Add zht CONTRIBUTING by DragonTaki --- CONTRIBUTING_en.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING_en.md b/CONTRIBUTING_en.md index 820a9b4..996ee24 100644 --- a/CONTRIBUTING_en.md +++ b/CONTRIBUTING_en.md @@ -1,6 +1,6 @@ # Contributing -[简体中文](./CONTRIBUTING.md) | English +[简体中文](./CONTRIBUTING.md) | [繁體中文](./CONTRIBUTING_zht.md) | English Welcome to participate in development! To ensure code maintainability and playability, if you wish to develop new features or gameplay, please first contact me (by sending a [mail](mailto:zoujin.dev@exlb.org) or opening an [Issue](https://github.com/LorisYounger/VPet/issues/new)) with your idea. This is to make sure your contribution fits the game, and will not get outright rejected for being unfitting (causing your effort to be wasted). You don't need to contact me regarding fixing errors or bugs - simply send a PR in that case. @@ -88,4 +88,4 @@ You **must** inform users of the source of our animation files, and provide a li * All of the above authorization information **must** be disclosed. * You **must** provide a link to [this page](https://github.com/LorisYounger/VPet). -* **No** profit should be made with our files. \ No newline at end of file +* **No** profit should be made with our files. From 7a03f563041ccf3395c6f357b28217acce318a6c Mon Sep 17 00:00:00 2001 From: Dragon Taki Date: Thu, 14 Dec 2023 04:31:51 +0800 Subject: [PATCH 07/58] Add zht CONTRIBUTING by DragonTaki --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b31d69a..e8dcbef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -简体中文 | [English](./CONTRIBUTING_en.md) +简体中文 | [繁體中文](./CONTRIBUTING_zht.md) | [English](./CONTRIBUTING_en.md) ## 参与开发 From 4c0d985854e0efe5846473e8a986d96af44171ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=AB=E5=9F=8Evia?= <969954321@qq.com> Date: Mon, 18 Dec 2023 17:49:06 +0800 Subject: [PATCH 08/58] =?UTF-8?q?=E5=88=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VPet-Simulator.Core/Display/basestyle.xaml | 2 ++ .../WinDesign/winBetterBuy.xaml | 15 +++++++++++++-- .../WinDesign/winBetterBuy.xaml.cs | 10 ++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/VPet-Simulator.Core/Display/basestyle.xaml b/VPet-Simulator.Core/Display/basestyle.xaml index a41cbee..fcad8b7 100644 --- a/VPet-Simulator.Core/Display/basestyle.xaml +++ b/VPet-Simulator.Core/Display/basestyle.xaml @@ -185,6 +185,8 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/VPet.Solution/Templates.xaml b/VPet.Solution/Templates.xaml new file mode 100644 index 0000000..ac14da7 --- /dev/null +++ b/VPet.Solution/Templates.xaml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VPet.Solution/Usings.cs b/VPet.Solution/Usings.cs new file mode 100644 index 0000000..953c41b --- /dev/null +++ b/VPet.Solution/Usings.cs @@ -0,0 +1,6 @@ +global using global::HKW.HKWUtils.Observable; +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Threading.Tasks; diff --git a/VPet.Solution/Utils/Expansions.cs b/VPet.Solution/Utils/Expansions.cs new file mode 100644 index 0000000..60b6345 --- /dev/null +++ b/VPet.Solution/Utils/Expansions.cs @@ -0,0 +1,312 @@ +using System.Collections; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.Globalization; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace HKW.HKWUtils; + +/// +/// 拓展 +/// +public static class Extensions +{ + /// + /// + /// + /// + /// + /// + /// + public static bool Contains(this string source, string value, StringComparison comparisonType) + { + return source.IndexOf(value, comparisonType) >= 0; + } + + //public static string GetSourceFile(this BitmapImage image) + //{ + // return ((FileStream)image.StreamSource).Name; + //} + + /// + /// 关闭流 + /// + /// 图像资源 + public static void CloseStream(this ImageSource source) + { + if (source is not BitmapImage image) + return; + image.StreamSource?.Close(); + } + + /// + /// 图像复制 + /// + /// 图像 + /// 复制的图像 + public static BitmapImage Copy(this BitmapImage image) + { + if (image is null) + return null; + BitmapImage newImage = new(); + newImage.BeginInit(); + newImage.DecodePixelWidth = image.DecodePixelWidth; + newImage.DecodePixelHeight = image.DecodePixelHeight; + try + { + using var bitmap = new Bitmap(image.StreamSource); + var ms = new MemoryStream(); + bitmap.Save(ms, ImageFormat.Png); + image.StreamSource.CopyTo(ms); + newImage.StreamSource = ms; + } + finally + { + newImage.EndInit(); + } + return newImage; + } + + /// + /// 保存至Png图片 + /// + /// 图片资源 + /// 路径 + //public static void SaveToPng(this BitmapImage image, string path) + //{ + // if (image is null) + // return; + // if (path.EndsWith(".png") is false) + // path += ".png"; + // var encoder = new PngBitmapEncoder(); + // var stream = image.StreamSource; + // // 保存位置 + // var position = stream.Position; + // // 必须要重置位置, 否则EndInit将出错 + // stream.Seek(0, SeekOrigin.Begin); + // encoder.Frames.Add(BitmapFrame.Create(image.StreamSource)); + // // 恢复位置 + // stream.Seek(position, SeekOrigin.Begin); + // using var fs = new FileStream(path, FileMode.Create); + // encoder.Save(fs); + //} + public static void SaveToPng(this BitmapImage image, string path) + { + if (image is null) + return; + if (path.EndsWith(".png") is false) + path += ".png"; + var stream = image.StreamSource; + // 保存位置 + var position = stream.Position; + // 必须要重置位置, 否则EndInit将出错 + stream.Seek(0, SeekOrigin.Begin); + using var fs = new FileStream(path, FileMode.Create); + stream.CopyTo(fs); + // 恢复位置 + stream.Seek(position, SeekOrigin.Begin); + } + + /// + /// 尝试添加 + /// + /// 键类型 + /// + /// + /// 键 + /// 值 + /// 成功为 失败为 + public static bool TryAdd( + this IDictionary dictionary, + TKey key, + TValue value + ) + { + if (dictionary.ContainsKey(key)) + return false; + dictionary.Add(key, value); + return true; + } + + /// + /// 流内容对比 + /// + /// 原始流 + /// 目标流 + /// 缓冲区大小 (越大速度越快(流内容越大效果越明显), 但会提高内存占用 (bufferSize = bufferLength * sizeof(long) * 2)) + /// 内容相同为 否则为 + public static bool ContentsEqual(this Stream source, Stream target, int bufferLength = 8) + { + int bufferSize = bufferLength * sizeof(long); + var sourceBuffer = new byte[bufferSize]; + var targetBuffer = new byte[bufferSize]; + while (true) + { + int sourceCount = ReadFullBuffer(source, sourceBuffer); + int targetCount = ReadFullBuffer(target, targetBuffer); + if (sourceCount != targetCount) + return false; + if (sourceCount == 0) + return true; + + for (int i = 0; i < sourceCount; i += sizeof(long)) + if (BitConverter.ToInt64(sourceBuffer, i) != BitConverter.ToInt64(targetBuffer, i)) + return false; + } + static int ReadFullBuffer(Stream stream, byte[] buffer) + { + int bytesRead = 0; + while (bytesRead < buffer.Length) + { + int read = stream.Read(buffer, bytesRead, buffer.Length - bytesRead); + if (read == 0) + return bytesRead; + bytesRead += read; + } + return bytesRead; + } + } + + public static T? FindVisualChild(this DependencyObject obj) + where T : DependencyObject + { + if (obj is null) + return null; + var count = VisualTreeHelper.GetChildrenCount(obj); + for (int i = 0; i < count; i++) + { + var child = VisualTreeHelper.GetChild(obj, i); + if (child is T t) + return t; + if (FindVisualChild(child) is T childItem) + return childItem; + } + return null; + } + + public static T FindParent(this DependencyObject obj) + where T : class + { + while (obj != null) + { + if (obj is T) + return obj as T; + obj = VisualTreeHelper.GetParent(obj); + } + return null; + } + + public static string GetFullInfo(this CultureInfo cultureInfo) + { + return $"{cultureInfo.DisplayName} [{cultureInfo.Name}]"; + } + + /// + /// 尝试使用索引获取值 + /// + /// 值类型 + /// 列表 + /// 索引 + /// 值 + /// 成功为 失败为 + public static bool TryGetValue(this IList list, int index, out T value) + { + value = default; + if (index < 0 || index >= list.Count) + return false; + value = list[index]; + return true; + } + + /// + /// 尝试使用索引获取值 + /// + /// 值类型 + /// 列表 + /// 索引 + /// 值 + /// 成功为 失败为 + public static bool TryGetValue(this IList list, int index, out object value) + { + value = default; + if (index < 0 || index >= list.Count) + return false; + value = list[index]; + return true; + } + + /// + /// 获取目标 + /// + /// 类型 + /// 弱引用 + /// 获取成功返回目标值, 获取失败则返回 + public static T? GetTarget(this WeakReference weakReference) + where T : class + { + return weakReference.TryGetTarget(out var t) ? t : null; + } + + /// + /// 枚举出带有索引值的枚举值 + /// + /// 值类型 + /// 集合 + /// 带有索引的枚举值 + public static IEnumerable> Enumerate(this IEnumerable collection) + { + var index = 0; + foreach (var item in collection) + yield return new(index++, item); + } + + public static void SetDataContext(this Window window) + where T : new() + { + window.DataContext = new T(); + window.Closed += (s, e) => + { + try + { + window.DataContext = null; + } + catch { } + }; + } +} + +/// +/// 项信息 +/// +/// +[DebuggerDisplay("[{Index}, {Value}]")] +public readonly struct ItemInfo +{ + /// + /// 索引值 + /// + public int Index { get; } + + /// + /// 值 + /// + public T Value { get; } + + /// + /// 值 + /// 索引值 + public ItemInfo(int index, T value) + { + Index = index; + Value = value; + } + + /// + public override string ToString() + { + return $"[{Index}, {Value}]"; + } +} diff --git a/VPet.Solution/Utils/HashCode.cs b/VPet.Solution/Utils/HashCode.cs new file mode 100644 index 0000000..b88ff89 --- /dev/null +++ b/VPet.Solution/Utils/HashCode.cs @@ -0,0 +1,66 @@ +namespace HKW.HKWUtils; + +/// +/// 哈希值 +/// +public class HashCode +{ + /// + /// 默认种子 + /// + public const int DefaultSeed = 114514; + + /// + /// 默认系数 + /// + public const int DefaultFactor = 1919810; + + /// + /// 组合哈希值 + /// + /// 值 + /// 组合的哈希值 + public static int Combine(params object[] values) + { + return CustomHash(DefaultSeed, DefaultFactor, values.Select(v => v.GetHashCode())); + } + + /// + /// 组合哈希值 + /// + /// 种子 + /// 系数 + /// 值 + /// 组合的哈希值 + public static int Combine(int seed, int factor, params object[] values) + { + return CustomHash(seed, factor, values.Select(v => v.GetHashCode())); + } + + /// + /// 自定义组合哈希 + /// + /// 种子 + /// 系数 + /// 哈希集合 + /// 组合的哈希 + public static int CustomHash(int seed, int factor, IEnumerable collection) + { + int hash = seed; + foreach (int i in collection) + hash = unchecked((hash * factor) + i); + return hash; + } + + /// + /// 自定义组合哈希 + /// + /// 种子 + /// 系数 + /// 哈希集合 + /// 组合的哈希 + public static int CustomHash(int seed, int factor, params int[] values) + { + return CustomHash(seed, factor, collection: values); + } +} diff --git a/VPet.Solution/Utils/ObservableEnumFlags.cs b/VPet.Solution/Utils/ObservableEnumFlags.cs new file mode 100644 index 0000000..3e863ce --- /dev/null +++ b/VPet.Solution/Utils/ObservableEnumFlags.cs @@ -0,0 +1,72 @@ +namespace HKW.HKWUtils; + +/// +/// 可观察的枚举标签模型 +/// +/// 枚举类型 +public class ObservableEnumFlags : ObservableClass> + where T : Enum +{ + private T _EnumValue; + public T EnumValue + { + get => _EnumValue; + set => SetProperty(ref _EnumValue, value); + } + + /// + /// 添加枚举命令 + /// + public ObservableCommand AddCommand { get; } = new(); + + /// + /// 删除枚举命令 + /// + public ObservableCommand RemoveCommand { get; } = new(); + + /// + /// 枚举类型 + /// + public Type EnumType = typeof(T); + + /// + /// 枚举基类 + /// + public Type UnderlyingType { get; } = Enum.GetUnderlyingType(typeof(T)); + + public ObservableEnumFlags() + { + if (Attribute.IsDefined(EnumType, typeof(FlagsAttribute)) is false) + throw new Exception($"此枚举类型未使用特性 [{nameof(FlagsAttribute)}]"); + AddCommand.ExecuteCommand += AddCommand_Execute; + RemoveCommand.ExecuteCommand += RemoveCommand_Execute; + } + + public ObservableEnumFlags(T value) + : this() + { + EnumValue = value; + } + + private void AddCommand_Execute(T v) + { + if (UnderlyingType == typeof(int)) + { + EnumValue = (T) + Enum.Parse(EnumType, (Convert.ToInt32(EnumValue) | Convert.ToInt32(v)).ToString()); + } + else + throw new NotImplementedException($"Value type: {UnderlyingType}"); + } + + private void RemoveCommand_Execute(T v) + { + if (UnderlyingType == typeof(int)) + { + EnumValue = (T) + Enum.Parse(EnumType, (Convert.ToInt32(EnumValue) & ~Convert.ToInt32(v)).ToString()); + } + else + throw new NotImplementedException($"Value type: {UnderlyingType}"); + } +} diff --git a/VPet.Solution/Utils/ObservablePoint.cs b/VPet.Solution/Utils/ObservablePoint.cs new file mode 100644 index 0000000..eff89d6 --- /dev/null +++ b/VPet.Solution/Utils/ObservablePoint.cs @@ -0,0 +1,77 @@ +namespace HKW.HKWUtils; + +/// +/// 可观察地点 +/// +/// 类型 +public class ObservablePoint + : ObservableClass>, + IEquatable> +{ + private T _x; + public T X + { + get => _x; + set => SetProperty(ref _x, value); + } + + private T _y; + public T Y + { + get => _y; + set => SetProperty(ref _y, value); + } + + public ObservablePoint() { } + + public ObservablePoint(T x, T y) + { + X = x; + Y = y; + } + + /// + /// 复制一个新的对象 + /// + /// 新对象 + public ObservablePoint Copy() + { + return new(X, Y); + } + + #region Other + + /// + public override int GetHashCode() + { + return HashCode.Combine(X, Y); + } + + /// + public override bool Equals(object? obj) + { + return obj is ObservablePoint temp + && EqualityComparer.Default.Equals(X, temp.X) + && EqualityComparer.Default.Equals(Y, temp.Y); + } + + /// + public bool Equals(ObservablePoint? other) + { + return Equals(obj: other); + } + + /// + public static bool operator ==(ObservablePoint a, ObservablePoint b) + { + return Equals(a, b); + } + + /// + public static bool operator !=(ObservablePoint a, ObservablePoint b) + { + return Equals(a, b) is not true; + } + + #endregion +} diff --git a/VPet.Solution/Utils/ObservableRange.cs b/VPet.Solution/Utils/ObservableRange.cs new file mode 100644 index 0000000..76a1d6f --- /dev/null +++ b/VPet.Solution/Utils/ObservableRange.cs @@ -0,0 +1,77 @@ +namespace HKW.HKWUtils; + +/// +/// 可观察的范围 +/// +/// 类型 +public class ObservableRange + : ObservableClass>, + IEquatable> +{ + private T _min; + public T Min + { + get => _min; + set => SetProperty(ref _min, value); + } + + private T _max; + public T Max + { + get => _max; + set => SetProperty(ref _max, value); + } + + public ObservableRange() { } + + public ObservableRange(T min, T max) + { + _min = min; + _max = max; + } + + /// + /// 复制一个新的对象 + /// + /// 新对象 + public ObservableRange Copy() + { + return new(Min, Max); + } + + #region Other + + /// + public override int GetHashCode() + { + return HashCode.Combine(Min, Max); + } + + /// + public override bool Equals(object? obj) + { + return obj is ObservableRange temp + && EqualityComparer.Default.Equals(Min, temp.Min) + && EqualityComparer.Default.Equals(Max, temp.Max); + } + + /// + public bool Equals(ObservableRange? other) + { + return Equals(obj: other); + } + + /// + public static bool operator ==(ObservableRange a, ObservableRange b) + { + return Equals(a, b); + } + + /// + public static bool operator !=(ObservableRange a, ObservableRange b) + { + return Equals(a, b) is not true; + } + + #endregion +} diff --git a/VPet.Solution/Utils/ObservableRect.cs b/VPet.Solution/Utils/ObservableRect.cs new file mode 100644 index 0000000..49924a7 --- /dev/null +++ b/VPet.Solution/Utils/ObservableRect.cs @@ -0,0 +1,89 @@ +namespace HKW.HKWUtils; + +public class ObservableRect : ObservableClass>, IEquatable> +{ + private T _x; + public T X + { + get => _x; + set => SetProperty(ref _x, value); + } + + private T _y; + public T Y + { + get => _y; + set => SetProperty(ref _y, value); + } + + private T _width; + public T Width + { + get => _width; + set => SetProperty(ref _width, value); + } + + private T _heigth; + public T Height + { + get => _heigth; + set => SetProperty(ref _heigth, value); + } + + public ObservableRect() { } + + public ObservableRect(T x, T y, T width, T hetght) + { + X = x; + Y = y; + Width = width; + Height = hetght; + } + + /// + /// 复制一个新的对象 + /// + /// 新对象 + public ObservableRect Copy() + { + return new(X, Y, Width, Height); + } + + #region Other + + /// + public override int GetHashCode() + { + return HashCode.Combine(X, Y, Width, Height); + } + + /// + public override bool Equals(object? obj) + { + return obj is ObservableRect temp + && EqualityComparer.Default.Equals(X, temp.X) + && EqualityComparer.Default.Equals(Y, temp.Y) + && EqualityComparer.Default.Equals(Width, temp.Width) + && EqualityComparer.Default.Equals(Height, temp.Height); + } + + /// + public bool Equals(ObservableRect? other) + { + return Equals(obj: other); + } + + /// + public static bool operator ==(ObservableRect a, ObservableRect b) + { + return Equals(a, b); + } + + /// + public static bool operator !=(ObservableRect a, ObservableRect b) + { + return Equals(a, b) is not true; + } + + #endregion +} diff --git a/VPet.Solution/Utils/Utils.cs b/VPet.Solution/Utils/Utils.cs new file mode 100644 index 0000000..c628c1b --- /dev/null +++ b/VPet.Solution/Utils/Utils.cs @@ -0,0 +1,79 @@ +using System.Windows.Media.Imaging; + +namespace HKW.HKWUtils; + +/// +/// 工具 +/// +public static class Utils +{ + /// + /// 解码像素宽度 + /// + public const int DecodePixelWidth = 250; + + /// + /// 解码像素高度 + /// + public const int DecodePixelHeight = 250; + public static char[] Separator { get; } = new char[] { '_' }; + + //public static BitmapImage LoadImageToStream(string imagePath) + //{ + // BitmapImage bitmapImage = new(); + // bitmapImage.BeginInit(); + // bitmapImage.DecodePixelWidth = DecodePixelWidth; + // try + // { + // bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream; + // } + // finally + // { + // bitmapImage.EndInit(); + // } + // return bitmapImage; + //} + + /// + /// 载入图片至内存流 + /// + /// 图片路径 + /// + public static BitmapImage LoadImageToMemoryStream(string imagePath) + { + BitmapImage bitmapImage = new(); + bitmapImage.BeginInit(); + try + { + var bytes = File.ReadAllBytes(imagePath); + bitmapImage.StreamSource = new MemoryStream(bytes); + bitmapImage.DecodePixelWidth = DecodePixelWidth; + } + finally + { + bitmapImage.EndInit(); + } + return bitmapImage; + } + + /// + /// 载入图片至内存流 + /// + /// 图片流 + /// + public static BitmapImage LoadImageToMemoryStream(Stream imageStream) + { + BitmapImage bitmapImage = new(); + bitmapImage.BeginInit(); + try + { + bitmapImage.StreamSource = imageStream; + bitmapImage.DecodePixelWidth = DecodePixelWidth; + } + finally + { + bitmapImage.EndInit(); + } + return bitmapImage; + } +} diff --git a/VPet.Solution/VPet.Solution.csproj b/VPet.Solution/VPet.Solution.csproj index daa478f..dceafe2 100644 --- a/VPet.Solution/VPet.Solution.csproj +++ b/VPet.Solution/VPet.Solution.csproj @@ -14,6 +14,8 @@ 4 true true + enable + latest AnyCPU @@ -39,7 +41,8 @@ ..\packages\LinePutScript.1.9.2\lib\net462\LinePutScript.dll - ..\packages\LinePutScript.Localization.WPF.1.0.6\lib\net462\LinePutScript.Localization.WPF.dll + + ..\packages\LinePutScript.Localization.WPF.1.0.6\lib\net462\LinePutScript.Localization.WPF.dll ..\packages\Panuon.WPF.1.0.2\lib\net462\Panuon.WPF.dll @@ -49,6 +52,7 @@ + @@ -67,7 +71,7 @@ MSBuild:Compile Designer - + MSBuild:Compile Designer @@ -75,9 +79,50 @@ App.xaml Code - + + MainWindow.xaml - Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MSBuild:Compile + Designer + true + + + NativeStyles.xaml @@ -117,5 +162,8 @@ VPet-Simulator.Windows.Interface + + + \ No newline at end of file diff --git a/VPet.Solution/ViewModels/MainWindowVM.cs b/VPet.Solution/ViewModels/MainWindowVM.cs new file mode 100644 index 0000000..3f2ed0e --- /dev/null +++ b/VPet.Solution/ViewModels/MainWindowVM.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VPet_Simulator.Core; +using VPet_Simulator.Windows.Interface; + +namespace VPet.Solution.ViewModels; + +public class MainWindowVM : ObservableClass +{ + public MainWindowVM() { } + + public static void LoadSettings(string path) + { + foreach (var file in Directory.EnumerateFiles(path)) + { + var setting = new Setting(path); + } + } +} diff --git a/VPet.Solution/Views/MainWindow.xaml b/VPet.Solution/Views/MainWindow.xaml new file mode 100644 index 0000000..199086c --- /dev/null +++ b/VPet.Solution/Views/MainWindow.xaml @@ -0,0 +1,1849 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +