");
+ int main_version, engine_version, sa_version;
+ if (int.TryParse(arr[0], out main_version) && int.TryParse(arr[1], out engine_version))
+ {
+
+ }
+ }
+ // todo open faile update dialog
+ }
+
+ public static void DownLoad(string Url, string FileName)
+ {
+ bool Value = false;
+ WebResponse response = null;
+ Stream stream = null;
+
+ try
+ {
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
+
+ response = request.GetResponse();
+ stream = response.GetResponseStream();
+
+ if (!response.ContentType.ToLower().StartsWith("text/"))
+ {
+ Value = SaveBinaryFile(response, FileName);
+
+ }
+
+ }
+ catch (Exception err)
+ {
+ string aa = err.ToString();
+ }
+
+ }
+
+ private static bool SaveBinaryFile(WebResponse response, string FileName)
+ {
+ bool Value = true;
+ byte[] buffer = new byte[1024];
+
+ try
+ {
+ if (File.Exists(FileName))
+ File.Delete(FileName);
+ Stream outStream = File.Create(FileName);
+ Stream inStream = response.GetResponseStream();
+
+ int l;
+ do
+ {
+ l = inStream.Read(buffer, 0, buffer.Length);
+ if (l > 0)
+ outStream.Write(buffer, 0, l);
+ }
+ while (l > 0);
+
+ outStream.Close();
+ inStream.Close();
+ }
+ catch
+ {
+ Value = false;
+ }
+ return Value;
+ }
+
+ }
+}
diff --git a/Manager/VersionManager.cs b/Manager/VersionManager.cs
new file mode 100644
index 0000000..cfe7e64
--- /dev/null
+++ b/Manager/VersionManager.cs
@@ -0,0 +1,8 @@
+namespace Zerolauncher.Manager
+{
+ class VersionManager
+ {
+ public static int GetMainVer() { return 10001; }
+
+ }
+}
diff --git a/Manager/WebApiManager.cs b/Manager/WebApiManager.cs
new file mode 100644
index 0000000..c4b9703
--- /dev/null
+++ b/Manager/WebApiManager.cs
@@ -0,0 +1,159 @@
+using System.Diagnostics;
+using System.IO;
+using System.Net;
+using System.Text;
+namespace Zerolauncher.Manager
+{
+ internal class WebApiManager
+ {
+ static HttpListener listener = new HttpListener();
+ static CancellationTokenSource cts = new CancellationTokenSource();
+ public static async Task StartListener()
+ {
+ listener.Prefixes.Add("http://127.0.0.1:7233/");
+ listener.Start();
+ Trace.WriteLine("Listening...");
+
+ while (!cts.Token.IsCancellationRequested)
+ {
+ HttpListenerContext context = await listener.GetContextAsync();
+ HttpListenerRequest request = context.Request;
+ HttpListenerResponse response = context.Response;
+ var raw = request.RawUrl;
+ ResponesBody? rb = null;
+ if (raw != null && raw.Contains("?"))
+ {
+ var lines = raw.Split("?");
+ var args = request.QueryString;
+ var nick = args["name"];
+ if (nick != null)
+ {
+ var acc = TeamManager.Nick2Acc(nick);
+ if (acc != null)
+ {
+ switch (lines[0])
+ {
+ case "/CloseGame":
+ {
+ if (EngineManager.ExitGame(acc))
+ {
+ rb = new ResponesBody(1, 0, $"Account [{nick}] successful to close.");
+ }
+ else
+ {
+ rb = new ResponesBody($"Account [{nick}] is unluacher.");
+ break;
+ }
+ }
+ break;
+ case "/ToNormalSize":
+ {
+ switch (EngineManager.TurnGameSizeNormal(acc))
+ {
+ case 2:
+ rb = new ResponesBody(1, 0, $"Account [{nick}] now is normal size.");
+ break;
+ case 1:
+ rb = new ResponesBody(0, 0, $"Account [{nick}] is loading, please wait.");
+ break;
+ case 0:
+ rb = new ResponesBody($"Account [{nick}] is unluacher.");
+ break;
+ }
+ }
+ break;
+ case "/ToMiniSize":
+ {
+ switch (EngineManager.TurnGameSizeMini(acc))
+ {
+ case 2:
+ rb = new ResponesBody(1, 0, $"Account [{nick}] now is mini size.");
+ break;
+ case 1:
+ rb = new ResponesBody(0, 0, $"Account [{nick}] is loading, please wait.");
+ break;
+ case 0:
+ rb = new ResponesBody($"Account [{nick}] is unluacher.");
+ break;
+ }
+ }
+ break;
+ case "/LoginGame":
+ {
+ if (EngineManager.CreateGame(acc))
+ {
+ rb = new ResponesBody(0, 0, $"Account [{nick}] successful to start.");
+ }
+ else
+ {
+ int hwnd = EngineManager.CheckGameState(acc);
+ if (hwnd <= 0)
+ {
+ rb = new ResponesBody(0, 0, $"Account [{nick}] is loading, please wait.");
+ }
+ else
+ {
+ rb = new ResponesBody(1, hwnd, $"Account [{nick}] now is running.");
+ }
+ }
+ }
+ break;
+ default:
+ rb = new ResponesBody($"commad [{lines[0]}] undefind.");
+ break;
+ }
+ }
+ else
+ {
+ rb = new ResponesBody($"Account [{nick}] undefind.");
+ }
+ }
+ else
+ {
+ rb = new ResponesBody("args is missing.");
+ }
+
+ }
+ if (rb == null)
+ {
+ rb = new ResponesBody();
+ }
+ byte[] buffer = Encoding.UTF8.GetBytes(rb.Encode());
+
+ response.ContentLength64 = buffer.Length;
+ Stream output = response.OutputStream;
+ await output.WriteAsync(buffer, 0, buffer.Length);
+ output.Close();
+ }
+ listener.Stop();
+ }
+
+ public static void StopListener() { cts.Cancel(); }
+ }
+
+ class ResponesBody
+ {
+ public int status;
+ public int hwnd;
+ public string message;
+
+ public ResponesBody(string message)
+ {
+ this.status = -1;
+ this.hwnd = 0;
+ this.message = message;
+ }
+
+ public ResponesBody(int status=-1, int hwnd=0, string message= "Hello, World!")
+ {
+ this.status = status;
+ this.hwnd = hwnd;
+ this.message = message;
+ }
+
+ public string Encode()
+ {
+ return $"{{\"state\": {status}, \"hwnd\": {hwnd}, \"message\": \"{message}\"}}";
+ }
+ }
+}
diff --git a/ServicesStaticInfo.cs b/ServicesStaticInfo.cs
new file mode 100644
index 0000000..e02a536
--- /dev/null
+++ b/ServicesStaticInfo.cs
@@ -0,0 +1,9 @@
+namespace Zerolauncher
+{
+ class ServicesStaticInfo
+ {
+ public static string[] ServicesName = ["4399大区", "7k7k大区", "第七大道"];
+ public static string[] ServicesShortName = ["43", "7k", "7d"];
+
+ }
+}
diff --git a/StaticHandleProtol.cs b/StaticHandleProtol.cs
new file mode 100644
index 0000000..bd7f213
--- /dev/null
+++ b/StaticHandleProtol.cs
@@ -0,0 +1,27 @@
+namespace Zerolauncher
+{
+ class StaticHandleS
+ {
+ public const string ShowWindow = "a0";
+ public const string HintText = "b0";
+ public const string MiniSize = "c0";
+ public const string NormalSize = "d0";
+ public const string UseBrowser = "e0";
+ public const string GameSa = "f0";
+ public const string CloseGame = "g0";
+ }
+
+ class StaticHandleC
+ {
+ public const string StartDone = "0a";
+ public const string BrowserDone = "0b";
+ public const string StartGame = "0c";
+ public const string GameDone = "0d";
+ }
+
+ class StaticHandleA
+ {
+ public const string GameMode = "0a";
+ public const string UpdateMode = "0b";
+ }
+}
diff --git a/Zerolauncher.csproj b/Zerolauncher.csproj
new file mode 100644
index 0000000..ef6538f
--- /dev/null
+++ b/Zerolauncher.csproj
@@ -0,0 +1,57 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ enable
+ true
+ res\title.ico
+ true
+ true
+
+
+
+ full
+
+
+
+ full
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Zerolauncher.sln b/Zerolauncher.sln
new file mode 100644
index 0000000..60ff396
--- /dev/null
+++ b/Zerolauncher.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34408.163
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zerolauncher", "Zerolauncher.csproj", "{C6930B95-44F3-4B41-90A6-20BA34560BF7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C6930B95-44F3-4B41-90A6-20BA34560BF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6930B95-44F3-4B41-90A6-20BA34560BF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6930B95-44F3-4B41-90A6-20BA34560BF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6930B95-44F3-4B41-90A6-20BA34560BF7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {89B100BA-83CE-4B02-8537-22B5A520DFCE}
+ EndGlobalSection
+EndGlobal
diff --git a/controls/AirButton.cs b/controls/AirButton.cs
new file mode 100644
index 0000000..2e5f917
--- /dev/null
+++ b/controls/AirButton.cs
@@ -0,0 +1,68 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace Zerolauncher.controls
+{
+ ///
+ /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
+ ///
+ /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
+ /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
+ /// 元素中:
+ ///
+ /// xmlns:MyNamespace="clr-namespace:Zerolauncher.controls"
+ ///
+ ///
+ /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
+ /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
+ /// 元素中:
+ ///
+ /// xmlns:MyNamespace="clr-namespace:Zerolauncher.controls;assembly=Zerolauncher.controls"
+ ///
+ /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
+ /// 并重新生成以避免编译错误:
+ ///
+ /// 在解决方案资源管理器中右击目标项目,然后依次单击
+ /// “添加引用”->“项目”->[浏览查找并选择此项目]
+ ///
+ ///
+ /// 步骤 2)
+ /// 继续操作并在 XAML 文件中使用控件。
+ ///
+ ///
+ ///
+ ///
+
+ public class AirButton : Button
+ {
+ static AirButton()
+ {
+ //DefaultStyleKeyProperty.OverrideMetadata(typeof(AirButton), new FrameworkPropertyMetadata(typeof(AirButton)));
+ }
+
+ protected override void OnMouseEnter(MouseEventArgs e)
+ {
+ // 不执行任何操作
+ }
+
+ protected override void OnMouseLeave(MouseEventArgs e)
+ {
+ // 不执行任何操作
+ }
+
+ protected override void OnMouseDown(MouseButtonEventArgs e)
+ {
+ base.OnMouseDown(e);
+ this.RenderTransform = new TranslateTransform(3, 3);
+ }
+
+ protected override void OnMouseUp(MouseButtonEventArgs e)
+ {
+ base.OnMouseUp(e);
+ this.RenderTransform = new TranslateTransform(0, 0);
+ }
+ }
+
+}
diff --git a/controls/AirButton.xaml b/controls/AirButton.xaml
new file mode 100644
index 0000000..793541d
--- /dev/null
+++ b/controls/AirButton.xaml
@@ -0,0 +1,20 @@
+
+
+
+
\ No newline at end of file
diff --git a/controls/AirTextBox.xaml b/controls/AirTextBox.xaml
new file mode 100644
index 0000000..42f1cd1
--- /dev/null
+++ b/controls/AirTextBox.xaml
@@ -0,0 +1,3 @@
+
+
\ No newline at end of file
diff --git a/controls/MemberControl.xaml b/controls/MemberControl.xaml
new file mode 100644
index 0000000..31a05be
--- /dev/null
+++ b/controls/MemberControl.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/controls/MemberControl.xaml.cs b/controls/MemberControl.xaml.cs
new file mode 100644
index 0000000..53d7141
--- /dev/null
+++ b/controls/MemberControl.xaml.cs
@@ -0,0 +1,114 @@
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using Zerolauncher.dialog;
+using Zerolauncher.Manager;
+
+namespace Zerolauncher.controls
+{
+ ///
+ /// MemberControl.xaml 的交互逻辑
+ ///
+ public partial class MemberControl : UserControl
+ {
+ public int memberId { get; set; }
+
+ private bool isMouseDown;
+
+
+ public MemberControl()
+ {
+ InitializeComponent();
+ isMouseDown = false;
+ // 鼠标按下事件
+ MouseDown += (s, e) =>
+ {
+ RenderTransform = new TranslateTransform(3, 3);
+ isMouseDown = true;
+ };
+
+ // 鼠标松开事件
+ MouseUp += (s, e) =>
+ {
+ if (!isMouseDown) return;
+ RenderTransform = new TranslateTransform(0, 0);
+ if (e.ChangedButton == MouseButton.Right) return;
+ if (!EngineManager.CreateGame(memberId)) MessageBox.Show("账号已启动!请勿重复启动", "提示");
+
+ };
+
+ // 鼠标离开事件
+ MouseLeave += (s, e) =>
+ {
+ if (Mouse.LeftButton == MouseButtonState.Pressed)
+ {
+ RenderTransform = new TranslateTransform(0, 0);
+ isMouseDown = false;
+ }
+ };
+
+ // 鼠标捕获丢失事件
+ LostMouseCapture += (s, e) =>
+ {
+ RenderTransform = new TranslateTransform(0, 0);
+ isMouseDown = false;
+ };
+ ContextMenu = CreateContextMenu();
+ }
+
+ private ContextMenu CreateContextMenu()
+ {
+ ContextMenu contextMenu = new ContextMenu();
+
+ MenuItem editItem = new MenuItem { Header = "编辑" };
+ editItem.Click += editItem_Click;
+ contextMenu.Items.Add(editItem);
+
+ MenuItem delItem = new MenuItem { Header = "删除" };
+ delItem.Click += delItem_Click;
+ contextMenu.Items.Add(delItem);
+
+ MenuItem changeTeamItem = new MenuItem { Header = "移动到" };
+ contextMenu.Items.Add(changeTeamItem);
+ changeTeamItem.MouseEnter += (sender, args) =>
+ {
+ // 清空ContextMenu的items
+ changeTeamItem.Items.Clear();
+
+ // 假设你有一个字符串数组
+ string[] items = TeamManager.GetAllTeamName();
+
+ // 遍历字符串数组,为每个元素创建一个MenuItem
+ for (int i = 0; i < items.Length; i++)
+ {
+ MenuItem menuItem = new MenuItem { Header = items[i] };
+ menuItem.Tag = i;
+ menuItem.Click += (sender, args) =>
+ {
+ // 输出被点击的item的index
+ MenuItem menuItem = sender as MenuItem;
+ int i = (int)menuItem.Tag;
+ Trace.WriteLine("Clicked item index: " + i);
+ AccountManager.MoveAccount(memberId, i);
+ };
+ changeTeamItem.Items.Add(menuItem);
+ }
+ };
+
+ return contextMenu;
+ }
+
+ private void delItem_Click(object sender, RoutedEventArgs e)
+ {
+ AccountManager.DeleteAccount(memberId);
+ }
+
+ private void editItem_Click(object sender, RoutedEventArgs e)
+ {
+ Trace.WriteLine("edit member " + memberId.ToString());
+ EditMemberDialog.CreateDailog(MainWindow.Instance, memberId);
+ }
+ }
+}
diff --git a/controls/TextBoxRule.cs b/controls/TextBoxRule.cs
new file mode 100644
index 0000000..bd48f8a
--- /dev/null
+++ b/controls/TextBoxRule.cs
@@ -0,0 +1,167 @@
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+using System.Windows.Controls;
+
+///
+/// 不能为空验证
+///
+public class NotNullValidationRule : ValidationRule
+{
+ public NotNullValidationRule()
+ {
+ ValidatesOnTargetUpdated = true;
+ }
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ if (string.IsNullOrEmpty(value as string) || string.IsNullOrWhiteSpace(value as string))
+ {
+ return new ValidationResult(false, "不能为空!");
+ }
+ return ValidationResult.ValidResult;
+ }
+}
+
+///
+/// 自定义正则表达式验证
+///
+/*
+ 一、校验数字的表达式
+ 1. 数字:^[0-9]*$
+ 2. n位的数字:^\d{n}$
+ 3. 至少n位的数字:^\d{n,}$
+ 4. m-n位的数字:^\d{m,n}$
+ 5. 零和非零开头的数字:^(0|[1-9][0-9]*)$
+ 6. 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
+ 7. 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
+ 8. 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
+ 9. 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
+ 10. 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
+ 11. 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
+ 12. 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
+ 13. 非负整数:^\d+$ 或 ^[1-9]\d*|0$
+ 14. 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
+ 15. 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
+ 16. 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
+ 17. 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
+ 18. 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
+ 19. 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
+ 二、校验字符的表达式
+ 1. 汉字:^[\u4e00-\u9fa5]{0,}$
+ 2. 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
+ 3. 长度为3-20的所有字符:^.{3,20}$
+ 4. 由26个英文字母组成的字符串:^[A-Za-z]+$
+ 5. 由26个大写英文字母组成的字符串:^[A-Z]+$
+ 6. 由26个小写英文字母组成的字符串:^[a-z]+$
+ 7. 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
+ 8. 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
+ 9. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
+ 10. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
+ 11. 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+ 12 禁止输入含有~的字符:[^~\x22]+
+ 三、特殊需求表达式
+ 1. Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
+ 2. 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
+ 3. InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
+ 4. 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
+ 5. 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
+ 6. 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
+ 7. 身份证号(15位、18位数字):^\d{15}|\d{18}$
+ 8. 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
+ 9. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
+ 10. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
+ 11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
+ 12. 日期格式:^\d{4}-\d{1,2}-\d{1,2}
+ 13. 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
+ 14. 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
+ 15. 钱的输入格式:
+ 16. 1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
+ 17. 2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
+ 18. 3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
+ 19. 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
+ 20. 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
+ 21. 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
+ 22. 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
+ 23 8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
+ 24. 备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
+ 25. xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
+ 26. 中文字符的正则表达式:[\u4e00-\u9fa5]
+ 27. 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
+ 28. 空白行的正则表达式:\n\s*\r (可以用来删除空白行)
+ 29. HTML标记的正则表达式:<(\S*?)[^>]*>.*?\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
+ 30. 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
+ 31. 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
+ 32. 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
+ 33. IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
+ 34. IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
+*/
+public class CustomRegularValidationRule : ValidationRule
+{
+ public CustomRegularValidationRule()
+ {
+ ValidatesOnTargetUpdated = true;
+ }
+ public string RegularString { get; set; } // 正则表达式规则
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ string str = value as string;
+ if (!string.IsNullOrWhiteSpace(str))
+ {
+ // 检查输入的字符串是否符合当前正则规范
+ if (!Regex.IsMatch(str, RegularString))
+ {
+ return new ValidationResult(false, "内容格式不正确");
+ }
+ }
+ return ValidationResult.ValidResult;
+ }
+}
+
+///
+/// 长度限制
+///
+class LengthLimitValidationRule : ValidationRule
+{
+ public LengthLimitValidationRule()
+ {
+ ValidatesOnTargetUpdated = true;
+ }
+ public double Minimum { get; set; }
+ public double Maximum { get; set; }
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ if (value == null) return ValidationResult.ValidResult;
+ double number = value.ToString().Length;
+ if (number > Maximum || number < Minimum)
+ {
+ return new ValidationResult(false, string.Format("值长度限制在 {0} 到 {1}", Minimum, Maximum));
+ }
+ return ValidationResult.ValidResult;
+ }
+}
+
+///
+/// ip规则验证
+///
+public class IPAddressRule : ValidationRule
+{
+ public IPAddressRule()
+ {
+ ValidatesOnTargetUpdated = true;
+ }
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ string IPAddress = value as string;
+
+ if (!string.IsNullOrWhiteSpace(IPAddress))
+ {
+ string IPAddressFormartRegex = @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$";
+
+ // 检查输入的字符串是否符合IP地址格式
+ if (!Regex.IsMatch(IPAddress, IPAddressFormartRegex))
+ {
+ return new ValidationResult(false, "IP地址格式不正确");
+ }
+ }
+ return ValidationResult.ValidResult;
+ }
+}
diff --git a/dialog/BaseDialog.xaml b/dialog/BaseDialog.xaml
new file mode 100644
index 0000000..af618a6
--- /dev/null
+++ b/dialog/BaseDialog.xaml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dialog/BaseDialog.xaml.cs b/dialog/BaseDialog.xaml.cs
new file mode 100644
index 0000000..65e09fc
--- /dev/null
+++ b/dialog/BaseDialog.xaml.cs
@@ -0,0 +1,40 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace Zerolauncher.dialog
+{
+ ///
+ /// BaseDialog.xaml 的交互逻辑
+ ///
+ public partial class BaseDialog : Window
+ {
+
+ //Storyboard storyboard;
+
+ public BaseDialog(UserControl control)
+ {
+ InitializeComponent();
+ //storyboard = FindResource("BlinkAnimation") as Storyboard;
+ mControl.Children.Add(control);
+ }
+
+ //protected override void OnDeactivated(EventArgs e)
+ //{
+ // base.OnDeactivated(e);
+ // // 当窗口失去焦点时,开始播放闪烁动画
+ // storyboard.Begin(this);
+ //}
+
+ private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ // 实现窗口的拖动
+ DragMove();
+ }
+
+ private void AirButton_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+ }
+}
diff --git a/dialog/DialogHelper.cs b/dialog/DialogHelper.cs
new file mode 100644
index 0000000..1e01054
--- /dev/null
+++ b/dialog/DialogHelper.cs
@@ -0,0 +1,128 @@
+using System.Windows;
+
+namespace Zerolauncher.dialog
+{
+ class EditMemberDialog
+ {
+ static BaseDialog? baseDialog;
+ static EditMember? editControl;
+
+ public static int? member;
+
+ public static void CreateDailog(Window p, int? memberId)
+ {
+ if (editControl != null || baseDialog != null)
+ {
+ return;
+ }
+ member = memberId;
+ editControl = new EditMember();
+ baseDialog = new BaseDialog(editControl);
+ baseDialog.ShowDialog();
+ baseDialog = null;
+ editControl = null;
+ member = null;
+ }
+
+ public static void Close()
+ {
+ if (baseDialog != null)
+ {
+ baseDialog.Close();
+ }
+ }
+
+ }
+
+ class EditTeamDialog
+ {
+ static BaseDialog? baseDialog;
+ static EditTeamControl? editControl;
+
+
+ public static bool CreateDailog(Window p, string? oldTeamName=null)
+ {
+ if (editControl != null || baseDialog != null)
+ {
+ return false;
+ }
+ if (oldTeamName != null)
+ {
+ editControl = new EditTeamControl(true);
+ editControl.edit_name.Text = oldTeamName;
+ }
+ else
+ {
+ editControl = new EditTeamControl(false);
+ editControl.btn_del.Visibility = Visibility.Hidden;
+ }
+ baseDialog = new BaseDialog(editControl);
+ baseDialog.ShowDialog();
+ baseDialog = null;
+ editControl = null;
+ return true;
+ }
+
+ public static void Close()
+ {
+ if (baseDialog != null)
+ {
+ baseDialog.Close();
+ }
+ }
+ }
+
+ class AddMemebersDialog
+ {
+ static BaseDialog? baseDialog;
+ static UseAccDataTextAdd? editControl;
+
+ public static void CreateDailog(Window p)
+ {
+ if (editControl != null || baseDialog != null)
+ {
+ return;
+ }
+ editControl = new UseAccDataTextAdd();
+ baseDialog = new BaseDialog(editControl);
+ baseDialog.ShowDialog();
+ baseDialog = null;
+ editControl = null;
+ }
+
+ public static void Close()
+ {
+ if (baseDialog != null)
+ {
+ baseDialog.Close();
+ }
+ }
+ }
+
+ class UpdateDialog
+ {
+ static BaseDialog? baseDialog;
+ static DownloadControl? editControl;
+
+ public static void CreateDailog(Window p)
+ {
+ if (editControl != null || baseDialog != null)
+ {
+ return;
+ }
+ editControl = new DownloadControl();
+ baseDialog = new BaseDialog(editControl);
+ baseDialog.ShowDialog();
+ baseDialog = null;
+ editControl = null;
+ }
+
+ public static void Close()
+ {
+ if (baseDialog != null)
+ {
+ baseDialog.Close();
+ }
+ }
+ }
+}
diff --git a/dialog/DownloadControl.xaml b/dialog/DownloadControl.xaml
new file mode 100644
index 0000000..22a801a
--- /dev/null
+++ b/dialog/DownloadControl.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/dialog/DownloadControl.xaml.cs b/dialog/DownloadControl.xaml.cs
new file mode 100644
index 0000000..86c2a7d
--- /dev/null
+++ b/dialog/DownloadControl.xaml.cs
@@ -0,0 +1,104 @@
+using System.IO;
+using System.Net.Http;
+using System.Windows.Controls;
+
+namespace Zerolauncher.dialog
+{
+ ///
+ /// DownloadControl.xaml 的交互逻辑
+ ///
+ public partial class DownloadControl : UserControl
+ {
+ const string cache_dir = "./.cache/auto.cache";
+
+ public DownloadControl()
+ {
+ InitializeComponent();
+ }
+
+ private void OnError(Exception ex)
+ {
+ // UnityEngine.Debug.Log("捕获异常 >>> " + ex);
+ }
+
+ public async Task Download(string fileUrl)
+ {
+ using (HttpClient client = new HttpClient())
+ {
+ // 获取文件大小
+ HttpResponseMessage responseHead = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, fileUrl));
+ long? contentLength = responseHead.Content.Headers.ContentLength;
+ Console.WriteLine($"文件大小:{contentLength} 字节");
+
+ // 计算块大小
+ int blockSize = 1024 * 1024; // 1MB
+ int blockCount = (int)Math.Ceiling((double)contentLength / blockSize);
+
+ // 创建SemaphoreSlim以限制同时进行的下载任务的数量
+ SemaphoreSlim semaphore = new SemaphoreSlim(4); // 最多允许4个并发下载任务
+
+ using (FileStream fileStream = new FileStream(cache_dir, FileMode.Create, FileAccess.Write, FileShare.None, blockSize, true))
+ {
+ // 创建任务列表
+ Task[] tasks = new Task[blockCount];
+
+ for (int i = 0; i < blockCount; i++)
+ {
+ int blockNumber = i;
+ tasks[i] = Task.Run(async () =>
+ {
+ await semaphore.WaitAsync(); // 等待获取许可
+
+ try
+ {
+ // 计算当前块的范围
+ var start = blockNumber * blockSize;
+ var end = (blockNumber == blockCount - 1) ? contentLength - 1 : start + blockSize - 1;
+
+ // 设置请求头,请求指定范围的数据
+ var request = new HttpRequestMessage { RequestUri = new Uri(fileUrl), Method = HttpMethod.Get };
+ request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(start, end);
+
+ // 下载当前块
+ using (HttpResponseMessage response = await client.SendAsync(request))
+ {
+ response.EnsureSuccessStatusCode();
+ byte[] buffer = await response.Content.ReadAsByteArrayAsync();
+ await fileStream.WriteAsync(buffer, 0, buffer.Length);
+ }
+
+ // 显示下载进度
+ double percent = (double)(blockNumber + 1) / blockCount * 100;
+ Console.WriteLine($"已下载:{percent:F2}%");
+ }
+ finally
+ {
+ semaphore.Release(); // 释放许可
+ }
+ });
+ }
+
+ // 等待所有任务完成
+ await Task.WhenAll(tasks);
+ }
+ }
+
+ Console.WriteLine("下载完成!");
+ }
+
+ private void OnUpdate(long size, long count)
+ {
+
+ }
+
+ private void OnDone(byte[] data)
+ {
+
+ }
+
+ private void OnDestroy()
+ {
+ }
+
+ }
+}
diff --git a/dialog/EditMember.xaml b/dialog/EditMember.xaml
new file mode 100644
index 0000000..fb0086e
--- /dev/null
+++ b/dialog/EditMember.xaml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dialog/EditMember.xaml.cs b/dialog/EditMember.xaml.cs
new file mode 100644
index 0000000..42a6eeb
--- /dev/null
+++ b/dialog/EditMember.xaml.cs
@@ -0,0 +1,80 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using Zerolauncher.Manager;
+
+namespace Zerolauncher.dialog
+{
+ ///
+ /// EditMember.xaml 的交互逻辑
+ ///
+ public partial class EditMember : UserControl
+ {
+
+ private Dictionary
_services;
+
+ public EditMember()
+ {
+ _services = new Dictionary();
+ int i = 0;
+ foreach (string serviceName in ServicesStaticInfo.ServicesName)
+ {
+ _services[i++] = serviceName;
+ }
+ InitializeComponent();
+ cb_pid.ItemsSource = _services;
+ if(EditMemberDialog.member != null)
+ {
+ int index = (int)EditMemberDialog.member;
+ var acc = AccountManager.accountsList[index];
+ cb_pid.SelectedIndex = acc.providerId;
+ edit_sid.Text = acc.serverId;
+ edit_acc.Text = acc.userName;
+ edit_pwd.Password = acc.userPWD;
+ edit_nick.Text = acc.nickName;
+ }
+ }
+
+ private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
+ {
+ PasswordBox passwordBox = sender as PasswordBox;
+ VisualBrush helpBrush = passwordBox.Resources["HelpBrush"] as VisualBrush;
+ if (passwordBox.Password.Length > 0)
+ {
+ passwordBox.Background = new SolidColorBrush(Color.FromRgb(255, 255, 255));
+ }
+ else
+ {
+ passwordBox.Background = helpBrush;
+ }
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ if (string.IsNullOrEmpty(cb_pid.Text) || string.IsNullOrEmpty(edit_sid.Text) || string.IsNullOrEmpty(edit_acc.Text) || string.IsNullOrEmpty(edit_pwd.Password) || string.IsNullOrEmpty(edit_nick.Text))
+ {
+ MessageBox.Show("所有选项均不能为空!", "提示");
+ return;
+ }
+ if (EditMemberDialog.member == null)
+ {
+ AccountManager.AddAccount(new Account { providerId = cb_pid.SelectedIndex, serverId = edit_sid.Text, userName = edit_acc.Text, userPWD = edit_pwd.Password, nickName = edit_nick.Text });
+
+ EditMemberDialog.Close();
+ return;
+ }
+ int index = (int)EditMemberDialog.member;
+ var acc = AccountManager.accountsList[index];
+ acc.providerId = cb_pid.SelectedIndex;
+ acc.serverId = edit_sid.Text;
+ acc.userName = edit_acc.Text;
+ acc.userPWD = edit_pwd.Password;
+ acc.nickName = edit_nick.Text;
+ AccountManager.saveEdit();
+ EditMemberDialog.Close();
+ return;
+ }
+
+ }
+}
+
diff --git a/dialog/EditTeamControl.xaml b/dialog/EditTeamControl.xaml
new file mode 100644
index 0000000..bbbcd4a
--- /dev/null
+++ b/dialog/EditTeamControl.xaml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dialog/EditTeamControl.xaml.cs b/dialog/EditTeamControl.xaml.cs
new file mode 100644
index 0000000..a3befa8
--- /dev/null
+++ b/dialog/EditTeamControl.xaml.cs
@@ -0,0 +1,45 @@
+using System.Windows;
+using System.Windows.Controls;
+using Zerolauncher.Manager;
+
+namespace Zerolauncher.dialog
+{
+ ///
+ /// EditTeamControl.xaml 的交互逻辑
+ ///
+ public partial class EditTeamControl : UserControl
+ {
+
+ bool isEditModle;
+
+ public EditTeamControl(bool isEditModle)
+ {
+ InitializeComponent();
+ this.isEditModle = isEditModle;
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ if(string.IsNullOrEmpty(edit_name.Text))
+ {
+ MessageBox.Show("昵称不能为空!", "提示");
+ return;
+ }
+ if (isEditModle) AccountManager.editTeamName(edit_name.Text); else TeamManager.addTeam(edit_name.Text);
+ EditTeamDialog.Close();
+ }
+
+ private void Button_Click_1(object sender, RoutedEventArgs e)
+ {
+ MessageBoxResult result = MessageBox.Show("即将放生此队伍以及队伍里所有的账号\n将会为你带来114点功德\n您确定要执行此操作吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
+ if (result == MessageBoxResult.OK)
+ {
+ if (!AccountManager.DeleteTeam())
+ {
+ MessageBox.Show("少爷这已经是最后一个队伍了!\n请新建一个队伍后再放生这个吧~", "提示");
+ }
+ }
+
+ }
+ }
+}
diff --git a/dialog/UseAccDataTextAdd.xaml b/dialog/UseAccDataTextAdd.xaml
new file mode 100644
index 0000000..02010b3
--- /dev/null
+++ b/dialog/UseAccDataTextAdd.xaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dialog/UseAccDataTextAdd.xaml.cs b/dialog/UseAccDataTextAdd.xaml.cs
new file mode 100644
index 0000000..fad86d7
--- /dev/null
+++ b/dialog/UseAccDataTextAdd.xaml.cs
@@ -0,0 +1,70 @@
+using Microsoft.Win32;
+using System.IO;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using Zerolauncher.Manager;
+
+namespace Zerolauncher.dialog
+{
+ ///
+ /// UseAccDataTextAdd.xaml 的交互逻辑
+ ///
+ public partial class UseAccDataTextAdd : UserControl
+ {
+ public UseAccDataTextAdd()
+ {
+ InitializeComponent();
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ //创建一个打开文件式的对话框
+ OpenFileDialog ofd = new OpenFileDialog();
+ //设置这个对话框的起始打开路径
+ ofd.InitialDirectory = @"C:\";
+ //设置打开的文件的类型,注意过滤器的语法
+ ofd.Filter = "账号文本|*.txt|其他格式|*.";
+ //调用ShowDialog()方法显示该对话框,该方法的返回值代表用户是否点击了确定按钮
+ if (ofd.ShowDialog() == true)
+ {
+ string[] lines = File.ReadAllLines(ofd.FileName, Encoding.UTF8);
+ for (int i = 0; i < lines.Length; i++)
+ {
+ var accTexts = lines[i].Split(input_split.Text);
+ if (accTexts.Length != 5)
+ {
+ MessageBox.Show($"文本在{i}行非法!\n{lines[i]}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+ var acc = new Account { };
+ if (!int.TryParse(accTexts[0], out acc.providerId))
+ {
+ MessageBox.Show($"输入的服务器代号错误!在{i}行\n错误:[{lines[i]}]无法转换成服务器代号", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+ if(0 < acc.providerId || acc.providerId > ServicesStaticInfo.ServicesName.Length)
+ {
+ MessageBox.Show($"输入的服务器代号错误!在{i}行\n错误:[{acc.providerId}]不是有效的服务器代号", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+ acc.serverId = accTexts[1];
+ acc.userName = accTexts[2];
+ acc.userPWD = accTexts[3];
+ acc.nickName = accTexts[4];
+ if (!AccountManager.AddAccounts(acc))
+ {
+ MessageBox.Show($"文本在{i}行出错!\n警告:[{acc.nickName}]昵称冲突,将跳过添加此账号", "Warring", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ MessageBox.Show("添加完成!", "提示");
+ AccountManager.saveEdit();
+ AddMemebersDialog.Close();
+ }
+ else
+ {
+ MessageBox.Show("没有选择文件");
+ }
+ }
+ }
+}
diff --git a/res/1.png b/res/1.png
new file mode 100644
index 0000000..9bf47cd
Binary files /dev/null and b/res/1.png differ
diff --git a/res/111.png b/res/111.png
new file mode 100644
index 0000000..cd1649d
Binary files /dev/null and b/res/111.png differ
diff --git a/res/112.png b/res/112.png
new file mode 100644
index 0000000..175efd9
Binary files /dev/null and b/res/112.png differ
diff --git a/res/2.png b/res/2.png
new file mode 100644
index 0000000..77f7191
Binary files /dev/null and b/res/2.png differ
diff --git a/res/21.png b/res/21.png
new file mode 100644
index 0000000..00149bc
Binary files /dev/null and b/res/21.png differ
diff --git a/res/22.png b/res/22.png
new file mode 100644
index 0000000..fd19f4d
Binary files /dev/null and b/res/22.png differ
diff --git a/res/24.png b/res/24.png
new file mode 100644
index 0000000..2f2a2ec
Binary files /dev/null and b/res/24.png differ
diff --git a/res/25.png b/res/25.png
new file mode 100644
index 0000000..8d72aed
Binary files /dev/null and b/res/25.png differ
diff --git a/res/319145.jpg b/res/319145.jpg
new file mode 100644
index 0000000..a151247
Binary files /dev/null and b/res/319145.jpg differ
diff --git a/res/319163.jpg b/res/319163.jpg
new file mode 100644
index 0000000..1c51390
Binary files /dev/null and b/res/319163.jpg differ
diff --git a/res/39376.jpg b/res/39376.jpg
new file mode 100644
index 0000000..f939a51
Binary files /dev/null and b/res/39376.jpg differ
diff --git a/res/39389.jpg b/res/39389.jpg
new file mode 100644
index 0000000..15e45b1
Binary files /dev/null and b/res/39389.jpg differ
diff --git a/res/4.png b/res/4.png
new file mode 100644
index 0000000..b0960e2
Binary files /dev/null and b/res/4.png differ
diff --git a/res/5.png b/res/5.png
new file mode 100644
index 0000000..07d9d71
Binary files /dev/null and b/res/5.png differ
diff --git a/res/592342.jpg b/res/592342.jpg
new file mode 100644
index 0000000..a9b4126
Binary files /dev/null and b/res/592342.jpg differ
diff --git a/res/592343.jpg b/res/592343.jpg
new file mode 100644
index 0000000..623990d
Binary files /dev/null and b/res/592343.jpg differ
diff --git a/res/61.png b/res/61.png
new file mode 100644
index 0000000..05bfe28
Binary files /dev/null and b/res/61.png differ
diff --git a/res/88657.jpg b/res/88657.jpg
new file mode 100644
index 0000000..3e265c8
Binary files /dev/null and b/res/88657.jpg differ
diff --git a/res/RulePic/0.png b/res/RulePic/0.png
new file mode 100644
index 0000000..4c200aa
Binary files /dev/null and b/res/RulePic/0.png differ
diff --git a/res/RulePic/1.png b/res/RulePic/1.png
new file mode 100644
index 0000000..d1d323c
Binary files /dev/null and b/res/RulePic/1.png differ
diff --git a/res/RulePic/2.png b/res/RulePic/2.png
new file mode 100644
index 0000000..849ce84
Binary files /dev/null and b/res/RulePic/2.png differ
diff --git a/res/RulePic/3.png b/res/RulePic/3.png
new file mode 100644
index 0000000..6ec092b
Binary files /dev/null and b/res/RulePic/3.png differ
diff --git a/res/RulePic/4.png b/res/RulePic/4.png
new file mode 100644
index 0000000..f24cdfa
Binary files /dev/null and b/res/RulePic/4.png differ
diff --git a/res/about1.png b/res/about1.png
new file mode 100644
index 0000000..e4b0f8a
Binary files /dev/null and b/res/about1.png differ
diff --git a/res/btn_close1.png b/res/btn_close1.png
new file mode 100644
index 0000000..31eff90
Binary files /dev/null and b/res/btn_close1.png differ
diff --git a/res/btn_mini1.png b/res/btn_mini1.png
new file mode 100644
index 0000000..37231ec
Binary files /dev/null and b/res/btn_mini1.png differ
diff --git a/res/config.png b/res/config.png
new file mode 100644
index 0000000..2803558
Binary files /dev/null and b/res/config.png differ
diff --git a/res/defaultUserData.json b/res/defaultUserData.json
new file mode 100644
index 0000000..3202717
--- /dev/null
+++ b/res/defaultUserData.json
@@ -0,0 +1,45 @@
+{
+ "time": "Tue May 30 03:14:24 2023",
+ "pluginAcc": {"user": null, "pwd": null},
+ "lastTeamIndex": 0,
+ "teamAcc": [
+ {
+ "name": "队伍1",
+ "member": [
+ {
+ "nickName": "示范账号",
+ "user": "test",
+ "pwd": "test",
+ "providerId": 0,
+ "serverId": "179"
+ }
+ ]
+ }
+ ],
+ "serverList": {
+ "time": "Tue May 30 03:14:24 2023",
+ "Services": [
+ {
+ "name": "4399游戏",
+ "nick": "43",
+ "postUrl": "http://ptlogin.4399.com/ptlogin/login.do?v=1",
+ "loginBody": "loginFrom=uframe&postLoginHandler=default&layoutSelfAdapting=true&externalLogin=qq&displayMode=popup&layout=vertical&appId=www_home&mainDivId=popup_login_div&includeFcmInfo=false&userNameLabel=4399用户名&userNameTip=请输入4399用户名&welcomeTip=欢迎回到4399&username=%1&password=%2",
+ "gameUrl": "http://web.4399.com/stat/togame.php?target=ddt&server_id=S%1"
+ },
+ {
+ "name": "7k7k游戏",
+ "nick": "7k",
+ "postUrl": "http://zc.7k7k.com/post_login",
+ "loginBody": "username=%1&password=%2&rf=http://www.7k7k.com/#bottom",
+ "gameUrl": "http://web.7k7k.com/games/togame.php?target=ddt_7&server_id=%1"
+ },
+ {
+ "name": "7道",
+ "nick": "7道",
+ "postUrl": "http://zc.7k7k.com/post_login",
+ "loginBody": "username=%1&password=%2",
+ "gameUrl": "http://web.7k7k.com/games/togame.php?target=ddt_7&server_id=1"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/res/del.png b/res/del.png
new file mode 100644
index 0000000..0d2abba
Binary files /dev/null and b/res/del.png differ
diff --git a/res/player_ico.png b/res/player_ico.png
new file mode 100644
index 0000000..2286c85
Binary files /dev/null and b/res/player_ico.png differ
diff --git a/res/player_ico1.png b/res/player_ico1.png
new file mode 100644
index 0000000..4f078d3
Binary files /dev/null and b/res/player_ico1.png differ
diff --git a/res/title.ico b/res/title.ico
new file mode 100644
index 0000000..48b7bf3
Binary files /dev/null and b/res/title.ico differ
diff --git a/res/wp12470772-ddtank-wallpapers.jpg b/res/wp12470772-ddtank-wallpapers.jpg
new file mode 100644
index 0000000..0e63b73
Binary files /dev/null and b/res/wp12470772-ddtank-wallpapers.jpg differ
diff --git a/res/wp12470850-ddtank-wallpapers.jpg b/res/wp12470850-ddtank-wallpapers.jpg
new file mode 100644
index 0000000..30660bf
Binary files /dev/null and b/res/wp12470850-ddtank-wallpapers.jpg differ