diff --git a/Controller/InventoryController.cs b/Controller/InventoryController.cs new file mode 100644 index 0000000..eadd5d6 --- /dev/null +++ b/Controller/InventoryController.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Controller +{ + public class InventoryController + { + } +} diff --git a/Controller/LoginController.cs b/Controller/LoginController.cs new file mode 100644 index 0000000..2ca0ee9 --- /dev/null +++ b/Controller/LoginController.cs @@ -0,0 +1,46 @@ +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Model; +using Milimoe.FunGame.Core.Library.Exception; + +namespace Milimoe.FunGame.Desktop.Controller +{ + public class LoginController : BaseController + { + private readonly LoginModel LoginModel; + + public LoginController() + { + LoginModel = new LoginModel(); + } + + public override void Dispose() + { + LoginModel.Dispose(); + } + + public static async Task LoginAccount(params object[]? objs) + { + bool result = false; + + try + { + LoginEventArgs LoginEventArgs = new(objs); + if (RunTime.Login?.OnBeforeLoginEvent(LoginEventArgs) == Core.Library.Constant.EventResult.Fail) return false; + + result = await LoginModel.LoginAccountAsync(objs); + + if (result) RunTime.Login?.OnSucceedLoginEvent(LoginEventArgs); + else RunTime.Login?.OnFailedLoginEvent(LoginEventArgs); + RunTime.Login?.OnAfterLoginEvent(LoginEventArgs); + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + + return result; + } + } +} diff --git a/Controller/MainController.cs b/Controller/MainController.cs new file mode 100644 index 0000000..57697b9 --- /dev/null +++ b/Controller/MainController.cs @@ -0,0 +1,107 @@ +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.Model; +using Milimoe.FunGame.Desktop.UI; +using Milimoe.FunGame.Desktop.Library; + +namespace Milimoe.FunGame.Desktop.Controller +{ + public class MainController : BaseController + { + public bool Connected => Do(MainInvokeType.Connected); + + private MainModel MainModel { get; } + private Main Main { get; } + + public MainController(Main Main) + { + this.Main = Main; + MainModel = new MainModel(Main); + } + + public override void Dispose() + { + MainModel.Dispose(); + } + + /** + * 从内部去调用Model的方法,并记录日志。 + */ + private T Do(MainInvokeType DoType, params object[] args) + { + object result = new(); + switch(DoType) + { + case MainInvokeType.LogOut: + if (Main.OnBeforeLogoutEvent(new GeneralEventArgs()) == EventResult.Fail) return (T)result; + result = MainModel.LogOut(); + break; + + case MainInvokeType.IntoRoom: + string roomid = new("-1"); + if (args != null && args.Length > 0) roomid = (string)args[0]; + if (Main.OnBeforeIntoRoomEvent(new RoomEventArgs(roomid)) == EventResult.Fail) return (T)result; + result = MainModel.IntoRoom(roomid); + break; + + case MainInvokeType.UpdateRoom: + result = MainModel.UpdateRoom(); + break; + + case MainInvokeType.QuitRoom: + roomid = new("-1"); + if (args != null && args.Length > 0) roomid = (string)args[0]; + if (Main.OnBeforeQuitRoomEvent(new RoomEventArgs(roomid)) == EventResult.Fail) return (T)result; + result = MainModel.QuitRoom(roomid); + break; + + case MainInvokeType.CreateRoom: + if (Main.OnBeforeCreateRoomEvent(new RoomEventArgs()) == EventResult.Fail) return (T)result; + result = MainModel.CreateRoom(); + break; + + case MainInvokeType.Chat: + string msg = ""; + if (args != null && args.Length > 0) msg = (string)args[0]; + if (Main.OnBeforeSendTalkEvent(new SendTalkEventArgs(msg)) == EventResult.Fail) return (T)result; + if (msg.Trim() != "") result = MainModel.Chat(msg); + break; + + default: + break; + } + return (T)result; + } + + public bool LogOut() + { + return Do(MainInvokeType.LogOut); + } + + public bool UpdateRoom() + { + return Do(MainInvokeType.UpdateRoom); + } + + public bool IntoRoom(string roomid) + { + return Do(MainInvokeType.IntoRoom, roomid); + } + + public bool QuitRoom(string roomid) + { + return Do(MainInvokeType.QuitRoom, roomid); + } + + public bool CreateRoom() + { + return Do(MainInvokeType.CreateRoom); + } + + public bool Chat(string msg) + { + return Do(MainInvokeType.Chat, msg); + } + } +} diff --git a/Controller/RegisterController.cs b/Controller/RegisterController.cs new file mode 100644 index 0000000..5368dc7 --- /dev/null +++ b/Controller/RegisterController.cs @@ -0,0 +1,51 @@ +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Model; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.UI; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Core.Library.Common.Event; + +namespace Milimoe.FunGame.Desktop.Controller +{ + public class RegisterController : BaseController + { + private readonly Register Register; + private readonly RegisterModel RegModel; + + public RegisterController(Register reg) + { + Register = reg; + RegModel = new RegisterModel(reg); + } + + public override void Dispose() + { + RegModel.Dispose(); + } + + public async Task Reg(params object[]? objs) + { + bool result = false; + + try + { + RegisterEventArgs RegEventArgs = new (objs); + if (Register.OnBeforeRegEvent(RegEventArgs) == EventResult.Fail) return false; + + result = await RegModel.Reg(objs); + + if (result) Register.OnSucceedRegEvent(RegEventArgs); + else Register.OnFailedRegEvent(RegEventArgs); + Register.OnAfterRegEvent(RegEventArgs); + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + + return result; + } + } +} diff --git a/Controller/RoomSettingController.cs b/Controller/RoomSettingController.cs new file mode 100644 index 0000000..47dcd9d --- /dev/null +++ b/Controller/RoomSettingController.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Controller +{ + public class RoomSettingController + { + } +} diff --git a/Controller/RunTimeController.cs b/Controller/RunTimeController.cs new file mode 100644 index 0000000..d473d0e --- /dev/null +++ b/Controller/RunTimeController.cs @@ -0,0 +1,119 @@ +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Model; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Controller +{ + public class RunTimeController + { + public bool Connected => Do(RunTimeInvokeType.Connected); + + private RunTimeModel RunTimeModel { get; } + private Main Main { get; } + + public RunTimeController(Main Main) + { + this.Main = Main; + RunTimeModel = new RunTimeModel(Main); + } + + /** + * 从内部去调用Model的方法,并记录日志。 + */ + private T Do(RunTimeInvokeType DoType, params object[] args) + { + object result = new(); + switch (DoType) + { + case RunTimeInvokeType.GetServerConnection: + result = RunTimeModel.GetServerConnection(); + break; + + case RunTimeInvokeType.Connect: + result = RunTimeModel.Connect(); + if ((ConnectResult)result != ConnectResult.Success) + { + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + } + break; + + case RunTimeInvokeType.Connected: + result = RunTimeModel.Connected; + break; + + case RunTimeInvokeType.Disconnect: + if (Main.OnBeforeDisconnectEvent(new GeneralEventArgs()) == EventResult.Fail) return (T)result; + RunTimeModel.Disconnect(); + break; + + case RunTimeInvokeType.Disconnected: + break; + + case RunTimeInvokeType.AutoLogin: + break; + + case RunTimeInvokeType.Close: + if (args != null && args.Length > 0) + { + RunTimeModel.Error((Exception)args[0]); + result = true; + } + else + result = RunTimeModel.Close(); + break; + + default: + break; + } + return (T)result; + } + + public bool GetServerConnection() + { + return Do(RunTimeInvokeType.GetServerConnection); + } + + public ConnectResult Connect() + { + return Do(RunTimeInvokeType.Connect); + } + + public void Disconnect() + { + Do(RunTimeInvokeType.Disconnect); + } + + public void Disconnected() + { + Do(RunTimeInvokeType.Disconnected); + } + + public bool Close() + { + return Do(RunTimeInvokeType.Close); + } + + public bool Error(Exception e) + { + return Do(RunTimeInvokeType.Close, e); + } + + public async Task AutoLogin(params object[] objs) + { + try + { + Do(RunTimeInvokeType.AutoLogin); + LoginController LoginController = new(); + await LoginController.LoginAccount(objs); + LoginController.Dispose(); + } + catch (Exception e) + { + RunTime.WriteGameInfo(e.GetErrorInfo()); + } + } + } +} diff --git a/Controller/StoreController.cs b/Controller/StoreController.cs new file mode 100644 index 0000000..0d04065 --- /dev/null +++ b/Controller/StoreController.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Controller +{ + public class StoreController + { + } +} diff --git a/Controller/UserCenterController.cs b/Controller/UserCenterController.cs new file mode 100644 index 0000000..024de9a --- /dev/null +++ b/Controller/UserCenterController.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Controller +{ + public class UserCenterController + { + } +} diff --git a/FunGame.Desktop.csproj b/FunGame.Desktop.csproj new file mode 100644 index 0000000..50e10de --- /dev/null +++ b/FunGame.Desktop.csproj @@ -0,0 +1,63 @@ + + + + WinExe + net7.0-windows + enable + true + enable + Images\logo.ico + + logo.ico + Milimoe + ..\bin + False + False + Milimoe + FunGame + FunGame.Desktop + ..\bin + 1.0 + 1.0 + Milimoe.$(MSBuildProjectName.Replace(" ", "_")) + + + + embedded + + + + embedded + + + + + + + + + Component + + + True + True + Resources.resx + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + True + \ + + + + \ No newline at end of file diff --git a/FunGame.Desktop.sln b/FunGame.Desktop.sln new file mode 100644 index 0000000..bb675cf --- /dev/null +++ b/FunGame.Desktop.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33103.184 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunGame.Desktop", "FunGame.Desktop.csproj", "{22D5BDE1-69FE-460D-84C8-11B396A70635}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {22D5BDE1-69FE-460D-84C8-11B396A70635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22D5BDE1-69FE-460D-84C8-11B396A70635}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22D5BDE1-69FE-460D-84C8-11B396A70635}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22D5BDE1-69FE-460D-84C8-11B396A70635}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F4D2F503-8CFC-4B03-9B33-D2DDAB33B84E} + EndGlobalSection +EndGlobal diff --git a/Images/back.jpg b/Images/back.jpg new file mode 100644 index 0000000..2bbc4df Binary files /dev/null and b/Images/back.jpg differ diff --git a/Images/exit.png b/Images/exit.png new file mode 100644 index 0000000..f4fb70c Binary files /dev/null and b/Images/exit.png differ diff --git a/Images/green.png b/Images/green.png new file mode 100644 index 0000000..e88681d Binary files /dev/null and b/Images/green.png differ diff --git a/Images/logo.ico b/Images/logo.ico new file mode 100644 index 0000000..4082874 Binary files /dev/null and b/Images/logo.ico differ diff --git a/Images/min.png b/Images/min.png new file mode 100644 index 0000000..864c84f Binary files /dev/null and b/Images/min.png differ diff --git a/Images/red.png b/Images/red.png new file mode 100644 index 0000000..1414926 Binary files /dev/null and b/Images/red.png differ diff --git a/Images/send.png b/Images/send.png new file mode 100644 index 0000000..d888873 Binary files /dev/null and b/Images/send.png differ diff --git a/Images/yellow.png b/Images/yellow.png new file mode 100644 index 0000000..cab8859 Binary files /dev/null and b/Images/yellow.png differ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..0ad25db --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/Library/Base/BaseLogin.cs b/Library/Base/BaseLogin.cs new file mode 100644 index 0000000..6807845 --- /dev/null +++ b/Library/Base/BaseLogin.cs @@ -0,0 +1,51 @@ +using Milimoe.FunGame.Core.Interface; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.Library.Component; + +namespace Milimoe.FunGame.Desktop.Library.Base +{ + public class BaseLogin : GeneralForm, ILoginEventHandler + { + public event ILoginEventHandler.BeforeEventHandler? BeforeLogin; + public event ILoginEventHandler.AfterEventHandler? AfterLogin; + public event ILoginEventHandler.SucceedEventHandler? SucceedLogin; + public event ILoginEventHandler.FailedEventHandler? FailedLogin; + + public EventResult OnAfterLoginEvent(LoginEventArgs e) + { + if (AfterLogin != null) + { + return AfterLogin.Invoke(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnBeforeLoginEvent(LoginEventArgs e) + { + if (BeforeLogin != null) + { + return BeforeLogin.Invoke(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedLoginEvent(LoginEventArgs e) + { + if (FailedLogin != null) + { + return FailedLogin.Invoke(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedLoginEvent(LoginEventArgs e) + { + if (SucceedLogin != null) + { + return SucceedLogin.Invoke(this, e); + } + else return EventResult.NoEventImplement; + } + } +} diff --git a/Library/Base/BaseMain.cs b/Library/Base/BaseMain.cs new file mode 100644 index 0000000..5089a9b --- /dev/null +++ b/Library/Base/BaseMain.cs @@ -0,0 +1,503 @@ +using Milimoe.FunGame.Core.Interface; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.Library.Component; + +namespace Milimoe.FunGame.Desktop.Library.Base +{ + public class BaseMain : GeneralForm, IConnectEventHandler, IDisconnectEventHandler, ILoginEventHandler, ILogoutEventHandler, IIntoRoomEventHandler, ISendTalkEventHandler, + ICreateRoomEventHandler, IQuitRoomEventHandler, IStartMatchEventHandler, IStartGameEventHandler, IOpenInventoryEventHandler, IOpenStoreEventHandler + { + public event IEventHandler.BeforeEventHandler? BeforeConnect; + public event IEventHandler.AfterEventHandler? AfterConnect; + public event IEventHandler.SucceedEventHandler? SucceedConnect; + public event IEventHandler.FailedEventHandler? FailedConnect; + + public EventResult OnAfterConnectEvent(GeneralEventArgs e) + { + if (AfterConnect != null) + { + return AfterConnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnBeforeConnectEvent(GeneralEventArgs e) + { + if (BeforeConnect != null) + { + return BeforeConnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedConnectEvent(GeneralEventArgs e) + { + if (SucceedConnect != null) + { + return SucceedConnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedConnectEvent(GeneralEventArgs e) + { + if (FailedConnect != null) + { + return FailedConnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IEventHandler.BeforeEventHandler? BeforeDisconnect; + public event IEventHandler.AfterEventHandler? AfterDisconnect; + public event IEventHandler.SucceedEventHandler? SucceedDisconnect; + public event IEventHandler.FailedEventHandler? FailedDisconnect; + + public EventResult OnAfterDisconnectEvent(GeneralEventArgs e) + { + if (AfterDisconnect != null) + { + return AfterDisconnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnBeforeDisconnectEvent(GeneralEventArgs e) + { + if (BeforeDisconnect != null) + { + return BeforeDisconnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedDisconnectEvent(GeneralEventArgs e) + { + if (FailedDisconnect != null) + { + return FailedDisconnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedDisconnectEvent(GeneralEventArgs e) + { + if (SucceedDisconnect != null) + { + return SucceedDisconnect(this, e); + } + else return EventResult.NoEventImplement; + } + + public event ILoginEventHandler.BeforeEventHandler? BeforeLogin; + public event ILoginEventHandler.AfterEventHandler? AfterLogin; + public event ILoginEventHandler.SucceedEventHandler? SucceedLogin; + public event ILoginEventHandler.FailedEventHandler? FailedLogin; + + public EventResult OnBeforeLoginEvent(LoginEventArgs e) + { + if (BeforeLogin != null) + { + return BeforeLogin(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterLoginEvent(LoginEventArgs e) + { + if (AfterLogin != null) + { + return AfterLogin(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedLoginEvent(LoginEventArgs e) + { + if (SucceedLogin != null) + { + return SucceedLogin(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedLoginEvent(LoginEventArgs e) + { + if (FailedLogin != null) + { + return FailedLogin(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IEventHandler.BeforeEventHandler? BeforeLogout; + public event IEventHandler.AfterEventHandler? AfterLogout; + public event IEventHandler.SucceedEventHandler? SucceedLogout; + public event IEventHandler.FailedEventHandler? FailedLogout; + + public EventResult OnAfterLogoutEvent(GeneralEventArgs e) + { + if (AfterLogout != null) + { + return AfterLogout(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnBeforeLogoutEvent(GeneralEventArgs e) + { + if (BeforeLogout != null) + { + return BeforeLogout(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedLogoutEvent(GeneralEventArgs e) + { + if (FailedLogout != null) + { + return FailedLogout(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedLogoutEvent(GeneralEventArgs e) + { + if (SucceedLogout != null) + { + return SucceedLogout(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IIntoRoomEventHandler.BeforeEventHandler? BeforeIntoRoom; + public event IIntoRoomEventHandler.AfterEventHandler? AfterIntoRoom; + public event IIntoRoomEventHandler.SucceedEventHandler? SucceedIntoRoom; + public event IIntoRoomEventHandler.FailedEventHandler? FailedIntoRoom; + + public EventResult OnBeforeIntoRoomEvent(RoomEventArgs e) + { + if (BeforeIntoRoom != null) + { + return BeforeIntoRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterIntoRoomEvent(RoomEventArgs e) + { + if (AfterIntoRoom != null) + { + return AfterIntoRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedIntoRoomEvent(RoomEventArgs e) + { + if (SucceedIntoRoom != null) + { + return SucceedIntoRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedIntoRoomEvent(RoomEventArgs e) + { + if (FailedIntoRoom != null) + { + return FailedIntoRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public event ISendTalkEventHandler.BeforeEventHandler? BeforeSendTalk; + public event ISendTalkEventHandler.AfterEventHandler? AfterSendTalk; + public event ISendTalkEventHandler.SucceedEventHandler? SucceedSendTalk; + public event ISendTalkEventHandler.FailedEventHandler? FailedSendTalk; + + public EventResult OnBeforeSendTalkEvent(SendTalkEventArgs e) + { + if (BeforeSendTalk != null) + { + return BeforeSendTalk(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterSendTalkEvent(SendTalkEventArgs e) + { + if (AfterSendTalk != null) + { + return AfterSendTalk(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedSendTalkEvent(SendTalkEventArgs e) + { + if (SucceedSendTalk != null) + { + return SucceedSendTalk(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedSendTalkEvent(SendTalkEventArgs e) + { + if (FailedSendTalk != null) + { + return FailedSendTalk(this, e); + } + else return EventResult.NoEventImplement; + } + + public event ICreateRoomEventHandler.BeforeEventHandler? BeforeCreateRoom; + public event ICreateRoomEventHandler.AfterEventHandler? AfterCreateRoom; + public event ICreateRoomEventHandler.SucceedEventHandler? SucceedCreateRoom; + public event ICreateRoomEventHandler.FailedEventHandler? FailedCreateRoom; + + public EventResult OnBeforeCreateRoomEvent(RoomEventArgs e) + { + if (BeforeCreateRoom != null) + { + return BeforeCreateRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterCreateRoomEvent(RoomEventArgs e) + { + if (AfterCreateRoom != null) + { + return AfterCreateRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedCreateRoomEvent(RoomEventArgs e) + { + if (SucceedCreateRoom != null) + { + return SucceedCreateRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedCreateRoomEvent(RoomEventArgs e) + { + if (FailedCreateRoom != null) + { + return FailedCreateRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IQuitRoomEventHandler.BeforeEventHandler? BeforeQuitRoom; + public event IQuitRoomEventHandler.AfterEventHandler? AfterQuitRoom; + public event IQuitRoomEventHandler.SucceedEventHandler? SucceedQuitRoom; + public event IQuitRoomEventHandler.FailedEventHandler? FailedQuitRoom; + + public EventResult OnBeforeQuitRoomEvent(RoomEventArgs e) + { + if (BeforeQuitRoom != null) + { + return BeforeQuitRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterQuitRoomEvent(RoomEventArgs e) + { + if (AfterQuitRoom != null) + { + return AfterQuitRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedQuitRoomEvent(RoomEventArgs e) + { + if (SucceedQuitRoom != null) + { + return SucceedQuitRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedQuitRoomEvent(RoomEventArgs e) + { + if (FailedQuitRoom != null) + { + return FailedQuitRoom(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IEventHandler.BeforeEventHandler? BeforeStartMatch; + public event IEventHandler.AfterEventHandler? AfterStartMatch; + public event IEventHandler.SucceedEventHandler? SucceedStartMatch; + public event IEventHandler.FailedEventHandler? FailedStartMatch; + + public EventResult OnBeforeStartMatchEvent(GeneralEventArgs e) + { + if (BeforeStartMatch != null) + { + return BeforeStartMatch(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterStartMatchEvent(GeneralEventArgs e) + { + if (AfterStartMatch != null) + { + return AfterStartMatch(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedStartMatchEvent(GeneralEventArgs e) + { + if (SucceedStartMatch != null) + { + return SucceedStartMatch(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedStartMatchEvent(GeneralEventArgs e) + { + if (FailedStartMatch != null) + { + return FailedStartMatch(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IEventHandler.BeforeEventHandler? BeforeStartGame; + public event IEventHandler.AfterEventHandler? AfterStartGame; + public event IEventHandler.SucceedEventHandler? SucceedStartGame; + public event IEventHandler.FailedEventHandler? FailedStartGame; + + public EventResult OnBeforeStartGameEvent(GeneralEventArgs e) + { + if (BeforeStartGame != null) + { + return BeforeStartGame(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterStartGameEvent(GeneralEventArgs e) + { + if (AfterStartGame != null) + { + return AfterStartGame(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedStartGameEvent(GeneralEventArgs e) + { + if (SucceedStartGame != null) + { + return SucceedStartGame(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedStartGameEvent(GeneralEventArgs e) + { + if (FailedStartGame != null) + { + return FailedStartGame(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IEventHandler.BeforeEventHandler? BeforeOpenInventory; + public event IEventHandler.AfterEventHandler? AfterOpenInventory; + public event IEventHandler.SucceedEventHandler? SucceedOpenInventory; + public event IEventHandler.FailedEventHandler? FailedOpenInventory; + + public EventResult OnBeforeOpenInventoryEvent(GeneralEventArgs e) + { + if (BeforeOpenInventory != null) + { + return BeforeOpenInventory(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterOpenInventoryEvent(GeneralEventArgs e) + { + if (AfterOpenInventory != null) + { + return AfterOpenInventory(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedOpenInventoryEvent(GeneralEventArgs e) + { + if (SucceedOpenInventory != null) + { + return SucceedOpenInventory(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedOpenInventoryEvent(GeneralEventArgs e) + { + if (FailedOpenInventory != null) + { + return FailedOpenInventory(this, e); + } + else return EventResult.NoEventImplement; + } + + public event IEventHandler.BeforeEventHandler? BeforeOpenStore; + public event IEventHandler.AfterEventHandler? AfterOpenStore; + public event IEventHandler.SucceedEventHandler? SucceedOpenStore; + public event IEventHandler.FailedEventHandler? FailedOpenStore; + + public EventResult OnBeforeOpenStoreEvent(GeneralEventArgs e) + { + if (BeforeOpenStore != null) + { + return BeforeOpenStore(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnAfterOpenStoreEvent(GeneralEventArgs e) + { + if (AfterOpenStore != null) + { + return AfterOpenStore(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedOpenStoreEvent(GeneralEventArgs e) + { + if (SucceedOpenStore != null) + { + return SucceedOpenStore(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedOpenStoreEvent(GeneralEventArgs e) + { + if (FailedOpenStore != null) + { + return FailedOpenStore(this, e); + } + else return EventResult.NoEventImplement; + } + } +} diff --git a/Library/Base/BaseReg.cs b/Library/Base/BaseReg.cs new file mode 100644 index 0000000..672b60c --- /dev/null +++ b/Library/Base/BaseReg.cs @@ -0,0 +1,51 @@ +using Milimoe.FunGame.Core.Interface; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.Library.Component; + +namespace Milimoe.FunGame.Desktop.Library.Base +{ + public class BaseReg : GeneralForm, IRegEventHandler + { + public event IRegEventHandler.BeforeEventHandler? BeforeReg; + public event IRegEventHandler.AfterEventHandler? AfterReg; + public event IRegEventHandler.SucceedEventHandler? SucceedReg; + public event IRegEventHandler.FailedEventHandler? FailedReg; + + public EventResult OnAfterRegEvent(RegisterEventArgs e) + { + if (AfterReg != null) + { + return AfterReg(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnBeforeRegEvent(RegisterEventArgs e) + { + if (BeforeReg != null) + { + return BeforeReg(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnFailedRegEvent(RegisterEventArgs e) + { + if (FailedReg != null) + { + return FailedReg(this, e); + } + else return EventResult.NoEventImplement; + } + + public EventResult OnSucceedRegEvent(RegisterEventArgs e) + { + if (SucceedReg != null) + { + return SucceedReg(this, e); + } + else return EventResult.NoEventImplement; + } + } +} diff --git a/Library/Component/ExitButton.Designer.cs b/Library/Component/ExitButton.Designer.cs new file mode 100644 index 0000000..73edb2d --- /dev/null +++ b/Library/Component/ExitButton.Designer.cs @@ -0,0 +1,36 @@ +namespace Milimoe.FunGame.Desktop.Library.Component +{ + partial class ExitButton + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Library/Component/ExitButton.cs b/Library/Component/ExitButton.cs new file mode 100644 index 0000000..3ac34e2 --- /dev/null +++ b/Library/Component/ExitButton.cs @@ -0,0 +1,63 @@ +using System.ComponentModel; + +namespace Milimoe.FunGame.Desktop.Library.Component +{ + public partial class ExitButton : Button + { + public GeneralForm? RelativeForm { get; set; } + + public ExitButton() + { + InitializeComponent(); + Anchor = System.Windows.Forms.AnchorStyles.None; + BackColor = System.Drawing.Color.White; + BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.exit; + FlatAppearance.BorderColor = System.Drawing.Color.White; + FlatAppearance.BorderSize = 0; + FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); + FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); + FlatStyle = System.Windows.Forms.FlatStyle.Flat; + Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + ForeColor = System.Drawing.Color.Red; + Location = new System.Drawing.Point(750, 3); + Size = new System.Drawing.Size(47, 47); + TextAlign = System.Drawing.ContentAlignment.TopLeft; + UseVisualStyleBackColor = false; + + Click += ExitButton_Click; + } + + public ExitButton(IContainer container) + { + container.Add(this); + InitializeComponent(); + Anchor = System.Windows.Forms.AnchorStyles.None; + BackColor = System.Drawing.Color.White; + BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.exit; + FlatAppearance.BorderColor = System.Drawing.Color.White; + FlatAppearance.BorderSize = 0; + FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); + FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); + FlatStyle = System.Windows.Forms.FlatStyle.Flat; + Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + ForeColor = System.Drawing.Color.Red; + Location = new System.Drawing.Point(750, 3); + Size = new System.Drawing.Size(47, 47); + TextAlign = System.Drawing.ContentAlignment.TopLeft; + UseVisualStyleBackColor = false; + + Click += ExitButton_Click; + } + + /// + /// 自带的关闭按钮,可以重写 + /// 绑定RelativeForm才能生效 + /// + /// object? + /// EventArgs + protected virtual void ExitButton_Click(object? sender, EventArgs e) + { + RelativeForm?.Dispose(); + } + } +} diff --git a/Library/Component/ExitButton.resx b/Library/Component/ExitButton.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Library/Component/ExitButton.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Library/Component/GeneralForm.Designer.cs b/Library/Component/GeneralForm.Designer.cs new file mode 100644 index 0000000..a2e0fa3 --- /dev/null +++ b/Library/Component/GeneralForm.Designer.cs @@ -0,0 +1,57 @@ +namespace Milimoe.FunGame.Desktop.Library.Component +{ + partial class GeneralForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Title = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // Title + // + this.Title.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Title_MouseDown); + this.Title.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Title_MouseMove); + // + // GeneralForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(536, 284); + this.Controls.Add(this.Title); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Name = "GeneralForm"; + this.Text = "GeneralForm"; + this.FormClosed += FormClosedEvent; + this.Load += LoadEvent; + this.ResumeLayout(false); + } + + #endregion + + protected Label Title; + } +} \ No newline at end of file diff --git a/Library/Component/GeneralForm.cs b/Library/Component/GeneralForm.cs new file mode 100644 index 0000000..a092a00 --- /dev/null +++ b/Library/Component/GeneralForm.cs @@ -0,0 +1,104 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Library.Component +{ + public partial class GeneralForm : Form + { + protected int loc_x, loc_y; // 窗口当前坐标 + + public GeneralForm() + { + InitializeComponent(); + } + + /// + /// 绑定事件,子类需要重写 + /// + protected virtual void BindEvent() + { + + } + + /// + /// 鼠标按下,开始移动主窗口 + /// + /// + /// + protected virtual void Title_MouseDown(object sender, MouseEventArgs e) + { + //判断是否为鼠标左键 + if (e.Button == MouseButtons.Left) + { + //获取鼠标左键按下时的位置 + loc_x = e.Location.X; + loc_y = e.Location.Y; + } + } + + /// + /// 鼠标移动,正在移动主窗口 + /// + /// + /// + protected virtual void Title_MouseMove(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + //计算鼠标移动距离 + Left += e.Location.X - loc_x; + Top += e.Location.Y - loc_y; + } + } + + /// + /// 自定义窗体销毁方法 + /// + protected virtual void FormClosedEvent(object? sender, FormClosedEventArgs e) + { + if (GetType() != typeof(ShowMessage)) + { + Singleton.Remove(this); + if (GetType() == typeof(Main)) + { + RunTime.Main = null; + } + else if (GetType() == typeof(Login)) + { + RunTime.Login = null; + } + else if (GetType() == typeof(Register)) + { + RunTime.Register = null; + } + else if (GetType() == typeof(InventoryUI)) + { + RunTime.Inventory = null; + } + else if (GetType() == typeof(StoreUI)) + { + RunTime.Store = null; + } + else if (GetType() == typeof(RoomSetting)) + { + RunTime.RoomSetting = null; + } + else if (GetType() == typeof(UserCenter)) + { + RunTime.UserCenter = null; + } + Dispose(); + } + } + + /// + /// 窗体加载事件,触发BindEvent() + /// + /// + /// + protected virtual void LoadEvent(object? sender, EventArgs e) + { + BindEvent(); + } + } +} diff --git a/Library/Component/GeneralForm.resx b/Library/Component/GeneralForm.resx new file mode 100644 index 0000000..405ea9b --- /dev/null +++ b/Library/Component/GeneralForm.resx @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + \ No newline at end of file diff --git a/Library/Component/MinButton.Designer.cs b/Library/Component/MinButton.Designer.cs new file mode 100644 index 0000000..2baedd8 --- /dev/null +++ b/Library/Component/MinButton.Designer.cs @@ -0,0 +1,36 @@ +namespace Milimoe.FunGame.Desktop.Library.Component +{ + partial class MinButton + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Library/Component/MinButton.cs b/Library/Component/MinButton.cs new file mode 100644 index 0000000..3de3d8f --- /dev/null +++ b/Library/Component/MinButton.cs @@ -0,0 +1,66 @@ +using System.ComponentModel; + +namespace Milimoe.FunGame.Desktop.Library.Component +{ + public partial class MinButton : Button + { + public GeneralForm? RelativeForm { get; set; } + + public MinButton() + { + InitializeComponent(); + Anchor = System.Windows.Forms.AnchorStyles.None; + BackColor = System.Drawing.Color.White; + BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.min; + FlatAppearance.BorderColor = System.Drawing.Color.White; + FlatAppearance.BorderSize = 0; + FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray; + FlatAppearance.MouseOverBackColor = System.Drawing.Color.DarkGray; + FlatStyle = System.Windows.Forms.FlatStyle.Flat; + Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + ForeColor = System.Drawing.Color.Black; + Location = new System.Drawing.Point(750, 3); + Size = new System.Drawing.Size(47, 47); + TextAlign = System.Drawing.ContentAlignment.TopLeft; + UseVisualStyleBackColor = false; + + Click += MinForm_Click; + } + + public MinButton(IContainer container) + { + container.Add(this); + InitializeComponent(); + Anchor = System.Windows.Forms.AnchorStyles.None; + BackColor = System.Drawing.Color.White; + BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.min; + FlatAppearance.BorderColor = System.Drawing.Color.White; + FlatAppearance.BorderSize = 0; + FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray; + FlatAppearance.MouseOverBackColor = System.Drawing.Color.DarkGray; + FlatStyle = System.Windows.Forms.FlatStyle.Flat; + Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + ForeColor = System.Drawing.Color.Red; + Location = new System.Drawing.Point(750, 3); + Size = new System.Drawing.Size(47, 47); + TextAlign = System.Drawing.ContentAlignment.TopLeft; + UseVisualStyleBackColor = false; + + Click += MinForm_Click; + } + + /// + /// 自带的最小化窗口 + /// 绑定RelativeForm才能生效 + /// + /// object? + /// EventArgs + private void MinForm_Click(object? sender, EventArgs e) + { + if (RelativeForm != null) + { + RelativeForm.WindowState = FormWindowState.Minimized; + } + } + } +} diff --git a/Library/Component/MinButton.resx b/Library/Component/MinButton.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Library/Component/MinButton.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Library/Component/ShowMessage.Designer.cs b/Library/Component/ShowMessage.Designer.cs new file mode 100644 index 0000000..4828802 --- /dev/null +++ b/Library/Component/ShowMessage.Designer.cs @@ -0,0 +1,193 @@ +namespace Milimoe.FunGame.Desktop.Library.Component +{ + partial class ShowMessage + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShowMessage)); + this.MsgText = new System.Windows.Forms.Label(); + this.LeftButton = new System.Windows.Forms.Button(); + this.Exit = new FunGame.Desktop.Library.Component.ExitButton(this.components); + this.RightButton = new System.Windows.Forms.Button(); + this.MidButton = new System.Windows.Forms.Button(); + this.TransparentRect = new FunGame.Desktop.Library.Component.TransparentRect(); + this.InputButton = new System.Windows.Forms.Button(); + this.InputText = new System.Windows.Forms.TextBox(); + this.TransparentRect.SuspendLayout(); + this.SuspendLayout(); + // + // MsgText + // + this.MsgText.BackColor = System.Drawing.Color.Transparent; + this.MsgText.Font = new System.Drawing.Font("LanaPixel", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.MsgText.Location = new System.Drawing.Point(2, 51); + this.MsgText.Name = "MsgText"; + this.MsgText.Size = new System.Drawing.Size(232, 73); + this.MsgText.TabIndex = 100; + this.MsgText.Text = "Message"; + this.MsgText.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // LeftButton + // + this.LeftButton.Font = new System.Drawing.Font("LanaPixel", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.LeftButton.Location = new System.Drawing.Point(13, 127); + this.LeftButton.Name = "LeftButton"; + this.LeftButton.Size = new System.Drawing.Size(98, 37); + this.LeftButton.TabIndex = 1; + this.LeftButton.Text = "Left"; + this.LeftButton.UseVisualStyleBackColor = true; + this.LeftButton.Click += new System.EventHandler(this.LeftButton_Click); + // + // Exit + // + this.Exit.Anchor = System.Windows.Forms.AnchorStyles.None; + this.Exit.BackColor = System.Drawing.Color.White; + this.Exit.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("Exit.BackgroundImage"))); + this.Exit.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.Exit.FlatAppearance.BorderSize = 0; + this.Exit.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); + this.Exit.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); + this.Exit.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.Exit.Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.Exit.ForeColor = System.Drawing.Color.Red; + this.Exit.Location = new System.Drawing.Point(187, 1); + this.Exit.Name = "Exit"; + this.Exit.Size = new System.Drawing.Size(47, 47); + this.Exit.TabIndex = 3; + this.Exit.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.Exit.UseVisualStyleBackColor = false; + this.Exit.Click += new System.EventHandler(this.Exit_Click); + // + // RightButton + // + this.RightButton.Font = new System.Drawing.Font("LanaPixel", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.RightButton.Location = new System.Drawing.Point(125, 127); + this.RightButton.Name = "RightButton"; + this.RightButton.Size = new System.Drawing.Size(98, 37); + this.RightButton.TabIndex = 2; + this.RightButton.Text = "Right"; + this.RightButton.UseVisualStyleBackColor = true; + this.RightButton.Click += new System.EventHandler(this.RightButton_Click); + // + // MidButton + // + this.MidButton.Font = new System.Drawing.Font("LanaPixel", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.MidButton.Location = new System.Drawing.Point(65, 127); + this.MidButton.Name = "MidButton"; + this.MidButton.Size = new System.Drawing.Size(98, 37); + this.MidButton.TabIndex = 1; + this.MidButton.Text = "Middle"; + this.MidButton.UseVisualStyleBackColor = true; + this.MidButton.Click += new System.EventHandler(this.MidButton_Click); + // + // Title + // + this.Title.BackColor = System.Drawing.Color.Transparent; + this.Title.Font = new System.Drawing.Font("LanaPixel", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.Title.Location = new System.Drawing.Point(2, 1); + this.Title.Name = "Title"; + this.Title.Size = new System.Drawing.Size(179, 47); + this.Title.TabIndex = 97; + this.Title.Text = "Message"; + this.Title.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // TransparentRect + // + this.TransparentRect.BackColor = System.Drawing.Color.WhiteSmoke; + this.TransparentRect.BorderColor = System.Drawing.Color.WhiteSmoke; + this.TransparentRect.Controls.Add(this.InputButton); + this.TransparentRect.Controls.Add(this.InputText); + this.TransparentRect.Controls.Add(this.Title); + this.TransparentRect.Controls.Add(this.MidButton); + this.TransparentRect.Controls.Add(this.RightButton); + this.TransparentRect.Controls.Add(this.Exit); + this.TransparentRect.Controls.Add(this.LeftButton); + this.TransparentRect.Controls.Add(this.MsgText); + this.TransparentRect.Location = new System.Drawing.Point(0, 0); + this.TransparentRect.Name = "TransparentRect"; + this.TransparentRect.Opacity = 125; + this.TransparentRect.Radius = 20; + this.TransparentRect.ShapeBorderStyle = FunGame.Desktop.Library.Component.TransparentRect.ShapeBorderStyles.ShapeBSNone; + this.TransparentRect.Size = new System.Drawing.Size(235, 170); + this.TransparentRect.TabIndex = 103; + this.TransparentRect.TabStop = false; + // + // InputButton + // + this.InputButton.Font = new System.Drawing.Font("LanaPixel", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.InputButton.Location = new System.Drawing.Point(168, 130); + this.InputButton.Name = "InputButton"; + this.InputButton.Size = new System.Drawing.Size(66, 34); + this.InputButton.TabIndex = 2; + this.InputButton.Text = "OK"; + this.InputButton.UseVisualStyleBackColor = true; + this.InputButton.Visible = false; + this.InputButton.Click += new System.EventHandler(this.InputButton_Click); + // + // InputText + // + this.InputText.Font = new System.Drawing.Font("LanaPixel", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.InputText.Location = new System.Drawing.Point(2, 130); + this.InputText.MaxLength = 21; + this.InputText.Name = "InputText"; + this.InputText.Size = new System.Drawing.Size(163, 34); + this.InputText.TabIndex = 1; + this.InputText.Visible = false; + this.InputText.WordWrap = false; + this.InputText.KeyUp += new KeyEventHandler(this.InputText_KeyUp); + // + // ShowMessage + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.WhiteSmoke; + this.ClientSize = new System.Drawing.Size(235, 170); + this.Controls.Add(this.TransparentRect); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ShowMessage"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Show"; + this.TransparentRect.ResumeLayout(false); + this.TransparentRect.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private Label MsgText; + private Button LeftButton; + private ExitButton Exit; + private Button RightButton; + private Button MidButton; + private TransparentRect TransparentRect; + private Button InputButton; + private TextBox InputText; + } +} \ No newline at end of file diff --git a/Library/Component/ShowMessage.cs b/Library/Component/ShowMessage.cs new file mode 100644 index 0000000..1c07fa8 --- /dev/null +++ b/Library/Component/ShowMessage.cs @@ -0,0 +1,274 @@ +using Milimoe.FunGame.Core.Library.Constant; + +namespace Milimoe.FunGame.Desktop.Library.Component +{ + public partial class ShowMessage : GeneralForm + { + private MessageResult MessageResult = MessageResult.Cancel; + private string InputResult = ""; + private readonly int AutoClose = 0; + private readonly Task? TaskAutoClose; + + private const string TITLE_TIP = "提示"; + private const string TITLE_WARNING = "警告"; + private const string TITLE_ERROR = "错误"; + private const string BUTTON_OK = "确定"; + private const string BUTTON_CANCEL = "取消"; + private const string BUTTON_YES = "是"; + private const string BUTTON_NO = "否"; + private const string BUTTON_RETRY = "重试"; + + /// + /// 构造方法 + /// + /// /// 参数数组,按下面的注释传参,不要乱传 + private ShowMessage(params object[] objs) + { + InitializeComponent(); + Opacity = 0.85; // 透明度 + if (objs != null) + { + /** + * objs: + * 0 = title + * 1 = msg + * 2 = autoclose(second) + * 3 = button type + * 4 = mid text + * 5 = left text + * 6 = right text + */ + int length = objs.Length; + if (length > 0 && objs[0] != null) + { + Title.Text = (string)objs[0]; + Text = Title.Text; + } + if (length > 1 && objs[1] != null) + { + MsgText.Text = (string)objs[1]; + } + if (length > 2 && objs[2] != null) + { + AutoClose = (int)objs[2]; + } + if (length > 3 && objs[3] != null) + { + MessageButtonType type = (MessageButtonType)objs[3]; + switch (type) + { + case MessageButtonType.OK: + MidButton.Text = BUTTON_OK; + InputText.Visible = false; + InputButton.Visible = false; + LeftButton.Visible = false; + RightButton.Visible = false; + MidButton.Visible = true; + break; + case MessageButtonType.OKCancel: + LeftButton.Text = BUTTON_OK; + RightButton.Text = BUTTON_CANCEL; + InputText.Visible = false; + InputButton.Visible = false; + LeftButton.Visible = true; + RightButton.Visible = true; + MidButton.Visible = false; + break; + case MessageButtonType.YesNo: + LeftButton.Text = BUTTON_YES; + RightButton.Text = BUTTON_NO; + InputText.Visible = false; + InputButton.Visible = false; + LeftButton.Visible = true; + RightButton.Visible = true; + MidButton.Visible = false; + break; + case MessageButtonType.RetryCancel: + LeftButton.Text = BUTTON_RETRY; + RightButton.Text = BUTTON_CANCEL; + InputText.Visible = false; + InputButton.Visible = false; + LeftButton.Visible = true; + RightButton.Visible = true; + MidButton.Visible = false; + break; + case MessageButtonType.Input: + InputButton.Text = BUTTON_OK; + LeftButton.Visible = false; + RightButton.Visible = false; + MidButton.Visible = false; + InputText.Visible = true; + InputButton.Visible = true; + break; + } + if (length > 4 && objs[4] != null) MidButton.Text = (string)objs[4]; + if (length > 5 && objs[5] != null) LeftButton.Text = (string)objs[5]; + if (length > 6 && objs[6] != null) RightButton.Text = (string)objs[6]; + } + } + else + { + MessageResult = MessageResult.Cancel; + Dispose(); + } + if (AutoClose > 0) + { + TaskAutoClose = Task.Factory.StartNew(() => + { + Thread.Sleep(1); + string msg = MsgText.Text; + int s = AutoClose; + BeginInvoke(() => ChangeSecond(msg, s)); + while (s > 0) + { + Thread.Sleep(1000); + s--; + if (IsHandleCreated) BeginInvoke(() => ChangeSecond(msg, s)); + } + MessageResult = MessageResult.OK; + Close(); + }); + } + ShowDialog(); + } + + /// + /// 设置窗体按钮返回值 + /// + /// + private void SetButtonResult(string text) + { + MessageResult = text switch + { + BUTTON_OK => MessageResult.OK, + BUTTON_CANCEL => MessageResult.Cancel, + BUTTON_YES => MessageResult.Yes, + BUTTON_NO => MessageResult.No, + BUTTON_RETRY => MessageResult.Retry, + _ => MessageResult.Cancel + }; + TaskAutoClose?.Wait(1); + Dispose(); + } + + public static MessageResult Message(string msg, string title, int autoclose = 0) + { + object[] objs = { title, msg, autoclose, MessageButtonType.OK, BUTTON_OK}; + MessageResult result = new ShowMessage(objs).MessageResult; + return result; + } + + public static MessageResult TipMessage(string msg, string? title = null, int autoclose = 0) + { + object[] objs = { title ?? TITLE_TIP, msg, autoclose, MessageButtonType.OK, BUTTON_OK }; + MessageResult result = new ShowMessage(objs).MessageResult; + return result; + } + + public static MessageResult WarningMessage(string msg, string? title = null, int autoclose = 0) + { + object[] objs = { title ?? TITLE_WARNING, msg, autoclose, MessageButtonType.OK, BUTTON_OK }; + MessageResult result = new ShowMessage(objs).MessageResult; + return result; + } + + public static MessageResult ErrorMessage(string msg, string? title = null, int autoclose = 0) + { + object[] objs = { title ?? TITLE_ERROR, msg, autoclose, MessageButtonType.OK, BUTTON_OK }; + MessageResult result = new ShowMessage(objs).MessageResult; + return result; + } + + public static MessageResult YesNoMessage(string msg, string title) + { + object[] objs = { title, msg, 0, MessageButtonType.YesNo, BUTTON_CANCEL, BUTTON_YES, BUTTON_NO }; + MessageResult result = new ShowMessage(objs).MessageResult; + return result; + } + + public static MessageResult OKCancelMessage(string msg, string title) + { + object[] objs = { title, msg, 0, MessageButtonType.OKCancel, BUTTON_CANCEL, BUTTON_OK, BUTTON_CANCEL }; + MessageResult result = new ShowMessage(objs).MessageResult; + return result; + } + + public static MessageResult RetryCancelMessage(string msg, string title) + { + object[] objs = { title, msg, 0, MessageButtonType.RetryCancel, BUTTON_CANCEL, BUTTON_RETRY, BUTTON_CANCEL }; + MessageResult result = new ShowMessage(objs).MessageResult; + return result; + } + + public static string InputMessage(string msg, string title) + { + object[] objs = { title, msg, 0, MessageButtonType.Input }; + string result = new ShowMessage(objs).InputResult; + return result; + } + + public static string InputMessageCancel(string msg, string title, out MessageResult cancel) + { + object[] objs = { title, msg, 0, MessageButtonType.Input }; + ShowMessage window = new ShowMessage(objs); + string result = window.InputResult; + cancel = window.MessageResult; + return result; + } + + private void ChangeSecond(string msg, int s) + { + MsgText.Text = msg + "\n[ " + s + " 秒后自动关闭 ]"; + } + + private void LeftButton_Click(object sender, EventArgs e) + { + SetButtonResult(LeftButton.Text); + } + + private void RightButton_Click(object sender, EventArgs e) + { + SetButtonResult(RightButton.Text); + } + + private void MidButton_Click(object sender, EventArgs e) + { + SetButtonResult(MidButton.Text); + } + + private void InputButton_Click() + { + MessageResult = MessageResult.OK; + if (InputText.Text != null && !InputText.Text.Equals("")) + { + InputResult = InputText.Text; + Dispose(); + } + else + { + InputText.Enabled = false; + WarningMessage("不能输入空值!"); + InputText.Enabled = true; + } + } + + private void InputButton_Click(object sender, EventArgs e) + { + InputButton_Click(); + } + + private void InputText_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode.Equals(Keys.Enter)) + { + InputButton_Click(); + } + } + + private void Exit_Click(object sender, EventArgs e) + { + MessageResult = MessageResult.Cancel; + Dispose(); + } + } +} diff --git a/Library/Component/ShowMessage.resx b/Library/Component/ShowMessage.resx new file mode 100644 index 0000000..8ac3ecc --- /dev/null +++ b/Library/Component/ShowMessage.resx @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + + + iVBORw0KGgoAAAANSUhEUgAAAC8AAAAvCAYAAABzJ5OsAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAu + IgAALiIBquLdkgAAAQlJREFUaEPtmYEJwjAURDOSI3SUjtINOpKjOEr9h1Hyz9+E1haN3METif2Xp6CE + mpaUll55yt86pJC3x26Q/LfYLJ/SaEzEkD4I5qkPjOH+JTvkr/nakil77ArmqQ9cw/1LJC/5t85T5GcD + b6AEm+NLV3LJbi5Yp+sA5rlzDvcv2SwfsfLJZV8XrNN1YAp7W0he8kFvC8kbHFvBrwheYcKjRNTZRPIG + x1YkX0XyBsdWJF9F8gbHViRf5RD5hyiOCHsZwt4WB8lDwJ45dDCrInnJB70tNsuvbJ7ddgXz1Ad038Yj + eR/MUx+QvEfyPpinPiB5j+R9ME994BT5jv9Q+yX+S74/XvIdkpY7JUbXJnJZ8twAAAAASUVORK5CYII= + + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA + AAC8x9z/x9Tp/7zH3f+8wdv/xMrf/9nh6/+/xdb/3eTv/9PY5//T0uL/6OHu/+nl7f/X1uH/5+Pf/+jl + 3f/g4eP/5eft/+rp6//p5+f/6efi/+zo5P/u5+T/7ebj/+zm4//p4+X/4uHi/9zg4//e3N7/09HX//Px + 9//9+/v/4eDr/9TV6//e3ev/7+/y//Pv9P/+/Pz/9fH2/+fh6//X1+T/v77V/9bT3f/U09v/xsXP/9TQ + 2v/h3eb/39zk/97c5//d3Ob/3Nzn/6OqxP+cp8f/mqXI/8HG3f/L1ur/6fD7/9XZ5//q6u//9/b5/8nP + 2f/U2uX/1tri/7/H4P/P1er/ucTc/7rF3P/AxeD/x8vc/8fL2v/Cydj/2uPw/+Hq8f/Hy+H/6OLs/+Hb + 6P/Cv9n/z9Dg/+3q6f/o4+D/5eLh/+Tk5P/o5uf/6Obl/+nn4v/p5eD/7ebi/+rk3v/p5uD/5+Xj/+Di + 4v/c2tz/vr7N/6ipx//T0t//+/n6/+Ph7f/S0+P/8fH1/+zr8P/7+Pr/+fb3/+ji7P/n5PH/1tPl/8jL + 2P/Qztn/3tvl/9TR2v/j3+j/4d3l/+Db5f/a2OL/393n/93d6v+2u9b/zNHn/+Hq+P/j6/v/5e75/8/U + 6f/W2eX/7uzy//Ly9f/Hy9n/zNPg/+Lo7/+zutX/w8ni/7W/3f+st9T/ycri/8jH2f++wNj/1t3s/+Dn + 7//V3er/19Tk/9nX5f+2udT/4dro/8fF2v/k5Ob/7Ofk/+nl4v/n4uL/5uTi/+fl4//o5uH/6uXg/+zm + 3//s5+D/7Ojg/+nm4P/j4OD/wsLR/+Lf6v+vrcb/6+rz/9fW5P/Q0Ob/7ez1//Hu8//39/n//Pr7/+rm + 7f/r5fD/0c7j/+vo9f/T1eP/5OLt/9vY4//j3+j/5N/o/+Pf5//W0dz/29jj/9/e6f/h3+r/ztHh/87U + 6f+1udL/sLnU/7jC1//U1ub/9PL1//Px9v/j4uz/w8fc/8/W4P/K0dz/sbzV/7nF4P+nsM7/yM3j/83M + 3P/Kyt3/0Nbn/9ng6P/Z3ur/x8ve/9XV5P/BxNb/v73U/8fH2v/Z1uP/trXL/+rl4//r5uH/6OTf/+Xl + 3//j493/5+Xe/+vm3//r5d7/6eTe/+nl3P/m4dr/19LN/83J0//q4en/19Pi/9bT3v/o5O//2NXn//bz + 9v/x8fX/+/r8//Hu8//o4uz/3Nfj/8K91//p4u//3N3o/8jH1v/V0d7/5+Tt/+rl7P/X1d//0tPd/9/b + 5v/k3ub/yMrd/9XZ5f/Nz+T/xMXb/4ySsP/T1OL/5+Xp//Hv8//k5Ov/1Nbm/7zD3P+8xtb/tL7U/622 + z//BzOb/pa/L/8bH2//Oy9z/wcjb/9La4//K0+D/y9Hi//Lz9//h3On/2dbm/8jG2//k3uz/39jo/9LS + 5P/d2dz/6+Xh/+rl4f/n5N3/6OXe/+nk3P/q5d3/6eXc/+rn3f/l4db/4tvS/87Iv//Exs3/6+Xu/97d + 7P/X1OX/3NTl/9bZ6f/18fb/8fD0//n2+v/n5e3/5d3r/8nF2P/d2Oj/4dvl//f0+f+4u83/2dXg/+vp + 7//a2OH/z8/c/9fW4v/c2uT/3dzk/7K1zf/X2+n/x83h/8rJ3P+sr8n/t7zO/+Pl6v/r6fH/1NPf/9HV + 4/+6w9j/uMHU/7vF1/+vu9b/2d/v/7jB1f/Cxtr/ub/R/8TL1v/Cytb/vsfY/7vB1f/JyNn/xcTY/+bi + 6//LyN3/6uLv/9DP4f/49/n/2tjg/+vl3//o5N7/5uHa/+Tf1//j4NX/5N3T/9zUxf/Tybf/zcKs/8K4 + oP+xqpb/vr7K/9fS4v/g3en/zMzk/7Kz1P/v8PX/7ezx//36/P/07/b/5t/t/8O90v/Kx9n/7+ju//Ht + 9v/59vj/wcPV/97a5f/m5ez/ycnV/9HQ3f/a2+X/2tjj/9/c6f+fp8b/yM3m/9Ta6P/Bwdf/2tvl/4qR + pf/q6O//zc/c/9DT4f/J0N3/wMva/8HN2v+6xdn/1dnt//Lz+P+9ydz/rrjO/77H0v+/x9P/vMTR/8zQ + 2f/V1d7/2Nnm/7u80//Kyd7/3+Dy/9/e8f/LzOP/9fT3/9rZ4f/p5d//6eLd/+Pf1v/Oycz/xcTM/769 + wv+rqan/rKej/6Oemf+hmpf/h4OO/9PP3v/s5fD/4+Du/87Q3//V1er/8vP1/+np7f/08fX/5+Lr/9rT + 4f+3tcr/tKvF/9vT5v/r5/D/1tbj/9LO4f/d1+L/2Nvj/9TS3v/Rz9r/3d/p/97e6P/GyNz/uL7X/8/V + 5f/n7/X/ur/V/+nn7P+dpLb/pae6/8/Q4f/L0d//x9Lg/9Hb5//P2OX/1+Dw/+Pn7//8/Pz/qbXQ/8LP + 5v+vuM7/wcrU/62yzP/a1uH/29jh/8rL4P/OzOP/2drn//r6/P/y8/r/ys7j//Pz+f/CwNL/2NPN/9vU + y//AwsX/29rl/87Q3f/IzN3/pazD/9bX5v/a1eH/49nl/6qkwP/k3uz/8Ozy/9fX5//V1+X/8/H2/+/t + 8//y7/T/6OLr/+Xf6v/Mx9r/1M/e/+fj7//V1uX/y8zd/+ro8v/Kx9f/4+Lp/8jJ1f/Z1eL/1NDb/+Pg + 6//e4Or/t7zV/7/F2//Dy+H/5e31/83U4v/k5vD/x8zW/3aBmf+WoLn/i5iv/8LJ4P/X4Ov/1tvs/9Ta + 7P/e4ev//f39/7LB1/+3xdz/xNHl/5mowP/Cxdz/2dfh/93Z5v+1tdD/5eDt/9TT4//7+vr/7+3z/9LV + 5f/q5fP/w8Pb/66ko/+1saz/8/L0//z6+v/9+/v/+ff3/+zr8P/g3+j/4d7x/+Lc6v+5u9P/8O/1//Hv + 9v/V1uP/29vo//Xy9//o4+z/7uny/+rk7f/a1ub/v7rT/9rV5P/p5u//9/X3//j2+v/P0Nr/vr3R/+ro + 7//Jytb/2Nfk/9jT3//i4Oz/4eLs/77B2P/JzOH/uL/d/+Po9f/s7/b/v8TW/5Kbt/+Hj7D/jZm2/6i1 + zP+gqsX/zNLj/+Ll7//T2uf/2t7q//39/f+2xNj/vs3h/9fj8f/AzeP/tbvR/9zY5P/a2uP/pafA/8PD + 1//v8vb/+/n7/9vb5f/19/j/4+Lu/9fV5/+vq8D/ubjD//z5+//9+fr//fv6//bz9f/j3+r/7ez0/+bj + 9P/T0OH/6Ofz//r4/P/19Pb/2Nrl/9zd6f/p5ez/6ePt/+3o8f/p4e3/vLjO/9DL2//k4u7/8+73//jz + 9v/8+vr/09Xl/7O2zf/o5ev/5unu/8zO2f/X1uD/3Nzl/+Xo7/+/wtv/y87k/7zC3P/U3Oz/6u/2/7G4 + 0P+Vnb7/hpCw/4OMr/+HkLL/qLHJ/+ru8f/8+/z/xMre/+3v9f/8/Pz/2uHu/7fD3f/X4vH/2+fx/8TP + 3//DxNT/3trn/7q6zv+2us//y87f/8TF3f/U0+T/+vr4//P1+v/c2u3/087e/8G/0v/8+vv//vz8//z6 + +v/w7PH/49zs/8/N3v/z8fj/8fH4//37/P/+/f3//Pv8/9nb5f/Y1+b/3dfk/+3m7//p4u3/5uDt/8PA + 2P/Oydv/4uDs//z6+//7+vv/6+ju/8PF1f/m5e3/3drk/+zr8f/q7fP/zc/b/9bY4v/m6fD/3eTt/7G5 + 2P/HzuP/ys3h//Dw+P/Iz9//mqTF/4mVtf+5wNX/jJey/+Xl8P/7+vz/+vr8/8HH2f/8+/z//f39/77G + 4v+8yN//wM/k/93p8v/U3un/u8TT/83M3f/Lx9j/4dzl/+Ld5v/Kx9r/19fl//z8/P/6+/z/4+L1/+Hb + 6v/BvtL/+vj7//37/P/j4+n/29rl/9jT4f/Gxdj/3trm/+jn7f/39fb//fv7//38+//U1eL/09Dg/9rU + 4P/w6e7/6OHs/9jX5v/i4+7/5OLt/+Tl8f/8+/v/+ff7/9HQ3v/k4Oj/9PDz/9zY5P/h4Of/6+zy/+nr + 8f/Lzdf/4eTs/+js8v/S2en/qrTU/9fb7v/l7fP/6fL4/9fg7/+yvdL/gpCr/5+qv//4+Pz/+/v9/9zd + 6P/f4+z/+/76//39/f+ls9L/t8Xc/7nJ4f/Czd//ytTg/8LO1/+sscf/xsXZ/+DY5f/f2uX/1dPh/8XF + 2v/o6PH//Pv8/+vp+f/f3Ov/zc3e//P09v/9/Pz//fv8//v6+//m5u//ycfZ/97Y5//Y0+T/yczb/+vs + 8v/39vv/ysva/9XX5v/f2+r/497o/9nS3v++uM3/9/P5//v7+f/z8/n/+fr7//T09//V1OT/49/n//Ds + 8//W0Nv/29ji/+jn8P/o6O//6Onz/9TX4//r7/T/7O/1/9Da6//CzOP/4+72/+Pv9f/m8ff/4Orz/87Z + 5v/HzOH/+vv8/+rp8v/Eyt3/+vv8//v+/P/+/v7/uMTe/6Syzv/BzOL/v8zf/7fF3P+yvsv/n6a+/7/B + 1P/Rzt3/3tnk/9zY4//OzN//0tLj/+zp9P/m5fP/z9Hg//Dx9f/9+/z/+/r7//r5+f/a2uf/0M/i/9vZ + 6v/R0Ob/0dLp/93e8P/Iydz/vsHP/6itwf/X2eT/6ejx/9XS4P/SzN3/0Mze/+Db6v/19Pb//fz8//v4 + +f/i4+r/1dTf/+fj6//r5+7/0s7a/9nT3v/b2eT/6enx/+bk8P/e3un/5OTu/+7w8v/n6/L/2N3q/9LZ + 6//j7/b/2+fy/9vq9f/T3+j/vMPY/8jM4P/V2uf/5Obu//7+/v/+/v7//v7+/7zK4P+8yN//tsHa/8HN + 5P+uu9f/sLnO/5CXqP+3us3/ysvY/9bU3v/b1+H/yMjY/7u+1P/c2er/4Nzs/9TT4f/5+/r//fz9/+vs + 8f/Extn/29jp/+zl8v/r5fH/6Of3//Hy+v/18fb/2Nbq/77F2v+Qma//wcXR//n6+f/28/j/zMjb/+fg + 7f/Kyt//ubzR/8zL3f/R0d3/0NDh/8PC1f+7vs//ubnM/8XBzv/f2OL/yMfT/9rd4v/h4ev/4d/q/9fV + 4v/q7PH/5urx/9nc5f/k5/P/1+Ds/97s9f/N2Ob/z9vm/8bR4P+2wNv/u7/Z/+rq8v/9/f3//f3+//7+ + /v/G0+L/rrvU/8fR5v/L1un/qrTX/7e/1/+VnrD/p6rE/9XV4f/Kydj/0NDc/9LR3f+vtMr/2dTm/8bI + 2v/29fj/7Oz1/9PU4f+0tdL/4uHu/+ji7v/s5O//7Ofx/+/s8v/39Pj/+fb5/9bX6f/d3u3/zNLg//Tz + +f/8/Pz//Pv6/8zO3v/u6vP/3dvr/8TG2//b1+H/4Nzj/9zX5v++wtL/zM/c/77D3f+mrMT/y8fX/9rV + 4f++vcj/397p/93c5v/Sz9z/6OXv/+jq7f/d3Oj/5uXu/+Xm8v/R1uj/1+Lt/8TP3f/G093/vcjj/8TK + 5/+4wd3/+vr9//39/f/+/v7/0dvo/8HN5P+/yeH/0tzr/8HN5f+2wNz/jJWs/7S50P/S1OL/wsbX/7m6 + zv/Rzdv/u77S/8bH2v+8wNb/0djj/8vO4P/g5Oz/vcHT/+nk7v/p4+7/7eXz/+vk8f/z8Pf/8fH1/9bZ + 5v/Kzd3/x8fd/5Wcq//FyNT/+vr7//n6+v/g4Of/5OLs//Lt9v/HyNz/1NPf/8TD1f+lpsP/0Mzg/8zM + 3P/h3er/uLjN/8TG2f/OzNf/xcHN/87N1//X1uD/1tPf/93Z5P/r7PD/29vl/9/e6f/y8/f/1dbj/8fR + 5P++ytj/vcjY/7rG4v/Ey+P/u8Le//Tz+f/9/f7//v7+/9Db4v/Y4u7/tMHZ/8/Y6f/h6/b/w87l/5ae + v//Axd3/2Njl/8bI2v+1uc3/xMXV/7O50P/Dz+H/rLXU/9ve5//S0t3/2Nrl/8/L3P/q5O7/6+Tw/+rl + 7v/m4vL/z9Pm/7fB3P/f5vX/4efv/9Xa6v+zu8//1tvk//z7/P/t7fL/7+/1/8/Q4v/W1OX/zcve/9TV + 3v/MzNr/zdDa/7O3zv/Bwt3/1NLh/+ni7f/q5+7/vbnO/8TDzf/Pztn/0tHb/9XS3f/W0t3/6enu/9/g + 6P/f3Oj/4+Dq/+Pj6P/f4+//yNTh/7XA0P+4w9//0dTq/8fO4v/08/n//Pz7//39/f/Y4Or/2ODr/9Xa + 5//O1ef/4+z1/8/Z6f+7wtv/tL3W/83Q4P/Kztn/vcHO/7O0zf+4wtf/z9vu/5qixv/Izdj/09rk/72+ + 0P/n4O7/x8XW/9HP5P/Cwtj/wMXg/8jO6P/W3/P/ucHe/5WfyP/KzOT/39/t/7zC2P/JyNb/xsnc/8LI + 1v+wuNL/zs3f/9/d6//b1+T/0c3Z/8zJ0//i4e7/vr/Y/7W41P/f2+f/5ODr/9nU4/+wsML/0tDb/8zK + 1f/PzNf/1dHc/+jn7P/i5Oz/2trl/+Hf6P/Y1uT/+fn5/9DV4/+8xdb/ucji/87S7P/Cx9r/+Pr8//3+ + /f/+/v3/2+Ls/87W4P/U2OL/5Ozz/9zg8P/Bydz/z9Xm/8nV5v+3wtf/yMrY/7+/z/+hpsL/2OPx/8fS + 6P+utdD/zdDa/9Xa4/+2us//wsDX/7O41P+lrcz/sbnZ/9PZ7/+vt9b/v8nm/7G52P/JzOL/r7PN/7q9 + 2P/OzN//qKvB/9na6P/Fytr/rLHH/727yf/j3+n/5OHq/9TR2//NydP/6OXu/83N3P/AxN7/zcrf/+Dc + 5v/j3ur/q6zE/7650P/U0Nn/yMfR/9vW4f/j4un/3d/o/9jZ4//l5Oz/2dji//Tx9v/Hydj/uMTZ/9Dd + 8v/AxN3/1dbm//39/f/+/v7//f39/9PZ4//W2+X/y87Y//Py9//c3u3/y9Hm/8TL3P/d6PL/ztnr/7W9 + z/+2tMz/uL/W/+Dn7/+2v9v/wsjb/9vc5v/U2OP/ys7a/8jM4P/Nzub/pa3O/9Pa8f+wudz/z9jv/83T + 6v/Dx+P/p6bK/72+2f/Kx93/xsXe/6mqyP+3utH/5+v2/+zz/P/V3ev/trvN/8vM2//U0dz/4N7l/93b + 5f/i4ev/yMnc/8bG2//c2OL/4Nvn/7i70P+lqML/1M/b/8bFz//h3On/5OHr/9nZ4//e3ub/29rj/+jo + 7v/g3eb/vL/R/7zI4f/j7Pr/1dvp/+ns8f/+/v7//v7+//7+/v/b3ej/2drk/9HS3v/f4Ov/yMzh/+bs + 9P/FzOH/3uXu/9zi7P/Aydn/pazC/83U4//Cxtv/oKnH/9TZ5//d3Of/0NPe/9na6P/Gx+H/naXL/7bC + 4//R1u3/ucLg/+Pp+f+4vt3/nKDH/7Sz2//Iwdv/pqXH/7K30P/i5fD/7fH4//Dz/P/r8v3/6vP8/+nx + +f/a4vD/w8ve/7u/1v/T0+D/4t/o/8nI2//c2uf/3tnm/9vW4//Fxtf/urnS/7S1zf/LyNL/4t/p/+He + 6f/Z2eP/4eDo/83N2f/r6PD/5ODp/6uzzP/f5/n/4uj1/9fa5f/9/P7//v7+//7+/v/+/v7/0dXf/9jX + 4f/S1uD/wMPW/8nP4v/K0eL/wsXd/9vi7P/Y3uj/m6W0/7G50f/Dxtv/tLrY/7W/1f/Q1OH/2tvm/8/P + 3P/Mzd//w8rj/5Ccyf/M1u//vsXg/+Ho+v/V3PD/nqHH/5+jyv+zsc//qKvK/9fa7f/u8vr/8PL7/+/z + /f/t8vv/7vP8/+nw+v/q8fv/6PD6/+30+//h6Pb/xs7g/7q7y//ExdT/3Nbk/97a5f/Y0+L/1tTh/7+7 + 0/+bnr7/zcvU/+Hf5f/c2uX/3Njj/+He6P/Nzdr/6ebr/8jO3v/Y4fL/4ur4/8zT5//j5ez//v7+//7+ + /v/+/v7//v7+/7O80P/O0Nr/rLLC/7e+0f/T1+r/vMLX/97g6f/Fyt3/qbC8/6y0xP+2utH/vL7W/7O4 + 0f/N0+L/ztHf/83O2//R0d3/ycvf/7e93f+hq9D/2OH1/9LY7//c5vb/usPg/5mi0f+ZnsD/wMff/+rx + +v/s8/v/7fT8/+3z/P/t8/z/7fP8/+30/f/u9Pz/7PT9/+rz/f/q8fr/8PT8//H0+//r7vb/v8PX/8nH + 2//Z1uH/19Lg/9vX4/+8utP/pqjD/8jI2f/i3ub/0dLd/9rX4v/d2uX/0tHd/9La6f/Z5PL/5e77/8vS + 6f/M0eL/+fn8//3+/P/+/v7//f39//7+/v/Aydn/pa3B/6Wswv++yNn/xMri/8PI2v/U0tn/srrH/4+X + rP+nsL//y8vZ/8DE2f/Hydn/1djj/8vN2f/GxNL/0tDc/8DE2/+wtdj/tb3d/9rh9P/T2O3/1+Dx/5+m + yv+ordf/3ePz/+vx+f/s8/z/7PT8/+z1/f/r9P3/6/T9/+zz/P/h6PD/7PH6/+71/f/u9f7/8Pf9/+32 + /P/w9v3/8/b9//P1/P/N1OP/wsPU/9TR3v/c2uT/vcDV/7S2zv+/wtj/4d7p/8/Q3P/Z1+L/3Nnl/7/B + 0f/d5PD/5O/3/8rV7P/Z4O//2tvp//39/f/9/f3//v7+//7+/v/9/f3/uMHN/7a90P+qssb/yM/d/6iv + zP/V1eL/0dHb/5acr/+fprf/qbHD/8/O3v+7vdL/zMzd/9Xb5f/CwtD/x8XS/9jU4P+yt8//rLLT/6+7 + 2f/S3O//zNPm/9bf9P+PmLz/vcDg/+3y/P/v9P3/7fP8/+30/f/s9P3/6vP8/+v0/f/q8/z/1Nzo/9LX + 5P/x9/3/8ff+/+72/f/v9v3/8vf9//D1/P/y9fz/7fH8/8HG2//Hx9j/wL/O/7a4y/+pq8j/v8HY/+Pi + 6f/Q0d3/2tjh/8fF1v/S2+f/6e/3/8vV6//X3+z/29/q//L0+P/+/v7//v7+//39/f/+/v7//v7+/7fA + zf+vtsn/srnL/83V4f+bpsD/1dTf/83N2/+Yorf/rLXE/7G5yv+5u9T/09Ph/8bI2//c4un/ur3K/87M + 2P/X09//oafE/7nA2v+qt9H/y9Xo/8vW6P/F0uv/qbPY/8XH5f/p7/v/6vD8/+zz/P/t9f3/7fX9/+31 + /P/u9v3/7fT9/+31/f/v9P3/8Pb8//H2/f/v9fz/7/b9//H2/v/s9P3/5e37/+Hr+//d5fr/q7PN/8nK + 3f+Nk7P/pajL/6Gkxf/DxtX/1dLc/83N2//Bx9n/4Orz/83V6f/Q3Or/5Obv/9/i6v/9/fv//v7+//7+ + /v/+/v7//v7+//7+/v/Fztr/srzN/7K7zv/J0Nz/r7jN/83O2v/JzNr/oq2//7e/zP/Dy9v/ubvd/+Tg + 6P/L0N3/297q/8DFzf/Qz9v/1NPf/5ulwv+9w9v/qbXP/8jR6P/I1Ob/vMrl/6m32f/S1vD/6vD8/+zy + /v/s8/z/7fT9/+zy/f/s8/3/7vX+/+30/f/v9f3/8PX+/+/0/P/w9v3/8Pb9/+/1/P/u9fz/6PH7/97o + +v/a4fr/1dz6/6ix0//P0+f/vcHU/5GZuv+3vNP/q7HG/8bE1P+zvM7/0tro/9Xc6//Y4e//xMzi/73B + 1//o6fL//f39//7+/v/+/v7//v7+//7+/v/+/v7/19/q/7jE0f+zv9X/y9Hb/8vP4P+6vdL/y87b/6u2 + x//DzNn/y9Te/8LJ4P/HyNr/yM3h/9XV5P/S1uD/ysnW/9PR3v+krsf/wMba/7O/1//AyuD/ytfo/6y5 + 2v+uuNr/0NXw/9PX7v/h5vP/8PX+//D2/v/s8/3/6fL9/+z0/f/u9v3/8Pf9//D2/f/x9v7/8vj+//L3 + /v/w9/3/7PX8/+Tv/P/Y5Pz/z9r7/8nT+v+9yPD/rbfV/8jO4v+Um8D/rbTN/7W5zv+vts3/ucXa/9je + 6v/I0+P/0tnu/8LI2//X3un/3d/u//7+/v/+/v7//v7+//7+/v/+/v7//v7+/9rf6v/N1eT/tb/Z/9HZ + 4v/e5O7/wcbb/8/R4P+1vdL/ydLf/83W4//d5PH/v8TX/52lwv+ss8z/4eTv/8TF0P/Lytf/srrR/83V + 4//BzOD/uMPX/8jU5f+tueD/pq3W/5OVxf+rttv/4+r8/+71/v/v9f7/6/P9/+rz/f/u9P3/8PX9//H3 + /v/v9f7/8Pb9//H3/v/x9v3/7vT7/+rz/f/d6vz/09/5/83X+//G0fr/wcz5/5Sdwf/HzOP/kpvE/6Ws + x//Gyt7/s7jN/7jB1v/K0+L/ztjq/7e/1P/3+fr/1tvp/97h7P/+/v7///////7+/v/+/v7//v7+//7+ + /v/x8vb/09Xi/77D2f/X3e3/3eLs/9Xc6//Bxtn/wMfg/9HZ5v/R2ef/3ebx/8DF2//Z2+b/oqnE/8PH + 2f/GyNL/w8TV/7O60//P1+L/wcvf/7XA1f/I0+j/sbzl/4GJu/+Qm8z/ztr8/9nj/f/n7/z/6/P9/+zz + /v/s9P7/7vT9//D2/f/v9fz/8ff+//H3/v/x9/7/8ff9/+3y/f/l7/v/1+P8/7rD7/+/yPj/xtH1/8PN + /P+yu+b/oqnH/6WszP+vs8z/usHV/7O90f+/xt7/v8ve/7/K2//P0+H//fv7/9Xa6//e4ev//f79//7+ + /v/9/f3//v7+//7+/v/9/f3/+/z9/+rs8//Hytn/xs3e/+Hp8//p8Pn/xMzc/8fP4P/Q1+v/2d/y/9zg + 8P/Z3+7/w8TV/9fa5/+or8z/x8ra/73A0P/IzuT/0tvm/7/I3v+1v9X/xdDm/7C74f99h7v/v8r0/8rV + +//R2vr/4uv9/+z0/f/r8/3/6vP8/+3z/f/x9v7/8ff+//H3/v/x9/7/8ff9//L4/f/v9P3/6e/9/7/J + 8f+9yfb/ucXx/8LI7//O0fj/v8b2/6Gszf+lrsz/o6fF/7/F2P+6wtb/vMbb/7zI3/+wutD/8/X6//T1 + +P/T1ej/5+rv//3+/v/9/f3//v7+//7+/v/+/v7//v7+//39/f/8/f3/4eHo/9PW5P/Y4e//4e71/+Ps + 9P/Byt3/vcfg/97l9v/c4/L/6ez5/8rP4f/U1eT/t7nR/7q/1v+/wtT/1d3s/8/Z5v+/yt//t8LY/8TP + 5v+kr9b/orDg/8nT+v/K0/v/0Nf6/9je+v/k6/r/7fT9/+rz/f/t9P7/7/X9/+72/f/v9v3/7/b9/+70 + /f/u9f7/7PP8/9/f9//QzuT/xsbS/83M1v/MzdX/vrzE/7O16f+mq9P/lZ69/56kyP/Fy97/srrW/7zK + 3v+1v9b/vcXX//n7+//V2OX/2dvq//r7/P/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/+fb6//Hx + 9//Y2eT/1djl/93n8v/e6/L/3+nz/6+82v/N1u7/4uz3/9zm8v/l7Pj/v8LY/8/R5f+ytM3/mJ25/97l + 9//W4e7/yNHl/8HO4f/H0ur/q7bc/6++6f/H0vr/wMz6/6mv5f+mreH/t77w/+jv/P/r8vz/7PL9/+/2 + /f/u9P3/6u74/+/z/f/w8/3/7fP8/+/0+v/a2+7/s6KQ/5mCa/+rmYT/u6yf/6ydkf+4tsr/kJDB/4mP + sv+ao8P/z9Pn/6y11P++yuL/t8LW/8rQ3//39/v/193t/+Dg6v/9/f7//v79//7+/v/+/v7//f39//7+ + /v/9/f3/5unv/9jc7//W2/D/2Nvr/97d6f/P1Of/2uTy/97n8v/a4vL/p7DT/+Pr+f/e5vL/4Ofy/9/i + 7/++v9j/urvO/52iwv/b5PX/1eHu/9Pd7v/L1uj/xNDn/7bB4P+/ye//u8Hp/7vA3//Iy9v/ys7f/83R + 5//S0t//6Oz3/9Xd7v/R1+7/0dnu/9LW6v++yOP/tsHb/7jC3P/b4e//wcff/5eOlf94Z1j/i3Zb/6mU + fv+OhHX/uLa//4iIpv9ucIr/mZ+7/87S5P+6wtz/t8HY/7K7z//a3+v/5uXw/9DW5//4+Pv//v7+//39 + /f/9/f3//f39//7+/f/9/f3/9fP0/9/h7v/g5vz/1tvp/97h7f/d3en/xMfd/8nR4v/Q2Of/09zn/8XN + 5P+7x+D/5Oz4/9rj7v/g6PH/xsra/6ytx/+jqcv/3Of3/9fi8f/Z4/P/0drr/7zI4P+8wOH/sbLZ/6Cb + pf+/t6f/wrWj/8a5q//Pxbz/v7W0/87N2/+9xeD/xc3q/9HY9P+osdj/r7TZ/73G5P/DyOT/2t3v/8vQ + 5P+nrc7/kpKq/3NpcP+Gdmj/bWlx/2xtiP9obIn/g4ep/6Goxv/P0ej/usLZ/7/I2f+6w9b/3eLs/9rb + 7//Z3Oj/+/z7//39/f/+/v7//f39//7+/f/9/fz/+Pn4/9DT1f/m5vL/2d3x//X2+f/7+/r/+Pf4/9fU + 5f+wttP/0djp/8jQ3f/L0+L/q7bT/9Xf7f/c5O7/2uDr/+Hn8P+ipsH/s7XU/9vo8v/V3+7/2+f0/9Ld + 6/+/yuL/sbTV/4uMt/+Og3r/qJB0/5yFZf+vmHj/xK+U/6qbkP/ExNT/oKXH/6Os1P/X2/f/19z6/8TJ + 5v+0u+D/rLLV/9zg8//N1O3/nKPL/8PJ4f+nrdD/houp/3+Apv91gKr/lJi5/6euzf+xttP/0NTr/8HI + 3//L0eH/vMTX/9PX5//T2Oz/0tPi/+Hh7v/8/P3//f39//39/f/9/f3/8vL0/9vb3P/p7ev/7e/1/9LV + 5//6+v3/+/v8//z6/P/i4uz/srfU/7G41P/T1uL/ys/e/8HI2/+nss//3OTv/9zl7v/c5e3/zNLk/73F + 2v/d6fL/0Nzq/9nm8//S3+7/t8Xb/46Qsv9vcZH/kIiR/4VuW/+AaVP/n4Zm/6CHa/98dXT/gomk/6On + yP+QmMH/wcXm/9fc+f/d4fj/ucPn/7vC5f+3vdz/2+H3/6Oqz/+4u9f/4eL0/9ji8//L0eb/maDE/8rQ + 5/+zudX/w8zh/9DW6/+7xNv/19vs/7rB2f/JzuT/4+Pu//Dy9v/JzOL/9vj7//7+/v/+/v7/+/z9/+Lk + 5//Y2tv/6u3q//v7+//e3+v/7e7z//j5+v/U2Oj/uMHb/7rD3/+nr87/w8bZ/8vM2v/N0N//rrjU/7vE + 3P/b4u7/2uLs/93k7v/Eytj/2+bw/8nW5P/T4u//ydjp/7zI3v+cpcT/aG6R/2Vohf9kZGz/Z2Bg/2dd + XP9dWmT/Vltz/4SMrP+hp8b/oaXJ/7W84P/W2vH/1dnw/9Pc9P+xut//pKzS/9bb9P/K0u//p7LV/9ja + 8f/o7Pf/7fD2/7G11P+4vNj/srfU/8zV6f/N0+n/wcXe/9rg7//ByOT/zdDh//j4+//2+Pn/zdDk//Dy + 9f/+/v7//v7+//7+/v/3+Pj/3d/e/+Pm5P/8/Pz/+Pj6/+Ph7P/d3+7/1try/9TY8f/R0+v/2Nvw/8/V + 6f+1utP/zdLh/8LL3v+Xpcf/09vr/9fh6//T3Ob/zNPk/9Te6//I1uL/y9vn/8bU5//I0+T/tsHZ/5uq + zP+WnMn/foSv/4SNr/9ob5H/dXyj/6Wt1f/Aw97/vMPb/4qPtP+3w+D/zdfr/8zX6//M1ur/usTi/7G9 + 3v++yeX/zdju/8TQ6//Fzuj/4ef1/+js+P+3udb/vcTc/7e91v/L0+f/x8/j/77E2//Y3uz/ytPo/9HV + 5v/8+/3/+vv7/8/S4v/6+vv//v7+//39/f/+/v7/+/z8/9ja2f/d4d///f39//z7/f/a3e3/z9Pn/9nd + 6f/h5vD/x8vZ/8DB1//Cwtj/ztXr/7rA2P/P2OX/rbnV/7rE3P/W4Or/yNLd/9Da6f/C0OH/yNTg/8XV + 4f+5yNr/wM3g/77H3f+uuNb/q7LW/7nC3f+nr9X/rbfU/6Kp0f+9wuL/3t/y/9/c8v+qsMz/tr/a/8rW + 6P/H1Of/xNDj/8XU5/+yvdz/rbjY/8XQ5//J0+z/w8rp/+ju+f/m6/j/uLnV/7e/1/+rssv/w8ze/7zE + 1v+1vNL/193s/8TM4v/R1Ob//Pv9//v7/f/Q0uP//f39//7+/v/+/v7//f39//P09P/X2tj/19vZ//z8 + /f/n6PL/1Nrr/+ns8f/g3+f//Pr8/+zs9P/Oz9v/0c/a/7y+0/+3v9X/xczd/8TO3v+rtdL/1uHv/8nU + 4f/J1OL/tsHW/8XP3v/Bztr/tcHS/6q3z/+qtM//rbfY/6q20//Fz+X/r7XU/8jP5v+ttdX/oafT/9TZ + 8P/n5fT/0M7j/6Krzf+8x+D/ws7g/73J2//D0OL/sr7X/7K83P/Ay+H/u8fc/7vD4//f5fb/1trp/6qv + zP+5wNb/o63F/7rE1f+2vtD/s7zO/8/Y5P+7w9//2Nrl//38/P/y9Pj/2dzp//39/f/9/f3//v7+//z8 + /f/g4eH/6Orn/9rc3P/8/fz/5ujz//v7+//8/Pv/6uzx/+nr8P/6+vz/z9Ld/9DR3v/Iydj/yMvb/6Gv + y//FzN7/s73V/9Db7P/M2OT/wcza/6660f++yNf/vsrV/7jC0/+2xNP/rbnR/5mnxf+Vnr7/vcTf/7/G + 3f+0utb/vcff/6Oq0/+7w+L/6e35/9fU5/+mq83/rbjT/7bC1v+8yNr/ucTW/6u2zf+wvNT/usXZ/7fC + 1f+0vdn/2+D4/9/h8/+ttNL/tb7W/5ulvP+xu8z/srrM/623yP/Gz+D/vsbf/9vd5f/7+Pr/3uDq//Hz + +P/9/f3//f39//39/f/u7u//6evj/+Tm3//s7vD//f38//v7+//9/Pz//Pz8//r8/P/p6O//5ubu/9jc + 5P/W1+L/1NXi/8nJ2P/Hzd3/mqW8/8vT5/+9yN3/yNbi/7nG1v+ruM7/vMnY/7vH0/+3wNH/rrnO/665 + y/+eqcb/lJ++/5KYu/+wuND/qLHL/7fA1P+irMv/oqrL/83R5f/NzeL/o6rE/6GrxP+quNL/v8zd/7C7 + y/+wuc7/r7nM/7bB0v+0vtD/sr3T/87V7//Qz+f/qrDR/7nA1v+iqL3/r7fJ/621x/+stcb/xM/i/7S6 + z//i5en//Pz8/97g6f/9/f3//v7+//7+/f/19vT/5ebg//Dy5P/k4+D//Pz9//39/f/8/Pz//Pz8//z8 + /P/8/Pz/+/r8/9HU3v/d3uv/x8nW/9nd6P/IzNn/09Tg/77E1f+pscX/u8fd/8HP2/+4xdX/pLDG/7vH + 1/+yv8v/srvK/6izx/+5xNb/lJ67/5qkvP+Pmrn/lKC+/6Krx/+vuNL/r7nP/52ryv/ByeX/zc7g/6Cl + wP+tuM3/n6vK/6+80v+wvM3/uMLS/7C6y/+zvc//s7zP/7TA1P/M0+7/wr/b/6y00v+7wtX/pazB/6y1 + x/+stcj/q7bI/8TO4f+mrMD/4ePp//f3+v/j5Oz//f39//39/f/9/Pz/5ubh//Hy5f/n5d7/+Pb2//39 + /f/8/Pz//Pz8//z8/P/8/Pz//f39//z9/f/q7O//x8vZ/9HS4f/d4+3/2N7o/9PT4P/Hy9v/vMPU/6Kt + yP++zNj/usfX/6GtwP+0wdD/rrnH/6u2xf+ircT/vcjY/5iivP+eqMD/l5+8/6auxP+lrcf/oqvF/7e9 + 1P+ZosP/tr3b/8zN4f+jpsX/tL7S/6Gsxv+wvNj/sb3R/7bA0P+3wtH/s73O/7S9z/+yvdL/v8fi/728 + 2P+wuNX/ucDU/6Wtw/+tuMv/q7bK/7O/0f+9xdb/r7XE/+Pk7v/h4ev/+Pf6//39/f/8/Pz/8vLv/+7t + 4//u7uT/5uXi//39/f/+/v7//v7+//7+/v/9/f3//f39//z8/P/8/Pz/+fr6/8/T3P++wdD/4Ofv/9/j + 8P/S1eP/0dbl/8TL2f+osc3/r7zQ/7rF1f+jrr3/o6/C/7C6y/+uucr/m6S+/7rG0/+jrcT/rrjO/5eh + v/+rtMr/qLDG/6+50v+osMj/oqvH/7G61P+9vtn/panH/7O+0/+yv9L/qbbT/6i0yP+yvM7/ucPV/7TC + 1P+3xNX/s77S/6620v+1s9L/tLzZ/7nB0/+uuM3/t8HT/7vE1v/By93/uL7O/8jL3P/m5/H/zdHi//z7 + /f/+/f3//v7+/+bm4//r7OP/4+Tc//r7+v/9/f3//Pz8//39/f/9/f3//v7+//39/f/8/Pz//Pz8//z8 + /P/t7vH/zM3c/9DX4f/f5vH/19vp/9nd7P/K0t//ytTk/5qlx/+0wNX/nqu7/5iiuP+ossT/q7XH/5qk + vf+0wM7/rrjM/7nD1f+msMv/rbjP/7a/0v+mscr/tsHW/6ixyP+nscj/q6/O/6mry/+zwtr/tsPW/6u4 + z/+7xdz/t8LX/8PQ3v+0wtX/u8jb/7zH1/+nr8z/razO/8HH4P/Cytr/wsze/8XP3P/P1+f/0Njn/8bL + 3P/R0+T/4uXw/+Hk7//9/f3//f39//39/f/Z2db/5+jg/9/f2v/9/f3//f39//z8/P/+/v7//v7+//z8 + /P/9/f3//f39//z8/P/7+/v/+vv7/9PU3//U1ej/3ubz/9vk8f/V3On/1dzs/9Tb6/+3wdn/m6bE/6Wv + wf+Klq3/q7XH/6qzxf+eqMD/sL7O/7S/0f+9x9n/r7rP/7C+1f++ytr/sr7U/7/I3P+yu9D/p7LM/6uy + zP+rr87/vMrg/8TO4P+8x9v/rbjV/7K+0v/N2er/vcvd/8DN4P+/ytj/rrbR/6Kkyf/P1Ov/xszg/8XP + 4f/X3+v/1dzq/9Tb6//a3u7/1tnq/87S4f/3+fz//v7+//39/f/7/Pz/1NbU/+fn4v/l5uP//f39//39 + /f/9/f3//f39//7+/v/9/f3//v7+//39/f/8/Pz//vz8//v7+//z8/X/19jn/9ji7f/f6PX/2ODt/9ff + 8f/U2+//0tvs/6awz/+Xn7n/hpCk/6y2yf+rtMb/o63E/6u5yf+xvc//vcja/7jE1/+wwNr/ytXn/7zI + 2/+uuM//0tnq/6izyv+2vtP/pKjI/8XQ5f/N1ub/ws7f/6i00P+1wtr/1N3t/8vW5//J1ef/yNPk/7a+ + 2P+nq9L/09vt/8TJ3v/FzeH/2ODr/9Td6v/V3e3/5ef2/87S4//e4ez//f39//39/f/9/f3/+/v7/9HU + 0//m5uH/4uPg//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/8/Pz//f39//7+/v/8/Pz//P39/+Di + 6f/b4e3/5ev4/+Ln9P/c4/P/xtDm/9jg7f/By9//nKfB/4WQpf+eqb3/srrL/6myx/+qtsf/sb/Q/7G9 + 1f/E0uX/rr3Z/87Z7f/L1uj/ytXn/7O90//FzeL/vcbb/5+lw//I0uX/0Nro/8vX6P++yuH/ssLb/8fP + 4v/Q2er/zNnq/83a7P+zvdb/t73a/87V5P/HzuD/xM3e/9Dc5v/R2+z/197v/+Pk8//M0OT/8/T4//39 + /f/+/v7//v7+//39/v/U2tr/5efi/9ze2//+/v3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39 + /f/9/f3//v7+//39/f/z9fj/4OHu/+Ln9f/g6fb/2+Xv/8fP5//V2u3/197t/7XB1v+Vn7n/lqG2/7jB + 0v+zvND/rrrL/7rG1v+ntNH/y9rr/7jG4f/N2vD/0tzu/9zg8P+8xdr/ydPl/7rC2/+lrsv/yc/k/9Xe + 7v/P2uv/0tzt/7bD3/+9xtz/1d7u/8/c7f/Q3vD/srzV/73H2v/Fzd3/w87f/8TO3v/P2uX/0tzs/97k + 9P/c2+v/19jp//z8/P/+/v7//f39//39/f/9/v7/2+Dg/+bp5f/X2tj/+Pr4//7+/v/+/v7//f39//7+ + /v/+/v7//f39//39/f/+/v7//v7+//39/f/9/f3//Pz9/+Tk6//e4e//4Oj3/9ri8f/T2u3/xc7h/9Xd + 7P/J1ej/t8HY/46Ysv/BzN7/wszd/7nE1f/G0OL/tsLY/8XS6v/K2O7/ytnv/9Pf8f/T2+n/1+Du/622 + 1P/R3Or/l6LC/77G3P/U3uz/zdfo/9Ld7/+4wt7/wszk/9ff8P/O2uz/0eDy/666z//L0+P/v8jX/77J + 2v/Ez97/z9nl/9Ha6f/b3+7/xsnh//Dx9//+/v3//f79//7+/v/+/v7//f39/+Ll5v/e5OT/5uvq/97h + 4P/9/fz//f39//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/9/f3//f39//39/v/09Pf/4OLs/9re + 7//X3e//zNbo/83W5//U3uz/zdvq/7jG2/+lss//t8LX/9Lc6f/Ez93/ztbo/8zX5v+5xuD/1ODy/87b + 7//U4PL/z9no/9vj8f+6xNv/xM7l/6+91P+3wdf/1t/w/8zX6f/S3/H/u8je/83Y7//DzOH/ytrr/9He + 8v+yvND/y9bi/7O90P+4wtT/wczb/9Hb6f++x9z/0dTo/87S5P/7/fv//v79//3+/f/+/v7//v7+//7+ + /v/5+/v/0tfa/+zw7v/h5uf/8vPz//39/f/9/f3//f39//39/f/9/f3//f39//7+/v/9/f3//f39//7+ + /v/+/v7//Pz8/+vr8P/g4fD/1Nzv/7rF4//M1+f/zNrp/8PS3P/Ay+D/sb3U/7nB2v/c4fL/0Njo/83V + 5v/a4vP/wMvi/9bh9P/P3e//0+Hz/87b7f/Y4e7/ztjp/6u11f/N2+r/s77X/9Pd7//J1ef/y9nr/8XT + 5v+/zuT/uMXe/8rY6v/S3/D/s7zS/8jT4P+wus7/t8LS/8LP2//O2eb/p7HP/7vA3f/19/r//f39//7+ + /v///////v7+//7+/v/+/v7//v7+/+nr7//m7O7/7PL0/+Lp7f/o6ez//v7+//39/f/+/v7//f39//39 + /f/9/f3//f39//7+/v/9/f3//f39//z8/P/6+fv/4ODs/9fd7v+4xeD/usng/8LS4P+8y9X/vs3Z/6y5 + zv+1v9P/0Nfq/9zh7v/V3e3/2eLy/9fh8f/L1+z/ztzu/83b7f/O2+3/0Nrs/9DZ6v+zwtb/zdjr/7G+ + 1//K1ej/ws7g/8XT5f/C0OD/s8Db/7XB3P/K1ub/1eHt/7C6z/+4wdf/s77O/7jD0f/Bzdj/s77U/7K5 + 1P/V3On/+/z8//39/f/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7/4ufs/+nw+P/t9v3/5u/1//7+ + /v/+/v7//f39//39/f/+/v7//f39//7+/v/+/v7//f39//7+/v/9/f3//f39//Du8//f4e3/1t3u/6y3 + 1v+0w9P/t8TR/7jE0P+xu8z/p7HG/7S+0v/f5PH/2uPw/9Td6//d5vT/zdnu/8vZ7P/K2Or/ytjq/8fW + 5f/N2Ob/x9Pk/7PB2P/N1+n/s8DT/8DN2/+9y9v/tsbX/6m40/+7yd7/wtDg/8rY5f+qtcv/sb3R/7G8 + zf+2ws3/vcbZ/6qz0P/Cyd//+Pr8//39/f/9/f3//f39//7+/v/+/v7//v7+///////+/v7//v7+//z9 + /f/i5+//4er0/+v1/v/9/f3//f39//7+/v/9/f3//Pz8//39/f/+/v7//v7+//39/f/9/f3//Pz8//39 + /f/8+/z/29vh/97e6//Ezd//prTH/6SwwP+krb3/o66+/56twP+fq7//zdjq/9fg7v/T3On/197r/9Tc + 7//H1en/xtTl/8PR4//Az97/x9Ti/8PR3f+ruc//zdjq/7O/0/+9ytn/v8ra/7HB0P+iscz/v8/l/7jG + 2v/Dz+H/nqfC/6exx/+yvcr/t8TS/6evyv+2vdv/3+Xu//z8+//9/f3//f39//7+/v/+/v7//v7+//7+ + /v///////v7+//7+/v/9/v7//f79/+rt8v/W4Oj//f39//39/f/9/f3//v7+//39/f/9/f3//v7+//7+ + /v/9/f3//v7+//7+/v/+/v7//f39//X2+P/X1uH/2tvm/7nD1v+frb3/m6Wz/5ijsf+dqLb/pbDC/7G8 + z//U3e3/1t/s/8bO3P/b4O//vMnh/77P3v/Az9//v8/e/77L2P/AzNj/tMHS/7C/1P+9ytv/rbzQ/7XC + 0v+qt8r/nanD/7zK3/+wutP/u8jc/6Kswf+stsb/sr7K/6q1yf+stNP/xc3k//r7+//9/f7//Pz8//7+ + /v/+/v7//v7+//7+/v////////////7+/v/+/v7//v7+//7+/v/+/v7//f3+//7+/v/8/Pz//f39//39 + /f/+/v7//v7+//7+/v/+/v7//v7+//z8/P/+/v7//v7+//39/f/7/Pz/6ert/9LS3f/U2eb/sbnN/7q/ + 0/+bprv/kpyy/5unuP+ap7r/zdXo/9Tc7f/I0eD/zdbj/8bR5f+xwNf/u8nY/7nG1v+5xdP/u8fS/7C9 + yv+Ypr//x9Pg/6GuyP+wucv/pbLF/5Ohuf+zwdf/pbHL/6+70v+ttMb/sLnI/7G7zf+usc3/v8Lc//b2 + +//9+/v//fz9//7+/v/9/f3//v7+//////////////////7+/v/+/v7///////////////////////7+ + /v/9/f3//Pz8//39/f/9/f3//v7+//7+/v/9/f3//v7+//7+/v/+/v7//f39//39/f/9/f3//f39//z8 + /P/f3+n/u8DS/87S3v/Z2uf/4+Tw/+Tn8f+nsMT/mKS0/664zP/T2uj/0Nzn/73G1f/L1uL/qLbQ/6+6 + yv+yvs7/rbfI/7G7zP+ns8T/l6S6/7G9zv+ltcn/pK/C/5unuv+Pn7T/s8DV/6i0zv+osMj/sbnL/6m0 + x/+ssMv/srXR/+bq8f/7+/v/+/v7//z8/P/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//// + ///+/v7//v7+//39/f/+/v7//f39//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//v7+//7+ + /v/9/f3//Pz8//79/f/9+/v/0NTh/9vf6/+rssb/5ubt/8XH2/+/xdj/2t7o/5ieuf+Uobf/yNLk/9Hc + 5v/Czd7/vcfX/8XR4f+eq8L/pbDC/6GqvP+hq7z/oa2//5ypvf+lssb/s7/Q/52pvf+WorT/kJyy/7XB + 1P+rtc7/pa3E/6CrwP+vtMv/rrDL/8rO4f/7+vr//f39//7+/v/+/v7//v7+//7+/v/+/v7///////// + ///+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ + /v/+/v7//v7+//7+/v/9/f3//f39//7+/v/+/f3/+/n8/83S4P/Kz97/3eDr/7S4z/+qr8X/yMvf/8rR + 4v/GzeL/4OXv/6ayyv/Y4ez/ydbl/7rF1f/G0t3/tsLV/5upvf+cprj/mqK0/5ynuf+WorT/n6m8/7/K + 2f+Tn7P/n6i6/5mitv+2wdL/naO//52lvf+rrsT/pKbB/8DE2f/29/r/+vn7//z8/P/9/f3//v7+//7+ + /v/+/v7//v7+///////+/v7///////7+/v/+/v7//v7+//7+/v///////v7+//7+/v/9/f7//v7+//7+ + /v/+/v7//v7+//7+/v/+/v7//f39//7+/v/+/v7//v7+//3+/v/+/v7//vz8//z7+/+7wdj/xsnf/+fq + 9f/Axdr/ys/h/622y//q6vT/r7fP/8nK3P+psMr/xs3f/87b6f/Ez9//uMLS/7/L1/+stsz/lKC0/5ad + rv+bpLT/nae5/6Gpu/+3wNP/qbTL/7vB0//Kz9z/q63G/6OkwP+srMf/lZi5/7K3z//09Pj//f39//39 + /f/+/v7//v7+//7+/v/+/v7//f39//7+/v///////v7+//7+/v/+/v7///////7+/v/+/v7///////7+ + /v//////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/Library/Component/TextArea.Designer.cs b/Library/Component/TextArea.Designer.cs new file mode 100644 index 0000000..d1079ca --- /dev/null +++ b/Library/Component/TextArea.Designer.cs @@ -0,0 +1,36 @@ +namespace Milimoe.FunGame.Desktop.Library.Component +{ + partial class TextArea : RichTextBox + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Library/Component/TextArea.cs b/Library/Component/TextArea.cs new file mode 100644 index 0000000..5fe714b --- /dev/null +++ b/Library/Component/TextArea.cs @@ -0,0 +1,108 @@ +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace Milimoe.FunGame.Desktop.Library.Component +{ + [ToolboxBitmap(typeof(TextBox))] + partial class TextArea : RichTextBox + { + private string _emptyTextTip = ""; + private Color _emptyTextTipColor = Color.DarkGray; + private const int WM_PAINT = 0xF; + + public TextArea() : base() + { + + } + + [DefaultValue("")] + public string EmptyTextTip + { + get { return _emptyTextTip; } + set + { + _emptyTextTip = value; + base.Invalidate(); + } + } + + [DefaultValue(typeof(Color), "DarkGray")] + public Color EmptyTextTipColor + { + get { return _emptyTextTipColor; } + set + { + _emptyTextTipColor = value; + base.Invalidate(); + } + } + + protected override void WndProc(ref Message m) + { + base.WndProc(ref m); + if (m.Msg == WM_PAINT) + { + WmPaint(ref m); + } + } + + private void WmPaint(ref Message m) + { + using (Graphics graphics = Graphics.FromHwnd(base.Handle)) + { + if (Text.Length == 0 + && !string.IsNullOrEmpty(_emptyTextTip) + && !Focused) + { + TextFormatFlags format = + TextFormatFlags.EndEllipsis | + TextFormatFlags.VerticalCenter; + + if (RightToLeft == RightToLeft.Yes) + { + format |= TextFormatFlags.RightToLeft | TextFormatFlags.Right; + } + + TextRenderer.DrawText( + graphics, + _emptyTextTip, + Font, + base.ClientRectangle, + _emptyTextTipColor, + format); + } + } + } + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr LoadLibrary(string lpFileName); + protected override CreateParams CreateParams + { + get + { + CreateParams prams = base.CreateParams; + if (LoadLibrary("msftedit.dll") != IntPtr.Zero) + { + prams.ExStyle |= 0x020; // transparent + prams.ClassName = "RICHEDIT50W"; + } + return prams; + } + } + + public void AppendImage(string filename) + { + //Bitmap + Bitmap bmp = new(filename); + //Bitmapд + Clipboard.SetImage(bmp); + this.Paste(); + } + + public void AppendImage(Bitmap image) + { + Clipboard.SetImage(image); + this.Paste(); + } + } +} \ No newline at end of file diff --git a/Library/Component/TextArea.resx b/Library/Component/TextArea.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/Library/Component/TextArea.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Library/Component/TransparentRect.Designer.cs b/Library/Component/TransparentRect.Designer.cs new file mode 100644 index 0000000..38596e3 --- /dev/null +++ b/Library/Component/TransparentRect.Designer.cs @@ -0,0 +1,36 @@ +namespace Milimoe.FunGame.Desktop.Library.Component +{ + partial class TransparentRect + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Library/Component/TransparentRect.cs b/Library/Component/TransparentRect.cs new file mode 100644 index 0000000..2171994 --- /dev/null +++ b/Library/Component/TransparentRect.cs @@ -0,0 +1,116 @@ +using System.Drawing.Drawing2D; + +namespace Milimoe.FunGame.Desktop.Library.Component +{ + partial class TransparentRect : GroupBox + { + public enum ShapeBorderStyles + { + ShapeBSNone, + ShapeBSFixedSingle, + }; + private ShapeBorderStyles _borderStyle = ShapeBorderStyles.ShapeBSNone; + private Color _backColor = Color.Black; + private Color _borderColor = Color.White; + private int _radius = 20; + private int _opacity = 125; + protected int pointX = 0; + protected int pointY = 0; + protected Rectangle iRect = new Rectangle(); + public TransparentRect() + { + base.BackColor = Color.Transparent; + SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true); + SetStyle(ControlStyles.Opaque, false); + UpdateStyles(); + } + public new Color BackColor + { + get { return _backColor; } + set { _backColor = value; Invalidate(); } + } + public ShapeBorderStyles ShapeBorderStyle + { + get { return _borderStyle; } + set { _borderStyle = value; this.Invalidate(); } + } + public Color BorderColor + { + get { return _borderColor; } + set { _borderColor = value; Invalidate(); } + } + public int Opacity + { + get { return _opacity; } + set { _opacity = value; this.Invalidate(); } + } + public int Radius + { + get { return _radius; } + set { _radius = value; this.Invalidate(); } + } + public override Color ForeColor + { + get { return base.ForeColor; } + set { base.ForeColor = value; this.Invalidate(); } + } + protected override void OnPaint(PaintEventArgs e) + { + SmoothingMode sm = e.Graphics.SmoothingMode; + e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; + if (_borderStyle == ShapeBorderStyles.ShapeBSFixedSingle) DrawBorder(e.Graphics); + DrawLabelBackground(e.Graphics); + e.Graphics.SmoothingMode = sm; + } + private void DrawBorder(Graphics g) + { + Rectangle rect = this.ClientRectangle; + rect.Width--; + rect.Height--; + using (GraphicsPath bp = GetPath(rect, _radius)) + { + using (Pen p = new Pen(_borderColor)) + { + g.DrawPath(p, bp); + } + } + } + private void DrawLabelBackground(Graphics g) + { + Rectangle rect = this.ClientRectangle; + iRect = rect; + rect.X++; + rect.Y++; + rect.Width -= 2; + rect.Height -= 2; + using (GraphicsPath bb = GetPath(rect, _radius)) + { + using (Brush br = new SolidBrush(Color.FromArgb(_opacity, _backColor))) + { + g.FillPath(br, bb); + } + } + } + protected GraphicsPath GetPath(Rectangle rc, int r) + { + int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height; + r = r << 1; + GraphicsPath path = new GraphicsPath(); + if (r > 0) + { + if (r > h) { r = h; }; + if (r > w) { r = w; }; + path.AddArc(x, y, r, r, 180, 90); + path.AddArc(x + w - r, y, r, r, 270, 90); + path.AddArc(x + w - r, y + h - r, r, r, 0, 90); + path.AddArc(x, y + h - r, r, r, 90, 90); + path.CloseFigure(); + } + else + { + path.AddRectangle(rc); + } + return path; + } + } +} \ No newline at end of file diff --git a/Library/Config/Config.cs b/Library/Config/Config.cs new file mode 100644 index 0000000..76138b7 --- /dev/null +++ b/Library/Config/Config.cs @@ -0,0 +1,28 @@ +namespace Milimoe.FunGame.Desktop.Library +{ + public class Config + { + /** + * FunGame Desktop Configs + */ + public static bool FunGame_isAutoConnect { get; set; } = true; // 是否自动连接服务器 + public static bool FunGame_isAutoLogin { get; set; } = false; // 是否自动登录 + public static bool FunGame_isMatching { get; set; } = false; // 是否在匹配中 + public static bool FunGame_isConnected { get; set; } = false; // 是否连接上服务器 + public static bool FunGame_isRetrying { get; set; } = false; // 是否正在重连 + public static bool FunGame_isAutoRetry { get; set; } = true; // 是否自动重连 + public static bool Match_Mix { get; set; } = false; // 混战模式选项 + public static bool Match_Team { get; set; } = false; // 团队模式选项 + public static bool Match_HasPass { get; set; } = false; // 密码房间选项 + public static string FunGame_Roomid { get; set; } = "-1"; // 房间号 + public static string FunGame_ServerName { get; set; } = ""; // 服务器名称 + public static string FunGame_Notice { get; set; } = ""; // 公告 + public static string FunGame_AutoLoginUser { get; set; } = ""; // 自动登录的账号 + public static string FunGame_AutoLoginPassword { get; set; } = ""; // 自动登录的密码 + public static string FunGame_AutoLoginKey { get; set; } = ""; // 自动登录的秘钥 + + /*** GUID For Socket ***/ + public static Guid Guid_Socket { get; set; } = Guid.Empty; + public static Guid Guid_LoginKey { get; set; } = Guid.Empty; + } +} diff --git a/Library/Config/Constant.cs b/Library/Config/Constant.cs new file mode 100644 index 0000000..5256c31 --- /dev/null +++ b/Library/Config/Constant.cs @@ -0,0 +1,74 @@ +using System.Text; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Milimoe.FunGame.Desktop.Library +{ + public class Constant + { + /** + * Game Configs + */ + public static int FunGameType { get; } = (int)FunGameInfo.FunGame.FunGame_Desktop; + + /** + * Socket Configs + */ + public static string Server_Address { get; set; } = ""; // 服务器IP地址 + public static int Server_Port { get; set; } = 0; // 服务器端口号 + public static Encoding Default_Encoding { get; } = General.DefaultEncoding; + + /** + * FunGame Configs + */ + public const string GameMode_Mix = "混战模式"; + public const string GameMode_Team = "团队模式"; + public const string GameMode_MixHasPass = "带密码的混战模式"; + public const string GameMode_TeamHasPass = "带密码的团队模式"; + + public const string FunGame_PresetMessage = "- 快捷消息 -"; + public const string FunGame_SignIn = "签到"; + public const string FunGame_ShowCredits = "积分"; + public const string FunGame_ShowStock = "查看库存"; + public const string FunGame_ShowStore = "游戏商店"; + public const string FunGame_CreateMix = "创建游戏 混战"; + public const string FunGame_CreateTeam = "创建游戏 团队"; + public const string FunGame_StartGame = "开始游戏"; + public const string FunGame_Connect = "连接服务器"; + public const string FunGame_ConnectTo = "连接指定服务器"; + public const string FunGame_Disconnect = "登出并断开连接"; + public const string FunGame_DisconnectWhenNotLogin = "断开连接"; + public const string FunGame_Retry = "重新连接"; + public const string FunGame_AutoRetryOn = "开启自动重连"; + public const string FunGame_AutoRetryOff = "关闭自动重连"; + public static readonly object[] PresetOnineItems = + { + FunGame_PresetMessage, + FunGame_SignIn, + FunGame_ShowCredits, + FunGame_ShowStock, + FunGame_ShowStore, + FunGame_CreateMix, + FunGame_CreateTeam, + FunGame_StartGame, + FunGame_Disconnect, + FunGame_AutoRetryOn, + FunGame_AutoRetryOff + }; + public static readonly object[] PresetNoLoginItems = + { + FunGame_PresetMessage, + FunGame_DisconnectWhenNotLogin, + FunGame_AutoRetryOn, + FunGame_AutoRetryOff + }; + public static readonly object[] PresetNoConnectItems = + { + FunGame_PresetMessage, + FunGame_Connect, + FunGame_ConnectTo, + FunGame_Retry, + FunGame_AutoRetryOn, + FunGame_AutoRetryOff + }; + } +} diff --git a/Library/Config/RunTime.cs b/Library/Config/RunTime.cs new file mode 100644 index 0000000..b3998f1 --- /dev/null +++ b/Library/Config/RunTime.cs @@ -0,0 +1,24 @@ +namespace Milimoe.FunGame.Desktop.Library +{ + /// + /// 运行时单例 + /// 插件接口可以从这里拿Socket和窗体 + /// + public class RunTime + { + public static Core.Library.Common.Network.Socket? Socket { get; set; } = null; + public static Controller.RunTimeController? Connector { get; set; } = null; + public static UI.Main? Main { get; set; } = null; + public static UI.Login? Login { get; set; } = null; + public static UI.Register? Register { get; set; } = null; + public static UI.StoreUI? Store { get; set; } = null; + public static UI.InventoryUI? Inventory { get; set; } = null; + public static UI.RoomSetting? RoomSetting { get; set; } = null; + public static UI.UserCenter? UserCenter { get; set; } = null; + + public static void WritelnSystemInfo(string msg) + { + Main?.GetMessage(msg); + } + } +} diff --git a/Library/Config/Usercfg.cs b/Library/Config/Usercfg.cs new file mode 100644 index 0000000..1f50765 --- /dev/null +++ b/Library/Config/Usercfg.cs @@ -0,0 +1,13 @@ +using Milimoe.FunGame.Core.Entity; + +namespace Milimoe.FunGame.Desktop.Library +{ + public class Usercfg + { + /** + * 玩家设定内容 + */ + public static User? LoginUser { get; set; } = null; // 已登录的用户 + public static string LoginUserName { get; set; } = ""; // 已登录用户名 + } +} diff --git a/Model/InventoryModel.cs b/Model/InventoryModel.cs new file mode 100644 index 0000000..7e1359a --- /dev/null +++ b/Model/InventoryModel.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Model +{ + public class InventoryModel + { + } +} diff --git a/Model/LoginModel.cs b/Model/LoginModel.cs new file mode 100644 index 0000000..0457a77 --- /dev/null +++ b/Model/LoginModel.cs @@ -0,0 +1,142 @@ +using System.Data; +using System.Windows.Forms; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Library.Component; + +namespace Milimoe.FunGame.Desktop.Model +{ + /// + /// 请不要越过Controller直接调用Model中的方法。 + /// + public class LoginModel : BaseModel + { + private static SocketObject Work; + private static bool Working = false; + + public LoginModel() : base(RunTime.Socket) + { + + } + + public override void SocketHandler(SocketObject SocketObject) + { + try + { + if (SocketObject.SocketType == SocketMessageType.Login || SocketObject.SocketType == SocketMessageType.CheckLogin) + { + Work = SocketObject; + Working = false; + } + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + } + + public static async Task LoginAccountAsync(params object[]? objs) + { + try + { + Socket? Socket = RunTime.Socket; + if (Socket != null && objs != null) + { + string username = ""; + string password = ""; + string autokey = ""; + if (objs.Length > 0) username = (string)objs[0]; + if (objs.Length > 1) password = (string)objs[1]; + if (objs.Length > 2) autokey = (string)objs[2]; + password = password.Encrypt(username); + SetWorking(); + if (Socket.Send(SocketMessageType.Login, username, password, autokey) == SocketResult.Success) + { + string ErrorMsg = ""; + Guid CheckLoginKey = Guid.Empty; + (CheckLoginKey, ErrorMsg) = await Task.Factory.StartNew(GetCheckLoginKeyAsync); + if (ErrorMsg != null && ErrorMsg.Trim() != "") + { + ShowMessage.ErrorMessage(ErrorMsg, "登录失败"); + return false; + } + SetWorking(); + if (Socket.Send(SocketMessageType.CheckLogin, CheckLoginKey) == SocketResult.Success) + { + DataSet ds = await Task.Factory.StartNew(GetLoginUserAsync); + if (ds != null) + { + // 创建User对象并返回到Main + RunTime.Main?.UpdateUI(MainInvokeType.SetUser, new object[] { Factory.GetInstance(ds) }); + return true; + } + } + } + } + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + + return false; + } + + public static (Guid, string) GetCheckLoginKeyAsync() + { + Guid key = Guid.Empty; + string? msg = ""; + try + { + while (true) + { + if (!Working) break; + } + // 返回一个确认登录的Key + if (Work.Length > 0) key = Work.GetParam(0); + if (Work.Length > 1) msg = Work.GetParam(1); + if (key != Guid.Empty) + { + Config.Guid_LoginKey = key; + } + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + msg ??= ""; + return (key, msg); + } + + private static DataSet GetLoginUserAsync() + { + DataSet? ds = new(); + try + { + while (true) + { + if (!Working) break; + } + // 返回构造User对象的DataSet + if (Work.Length > 0) ds = Work.GetParam(0); + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + ds ??= new(); + return ds; + } + + private static void SetWorking() + { + Working = true; + Work = default; + } + } +} diff --git a/Model/MainModel.cs b/Model/MainModel.cs new file mode 100644 index 0000000..eb19ce2 --- /dev/null +++ b/Model/MainModel.cs @@ -0,0 +1,256 @@ +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Model +{ + public class MainModel : BaseModel + { + private readonly Main Main; + private string LastSendTalkMessage = ""; + + public MainModel(Main main) : base(RunTime.Socket) + { + Main = main; + } + + #region 公开方法 + + public bool LogOut() + { + try + { + // 需要当时登录给的Key发回去,确定是账号本人在操作才允许登出 + if (Config.Guid_LoginKey != Guid.Empty) + { + if (RunTime.Socket?.Send(SocketMessageType.Logout, Config.Guid_LoginKey) == SocketResult.Success) + { + return true; + } + } + else throw new CanNotLogOutException(); + } + catch (Exception e) + { + ShowMessage.ErrorMessage("无法登出您的账号,请联系服务器管理员。", "登出失败", 5); + Main.GetMessage(e.GetErrorInfo()); + Main.OnFailedLogoutEvent(new GeneralEventArgs()); + Main.OnAfterLogoutEvent(new GeneralEventArgs()); + } + return false; + } + + public bool IntoRoom(string roomid) + { + try + { + if (RunTime.Socket?.Send(SocketMessageType.IntoRoom, roomid) == SocketResult.Success) + return true; + else throw new CanNotIntoRoomException(); + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo()); + RoomEventArgs args = new(roomid); + Main.OnFailedIntoRoomEvent(args); + Main.OnAfterIntoRoomEvent(args); + return false; + } + } + + public bool UpdateRoom() + { + try + { + if (RunTime.Socket?.Send(SocketMessageType.UpdateRoom) == SocketResult.Success) + return true; + else throw new GetRoomListException(); + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo()); + return false; + } + } + + public bool QuitRoom(string roomid) + { + try + { + if (RunTime.Socket?.Send(SocketMessageType.QuitRoom, roomid) == SocketResult.Success) + return true; + else throw new QuitRoomException(); + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo()); + RoomEventArgs args = new(roomid); + Main.OnFailedQuitRoomEvent(args); + Main.OnAfterQuitRoomEvent(args); + return false; + } + } + + public bool CreateRoom() + { + try + { + if (RunTime.Socket?.Send(SocketMessageType.CreateRoom) == SocketResult.Success) + return true; + else throw new QuitRoomException(); + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo()); + RoomEventArgs args = new(); + Main.OnFailedCreateRoomEvent(args); + Main.OnAfterCreateRoomEvent(args); + return false; + } + } + + public bool Chat(string msg) + { + LastSendTalkMessage = msg; + try + { + if (RunTime.Socket?.Send(SocketMessageType.Chat, msg) == SocketResult.Success) + return true; + else throw new CanNotSendTalkException(); + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo()); + SendTalkEventArgs SendTalkEventArgs = new(LastSendTalkMessage); + Main.OnFailedSendTalkEvent(SendTalkEventArgs); + Main.OnAfterSendTalkEvent(SendTalkEventArgs); + return false; + } + } + + public override void SocketHandler(SocketObject SocketObject) + { + try + { + switch (SocketObject.SocketType) + { + case SocketMessageType.GetNotice: + SocketHandler_GetNotice(SocketObject); + break; + + case SocketMessageType.Logout: + SocketHandler_LogOut(SocketObject); + break; + + case SocketMessageType.HeartBeat: + if ((RunTime.Socket?.Connected ?? false) && Usercfg.LoginUser != null) + Main.UpdateUI(MainInvokeType.SetGreenAndPing); + break; + + case SocketMessageType.IntoRoom: + SocketHandler_IntoRoom(SocketObject); + break; + + case SocketMessageType.QuitRoom: + break; + + case SocketMessageType.Chat: + SocketHandler_Chat(SocketObject); + break; + + case SocketMessageType.UpdateRoom: + SocketHandler_UpdateRoom(SocketObject); + break; + + case SocketMessageType.Unknown: + default: + break; + } + } + catch (Exception e) + { + RunTime.Connector?.Error(e); + } + } + + #endregion + + #region SocketHandler + + private void SocketHandler_GetNotice(SocketObject SocketObject) + { + if (SocketObject.Length > 0) Config.FunGame_Notice = SocketObject.GetParam(0)!; + } + + private void SocketHandler_LogOut(SocketObject SocketObject) + { + Guid key = Guid.Empty; + string? msg = ""; + // 返回一个Key,如果这个Key是空的,登出失败 + if (SocketObject.Parameters != null && SocketObject.Length > 0) key = SocketObject.GetParam(0); + if (SocketObject.Parameters != null && SocketObject.Length > 1) msg = SocketObject.GetParam(1); + if (key != Guid.Empty) + { + Config.Guid_LoginKey = Guid.Empty; + Main.UpdateUI(MainInvokeType.LogOut, msg ?? ""); + Main.OnSucceedLogoutEvent(new GeneralEventArgs()); + } + else + { + ShowMessage.ErrorMessage("无法登出您的账号,请联系服务器管理员。", "登出失败", 5); + Main.OnFailedLogoutEvent(new GeneralEventArgs()); + } + Main.OnAfterLogoutEvent(new GeneralEventArgs()); + } + + private void SocketHandler_IntoRoom(SocketObject SocketObject) + { + string roomid = ""; + if (SocketObject.Length > 0) roomid = SocketObject.GetParam(0)!; + if (roomid.Trim() != "" && roomid == "-1") + { + Main.GetMessage($"已连接至公共聊天室。"); + } + else + { + Config.FunGame_Roomid = roomid; + } + RoomEventArgs args = new(roomid); + Main.OnSucceedIntoRoomEvent(args); + Main.OnAfterIntoRoomEvent(args); + } + + private void SocketHandler_UpdateRoom(SocketObject SocketObject) + { + List? list = SocketObject.GetParam>(0); + list ??= new List(); + Main.UpdateUI(MainInvokeType.UpdateRoom, list); + } + + private void SocketHandler_Chat(SocketObject SocketObject) + { + SendTalkEventArgs SendTalkEventArgs = new(LastSendTalkMessage); + if (SocketObject.Parameters != null && SocketObject.Length > 1) + { + string user = SocketObject.GetParam(0)!; + string msg = SocketObject.GetParam(1)!; + if (user != Usercfg.LoginUserName) + { + Main.GetMessage(msg, TimeType.None); + } + Main.OnSucceedSendTalkEvent(SendTalkEventArgs); + Main.OnAfterSendTalkEvent(SendTalkEventArgs); + return; + } + Main.OnFailedSendTalkEvent(SendTalkEventArgs); + Main.OnAfterSendTalkEvent(SendTalkEventArgs); + } + + #endregion + } +} diff --git a/Model/RegisterModel.cs b/Model/RegisterModel.cs new file mode 100644 index 0000000..b616e3e --- /dev/null +++ b/Model/RegisterModel.cs @@ -0,0 +1,139 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Model +{ + public class RegisterModel : BaseModel + { + private readonly Register Register; + private SocketObject Work; + private bool Working = false; + + public RegisterModel(Register reg) : base(RunTime.Socket) + { + Register = reg; + } + + public override void SocketHandler(SocketObject SocketObject) + { + try + { + if (SocketObject.SocketType == SocketMessageType.Reg || SocketObject.SocketType == SocketMessageType.CheckReg) + { + Work = SocketObject; + Working = false; + } + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + } + + public async Task Reg(params object[]? objs) + { + try + { + Socket? Socket = RunTime.Socket; + if (Socket != null && objs != null) + { + string username = ""; + string password = ""; + string email = ""; + if (objs.Length > 0) username = (string)objs[0]; + if (objs.Length > 1) password = (string)objs[1]; + password = password.Encrypt(username); + if (objs.Length > 2) email = (string)objs[2]; + SetWorking(); + if (Socket.Send(SocketMessageType.Reg, username, email) == SocketResult.Success) + { + RegInvokeType InvokeType = await Task.Factory.StartNew(GetRegInvokeType); + while (true) + { + switch (InvokeType) + { + case RegInvokeType.InputVerifyCode: + string verifycode = ShowMessage.InputMessageCancel("请输入注册邮件中的6位数字验证码", "注册验证码", out MessageResult cancel); + if (cancel != MessageResult.Cancel) + { + SetWorking(); + if (Socket.Send(SocketMessageType.CheckReg, username, password, email, verifycode) == SocketResult.Success) + { + bool success = false; + string msg = ""; + (success, msg) = await Task.Factory.StartNew(GetRegResult); + ShowMessage.Message(msg, "注册结果"); + if (success) return success; + } + break; + } + else return false; + case RegInvokeType.DuplicateUserName: + ShowMessage.WarningMessage("此账号名已被注册,请使用其他账号名。"); + return false; + case RegInvokeType.DuplicateEmail: + ShowMessage.WarningMessage("此邮箱已被使用,请使用其他邮箱注册。"); + return false; + } + } + } + } + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + return false; + } + + private RegInvokeType GetRegInvokeType() + { + RegInvokeType type = RegInvokeType.None; + try + { + while (true) + { + if (!Working) break; + } + if (Work.Length > 0) type = Work.GetParam(0); + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + return type; + } + + private (bool, string) GetRegResult() + { + bool success = false; + string? msg = ""; + try + { + while (true) + { + if (!Working) break; + } + if (Work.Length > 0) success = Work.GetParam(0); + if (Work.Length > 1) msg = Work.GetParam(1) ?? ""; + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + return (success, msg); + } + + private void SetWorking() + { + Working = true; + Work = default; + } + } +} diff --git a/Model/RoomSettingModel.cs b/Model/RoomSettingModel.cs new file mode 100644 index 0000000..03b2ead --- /dev/null +++ b/Model/RoomSettingModel.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Model +{ + public class RoomSettingModel + { + } +} diff --git a/Model/RunTimeModel.cs b/Model/RunTimeModel.cs new file mode 100644 index 0000000..e57e6f4 --- /dev/null +++ b/Model/RunTimeModel.cs @@ -0,0 +1,314 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Common.Network; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Model +{ + /// + /// 与创建关闭Socket相关的方法,使用此类 + /// + public class RunTimeModel + { + public bool Connected => Socket != null && Socket.Connected; + + private readonly Main Main; + private Task? ReceivingTask; + private Socket? Socket; + private bool IsReceiving = false; + + public RunTimeModel(Main main) + { + Main = main; + } + + #region 公开方法 + + public void Disconnect() + { + try + { + Socket?.Send(SocketMessageType.Disconnect, ""); + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo()); + Main.OnFailedDisconnectEvent(new GeneralEventArgs()); + Main.OnAfterDisconnectEvent(new GeneralEventArgs()); + } + } + + public void Disconnected() + { + Disconnect(); + } + + public bool GetServerConnection() + { + try + { + // 获取服务器IP + string? ipaddress = (string?)Implement.GetFunGameImplValue(InterfaceType.IClient, InterfaceMethod.RemoteServerIP); + if (ipaddress != null) + { + string[] s = ipaddress.Split(':'); + if (s != null && s.Length > 1) + { + Constant.Server_Address = s[0]; + Constant.Server_Port = Convert.ToInt32(s[1]); + if (Connect() == ConnectResult.Success) return true; // 连接服务器 + } + } + else + { + ShowMessage.ErrorMessage("查找可用的服务器失败!"); + Config.FunGame_isRetrying = false; + throw new FindServerFailedException(); + } + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + } + + return false; + } + + public ConnectResult Connect() + { + if (Main.OnBeforeConnectEvent(new GeneralEventArgs()) == EventResult.Fail) return ConnectResult.ConnectFailed; + if (Constant.Server_Address == "" || Constant.Server_Port <= 0) + { + ShowMessage.ErrorMessage("查找可用的服务器失败!"); + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + return ConnectResult.FindServerFailed; + } + try + { + if (Config.FunGame_isRetrying) + { + Main.GetMessage("正在连接服务器,请耐心等待。"); + Config.FunGame_isRetrying = false; + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + return ConnectResult.CanNotConnect; + } + if (!Config.FunGame_isConnected) + { + Main.CurrentRetryTimes++; + if (Main.CurrentRetryTimes == 0) Main.GetMessage("开始连接服务器...", TimeType.General); + else Main.GetMessage("第" + Main.CurrentRetryTimes + "次重试连接服务器..."); + // 超过重连次数上限 + if (Main.CurrentRetryTimes + 1 > Main.MaxRetryTimes) + { + throw new CanNotConnectException(); + } + // 与服务器建立连接 + Socket?.Close(); + Config.FunGame_isRetrying = true; + Socket = Socket.Connect(Constant.Server_Address, Constant.Server_Port); + if (Socket != null && Socket.Connected) + { + // 设置可复用Socket + RunTime.Socket = Socket; + // 发送连接请求 + if (Socket.Send(SocketMessageType.Connect) == SocketResult.Success) + { + Task t = Task.Factory.StartNew(() => + { + if (Receiving() == SocketMessageType.Connect) + { + Main.GetMessage("连接服务器成功,请登录账号以体验FunGame。"); + Main.UpdateUI(MainInvokeType.Connected); + StartReceiving(); + while (true) + { + if (IsReceiving) + { + Main.OnSucceedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + break; + } + } + } + else + { + Config.FunGame_isRetrying = false; + Socket.Close(); + } + }); + return ConnectResult.Success; + } + Socket?.Close(); + Config.FunGame_isRetrying = false; + throw new CanNotConnectException(); + } + } + else + { + Main.GetMessage("已连接至服务器,请勿重复连接。"); + return ConnectResult.CanNotConnect; + } + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + Main.UpdateUI(MainInvokeType.SetRed); + Config.FunGame_isRetrying = false; + Task.Factory.StartNew(() => + { + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Main.OnAfterConnectEvent(new GeneralEventArgs()); + }); + return ConnectResult.ConnectFailed; + } + return ConnectResult.CanNotConnect; + } + + public bool Close() + { + try + { + if (Socket != null) + { + Socket.Close(); + Socket = null; + } + if (ReceivingTask != null && !ReceivingTask.IsCompleted) + { + ReceivingTask.Wait(1); + ReceivingTask = null; + IsReceiving = false; + } + } + catch (Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + return false; + } + return true; + } + + public void Error(Exception e) + { + Main.GetMessage(e.GetErrorInfo(), TimeType.None); + Main.UpdateUI(MainInvokeType.Disconnected); + Main.OnFailedConnectEvent(new GeneralEventArgs()); + Close(); + } + + #endregion + + #region 私有方法 + + private void StartReceiving() + { + ReceivingTask = Task.Factory.StartNew(() => + { + Thread.Sleep(100); + IsReceiving = true; + while (Socket != null && Socket.Connected) + { + Receiving(); + } + }); + Socket?.StartReceiving(ReceivingTask); + } + + private SocketObject GetServerMessage() + { + if (Socket != null && Socket.Connected) + { + return Socket.Receive(); + } + return new SocketObject(); + } + + private SocketMessageType Receiving() + { + if (Socket is null) return SocketMessageType.Unknown; + SocketMessageType result = SocketMessageType.Unknown; + try + { + SocketObject ServerMessage = GetServerMessage(); + SocketMessageType type = ServerMessage.SocketType; + object[] objs = ServerMessage.Parameters; + result = type; + switch (type) + { + case SocketMessageType.Connect: + if (!SocketHandler_Connect(ServerMessage)) return SocketMessageType.Unknown; + break; + + case SocketMessageType.Disconnect: + SocketHandler_Disconnect(ServerMessage); + break; + + case SocketMessageType.HeartBeat: + if (Socket.Connected && Usercfg.LoginUser != null) + Main.UpdateUI(MainInvokeType.SetGreenAndPing); + break; + + case SocketMessageType.Unknown: + default: + break; + } + } + catch (Exception e) + { + // 报错中断服务器连接 + Error(e); + } + return result; + } + + #endregion + + #region SocketHandler + + private bool SocketHandler_Connect(SocketObject ServerMessage) + { + string msg = ""; + Guid token = Guid.Empty; + if (ServerMessage.Parameters.Length > 0) msg = ServerMessage.GetParam(0)!; + string[] strings = msg.Split(';'); + if (strings.Length != 2) + { + // 服务器拒绝连接 + msg = strings[0]; + Main.GetMessage(msg); + ShowMessage.ErrorMessage(msg); + return false; + } + string ServerName = strings[0]; + string ServerNotice = strings[1]; + Config.FunGame_ServerName = ServerName; + Config.FunGame_Notice = ServerNotice; + if (ServerMessage.Parameters.Length > 1) token = ServerMessage.GetParam(1); + Socket!.Token = token; + Config.Guid_Socket = token; + Main.GetMessage($"已连接服务器:{ServerName}。\n\n********** 服务器公告 **********\n\n{ServerNotice}\n\n"); + // 设置等待登录的黄灯 + Main.UpdateUI(MainInvokeType.WaitLoginAndSetYellow); + return true; + } + + private void SocketHandler_Disconnect(SocketObject ServerMessage) + { + string msg = ""; + if (ServerMessage.Parameters.Length > 0) msg = ServerMessage.GetParam(0)!; + Main.GetMessage(msg); + Main.UpdateUI(MainInvokeType.Disconnect); + Close(); + Main.OnSucceedDisconnectEvent(new GeneralEventArgs()); + Main.OnAfterDisconnectEvent(new GeneralEventArgs()); + } + + #endregion + } +} \ No newline at end of file diff --git a/Model/StoreModel.cs b/Model/StoreModel.cs new file mode 100644 index 0000000..57caba0 --- /dev/null +++ b/Model/StoreModel.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Model +{ + public class StoreModel + { + } +} diff --git a/Model/UserCenterModel.cs b/Model/UserCenterModel.cs new file mode 100644 index 0000000..9dd592b --- /dev/null +++ b/Model/UserCenterModel.cs @@ -0,0 +1,6 @@ +namespace Milimoe.FunGame.Desktop.Model +{ + public class UserCenterModel + { + } +} diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..8f425c3 --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Milimoe.FunGame.Desktop.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Milimoe.FunGame.Desktop.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap back { + get { + object obj = ResourceManager.GetObject("back", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap exit { + get { + object obj = ResourceManager.GetObject("exit", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap green { + get { + object obj = ResourceManager.GetObject("green", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Byte[] 类型的本地化资源。 + /// + internal static byte[] LanaPixel { + get { + object obj = ResourceManager.GetObject("LanaPixel", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// 查找类似于 (图标) 的 System.Drawing.Icon 类型的本地化资源。 + /// + internal static System.Drawing.Icon logo { + get { + object obj = ResourceManager.GetObject("logo", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap min { + get { + object obj = ResourceManager.GetObject("min", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap red { + get { + object obj = ResourceManager.GetObject("red", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap send { + get { + object obj = ResourceManager.GetObject("send", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap yellow { + get { + object obj = ResourceManager.GetObject("yellow", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..f2aec2b --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Images\back.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\exit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\LanaPixel.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Images\logo.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\min.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\send.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Images\yellow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb31c99 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# FunGame \ No newline at end of file diff --git a/Resources/LanaPixel.ttf b/Resources/LanaPixel.ttf new file mode 100644 index 0000000..ee30bb8 Binary files /dev/null and b/Resources/LanaPixel.ttf differ diff --git a/UI/Inventory/InventoryUI.Designer.cs b/UI/Inventory/InventoryUI.Designer.cs new file mode 100644 index 0000000..f5d432a --- /dev/null +++ b/UI/Inventory/InventoryUI.Designer.cs @@ -0,0 +1,39 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + partial class InventoryUI + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "InventoryUI"; + } + + #endregion + } +} \ No newline at end of file diff --git a/UI/Inventory/InventoryUI.cs b/UI/Inventory/InventoryUI.cs new file mode 100644 index 0000000..3063e55 --- /dev/null +++ b/UI/Inventory/InventoryUI.cs @@ -0,0 +1,10 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + public partial class InventoryUI : Form + { + public InventoryUI() + { + InitializeComponent(); + } + } +} diff --git a/UI/Inventory/InventoryUI.resx b/UI/Inventory/InventoryUI.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/Inventory/InventoryUI.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/Login/Login.Designer.cs b/UI/Login/Login.Designer.cs new file mode 100644 index 0000000..f50b27c --- /dev/null +++ b/UI/Login/Login.Designer.cs @@ -0,0 +1,244 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + partial class Login + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Login)); + this.ExitButton = new Milimoe.FunGame.Desktop.Library.Component.ExitButton(this.components); + this.MinButton = new Milimoe.FunGame.Desktop.Library.Component.MinButton(this.components); + this.Username = new System.Windows.Forms.Label(); + this.Password = new System.Windows.Forms.Label(); + this.UsernameText = new System.Windows.Forms.TextBox(); + this.PasswordText = new System.Windows.Forms.TextBox(); + this.RegButton = new System.Windows.Forms.Button(); + this.GoToLogin = new System.Windows.Forms.Button(); + this.ForgetPassword = new System.Windows.Forms.Button(); + this.FastLogin = new System.Windows.Forms.Button(); + this.TransparentRect = new Milimoe.FunGame.Desktop.Library.Component.TransparentRect(); + this.TransparentRect.SuspendLayout(); + this.SuspendLayout(); + // + // Title + // + this.Title.Font = new System.Drawing.Font("LanaPixel", 26.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.Title.Location = new System.Drawing.Point(7, 6); + this.Title.Size = new System.Drawing.Size(387, 47); + this.Title.TabIndex = 8; + this.Title.Text = "Welcome to FunGame!"; + this.Title.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // ExitButton + // + this.ExitButton.Anchor = System.Windows.Forms.AnchorStyles.None; + this.ExitButton.BackColor = System.Drawing.Color.White; + this.ExitButton.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("ExitButton.BackgroundImage"))); + this.ExitButton.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.ExitButton.FlatAppearance.BorderSize = 0; + this.ExitButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); + this.ExitButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); + this.ExitButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.ExitButton.Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.ExitButton.ForeColor = System.Drawing.Color.Red; + this.ExitButton.Location = new System.Drawing.Point(451, 4); + this.ExitButton.Name = "ExitButton"; + this.ExitButton.RelativeForm = this; + this.ExitButton.Size = new System.Drawing.Size(47, 47); + this.ExitButton.TabIndex = 7; + this.ExitButton.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.ExitButton.UseVisualStyleBackColor = false; + // + // MinButton + // + this.MinButton.Anchor = System.Windows.Forms.AnchorStyles.None; + this.MinButton.BackColor = System.Drawing.Color.White; + this.MinButton.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("MinButton.BackgroundImage"))); + this.MinButton.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.MinButton.FlatAppearance.BorderSize = 0; + this.MinButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray; + this.MinButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.DarkGray; + this.MinButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.MinButton.Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.MinButton.ForeColor = System.Drawing.Color.Black; + this.MinButton.Location = new System.Drawing.Point(398, 4); + this.MinButton.Name = "MinButton"; + this.MinButton.RelativeForm = this; + this.MinButton.Size = new System.Drawing.Size(47, 47); + this.MinButton.TabIndex = 6; + this.MinButton.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.MinButton.UseVisualStyleBackColor = false; + // + // Username + // + this.Username.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Username.Location = new System.Drawing.Point(56, 111); + this.Username.Name = "Username"; + this.Username.Size = new System.Drawing.Size(75, 33); + this.Username.TabIndex = 9; + this.Username.Text = "账号"; + this.Username.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // Password + // + this.Password.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Password.Location = new System.Drawing.Point(56, 144); + this.Password.Name = "Password"; + this.Password.Size = new System.Drawing.Size(75, 33); + this.Password.TabIndex = 10; + this.Password.Text = "密码"; + this.Password.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // UsernameText + // + this.UsernameText.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.UsernameText.Location = new System.Drawing.Point(143, 114); + this.UsernameText.Name = "UsernameText"; + this.UsernameText.Size = new System.Drawing.Size(216, 29); + this.UsernameText.TabIndex = 0; + // + // PasswordText + // + this.PasswordText.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.PasswordText.Location = new System.Drawing.Point(143, 148); + this.PasswordText.Name = "PasswordText"; + this.PasswordText.PasswordChar = '*'; + this.PasswordText.Size = new System.Drawing.Size(216, 29); + this.PasswordText.TabIndex = 1; + // + // RegButton + // + this.RegButton.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.RegButton.Location = new System.Drawing.Point(365, 113); + this.RegButton.Name = "RegButton"; + this.RegButton.Size = new System.Drawing.Size(81, 33); + this.RegButton.TabIndex = 4; + this.RegButton.Text = "立即注册"; + this.RegButton.UseVisualStyleBackColor = true; + this.RegButton.Click += new System.EventHandler(this.RegButton_Click); + // + // GoToLogin + // + this.GoToLogin.Font = new System.Drawing.Font("LanaPixel", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.GoToLogin.Location = new System.Drawing.Point(277, 216); + this.GoToLogin.Name = "GoToLogin"; + this.GoToLogin.Size = new System.Drawing.Size(128, 42); + this.GoToLogin.TabIndex = 2; + this.GoToLogin.Text = "账号登录"; + this.GoToLogin.UseVisualStyleBackColor = true; + this.GoToLogin.Click += new System.EventHandler(this.GoToLogin_Click); + // + // ForgetPassword + // + this.ForgetPassword.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.ForgetPassword.Location = new System.Drawing.Point(365, 147); + this.ForgetPassword.Name = "ForgetPassword"; + this.ForgetPassword.Size = new System.Drawing.Size(81, 32); + this.ForgetPassword.TabIndex = 5; + this.ForgetPassword.Text = "找回密码"; + this.ForgetPassword.UseVisualStyleBackColor = true; + this.ForgetPassword.Click += new System.EventHandler(this.ForgetPassword_Click); + // + // FastLogin + // + this.FastLogin.Font = new System.Drawing.Font("LanaPixel", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.FastLogin.Location = new System.Drawing.Point(114, 216); + this.FastLogin.Name = "FastLogin"; + this.FastLogin.Size = new System.Drawing.Size(130, 42); + this.FastLogin.TabIndex = 3; + this.FastLogin.Text = "快捷登录"; + this.FastLogin.UseVisualStyleBackColor = true; + this.FastLogin.Click += new System.EventHandler(this.FastLogin_Click); + // + // TransparentRect + // + this.TransparentRect.BackColor = System.Drawing.Color.WhiteSmoke; + this.TransparentRect.BorderColor = System.Drawing.Color.WhiteSmoke; + this.TransparentRect.Controls.Add(this.Title); + this.TransparentRect.Controls.Add(this.MinButton); + this.TransparentRect.Controls.Add(this.ExitButton); + this.TransparentRect.Controls.Add(this.FastLogin); + this.TransparentRect.Controls.Add(this.UsernameText); + this.TransparentRect.Controls.Add(this.ForgetPassword); + this.TransparentRect.Controls.Add(this.Username); + this.TransparentRect.Controls.Add(this.GoToLogin); + this.TransparentRect.Controls.Add(this.Password); + this.TransparentRect.Controls.Add(this.RegButton); + this.TransparentRect.Controls.Add(this.PasswordText); + this.TransparentRect.Location = new System.Drawing.Point(0, 0); + this.TransparentRect.Name = "TransparentRect"; + this.TransparentRect.Opacity = 125; + this.TransparentRect.Radius = 20; + this.TransparentRect.ShapeBorderStyle = Milimoe.FunGame.Desktop.Library.Component.TransparentRect.ShapeBorderStyles.ShapeBSNone; + this.TransparentRect.Size = new System.Drawing.Size(503, 289); + this.TransparentRect.TabIndex = 11; + this.TransparentRect.TabStop = false; + this.TransparentRect.Controls.SetChildIndex(this.PasswordText, 0); + this.TransparentRect.Controls.SetChildIndex(this.RegButton, 0); + this.TransparentRect.Controls.SetChildIndex(this.Password, 0); + this.TransparentRect.Controls.SetChildIndex(this.GoToLogin, 0); + this.TransparentRect.Controls.SetChildIndex(this.Username, 0); + this.TransparentRect.Controls.SetChildIndex(this.ForgetPassword, 0); + this.TransparentRect.Controls.SetChildIndex(this.UsernameText, 0); + this.TransparentRect.Controls.SetChildIndex(this.FastLogin, 0); + this.TransparentRect.Controls.SetChildIndex(this.ExitButton, 0); + this.TransparentRect.Controls.SetChildIndex(this.MinButton, 0); + this.TransparentRect.Controls.SetChildIndex(this.Title, 0); + // + // Login + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.WhiteSmoke; + this.ClientSize = new System.Drawing.Size(503, 289); + this.Controls.Add(this.TransparentRect); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Login"; + this.Opacity = 0.9D; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Login"; + this.TransparentRect.ResumeLayout(false); + this.TransparentRect.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private Library.Component.ExitButton ExitButton; + private Library.Component.MinButton MinButton; + private Label Username; + private Label Password; + private TextBox UsernameText; + private TextBox PasswordText; + private Button RegButton; + private Button GoToLogin; + private Button ForgetPassword; + private Button FastLogin; + private Library.Component.TransparentRect TransparentRect; + } +} \ No newline at end of file diff --git a/UI/Login/Login.cs b/UI/Login/Login.cs new file mode 100644 index 0000000..b3a30af --- /dev/null +++ b/UI/Login/Login.cs @@ -0,0 +1,111 @@ +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Controller; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Library.Base; +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.Utility; + +namespace Milimoe.FunGame.Desktop.UI +{ + public partial class Login : BaseLogin + { + private readonly LoginController LoginController; + + public Login() + { + InitializeComponent(); + LoginController = new LoginController(); + } + + protected override void BindEvent() + { + base.BindEvent(); + Disposed += Login_Disposed; + BeforeLogin += BeforeLoginEvent; + AfterLogin += AfterLoginEvent; + FailedLogin += FailedLoginEvent; + SucceedLogin += SucceedLoginEvent; + } + + private void Login_Disposed(object? sender, EventArgs e) + { + LoginController.Dispose(); + } + + private async Task Login_Handler() + { + try + { + string username = UsernameText.Text.Trim(); + string password = PasswordText.Text.Trim(); + if (username == "" || password == "") + { + ShowMessage.ErrorMessage("账号或密码不能为空!"); + UsernameText.Focus(); + return false; + } + return await LoginController.LoginAccount(username, password); + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + return false; + } + } + + /// + /// 打开注册界面 + /// + /// + /// + private void RegButton_Click(object sender, EventArgs e) + { + OpenForm.SingleForm(FormType.Register, OpenFormType.Dialog); + } + + private void FastLogin_Click(object sender, EventArgs e) + { + ShowMessage.TipMessage("与No.16对话即可获得快速登录秘钥,快去试试吧!"); + } + + private async void GoToLogin_Click(object sender, EventArgs e) + { + GoToLogin.Enabled = false; + if (await Login_Handler() == false) GoToLogin.Enabled = true; + else Dispose(); + } + + private void ForgetPassword_Click(object sender, EventArgs e) + { + ShowMessage.TipMessage("暂不支持找回密码~"); + } + + public EventResult FailedLoginEvent(object sender, LoginEventArgs e) + { + if (InvokeRequired) GoToLogin.Invoke(() => GoToLogin.Enabled = true); + else GoToLogin.Enabled = true; + RunTime.Main?.OnFailedLoginEvent(e); + return EventResult.Success; + } + + private EventResult SucceedLoginEvent(object sender, LoginEventArgs e) + { + RunTime.Main?.OnSucceedLoginEvent(e); + return EventResult.Success; + } + + private EventResult BeforeLoginEvent(object sender, LoginEventArgs e) + { + if (RunTime.Main?.OnBeforeLoginEvent(e) == EventResult.Fail) return EventResult.Fail; + return EventResult.Success; + } + + private EventResult AfterLoginEvent(object sender, LoginEventArgs e) + { + RunTime.Main?.OnAfterLoginEvent(e); + return EventResult.Success; + } + } +} diff --git a/UI/Login/Login.resx b/UI/Login/Login.resx new file mode 100644 index 0000000..72662bd --- /dev/null +++ b/UI/Login/Login.resx @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + + + iVBORw0KGgoAAAANSUhEUgAAAC8AAAAvCAYAAABzJ5OsAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAu + IgAALiIBquLdkgAAAQlJREFUaEPtmYEJwjAURDOSI3SUjtINOpKjOEr9h1Hyz9+E1haN3METif2Xp6CE + mpaUll55yt86pJC3x26Q/LfYLJ/SaEzEkD4I5qkPjOH+JTvkr/nakil77ArmqQ9cw/1LJC/5t85T5GcD + b6AEm+NLV3LJbi5Yp+sA5rlzDvcv2SwfsfLJZV8XrNN1YAp7W0he8kFvC8kbHFvBrwheYcKjRNTZRPIG + x1YkX0XyBsdWJF9F8gbHViRf5RD5hyiOCHsZwt4WB8lDwJ45dDCrInnJB70tNsuvbJ7ddgXz1Ad038Yj + eR/MUx+QvEfyPpinPiB5j+R9ME994BT5jv9Q+yX+S74/XvIdkpY7JUbXJnJZ8twAAAAASUVORK5CYII= + + + + True + + + True + + + True + + + + iVBORw0KGgoAAAANSUhEUgAAAC8AAAAvCAYAAABzJ5OsAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAu + IgAALiIBquLdkgAAAIFJREFUaEPtzrENhEAMBVFKoCQqo41NrlezSHAErETAwshigpd9yzP8Soms9vg5 + oSM+IoYsjKcYTzGeYjzFeIrxFOMpxlO+G1/30wPG1q+Wur0Vv970NrV+tdSt8T0Zf2m76e2deJrxFOMp + xlOMpxhPMZ5iPMV4ivGUU3xC//iESizRsfmRb9P6wwAAAABJRU5ErkJggg== + + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA + AAC8x9z/x9Tp/7zH3f+8wdv/xMrf/9nh6/+/xdb/3eTv/9PY5//T0uL/6OHu/+nl7f/X1uH/5+Pf/+jl + 3f/g4eP/5eft/+rp6//p5+f/6efi/+zo5P/u5+T/7ebj/+zm4//p4+X/4uHi/9zg4//e3N7/09HX//Px + 9//9+/v/4eDr/9TV6//e3ev/7+/y//Pv9P/+/Pz/9fH2/+fh6//X1+T/v77V/9bT3f/U09v/xsXP/9TQ + 2v/h3eb/39zk/97c5//d3Ob/3Nzn/6OqxP+cp8f/mqXI/8HG3f/L1ur/6fD7/9XZ5//q6u//9/b5/8nP + 2f/U2uX/1tri/7/H4P/P1er/ucTc/7rF3P/AxeD/x8vc/8fL2v/Cydj/2uPw/+Hq8f/Hy+H/6OLs/+Hb + 6P/Cv9n/z9Dg/+3q6f/o4+D/5eLh/+Tk5P/o5uf/6Obl/+nn4v/p5eD/7ebi/+rk3v/p5uD/5+Xj/+Di + 4v/c2tz/vr7N/6ipx//T0t//+/n6/+Ph7f/S0+P/8fH1/+zr8P/7+Pr/+fb3/+ji7P/n5PH/1tPl/8jL + 2P/Qztn/3tvl/9TR2v/j3+j/4d3l/+Db5f/a2OL/393n/93d6v+2u9b/zNHn/+Hq+P/j6/v/5e75/8/U + 6f/W2eX/7uzy//Ly9f/Hy9n/zNPg/+Lo7/+zutX/w8ni/7W/3f+st9T/ycri/8jH2f++wNj/1t3s/+Dn + 7//V3er/19Tk/9nX5f+2udT/4dro/8fF2v/k5Ob/7Ofk/+nl4v/n4uL/5uTi/+fl4//o5uH/6uXg/+zm + 3//s5+D/7Ojg/+nm4P/j4OD/wsLR/+Lf6v+vrcb/6+rz/9fW5P/Q0Ob/7ez1//Hu8//39/n//Pr7/+rm + 7f/r5fD/0c7j/+vo9f/T1eP/5OLt/9vY4//j3+j/5N/o/+Pf5//W0dz/29jj/9/e6f/h3+r/ztHh/87U + 6f+1udL/sLnU/7jC1//U1ub/9PL1//Px9v/j4uz/w8fc/8/W4P/K0dz/sbzV/7nF4P+nsM7/yM3j/83M + 3P/Kyt3/0Nbn/9ng6P/Z3ur/x8ve/9XV5P/BxNb/v73U/8fH2v/Z1uP/trXL/+rl4//r5uH/6OTf/+Xl + 3//j493/5+Xe/+vm3//r5d7/6eTe/+nl3P/m4dr/19LN/83J0//q4en/19Pi/9bT3v/o5O//2NXn//bz + 9v/x8fX/+/r8//Hu8//o4uz/3Nfj/8K91//p4u//3N3o/8jH1v/V0d7/5+Tt/+rl7P/X1d//0tPd/9/b + 5v/k3ub/yMrd/9XZ5f/Nz+T/xMXb/4ySsP/T1OL/5+Xp//Hv8//k5Ov/1Nbm/7zD3P+8xtb/tL7U/622 + z//BzOb/pa/L/8bH2//Oy9z/wcjb/9La4//K0+D/y9Hi//Lz9//h3On/2dbm/8jG2//k3uz/39jo/9LS + 5P/d2dz/6+Xh/+rl4f/n5N3/6OXe/+nk3P/q5d3/6eXc/+rn3f/l4db/4tvS/87Iv//Exs3/6+Xu/97d + 7P/X1OX/3NTl/9bZ6f/18fb/8fD0//n2+v/n5e3/5d3r/8nF2P/d2Oj/4dvl//f0+f+4u83/2dXg/+vp + 7//a2OH/z8/c/9fW4v/c2uT/3dzk/7K1zf/X2+n/x83h/8rJ3P+sr8n/t7zO/+Pl6v/r6fH/1NPf/9HV + 4/+6w9j/uMHU/7vF1/+vu9b/2d/v/7jB1f/Cxtr/ub/R/8TL1v/Cytb/vsfY/7vB1f/JyNn/xcTY/+bi + 6//LyN3/6uLv/9DP4f/49/n/2tjg/+vl3//o5N7/5uHa/+Tf1//j4NX/5N3T/9zUxf/Tybf/zcKs/8K4 + oP+xqpb/vr7K/9fS4v/g3en/zMzk/7Kz1P/v8PX/7ezx//36/P/07/b/5t/t/8O90v/Kx9n/7+ju//Ht + 9v/59vj/wcPV/97a5f/m5ez/ycnV/9HQ3f/a2+X/2tjj/9/c6f+fp8b/yM3m/9Ta6P/Bwdf/2tvl/4qR + pf/q6O//zc/c/9DT4f/J0N3/wMva/8HN2v+6xdn/1dnt//Lz+P+9ydz/rrjO/77H0v+/x9P/vMTR/8zQ + 2f/V1d7/2Nnm/7u80//Kyd7/3+Dy/9/e8f/LzOP/9fT3/9rZ4f/p5d//6eLd/+Pf1v/Oycz/xcTM/769 + wv+rqan/rKej/6Oemf+hmpf/h4OO/9PP3v/s5fD/4+Du/87Q3//V1er/8vP1/+np7f/08fX/5+Lr/9rT + 4f+3tcr/tKvF/9vT5v/r5/D/1tbj/9LO4f/d1+L/2Nvj/9TS3v/Rz9r/3d/p/97e6P/GyNz/uL7X/8/V + 5f/n7/X/ur/V/+nn7P+dpLb/pae6/8/Q4f/L0d//x9Lg/9Hb5//P2OX/1+Dw/+Pn7//8/Pz/qbXQ/8LP + 5v+vuM7/wcrU/62yzP/a1uH/29jh/8rL4P/OzOP/2drn//r6/P/y8/r/ys7j//Pz+f/CwNL/2NPN/9vU + y//AwsX/29rl/87Q3f/IzN3/pazD/9bX5v/a1eH/49nl/6qkwP/k3uz/8Ozy/9fX5//V1+X/8/H2/+/t + 8//y7/T/6OLr/+Xf6v/Mx9r/1M/e/+fj7//V1uX/y8zd/+ro8v/Kx9f/4+Lp/8jJ1f/Z1eL/1NDb/+Pg + 6//e4Or/t7zV/7/F2//Dy+H/5e31/83U4v/k5vD/x8zW/3aBmf+WoLn/i5iv/8LJ4P/X4Ov/1tvs/9Ta + 7P/e4ev//f39/7LB1/+3xdz/xNHl/5mowP/Cxdz/2dfh/93Z5v+1tdD/5eDt/9TT4//7+vr/7+3z/9LV + 5f/q5fP/w8Pb/66ko/+1saz/8/L0//z6+v/9+/v/+ff3/+zr8P/g3+j/4d7x/+Lc6v+5u9P/8O/1//Hv + 9v/V1uP/29vo//Xy9//o4+z/7uny/+rk7f/a1ub/v7rT/9rV5P/p5u//9/X3//j2+v/P0Nr/vr3R/+ro + 7//Jytb/2Nfk/9jT3//i4Oz/4eLs/77B2P/JzOH/uL/d/+Po9f/s7/b/v8TW/5Kbt/+Hj7D/jZm2/6i1 + zP+gqsX/zNLj/+Ll7//T2uf/2t7q//39/f+2xNj/vs3h/9fj8f/AzeP/tbvR/9zY5P/a2uP/pafA/8PD + 1//v8vb/+/n7/9vb5f/19/j/4+Lu/9fV5/+vq8D/ubjD//z5+//9+fr//fv6//bz9f/j3+r/7ez0/+bj + 9P/T0OH/6Ofz//r4/P/19Pb/2Nrl/9zd6f/p5ez/6ePt/+3o8f/p4e3/vLjO/9DL2//k4u7/8+73//jz + 9v/8+vr/09Xl/7O2zf/o5ev/5unu/8zO2f/X1uD/3Nzl/+Xo7/+/wtv/y87k/7zC3P/U3Oz/6u/2/7G4 + 0P+Vnb7/hpCw/4OMr/+HkLL/qLHJ/+ru8f/8+/z/xMre/+3v9f/8/Pz/2uHu/7fD3f/X4vH/2+fx/8TP + 3//DxNT/3trn/7q6zv+2us//y87f/8TF3f/U0+T/+vr4//P1+v/c2u3/087e/8G/0v/8+vv//vz8//z6 + +v/w7PH/49zs/8/N3v/z8fj/8fH4//37/P/+/f3//Pv8/9nb5f/Y1+b/3dfk/+3m7//p4u3/5uDt/8PA + 2P/Oydv/4uDs//z6+//7+vv/6+ju/8PF1f/m5e3/3drk/+zr8f/q7fP/zc/b/9bY4v/m6fD/3eTt/7G5 + 2P/HzuP/ys3h//Dw+P/Iz9//mqTF/4mVtf+5wNX/jJey/+Xl8P/7+vz/+vr8/8HH2f/8+/z//f39/77G + 4v+8yN//wM/k/93p8v/U3un/u8TT/83M3f/Lx9j/4dzl/+Ld5v/Kx9r/19fl//z8/P/6+/z/4+L1/+Hb + 6v/BvtL/+vj7//37/P/j4+n/29rl/9jT4f/Gxdj/3trm/+jn7f/39fb//fv7//38+//U1eL/09Dg/9rU + 4P/w6e7/6OHs/9jX5v/i4+7/5OLt/+Tl8f/8+/v/+ff7/9HQ3v/k4Oj/9PDz/9zY5P/h4Of/6+zy/+nr + 8f/Lzdf/4eTs/+js8v/S2en/qrTU/9fb7v/l7fP/6fL4/9fg7/+yvdL/gpCr/5+qv//4+Pz/+/v9/9zd + 6P/f4+z/+/76//39/f+ls9L/t8Xc/7nJ4f/Czd//ytTg/8LO1/+sscf/xsXZ/+DY5f/f2uX/1dPh/8XF + 2v/o6PH//Pv8/+vp+f/f3Ov/zc3e//P09v/9/Pz//fv8//v6+//m5u//ycfZ/97Y5//Y0+T/yczb/+vs + 8v/39vv/ysva/9XX5v/f2+r/497o/9nS3v++uM3/9/P5//v7+f/z8/n/+fr7//T09//V1OT/49/n//Ds + 8//W0Nv/29ji/+jn8P/o6O//6Onz/9TX4//r7/T/7O/1/9Da6//CzOP/4+72/+Pv9f/m8ff/4Orz/87Z + 5v/HzOH/+vv8/+rp8v/Eyt3/+vv8//v+/P/+/v7/uMTe/6Syzv/BzOL/v8zf/7fF3P+yvsv/n6a+/7/B + 1P/Rzt3/3tnk/9zY4//OzN//0tLj/+zp9P/m5fP/z9Hg//Dx9f/9+/z/+/r7//r5+f/a2uf/0M/i/9vZ + 6v/R0Ob/0dLp/93e8P/Iydz/vsHP/6itwf/X2eT/6ejx/9XS4P/SzN3/0Mze/+Db6v/19Pb//fz8//v4 + +f/i4+r/1dTf/+fj6//r5+7/0s7a/9nT3v/b2eT/6enx/+bk8P/e3un/5OTu/+7w8v/n6/L/2N3q/9LZ + 6//j7/b/2+fy/9vq9f/T3+j/vMPY/8jM4P/V2uf/5Obu//7+/v/+/v7//v7+/7zK4P+8yN//tsHa/8HN + 5P+uu9f/sLnO/5CXqP+3us3/ysvY/9bU3v/b1+H/yMjY/7u+1P/c2er/4Nzs/9TT4f/5+/r//fz9/+vs + 8f/Extn/29jp/+zl8v/r5fH/6Of3//Hy+v/18fb/2Nbq/77F2v+Qma//wcXR//n6+f/28/j/zMjb/+fg + 7f/Kyt//ubzR/8zL3f/R0d3/0NDh/8PC1f+7vs//ubnM/8XBzv/f2OL/yMfT/9rd4v/h4ev/4d/q/9fV + 4v/q7PH/5urx/9nc5f/k5/P/1+Ds/97s9f/N2Ob/z9vm/8bR4P+2wNv/u7/Z/+rq8v/9/f3//f3+//7+ + /v/G0+L/rrvU/8fR5v/L1un/qrTX/7e/1/+VnrD/p6rE/9XV4f/Kydj/0NDc/9LR3f+vtMr/2dTm/8bI + 2v/29fj/7Oz1/9PU4f+0tdL/4uHu/+ji7v/s5O//7Ofx/+/s8v/39Pj/+fb5/9bX6f/d3u3/zNLg//Tz + +f/8/Pz//Pv6/8zO3v/u6vP/3dvr/8TG2//b1+H/4Nzj/9zX5v++wtL/zM/c/77D3f+mrMT/y8fX/9rV + 4f++vcj/397p/93c5v/Sz9z/6OXv/+jq7f/d3Oj/5uXu/+Xm8v/R1uj/1+Lt/8TP3f/G093/vcjj/8TK + 5/+4wd3/+vr9//39/f/+/v7/0dvo/8HN5P+/yeH/0tzr/8HN5f+2wNz/jJWs/7S50P/S1OL/wsbX/7m6 + zv/Rzdv/u77S/8bH2v+8wNb/0djj/8vO4P/g5Oz/vcHT/+nk7v/p4+7/7eXz/+vk8f/z8Pf/8fH1/9bZ + 5v/Kzd3/x8fd/5Wcq//FyNT/+vr7//n6+v/g4Of/5OLs//Lt9v/HyNz/1NPf/8TD1f+lpsP/0Mzg/8zM + 3P/h3er/uLjN/8TG2f/OzNf/xcHN/87N1//X1uD/1tPf/93Z5P/r7PD/29vl/9/e6f/y8/f/1dbj/8fR + 5P++ytj/vcjY/7rG4v/Ey+P/u8Le//Tz+f/9/f7//v7+/9Db4v/Y4u7/tMHZ/8/Y6f/h6/b/w87l/5ae + v//Axd3/2Njl/8bI2v+1uc3/xMXV/7O50P/Dz+H/rLXU/9ve5//S0t3/2Nrl/8/L3P/q5O7/6+Tw/+rl + 7v/m4vL/z9Pm/7fB3P/f5vX/4efv/9Xa6v+zu8//1tvk//z7/P/t7fL/7+/1/8/Q4v/W1OX/zcve/9TV + 3v/MzNr/zdDa/7O3zv/Bwt3/1NLh/+ni7f/q5+7/vbnO/8TDzf/Pztn/0tHb/9XS3f/W0t3/6enu/9/g + 6P/f3Oj/4+Dq/+Pj6P/f4+//yNTh/7XA0P+4w9//0dTq/8fO4v/08/n//Pz7//39/f/Y4Or/2ODr/9Xa + 5//O1ef/4+z1/8/Z6f+7wtv/tL3W/83Q4P/Kztn/vcHO/7O0zf+4wtf/z9vu/5qixv/Izdj/09rk/72+ + 0P/n4O7/x8XW/9HP5P/Cwtj/wMXg/8jO6P/W3/P/ucHe/5WfyP/KzOT/39/t/7zC2P/JyNb/xsnc/8LI + 1v+wuNL/zs3f/9/d6//b1+T/0c3Z/8zJ0//i4e7/vr/Y/7W41P/f2+f/5ODr/9nU4/+wsML/0tDb/8zK + 1f/PzNf/1dHc/+jn7P/i5Oz/2trl/+Hf6P/Y1uT/+fn5/9DV4/+8xdb/ucji/87S7P/Cx9r/+Pr8//3+ + /f/+/v3/2+Ls/87W4P/U2OL/5Ozz/9zg8P/Bydz/z9Xm/8nV5v+3wtf/yMrY/7+/z/+hpsL/2OPx/8fS + 6P+utdD/zdDa/9Xa4/+2us//wsDX/7O41P+lrcz/sbnZ/9PZ7/+vt9b/v8nm/7G52P/JzOL/r7PN/7q9 + 2P/OzN//qKvB/9na6P/Fytr/rLHH/727yf/j3+n/5OHq/9TR2//NydP/6OXu/83N3P/AxN7/zcrf/+Dc + 5v/j3ur/q6zE/7650P/U0Nn/yMfR/9vW4f/j4un/3d/o/9jZ4//l5Oz/2dji//Tx9v/Hydj/uMTZ/9Dd + 8v/AxN3/1dbm//39/f/+/v7//f39/9PZ4//W2+X/y87Y//Py9//c3u3/y9Hm/8TL3P/d6PL/ztnr/7W9 + z/+2tMz/uL/W/+Dn7/+2v9v/wsjb/9vc5v/U2OP/ys7a/8jM4P/Nzub/pa3O/9Pa8f+wudz/z9jv/83T + 6v/Dx+P/p6bK/72+2f/Kx93/xsXe/6mqyP+3utH/5+v2/+zz/P/V3ev/trvN/8vM2//U0dz/4N7l/93b + 5f/i4ev/yMnc/8bG2//c2OL/4Nvn/7i70P+lqML/1M/b/8bFz//h3On/5OHr/9nZ4//e3ub/29rj/+jo + 7v/g3eb/vL/R/7zI4f/j7Pr/1dvp/+ns8f/+/v7//v7+//7+/v/b3ej/2drk/9HS3v/f4Ov/yMzh/+bs + 9P/FzOH/3uXu/9zi7P/Aydn/pazC/83U4//Cxtv/oKnH/9TZ5//d3Of/0NPe/9na6P/Gx+H/naXL/7bC + 4//R1u3/ucLg/+Pp+f+4vt3/nKDH/7Sz2//Iwdv/pqXH/7K30P/i5fD/7fH4//Dz/P/r8v3/6vP8/+nx + +f/a4vD/w8ve/7u/1v/T0+D/4t/o/8nI2//c2uf/3tnm/9vW4//Fxtf/urnS/7S1zf/LyNL/4t/p/+He + 6f/Z2eP/4eDo/83N2f/r6PD/5ODp/6uzzP/f5/n/4uj1/9fa5f/9/P7//v7+//7+/v/+/v7/0dXf/9jX + 4f/S1uD/wMPW/8nP4v/K0eL/wsXd/9vi7P/Y3uj/m6W0/7G50f/Dxtv/tLrY/7W/1f/Q1OH/2tvm/8/P + 3P/Mzd//w8rj/5Ccyf/M1u//vsXg/+Ho+v/V3PD/nqHH/5+jyv+zsc//qKvK/9fa7f/u8vr/8PL7/+/z + /f/t8vv/7vP8/+nw+v/q8fv/6PD6/+30+//h6Pb/xs7g/7q7y//ExdT/3Nbk/97a5f/Y0+L/1tTh/7+7 + 0/+bnr7/zcvU/+Hf5f/c2uX/3Njj/+He6P/Nzdr/6ebr/8jO3v/Y4fL/4ur4/8zT5//j5ez//v7+//7+ + /v/+/v7//v7+/7O80P/O0Nr/rLLC/7e+0f/T1+r/vMLX/97g6f/Fyt3/qbC8/6y0xP+2utH/vL7W/7O4 + 0f/N0+L/ztHf/83O2//R0d3/ycvf/7e93f+hq9D/2OH1/9LY7//c5vb/usPg/5mi0f+ZnsD/wMff/+rx + +v/s8/v/7fT8/+3z/P/t8/z/7fP8/+30/f/u9Pz/7PT9/+rz/f/q8fr/8PT8//H0+//r7vb/v8PX/8nH + 2//Z1uH/19Lg/9vX4/+8utP/pqjD/8jI2f/i3ub/0dLd/9rX4v/d2uX/0tHd/9La6f/Z5PL/5e77/8vS + 6f/M0eL/+fn8//3+/P/+/v7//f39//7+/v/Aydn/pa3B/6Wswv++yNn/xMri/8PI2v/U0tn/srrH/4+X + rP+nsL//y8vZ/8DE2f/Hydn/1djj/8vN2f/GxNL/0tDc/8DE2/+wtdj/tb3d/9rh9P/T2O3/1+Dx/5+m + yv+ordf/3ePz/+vx+f/s8/z/7PT8/+z1/f/r9P3/6/T9/+zz/P/h6PD/7PH6/+71/f/u9f7/8Pf9/+32 + /P/w9v3/8/b9//P1/P/N1OP/wsPU/9TR3v/c2uT/vcDV/7S2zv+/wtj/4d7p/8/Q3P/Z1+L/3Nnl/7/B + 0f/d5PD/5O/3/8rV7P/Z4O//2tvp//39/f/9/f3//v7+//7+/v/9/f3/uMHN/7a90P+qssb/yM/d/6iv + zP/V1eL/0dHb/5acr/+fprf/qbHD/8/O3v+7vdL/zMzd/9Xb5f/CwtD/x8XS/9jU4P+yt8//rLLT/6+7 + 2f/S3O//zNPm/9bf9P+PmLz/vcDg/+3y/P/v9P3/7fP8/+30/f/s9P3/6vP8/+v0/f/q8/z/1Nzo/9LX + 5P/x9/3/8ff+/+72/f/v9v3/8vf9//D1/P/y9fz/7fH8/8HG2//Hx9j/wL/O/7a4y/+pq8j/v8HY/+Pi + 6f/Q0d3/2tjh/8fF1v/S2+f/6e/3/8vV6//X3+z/29/q//L0+P/+/v7//v7+//39/f/+/v7//v7+/7fA + zf+vtsn/srnL/83V4f+bpsD/1dTf/83N2/+Yorf/rLXE/7G5yv+5u9T/09Ph/8bI2//c4un/ur3K/87M + 2P/X09//oafE/7nA2v+qt9H/y9Xo/8vW6P/F0uv/qbPY/8XH5f/p7/v/6vD8/+zz/P/t9f3/7fX9/+31 + /P/u9v3/7fT9/+31/f/v9P3/8Pb8//H2/f/v9fz/7/b9//H2/v/s9P3/5e37/+Hr+//d5fr/q7PN/8nK + 3f+Nk7P/pajL/6Gkxf/DxtX/1dLc/83N2//Bx9n/4Orz/83V6f/Q3Or/5Obv/9/i6v/9/fv//v7+//7+ + /v/+/v7//v7+//7+/v/Fztr/srzN/7K7zv/J0Nz/r7jN/83O2v/JzNr/oq2//7e/zP/Dy9v/ubvd/+Tg + 6P/L0N3/297q/8DFzf/Qz9v/1NPf/5ulwv+9w9v/qbXP/8jR6P/I1Ob/vMrl/6m32f/S1vD/6vD8/+zy + /v/s8/z/7fT9/+zy/f/s8/3/7vX+/+30/f/v9f3/8PX+/+/0/P/w9v3/8Pb9/+/1/P/u9fz/6PH7/97o + +v/a4fr/1dz6/6ix0//P0+f/vcHU/5GZuv+3vNP/q7HG/8bE1P+zvM7/0tro/9Xc6//Y4e//xMzi/73B + 1//o6fL//f39//7+/v/+/v7//v7+//7+/v/+/v7/19/q/7jE0f+zv9X/y9Hb/8vP4P+6vdL/y87b/6u2 + x//DzNn/y9Te/8LJ4P/HyNr/yM3h/9XV5P/S1uD/ysnW/9PR3v+krsf/wMba/7O/1//AyuD/ytfo/6y5 + 2v+uuNr/0NXw/9PX7v/h5vP/8PX+//D2/v/s8/3/6fL9/+z0/f/u9v3/8Pf9//D2/f/x9v7/8vj+//L3 + /v/w9/3/7PX8/+Tv/P/Y5Pz/z9r7/8nT+v+9yPD/rbfV/8jO4v+Um8D/rbTN/7W5zv+vts3/ucXa/9je + 6v/I0+P/0tnu/8LI2//X3un/3d/u//7+/v/+/v7//v7+//7+/v/+/v7//v7+/9rf6v/N1eT/tb/Z/9HZ + 4v/e5O7/wcbb/8/R4P+1vdL/ydLf/83W4//d5PH/v8TX/52lwv+ss8z/4eTv/8TF0P/Lytf/srrR/83V + 4//BzOD/uMPX/8jU5f+tueD/pq3W/5OVxf+rttv/4+r8/+71/v/v9f7/6/P9/+rz/f/u9P3/8PX9//H3 + /v/v9f7/8Pb9//H3/v/x9v3/7vT7/+rz/f/d6vz/09/5/83X+//G0fr/wcz5/5Sdwf/HzOP/kpvE/6Ws + x//Gyt7/s7jN/7jB1v/K0+L/ztjq/7e/1P/3+fr/1tvp/97h7P/+/v7///////7+/v/+/v7//v7+//7+ + /v/x8vb/09Xi/77D2f/X3e3/3eLs/9Xc6//Bxtn/wMfg/9HZ5v/R2ef/3ebx/8DF2//Z2+b/oqnE/8PH + 2f/GyNL/w8TV/7O60//P1+L/wcvf/7XA1f/I0+j/sbzl/4GJu/+Qm8z/ztr8/9nj/f/n7/z/6/P9/+zz + /v/s9P7/7vT9//D2/f/v9fz/8ff+//H3/v/x9/7/8ff9/+3y/f/l7/v/1+P8/7rD7/+/yPj/xtH1/8PN + /P+yu+b/oqnH/6WszP+vs8z/usHV/7O90f+/xt7/v8ve/7/K2//P0+H//fv7/9Xa6//e4ev//f79//7+ + /v/9/f3//v7+//7+/v/9/f3/+/z9/+rs8//Hytn/xs3e/+Hp8//p8Pn/xMzc/8fP4P/Q1+v/2d/y/9zg + 8P/Z3+7/w8TV/9fa5/+or8z/x8ra/73A0P/IzuT/0tvm/7/I3v+1v9X/xdDm/7C74f99h7v/v8r0/8rV + +//R2vr/4uv9/+z0/f/r8/3/6vP8/+3z/f/x9v7/8ff+//H3/v/x9/7/8ff9//L4/f/v9P3/6e/9/7/J + 8f+9yfb/ucXx/8LI7//O0fj/v8b2/6Gszf+lrsz/o6fF/7/F2P+6wtb/vMbb/7zI3/+wutD/8/X6//T1 + +P/T1ej/5+rv//3+/v/9/f3//v7+//7+/v/+/v7//v7+//39/f/8/f3/4eHo/9PW5P/Y4e//4e71/+Ps + 9P/Byt3/vcfg/97l9v/c4/L/6ez5/8rP4f/U1eT/t7nR/7q/1v+/wtT/1d3s/8/Z5v+/yt//t8LY/8TP + 5v+kr9b/orDg/8nT+v/K0/v/0Nf6/9je+v/k6/r/7fT9/+rz/f/t9P7/7/X9/+72/f/v9v3/7/b9/+70 + /f/u9f7/7PP8/9/f9//QzuT/xsbS/83M1v/MzdX/vrzE/7O16f+mq9P/lZ69/56kyP/Fy97/srrW/7zK + 3v+1v9b/vcXX//n7+//V2OX/2dvq//r7/P/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/+fb6//Hx + 9//Y2eT/1djl/93n8v/e6/L/3+nz/6+82v/N1u7/4uz3/9zm8v/l7Pj/v8LY/8/R5f+ytM3/mJ25/97l + 9//W4e7/yNHl/8HO4f/H0ur/q7bc/6++6f/H0vr/wMz6/6mv5f+mreH/t77w/+jv/P/r8vz/7PL9/+/2 + /f/u9P3/6u74/+/z/f/w8/3/7fP8/+/0+v/a2+7/s6KQ/5mCa/+rmYT/u6yf/6ydkf+4tsr/kJDB/4mP + sv+ao8P/z9Pn/6y11P++yuL/t8LW/8rQ3//39/v/193t/+Dg6v/9/f7//v79//7+/v/+/v7//f39//7+ + /v/9/f3/5unv/9jc7//W2/D/2Nvr/97d6f/P1Of/2uTy/97n8v/a4vL/p7DT/+Pr+f/e5vL/4Ofy/9/i + 7/++v9j/urvO/52iwv/b5PX/1eHu/9Pd7v/L1uj/xNDn/7bB4P+/ye//u8Hp/7vA3//Iy9v/ys7f/83R + 5//S0t//6Oz3/9Xd7v/R1+7/0dnu/9LW6v++yOP/tsHb/7jC3P/b4e//wcff/5eOlf94Z1j/i3Zb/6mU + fv+OhHX/uLa//4iIpv9ucIr/mZ+7/87S5P+6wtz/t8HY/7K7z//a3+v/5uXw/9DW5//4+Pv//v7+//39 + /f/9/f3//f39//7+/f/9/f3/9fP0/9/h7v/g5vz/1tvp/97h7f/d3en/xMfd/8nR4v/Q2Of/09zn/8XN + 5P+7x+D/5Oz4/9rj7v/g6PH/xsra/6ytx/+jqcv/3Of3/9fi8f/Z4/P/0drr/7zI4P+8wOH/sbLZ/6Cb + pf+/t6f/wrWj/8a5q//Pxbz/v7W0/87N2/+9xeD/xc3q/9HY9P+osdj/r7TZ/73G5P/DyOT/2t3v/8vQ + 5P+nrc7/kpKq/3NpcP+Gdmj/bWlx/2xtiP9obIn/g4ep/6Goxv/P0ej/usLZ/7/I2f+6w9b/3eLs/9rb + 7//Z3Oj/+/z7//39/f/+/v7//f39//7+/f/9/fz/+Pn4/9DT1f/m5vL/2d3x//X2+f/7+/r/+Pf4/9fU + 5f+wttP/0djp/8jQ3f/L0+L/q7bT/9Xf7f/c5O7/2uDr/+Hn8P+ipsH/s7XU/9vo8v/V3+7/2+f0/9Ld + 6/+/yuL/sbTV/4uMt/+Og3r/qJB0/5yFZf+vmHj/xK+U/6qbkP/ExNT/oKXH/6Os1P/X2/f/19z6/8TJ + 5v+0u+D/rLLV/9zg8//N1O3/nKPL/8PJ4f+nrdD/houp/3+Apv91gKr/lJi5/6euzf+xttP/0NTr/8HI + 3//L0eH/vMTX/9PX5//T2Oz/0tPi/+Hh7v/8/P3//f39//39/f/9/f3/8vL0/9vb3P/p7ev/7e/1/9LV + 5//6+v3/+/v8//z6/P/i4uz/srfU/7G41P/T1uL/ys/e/8HI2/+nss//3OTv/9zl7v/c5e3/zNLk/73F + 2v/d6fL/0Nzq/9nm8//S3+7/t8Xb/46Qsv9vcZH/kIiR/4VuW/+AaVP/n4Zm/6CHa/98dXT/gomk/6On + yP+QmMH/wcXm/9fc+f/d4fj/ucPn/7vC5f+3vdz/2+H3/6Oqz/+4u9f/4eL0/9ji8//L0eb/maDE/8rQ + 5/+zudX/w8zh/9DW6/+7xNv/19vs/7rB2f/JzuT/4+Pu//Dy9v/JzOL/9vj7//7+/v/+/v7/+/z9/+Lk + 5//Y2tv/6u3q//v7+//e3+v/7e7z//j5+v/U2Oj/uMHb/7rD3/+nr87/w8bZ/8vM2v/N0N//rrjU/7vE + 3P/b4u7/2uLs/93k7v/Eytj/2+bw/8nW5P/T4u//ydjp/7zI3v+cpcT/aG6R/2Vohf9kZGz/Z2Bg/2dd + XP9dWmT/Vltz/4SMrP+hp8b/oaXJ/7W84P/W2vH/1dnw/9Pc9P+xut//pKzS/9bb9P/K0u//p7LV/9ja + 8f/o7Pf/7fD2/7G11P+4vNj/srfU/8zV6f/N0+n/wcXe/9rg7//ByOT/zdDh//j4+//2+Pn/zdDk//Dy + 9f/+/v7//v7+//7+/v/3+Pj/3d/e/+Pm5P/8/Pz/+Pj6/+Ph7P/d3+7/1try/9TY8f/R0+v/2Nvw/8/V + 6f+1utP/zdLh/8LL3v+Xpcf/09vr/9fh6//T3Ob/zNPk/9Te6//I1uL/y9vn/8bU5//I0+T/tsHZ/5uq + zP+WnMn/foSv/4SNr/9ob5H/dXyj/6Wt1f/Aw97/vMPb/4qPtP+3w+D/zdfr/8zX6//M1ur/usTi/7G9 + 3v++yeX/zdju/8TQ6//Fzuj/4ef1/+js+P+3udb/vcTc/7e91v/L0+f/x8/j/77E2//Y3uz/ytPo/9HV + 5v/8+/3/+vv7/8/S4v/6+vv//v7+//39/f/+/v7/+/z8/9ja2f/d4d///f39//z7/f/a3e3/z9Pn/9nd + 6f/h5vD/x8vZ/8DB1//Cwtj/ztXr/7rA2P/P2OX/rbnV/7rE3P/W4Or/yNLd/9Da6f/C0OH/yNTg/8XV + 4f+5yNr/wM3g/77H3f+uuNb/q7LW/7nC3f+nr9X/rbfU/6Kp0f+9wuL/3t/y/9/c8v+qsMz/tr/a/8rW + 6P/H1Of/xNDj/8XU5/+yvdz/rbjY/8XQ5//J0+z/w8rp/+ju+f/m6/j/uLnV/7e/1/+rssv/w8ze/7zE + 1v+1vNL/193s/8TM4v/R1Ob//Pv9//v7/f/Q0uP//f39//7+/v/+/v7//f39//P09P/X2tj/19vZ//z8 + /f/n6PL/1Nrr/+ns8f/g3+f//Pr8/+zs9P/Oz9v/0c/a/7y+0/+3v9X/xczd/8TO3v+rtdL/1uHv/8nU + 4f/J1OL/tsHW/8XP3v/Bztr/tcHS/6q3z/+qtM//rbfY/6q20//Fz+X/r7XU/8jP5v+ttdX/oafT/9TZ + 8P/n5fT/0M7j/6Krzf+8x+D/ws7g/73J2//D0OL/sr7X/7K83P/Ay+H/u8fc/7vD4//f5fb/1trp/6qv + zP+5wNb/o63F/7rE1f+2vtD/s7zO/8/Y5P+7w9//2Nrl//38/P/y9Pj/2dzp//39/f/9/f3//v7+//z8 + /f/g4eH/6Orn/9rc3P/8/fz/5ujz//v7+//8/Pv/6uzx/+nr8P/6+vz/z9Ld/9DR3v/Iydj/yMvb/6Gv + y//FzN7/s73V/9Db7P/M2OT/wcza/6660f++yNf/vsrV/7jC0/+2xNP/rbnR/5mnxf+Vnr7/vcTf/7/G + 3f+0utb/vcff/6Oq0/+7w+L/6e35/9fU5/+mq83/rbjT/7bC1v+8yNr/ucTW/6u2zf+wvNT/usXZ/7fC + 1f+0vdn/2+D4/9/h8/+ttNL/tb7W/5ulvP+xu8z/srrM/623yP/Gz+D/vsbf/9vd5f/7+Pr/3uDq//Hz + +P/9/f3//f39//39/f/u7u//6evj/+Tm3//s7vD//f38//v7+//9/Pz//Pz8//r8/P/p6O//5ubu/9jc + 5P/W1+L/1NXi/8nJ2P/Hzd3/mqW8/8vT5/+9yN3/yNbi/7nG1v+ruM7/vMnY/7vH0/+3wNH/rrnO/665 + y/+eqcb/lJ++/5KYu/+wuND/qLHL/7fA1P+irMv/oqrL/83R5f/NzeL/o6rE/6GrxP+quNL/v8zd/7C7 + y/+wuc7/r7nM/7bB0v+0vtD/sr3T/87V7//Qz+f/qrDR/7nA1v+iqL3/r7fJ/621x/+stcb/xM/i/7S6 + z//i5en//Pz8/97g6f/9/f3//v7+//7+/f/19vT/5ebg//Dy5P/k4+D//Pz9//39/f/8/Pz//Pz8//z8 + /P/8/Pz/+/r8/9HU3v/d3uv/x8nW/9nd6P/IzNn/09Tg/77E1f+pscX/u8fd/8HP2/+4xdX/pLDG/7vH + 1/+yv8v/srvK/6izx/+5xNb/lJ67/5qkvP+Pmrn/lKC+/6Krx/+vuNL/r7nP/52ryv/ByeX/zc7g/6Cl + wP+tuM3/n6vK/6+80v+wvM3/uMLS/7C6y/+zvc//s7zP/7TA1P/M0+7/wr/b/6y00v+7wtX/pazB/6y1 + x/+stcj/q7bI/8TO4f+mrMD/4ePp//f3+v/j5Oz//f39//39/f/9/Pz/5ubh//Hy5f/n5d7/+Pb2//39 + /f/8/Pz//Pz8//z8/P/8/Pz//f39//z9/f/q7O//x8vZ/9HS4f/d4+3/2N7o/9PT4P/Hy9v/vMPU/6Kt + yP++zNj/usfX/6GtwP+0wdD/rrnH/6u2xf+ircT/vcjY/5iivP+eqMD/l5+8/6auxP+lrcf/oqvF/7e9 + 1P+ZosP/tr3b/8zN4f+jpsX/tL7S/6Gsxv+wvNj/sb3R/7bA0P+3wtH/s73O/7S9z/+yvdL/v8fi/728 + 2P+wuNX/ucDU/6Wtw/+tuMv/q7bK/7O/0f+9xdb/r7XE/+Pk7v/h4ev/+Pf6//39/f/8/Pz/8vLv/+7t + 4//u7uT/5uXi//39/f/+/v7//v7+//7+/v/9/f3//f39//z8/P/8/Pz/+fr6/8/T3P++wdD/4Ofv/9/j + 8P/S1eP/0dbl/8TL2f+osc3/r7zQ/7rF1f+jrr3/o6/C/7C6y/+uucr/m6S+/7rG0/+jrcT/rrjO/5eh + v/+rtMr/qLDG/6+50v+osMj/oqvH/7G61P+9vtn/panH/7O+0/+yv9L/qbbT/6i0yP+yvM7/ucPV/7TC + 1P+3xNX/s77S/6620v+1s9L/tLzZ/7nB0/+uuM3/t8HT/7vE1v/By93/uL7O/8jL3P/m5/H/zdHi//z7 + /f/+/f3//v7+/+bm4//r7OP/4+Tc//r7+v/9/f3//Pz8//39/f/9/f3//v7+//39/f/8/Pz//Pz8//z8 + /P/t7vH/zM3c/9DX4f/f5vH/19vp/9nd7P/K0t//ytTk/5qlx/+0wNX/nqu7/5iiuP+ossT/q7XH/5qk + vf+0wM7/rrjM/7nD1f+msMv/rbjP/7a/0v+mscr/tsHW/6ixyP+nscj/q6/O/6mry/+zwtr/tsPW/6u4 + z/+7xdz/t8LX/8PQ3v+0wtX/u8jb/7zH1/+nr8z/razO/8HH4P/Cytr/wsze/8XP3P/P1+f/0Njn/8bL + 3P/R0+T/4uXw/+Hk7//9/f3//f39//39/f/Z2db/5+jg/9/f2v/9/f3//f39//z8/P/+/v7//v7+//z8 + /P/9/f3//f39//z8/P/7+/v/+vv7/9PU3//U1ej/3ubz/9vk8f/V3On/1dzs/9Tb6/+3wdn/m6bE/6Wv + wf+Klq3/q7XH/6qzxf+eqMD/sL7O/7S/0f+9x9n/r7rP/7C+1f++ytr/sr7U/7/I3P+yu9D/p7LM/6uy + zP+rr87/vMrg/8TO4P+8x9v/rbjV/7K+0v/N2er/vcvd/8DN4P+/ytj/rrbR/6Kkyf/P1Ov/xszg/8XP + 4f/X3+v/1dzq/9Tb6//a3u7/1tnq/87S4f/3+fz//v7+//39/f/7/Pz/1NbU/+fn4v/l5uP//f39//39 + /f/9/f3//f39//7+/v/9/f3//v7+//39/f/8/Pz//vz8//v7+//z8/X/19jn/9ji7f/f6PX/2ODt/9ff + 8f/U2+//0tvs/6awz/+Xn7n/hpCk/6y2yf+rtMb/o63E/6u5yf+xvc//vcja/7jE1/+wwNr/ytXn/7zI + 2/+uuM//0tnq/6izyv+2vtP/pKjI/8XQ5f/N1ub/ws7f/6i00P+1wtr/1N3t/8vW5//J1ef/yNPk/7a+ + 2P+nq9L/09vt/8TJ3v/FzeH/2ODr/9Td6v/V3e3/5ef2/87S4//e4ez//f39//39/f/9/f3/+/v7/9HU + 0//m5uH/4uPg//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/8/Pz//f39//7+/v/8/Pz//P39/+Di + 6f/b4e3/5ev4/+Ln9P/c4/P/xtDm/9jg7f/By9//nKfB/4WQpf+eqb3/srrL/6myx/+qtsf/sb/Q/7G9 + 1f/E0uX/rr3Z/87Z7f/L1uj/ytXn/7O90//FzeL/vcbb/5+lw//I0uX/0Nro/8vX6P++yuH/ssLb/8fP + 4v/Q2er/zNnq/83a7P+zvdb/t73a/87V5P/HzuD/xM3e/9Dc5v/R2+z/197v/+Pk8//M0OT/8/T4//39 + /f/+/v7//v7+//39/v/U2tr/5efi/9ze2//+/v3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39 + /f/9/f3//v7+//39/f/z9fj/4OHu/+Ln9f/g6fb/2+Xv/8fP5//V2u3/197t/7XB1v+Vn7n/lqG2/7jB + 0v+zvND/rrrL/7rG1v+ntNH/y9rr/7jG4f/N2vD/0tzu/9zg8P+8xdr/ydPl/7rC2/+lrsv/yc/k/9Xe + 7v/P2uv/0tzt/7bD3/+9xtz/1d7u/8/c7f/Q3vD/srzV/73H2v/Fzd3/w87f/8TO3v/P2uX/0tzs/97k + 9P/c2+v/19jp//z8/P/+/v7//f39//39/f/9/v7/2+Dg/+bp5f/X2tj/+Pr4//7+/v/+/v7//f39//7+ + /v/+/v7//f39//39/f/+/v7//v7+//39/f/9/f3//Pz9/+Tk6//e4e//4Oj3/9ri8f/T2u3/xc7h/9Xd + 7P/J1ej/t8HY/46Ysv/BzN7/wszd/7nE1f/G0OL/tsLY/8XS6v/K2O7/ytnv/9Pf8f/T2+n/1+Du/622 + 1P/R3Or/l6LC/77G3P/U3uz/zdfo/9Ld7/+4wt7/wszk/9ff8P/O2uz/0eDy/666z//L0+P/v8jX/77J + 2v/Ez97/z9nl/9Ha6f/b3+7/xsnh//Dx9//+/v3//f79//7+/v/+/v7//f39/+Ll5v/e5OT/5uvq/97h + 4P/9/fz//f39//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/9/f3//f39//39/v/09Pf/4OLs/9re + 7//X3e//zNbo/83W5//U3uz/zdvq/7jG2/+lss//t8LX/9Lc6f/Ez93/ztbo/8zX5v+5xuD/1ODy/87b + 7//U4PL/z9no/9vj8f+6xNv/xM7l/6+91P+3wdf/1t/w/8zX6f/S3/H/u8je/83Y7//DzOH/ytrr/9He + 8v+yvND/y9bi/7O90P+4wtT/wczb/9Hb6f++x9z/0dTo/87S5P/7/fv//v79//3+/f/+/v7//v7+//7+ + /v/5+/v/0tfa/+zw7v/h5uf/8vPz//39/f/9/f3//f39//39/f/9/f3//f39//7+/v/9/f3//f39//7+ + /v/+/v7//Pz8/+vr8P/g4fD/1Nzv/7rF4//M1+f/zNrp/8PS3P/Ay+D/sb3U/7nB2v/c4fL/0Njo/83V + 5v/a4vP/wMvi/9bh9P/P3e//0+Hz/87b7f/Y4e7/ztjp/6u11f/N2+r/s77X/9Pd7//J1ef/y9nr/8XT + 5v+/zuT/uMXe/8rY6v/S3/D/s7zS/8jT4P+wus7/t8LS/8LP2//O2eb/p7HP/7vA3f/19/r//f39//7+ + /v///////v7+//7+/v/+/v7//v7+/+nr7//m7O7/7PL0/+Lp7f/o6ez//v7+//39/f/+/v7//f39//39 + /f/9/f3//f39//7+/v/9/f3//f39//z8/P/6+fv/4ODs/9fd7v+4xeD/usng/8LS4P+8y9X/vs3Z/6y5 + zv+1v9P/0Nfq/9zh7v/V3e3/2eLy/9fh8f/L1+z/ztzu/83b7f/O2+3/0Nrs/9DZ6v+zwtb/zdjr/7G+ + 1//K1ej/ws7g/8XT5f/C0OD/s8Db/7XB3P/K1ub/1eHt/7C6z/+4wdf/s77O/7jD0f/Bzdj/s77U/7K5 + 1P/V3On/+/z8//39/f/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7/4ufs/+nw+P/t9v3/5u/1//7+ + /v/+/v7//f39//39/f/+/v7//f39//7+/v/+/v7//f39//7+/v/9/f3//f39//Du8//f4e3/1t3u/6y3 + 1v+0w9P/t8TR/7jE0P+xu8z/p7HG/7S+0v/f5PH/2uPw/9Td6//d5vT/zdnu/8vZ7P/K2Or/ytjq/8fW + 5f/N2Ob/x9Pk/7PB2P/N1+n/s8DT/8DN2/+9y9v/tsbX/6m40/+7yd7/wtDg/8rY5f+qtcv/sb3R/7G8 + zf+2ws3/vcbZ/6qz0P/Cyd//+Pr8//39/f/9/f3//f39//7+/v/+/v7//v7+///////+/v7//v7+//z9 + /f/i5+//4er0/+v1/v/9/f3//f39//7+/v/9/f3//Pz8//39/f/+/v7//v7+//39/f/9/f3//Pz8//39 + /f/8+/z/29vh/97e6//Ezd//prTH/6SwwP+krb3/o66+/56twP+fq7//zdjq/9fg7v/T3On/197r/9Tc + 7//H1en/xtTl/8PR4//Az97/x9Ti/8PR3f+ruc//zdjq/7O/0/+9ytn/v8ra/7HB0P+iscz/v8/l/7jG + 2v/Dz+H/nqfC/6exx/+yvcr/t8TS/6evyv+2vdv/3+Xu//z8+//9/f3//f39//7+/v/+/v7//v7+//7+ + /v///////v7+//7+/v/9/v7//f79/+rt8v/W4Oj//f39//39/f/9/f3//v7+//39/f/9/f3//v7+//7+ + /v/9/f3//v7+//7+/v/+/v7//f39//X2+P/X1uH/2tvm/7nD1v+frb3/m6Wz/5ijsf+dqLb/pbDC/7G8 + z//U3e3/1t/s/8bO3P/b4O//vMnh/77P3v/Az9//v8/e/77L2P/AzNj/tMHS/7C/1P+9ytv/rbzQ/7XC + 0v+qt8r/nanD/7zK3/+wutP/u8jc/6Kswf+stsb/sr7K/6q1yf+stNP/xc3k//r7+//9/f7//Pz8//7+ + /v/+/v7//v7+//7+/v////////////7+/v/+/v7//v7+//7+/v/+/v7//f3+//7+/v/8/Pz//f39//39 + /f/+/v7//v7+//7+/v/+/v7//v7+//z8/P/+/v7//v7+//39/f/7/Pz/6ert/9LS3f/U2eb/sbnN/7q/ + 0/+bprv/kpyy/5unuP+ap7r/zdXo/9Tc7f/I0eD/zdbj/8bR5f+xwNf/u8nY/7nG1v+5xdP/u8fS/7C9 + yv+Ypr//x9Pg/6GuyP+wucv/pbLF/5Ohuf+zwdf/pbHL/6+70v+ttMb/sLnI/7G7zf+usc3/v8Lc//b2 + +//9+/v//fz9//7+/v/9/f3//v7+//////////////////7+/v/+/v7///////////////////////7+ + /v/9/f3//Pz8//39/f/9/f3//v7+//7+/v/9/f3//v7+//7+/v/+/v7//f39//39/f/9/f3//f39//z8 + /P/f3+n/u8DS/87S3v/Z2uf/4+Tw/+Tn8f+nsMT/mKS0/664zP/T2uj/0Nzn/73G1f/L1uL/qLbQ/6+6 + yv+yvs7/rbfI/7G7zP+ns8T/l6S6/7G9zv+ltcn/pK/C/5unuv+Pn7T/s8DV/6i0zv+osMj/sbnL/6m0 + x/+ssMv/srXR/+bq8f/7+/v/+/v7//z8/P/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//// + ///+/v7//v7+//39/f/+/v7//f39//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//v7+//7+ + /v/9/f3//Pz8//79/f/9+/v/0NTh/9vf6/+rssb/5ubt/8XH2/+/xdj/2t7o/5ieuf+Uobf/yNLk/9Hc + 5v/Czd7/vcfX/8XR4f+eq8L/pbDC/6GqvP+hq7z/oa2//5ypvf+lssb/s7/Q/52pvf+WorT/kJyy/7XB + 1P+rtc7/pa3E/6CrwP+vtMv/rrDL/8rO4f/7+vr//f39//7+/v/+/v7//v7+//7+/v/+/v7///////// + ///+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ + /v/+/v7//v7+//7+/v/9/f3//f39//7+/v/+/f3/+/n8/83S4P/Kz97/3eDr/7S4z/+qr8X/yMvf/8rR + 4v/GzeL/4OXv/6ayyv/Y4ez/ydbl/7rF1f/G0t3/tsLV/5upvf+cprj/mqK0/5ynuf+WorT/n6m8/7/K + 2f+Tn7P/n6i6/5mitv+2wdL/naO//52lvf+rrsT/pKbB/8DE2f/29/r/+vn7//z8/P/9/f3//v7+//7+ + /v/+/v7//v7+///////+/v7///////7+/v/+/v7//v7+//7+/v///////v7+//7+/v/9/f7//v7+//7+ + /v/+/v7//v7+//7+/v/+/v7//f39//7+/v/+/v7//v7+//3+/v/+/v7//vz8//z7+/+7wdj/xsnf/+fq + 9f/Axdr/ys/h/622y//q6vT/r7fP/8nK3P+psMr/xs3f/87b6f/Ez9//uMLS/7/L1/+stsz/lKC0/5ad + rv+bpLT/nae5/6Gpu/+3wNP/qbTL/7vB0//Kz9z/q63G/6OkwP+srMf/lZi5/7K3z//09Pj//f39//39 + /f/+/v7//v7+//7+/v/+/v7//f39//7+/v///////v7+//7+/v/+/v7///////7+/v/+/v7///////7+ + /v//////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/UI/Main/Main.Designer.cs b/UI/Main/Main.Designer.cs new file mode 100644 index 0000000..cae7ec4 --- /dev/null +++ b/UI/Main/Main.Designer.cs @@ -0,0 +1,618 @@ +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Desktop.Library.Component; + +namespace Milimoe.FunGame.Desktop.UI +{ + partial class Main + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); + this.Exit = new FunGame.Desktop.Library.Component.ExitButton(this.components); + this.MinForm = new Library.Component.MinButton(); + this.Connection = new System.Windows.Forms.Label(); + this.Light = new System.Windows.Forms.Label(); + this.SendTalkText = new System.Windows.Forms.Button(); + this.TalkText = new System.Windows.Forms.TextBox(); + this.StartMatch = new System.Windows.Forms.Button(); + this.CheckMix = new System.Windows.Forms.CheckBox(); + this.CheckTeam = new System.Windows.Forms.CheckBox(); + this.RoomSetting = new System.Windows.Forms.Button(); + this.Login = new System.Windows.Forms.Button(); + this.NowAccount = new System.Windows.Forms.Label(); + this.AccountSetting = new System.Windows.Forms.Button(); + this.About = new System.Windows.Forms.Button(); + this.Room = new System.Windows.Forms.Label(); + this.RoomText = new System.Windows.Forms.TextBox(); + this.PresetText = new System.Windows.Forms.ComboBox(); + this.RoomBox = new System.Windows.Forms.GroupBox(); + this.QueryRoom = new System.Windows.Forms.Button(); + this.RoomList = new System.Windows.Forms.ListBox(); + this.Notice = new System.Windows.Forms.GroupBox(); + this.NoticeText = new FunGame.Desktop.Library.Component.TextArea(); + this.InfoBox = new System.Windows.Forms.GroupBox(); + this.TransparentRectControl = new FunGame.Desktop.Library.Component.TransparentRect(); + this.GameInfo = new FunGame.Desktop.Library.Component.TextArea(); + this.QuitRoom = new System.Windows.Forms.Button(); + this.CreateRoom = new System.Windows.Forms.Button(); + this.Logout = new System.Windows.Forms.Button(); + this.CheckHasPass = new System.Windows.Forms.CheckBox(); + this.Stock = new System.Windows.Forms.Button(); + this.Store = new System.Windows.Forms.Button(); + this.Copyright = new System.Windows.Forms.LinkLabel(); + this.StopMatch = new System.Windows.Forms.Button(); + this.RoomBox.SuspendLayout(); + this.Notice.SuspendLayout(); + this.InfoBox.SuspendLayout(); + this.TransparentRectControl.SuspendLayout(); + this.SuspendLayout(); + // + // Exit + // + this.Exit.Anchor = System.Windows.Forms.AnchorStyles.None; + this.Exit.BackColor = System.Drawing.Color.White; + this.Exit.BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.exit; + this.Exit.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.Exit.FlatAppearance.BorderSize = 0; + this.Exit.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); + this.Exit.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); + this.Exit.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.Exit.Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.Exit.ForeColor = System.Drawing.Color.Red; + this.Exit.Location = new System.Drawing.Point(750, 3); + this.Exit.Name = "Exit"; + this.Exit.Size = new System.Drawing.Size(47, 47); + this.Exit.TabIndex = 15; + this.Exit.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.Exit.UseVisualStyleBackColor = false; + this.Exit.Click += new System.EventHandler(this.Exit_Click); + // + // Title + // + this.Title.BackColor = System.Drawing.Color.Transparent; + this.Title.Font = new System.Drawing.Font("LanaPixel", 26.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.Title.Location = new System.Drawing.Point(3, 3); + this.Title.Name = "Title"; + this.Title.Size = new System.Drawing.Size(689, 47); + this.Title.TabIndex = 96; + this.Title.Text = "FunGame By Mili.cyou"; + this.Title.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // MinForm + // + this.MinForm.Anchor = System.Windows.Forms.AnchorStyles.None; + this.MinForm.BackColor = System.Drawing.Color.White; + this.MinForm.BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.min; + this.MinForm.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.MinForm.FlatAppearance.BorderColor = System.Drawing.Color.LightGray; + this.MinForm.FlatAppearance.BorderSize = 0; + this.MinForm.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray; + this.MinForm.FlatAppearance.MouseOverBackColor = System.Drawing.Color.DarkGray; + this.MinForm.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.MinForm.Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.MinForm.ForeColor = System.Drawing.Color.Red; + this.MinForm.Location = new System.Drawing.Point(698, 3); + this.MinForm.Name = "MinForm"; + this.MinForm.Size = new System.Drawing.Size(47, 47); + this.MinForm.TabIndex = 14; + this.MinForm.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.MinForm.UseVisualStyleBackColor = false; + this.MinForm.RelativeForm = this; + // + // Connection + // + this.Connection.BackColor = System.Drawing.Color.Transparent; + this.Connection.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Connection.Location = new System.Drawing.Point(649, 424); + this.Connection.Margin = new System.Windows.Forms.Padding(3); + this.Connection.Name = "Connection"; + this.Connection.Size = new System.Drawing.Size(130, 23); + this.Connection.TabIndex = 92; + this.Connection.Text = "等待连接服务器"; + this.Connection.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // Light + // + this.Light.BackColor = System.Drawing.Color.Transparent; + this.Light.Image = global::Milimoe.FunGame.Desktop.Properties.Resources.yellow; + this.Light.Location = new System.Drawing.Point(777, 426); + this.Light.Name = "Light"; + this.Light.Size = new System.Drawing.Size(18, 18); + this.Light.TabIndex = 93; + // + // SendTalkText + // + this.SendTalkText.Anchor = System.Windows.Forms.AnchorStyles.None; + this.SendTalkText.BackColor = System.Drawing.Color.Transparent; + this.SendTalkText.BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.send; + this.SendTalkText.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.SendTalkText.FlatAppearance.BorderSize = 0; + this.SendTalkText.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Teal; + this.SendTalkText.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); + this.SendTalkText.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.SendTalkText.Font = new System.Drawing.Font("LanaPixel", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.SendTalkText.Location = new System.Drawing.Point(608, 421); + this.SendTalkText.Name = "SendTalkText"; + this.SendTalkText.Size = new System.Drawing.Size(51, 27); + this.SendTalkText.TabIndex = 3; + this.SendTalkText.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.SendTalkText.UseVisualStyleBackColor = false; + this.SendTalkText.Click += new System.EventHandler(this.SendTalkText_Click); + // + // TalkText + // + this.TalkText.AllowDrop = true; + this.TalkText.Font = new System.Drawing.Font("LanaPixel", 12.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.TalkText.ForeColor = System.Drawing.Color.DarkGray; + this.TalkText.Location = new System.Drawing.Point(317, 422); + this.TalkText.Name = "TalkText"; + this.TalkText.Size = new System.Drawing.Size(289, 26); + this.TalkText.TabIndex = 2; + this.TalkText.Text = "向消息队列发送消息..."; + this.TalkText.WordWrap = false; + this.TalkText.Click += new System.EventHandler(this.TalkText_ClickAndFocused); + this.TalkText.GotFocus += new System.EventHandler(this.TalkText_ClickAndFocused); + this.TalkText.KeyUp += new System.Windows.Forms.KeyEventHandler(this.TalkText_KeyUp); + this.TalkText.Leave += new System.EventHandler(this.TalkText_Leave); + // + // StartMatch + // + this.StartMatch.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.StartMatch.Location = new System.Drawing.Point(665, 184); + this.StartMatch.Name = "StartMatch"; + this.StartMatch.Size = new System.Drawing.Size(132, 35); + this.StartMatch.TabIndex = 9; + this.StartMatch.Text = "开始匹配"; + this.StartMatch.UseVisualStyleBackColor = true; + this.StartMatch.Click += new System.EventHandler(this.StartMatch_Click); + // + // CheckMix + // + this.CheckMix.BackColor = System.Drawing.Color.Transparent; + this.CheckMix.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.CheckMix.Location = new System.Drawing.Point(675, 94); + this.CheckMix.Name = "CheckMix"; + this.CheckMix.Size = new System.Drawing.Size(123, 24); + this.CheckMix.TabIndex = 6; + this.CheckMix.Text = "混战模式房间"; + this.CheckMix.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + this.CheckMix.UseVisualStyleBackColor = false; + this.CheckMix.CheckedChanged += new System.EventHandler(this.CheckMix_CheckedChanged); + // + // CheckTeam + // + this.CheckTeam.BackColor = System.Drawing.Color.Transparent; + this.CheckTeam.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.CheckTeam.Location = new System.Drawing.Point(675, 124); + this.CheckTeam.Name = "CheckTeam"; + this.CheckTeam.Size = new System.Drawing.Size(123, 24); + this.CheckTeam.TabIndex = 7; + this.CheckTeam.Text = "团队模式房间"; + this.CheckTeam.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + this.CheckTeam.UseVisualStyleBackColor = false; + this.CheckTeam.CheckedChanged += new System.EventHandler(this.CheckTeam_CheckedChanged); + // + // RoomSetting + // + this.RoomSetting.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.RoomSetting.Location = new System.Drawing.Point(665, 225); + this.RoomSetting.Name = "RoomSetting"; + this.RoomSetting.Size = new System.Drawing.Size(132, 35); + this.RoomSetting.TabIndex = 10; + this.RoomSetting.Text = "房间设置"; + this.RoomSetting.UseVisualStyleBackColor = true; + this.RoomSetting.Visible = false; + this.RoomSetting.Click += new System.EventHandler(this.RoomSetting_Click); + // + // Login + // + this.Login.Font = new System.Drawing.Font("LanaPixel", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Login.Location = new System.Drawing.Point(665, 380); + this.Login.Name = "Login"; + this.Login.Size = new System.Drawing.Size(132, 39); + this.Login.TabIndex = 13; + this.Login.Text = "登录账号"; + this.Login.UseVisualStyleBackColor = true; + this.Login.Click += new System.EventHandler(this.Login_Click); + // + // NowAccount + // + this.NowAccount.BackColor = System.Drawing.Color.Transparent; + this.NowAccount.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.NowAccount.Location = new System.Drawing.Point(659, 352); + this.NowAccount.Name = "NowAccount"; + this.NowAccount.Size = new System.Drawing.Size(141, 25); + this.NowAccount.TabIndex = 91; + this.NowAccount.Text = "请登录账号"; + this.NowAccount.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // AccountSetting + // + this.AccountSetting.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.AccountSetting.Location = new System.Drawing.Point(665, 317); + this.AccountSetting.Name = "AccountSetting"; + this.AccountSetting.Size = new System.Drawing.Size(65, 32); + this.AccountSetting.TabIndex = 11; + this.AccountSetting.Text = "设置"; + this.AccountSetting.UseVisualStyleBackColor = true; + // + // About + // + this.About.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.About.Location = new System.Drawing.Point(732, 317); + this.About.Name = "About"; + this.About.Size = new System.Drawing.Size(65, 32); + this.About.TabIndex = 12; + this.About.Text = "关于"; + this.About.UseVisualStyleBackColor = true; + // + // Room + // + this.Room.BackColor = System.Drawing.Color.Transparent; + this.Room.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Room.Location = new System.Drawing.Point(665, 263); + this.Room.Name = "Room"; + this.Room.Size = new System.Drawing.Size(132, 45); + this.Room.TabIndex = 90; + this.Room.Text = "房间号:114514"; + this.Room.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // RoomText + // + this.RoomText.AllowDrop = true; + this.RoomText.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.RoomText.ForeColor = System.Drawing.Color.DarkGray; + this.RoomText.Location = new System.Drawing.Point(6, 226); + this.RoomText.Name = "RoomText"; + this.RoomText.Size = new System.Drawing.Size(114, 25); + this.RoomText.TabIndex = 1; + this.RoomText.Text = "键入房间代号..."; + this.RoomText.WordWrap = false; + this.RoomText.Click += new System.EventHandler(this.RoomText_ClickAndFocused); + this.RoomText.GotFocus += new System.EventHandler(this.RoomText_ClickAndFocused); + this.RoomText.KeyUp += new System.Windows.Forms.KeyEventHandler(this.RoomText_KeyUp); + this.RoomText.Leave += new System.EventHandler(this.RoomText_Leave); + // + // PresetText + // + this.PresetText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.PresetText.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.PresetText.Font = new System.Drawing.Font("LanaPixel", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.PresetText.FormattingEnabled = true; + this.PresetText.Items.AddRange(new object[] { "- 快捷消息 -" }); + this.PresetText.Location = new System.Drawing.Point(195, 422); + this.PresetText.Name = "PresetText"; + this.PresetText.Size = new System.Drawing.Size(121, 26); + this.PresetText.TabIndex = 1; + this.PresetText.SelectedIndexChanged += new System.EventHandler(this.PresetText_SelectedIndexChanged); + // + // RoomBox + // + this.RoomBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.RoomBox.BackColor = System.Drawing.Color.Transparent; + this.RoomBox.Controls.Add(this.QueryRoom); + this.RoomBox.Controls.Add(this.RoomList); + this.RoomBox.Controls.Add(this.RoomText); + this.RoomBox.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.RoomBox.Location = new System.Drawing.Point(3, 56); + this.RoomBox.Name = "RoomBox"; + this.RoomBox.Size = new System.Drawing.Size(186, 258); + this.RoomBox.TabIndex = 0; + this.RoomBox.TabStop = false; + this.RoomBox.Text = "房间列表"; + // + // QueryRoom + // + this.QueryRoom.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.QueryRoom.Location = new System.Drawing.Point(126, 225); + this.QueryRoom.Name = "QueryRoom"; + this.QueryRoom.Size = new System.Drawing.Size(51, 27); + this.QueryRoom.TabIndex = 2; + this.QueryRoom.Text = "加入"; + this.QueryRoom.UseVisualStyleBackColor = true; + this.QueryRoom.Click += new System.EventHandler(this.QueryRoom_Click); + // + // RoomList + // + this.RoomList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.RoomList.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.RoomList.FormattingEnabled = true; + this.RoomList.ItemHeight = 19; + this.RoomList.Location = new System.Drawing.Point(0, 26); + this.RoomList.Name = "RoomList"; + this.RoomList.Size = new System.Drawing.Size(186, 192); + this.RoomList.TabIndex = 0; + this.RoomList.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.RoomList_MouseDoubleClick); + // + // Notice + // + this.Notice.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.Notice.BackColor = System.Drawing.Color.Transparent; + this.Notice.Controls.Add(this.NoticeText); + this.Notice.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Notice.Location = new System.Drawing.Point(3, 317); + this.Notice.Name = "Notice"; + this.Notice.Size = new System.Drawing.Size(186, 110); + this.Notice.TabIndex = 94; + this.Notice.TabStop = false; + this.Notice.Text = "通知公告"; + // + // NoticeText + // + this.NoticeText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.NoticeText.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.NoticeText.EmptyTextTip = null; + this.NoticeText.Location = new System.Drawing.Point(6, 24); + this.NoticeText.Name = "NoticeText"; + this.NoticeText.ReadOnly = true; + this.NoticeText.Size = new System.Drawing.Size(174, 86); + this.NoticeText.TabIndex = 0; + this.NoticeText.Text = ""; + // + // InfoBox + // + this.InfoBox.BackColor = System.Drawing.Color.Transparent; + this.InfoBox.Controls.Add(this.TransparentRectControl); + this.InfoBox.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.InfoBox.Location = new System.Drawing.Point(195, 56); + this.InfoBox.Name = "InfoBox"; + this.InfoBox.Size = new System.Drawing.Size(464, 363); + this.InfoBox.TabIndex = 95; + this.InfoBox.TabStop = false; + this.InfoBox.Text = "消息队列"; + // + // TransparentRectControl + // + this.TransparentRectControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TransparentRectControl.BackColor = System.Drawing.Color.Transparent; + this.TransparentRectControl.BorderColor = System.Drawing.Color.Transparent; + this.TransparentRectControl.Controls.Add(this.GameInfo); + this.TransparentRectControl.Location = new System.Drawing.Point(0, 20); + this.TransparentRectControl.Name = "TransparentRectControl"; + this.TransparentRectControl.Opacity = 125; + this.TransparentRectControl.Radius = 20; + this.TransparentRectControl.ShapeBorderStyle = Milimoe.FunGame.Desktop.Library.Component.TransparentRect.ShapeBorderStyles.ShapeBSNone; + this.TransparentRectControl.Size = new System.Drawing.Size(464, 343); + this.TransparentRectControl.TabIndex = 2; + this.TransparentRectControl.TabStop = false; + // + // GameInfo + // + this.GameInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.GameInfo.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.GameInfo.EmptyTextTip = null; + this.GameInfo.EmptyTextTipColor = System.Drawing.Color.Transparent; + this.GameInfo.Location = new System.Drawing.Point(6, 6); + this.GameInfo.Name = "GameInfo"; + this.GameInfo.ReadOnly = true; + this.GameInfo.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; + this.GameInfo.Size = new System.Drawing.Size(452, 331); + this.GameInfo.TabIndex = 1; + this.GameInfo.Text = ""; + // + // QuitRoom + // + this.QuitRoom.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.QuitRoom.Location = new System.Drawing.Point(665, 184); + this.QuitRoom.Name = "QuitRoom"; + this.QuitRoom.Size = new System.Drawing.Size(132, 35); + this.QuitRoom.TabIndex = 9; + this.QuitRoom.Text = "退出房间"; + this.QuitRoom.UseVisualStyleBackColor = true; + this.QuitRoom.Visible = false; + this.QuitRoom.Click += new System.EventHandler(this.QuitRoom_Click); + // + // CreateRoom + // + this.CreateRoom.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.CreateRoom.Location = new System.Drawing.Point(665, 225); + this.CreateRoom.Name = "CreateRoom"; + this.CreateRoom.Size = new System.Drawing.Size(132, 35); + this.CreateRoom.TabIndex = 10; + this.CreateRoom.Text = "创建房间"; + this.CreateRoom.UseVisualStyleBackColor = true; + this.CreateRoom.Click += new System.EventHandler(this.CreateRoom_Click); + // + // Logout + // + this.Logout.Font = new System.Drawing.Font("LanaPixel", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Logout.Location = new System.Drawing.Point(665, 380); + this.Logout.Name = "Logout"; + this.Logout.Size = new System.Drawing.Size(132, 39); + this.Logout.TabIndex = 13; + this.Logout.Text = "退出登录"; + this.Logout.UseVisualStyleBackColor = true; + this.Logout.Visible = false; + this.Logout.Click += new System.EventHandler(this.Logout_Click); + // + // CheckHasPass + // + this.CheckHasPass.BackColor = System.Drawing.Color.Transparent; + this.CheckHasPass.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.CheckHasPass.Location = new System.Drawing.Point(675, 154); + this.CheckHasPass.Name = "CheckHasPass"; + this.CheckHasPass.Size = new System.Drawing.Size(123, 24); + this.CheckHasPass.TabIndex = 8; + this.CheckHasPass.Text = "带密码的房间"; + this.CheckHasPass.TextAlign = System.Drawing.ContentAlignment.BottomLeft; + this.CheckHasPass.UseVisualStyleBackColor = false; + this.CheckHasPass.CheckedChanged += new System.EventHandler(this.CheckHasPass_CheckedChanged); + // + // Stock + // + this.Stock.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Stock.Location = new System.Drawing.Point(661, 56); + this.Stock.Name = "Stock"; + this.Stock.Size = new System.Drawing.Size(65, 32); + this.Stock.TabIndex = 4; + this.Stock.Text = "库存"; + this.Stock.UseVisualStyleBackColor = true; + // + // Store + // + this.Store.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Store.Location = new System.Drawing.Point(732, 56); + this.Store.Name = "Store"; + this.Store.Size = new System.Drawing.Size(65, 32); + this.Store.TabIndex = 5; + this.Store.Text = "商店"; + this.Store.UseVisualStyleBackColor = true; + // + // Copyright + // + this.Copyright.ActiveLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.Copyright.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.Copyright.BackColor = System.Drawing.Color.Transparent; + this.Copyright.Font = new System.Drawing.Font("LanaPixel", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Copyright.LinkArea = new System.Windows.Forms.LinkArea(6, 10); + this.Copyright.LinkBehavior = System.Windows.Forms.LinkBehavior.AlwaysUnderline; + this.Copyright.LinkColor = System.Drawing.Color.Teal; + this.Copyright.Location = new System.Drawing.Point(3, 430); + this.Copyright.Name = "Copyright"; + this.Copyright.Size = new System.Drawing.Size(186, 23); + this.Copyright.TabIndex = 97; + this.Copyright.TabStop = true; + this.Copyright.Text = FunGameInfo.FunGame_CopyRight; + this.Copyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.Copyright.UseCompatibleTextRendering = true; + this.Copyright.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.Copyright_LinkClicked); + // + // StopMatch + // + this.StopMatch.Font = new System.Drawing.Font("LanaPixel", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.StopMatch.Location = new System.Drawing.Point(665, 184); + this.StopMatch.Name = "StopMatch"; + this.StopMatch.Size = new System.Drawing.Size(132, 35); + this.StopMatch.TabIndex = 9; + this.StopMatch.Text = "停止匹配"; + this.StopMatch.UseVisualStyleBackColor = true; + this.StopMatch.Visible = false; + this.StopMatch.Click += new System.EventHandler(this.StopMatch_Click); + // + // Main + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackgroundImage = global::Milimoe.FunGame.Desktop.Properties.Resources.back; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.StopMatch); + this.Controls.Add(this.Copyright); + this.Controls.Add(this.Store); + this.Controls.Add(this.Stock); + this.Controls.Add(this.Logout); + this.Controls.Add(this.RoomSetting); + this.Controls.Add(this.QuitRoom); + this.Controls.Add(this.InfoBox); + this.Controls.Add(this.CreateRoom); + this.Controls.Add(this.Notice); + this.Controls.Add(this.RoomBox); + this.Controls.Add(this.PresetText); + this.Controls.Add(this.SendTalkText); + this.Controls.Add(this.TalkText); + this.Controls.Add(this.Room); + this.Controls.Add(this.About); + this.Controls.Add(this.AccountSetting); + this.Controls.Add(this.NowAccount); + this.Controls.Add(this.Login); + this.Controls.Add(this.CheckHasPass); + this.Controls.Add(this.CheckTeam); + this.Controls.Add(this.CheckMix); + this.Controls.Add(this.StartMatch); + this.Controls.Add(this.Light); + this.Controls.Add(this.Connection); + this.Controls.Add(this.MinForm); + this.Controls.Add(this.Title); + this.Controls.Add(this.Exit); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Main"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "FunGame"; + this.RoomBox.ResumeLayout(false); + this.RoomBox.PerformLayout(); + this.Notice.ResumeLayout(false); + this.InfoBox.ResumeLayout(false); + this.TransparentRectControl.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private ExitButton Exit; + private MinButton MinForm; + private Label Connection; + private Label Light; + private Button StartMatch; + private CheckBox CheckMix; + private CheckBox CheckTeam; + private Button RoomSetting; + private Button Login; + private Label NowAccount; + private Button AccountSetting; + private Button About; + private Label Room; + private Button SendTalkText; + private TextBox TalkText; + private TextBox RoomText; + private ComboBox PresetText; + private GroupBox RoomBox; + private ListBox RoomList; + private GroupBox Notice; + private GroupBox InfoBox; + private Button QuitRoom; + private Button CreateRoom; + private Button QueryRoom; + private Button Logout; + private CheckBox CheckHasPass; + private Button Stock; + private Button Store; + private LinkLabel Copyright; + private Button StopMatch; + private Library.Component.TextArea GameInfo; + private Library.Component.TextArea NoticeText; + private Library.Component.TransparentRect TransparentRectControl; + } +} \ No newline at end of file diff --git a/UI/Main/Main.cs b/UI/Main/Main.cs new file mode 100644 index 0000000..98effba --- /dev/null +++ b/UI/Main/Main.cs @@ -0,0 +1,1375 @@ +using System.Diagnostics; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Controller; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Library.Base; +using Milimoe.FunGame.Desktop.Library.Component; +using Milimoe.FunGame.Desktop.Utility; + +namespace Milimoe.FunGame.Desktop.UI +{ + public partial class Main : BaseMain + { + + #region 变量定义 + + /** + * 定义全局变量 + */ + public int MaxRetryTimes { get; } = SocketSet.MaxRetryTimes; // 最大重试连接次数 + public int CurrentRetryTimes { get; set; } = -1; // 当前重试连接次数 + + /** + * 定义全局对象 + */ + private Task? MatchFunGame = null; // 匹配线程 + private MainController? MainController = null; + + /** + * 定义委托 + * 子线程操作窗体控件时,先实例化Action,然后Invoke传递出去。 + */ + Action? StartMatch_Action = null; + Action? CreateRoom_Action = null; + + public Main() + { + InitializeComponent(); + InitAsync(); + } + + /// + /// 所有自定义初始化的内容 + /// + public async void InitAsync() + { + RunTime.Main = this; + SetButtonEnableIfLogon(false, ClientState.WaitConnect); + SetRoomid("-1"); // 房间号初始化 + ShowFunGameInfo(); // 显示FunGame信息 + GetFunGameConfig(); // 获取FunGame配置 + // 创建RunTime + RunTime.Connector = new RunTimeController(this); + // 窗口句柄创建后,进行委托 + await Task.Factory.StartNew(() => + { + while (true) + { + if (IsHandleCreated) + { + break; + } + } + if (Config.FunGame_isAutoConnect) RunTime.Connector?.GetServerConnection(); + }); + } + + /// + /// 绑定事件 + /// + protected override void BindEvent() + { + base.BindEvent(); + Disposed += Main_Disposed; + FailedConnect += FailedConnectEvent; + SucceedConnect += SucceedConnectEvent; + SucceedLogin += SucceedLoginEvent; + } + + #endregion + + #region 公有方法 + + /// + /// 提供公共方法给Controller更新UI + /// + /// string? + /// object[]? + public void UpdateUI(MainInvokeType type, params object[]? objs) + { + void action() + { + try + { + switch (type) + { + case MainInvokeType.SetGreen: + Config.FunGame_isRetrying = false; + SetServerStatusLight((int)LightType.Green); + SetButtonEnableIfLogon(true, ClientState.Online); + Config.FunGame_isConnected = true; + CurrentRetryTimes = 0; + break; + + case MainInvokeType.SetGreenAndPing: + Config.FunGame_isRetrying = false; + SetServerStatusLight((int)LightType.Green, ping: NetworkUtility.GetServerPing(Constant.Server_Address)); + SetButtonEnableIfLogon(true, ClientState.Online); + Config.FunGame_isConnected = true; + CurrentRetryTimes = 0; + break; + + case MainInvokeType.SetYellow: + Config.FunGame_isRetrying = false; + SetServerStatusLight((int)LightType.Yellow); + SetButtonEnableIfLogon(false, ClientState.WaitConnect); + Config.FunGame_isConnected = true; + CurrentRetryTimes = 0; + break; + + case MainInvokeType.WaitConnectAndSetYellow: + Config.FunGame_isRetrying = false; + SetServerStatusLight((int)LightType.Yellow); + SetButtonEnableIfLogon(false, ClientState.WaitConnect); + Config.FunGame_isConnected = true; + CurrentRetryTimes = 0; + if (MainController != null && Config.FunGame_isAutoConnect) + { + // 自动连接服务器 + RunTime.Connector?.Connect(); + } + break; + + case MainInvokeType.WaitLoginAndSetYellow: + Config.FunGame_isRetrying = false; + SetServerStatusLight((int)LightType.Yellow, true); + SetButtonEnableIfLogon(false, ClientState.WaitLogin); + Config.FunGame_isConnected = true; + CurrentRetryTimes = 0; + break; + + case MainInvokeType.SetRed: + SetServerStatusLight((int)LightType.Red); + SetButtonEnableIfLogon(false, ClientState.WaitConnect); + Config.FunGame_isConnected = false; + break; + + case MainInvokeType.Disconnected: + RoomList.Items.Clear(); + Config.FunGame_isRetrying = false; + Config.FunGame_isConnected = false; + SetServerStatusLight((int)LightType.Red); + SetButtonEnableIfLogon(false, ClientState.WaitConnect); + LogoutAccount(); + MainController?.Dispose(); + CloseConnectedWindows(); + break; + + case MainInvokeType.Disconnect: + RoomList.Items.Clear(); + Config.FunGame_isAutoRetry = false; + Config.FunGame_isRetrying = false; + Config.FunGame_isAutoConnect = false; + Config.FunGame_isAutoLogin = false; + Config.FunGame_isConnected = false; + SetServerStatusLight((int)LightType.Yellow); + SetButtonEnableIfLogon(false, ClientState.WaitConnect); + LogoutAccount(); + MainController?.Dispose(); + break; + + case MainInvokeType.LogIn: + break; + + case MainInvokeType.LogOut: + Config.FunGame_isRetrying = false; + Config.FunGame_isAutoLogin = false; + SetServerStatusLight((int)LightType.Yellow, true); + SetButtonEnableIfLogon(false, ClientState.WaitLogin); + LogoutAccount(); + if (objs != null && objs.Length > 0) + { + if (objs[0].GetType() == typeof(string)) + { + WritelnSystemInfo((string)objs[0]); + ShowMessage.Message((string)objs[0], "退出登录", 5); + } + } + break; + + case MainInvokeType.SetUser: + if (objs != null && objs.Length > 0) + { + LoginAccount(objs); + } + break; + + case MainInvokeType.Connected: + NoticeText.Text = Config.FunGame_Notice; + break; + + case MainInvokeType.UpdateRoom: + if (objs != null && objs.Length > 0) + { + List list = (List)objs[0]; + RoomList.Items.AddRange(list.ToArray()); + } + break; + + default: + break; + } + } + catch (Exception e) + { + WritelnGameInfo(e.GetErrorInfo()); + UpdateUI(MainInvokeType.SetRed); + } + } + InvokeUpdateUI(action); + } + + /// + /// 提供公共方法给Controller发送系统信息 + /// + /// + /// + public void GetMessage(string? msg, TimeType timetype = TimeType.TimeOnly) + { + void action() + { + try + { + if (msg == null || msg == "") return; + if (timetype != TimeType.None) + { + WritelnGameInfo(DateTimeUtility.GetDateTimeToString(timetype) + " >> " + msg); + } + else + { + WritelnGameInfo(msg); + } + } + catch (Exception e) + { + WritelnGameInfo(e.GetErrorInfo()); + } + }; + InvokeUpdateUI(action); + } + + #endregion + + #region 实现 + + /// + /// 委托更新UI + /// + /// + private void InvokeUpdateUI(Action action) + { + if (InvokeRequired) Invoke(action); + else action(); + } + + /// + /// 获取FunGame配置文件设定 + /// + private void GetFunGameConfig() + { + try + { + if (INIHelper.ExistINIFile()) + { + string isAutoConnect = INIHelper.ReadINI("Config", "AutoConnect"); + string isAutoLogin = INIHelper.ReadINI("Config", "AutoLogin"); + string strUserName = INIHelper.ReadINI("Account", "UserName"); + string strPassword = INIHelper.ReadINI("Account", "Password"); + string strAutoKey = INIHelper.ReadINI("Account", "AutoKey"); + + if (isAutoConnect != null && isAutoConnect.Trim() != "" && (isAutoConnect.ToLower().Equals("false") || isAutoConnect.ToLower().Equals("true"))) + Config.FunGame_isAutoConnect = Convert.ToBoolean(isAutoConnect); + else throw new ReadConfigException(); + + if (isAutoLogin != null && isAutoLogin.Trim() != "" && (isAutoLogin.ToLower().Equals("false") || isAutoLogin.ToLower().Equals("true"))) + Config.FunGame_isAutoLogin = Convert.ToBoolean(isAutoLogin); + else throw new ReadConfigException(); + + if (strUserName != null && strUserName.Trim() != "") + Config.FunGame_AutoLoginUser = strUserName.Trim(); + + if (strPassword != null && strPassword.Trim() != "") + Config.FunGame_AutoLoginPassword = strPassword.Trim(); + + if (strAutoKey != null && strAutoKey.Trim() != "") + Config.FunGame_AutoLoginKey = strAutoKey.Trim(); + } + else + { + INIHelper.Init((FunGameInfo.FunGame)Constant.FunGameType); + WritelnGameInfo(">> 首次启动,已自动为你创建配置文件。"); + GetFunGameConfig(); + } + } + catch (System.Exception e) + { + WritelnGameInfo(e.GetErrorInfo()); + } + } + + /// + /// 设置房间号和显示信息 + /// + /// + private void SetRoomid(string roomid) + { + Config.FunGame_Roomid = roomid; + if (!roomid.Equals("-1")) + { + WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 加入房间"); + WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 已加入房间 -> [ " + Config.FunGame_Roomid + " ]"); + Room.Text = "[ 当前房间 ]\n" + Convert.ToString(Config.FunGame_Roomid); + } + else + Room.Text = "暂未进入房间"; + } + + /// + /// 向消息队列输出换行符 + /// + private void WritelnGameInfo() + { + GameInfo.AppendText("\n"); + GameInfo.SelectionStart = GameInfo.Text.Length - 1; + GameInfo.ScrollToCaret(); + } + + /// + /// 向消息队列输出一行文字 + /// + /// + private void WritelnGameInfo(string msg) + { + if (msg.Trim() != "") + { + GameInfo.AppendText(msg + "\n"); + GameInfo.SelectionStart = GameInfo.Text.Length - 1; + GameInfo.ScrollToCaret(); + } + } + + /// + /// 向消息队列输出文字 + /// + /// + private void WriteGameInfo(string msg) + { + if (msg.Trim() != "") + { + GameInfo.AppendText(msg); + GameInfo.SelectionStart = GameInfo.Text.Length - 1; + GameInfo.ScrollToCaret(); + } + } + + /// + /// 向消息队列输出一行系统信息 + /// + /// + private void WritelnSystemInfo(string msg) + { + msg = DateTimeUtility.GetDateTimeToString(TimeType.TimeOnly) + " >> " + msg; + WritelnGameInfo(msg); + } + + /// + /// 在大厅中,设置按钮的显示和隐藏 + /// + private void InMain() + { + // 显示:匹配、创建房间 + // 隐藏:退出房间、房间设定 + SetRoomid("-1"); + QuitRoom.Visible = false; + StartMatch.Visible = true; + RoomSetting.Visible = false; + CreateRoom.Visible = true; + } + + /// + /// 在房间中,设置按钮的显示和隐藏 + /// + private void InRoom() + { + // 显示:退出房间、房间设置 + // 隐藏:停止匹配、创建房间 + StopMatch.Visible = false; + QuitRoom.Visible = true; + CreateRoom.Visible = false; + RoomSetting.Visible = true; + } + + /// + /// 未登录和离线时,停用按钮 + /// 登录的时候要激活按钮 + /// + /// 是否登录 + /// 客户端状态 + private void SetButtonEnableIfLogon(bool isLogon, ClientState status) + { + switch (status) + { + case ClientState.Online: + PresetText.Items.Clear(); + PresetText.Items.AddRange(Constant.PresetOnineItems); + break; + case ClientState.WaitConnect: + PresetText.Items.Clear(); + PresetText.Items.AddRange(Constant.PresetNoConnectItems); + break; + case ClientState.WaitLogin: + PresetText.Items.Clear(); + PresetText.Items.AddRange(Constant.PresetNoLoginItems); + break; + } + this.PresetText.SelectedIndex = 0; + CheckMix.Enabled = isLogon; + CheckTeam.Enabled = isLogon; + CheckHasPass.Enabled = isLogon; + StartMatch.Enabled = isLogon; + CreateRoom.Enabled = isLogon; + RoomBox.Enabled = isLogon; + AccountSetting.Enabled = isLogon; + Stock.Enabled = isLogon; + Store.Enabled = isLogon; + } + + /// + /// 加入房间 + /// + /// + /// + private void JoinRoom(bool isDouble, string roomid) + { + if (!isDouble) + if (!RoomText.Text.Equals("") && !RoomText.ForeColor.Equals(Color.DarkGray)) + { + if (CheckRoomIDExist(roomid)) + { + if (Config.FunGame_Roomid.Equals("-1")) + { + if (ShowMessage.YesNoMessage("已找到房间 -> [ " + roomid + " ]\n是否加入?", "已找到房间") == MessageResult.Yes) + { + SetRoomid(roomid); + InRoom(); + } + } + else + { + ShowMessage.TipMessage("你需要先退出房间才可以加入新的房间。"); + } + } + else + { + ShowMessage.WarningMessage("未找到此房间!"); + } + } + else + { + RoomText.Enabled = false; + ShowMessage.TipMessage("请输入房间号。"); + RoomText.Enabled = true; + RoomText.Focus(); + } + else + { + if (CheckRoomIDExist(roomid)) + { + if (Config.FunGame_Roomid.Equals("-1")) + { + if (ShowMessage.YesNoMessage("已找到房间 -> [ " + roomid + " ]\n是否加入?", "已找到房间") == MessageResult.Yes) + { + SetRoomid(roomid); + InRoom(); + } + } + else + { + ShowMessage.TipMessage("你需要先退出房间才可以加入新的房间。"); + } + } + else + { + ShowMessage.WarningMessage("未找到此房间!"); + } + } + } + + /// + /// 这里实现匹配相关的方法 + /// + /// 主要参数:触发方法的哪一个分支 + /// 可传多个参数 + private void StartMatch_Method(int i, object[]? objs = null) + { + switch (i) + { + case (int)StartMatchState.Matching: + // 开始匹配 + Config.FunGame_isMatching = true; + int loop = 0; + string roomid = Convert.ToString(new Random().Next(1, 10000)); + // 匹配中 匹配成功返回房间号 + Task.Factory.StartNew(() => + { + // 创建新线程,防止主界面阻塞 + Thread.Sleep(3000); + while (loop < 10000 && Config.FunGame_isMatching) + { + loop++; + if (loop == Convert.ToInt32(roomid)) + { + // 创建委托,操作主界面 + StartMatch_Action = (int i, object[]? objs) => + { + StartMatch_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(StartMatch_Action, (int)StartMatchState.Success, new object[] { roomid }); + } + else + { + StartMatch_Action((int)StartMatchState.Success, new object[] { roomid }); + } + break; + } + } + }); + break; + case (int)StartMatchState.Success: + Config.FunGame_isMatching = false; + // 匹配成功返回房间号 + roomid = "-1"; + if (objs != null) roomid = (string)objs[0]; + if (!roomid.Equals(-1)) + { + WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 匹配成功"); + WritelnGameInfo(">> 房间号: " + roomid); + SetRoomid(roomid); + } + else + { + WritelnGameInfo("ERROR:匹配失败!"); + break; + } + // 设置按钮可见性 + InRoom(); + // 创建委托,操作主界面 + StartMatch_Action = (i, objs) => + { + StartMatch_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(StartMatch_Action, (int)StartMatchState.Enable, new object[] { true }); + } + else + { + StartMatch_Action((int)StartMatchState.Enable, new object[] { true }); + } + MatchFunGame = null; + break; + case (int)StartMatchState.Enable: + // 设置匹配过程中的各种按钮是否可用 + bool isPause = false; + if (objs != null) isPause = (bool)objs[0]; + CheckMix.Enabled = isPause; + CheckTeam.Enabled = isPause; + CheckHasPass.Enabled = isPause; + CreateRoom.Enabled = isPause; + RoomBox.Enabled = isPause; + Login.Enabled = isPause; + break; + case (int)StartMatchState.Cancel: + WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 终止匹配"); + WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 已终止匹配。"); + Config.FunGame_isMatching = false; + StartMatch_Action = (i, objs) => + { + StartMatch_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(StartMatch_Action, (int)StartMatchState.Enable, new object[] { true }); + } + else + { + StartMatch_Action((int)StartMatchState.Enable, new object[] { true }); + } + MatchFunGame = null; + StopMatch.Visible = false; + StartMatch.Visible = true; + break; + } + } + + /// + /// 登录账号,显示登出按钮 + /// + private void LoginAccount(params object[]? objs) + { + if (objs != null && objs.Length > 0) + { + Usercfg.LoginUser = (User)objs[0]; + if (Usercfg.LoginUser is null) + { + throw new NoUserLogonException(); + } + Usercfg.LoginUserName = Usercfg.LoginUser.Username; + } + NowAccount.Text = "[ID] " + Usercfg.LoginUserName; + Login.Visible = false; + Logout.Visible = true; + UpdateUI(MainInvokeType.SetGreenAndPing); + string welcome = $"欢迎回来, {Usercfg.LoginUserName}!"; + ShowMessage.Message(welcome, "登录成功", 5); + WritelnSystemInfo(welcome); + } + + /// + /// 登出账号,显示登录按钮 + /// + private void LogoutAccount() + { + InMain(); + Usercfg.LoginUser = null; + Usercfg.LoginUserName = ""; + NowAccount.Text = "请登录账号"; + Logout.Visible = false; + Login.Visible = true; + } + + /// + /// 终止匹配实现方法 + /// + private void StopMatch_Click() + { + StartMatch_Action = (i, objs) => + { + StartMatch_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(StartMatch_Action, (int)StartMatchState.Cancel, new object[] { true }); + } + else + { + StartMatch_Action((int)StartMatchState.Cancel, new object[] { true }); + } + } + + /// + /// 发送消息实现 + /// + /// 是否离开焦点 + private void SendTalkText_Click(bool isLeave) + { + // 向消息队列发送消息 + string text = TalkText.Text; + if (text.Trim() != "" && !TalkText.ForeColor.Equals(Color.DarkGray)) + { + string msg; + if (Usercfg.LoginUserName == "") + { + msg = ":> " + text; + } + else + { + msg = DateTimeUtility.GetNowShortTime() + " [ " + Usercfg.LoginUserName + " ] 说: " + text; + } + WritelnGameInfo(msg); + if (Usercfg.LoginUser != null && !SwitchTalkMessage(text)) + { + MainController?.Chat(" [ " + Usercfg.LoginUserName + " ] 说: " + text); + } + TalkText.Text = ""; + if (isLeave) TalkText_Leave(); // 回车不离开焦点 + } + else + { + TalkText.Enabled = false; + ShowMessage.TipMessage("消息不能为空,请重新输入。"); + TalkText.Enabled = true; + TalkText.Focus(); + } + } + + /// + /// 发送消息实现,往消息队列发送消息 + /// + /// + private void SendTalkText_Click(string msg) + { + WritelnGameInfo((!Usercfg.LoginUserName.Equals("") ? DateTimeUtility.GetNowShortTime() + " [ " + Usercfg.LoginUserName + " ] 说: " : ":> ") + msg); + } + + /// + /// 焦点离开聊天框时设置灰色文本 + /// + private void TalkText_Leave() + { + if (TalkText.Text.Equals("")) + { + TalkText.ForeColor = Color.DarkGray; + TalkText.Text = "向消息队列发送消息..."; + } + } + + /// + /// 这里实现创建房间相关的方法 + /// + /// 主要参数:触发方法的哪一个分支 + /// 可传多个参数 + private void CreateRoom_Method(int i, object[]? objs = null) + { + if (!Config.FunGame_Roomid.Equals("-1")) + { + ShowMessage.WarningMessage("已在房间中,无法创建房间。"); + return; + } + string roomid = ""; + string roomtype = ""; + if (objs != null) + { + roomtype = (string)objs[0]; + } + switch (i) + { + case (int)CreateRoomState.Creating: + CreateRoom_Action = (i, objs) => + { + CreateRoom_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(CreateRoom_Action, (int)CreateRoomState.Success, new object[] { roomtype }); + } + else + { + CreateRoom_Action((int)CreateRoomState.Success, new object[] { roomtype }); + } + break; + case (int)CreateRoomState.Success: + roomid = Convert.ToString(new Random().Next(1, 10000)); + SetRoomid(roomid); + InRoom(); + WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 创建" + roomtype + "房间"); + WritelnGameInfo(">> 创建" + roomtype + "房间成功!房间号: " + roomid); + ShowMessage.Message("创建" + roomtype + "房间成功!\n房间号是 -> [ " + roomid + " ]", "创建成功"); + break; + } + } + + /// + /// 设置服务器连接状态指示灯 + /// + /// + /// + private void SetServerStatusLight(int light, bool waitlogin = false, int ping = 0) + { + switch(light) + { + case (int)LightType.Green: + Connection.Text = "服务器连接成功"; + this.Light.Image = Properties.Resources.green; + break; + case (int)LightType.Yellow: + Connection.Text = waitlogin ? "等待登录账号" : "等待连接服务器"; + this.Light.Image = Properties.Resources.yellow; + break; + case (int)LightType.Red: + default: + Connection.Text = "服务器连接失败"; + this.Light.Image = Properties.Resources.red; + break; + } + if (ping > 0) + { + Connection.Text = "心跳延迟 " + ping + "ms"; + if (ping < 100) + this.Light.Image = Properties.Resources.green; + else if (ping >= 100 && ping < 200) + this.Light.Image = Properties.Resources.yellow; + else if (ping >= 200) + this.Light.Image = Properties.Resources.red; + } + } + + /// + /// 显示FunGame信息 + /// + private void ShowFunGameInfo() + { + WritelnGameInfo(FunGameInfo.GetInfo((FunGameInfo.FunGame)Constant.FunGameType)); + } + + /// + /// 关闭所有登录后才能访问的窗口 + /// + private static void CloseConnectedWindows() + { + RunTime.Login?.Close(); + RunTime.Register?.Close(); + RunTime.Store?.Close(); + RunTime.Inventory?.Close(); + RunTime.RoomSetting?.Close(); + RunTime.UserCenter?.Close(); + } + + #endregion + + #region 事件 + + /// + /// 关闭程序 + /// + /// + /// + private void Exit_Click(object sender, EventArgs e) + { + if (ShowMessage.OKCancelMessage("你确定关闭游戏?", "退出") == (int)MessageResult.OK) + { + RunTime.Connector?.Close(); + Environment.Exit(0); + } + } + + /// + /// 开始匹配 + /// + /// + /// + private void StartMatch_Click(object sender, EventArgs e) + { + // 开始匹配 + WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 开始匹配"); + WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 开始匹配"); + WriteGameInfo(">> 匹配参数:"); + if (!Config.Match_Mix && !Config.Match_Team && !Config.Match_HasPass) + WritelnGameInfo("无"); + else + { + WriteGameInfo((Config.Match_Mix ? " 混战房间 " : "") + (Config.Match_Team ? " 团队房间 " : "") + (Config.Match_HasPass ? " 密码房间 " : "")); + WritelnGameInfo(); + } + // 显示停止匹配按钮 + StartMatch.Visible = false; + StopMatch.Visible = true; + // 暂停其他按钮 + StartMatch_Method((int)StartMatchState.Enable, new object[] { false }); + // 创建委托,开始匹配 + StartMatch_Action = (i, objs) => + { + StartMatch_Method(i, objs); + }; + // 创建新线程匹配 + MatchFunGame = Task.Factory.StartNew(() => + { + + if (InvokeRequired) + { + Invoke(StartMatch_Action, (int)StartMatchState.Matching, null); + } + else + { + StartMatch_Action((int)StartMatchState.Matching, null); + } + }); + } + + /// + /// 创建房间 + /// + /// + /// + private void CreateRoom_Click(object sender, EventArgs e) + { + string roomtype = ""; + if (Config.Match_Mix && Config.Match_Team) + { + ShowMessage.WarningMessage("创建房间不允许同时勾选混战和团队!"); + return; + } + else if (Config.Match_Mix && !Config.Match_Team && !Config.Match_HasPass) + { + roomtype = Constant.GameMode_Mix; + } + else if (!Config.Match_Mix && Config.Match_Team && !Config.Match_HasPass) + { + roomtype = Constant.GameMode_Team; + } + else if (Config.Match_Mix && !Config.Match_Team && Config.Match_HasPass) + { + roomtype = Constant.GameMode_MixHasPass; + } + else if (!Config.Match_Mix && Config.Match_Team && Config.Match_HasPass) + { + roomtype = Constant.GameMode_TeamHasPass; + } + if (roomtype.Equals("")) + { + ShowMessage.WarningMessage("请勾选你要创建的房间类型!"); + return; + } + CreateRoom_Action = (i, objs) => + { + CreateRoom_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(CreateRoom_Action, (int)CreateRoomState.Creating, new object[] { roomtype }); + } + else + { + CreateRoom_Action((int)CreateRoomState.Creating, new object[] { roomtype }); + } + } + + /// + /// 退出房间 + /// + /// + /// + private void QuitRoom_Click(object sender, EventArgs e) + { + WritelnGameInfo(DateTimeUtility.GetNowShortTime() + " 离开房间"); + WritelnGameInfo("[ " + Usercfg.LoginUserName + " ] 已离开房间 -> [ " + Config.FunGame_Roomid + " ]"); + InMain(); + } + + /// + /// 房间设置 + /// + /// + /// + private void RoomSetting_Click(object sender, EventArgs e) + { + + } + + /// + /// 查找房间 + /// + /// + /// + private void QueryRoom_Click(object sender, EventArgs e) + { + JoinRoom(false, RoomText.Text); + } + + /// + /// 登出 + /// + /// + /// + private void Logout_Click(object sender, EventArgs e) + { + if (ShowMessage.OKCancelMessage("你确定要退出登录吗?", "退出登录") == MessageResult.OK) + { + if (MainController == null || !MainController.LogOut()) + ShowMessage.WarningMessage("请求无效:退出登录失败!"); + } + } + + /// + /// 登录 + /// + /// + /// + private void Login_Click(object sender, EventArgs e) + { + if (MainController != null && Config.FunGame_isConnected) + OpenForm.SingleForm(FormType.Login, OpenFormType.Dialog); + else + ShowMessage.WarningMessage("请先连接服务器!"); + } + + /// + /// 终止匹配 + /// + /// + /// + private void StopMatch_Click(object sender, EventArgs e) + { + StopMatch_Click(); + } + + /// + /// 双击房间列表中的项可以加入房间 + /// + /// + /// + private void RoomList_MouseDoubleClick(object sender, MouseEventArgs e) + { + #pragma warning disable CS8600, CS8604 + if (RoomList.SelectedItem != null) + JoinRoom(true, RoomList.SelectedItem.ToString()); + } + + /// + /// 点击发送消息 + /// + /// + /// + private void SendTalkText_Click(object sender, EventArgs e) + { + SendTalkText_Click(true); + } + + /// + /// 勾选混战选项 + /// + /// + /// + private void CheckMix_CheckedChanged(object sender, EventArgs e) + { + if (CheckMix.Checked) Config.Match_Mix = true; + else Config.Match_Mix = false; + } + + /// + /// 勾选团队选项 + /// + /// + /// + private void CheckTeam_CheckedChanged(object sender, EventArgs e) + { + if (CheckTeam.Checked) Config.Match_Team = true; + else Config.Match_Team = false; + } + + /// + /// 勾选密码选项 + /// + /// + /// + private void CheckHasPass_CheckedChanged(object sender, EventArgs e) + { + if (CheckHasPass.Checked) Config.Match_HasPass = true; + else Config.Match_HasPass = false; + } + + /// + /// 房间号输入框点击/焦点事件 + /// + /// + /// + private void RoomText_ClickAndFocused(object sender, EventArgs e) + { + if (RoomText.Text.Equals("键入房间代号...")) + { + RoomText.ForeColor = Color.DarkGray; + RoomText.Text = ""; + } + } + + /// + /// 焦点离开房间号输入框事件 + /// + /// + /// + private void RoomText_Leave(object sender, EventArgs e) + { + if (RoomText.Text.Equals("")) + { + RoomText.ForeColor = Color.DarkGray; + RoomText.Text = "键入房间代号..."; + } + } + + /// + /// 房间号输入框内容改变事件 + /// + /// + /// + private void RoomText_KeyUp(object sender, KeyEventArgs e) + { + RoomText.ForeColor = Color.Black; + if (e.KeyCode.Equals(Keys.Enter)) + { + // 按下回车加入房间 + JoinRoom(false, RoomText.Text); + } + } + + /// + /// 聊天框点击/焦点事件 + /// + /// + /// + private void TalkText_ClickAndFocused(object sender, EventArgs e) + { + if (TalkText.Text.Equals("向消息队列发送消息...")) + { + TalkText.ForeColor = Color.DarkGray; + TalkText.Text = ""; + } + } + + /// + /// TalkText离开焦点事件 + /// + /// + /// + private void TalkText_Leave(object sender, EventArgs e) + { + TalkText_Leave(); + } + + /// + /// 聊天框内容改变事件 + /// + /// + /// + private void TalkText_KeyUp(object sender, KeyEventArgs e) + { + TalkText.ForeColor = Color.Black; + if (e.KeyCode.Equals(Keys.Enter)) + { + // 按下回车发送 + SendTalkText_Click(false); + } + } + + /// + /// 版权链接点击事件 + /// + /// + /// + private void Copyright_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + // Copyright 2023 mili.cyou + Process.Start(new ProcessStartInfo("https://mili.cyou/fungame") { UseShellExecute = true }); + } + + /// + /// 点击快捷消息 + /// + /// + /// + private void PresetText_SelectedIndexChanged(object sender, EventArgs e) + { + // 发送快捷消息并执行功能 + if (PresetText.SelectedIndex != 0) + { + string s = PresetText.SelectedItem.ToString(); + SendTalkText_Click(s); + SwitchTalkMessage(s); + PresetText.SelectedIndex = 0; + } + } + + private void Main_Disposed(object? sender, EventArgs e) + { + MainController?.Dispose(); + } + + /// + /// 连接服务器失败后触发事件 + /// + /// + /// + /// + public EventResult FailedConnectEvent(object sender, GeneralEventArgs e) + { + // 自动重连 + if (Config.FunGame_isConnected && Config.FunGame_isAutoRetry && CurrentRetryTimes <= MaxRetryTimes) + { + Task.Run(() => + { + Thread.Sleep(5000); + if (Config.FunGame_isConnected && Config.FunGame_isAutoRetry) RunTime.Connector?.Connect(); // 再次判断是否开启自动重连 + }); + GetMessage("连接服务器失败,5秒后自动尝试重连。"); + } + else GetMessage("无法连接至服务器,请检查你的网络连接。"); + return EventResult.Success; + } + + /// + /// 连接服务器成功后触发事件 + /// + /// + /// + /// + public EventResult SucceedConnectEvent(object sender, GeneralEventArgs e) + { + // 创建MainController + MainController = new MainController(this); + if (MainController != null && Config.FunGame_isAutoLogin && Config.FunGame_AutoLoginUser != "" && Config.FunGame_AutoLoginPassword != "" && Config.FunGame_AutoLoginKey != "") + { + // 自动登录 + _ = RunTime.Connector?.AutoLogin(Config.FunGame_AutoLoginUser, Config.FunGame_AutoLoginPassword, Config.FunGame_AutoLoginKey); + } + return EventResult.Success; + } + + /// + /// 登录成功后触发事件 + /// + /// + /// + /// + private EventResult SucceedLoginEvent(object sender, GeneralEventArgs e) + { + // 接入-1号房间聊天室 + MainController?.IntoRoom("-1"); + // 获取在线的房间列表 + MainController?.UpdateRoom(); + return EventResult.Success; + } + + #endregion + + #region 工具方法 + + /// + /// 判断是否存在这个房间 + /// + /// + /// + private bool CheckRoomIDExist(string roomid) + { + foreach (string BoxText in RoomList.Items) + { + if (roomid.Equals(BoxText)) + { + return true; + } + } + return false; + } + + /// + /// 判断快捷消息 + /// + /// + private bool SwitchTalkMessage(string s) + { + switch (s) + { + case Constant.FunGame_SignIn: + break; + case Constant.FunGame_ShowCredits: + break; + case Constant.FunGame_ShowStock: + break; + case Constant.FunGame_ShowStore: + break; + case Constant.FunGame_CreateMix: + CreateRoom_Action = (i, objs) => + { + CreateRoom_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(CreateRoom_Action, (int)CreateRoomState.Creating, new object[] { Constant.GameMode_Mix }); + } + else + { + CreateRoom_Action((int)CreateRoomState.Creating, new object[] { Constant.GameMode_Mix }); + } + break; + case Constant.FunGame_CreateTeam: + CreateRoom_Action = (i, objs) => + { + CreateRoom_Method(i, objs); + }; + if (InvokeRequired) + { + Invoke(CreateRoom_Action, (int)CreateRoomState.Creating, new object[] { Constant.GameMode_Team }); + } + else + { + CreateRoom_Action((int)CreateRoomState.Creating, new object[] { Constant.GameMode_Team }); + } + break; + case Constant.FunGame_StartGame: + break; + case Constant.FunGame_AutoRetryOn: + WritelnGameInfo(">> 自动重连开启"); + Config.FunGame_isAutoRetry = true; + break; + case Constant.FunGame_AutoRetryOff: + WritelnGameInfo(">> 自动重连关闭"); + Config.FunGame_isAutoRetry = false; + break; + case Constant.FunGame_Retry: + if (!Config.FunGame_isRetrying) + { + CurrentRetryTimes = -1; + Config.FunGame_isAutoRetry = true; + RunTime.Connector?.Connect(); + } + else + WritelnGameInfo(">> 你不能在连接服务器的同时重试连接!"); + break; + case Constant.FunGame_Connect: + if (!Config.FunGame_isConnected) + { + CurrentRetryTimes = -1; + Config.FunGame_isAutoRetry = true; + RunTime.Connector?.GetServerConnection(); + } + break; + case Constant.FunGame_Disconnect: + if (Config.FunGame_isConnected && MainController != null) + { + // 先退出登录再断开连接 + if (MainController?.LogOut() ?? false) RunTime.Connector?.Disconnect(); + } + break; + case Constant.FunGame_DisconnectWhenNotLogin: + if (Config.FunGame_isConnected && MainController != null) + { + RunTime.Connector?.Disconnect(); + } + break; + case Constant.FunGame_ConnectTo: + string msg = ShowMessage.InputMessage("请输入服务器IP地址和端口号,如: 127.0.0.1:22222。", "连接指定服务器"); + if (msg.Equals("")) return true; + string[] addr = msg.Split(':'); + string ip; + int port; + if (addr.Length < 2) + { + ip = addr[0]; + port = 22222; + } + else if (addr.Length < 3) + { + ip = addr[0]; + port = Convert.ToInt32(addr[1]); + } + else + { + ShowMessage.ErrorMessage("格式错误!\n这不是一个服务器地址。"); + return true; + } + ErrorType ErrorType = NetworkUtility.IsServerAddress(ip, port); + if (ErrorType == Core.Library.Constant.ErrorType.None) + { + Constant.Server_Address = ip; + Constant.Server_Port = port; + CurrentRetryTimes = -1; + Config.FunGame_isAutoRetry = true; + RunTime.Connector?.Connect(); + } + else if (ErrorType == Core.Library.Constant.ErrorType.IsNotIP) ShowMessage.ErrorMessage("这不是一个IP地址!"); + else if (ErrorType == Core.Library.Constant.ErrorType.IsNotPort) ShowMessage.ErrorMessage("这不是一个端口号!\n正确范围:1~65535"); + else ShowMessage.ErrorMessage("格式错误!\n这不是一个服务器地址。"); + break; + default: + break; + } + return false; + } + + #endregion + } +} \ No newline at end of file diff --git a/UI/Main/Main.resx b/UI/Main/Main.resx new file mode 100644 index 0000000..c3678a7 --- /dev/null +++ b/UI/Main/Main.resx @@ -0,0 +1,453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA + AAC8x9z/x9Tp/7zH3f+8wdv/xMrf/9nh6/+/xdb/3eTv/9PY5//T0uL/6OHu/+nl7f/X1uH/5+Pf/+jl + 3f/g4eP/5eft/+rp6//p5+f/6efi/+zo5P/u5+T/7ebj/+zm4//p4+X/4uHi/9zg4//e3N7/09HX//Px + 9//9+/v/4eDr/9TV6//e3ev/7+/y//Pv9P/+/Pz/9fH2/+fh6//X1+T/v77V/9bT3f/U09v/xsXP/9TQ + 2v/h3eb/39zk/97c5//d3Ob/3Nzn/6OqxP+cp8f/mqXI/8HG3f/L1ur/6fD7/9XZ5//q6u//9/b5/8nP + 2f/U2uX/1tri/7/H4P/P1er/ucTc/7rF3P/AxeD/x8vc/8fL2v/Cydj/2uPw/+Hq8f/Hy+H/6OLs/+Hb + 6P/Cv9n/z9Dg/+3q6f/o4+D/5eLh/+Tk5P/o5uf/6Obl/+nn4v/p5eD/7ebi/+rk3v/p5uD/5+Xj/+Di + 4v/c2tz/vr7N/6ipx//T0t//+/n6/+Ph7f/S0+P/8fH1/+zr8P/7+Pr/+fb3/+ji7P/n5PH/1tPl/8jL + 2P/Qztn/3tvl/9TR2v/j3+j/4d3l/+Db5f/a2OL/393n/93d6v+2u9b/zNHn/+Hq+P/j6/v/5e75/8/U + 6f/W2eX/7uzy//Ly9f/Hy9n/zNPg/+Lo7/+zutX/w8ni/7W/3f+st9T/ycri/8jH2f++wNj/1t3s/+Dn + 7//V3er/19Tk/9nX5f+2udT/4dro/8fF2v/k5Ob/7Ofk/+nl4v/n4uL/5uTi/+fl4//o5uH/6uXg/+zm + 3//s5+D/7Ojg/+nm4P/j4OD/wsLR/+Lf6v+vrcb/6+rz/9fW5P/Q0Ob/7ez1//Hu8//39/n//Pr7/+rm + 7f/r5fD/0c7j/+vo9f/T1eP/5OLt/9vY4//j3+j/5N/o/+Pf5//W0dz/29jj/9/e6f/h3+r/ztHh/87U + 6f+1udL/sLnU/7jC1//U1ub/9PL1//Px9v/j4uz/w8fc/8/W4P/K0dz/sbzV/7nF4P+nsM7/yM3j/83M + 3P/Kyt3/0Nbn/9ng6P/Z3ur/x8ve/9XV5P/BxNb/v73U/8fH2v/Z1uP/trXL/+rl4//r5uH/6OTf/+Xl + 3//j493/5+Xe/+vm3//r5d7/6eTe/+nl3P/m4dr/19LN/83J0//q4en/19Pi/9bT3v/o5O//2NXn//bz + 9v/x8fX/+/r8//Hu8//o4uz/3Nfj/8K91//p4u//3N3o/8jH1v/V0d7/5+Tt/+rl7P/X1d//0tPd/9/b + 5v/k3ub/yMrd/9XZ5f/Nz+T/xMXb/4ySsP/T1OL/5+Xp//Hv8//k5Ov/1Nbm/7zD3P+8xtb/tL7U/622 + z//BzOb/pa/L/8bH2//Oy9z/wcjb/9La4//K0+D/y9Hi//Lz9//h3On/2dbm/8jG2//k3uz/39jo/9LS + 5P/d2dz/6+Xh/+rl4f/n5N3/6OXe/+nk3P/q5d3/6eXc/+rn3f/l4db/4tvS/87Iv//Exs3/6+Xu/97d + 7P/X1OX/3NTl/9bZ6f/18fb/8fD0//n2+v/n5e3/5d3r/8nF2P/d2Oj/4dvl//f0+f+4u83/2dXg/+vp + 7//a2OH/z8/c/9fW4v/c2uT/3dzk/7K1zf/X2+n/x83h/8rJ3P+sr8n/t7zO/+Pl6v/r6fH/1NPf/9HV + 4/+6w9j/uMHU/7vF1/+vu9b/2d/v/7jB1f/Cxtr/ub/R/8TL1v/Cytb/vsfY/7vB1f/JyNn/xcTY/+bi + 6//LyN3/6uLv/9DP4f/49/n/2tjg/+vl3//o5N7/5uHa/+Tf1//j4NX/5N3T/9zUxf/Tybf/zcKs/8K4 + oP+xqpb/vr7K/9fS4v/g3en/zMzk/7Kz1P/v8PX/7ezx//36/P/07/b/5t/t/8O90v/Kx9n/7+ju//Ht + 9v/59vj/wcPV/97a5f/m5ez/ycnV/9HQ3f/a2+X/2tjj/9/c6f+fp8b/yM3m/9Ta6P/Bwdf/2tvl/4qR + pf/q6O//zc/c/9DT4f/J0N3/wMva/8HN2v+6xdn/1dnt//Lz+P+9ydz/rrjO/77H0v+/x9P/vMTR/8zQ + 2f/V1d7/2Nnm/7u80//Kyd7/3+Dy/9/e8f/LzOP/9fT3/9rZ4f/p5d//6eLd/+Pf1v/Oycz/xcTM/769 + wv+rqan/rKej/6Oemf+hmpf/h4OO/9PP3v/s5fD/4+Du/87Q3//V1er/8vP1/+np7f/08fX/5+Lr/9rT + 4f+3tcr/tKvF/9vT5v/r5/D/1tbj/9LO4f/d1+L/2Nvj/9TS3v/Rz9r/3d/p/97e6P/GyNz/uL7X/8/V + 5f/n7/X/ur/V/+nn7P+dpLb/pae6/8/Q4f/L0d//x9Lg/9Hb5//P2OX/1+Dw/+Pn7//8/Pz/qbXQ/8LP + 5v+vuM7/wcrU/62yzP/a1uH/29jh/8rL4P/OzOP/2drn//r6/P/y8/r/ys7j//Pz+f/CwNL/2NPN/9vU + y//AwsX/29rl/87Q3f/IzN3/pazD/9bX5v/a1eH/49nl/6qkwP/k3uz/8Ozy/9fX5//V1+X/8/H2/+/t + 8//y7/T/6OLr/+Xf6v/Mx9r/1M/e/+fj7//V1uX/y8zd/+ro8v/Kx9f/4+Lp/8jJ1f/Z1eL/1NDb/+Pg + 6//e4Or/t7zV/7/F2//Dy+H/5e31/83U4v/k5vD/x8zW/3aBmf+WoLn/i5iv/8LJ4P/X4Ov/1tvs/9Ta + 7P/e4ev//f39/7LB1/+3xdz/xNHl/5mowP/Cxdz/2dfh/93Z5v+1tdD/5eDt/9TT4//7+vr/7+3z/9LV + 5f/q5fP/w8Pb/66ko/+1saz/8/L0//z6+v/9+/v/+ff3/+zr8P/g3+j/4d7x/+Lc6v+5u9P/8O/1//Hv + 9v/V1uP/29vo//Xy9//o4+z/7uny/+rk7f/a1ub/v7rT/9rV5P/p5u//9/X3//j2+v/P0Nr/vr3R/+ro + 7//Jytb/2Nfk/9jT3//i4Oz/4eLs/77B2P/JzOH/uL/d/+Po9f/s7/b/v8TW/5Kbt/+Hj7D/jZm2/6i1 + zP+gqsX/zNLj/+Ll7//T2uf/2t7q//39/f+2xNj/vs3h/9fj8f/AzeP/tbvR/9zY5P/a2uP/pafA/8PD + 1//v8vb/+/n7/9vb5f/19/j/4+Lu/9fV5/+vq8D/ubjD//z5+//9+fr//fv6//bz9f/j3+r/7ez0/+bj + 9P/T0OH/6Ofz//r4/P/19Pb/2Nrl/9zd6f/p5ez/6ePt/+3o8f/p4e3/vLjO/9DL2//k4u7/8+73//jz + 9v/8+vr/09Xl/7O2zf/o5ev/5unu/8zO2f/X1uD/3Nzl/+Xo7/+/wtv/y87k/7zC3P/U3Oz/6u/2/7G4 + 0P+Vnb7/hpCw/4OMr/+HkLL/qLHJ/+ru8f/8+/z/xMre/+3v9f/8/Pz/2uHu/7fD3f/X4vH/2+fx/8TP + 3//DxNT/3trn/7q6zv+2us//y87f/8TF3f/U0+T/+vr4//P1+v/c2u3/087e/8G/0v/8+vv//vz8//z6 + +v/w7PH/49zs/8/N3v/z8fj/8fH4//37/P/+/f3//Pv8/9nb5f/Y1+b/3dfk/+3m7//p4u3/5uDt/8PA + 2P/Oydv/4uDs//z6+//7+vv/6+ju/8PF1f/m5e3/3drk/+zr8f/q7fP/zc/b/9bY4v/m6fD/3eTt/7G5 + 2P/HzuP/ys3h//Dw+P/Iz9//mqTF/4mVtf+5wNX/jJey/+Xl8P/7+vz/+vr8/8HH2f/8+/z//f39/77G + 4v+8yN//wM/k/93p8v/U3un/u8TT/83M3f/Lx9j/4dzl/+Ld5v/Kx9r/19fl//z8/P/6+/z/4+L1/+Hb + 6v/BvtL/+vj7//37/P/j4+n/29rl/9jT4f/Gxdj/3trm/+jn7f/39fb//fv7//38+//U1eL/09Dg/9rU + 4P/w6e7/6OHs/9jX5v/i4+7/5OLt/+Tl8f/8+/v/+ff7/9HQ3v/k4Oj/9PDz/9zY5P/h4Of/6+zy/+nr + 8f/Lzdf/4eTs/+js8v/S2en/qrTU/9fb7v/l7fP/6fL4/9fg7/+yvdL/gpCr/5+qv//4+Pz/+/v9/9zd + 6P/f4+z/+/76//39/f+ls9L/t8Xc/7nJ4f/Czd//ytTg/8LO1/+sscf/xsXZ/+DY5f/f2uX/1dPh/8XF + 2v/o6PH//Pv8/+vp+f/f3Ov/zc3e//P09v/9/Pz//fv8//v6+//m5u//ycfZ/97Y5//Y0+T/yczb/+vs + 8v/39vv/ysva/9XX5v/f2+r/497o/9nS3v++uM3/9/P5//v7+f/z8/n/+fr7//T09//V1OT/49/n//Ds + 8//W0Nv/29ji/+jn8P/o6O//6Onz/9TX4//r7/T/7O/1/9Da6//CzOP/4+72/+Pv9f/m8ff/4Orz/87Z + 5v/HzOH/+vv8/+rp8v/Eyt3/+vv8//v+/P/+/v7/uMTe/6Syzv/BzOL/v8zf/7fF3P+yvsv/n6a+/7/B + 1P/Rzt3/3tnk/9zY4//OzN//0tLj/+zp9P/m5fP/z9Hg//Dx9f/9+/z/+/r7//r5+f/a2uf/0M/i/9vZ + 6v/R0Ob/0dLp/93e8P/Iydz/vsHP/6itwf/X2eT/6ejx/9XS4P/SzN3/0Mze/+Db6v/19Pb//fz8//v4 + +f/i4+r/1dTf/+fj6//r5+7/0s7a/9nT3v/b2eT/6enx/+bk8P/e3un/5OTu/+7w8v/n6/L/2N3q/9LZ + 6//j7/b/2+fy/9vq9f/T3+j/vMPY/8jM4P/V2uf/5Obu//7+/v/+/v7//v7+/7zK4P+8yN//tsHa/8HN + 5P+uu9f/sLnO/5CXqP+3us3/ysvY/9bU3v/b1+H/yMjY/7u+1P/c2er/4Nzs/9TT4f/5+/r//fz9/+vs + 8f/Extn/29jp/+zl8v/r5fH/6Of3//Hy+v/18fb/2Nbq/77F2v+Qma//wcXR//n6+f/28/j/zMjb/+fg + 7f/Kyt//ubzR/8zL3f/R0d3/0NDh/8PC1f+7vs//ubnM/8XBzv/f2OL/yMfT/9rd4v/h4ev/4d/q/9fV + 4v/q7PH/5urx/9nc5f/k5/P/1+Ds/97s9f/N2Ob/z9vm/8bR4P+2wNv/u7/Z/+rq8v/9/f3//f3+//7+ + /v/G0+L/rrvU/8fR5v/L1un/qrTX/7e/1/+VnrD/p6rE/9XV4f/Kydj/0NDc/9LR3f+vtMr/2dTm/8bI + 2v/29fj/7Oz1/9PU4f+0tdL/4uHu/+ji7v/s5O//7Ofx/+/s8v/39Pj/+fb5/9bX6f/d3u3/zNLg//Tz + +f/8/Pz//Pv6/8zO3v/u6vP/3dvr/8TG2//b1+H/4Nzj/9zX5v++wtL/zM/c/77D3f+mrMT/y8fX/9rV + 4f++vcj/397p/93c5v/Sz9z/6OXv/+jq7f/d3Oj/5uXu/+Xm8v/R1uj/1+Lt/8TP3f/G093/vcjj/8TK + 5/+4wd3/+vr9//39/f/+/v7/0dvo/8HN5P+/yeH/0tzr/8HN5f+2wNz/jJWs/7S50P/S1OL/wsbX/7m6 + zv/Rzdv/u77S/8bH2v+8wNb/0djj/8vO4P/g5Oz/vcHT/+nk7v/p4+7/7eXz/+vk8f/z8Pf/8fH1/9bZ + 5v/Kzd3/x8fd/5Wcq//FyNT/+vr7//n6+v/g4Of/5OLs//Lt9v/HyNz/1NPf/8TD1f+lpsP/0Mzg/8zM + 3P/h3er/uLjN/8TG2f/OzNf/xcHN/87N1//X1uD/1tPf/93Z5P/r7PD/29vl/9/e6f/y8/f/1dbj/8fR + 5P++ytj/vcjY/7rG4v/Ey+P/u8Le//Tz+f/9/f7//v7+/9Db4v/Y4u7/tMHZ/8/Y6f/h6/b/w87l/5ae + v//Axd3/2Njl/8bI2v+1uc3/xMXV/7O50P/Dz+H/rLXU/9ve5//S0t3/2Nrl/8/L3P/q5O7/6+Tw/+rl + 7v/m4vL/z9Pm/7fB3P/f5vX/4efv/9Xa6v+zu8//1tvk//z7/P/t7fL/7+/1/8/Q4v/W1OX/zcve/9TV + 3v/MzNr/zdDa/7O3zv/Bwt3/1NLh/+ni7f/q5+7/vbnO/8TDzf/Pztn/0tHb/9XS3f/W0t3/6enu/9/g + 6P/f3Oj/4+Dq/+Pj6P/f4+//yNTh/7XA0P+4w9//0dTq/8fO4v/08/n//Pz7//39/f/Y4Or/2ODr/9Xa + 5//O1ef/4+z1/8/Z6f+7wtv/tL3W/83Q4P/Kztn/vcHO/7O0zf+4wtf/z9vu/5qixv/Izdj/09rk/72+ + 0P/n4O7/x8XW/9HP5P/Cwtj/wMXg/8jO6P/W3/P/ucHe/5WfyP/KzOT/39/t/7zC2P/JyNb/xsnc/8LI + 1v+wuNL/zs3f/9/d6//b1+T/0c3Z/8zJ0//i4e7/vr/Y/7W41P/f2+f/5ODr/9nU4/+wsML/0tDb/8zK + 1f/PzNf/1dHc/+jn7P/i5Oz/2trl/+Hf6P/Y1uT/+fn5/9DV4/+8xdb/ucji/87S7P/Cx9r/+Pr8//3+ + /f/+/v3/2+Ls/87W4P/U2OL/5Ozz/9zg8P/Bydz/z9Xm/8nV5v+3wtf/yMrY/7+/z/+hpsL/2OPx/8fS + 6P+utdD/zdDa/9Xa4/+2us//wsDX/7O41P+lrcz/sbnZ/9PZ7/+vt9b/v8nm/7G52P/JzOL/r7PN/7q9 + 2P/OzN//qKvB/9na6P/Fytr/rLHH/727yf/j3+n/5OHq/9TR2//NydP/6OXu/83N3P/AxN7/zcrf/+Dc + 5v/j3ur/q6zE/7650P/U0Nn/yMfR/9vW4f/j4un/3d/o/9jZ4//l5Oz/2dji//Tx9v/Hydj/uMTZ/9Dd + 8v/AxN3/1dbm//39/f/+/v7//f39/9PZ4//W2+X/y87Y//Py9//c3u3/y9Hm/8TL3P/d6PL/ztnr/7W9 + z/+2tMz/uL/W/+Dn7/+2v9v/wsjb/9vc5v/U2OP/ys7a/8jM4P/Nzub/pa3O/9Pa8f+wudz/z9jv/83T + 6v/Dx+P/p6bK/72+2f/Kx93/xsXe/6mqyP+3utH/5+v2/+zz/P/V3ev/trvN/8vM2//U0dz/4N7l/93b + 5f/i4ev/yMnc/8bG2//c2OL/4Nvn/7i70P+lqML/1M/b/8bFz//h3On/5OHr/9nZ4//e3ub/29rj/+jo + 7v/g3eb/vL/R/7zI4f/j7Pr/1dvp/+ns8f/+/v7//v7+//7+/v/b3ej/2drk/9HS3v/f4Ov/yMzh/+bs + 9P/FzOH/3uXu/9zi7P/Aydn/pazC/83U4//Cxtv/oKnH/9TZ5//d3Of/0NPe/9na6P/Gx+H/naXL/7bC + 4//R1u3/ucLg/+Pp+f+4vt3/nKDH/7Sz2//Iwdv/pqXH/7K30P/i5fD/7fH4//Dz/P/r8v3/6vP8/+nx + +f/a4vD/w8ve/7u/1v/T0+D/4t/o/8nI2//c2uf/3tnm/9vW4//Fxtf/urnS/7S1zf/LyNL/4t/p/+He + 6f/Z2eP/4eDo/83N2f/r6PD/5ODp/6uzzP/f5/n/4uj1/9fa5f/9/P7//v7+//7+/v/+/v7/0dXf/9jX + 4f/S1uD/wMPW/8nP4v/K0eL/wsXd/9vi7P/Y3uj/m6W0/7G50f/Dxtv/tLrY/7W/1f/Q1OH/2tvm/8/P + 3P/Mzd//w8rj/5Ccyf/M1u//vsXg/+Ho+v/V3PD/nqHH/5+jyv+zsc//qKvK/9fa7f/u8vr/8PL7/+/z + /f/t8vv/7vP8/+nw+v/q8fv/6PD6/+30+//h6Pb/xs7g/7q7y//ExdT/3Nbk/97a5f/Y0+L/1tTh/7+7 + 0/+bnr7/zcvU/+Hf5f/c2uX/3Njj/+He6P/Nzdr/6ebr/8jO3v/Y4fL/4ur4/8zT5//j5ez//v7+//7+ + /v/+/v7//v7+/7O80P/O0Nr/rLLC/7e+0f/T1+r/vMLX/97g6f/Fyt3/qbC8/6y0xP+2utH/vL7W/7O4 + 0f/N0+L/ztHf/83O2//R0d3/ycvf/7e93f+hq9D/2OH1/9LY7//c5vb/usPg/5mi0f+ZnsD/wMff/+rx + +v/s8/v/7fT8/+3z/P/t8/z/7fP8/+30/f/u9Pz/7PT9/+rz/f/q8fr/8PT8//H0+//r7vb/v8PX/8nH + 2//Z1uH/19Lg/9vX4/+8utP/pqjD/8jI2f/i3ub/0dLd/9rX4v/d2uX/0tHd/9La6f/Z5PL/5e77/8vS + 6f/M0eL/+fn8//3+/P/+/v7//f39//7+/v/Aydn/pa3B/6Wswv++yNn/xMri/8PI2v/U0tn/srrH/4+X + rP+nsL//y8vZ/8DE2f/Hydn/1djj/8vN2f/GxNL/0tDc/8DE2/+wtdj/tb3d/9rh9P/T2O3/1+Dx/5+m + yv+ordf/3ePz/+vx+f/s8/z/7PT8/+z1/f/r9P3/6/T9/+zz/P/h6PD/7PH6/+71/f/u9f7/8Pf9/+32 + /P/w9v3/8/b9//P1/P/N1OP/wsPU/9TR3v/c2uT/vcDV/7S2zv+/wtj/4d7p/8/Q3P/Z1+L/3Nnl/7/B + 0f/d5PD/5O/3/8rV7P/Z4O//2tvp//39/f/9/f3//v7+//7+/v/9/f3/uMHN/7a90P+qssb/yM/d/6iv + zP/V1eL/0dHb/5acr/+fprf/qbHD/8/O3v+7vdL/zMzd/9Xb5f/CwtD/x8XS/9jU4P+yt8//rLLT/6+7 + 2f/S3O//zNPm/9bf9P+PmLz/vcDg/+3y/P/v9P3/7fP8/+30/f/s9P3/6vP8/+v0/f/q8/z/1Nzo/9LX + 5P/x9/3/8ff+/+72/f/v9v3/8vf9//D1/P/y9fz/7fH8/8HG2//Hx9j/wL/O/7a4y/+pq8j/v8HY/+Pi + 6f/Q0d3/2tjh/8fF1v/S2+f/6e/3/8vV6//X3+z/29/q//L0+P/+/v7//v7+//39/f/+/v7//v7+/7fA + zf+vtsn/srnL/83V4f+bpsD/1dTf/83N2/+Yorf/rLXE/7G5yv+5u9T/09Ph/8bI2//c4un/ur3K/87M + 2P/X09//oafE/7nA2v+qt9H/y9Xo/8vW6P/F0uv/qbPY/8XH5f/p7/v/6vD8/+zz/P/t9f3/7fX9/+31 + /P/u9v3/7fT9/+31/f/v9P3/8Pb8//H2/f/v9fz/7/b9//H2/v/s9P3/5e37/+Hr+//d5fr/q7PN/8nK + 3f+Nk7P/pajL/6Gkxf/DxtX/1dLc/83N2//Bx9n/4Orz/83V6f/Q3Or/5Obv/9/i6v/9/fv//v7+//7+ + /v/+/v7//v7+//7+/v/Fztr/srzN/7K7zv/J0Nz/r7jN/83O2v/JzNr/oq2//7e/zP/Dy9v/ubvd/+Tg + 6P/L0N3/297q/8DFzf/Qz9v/1NPf/5ulwv+9w9v/qbXP/8jR6P/I1Ob/vMrl/6m32f/S1vD/6vD8/+zy + /v/s8/z/7fT9/+zy/f/s8/3/7vX+/+30/f/v9f3/8PX+/+/0/P/w9v3/8Pb9/+/1/P/u9fz/6PH7/97o + +v/a4fr/1dz6/6ix0//P0+f/vcHU/5GZuv+3vNP/q7HG/8bE1P+zvM7/0tro/9Xc6//Y4e//xMzi/73B + 1//o6fL//f39//7+/v/+/v7//v7+//7+/v/+/v7/19/q/7jE0f+zv9X/y9Hb/8vP4P+6vdL/y87b/6u2 + x//DzNn/y9Te/8LJ4P/HyNr/yM3h/9XV5P/S1uD/ysnW/9PR3v+krsf/wMba/7O/1//AyuD/ytfo/6y5 + 2v+uuNr/0NXw/9PX7v/h5vP/8PX+//D2/v/s8/3/6fL9/+z0/f/u9v3/8Pf9//D2/f/x9v7/8vj+//L3 + /v/w9/3/7PX8/+Tv/P/Y5Pz/z9r7/8nT+v+9yPD/rbfV/8jO4v+Um8D/rbTN/7W5zv+vts3/ucXa/9je + 6v/I0+P/0tnu/8LI2//X3un/3d/u//7+/v/+/v7//v7+//7+/v/+/v7//v7+/9rf6v/N1eT/tb/Z/9HZ + 4v/e5O7/wcbb/8/R4P+1vdL/ydLf/83W4//d5PH/v8TX/52lwv+ss8z/4eTv/8TF0P/Lytf/srrR/83V + 4//BzOD/uMPX/8jU5f+tueD/pq3W/5OVxf+rttv/4+r8/+71/v/v9f7/6/P9/+rz/f/u9P3/8PX9//H3 + /v/v9f7/8Pb9//H3/v/x9v3/7vT7/+rz/f/d6vz/09/5/83X+//G0fr/wcz5/5Sdwf/HzOP/kpvE/6Ws + x//Gyt7/s7jN/7jB1v/K0+L/ztjq/7e/1P/3+fr/1tvp/97h7P/+/v7///////7+/v/+/v7//v7+//7+ + /v/x8vb/09Xi/77D2f/X3e3/3eLs/9Xc6//Bxtn/wMfg/9HZ5v/R2ef/3ebx/8DF2//Z2+b/oqnE/8PH + 2f/GyNL/w8TV/7O60//P1+L/wcvf/7XA1f/I0+j/sbzl/4GJu/+Qm8z/ztr8/9nj/f/n7/z/6/P9/+zz + /v/s9P7/7vT9//D2/f/v9fz/8ff+//H3/v/x9/7/8ff9/+3y/f/l7/v/1+P8/7rD7/+/yPj/xtH1/8PN + /P+yu+b/oqnH/6WszP+vs8z/usHV/7O90f+/xt7/v8ve/7/K2//P0+H//fv7/9Xa6//e4ev//f79//7+ + /v/9/f3//v7+//7+/v/9/f3/+/z9/+rs8//Hytn/xs3e/+Hp8//p8Pn/xMzc/8fP4P/Q1+v/2d/y/9zg + 8P/Z3+7/w8TV/9fa5/+or8z/x8ra/73A0P/IzuT/0tvm/7/I3v+1v9X/xdDm/7C74f99h7v/v8r0/8rV + +//R2vr/4uv9/+z0/f/r8/3/6vP8/+3z/f/x9v7/8ff+//H3/v/x9/7/8ff9//L4/f/v9P3/6e/9/7/J + 8f+9yfb/ucXx/8LI7//O0fj/v8b2/6Gszf+lrsz/o6fF/7/F2P+6wtb/vMbb/7zI3/+wutD/8/X6//T1 + +P/T1ej/5+rv//3+/v/9/f3//v7+//7+/v/+/v7//v7+//39/f/8/f3/4eHo/9PW5P/Y4e//4e71/+Ps + 9P/Byt3/vcfg/97l9v/c4/L/6ez5/8rP4f/U1eT/t7nR/7q/1v+/wtT/1d3s/8/Z5v+/yt//t8LY/8TP + 5v+kr9b/orDg/8nT+v/K0/v/0Nf6/9je+v/k6/r/7fT9/+rz/f/t9P7/7/X9/+72/f/v9v3/7/b9/+70 + /f/u9f7/7PP8/9/f9//QzuT/xsbS/83M1v/MzdX/vrzE/7O16f+mq9P/lZ69/56kyP/Fy97/srrW/7zK + 3v+1v9b/vcXX//n7+//V2OX/2dvq//r7/P/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/+fb6//Hx + 9//Y2eT/1djl/93n8v/e6/L/3+nz/6+82v/N1u7/4uz3/9zm8v/l7Pj/v8LY/8/R5f+ytM3/mJ25/97l + 9//W4e7/yNHl/8HO4f/H0ur/q7bc/6++6f/H0vr/wMz6/6mv5f+mreH/t77w/+jv/P/r8vz/7PL9/+/2 + /f/u9P3/6u74/+/z/f/w8/3/7fP8/+/0+v/a2+7/s6KQ/5mCa/+rmYT/u6yf/6ydkf+4tsr/kJDB/4mP + sv+ao8P/z9Pn/6y11P++yuL/t8LW/8rQ3//39/v/193t/+Dg6v/9/f7//v79//7+/v/+/v7//f39//7+ + /v/9/f3/5unv/9jc7//W2/D/2Nvr/97d6f/P1Of/2uTy/97n8v/a4vL/p7DT/+Pr+f/e5vL/4Ofy/9/i + 7/++v9j/urvO/52iwv/b5PX/1eHu/9Pd7v/L1uj/xNDn/7bB4P+/ye//u8Hp/7vA3//Iy9v/ys7f/83R + 5//S0t//6Oz3/9Xd7v/R1+7/0dnu/9LW6v++yOP/tsHb/7jC3P/b4e//wcff/5eOlf94Z1j/i3Zb/6mU + fv+OhHX/uLa//4iIpv9ucIr/mZ+7/87S5P+6wtz/t8HY/7K7z//a3+v/5uXw/9DW5//4+Pv//v7+//39 + /f/9/f3//f39//7+/f/9/f3/9fP0/9/h7v/g5vz/1tvp/97h7f/d3en/xMfd/8nR4v/Q2Of/09zn/8XN + 5P+7x+D/5Oz4/9rj7v/g6PH/xsra/6ytx/+jqcv/3Of3/9fi8f/Z4/P/0drr/7zI4P+8wOH/sbLZ/6Cb + pf+/t6f/wrWj/8a5q//Pxbz/v7W0/87N2/+9xeD/xc3q/9HY9P+osdj/r7TZ/73G5P/DyOT/2t3v/8vQ + 5P+nrc7/kpKq/3NpcP+Gdmj/bWlx/2xtiP9obIn/g4ep/6Goxv/P0ej/usLZ/7/I2f+6w9b/3eLs/9rb + 7//Z3Oj/+/z7//39/f/+/v7//f39//7+/f/9/fz/+Pn4/9DT1f/m5vL/2d3x//X2+f/7+/r/+Pf4/9fU + 5f+wttP/0djp/8jQ3f/L0+L/q7bT/9Xf7f/c5O7/2uDr/+Hn8P+ipsH/s7XU/9vo8v/V3+7/2+f0/9Ld + 6/+/yuL/sbTV/4uMt/+Og3r/qJB0/5yFZf+vmHj/xK+U/6qbkP/ExNT/oKXH/6Os1P/X2/f/19z6/8TJ + 5v+0u+D/rLLV/9zg8//N1O3/nKPL/8PJ4f+nrdD/houp/3+Apv91gKr/lJi5/6euzf+xttP/0NTr/8HI + 3//L0eH/vMTX/9PX5//T2Oz/0tPi/+Hh7v/8/P3//f39//39/f/9/f3/8vL0/9vb3P/p7ev/7e/1/9LV + 5//6+v3/+/v8//z6/P/i4uz/srfU/7G41P/T1uL/ys/e/8HI2/+nss//3OTv/9zl7v/c5e3/zNLk/73F + 2v/d6fL/0Nzq/9nm8//S3+7/t8Xb/46Qsv9vcZH/kIiR/4VuW/+AaVP/n4Zm/6CHa/98dXT/gomk/6On + yP+QmMH/wcXm/9fc+f/d4fj/ucPn/7vC5f+3vdz/2+H3/6Oqz/+4u9f/4eL0/9ji8//L0eb/maDE/8rQ + 5/+zudX/w8zh/9DW6/+7xNv/19vs/7rB2f/JzuT/4+Pu//Dy9v/JzOL/9vj7//7+/v/+/v7/+/z9/+Lk + 5//Y2tv/6u3q//v7+//e3+v/7e7z//j5+v/U2Oj/uMHb/7rD3/+nr87/w8bZ/8vM2v/N0N//rrjU/7vE + 3P/b4u7/2uLs/93k7v/Eytj/2+bw/8nW5P/T4u//ydjp/7zI3v+cpcT/aG6R/2Vohf9kZGz/Z2Bg/2dd + XP9dWmT/Vltz/4SMrP+hp8b/oaXJ/7W84P/W2vH/1dnw/9Pc9P+xut//pKzS/9bb9P/K0u//p7LV/9ja + 8f/o7Pf/7fD2/7G11P+4vNj/srfU/8zV6f/N0+n/wcXe/9rg7//ByOT/zdDh//j4+//2+Pn/zdDk//Dy + 9f/+/v7//v7+//7+/v/3+Pj/3d/e/+Pm5P/8/Pz/+Pj6/+Ph7P/d3+7/1try/9TY8f/R0+v/2Nvw/8/V + 6f+1utP/zdLh/8LL3v+Xpcf/09vr/9fh6//T3Ob/zNPk/9Te6//I1uL/y9vn/8bU5//I0+T/tsHZ/5uq + zP+WnMn/foSv/4SNr/9ob5H/dXyj/6Wt1f/Aw97/vMPb/4qPtP+3w+D/zdfr/8zX6//M1ur/usTi/7G9 + 3v++yeX/zdju/8TQ6//Fzuj/4ef1/+js+P+3udb/vcTc/7e91v/L0+f/x8/j/77E2//Y3uz/ytPo/9HV + 5v/8+/3/+vv7/8/S4v/6+vv//v7+//39/f/+/v7/+/z8/9ja2f/d4d///f39//z7/f/a3e3/z9Pn/9nd + 6f/h5vD/x8vZ/8DB1//Cwtj/ztXr/7rA2P/P2OX/rbnV/7rE3P/W4Or/yNLd/9Da6f/C0OH/yNTg/8XV + 4f+5yNr/wM3g/77H3f+uuNb/q7LW/7nC3f+nr9X/rbfU/6Kp0f+9wuL/3t/y/9/c8v+qsMz/tr/a/8rW + 6P/H1Of/xNDj/8XU5/+yvdz/rbjY/8XQ5//J0+z/w8rp/+ju+f/m6/j/uLnV/7e/1/+rssv/w8ze/7zE + 1v+1vNL/193s/8TM4v/R1Ob//Pv9//v7/f/Q0uP//f39//7+/v/+/v7//f39//P09P/X2tj/19vZ//z8 + /f/n6PL/1Nrr/+ns8f/g3+f//Pr8/+zs9P/Oz9v/0c/a/7y+0/+3v9X/xczd/8TO3v+rtdL/1uHv/8nU + 4f/J1OL/tsHW/8XP3v/Bztr/tcHS/6q3z/+qtM//rbfY/6q20//Fz+X/r7XU/8jP5v+ttdX/oafT/9TZ + 8P/n5fT/0M7j/6Krzf+8x+D/ws7g/73J2//D0OL/sr7X/7K83P/Ay+H/u8fc/7vD4//f5fb/1trp/6qv + zP+5wNb/o63F/7rE1f+2vtD/s7zO/8/Y5P+7w9//2Nrl//38/P/y9Pj/2dzp//39/f/9/f3//v7+//z8 + /f/g4eH/6Orn/9rc3P/8/fz/5ujz//v7+//8/Pv/6uzx/+nr8P/6+vz/z9Ld/9DR3v/Iydj/yMvb/6Gv + y//FzN7/s73V/9Db7P/M2OT/wcza/6660f++yNf/vsrV/7jC0/+2xNP/rbnR/5mnxf+Vnr7/vcTf/7/G + 3f+0utb/vcff/6Oq0/+7w+L/6e35/9fU5/+mq83/rbjT/7bC1v+8yNr/ucTW/6u2zf+wvNT/usXZ/7fC + 1f+0vdn/2+D4/9/h8/+ttNL/tb7W/5ulvP+xu8z/srrM/623yP/Gz+D/vsbf/9vd5f/7+Pr/3uDq//Hz + +P/9/f3//f39//39/f/u7u//6evj/+Tm3//s7vD//f38//v7+//9/Pz//Pz8//r8/P/p6O//5ubu/9jc + 5P/W1+L/1NXi/8nJ2P/Hzd3/mqW8/8vT5/+9yN3/yNbi/7nG1v+ruM7/vMnY/7vH0/+3wNH/rrnO/665 + y/+eqcb/lJ++/5KYu/+wuND/qLHL/7fA1P+irMv/oqrL/83R5f/NzeL/o6rE/6GrxP+quNL/v8zd/7C7 + y/+wuc7/r7nM/7bB0v+0vtD/sr3T/87V7//Qz+f/qrDR/7nA1v+iqL3/r7fJ/621x/+stcb/xM/i/7S6 + z//i5en//Pz8/97g6f/9/f3//v7+//7+/f/19vT/5ebg//Dy5P/k4+D//Pz9//39/f/8/Pz//Pz8//z8 + /P/8/Pz/+/r8/9HU3v/d3uv/x8nW/9nd6P/IzNn/09Tg/77E1f+pscX/u8fd/8HP2/+4xdX/pLDG/7vH + 1/+yv8v/srvK/6izx/+5xNb/lJ67/5qkvP+Pmrn/lKC+/6Krx/+vuNL/r7nP/52ryv/ByeX/zc7g/6Cl + wP+tuM3/n6vK/6+80v+wvM3/uMLS/7C6y/+zvc//s7zP/7TA1P/M0+7/wr/b/6y00v+7wtX/pazB/6y1 + x/+stcj/q7bI/8TO4f+mrMD/4ePp//f3+v/j5Oz//f39//39/f/9/Pz/5ubh//Hy5f/n5d7/+Pb2//39 + /f/8/Pz//Pz8//z8/P/8/Pz//f39//z9/f/q7O//x8vZ/9HS4f/d4+3/2N7o/9PT4P/Hy9v/vMPU/6Kt + yP++zNj/usfX/6GtwP+0wdD/rrnH/6u2xf+ircT/vcjY/5iivP+eqMD/l5+8/6auxP+lrcf/oqvF/7e9 + 1P+ZosP/tr3b/8zN4f+jpsX/tL7S/6Gsxv+wvNj/sb3R/7bA0P+3wtH/s73O/7S9z/+yvdL/v8fi/728 + 2P+wuNX/ucDU/6Wtw/+tuMv/q7bK/7O/0f+9xdb/r7XE/+Pk7v/h4ev/+Pf6//39/f/8/Pz/8vLv/+7t + 4//u7uT/5uXi//39/f/+/v7//v7+//7+/v/9/f3//f39//z8/P/8/Pz/+fr6/8/T3P++wdD/4Ofv/9/j + 8P/S1eP/0dbl/8TL2f+osc3/r7zQ/7rF1f+jrr3/o6/C/7C6y/+uucr/m6S+/7rG0/+jrcT/rrjO/5eh + v/+rtMr/qLDG/6+50v+osMj/oqvH/7G61P+9vtn/panH/7O+0/+yv9L/qbbT/6i0yP+yvM7/ucPV/7TC + 1P+3xNX/s77S/6620v+1s9L/tLzZ/7nB0/+uuM3/t8HT/7vE1v/By93/uL7O/8jL3P/m5/H/zdHi//z7 + /f/+/f3//v7+/+bm4//r7OP/4+Tc//r7+v/9/f3//Pz8//39/f/9/f3//v7+//39/f/8/Pz//Pz8//z8 + /P/t7vH/zM3c/9DX4f/f5vH/19vp/9nd7P/K0t//ytTk/5qlx/+0wNX/nqu7/5iiuP+ossT/q7XH/5qk + vf+0wM7/rrjM/7nD1f+msMv/rbjP/7a/0v+mscr/tsHW/6ixyP+nscj/q6/O/6mry/+zwtr/tsPW/6u4 + z/+7xdz/t8LX/8PQ3v+0wtX/u8jb/7zH1/+nr8z/razO/8HH4P/Cytr/wsze/8XP3P/P1+f/0Njn/8bL + 3P/R0+T/4uXw/+Hk7//9/f3//f39//39/f/Z2db/5+jg/9/f2v/9/f3//f39//z8/P/+/v7//v7+//z8 + /P/9/f3//f39//z8/P/7+/v/+vv7/9PU3//U1ej/3ubz/9vk8f/V3On/1dzs/9Tb6/+3wdn/m6bE/6Wv + wf+Klq3/q7XH/6qzxf+eqMD/sL7O/7S/0f+9x9n/r7rP/7C+1f++ytr/sr7U/7/I3P+yu9D/p7LM/6uy + zP+rr87/vMrg/8TO4P+8x9v/rbjV/7K+0v/N2er/vcvd/8DN4P+/ytj/rrbR/6Kkyf/P1Ov/xszg/8XP + 4f/X3+v/1dzq/9Tb6//a3u7/1tnq/87S4f/3+fz//v7+//39/f/7/Pz/1NbU/+fn4v/l5uP//f39//39 + /f/9/f3//f39//7+/v/9/f3//v7+//39/f/8/Pz//vz8//v7+//z8/X/19jn/9ji7f/f6PX/2ODt/9ff + 8f/U2+//0tvs/6awz/+Xn7n/hpCk/6y2yf+rtMb/o63E/6u5yf+xvc//vcja/7jE1/+wwNr/ytXn/7zI + 2/+uuM//0tnq/6izyv+2vtP/pKjI/8XQ5f/N1ub/ws7f/6i00P+1wtr/1N3t/8vW5//J1ef/yNPk/7a+ + 2P+nq9L/09vt/8TJ3v/FzeH/2ODr/9Td6v/V3e3/5ef2/87S4//e4ez//f39//39/f/9/f3/+/v7/9HU + 0//m5uH/4uPg//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/8/Pz//f39//7+/v/8/Pz//P39/+Di + 6f/b4e3/5ev4/+Ln9P/c4/P/xtDm/9jg7f/By9//nKfB/4WQpf+eqb3/srrL/6myx/+qtsf/sb/Q/7G9 + 1f/E0uX/rr3Z/87Z7f/L1uj/ytXn/7O90//FzeL/vcbb/5+lw//I0uX/0Nro/8vX6P++yuH/ssLb/8fP + 4v/Q2er/zNnq/83a7P+zvdb/t73a/87V5P/HzuD/xM3e/9Dc5v/R2+z/197v/+Pk8//M0OT/8/T4//39 + /f/+/v7//v7+//39/v/U2tr/5efi/9ze2//+/v3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39 + /f/9/f3//v7+//39/f/z9fj/4OHu/+Ln9f/g6fb/2+Xv/8fP5//V2u3/197t/7XB1v+Vn7n/lqG2/7jB + 0v+zvND/rrrL/7rG1v+ntNH/y9rr/7jG4f/N2vD/0tzu/9zg8P+8xdr/ydPl/7rC2/+lrsv/yc/k/9Xe + 7v/P2uv/0tzt/7bD3/+9xtz/1d7u/8/c7f/Q3vD/srzV/73H2v/Fzd3/w87f/8TO3v/P2uX/0tzs/97k + 9P/c2+v/19jp//z8/P/+/v7//f39//39/f/9/v7/2+Dg/+bp5f/X2tj/+Pr4//7+/v/+/v7//f39//7+ + /v/+/v7//f39//39/f/+/v7//v7+//39/f/9/f3//Pz9/+Tk6//e4e//4Oj3/9ri8f/T2u3/xc7h/9Xd + 7P/J1ej/t8HY/46Ysv/BzN7/wszd/7nE1f/G0OL/tsLY/8XS6v/K2O7/ytnv/9Pf8f/T2+n/1+Du/622 + 1P/R3Or/l6LC/77G3P/U3uz/zdfo/9Ld7/+4wt7/wszk/9ff8P/O2uz/0eDy/666z//L0+P/v8jX/77J + 2v/Ez97/z9nl/9Ha6f/b3+7/xsnh//Dx9//+/v3//f79//7+/v/+/v7//f39/+Ll5v/e5OT/5uvq/97h + 4P/9/fz//f39//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/9/f3//f39//39/v/09Pf/4OLs/9re + 7//X3e//zNbo/83W5//U3uz/zdvq/7jG2/+lss//t8LX/9Lc6f/Ez93/ztbo/8zX5v+5xuD/1ODy/87b + 7//U4PL/z9no/9vj8f+6xNv/xM7l/6+91P+3wdf/1t/w/8zX6f/S3/H/u8je/83Y7//DzOH/ytrr/9He + 8v+yvND/y9bi/7O90P+4wtT/wczb/9Hb6f++x9z/0dTo/87S5P/7/fv//v79//3+/f/+/v7//v7+//7+ + /v/5+/v/0tfa/+zw7v/h5uf/8vPz//39/f/9/f3//f39//39/f/9/f3//f39//7+/v/9/f3//f39//7+ + /v/+/v7//Pz8/+vr8P/g4fD/1Nzv/7rF4//M1+f/zNrp/8PS3P/Ay+D/sb3U/7nB2v/c4fL/0Njo/83V + 5v/a4vP/wMvi/9bh9P/P3e//0+Hz/87b7f/Y4e7/ztjp/6u11f/N2+r/s77X/9Pd7//J1ef/y9nr/8XT + 5v+/zuT/uMXe/8rY6v/S3/D/s7zS/8jT4P+wus7/t8LS/8LP2//O2eb/p7HP/7vA3f/19/r//f39//7+ + /v///////v7+//7+/v/+/v7//v7+/+nr7//m7O7/7PL0/+Lp7f/o6ez//v7+//39/f/+/v7//f39//39 + /f/9/f3//f39//7+/v/9/f3//f39//z8/P/6+fv/4ODs/9fd7v+4xeD/usng/8LS4P+8y9X/vs3Z/6y5 + zv+1v9P/0Nfq/9zh7v/V3e3/2eLy/9fh8f/L1+z/ztzu/83b7f/O2+3/0Nrs/9DZ6v+zwtb/zdjr/7G+ + 1//K1ej/ws7g/8XT5f/C0OD/s8Db/7XB3P/K1ub/1eHt/7C6z/+4wdf/s77O/7jD0f/Bzdj/s77U/7K5 + 1P/V3On/+/z8//39/f/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7/4ufs/+nw+P/t9v3/5u/1//7+ + /v/+/v7//f39//39/f/+/v7//f39//7+/v/+/v7//f39//7+/v/9/f3//f39//Du8//f4e3/1t3u/6y3 + 1v+0w9P/t8TR/7jE0P+xu8z/p7HG/7S+0v/f5PH/2uPw/9Td6//d5vT/zdnu/8vZ7P/K2Or/ytjq/8fW + 5f/N2Ob/x9Pk/7PB2P/N1+n/s8DT/8DN2/+9y9v/tsbX/6m40/+7yd7/wtDg/8rY5f+qtcv/sb3R/7G8 + zf+2ws3/vcbZ/6qz0P/Cyd//+Pr8//39/f/9/f3//f39//7+/v/+/v7//v7+///////+/v7//v7+//z9 + /f/i5+//4er0/+v1/v/9/f3//f39//7+/v/9/f3//Pz8//39/f/+/v7//v7+//39/f/9/f3//Pz8//39 + /f/8+/z/29vh/97e6//Ezd//prTH/6SwwP+krb3/o66+/56twP+fq7//zdjq/9fg7v/T3On/197r/9Tc + 7//H1en/xtTl/8PR4//Az97/x9Ti/8PR3f+ruc//zdjq/7O/0/+9ytn/v8ra/7HB0P+iscz/v8/l/7jG + 2v/Dz+H/nqfC/6exx/+yvcr/t8TS/6evyv+2vdv/3+Xu//z8+//9/f3//f39//7+/v/+/v7//v7+//7+ + /v///////v7+//7+/v/9/v7//f79/+rt8v/W4Oj//f39//39/f/9/f3//v7+//39/f/9/f3//v7+//7+ + /v/9/f3//v7+//7+/v/+/v7//f39//X2+P/X1uH/2tvm/7nD1v+frb3/m6Wz/5ijsf+dqLb/pbDC/7G8 + z//U3e3/1t/s/8bO3P/b4O//vMnh/77P3v/Az9//v8/e/77L2P/AzNj/tMHS/7C/1P+9ytv/rbzQ/7XC + 0v+qt8r/nanD/7zK3/+wutP/u8jc/6Kswf+stsb/sr7K/6q1yf+stNP/xc3k//r7+//9/f7//Pz8//7+ + /v/+/v7//v7+//7+/v////////////7+/v/+/v7//v7+//7+/v/+/v7//f3+//7+/v/8/Pz//f39//39 + /f/+/v7//v7+//7+/v/+/v7//v7+//z8/P/+/v7//v7+//39/f/7/Pz/6ert/9LS3f/U2eb/sbnN/7q/ + 0/+bprv/kpyy/5unuP+ap7r/zdXo/9Tc7f/I0eD/zdbj/8bR5f+xwNf/u8nY/7nG1v+5xdP/u8fS/7C9 + yv+Ypr//x9Pg/6GuyP+wucv/pbLF/5Ohuf+zwdf/pbHL/6+70v+ttMb/sLnI/7G7zf+usc3/v8Lc//b2 + +//9+/v//fz9//7+/v/9/f3//v7+//////////////////7+/v/+/v7///////////////////////7+ + /v/9/f3//Pz8//39/f/9/f3//v7+//7+/v/9/f3//v7+//7+/v/+/v7//f39//39/f/9/f3//f39//z8 + /P/f3+n/u8DS/87S3v/Z2uf/4+Tw/+Tn8f+nsMT/mKS0/664zP/T2uj/0Nzn/73G1f/L1uL/qLbQ/6+6 + yv+yvs7/rbfI/7G7zP+ns8T/l6S6/7G9zv+ltcn/pK/C/5unuv+Pn7T/s8DV/6i0zv+osMj/sbnL/6m0 + x/+ssMv/srXR/+bq8f/7+/v/+/v7//z8/P/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//// + ///+/v7//v7+//39/f/+/v7//f39//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//v7+//7+ + /v/9/f3//Pz8//79/f/9+/v/0NTh/9vf6/+rssb/5ubt/8XH2/+/xdj/2t7o/5ieuf+Uobf/yNLk/9Hc + 5v/Czd7/vcfX/8XR4f+eq8L/pbDC/6GqvP+hq7z/oa2//5ypvf+lssb/s7/Q/52pvf+WorT/kJyy/7XB + 1P+rtc7/pa3E/6CrwP+vtMv/rrDL/8rO4f/7+vr//f39//7+/v/+/v7//v7+//7+/v/+/v7///////// + ///+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ + /v/+/v7//v7+//7+/v/9/f3//f39//7+/v/+/f3/+/n8/83S4P/Kz97/3eDr/7S4z/+qr8X/yMvf/8rR + 4v/GzeL/4OXv/6ayyv/Y4ez/ydbl/7rF1f/G0t3/tsLV/5upvf+cprj/mqK0/5ynuf+WorT/n6m8/7/K + 2f+Tn7P/n6i6/5mitv+2wdL/naO//52lvf+rrsT/pKbB/8DE2f/29/r/+vn7//z8/P/9/f3//v7+//7+ + /v/+/v7//v7+///////+/v7///////7+/v/+/v7//v7+//7+/v///////v7+//7+/v/9/f7//v7+//7+ + /v/+/v7//v7+//7+/v/+/v7//f39//7+/v/+/v7//v7+//3+/v/+/v7//vz8//z7+/+7wdj/xsnf/+fq + 9f/Axdr/ys/h/622y//q6vT/r7fP/8nK3P+psMr/xs3f/87b6f/Ez9//uMLS/7/L1/+stsz/lKC0/5ad + rv+bpLT/nae5/6Gpu/+3wNP/qbTL/7vB0//Kz9z/q63G/6OkwP+srMf/lZi5/7K3z//09Pj//f39//39 + /f/+/v7//v7+//7+/v/+/v7//f39//7+/v///////v7+//7+/v/+/v7///////7+/v/+/v7///////7+ + /v//////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/UI/Register/Register.Designer.cs b/UI/Register/Register.Designer.cs new file mode 100644 index 0000000..30d9936 --- /dev/null +++ b/UI/Register/Register.Designer.cs @@ -0,0 +1,268 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + partial class Register + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Register)); + this.ExitButton = new Milimoe.FunGame.Desktop.Library.Component.ExitButton(this.components); + this.MinButton = new Milimoe.FunGame.Desktop.Library.Component.MinButton(this.components); + this.Username = new System.Windows.Forms.Label(); + this.Password = new System.Windows.Forms.Label(); + this.CheckPassword = new System.Windows.Forms.Label(); + this.UsernameText = new System.Windows.Forms.TextBox(); + this.PasswordText = new System.Windows.Forms.TextBox(); + this.CheckPasswordText = new System.Windows.Forms.TextBox(); + this.RegButton = new System.Windows.Forms.Button(); + this.GoToLogin = new System.Windows.Forms.Button(); + this.EmailText = new System.Windows.Forms.TextBox(); + this.Email = new System.Windows.Forms.Label(); + this.TransparentRect = new Milimoe.FunGame.Desktop.Library.Component.TransparentRect(); + this.TransparentRect.SuspendLayout(); + this.SuspendLayout(); + // + // Title + // + this.Title.Font = new System.Drawing.Font("LanaPixel", 26.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.Title.Location = new System.Drawing.Point(4, 4); + this.Title.Size = new System.Drawing.Size(391, 47); + this.Title.TabIndex = 8; + this.Title.Text = "FunGame Register"; + this.Title.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // ExitButton + // + this.ExitButton.Anchor = System.Windows.Forms.AnchorStyles.None; + this.ExitButton.BackColor = System.Drawing.Color.White; + this.ExitButton.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("ExitButton.BackgroundImage"))); + this.ExitButton.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.ExitButton.FlatAppearance.BorderSize = 0; + this.ExitButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); + this.ExitButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); + this.ExitButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.ExitButton.Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.ExitButton.ForeColor = System.Drawing.Color.Red; + this.ExitButton.Location = new System.Drawing.Point(453, 4); + this.ExitButton.Name = "ExitButton"; + this.ExitButton.RelativeForm = null; + this.ExitButton.Size = new System.Drawing.Size(47, 47); + this.ExitButton.TabIndex = 7; + this.ExitButton.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.ExitButton.UseVisualStyleBackColor = false; + this.ExitButton.Click += new System.EventHandler(this.ExitButton_Click); + // + // MinButton + // + this.MinButton.Anchor = System.Windows.Forms.AnchorStyles.None; + this.MinButton.BackColor = System.Drawing.Color.White; + this.MinButton.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("MinButton.BackgroundImage"))); + this.MinButton.FlatAppearance.BorderColor = System.Drawing.Color.White; + this.MinButton.FlatAppearance.BorderSize = 0; + this.MinButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray; + this.MinButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.DarkGray; + this.MinButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.MinButton.Font = new System.Drawing.Font("LanaPixel", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); + this.MinButton.ForeColor = System.Drawing.Color.Black; + this.MinButton.Location = new System.Drawing.Point(401, 4); + this.MinButton.Name = "MinButton"; + this.MinButton.RelativeForm = null; + this.MinButton.Size = new System.Drawing.Size(47, 47); + this.MinButton.TabIndex = 6; + this.MinButton.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.MinButton.UseVisualStyleBackColor = false; + // + // Username + // + this.Username.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Username.Location = new System.Drawing.Point(96, 83); + this.Username.Name = "Username"; + this.Username.Size = new System.Drawing.Size(92, 33); + this.Username.TabIndex = 9; + this.Username.Text = "账号"; + this.Username.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // Password + // + this.Password.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Password.Location = new System.Drawing.Point(96, 116); + this.Password.Name = "Password"; + this.Password.Size = new System.Drawing.Size(92, 33); + this.Password.TabIndex = 10; + this.Password.Text = "密码"; + this.Password.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // CheckPassword + // + this.CheckPassword.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.CheckPassword.Location = new System.Drawing.Point(96, 149); + this.CheckPassword.Name = "CheckPassword"; + this.CheckPassword.Size = new System.Drawing.Size(92, 33); + this.CheckPassword.TabIndex = 11; + this.CheckPassword.Text = "确认密码"; + this.CheckPassword.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // UsernameText + // + this.UsernameText.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.UsernameText.Location = new System.Drawing.Point(194, 83); + this.UsernameText.Name = "UsernameText"; + this.UsernameText.Size = new System.Drawing.Size(216, 29); + this.UsernameText.TabIndex = 0; + // + // PasswordText + // + this.PasswordText.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.PasswordText.Location = new System.Drawing.Point(194, 117); + this.PasswordText.Name = "PasswordText"; + this.PasswordText.PasswordChar = '*'; + this.PasswordText.Size = new System.Drawing.Size(216, 29); + this.PasswordText.TabIndex = 1; + // + // CheckPasswordText + // + this.CheckPasswordText.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.CheckPasswordText.Location = new System.Drawing.Point(194, 151); + this.CheckPasswordText.Name = "CheckPasswordText"; + this.CheckPasswordText.PasswordChar = '*'; + this.CheckPasswordText.Size = new System.Drawing.Size(216, 29); + this.CheckPasswordText.TabIndex = 2; + // + // RegButton + // + this.RegButton.Font = new System.Drawing.Font("LanaPixel", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.RegButton.Location = new System.Drawing.Point(273, 245); + this.RegButton.Name = "RegButton"; + this.RegButton.Size = new System.Drawing.Size(108, 42); + this.RegButton.TabIndex = 4; + this.RegButton.Text = "注册"; + this.RegButton.UseVisualStyleBackColor = true; + this.RegButton.Click += new System.EventHandler(this.RegButton_Click); + // + // GoToLogin + // + this.GoToLogin.Font = new System.Drawing.Font("LanaPixel", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.GoToLogin.Location = new System.Drawing.Point(130, 245); + this.GoToLogin.Name = "GoToLogin"; + this.GoToLogin.Size = new System.Drawing.Size(108, 42); + this.GoToLogin.TabIndex = 5; + this.GoToLogin.Text = "登录"; + this.GoToLogin.UseVisualStyleBackColor = true; + this.GoToLogin.Click += new System.EventHandler(this.GoToLogin_Click); + // + // EmailText + // + this.EmailText.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.EmailText.Location = new System.Drawing.Point(194, 186); + this.EmailText.Name = "EmailText"; + this.EmailText.Size = new System.Drawing.Size(216, 29); + this.EmailText.TabIndex = 3; + // + // Email + // + this.Email.Font = new System.Drawing.Font("LanaPixel", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Email.Location = new System.Drawing.Point(96, 184); + this.Email.Name = "Email"; + this.Email.Size = new System.Drawing.Size(92, 33); + this.Email.TabIndex = 12; + this.Email.Text = "邮箱"; + this.Email.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // TransparentRect + // + this.TransparentRect.BackColor = System.Drawing.Color.WhiteSmoke; + this.TransparentRect.BorderColor = System.Drawing.Color.WhiteSmoke; + this.TransparentRect.Controls.Add(this.MinButton); + this.TransparentRect.Controls.Add(this.EmailText); + this.TransparentRect.Controls.Add(this.ExitButton); + this.TransparentRect.Controls.Add(this.Email); + this.TransparentRect.Controls.Add(this.Title); + this.TransparentRect.Controls.Add(this.GoToLogin); + this.TransparentRect.Controls.Add(this.RegButton); + this.TransparentRect.Controls.Add(this.Username); + this.TransparentRect.Controls.Add(this.CheckPasswordText); + this.TransparentRect.Controls.Add(this.Password); + this.TransparentRect.Controls.Add(this.PasswordText); + this.TransparentRect.Controls.Add(this.CheckPassword); + this.TransparentRect.Controls.Add(this.UsernameText); + this.TransparentRect.Location = new System.Drawing.Point(0, 0); + this.TransparentRect.Name = "TransparentRect"; + this.TransparentRect.Opacity = 125; + this.TransparentRect.Radius = 20; + this.TransparentRect.ShapeBorderStyle = Milimoe.FunGame.Desktop.Library.Component.TransparentRect.ShapeBorderStyles.ShapeBSNone; + this.TransparentRect.Size = new System.Drawing.Size(503, 319); + this.TransparentRect.TabIndex = 13; + this.TransparentRect.TabStop = false; + this.TransparentRect.Controls.SetChildIndex(this.UsernameText, 0); + this.TransparentRect.Controls.SetChildIndex(this.CheckPassword, 0); + this.TransparentRect.Controls.SetChildIndex(this.PasswordText, 0); + this.TransparentRect.Controls.SetChildIndex(this.Password, 0); + this.TransparentRect.Controls.SetChildIndex(this.CheckPasswordText, 0); + this.TransparentRect.Controls.SetChildIndex(this.Username, 0); + this.TransparentRect.Controls.SetChildIndex(this.RegButton, 0); + this.TransparentRect.Controls.SetChildIndex(this.GoToLogin, 0); + this.TransparentRect.Controls.SetChildIndex(this.Title, 0); + this.TransparentRect.Controls.SetChildIndex(this.Email, 0); + this.TransparentRect.Controls.SetChildIndex(this.ExitButton, 0); + this.TransparentRect.Controls.SetChildIndex(this.EmailText, 0); + this.TransparentRect.Controls.SetChildIndex(this.MinButton, 0); + // + // Register + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.WhiteSmoke; + this.ClientSize = new System.Drawing.Size(503, 319); + this.Controls.Add(this.TransparentRect); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "Register"; + this.Opacity = 0.9D; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "FunGame Register"; + this.TransparentRect.ResumeLayout(false); + this.TransparentRect.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private Library.Component.ExitButton ExitButton; + private Library.Component.MinButton MinButton; + private Label Username; + private Label Password; + private Label CheckPassword; + private TextBox UsernameText; + private TextBox PasswordText; + private TextBox CheckPasswordText; + private Button RegButton; + private Button GoToLogin; + private TextBox EmailText; + private Label Email; + private Library.Component.TransparentRect TransparentRect; + } +} \ No newline at end of file diff --git a/UI/Register/Register.cs b/UI/Register/Register.cs new file mode 100644 index 0000000..ae30181 --- /dev/null +++ b/UI/Register/Register.cs @@ -0,0 +1,140 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Controller; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.Library.Base; +using Milimoe.FunGame.Desktop.Library.Component; + +namespace Milimoe.FunGame.Desktop.UI +{ + public partial class Register : BaseReg + { + public bool CheckReg { get; set; } = false; + + private readonly RegisterController RegController; + + public Register() + { + InitializeComponent(); + RegController = new RegisterController(this); + } + + protected override void BindEvent() + { + base.BindEvent(); + Disposed += Register_Disposed; + SucceedReg += SucceedRegEvent; + } + + private void Register_Disposed(object? sender, EventArgs e) + { + RegController.Dispose(); + } + + private async Task Reg_Handler() + { + try + { + string username = UsernameText.Text.Trim(); + string password = PasswordText.Text.Trim(); + string checkpassword = CheckPasswordText.Text.Trim(); + string email = EmailText.Text.Trim(); + if (username != "") + { + if (NetworkUtility.IsUserName(username)) + { + int length = NetworkUtility.GetUserNameLength(username); + if (length >= 3 && length <= 12) // 字节范围 3~12 + { + if (password != checkpassword) + { + ShowMessage.ErrorMessage("两个密码不相同,请重新输入!"); + CheckPasswordText.Focus(); + return false; + } + } + else + { + ShowMessage.ErrorMessage("账号名长度不符合要求:最多6个中文字符或12个英文字符"); + UsernameText.Focus(); + return false; + } + } + else + { + ShowMessage.ErrorMessage("账号名不符合要求:不能包含特殊字符"); + UsernameText.Focus(); + return false; + } + } + if (password != "") + { + int length = password.Length; + if (length < 6 || length > 15) // 字节范围 3~12 + { + ShowMessage.ErrorMessage("密码长度不符合要求:6~15个字符数"); + PasswordText.Focus(); + return false; + } + } + if (username == "" || password == "" || checkpassword == "") + { + ShowMessage.ErrorMessage("请将账号和密码填写完整!"); + UsernameText.Focus(); + return false; + } + if (email == "") + { + ShowMessage.ErrorMessage("邮箱不能为空!"); + EmailText.Focus(); + return false; + } + if (!NetworkUtility.IsEmail(email)) + { + ShowMessage.ErrorMessage("这不是一个邮箱地址!"); + EmailText.Focus(); + return false; + } + return await RegController.Reg(username, password, email); + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + return false; + } + } + + /// + /// 关闭窗口 + /// + /// + /// + private void ExitButton_Click(object sender, EventArgs e) + { + Dispose(); + } + + private EventResult SucceedRegEvent(object sender, GeneralEventArgs e) + { + string username = ((RegisterEventArgs)e).Username; + string password = ((RegisterEventArgs)e).Password; + _ = LoginController.LoginAccount(username, password); + RunTime.Login?.Close(); + return EventResult.Success; + } + + private async void RegButton_Click(object sender, EventArgs e) + { + RegButton.Enabled = false; + if (!await Reg_Handler()) RegButton.Enabled = true; + else Dispose(); + } + + private void GoToLogin_Click(object sender, EventArgs e) + { + Dispose(); + } + } +} diff --git a/UI/Register/Register.resx b/UI/Register/Register.resx new file mode 100644 index 0000000..b2e8252 --- /dev/null +++ b/UI/Register/Register.resx @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAC8AAAAvCAYAAABzJ5OsAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAu + IgAALiIBquLdkgAAAQlJREFUaEPtmYEJwjAURDOSI3SUjtINOpKjOEr9h1Hyz9+E1haN3METif2Xp6CE + mpaUll55yt86pJC3x26Q/LfYLJ/SaEzEkD4I5qkPjOH+JTvkr/nakil77ArmqQ9cw/1LJC/5t85T5GcD + b6AEm+NLV3LJbi5Yp+sA5rlzDvcv2SwfsfLJZV8XrNN1YAp7W0he8kFvC8kbHFvBrwheYcKjRNTZRPIG + x1YkX0XyBsdWJF9F8gbHViRf5RD5hyiOCHsZwt4WB8lDwJ45dDCrInnJB70tNsuvbJ7ddgXz1Ad038Yj + eR/MUx+QvEfyPpinPiB5j+R9ME994BT5jv9Q+yX+S74/XvIdkpY7JUbXJnJZ8twAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAC8AAAAvCAYAAABzJ5OsAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAu + IgAALiIBquLdkgAAAIFJREFUaEPtzrENhEAMBVFKoCQqo41NrlezSHAErETAwshigpd9yzP8Soms9vg5 + oSM+IoYsjKcYTzGeYjzFeIrxFOMpxlO+G1/30wPG1q+Wur0Vv970NrV+tdSt8T0Zf2m76e2deJrxFOMp + xlOMpxhPMZ5iPMV4ivGUU3xC//iESizRsfmRb9P6wwAAAABJRU5ErkJggg== + + + + + AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA + AAC8x9z/x9Tp/7zH3f+8wdv/xMrf/9nh6/+/xdb/3eTv/9PY5//T0uL/6OHu/+nl7f/X1uH/5+Pf/+jl + 3f/g4eP/5eft/+rp6//p5+f/6efi/+zo5P/u5+T/7ebj/+zm4//p4+X/4uHi/9zg4//e3N7/09HX//Px + 9//9+/v/4eDr/9TV6//e3ev/7+/y//Pv9P/+/Pz/9fH2/+fh6//X1+T/v77V/9bT3f/U09v/xsXP/9TQ + 2v/h3eb/39zk/97c5//d3Ob/3Nzn/6OqxP+cp8f/mqXI/8HG3f/L1ur/6fD7/9XZ5//q6u//9/b5/8nP + 2f/U2uX/1tri/7/H4P/P1er/ucTc/7rF3P/AxeD/x8vc/8fL2v/Cydj/2uPw/+Hq8f/Hy+H/6OLs/+Hb + 6P/Cv9n/z9Dg/+3q6f/o4+D/5eLh/+Tk5P/o5uf/6Obl/+nn4v/p5eD/7ebi/+rk3v/p5uD/5+Xj/+Di + 4v/c2tz/vr7N/6ipx//T0t//+/n6/+Ph7f/S0+P/8fH1/+zr8P/7+Pr/+fb3/+ji7P/n5PH/1tPl/8jL + 2P/Qztn/3tvl/9TR2v/j3+j/4d3l/+Db5f/a2OL/393n/93d6v+2u9b/zNHn/+Hq+P/j6/v/5e75/8/U + 6f/W2eX/7uzy//Ly9f/Hy9n/zNPg/+Lo7/+zutX/w8ni/7W/3f+st9T/ycri/8jH2f++wNj/1t3s/+Dn + 7//V3er/19Tk/9nX5f+2udT/4dro/8fF2v/k5Ob/7Ofk/+nl4v/n4uL/5uTi/+fl4//o5uH/6uXg/+zm + 3//s5+D/7Ojg/+nm4P/j4OD/wsLR/+Lf6v+vrcb/6+rz/9fW5P/Q0Ob/7ez1//Hu8//39/n//Pr7/+rm + 7f/r5fD/0c7j/+vo9f/T1eP/5OLt/9vY4//j3+j/5N/o/+Pf5//W0dz/29jj/9/e6f/h3+r/ztHh/87U + 6f+1udL/sLnU/7jC1//U1ub/9PL1//Px9v/j4uz/w8fc/8/W4P/K0dz/sbzV/7nF4P+nsM7/yM3j/83M + 3P/Kyt3/0Nbn/9ng6P/Z3ur/x8ve/9XV5P/BxNb/v73U/8fH2v/Z1uP/trXL/+rl4//r5uH/6OTf/+Xl + 3//j493/5+Xe/+vm3//r5d7/6eTe/+nl3P/m4dr/19LN/83J0//q4en/19Pi/9bT3v/o5O//2NXn//bz + 9v/x8fX/+/r8//Hu8//o4uz/3Nfj/8K91//p4u//3N3o/8jH1v/V0d7/5+Tt/+rl7P/X1d//0tPd/9/b + 5v/k3ub/yMrd/9XZ5f/Nz+T/xMXb/4ySsP/T1OL/5+Xp//Hv8//k5Ov/1Nbm/7zD3P+8xtb/tL7U/622 + z//BzOb/pa/L/8bH2//Oy9z/wcjb/9La4//K0+D/y9Hi//Lz9//h3On/2dbm/8jG2//k3uz/39jo/9LS + 5P/d2dz/6+Xh/+rl4f/n5N3/6OXe/+nk3P/q5d3/6eXc/+rn3f/l4db/4tvS/87Iv//Exs3/6+Xu/97d + 7P/X1OX/3NTl/9bZ6f/18fb/8fD0//n2+v/n5e3/5d3r/8nF2P/d2Oj/4dvl//f0+f+4u83/2dXg/+vp + 7//a2OH/z8/c/9fW4v/c2uT/3dzk/7K1zf/X2+n/x83h/8rJ3P+sr8n/t7zO/+Pl6v/r6fH/1NPf/9HV + 4/+6w9j/uMHU/7vF1/+vu9b/2d/v/7jB1f/Cxtr/ub/R/8TL1v/Cytb/vsfY/7vB1f/JyNn/xcTY/+bi + 6//LyN3/6uLv/9DP4f/49/n/2tjg/+vl3//o5N7/5uHa/+Tf1//j4NX/5N3T/9zUxf/Tybf/zcKs/8K4 + oP+xqpb/vr7K/9fS4v/g3en/zMzk/7Kz1P/v8PX/7ezx//36/P/07/b/5t/t/8O90v/Kx9n/7+ju//Ht + 9v/59vj/wcPV/97a5f/m5ez/ycnV/9HQ3f/a2+X/2tjj/9/c6f+fp8b/yM3m/9Ta6P/Bwdf/2tvl/4qR + pf/q6O//zc/c/9DT4f/J0N3/wMva/8HN2v+6xdn/1dnt//Lz+P+9ydz/rrjO/77H0v+/x9P/vMTR/8zQ + 2f/V1d7/2Nnm/7u80//Kyd7/3+Dy/9/e8f/LzOP/9fT3/9rZ4f/p5d//6eLd/+Pf1v/Oycz/xcTM/769 + wv+rqan/rKej/6Oemf+hmpf/h4OO/9PP3v/s5fD/4+Du/87Q3//V1er/8vP1/+np7f/08fX/5+Lr/9rT + 4f+3tcr/tKvF/9vT5v/r5/D/1tbj/9LO4f/d1+L/2Nvj/9TS3v/Rz9r/3d/p/97e6P/GyNz/uL7X/8/V + 5f/n7/X/ur/V/+nn7P+dpLb/pae6/8/Q4f/L0d//x9Lg/9Hb5//P2OX/1+Dw/+Pn7//8/Pz/qbXQ/8LP + 5v+vuM7/wcrU/62yzP/a1uH/29jh/8rL4P/OzOP/2drn//r6/P/y8/r/ys7j//Pz+f/CwNL/2NPN/9vU + y//AwsX/29rl/87Q3f/IzN3/pazD/9bX5v/a1eH/49nl/6qkwP/k3uz/8Ozy/9fX5//V1+X/8/H2/+/t + 8//y7/T/6OLr/+Xf6v/Mx9r/1M/e/+fj7//V1uX/y8zd/+ro8v/Kx9f/4+Lp/8jJ1f/Z1eL/1NDb/+Pg + 6//e4Or/t7zV/7/F2//Dy+H/5e31/83U4v/k5vD/x8zW/3aBmf+WoLn/i5iv/8LJ4P/X4Ov/1tvs/9Ta + 7P/e4ev//f39/7LB1/+3xdz/xNHl/5mowP/Cxdz/2dfh/93Z5v+1tdD/5eDt/9TT4//7+vr/7+3z/9LV + 5f/q5fP/w8Pb/66ko/+1saz/8/L0//z6+v/9+/v/+ff3/+zr8P/g3+j/4d7x/+Lc6v+5u9P/8O/1//Hv + 9v/V1uP/29vo//Xy9//o4+z/7uny/+rk7f/a1ub/v7rT/9rV5P/p5u//9/X3//j2+v/P0Nr/vr3R/+ro + 7//Jytb/2Nfk/9jT3//i4Oz/4eLs/77B2P/JzOH/uL/d/+Po9f/s7/b/v8TW/5Kbt/+Hj7D/jZm2/6i1 + zP+gqsX/zNLj/+Ll7//T2uf/2t7q//39/f+2xNj/vs3h/9fj8f/AzeP/tbvR/9zY5P/a2uP/pafA/8PD + 1//v8vb/+/n7/9vb5f/19/j/4+Lu/9fV5/+vq8D/ubjD//z5+//9+fr//fv6//bz9f/j3+r/7ez0/+bj + 9P/T0OH/6Ofz//r4/P/19Pb/2Nrl/9zd6f/p5ez/6ePt/+3o8f/p4e3/vLjO/9DL2//k4u7/8+73//jz + 9v/8+vr/09Xl/7O2zf/o5ev/5unu/8zO2f/X1uD/3Nzl/+Xo7/+/wtv/y87k/7zC3P/U3Oz/6u/2/7G4 + 0P+Vnb7/hpCw/4OMr/+HkLL/qLHJ/+ru8f/8+/z/xMre/+3v9f/8/Pz/2uHu/7fD3f/X4vH/2+fx/8TP + 3//DxNT/3trn/7q6zv+2us//y87f/8TF3f/U0+T/+vr4//P1+v/c2u3/087e/8G/0v/8+vv//vz8//z6 + +v/w7PH/49zs/8/N3v/z8fj/8fH4//37/P/+/f3//Pv8/9nb5f/Y1+b/3dfk/+3m7//p4u3/5uDt/8PA + 2P/Oydv/4uDs//z6+//7+vv/6+ju/8PF1f/m5e3/3drk/+zr8f/q7fP/zc/b/9bY4v/m6fD/3eTt/7G5 + 2P/HzuP/ys3h//Dw+P/Iz9//mqTF/4mVtf+5wNX/jJey/+Xl8P/7+vz/+vr8/8HH2f/8+/z//f39/77G + 4v+8yN//wM/k/93p8v/U3un/u8TT/83M3f/Lx9j/4dzl/+Ld5v/Kx9r/19fl//z8/P/6+/z/4+L1/+Hb + 6v/BvtL/+vj7//37/P/j4+n/29rl/9jT4f/Gxdj/3trm/+jn7f/39fb//fv7//38+//U1eL/09Dg/9rU + 4P/w6e7/6OHs/9jX5v/i4+7/5OLt/+Tl8f/8+/v/+ff7/9HQ3v/k4Oj/9PDz/9zY5P/h4Of/6+zy/+nr + 8f/Lzdf/4eTs/+js8v/S2en/qrTU/9fb7v/l7fP/6fL4/9fg7/+yvdL/gpCr/5+qv//4+Pz/+/v9/9zd + 6P/f4+z/+/76//39/f+ls9L/t8Xc/7nJ4f/Czd//ytTg/8LO1/+sscf/xsXZ/+DY5f/f2uX/1dPh/8XF + 2v/o6PH//Pv8/+vp+f/f3Ov/zc3e//P09v/9/Pz//fv8//v6+//m5u//ycfZ/97Y5//Y0+T/yczb/+vs + 8v/39vv/ysva/9XX5v/f2+r/497o/9nS3v++uM3/9/P5//v7+f/z8/n/+fr7//T09//V1OT/49/n//Ds + 8//W0Nv/29ji/+jn8P/o6O//6Onz/9TX4//r7/T/7O/1/9Da6//CzOP/4+72/+Pv9f/m8ff/4Orz/87Z + 5v/HzOH/+vv8/+rp8v/Eyt3/+vv8//v+/P/+/v7/uMTe/6Syzv/BzOL/v8zf/7fF3P+yvsv/n6a+/7/B + 1P/Rzt3/3tnk/9zY4//OzN//0tLj/+zp9P/m5fP/z9Hg//Dx9f/9+/z/+/r7//r5+f/a2uf/0M/i/9vZ + 6v/R0Ob/0dLp/93e8P/Iydz/vsHP/6itwf/X2eT/6ejx/9XS4P/SzN3/0Mze/+Db6v/19Pb//fz8//v4 + +f/i4+r/1dTf/+fj6//r5+7/0s7a/9nT3v/b2eT/6enx/+bk8P/e3un/5OTu/+7w8v/n6/L/2N3q/9LZ + 6//j7/b/2+fy/9vq9f/T3+j/vMPY/8jM4P/V2uf/5Obu//7+/v/+/v7//v7+/7zK4P+8yN//tsHa/8HN + 5P+uu9f/sLnO/5CXqP+3us3/ysvY/9bU3v/b1+H/yMjY/7u+1P/c2er/4Nzs/9TT4f/5+/r//fz9/+vs + 8f/Extn/29jp/+zl8v/r5fH/6Of3//Hy+v/18fb/2Nbq/77F2v+Qma//wcXR//n6+f/28/j/zMjb/+fg + 7f/Kyt//ubzR/8zL3f/R0d3/0NDh/8PC1f+7vs//ubnM/8XBzv/f2OL/yMfT/9rd4v/h4ev/4d/q/9fV + 4v/q7PH/5urx/9nc5f/k5/P/1+Ds/97s9f/N2Ob/z9vm/8bR4P+2wNv/u7/Z/+rq8v/9/f3//f3+//7+ + /v/G0+L/rrvU/8fR5v/L1un/qrTX/7e/1/+VnrD/p6rE/9XV4f/Kydj/0NDc/9LR3f+vtMr/2dTm/8bI + 2v/29fj/7Oz1/9PU4f+0tdL/4uHu/+ji7v/s5O//7Ofx/+/s8v/39Pj/+fb5/9bX6f/d3u3/zNLg//Tz + +f/8/Pz//Pv6/8zO3v/u6vP/3dvr/8TG2//b1+H/4Nzj/9zX5v++wtL/zM/c/77D3f+mrMT/y8fX/9rV + 4f++vcj/397p/93c5v/Sz9z/6OXv/+jq7f/d3Oj/5uXu/+Xm8v/R1uj/1+Lt/8TP3f/G093/vcjj/8TK + 5/+4wd3/+vr9//39/f/+/v7/0dvo/8HN5P+/yeH/0tzr/8HN5f+2wNz/jJWs/7S50P/S1OL/wsbX/7m6 + zv/Rzdv/u77S/8bH2v+8wNb/0djj/8vO4P/g5Oz/vcHT/+nk7v/p4+7/7eXz/+vk8f/z8Pf/8fH1/9bZ + 5v/Kzd3/x8fd/5Wcq//FyNT/+vr7//n6+v/g4Of/5OLs//Lt9v/HyNz/1NPf/8TD1f+lpsP/0Mzg/8zM + 3P/h3er/uLjN/8TG2f/OzNf/xcHN/87N1//X1uD/1tPf/93Z5P/r7PD/29vl/9/e6f/y8/f/1dbj/8fR + 5P++ytj/vcjY/7rG4v/Ey+P/u8Le//Tz+f/9/f7//v7+/9Db4v/Y4u7/tMHZ/8/Y6f/h6/b/w87l/5ae + v//Axd3/2Njl/8bI2v+1uc3/xMXV/7O50P/Dz+H/rLXU/9ve5//S0t3/2Nrl/8/L3P/q5O7/6+Tw/+rl + 7v/m4vL/z9Pm/7fB3P/f5vX/4efv/9Xa6v+zu8//1tvk//z7/P/t7fL/7+/1/8/Q4v/W1OX/zcve/9TV + 3v/MzNr/zdDa/7O3zv/Bwt3/1NLh/+ni7f/q5+7/vbnO/8TDzf/Pztn/0tHb/9XS3f/W0t3/6enu/9/g + 6P/f3Oj/4+Dq/+Pj6P/f4+//yNTh/7XA0P+4w9//0dTq/8fO4v/08/n//Pz7//39/f/Y4Or/2ODr/9Xa + 5//O1ef/4+z1/8/Z6f+7wtv/tL3W/83Q4P/Kztn/vcHO/7O0zf+4wtf/z9vu/5qixv/Izdj/09rk/72+ + 0P/n4O7/x8XW/9HP5P/Cwtj/wMXg/8jO6P/W3/P/ucHe/5WfyP/KzOT/39/t/7zC2P/JyNb/xsnc/8LI + 1v+wuNL/zs3f/9/d6//b1+T/0c3Z/8zJ0//i4e7/vr/Y/7W41P/f2+f/5ODr/9nU4/+wsML/0tDb/8zK + 1f/PzNf/1dHc/+jn7P/i5Oz/2trl/+Hf6P/Y1uT/+fn5/9DV4/+8xdb/ucji/87S7P/Cx9r/+Pr8//3+ + /f/+/v3/2+Ls/87W4P/U2OL/5Ozz/9zg8P/Bydz/z9Xm/8nV5v+3wtf/yMrY/7+/z/+hpsL/2OPx/8fS + 6P+utdD/zdDa/9Xa4/+2us//wsDX/7O41P+lrcz/sbnZ/9PZ7/+vt9b/v8nm/7G52P/JzOL/r7PN/7q9 + 2P/OzN//qKvB/9na6P/Fytr/rLHH/727yf/j3+n/5OHq/9TR2//NydP/6OXu/83N3P/AxN7/zcrf/+Dc + 5v/j3ur/q6zE/7650P/U0Nn/yMfR/9vW4f/j4un/3d/o/9jZ4//l5Oz/2dji//Tx9v/Hydj/uMTZ/9Dd + 8v/AxN3/1dbm//39/f/+/v7//f39/9PZ4//W2+X/y87Y//Py9//c3u3/y9Hm/8TL3P/d6PL/ztnr/7W9 + z/+2tMz/uL/W/+Dn7/+2v9v/wsjb/9vc5v/U2OP/ys7a/8jM4P/Nzub/pa3O/9Pa8f+wudz/z9jv/83T + 6v/Dx+P/p6bK/72+2f/Kx93/xsXe/6mqyP+3utH/5+v2/+zz/P/V3ev/trvN/8vM2//U0dz/4N7l/93b + 5f/i4ev/yMnc/8bG2//c2OL/4Nvn/7i70P+lqML/1M/b/8bFz//h3On/5OHr/9nZ4//e3ub/29rj/+jo + 7v/g3eb/vL/R/7zI4f/j7Pr/1dvp/+ns8f/+/v7//v7+//7+/v/b3ej/2drk/9HS3v/f4Ov/yMzh/+bs + 9P/FzOH/3uXu/9zi7P/Aydn/pazC/83U4//Cxtv/oKnH/9TZ5//d3Of/0NPe/9na6P/Gx+H/naXL/7bC + 4//R1u3/ucLg/+Pp+f+4vt3/nKDH/7Sz2//Iwdv/pqXH/7K30P/i5fD/7fH4//Dz/P/r8v3/6vP8/+nx + +f/a4vD/w8ve/7u/1v/T0+D/4t/o/8nI2//c2uf/3tnm/9vW4//Fxtf/urnS/7S1zf/LyNL/4t/p/+He + 6f/Z2eP/4eDo/83N2f/r6PD/5ODp/6uzzP/f5/n/4uj1/9fa5f/9/P7//v7+//7+/v/+/v7/0dXf/9jX + 4f/S1uD/wMPW/8nP4v/K0eL/wsXd/9vi7P/Y3uj/m6W0/7G50f/Dxtv/tLrY/7W/1f/Q1OH/2tvm/8/P + 3P/Mzd//w8rj/5Ccyf/M1u//vsXg/+Ho+v/V3PD/nqHH/5+jyv+zsc//qKvK/9fa7f/u8vr/8PL7/+/z + /f/t8vv/7vP8/+nw+v/q8fv/6PD6/+30+//h6Pb/xs7g/7q7y//ExdT/3Nbk/97a5f/Y0+L/1tTh/7+7 + 0/+bnr7/zcvU/+Hf5f/c2uX/3Njj/+He6P/Nzdr/6ebr/8jO3v/Y4fL/4ur4/8zT5//j5ez//v7+//7+ + /v/+/v7//v7+/7O80P/O0Nr/rLLC/7e+0f/T1+r/vMLX/97g6f/Fyt3/qbC8/6y0xP+2utH/vL7W/7O4 + 0f/N0+L/ztHf/83O2//R0d3/ycvf/7e93f+hq9D/2OH1/9LY7//c5vb/usPg/5mi0f+ZnsD/wMff/+rx + +v/s8/v/7fT8/+3z/P/t8/z/7fP8/+30/f/u9Pz/7PT9/+rz/f/q8fr/8PT8//H0+//r7vb/v8PX/8nH + 2//Z1uH/19Lg/9vX4/+8utP/pqjD/8jI2f/i3ub/0dLd/9rX4v/d2uX/0tHd/9La6f/Z5PL/5e77/8vS + 6f/M0eL/+fn8//3+/P/+/v7//f39//7+/v/Aydn/pa3B/6Wswv++yNn/xMri/8PI2v/U0tn/srrH/4+X + rP+nsL//y8vZ/8DE2f/Hydn/1djj/8vN2f/GxNL/0tDc/8DE2/+wtdj/tb3d/9rh9P/T2O3/1+Dx/5+m + yv+ordf/3ePz/+vx+f/s8/z/7PT8/+z1/f/r9P3/6/T9/+zz/P/h6PD/7PH6/+71/f/u9f7/8Pf9/+32 + /P/w9v3/8/b9//P1/P/N1OP/wsPU/9TR3v/c2uT/vcDV/7S2zv+/wtj/4d7p/8/Q3P/Z1+L/3Nnl/7/B + 0f/d5PD/5O/3/8rV7P/Z4O//2tvp//39/f/9/f3//v7+//7+/v/9/f3/uMHN/7a90P+qssb/yM/d/6iv + zP/V1eL/0dHb/5acr/+fprf/qbHD/8/O3v+7vdL/zMzd/9Xb5f/CwtD/x8XS/9jU4P+yt8//rLLT/6+7 + 2f/S3O//zNPm/9bf9P+PmLz/vcDg/+3y/P/v9P3/7fP8/+30/f/s9P3/6vP8/+v0/f/q8/z/1Nzo/9LX + 5P/x9/3/8ff+/+72/f/v9v3/8vf9//D1/P/y9fz/7fH8/8HG2//Hx9j/wL/O/7a4y/+pq8j/v8HY/+Pi + 6f/Q0d3/2tjh/8fF1v/S2+f/6e/3/8vV6//X3+z/29/q//L0+P/+/v7//v7+//39/f/+/v7//v7+/7fA + zf+vtsn/srnL/83V4f+bpsD/1dTf/83N2/+Yorf/rLXE/7G5yv+5u9T/09Ph/8bI2//c4un/ur3K/87M + 2P/X09//oafE/7nA2v+qt9H/y9Xo/8vW6P/F0uv/qbPY/8XH5f/p7/v/6vD8/+zz/P/t9f3/7fX9/+31 + /P/u9v3/7fT9/+31/f/v9P3/8Pb8//H2/f/v9fz/7/b9//H2/v/s9P3/5e37/+Hr+//d5fr/q7PN/8nK + 3f+Nk7P/pajL/6Gkxf/DxtX/1dLc/83N2//Bx9n/4Orz/83V6f/Q3Or/5Obv/9/i6v/9/fv//v7+//7+ + /v/+/v7//v7+//7+/v/Fztr/srzN/7K7zv/J0Nz/r7jN/83O2v/JzNr/oq2//7e/zP/Dy9v/ubvd/+Tg + 6P/L0N3/297q/8DFzf/Qz9v/1NPf/5ulwv+9w9v/qbXP/8jR6P/I1Ob/vMrl/6m32f/S1vD/6vD8/+zy + /v/s8/z/7fT9/+zy/f/s8/3/7vX+/+30/f/v9f3/8PX+/+/0/P/w9v3/8Pb9/+/1/P/u9fz/6PH7/97o + +v/a4fr/1dz6/6ix0//P0+f/vcHU/5GZuv+3vNP/q7HG/8bE1P+zvM7/0tro/9Xc6//Y4e//xMzi/73B + 1//o6fL//f39//7+/v/+/v7//v7+//7+/v/+/v7/19/q/7jE0f+zv9X/y9Hb/8vP4P+6vdL/y87b/6u2 + x//DzNn/y9Te/8LJ4P/HyNr/yM3h/9XV5P/S1uD/ysnW/9PR3v+krsf/wMba/7O/1//AyuD/ytfo/6y5 + 2v+uuNr/0NXw/9PX7v/h5vP/8PX+//D2/v/s8/3/6fL9/+z0/f/u9v3/8Pf9//D2/f/x9v7/8vj+//L3 + /v/w9/3/7PX8/+Tv/P/Y5Pz/z9r7/8nT+v+9yPD/rbfV/8jO4v+Um8D/rbTN/7W5zv+vts3/ucXa/9je + 6v/I0+P/0tnu/8LI2//X3un/3d/u//7+/v/+/v7//v7+//7+/v/+/v7//v7+/9rf6v/N1eT/tb/Z/9HZ + 4v/e5O7/wcbb/8/R4P+1vdL/ydLf/83W4//d5PH/v8TX/52lwv+ss8z/4eTv/8TF0P/Lytf/srrR/83V + 4//BzOD/uMPX/8jU5f+tueD/pq3W/5OVxf+rttv/4+r8/+71/v/v9f7/6/P9/+rz/f/u9P3/8PX9//H3 + /v/v9f7/8Pb9//H3/v/x9v3/7vT7/+rz/f/d6vz/09/5/83X+//G0fr/wcz5/5Sdwf/HzOP/kpvE/6Ws + x//Gyt7/s7jN/7jB1v/K0+L/ztjq/7e/1P/3+fr/1tvp/97h7P/+/v7///////7+/v/+/v7//v7+//7+ + /v/x8vb/09Xi/77D2f/X3e3/3eLs/9Xc6//Bxtn/wMfg/9HZ5v/R2ef/3ebx/8DF2//Z2+b/oqnE/8PH + 2f/GyNL/w8TV/7O60//P1+L/wcvf/7XA1f/I0+j/sbzl/4GJu/+Qm8z/ztr8/9nj/f/n7/z/6/P9/+zz + /v/s9P7/7vT9//D2/f/v9fz/8ff+//H3/v/x9/7/8ff9/+3y/f/l7/v/1+P8/7rD7/+/yPj/xtH1/8PN + /P+yu+b/oqnH/6WszP+vs8z/usHV/7O90f+/xt7/v8ve/7/K2//P0+H//fv7/9Xa6//e4ev//f79//7+ + /v/9/f3//v7+//7+/v/9/f3/+/z9/+rs8//Hytn/xs3e/+Hp8//p8Pn/xMzc/8fP4P/Q1+v/2d/y/9zg + 8P/Z3+7/w8TV/9fa5/+or8z/x8ra/73A0P/IzuT/0tvm/7/I3v+1v9X/xdDm/7C74f99h7v/v8r0/8rV + +//R2vr/4uv9/+z0/f/r8/3/6vP8/+3z/f/x9v7/8ff+//H3/v/x9/7/8ff9//L4/f/v9P3/6e/9/7/J + 8f+9yfb/ucXx/8LI7//O0fj/v8b2/6Gszf+lrsz/o6fF/7/F2P+6wtb/vMbb/7zI3/+wutD/8/X6//T1 + +P/T1ej/5+rv//3+/v/9/f3//v7+//7+/v/+/v7//v7+//39/f/8/f3/4eHo/9PW5P/Y4e//4e71/+Ps + 9P/Byt3/vcfg/97l9v/c4/L/6ez5/8rP4f/U1eT/t7nR/7q/1v+/wtT/1d3s/8/Z5v+/yt//t8LY/8TP + 5v+kr9b/orDg/8nT+v/K0/v/0Nf6/9je+v/k6/r/7fT9/+rz/f/t9P7/7/X9/+72/f/v9v3/7/b9/+70 + /f/u9f7/7PP8/9/f9//QzuT/xsbS/83M1v/MzdX/vrzE/7O16f+mq9P/lZ69/56kyP/Fy97/srrW/7zK + 3v+1v9b/vcXX//n7+//V2OX/2dvq//r7/P/+/v7//v7+//7+/v/+/v7//v7+//39/f/9/f3/+fb6//Hx + 9//Y2eT/1djl/93n8v/e6/L/3+nz/6+82v/N1u7/4uz3/9zm8v/l7Pj/v8LY/8/R5f+ytM3/mJ25/97l + 9//W4e7/yNHl/8HO4f/H0ur/q7bc/6++6f/H0vr/wMz6/6mv5f+mreH/t77w/+jv/P/r8vz/7PL9/+/2 + /f/u9P3/6u74/+/z/f/w8/3/7fP8/+/0+v/a2+7/s6KQ/5mCa/+rmYT/u6yf/6ydkf+4tsr/kJDB/4mP + sv+ao8P/z9Pn/6y11P++yuL/t8LW/8rQ3//39/v/193t/+Dg6v/9/f7//v79//7+/v/+/v7//f39//7+ + /v/9/f3/5unv/9jc7//W2/D/2Nvr/97d6f/P1Of/2uTy/97n8v/a4vL/p7DT/+Pr+f/e5vL/4Ofy/9/i + 7/++v9j/urvO/52iwv/b5PX/1eHu/9Pd7v/L1uj/xNDn/7bB4P+/ye//u8Hp/7vA3//Iy9v/ys7f/83R + 5//S0t//6Oz3/9Xd7v/R1+7/0dnu/9LW6v++yOP/tsHb/7jC3P/b4e//wcff/5eOlf94Z1j/i3Zb/6mU + fv+OhHX/uLa//4iIpv9ucIr/mZ+7/87S5P+6wtz/t8HY/7K7z//a3+v/5uXw/9DW5//4+Pv//v7+//39 + /f/9/f3//f39//7+/f/9/f3/9fP0/9/h7v/g5vz/1tvp/97h7f/d3en/xMfd/8nR4v/Q2Of/09zn/8XN + 5P+7x+D/5Oz4/9rj7v/g6PH/xsra/6ytx/+jqcv/3Of3/9fi8f/Z4/P/0drr/7zI4P+8wOH/sbLZ/6Cb + pf+/t6f/wrWj/8a5q//Pxbz/v7W0/87N2/+9xeD/xc3q/9HY9P+osdj/r7TZ/73G5P/DyOT/2t3v/8vQ + 5P+nrc7/kpKq/3NpcP+Gdmj/bWlx/2xtiP9obIn/g4ep/6Goxv/P0ej/usLZ/7/I2f+6w9b/3eLs/9rb + 7//Z3Oj/+/z7//39/f/+/v7//f39//7+/f/9/fz/+Pn4/9DT1f/m5vL/2d3x//X2+f/7+/r/+Pf4/9fU + 5f+wttP/0djp/8jQ3f/L0+L/q7bT/9Xf7f/c5O7/2uDr/+Hn8P+ipsH/s7XU/9vo8v/V3+7/2+f0/9Ld + 6/+/yuL/sbTV/4uMt/+Og3r/qJB0/5yFZf+vmHj/xK+U/6qbkP/ExNT/oKXH/6Os1P/X2/f/19z6/8TJ + 5v+0u+D/rLLV/9zg8//N1O3/nKPL/8PJ4f+nrdD/houp/3+Apv91gKr/lJi5/6euzf+xttP/0NTr/8HI + 3//L0eH/vMTX/9PX5//T2Oz/0tPi/+Hh7v/8/P3//f39//39/f/9/f3/8vL0/9vb3P/p7ev/7e/1/9LV + 5//6+v3/+/v8//z6/P/i4uz/srfU/7G41P/T1uL/ys/e/8HI2/+nss//3OTv/9zl7v/c5e3/zNLk/73F + 2v/d6fL/0Nzq/9nm8//S3+7/t8Xb/46Qsv9vcZH/kIiR/4VuW/+AaVP/n4Zm/6CHa/98dXT/gomk/6On + yP+QmMH/wcXm/9fc+f/d4fj/ucPn/7vC5f+3vdz/2+H3/6Oqz/+4u9f/4eL0/9ji8//L0eb/maDE/8rQ + 5/+zudX/w8zh/9DW6/+7xNv/19vs/7rB2f/JzuT/4+Pu//Dy9v/JzOL/9vj7//7+/v/+/v7/+/z9/+Lk + 5//Y2tv/6u3q//v7+//e3+v/7e7z//j5+v/U2Oj/uMHb/7rD3/+nr87/w8bZ/8vM2v/N0N//rrjU/7vE + 3P/b4u7/2uLs/93k7v/Eytj/2+bw/8nW5P/T4u//ydjp/7zI3v+cpcT/aG6R/2Vohf9kZGz/Z2Bg/2dd + XP9dWmT/Vltz/4SMrP+hp8b/oaXJ/7W84P/W2vH/1dnw/9Pc9P+xut//pKzS/9bb9P/K0u//p7LV/9ja + 8f/o7Pf/7fD2/7G11P+4vNj/srfU/8zV6f/N0+n/wcXe/9rg7//ByOT/zdDh//j4+//2+Pn/zdDk//Dy + 9f/+/v7//v7+//7+/v/3+Pj/3d/e/+Pm5P/8/Pz/+Pj6/+Ph7P/d3+7/1try/9TY8f/R0+v/2Nvw/8/V + 6f+1utP/zdLh/8LL3v+Xpcf/09vr/9fh6//T3Ob/zNPk/9Te6//I1uL/y9vn/8bU5//I0+T/tsHZ/5uq + zP+WnMn/foSv/4SNr/9ob5H/dXyj/6Wt1f/Aw97/vMPb/4qPtP+3w+D/zdfr/8zX6//M1ur/usTi/7G9 + 3v++yeX/zdju/8TQ6//Fzuj/4ef1/+js+P+3udb/vcTc/7e91v/L0+f/x8/j/77E2//Y3uz/ytPo/9HV + 5v/8+/3/+vv7/8/S4v/6+vv//v7+//39/f/+/v7/+/z8/9ja2f/d4d///f39//z7/f/a3e3/z9Pn/9nd + 6f/h5vD/x8vZ/8DB1//Cwtj/ztXr/7rA2P/P2OX/rbnV/7rE3P/W4Or/yNLd/9Da6f/C0OH/yNTg/8XV + 4f+5yNr/wM3g/77H3f+uuNb/q7LW/7nC3f+nr9X/rbfU/6Kp0f+9wuL/3t/y/9/c8v+qsMz/tr/a/8rW + 6P/H1Of/xNDj/8XU5/+yvdz/rbjY/8XQ5//J0+z/w8rp/+ju+f/m6/j/uLnV/7e/1/+rssv/w8ze/7zE + 1v+1vNL/193s/8TM4v/R1Ob//Pv9//v7/f/Q0uP//f39//7+/v/+/v7//f39//P09P/X2tj/19vZ//z8 + /f/n6PL/1Nrr/+ns8f/g3+f//Pr8/+zs9P/Oz9v/0c/a/7y+0/+3v9X/xczd/8TO3v+rtdL/1uHv/8nU + 4f/J1OL/tsHW/8XP3v/Bztr/tcHS/6q3z/+qtM//rbfY/6q20//Fz+X/r7XU/8jP5v+ttdX/oafT/9TZ + 8P/n5fT/0M7j/6Krzf+8x+D/ws7g/73J2//D0OL/sr7X/7K83P/Ay+H/u8fc/7vD4//f5fb/1trp/6qv + zP+5wNb/o63F/7rE1f+2vtD/s7zO/8/Y5P+7w9//2Nrl//38/P/y9Pj/2dzp//39/f/9/f3//v7+//z8 + /f/g4eH/6Orn/9rc3P/8/fz/5ujz//v7+//8/Pv/6uzx/+nr8P/6+vz/z9Ld/9DR3v/Iydj/yMvb/6Gv + y//FzN7/s73V/9Db7P/M2OT/wcza/6660f++yNf/vsrV/7jC0/+2xNP/rbnR/5mnxf+Vnr7/vcTf/7/G + 3f+0utb/vcff/6Oq0/+7w+L/6e35/9fU5/+mq83/rbjT/7bC1v+8yNr/ucTW/6u2zf+wvNT/usXZ/7fC + 1f+0vdn/2+D4/9/h8/+ttNL/tb7W/5ulvP+xu8z/srrM/623yP/Gz+D/vsbf/9vd5f/7+Pr/3uDq//Hz + +P/9/f3//f39//39/f/u7u//6evj/+Tm3//s7vD//f38//v7+//9/Pz//Pz8//r8/P/p6O//5ubu/9jc + 5P/W1+L/1NXi/8nJ2P/Hzd3/mqW8/8vT5/+9yN3/yNbi/7nG1v+ruM7/vMnY/7vH0/+3wNH/rrnO/665 + y/+eqcb/lJ++/5KYu/+wuND/qLHL/7fA1P+irMv/oqrL/83R5f/NzeL/o6rE/6GrxP+quNL/v8zd/7C7 + y/+wuc7/r7nM/7bB0v+0vtD/sr3T/87V7//Qz+f/qrDR/7nA1v+iqL3/r7fJ/621x/+stcb/xM/i/7S6 + z//i5en//Pz8/97g6f/9/f3//v7+//7+/f/19vT/5ebg//Dy5P/k4+D//Pz9//39/f/8/Pz//Pz8//z8 + /P/8/Pz/+/r8/9HU3v/d3uv/x8nW/9nd6P/IzNn/09Tg/77E1f+pscX/u8fd/8HP2/+4xdX/pLDG/7vH + 1/+yv8v/srvK/6izx/+5xNb/lJ67/5qkvP+Pmrn/lKC+/6Krx/+vuNL/r7nP/52ryv/ByeX/zc7g/6Cl + wP+tuM3/n6vK/6+80v+wvM3/uMLS/7C6y/+zvc//s7zP/7TA1P/M0+7/wr/b/6y00v+7wtX/pazB/6y1 + x/+stcj/q7bI/8TO4f+mrMD/4ePp//f3+v/j5Oz//f39//39/f/9/Pz/5ubh//Hy5f/n5d7/+Pb2//39 + /f/8/Pz//Pz8//z8/P/8/Pz//f39//z9/f/q7O//x8vZ/9HS4f/d4+3/2N7o/9PT4P/Hy9v/vMPU/6Kt + yP++zNj/usfX/6GtwP+0wdD/rrnH/6u2xf+ircT/vcjY/5iivP+eqMD/l5+8/6auxP+lrcf/oqvF/7e9 + 1P+ZosP/tr3b/8zN4f+jpsX/tL7S/6Gsxv+wvNj/sb3R/7bA0P+3wtH/s73O/7S9z/+yvdL/v8fi/728 + 2P+wuNX/ucDU/6Wtw/+tuMv/q7bK/7O/0f+9xdb/r7XE/+Pk7v/h4ev/+Pf6//39/f/8/Pz/8vLv/+7t + 4//u7uT/5uXi//39/f/+/v7//v7+//7+/v/9/f3//f39//z8/P/8/Pz/+fr6/8/T3P++wdD/4Ofv/9/j + 8P/S1eP/0dbl/8TL2f+osc3/r7zQ/7rF1f+jrr3/o6/C/7C6y/+uucr/m6S+/7rG0/+jrcT/rrjO/5eh + v/+rtMr/qLDG/6+50v+osMj/oqvH/7G61P+9vtn/panH/7O+0/+yv9L/qbbT/6i0yP+yvM7/ucPV/7TC + 1P+3xNX/s77S/6620v+1s9L/tLzZ/7nB0/+uuM3/t8HT/7vE1v/By93/uL7O/8jL3P/m5/H/zdHi//z7 + /f/+/f3//v7+/+bm4//r7OP/4+Tc//r7+v/9/f3//Pz8//39/f/9/f3//v7+//39/f/8/Pz//Pz8//z8 + /P/t7vH/zM3c/9DX4f/f5vH/19vp/9nd7P/K0t//ytTk/5qlx/+0wNX/nqu7/5iiuP+ossT/q7XH/5qk + vf+0wM7/rrjM/7nD1f+msMv/rbjP/7a/0v+mscr/tsHW/6ixyP+nscj/q6/O/6mry/+zwtr/tsPW/6u4 + z/+7xdz/t8LX/8PQ3v+0wtX/u8jb/7zH1/+nr8z/razO/8HH4P/Cytr/wsze/8XP3P/P1+f/0Njn/8bL + 3P/R0+T/4uXw/+Hk7//9/f3//f39//39/f/Z2db/5+jg/9/f2v/9/f3//f39//z8/P/+/v7//v7+//z8 + /P/9/f3//f39//z8/P/7+/v/+vv7/9PU3//U1ej/3ubz/9vk8f/V3On/1dzs/9Tb6/+3wdn/m6bE/6Wv + wf+Klq3/q7XH/6qzxf+eqMD/sL7O/7S/0f+9x9n/r7rP/7C+1f++ytr/sr7U/7/I3P+yu9D/p7LM/6uy + zP+rr87/vMrg/8TO4P+8x9v/rbjV/7K+0v/N2er/vcvd/8DN4P+/ytj/rrbR/6Kkyf/P1Ov/xszg/8XP + 4f/X3+v/1dzq/9Tb6//a3u7/1tnq/87S4f/3+fz//v7+//39/f/7/Pz/1NbU/+fn4v/l5uP//f39//39 + /f/9/f3//f39//7+/v/9/f3//v7+//39/f/8/Pz//vz8//v7+//z8/X/19jn/9ji7f/f6PX/2ODt/9ff + 8f/U2+//0tvs/6awz/+Xn7n/hpCk/6y2yf+rtMb/o63E/6u5yf+xvc//vcja/7jE1/+wwNr/ytXn/7zI + 2/+uuM//0tnq/6izyv+2vtP/pKjI/8XQ5f/N1ub/ws7f/6i00P+1wtr/1N3t/8vW5//J1ef/yNPk/7a+ + 2P+nq9L/09vt/8TJ3v/FzeH/2ODr/9Td6v/V3e3/5ef2/87S4//e4ez//f39//39/f/9/f3/+/v7/9HU + 0//m5uH/4uPg//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/8/Pz//f39//7+/v/8/Pz//P39/+Di + 6f/b4e3/5ev4/+Ln9P/c4/P/xtDm/9jg7f/By9//nKfB/4WQpf+eqb3/srrL/6myx/+qtsf/sb/Q/7G9 + 1f/E0uX/rr3Z/87Z7f/L1uj/ytXn/7O90//FzeL/vcbb/5+lw//I0uX/0Nro/8vX6P++yuH/ssLb/8fP + 4v/Q2er/zNnq/83a7P+zvdb/t73a/87V5P/HzuD/xM3e/9Dc5v/R2+z/197v/+Pk8//M0OT/8/T4//39 + /f/+/v7//v7+//39/v/U2tr/5efi/9ze2//+/v3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39 + /f/9/f3//v7+//39/f/z9fj/4OHu/+Ln9f/g6fb/2+Xv/8fP5//V2u3/197t/7XB1v+Vn7n/lqG2/7jB + 0v+zvND/rrrL/7rG1v+ntNH/y9rr/7jG4f/N2vD/0tzu/9zg8P+8xdr/ydPl/7rC2/+lrsv/yc/k/9Xe + 7v/P2uv/0tzt/7bD3/+9xtz/1d7u/8/c7f/Q3vD/srzV/73H2v/Fzd3/w87f/8TO3v/P2uX/0tzs/97k + 9P/c2+v/19jp//z8/P/+/v7//f39//39/f/9/v7/2+Dg/+bp5f/X2tj/+Pr4//7+/v/+/v7//f39//7+ + /v/+/v7//f39//39/f/+/v7//v7+//39/f/9/f3//Pz9/+Tk6//e4e//4Oj3/9ri8f/T2u3/xc7h/9Xd + 7P/J1ej/t8HY/46Ysv/BzN7/wszd/7nE1f/G0OL/tsLY/8XS6v/K2O7/ytnv/9Pf8f/T2+n/1+Du/622 + 1P/R3Or/l6LC/77G3P/U3uz/zdfo/9Ld7/+4wt7/wszk/9ff8P/O2uz/0eDy/666z//L0+P/v8jX/77J + 2v/Ez97/z9nl/9Ha6f/b3+7/xsnh//Dx9//+/v3//f79//7+/v/+/v7//f39/+Ll5v/e5OT/5uvq/97h + 4P/9/fz//f39//39/f/9/f3//v7+//39/f/9/f3//f39//39/f/9/f3//f39//39/v/09Pf/4OLs/9re + 7//X3e//zNbo/83W5//U3uz/zdvq/7jG2/+lss//t8LX/9Lc6f/Ez93/ztbo/8zX5v+5xuD/1ODy/87b + 7//U4PL/z9no/9vj8f+6xNv/xM7l/6+91P+3wdf/1t/w/8zX6f/S3/H/u8je/83Y7//DzOH/ytrr/9He + 8v+yvND/y9bi/7O90P+4wtT/wczb/9Hb6f++x9z/0dTo/87S5P/7/fv//v79//3+/f/+/v7//v7+//7+ + /v/5+/v/0tfa/+zw7v/h5uf/8vPz//39/f/9/f3//f39//39/f/9/f3//f39//7+/v/9/f3//f39//7+ + /v/+/v7//Pz8/+vr8P/g4fD/1Nzv/7rF4//M1+f/zNrp/8PS3P/Ay+D/sb3U/7nB2v/c4fL/0Njo/83V + 5v/a4vP/wMvi/9bh9P/P3e//0+Hz/87b7f/Y4e7/ztjp/6u11f/N2+r/s77X/9Pd7//J1ef/y9nr/8XT + 5v+/zuT/uMXe/8rY6v/S3/D/s7zS/8jT4P+wus7/t8LS/8LP2//O2eb/p7HP/7vA3f/19/r//f39//7+ + /v///////v7+//7+/v/+/v7//v7+/+nr7//m7O7/7PL0/+Lp7f/o6ez//v7+//39/f/+/v7//f39//39 + /f/9/f3//f39//7+/v/9/f3//f39//z8/P/6+fv/4ODs/9fd7v+4xeD/usng/8LS4P+8y9X/vs3Z/6y5 + zv+1v9P/0Nfq/9zh7v/V3e3/2eLy/9fh8f/L1+z/ztzu/83b7f/O2+3/0Nrs/9DZ6v+zwtb/zdjr/7G+ + 1//K1ej/ws7g/8XT5f/C0OD/s8Db/7XB3P/K1ub/1eHt/7C6z/+4wdf/s77O/7jD0f/Bzdj/s77U/7K5 + 1P/V3On/+/z8//39/f/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7/4ufs/+nw+P/t9v3/5u/1//7+ + /v/+/v7//f39//39/f/+/v7//f39//7+/v/+/v7//f39//7+/v/9/f3//f39//Du8//f4e3/1t3u/6y3 + 1v+0w9P/t8TR/7jE0P+xu8z/p7HG/7S+0v/f5PH/2uPw/9Td6//d5vT/zdnu/8vZ7P/K2Or/ytjq/8fW + 5f/N2Ob/x9Pk/7PB2P/N1+n/s8DT/8DN2/+9y9v/tsbX/6m40/+7yd7/wtDg/8rY5f+qtcv/sb3R/7G8 + zf+2ws3/vcbZ/6qz0P/Cyd//+Pr8//39/f/9/f3//f39//7+/v/+/v7//v7+///////+/v7//v7+//z9 + /f/i5+//4er0/+v1/v/9/f3//f39//7+/v/9/f3//Pz8//39/f/+/v7//v7+//39/f/9/f3//Pz8//39 + /f/8+/z/29vh/97e6//Ezd//prTH/6SwwP+krb3/o66+/56twP+fq7//zdjq/9fg7v/T3On/197r/9Tc + 7//H1en/xtTl/8PR4//Az97/x9Ti/8PR3f+ruc//zdjq/7O/0/+9ytn/v8ra/7HB0P+iscz/v8/l/7jG + 2v/Dz+H/nqfC/6exx/+yvcr/t8TS/6evyv+2vdv/3+Xu//z8+//9/f3//f39//7+/v/+/v7//v7+//7+ + /v///////v7+//7+/v/9/v7//f79/+rt8v/W4Oj//f39//39/f/9/f3//v7+//39/f/9/f3//v7+//7+ + /v/9/f3//v7+//7+/v/+/v7//f39//X2+P/X1uH/2tvm/7nD1v+frb3/m6Wz/5ijsf+dqLb/pbDC/7G8 + z//U3e3/1t/s/8bO3P/b4O//vMnh/77P3v/Az9//v8/e/77L2P/AzNj/tMHS/7C/1P+9ytv/rbzQ/7XC + 0v+qt8r/nanD/7zK3/+wutP/u8jc/6Kswf+stsb/sr7K/6q1yf+stNP/xc3k//r7+//9/f7//Pz8//7+ + /v/+/v7//v7+//7+/v////////////7+/v/+/v7//v7+//7+/v/+/v7//f3+//7+/v/8/Pz//f39//39 + /f/+/v7//v7+//7+/v/+/v7//v7+//z8/P/+/v7//v7+//39/f/7/Pz/6ert/9LS3f/U2eb/sbnN/7q/ + 0/+bprv/kpyy/5unuP+ap7r/zdXo/9Tc7f/I0eD/zdbj/8bR5f+xwNf/u8nY/7nG1v+5xdP/u8fS/7C9 + yv+Ypr//x9Pg/6GuyP+wucv/pbLF/5Ohuf+zwdf/pbHL/6+70v+ttMb/sLnI/7G7zf+usc3/v8Lc//b2 + +//9+/v//fz9//7+/v/9/f3//v7+//////////////////7+/v/+/v7///////////////////////7+ + /v/9/f3//Pz8//39/f/9/f3//v7+//7+/v/9/f3//v7+//7+/v/+/v7//f39//39/f/9/f3//f39//z8 + /P/f3+n/u8DS/87S3v/Z2uf/4+Tw/+Tn8f+nsMT/mKS0/664zP/T2uj/0Nzn/73G1f/L1uL/qLbQ/6+6 + yv+yvs7/rbfI/7G7zP+ns8T/l6S6/7G9zv+ltcn/pK/C/5unuv+Pn7T/s8DV/6i0zv+osMj/sbnL/6m0 + x/+ssMv/srXR/+bq8f/7+/v/+/v7//z8/P/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//// + ///+/v7//v7+//39/f/+/v7//f39//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3//v7+//7+ + /v/9/f3//Pz8//79/f/9+/v/0NTh/9vf6/+rssb/5ubt/8XH2/+/xdj/2t7o/5ieuf+Uobf/yNLk/9Hc + 5v/Czd7/vcfX/8XR4f+eq8L/pbDC/6GqvP+hq7z/oa2//5ypvf+lssb/s7/Q/52pvf+WorT/kJyy/7XB + 1P+rtc7/pa3E/6CrwP+vtMv/rrDL/8rO4f/7+vr//f39//7+/v/+/v7//v7+//7+/v/+/v7///////// + ///+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ + /v/+/v7//v7+//7+/v/9/f3//f39//7+/v/+/f3/+/n8/83S4P/Kz97/3eDr/7S4z/+qr8X/yMvf/8rR + 4v/GzeL/4OXv/6ayyv/Y4ez/ydbl/7rF1f/G0t3/tsLV/5upvf+cprj/mqK0/5ynuf+WorT/n6m8/7/K + 2f+Tn7P/n6i6/5mitv+2wdL/naO//52lvf+rrsT/pKbB/8DE2f/29/r/+vn7//z8/P/9/f3//v7+//7+ + /v/+/v7//v7+///////+/v7///////7+/v/+/v7//v7+//7+/v///////v7+//7+/v/9/f7//v7+//7+ + /v/+/v7//v7+//7+/v/+/v7//f39//7+/v/+/v7//v7+//3+/v/+/v7//vz8//z7+/+7wdj/xsnf/+fq + 9f/Axdr/ys/h/622y//q6vT/r7fP/8nK3P+psMr/xs3f/87b6f/Ez9//uMLS/7/L1/+stsz/lKC0/5ad + rv+bpLT/nae5/6Gpu/+3wNP/qbTL/7vB0//Kz9z/q63G/6OkwP+srMf/lZi5/7K3z//09Pj//f39//39 + /f/+/v7//v7+//7+/v/+/v7//f39//7+/v///////v7+//7+/v/+/v7///////7+/v/+/v7///////7+ + /v//////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + + + \ No newline at end of file diff --git a/UI/RoomSetting/RoomSetting.Designer.cs b/UI/RoomSetting/RoomSetting.Designer.cs new file mode 100644 index 0000000..9426073 --- /dev/null +++ b/UI/RoomSetting/RoomSetting.Designer.cs @@ -0,0 +1,39 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + partial class RoomSetting + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "RoomSetting"; + } + + #endregion + } +} \ No newline at end of file diff --git a/UI/RoomSetting/RoomSetting.cs b/UI/RoomSetting/RoomSetting.cs new file mode 100644 index 0000000..da43391 --- /dev/null +++ b/UI/RoomSetting/RoomSetting.cs @@ -0,0 +1,10 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + public partial class RoomSetting : Form + { + public RoomSetting() + { + InitializeComponent(); + } + } +} diff --git a/UI/RoomSetting/RoomSetting.resx b/UI/RoomSetting/RoomSetting.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/RoomSetting/RoomSetting.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/Start.cs b/UI/Start.cs new file mode 100644 index 0000000..dfbc124 --- /dev/null +++ b/UI/Start.cs @@ -0,0 +1,15 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + internal static class Start + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + ApplicationConfiguration.Initialize(); + Application.Run(new Main()); + } + } +} \ No newline at end of file diff --git a/UI/Store/Store.Designer.cs b/UI/Store/Store.Designer.cs new file mode 100644 index 0000000..76d1a9b --- /dev/null +++ b/UI/Store/Store.Designer.cs @@ -0,0 +1,39 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + partial class StoreUI + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "Store"; + } + + #endregion + } +} \ No newline at end of file diff --git a/UI/Store/Store.cs b/UI/Store/Store.cs new file mode 100644 index 0000000..9bf65b9 --- /dev/null +++ b/UI/Store/Store.cs @@ -0,0 +1,10 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + public partial class StoreUI : Form + { + public StoreUI() + { + InitializeComponent(); + } + } +} diff --git a/UI/Store/Store.resx b/UI/Store/Store.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/Store/Store.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/UserCenter/UserCenter.Designer.cs b/UI/UserCenter/UserCenter.Designer.cs new file mode 100644 index 0000000..ef21500 --- /dev/null +++ b/UI/UserCenter/UserCenter.Designer.cs @@ -0,0 +1,39 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + partial class UserCenter + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "UserCenter"; + } + + #endregion + } +} \ No newline at end of file diff --git a/UI/UserCenter/UserCenter.cs b/UI/UserCenter/UserCenter.cs new file mode 100644 index 0000000..ea5cb72 --- /dev/null +++ b/UI/UserCenter/UserCenter.cs @@ -0,0 +1,10 @@ +namespace Milimoe.FunGame.Desktop.UI +{ + public partial class UserCenter : Form + { + public UserCenter() + { + InitializeComponent(); + } + } +} diff --git a/UI/UserCenter/UserCenter.resx b/UI/UserCenter/UserCenter.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/UserCenter/UserCenter.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Utility/OpenForm.cs b/Utility/OpenForm.cs new file mode 100644 index 0000000..c8d406e --- /dev/null +++ b/Utility/OpenForm.cs @@ -0,0 +1,96 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Library.Exception; +using Milimoe.FunGame.Desktop.Library; +using Milimoe.FunGame.Desktop.UI; + +namespace Milimoe.FunGame.Desktop.Utility +{ + public class OpenForm + { + /// + /// + /// + /// 窗体类型 + /// 打开类型 + /// 构造参数 + /// 目标窗口可能已处于打开状态 + public static void SingleForm(FormType type, OpenFormType opentype = OpenFormType.General, params object[]? objs) + { + try + { + Form form = new(); + bool IsExist = false; + switch (type) + { + case FormType.Register: + form = new Register(); + IsExist = RunTime.Register != null; + RunTime.Register = (Register)form; + break; + case FormType.Login: + form = new Login(); + IsExist = RunTime.Login != null; + RunTime.Login = (Login)form; + break; + case FormType.Inventory: + form = new InventoryUI(); + IsExist = RunTime.Inventory != null; + RunTime.Inventory = (InventoryUI)form; + break; + case FormType.RoomSetting: + form = new RoomSetting(); + IsExist = RunTime.RoomSetting != null; + RunTime.RoomSetting = (RoomSetting)form; + break; + case FormType.Store: + form = new StoreUI(); + IsExist = RunTime.Store != null; + RunTime.Store = (StoreUI)form; + break; + case FormType.UserCenter: + form = new UserCenter(); + IsExist = RunTime.UserCenter != null; + RunTime.UserCenter = (UserCenter)form; + break; + case FormType.Main: + form = new Main(); + IsExist = RunTime.Main != null; + RunTime.Main = (Main)form; + break; + default: + break; + } + if (Singleton.IsExist(form) || IsExist) + { + throw new FormHasBeenOpenedException(); + } + else + { + NewSingleForm(form, opentype); + } + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + } + + private static void NewSingleForm(Form form, OpenFormType opentype) + { + try + { + if (Singleton.Add(form)) + { + if (opentype == OpenFormType.Dialog) form.ShowDialog(); + else form.Show(); + } + else throw new FormCanNotOpenException(); + } + catch (Exception e) + { + RunTime.WritelnSystemInfo(e.GetErrorInfo()); + } + } + } +}