commit 8b8af65a1bb6e636a3e1653ebcd9a552cbf4d942 Author: leandrotlz Date: Mon Dec 23 10:45:29 2013 -0800 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdc3535 --- /dev/null +++ b/.gitignore @@ -0,0 +1,108 @@ +# Build Folders (you can keep bin if you'd like, to store dlls and pdbs) +[Bb]in/ +[Oo]bj/ + +# mstest test results +TestResults + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.log +*.vspscc +*.vssscc +.builds + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper* + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Publish Web Output +*.Publish.xml + +# NuGet Packages Directory +packages + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +[Bb]in +[Oo]bj +sql +TestResults +[Tt]est[Rr]esult* +*.Cache +ClientBin +[Ss]tyle[Cc]op.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ef7e7ef --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 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 General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is 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. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + 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. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + 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 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. Use with the GNU Affero General Public License. + + 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 Affero 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 special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 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 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 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + 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 GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2099bec --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +Tequila +======= + +Tequila is a general purpose patcher that can keep software up to date and launch it. + +It was originally created for Titan Icon, a project that required relocating existing software into a different folder before patching it. In its current state, it's trivial to modify it for use with other software. + +The initial commit still has some hard-coded links for Titan Icon. The manifest URL has been left in for use as pseudo-documentation on what's expected from the XML file. + +Features +======= + +Contained in a single executable: users only need to download one file and run it; it will find the existing installation, relocate itself to it, and create a desktop shortcut. + +Patches itself: Tequila will compare its own MD5 sum to the one in the manifest file, update itself if needed, and restart. + +Multiple download links: each file in the manifest can have any number of source URLs. Tequila will pick one randomly, and attempt another if the first one fails; it will only error out after trying all the links. + +Multiple launch profiles: it can be used to launch the same executable with different parameters, or different executables. + +Developer-only profiles: certain launch profiles will be hidden from the launch list unless Tequila is started with -dev. + +Bypasses User Account Control: it will relocate an existing installation to Local App Data, to avoid problems with UAC and VirtualStore. + +Command Line Options +======= + +-noselfpatch: do not attempt to patch itself. + +-md5: generates an MD5 sum of itself and copies it to the clipboard, for use it with self patching. + +-dev: display the devlaunch profiles. + +-nomove: do not relocate Tequila to the install folder. + diff --git a/Tequila.sln b/Tequila.sln new file mode 100644 index 0000000..d5151ee --- /dev/null +++ b/Tequila.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C# Express 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TequilaPC", "TequilaPC\TequilaPC.csproj", "{18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + AppStore|x86 = AppStore|x86 + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162}.AppStore|x86.ActiveCfg = Release|x86 + {18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162}.AppStore|x86.Build.0 = Release|x86 + {18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162}.Debug|x86.ActiveCfg = Debug|x86 + {18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162}.Debug|x86.Build.0 = Debug|x86 + {18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162}.Release|x86.ActiveCfg = Release|x86 + {18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + EndGlobalSection +EndGlobal diff --git a/Tequila.userprefs b/Tequila.userprefs new file mode 100644 index 0000000..48ccb28 --- /dev/null +++ b/Tequila.userprefs @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/TequilaPC/Classes/DirCopy.cs b/TequilaPC/Classes/DirCopy.cs new file mode 100644 index 0000000..df46ef1 --- /dev/null +++ b/TequilaPC/Classes/DirCopy.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; + +namespace Tequila +{ + class DirCopy + { + public static bool Kill = false; + private long m_FileCount = 0; + private long m_FilesDone = 0; + private bool m_Active = false; + private string m_SourceDirName; + private string m_DestDirName; + private bool m_copySubDirs = true; + + public bool Active + { + get { return m_Active; } + } + public int Progress + { + get { + return MyToolkit.MinMax((int)((float)m_FilesDone / (float)m_FileCount * 100f), 0, 100); + } + } + + public DirCopy(string SourceDirName, string DestDirName) { + m_SourceDirName = SourceDirName; + m_DestDirName = DestDirName; + } + + public string sourceDirName { + get { return m_SourceDirName; } + } + + public string destDirName { + get { return m_DestDirName; } + } + + public bool copySubDirs { + get { return m_copySubDirs; } + } + + public void DirectoryCopy() + { + m_Active = true; + m_FileCount = DirectoryCount(sourceDirName); + DirectoryCopyStep(sourceDirName, destDirName, copySubDirs); + m_Active = false; + } + + public void DirectoryCopyNoReplace() + { + m_Active = true; + m_FileCount = DirectoryCount(sourceDirName); + DirectoryCopyStep(sourceDirName, destDirName, copySubDirs, false); + m_Active = false; + } + + private void DirectoryCopyStep(string sourceDirName, string destDirName, bool copySubDirs = true, bool replace = true) + { + try{ + DirectoryInfo dir = new DirectoryInfo(sourceDirName); + DirectoryInfo[] dirs = dir.GetDirectories(); + + if (!dir.Exists) + { + throw new DirectoryNotFoundException( + "Source directory does not exist or could not be found: " + + sourceDirName); + } + + if (!Directory.Exists(destDirName)) + { + Directory.CreateDirectory(destDirName); + } + + FileInfo[] files = dir.GetFiles(); + foreach (FileInfo file in files) + { + if (Kill) return; + string temppath = Path.Combine(destDirName, file.Name); + + if (File.Exists(temppath) && replace) { + File.SetAttributes(temppath, File.GetAttributes(temppath) & ~FileAttributes.ReadOnly); + File.Delete(temppath); + } + + try { file.CopyTo(temppath, true); } + catch (Exception ex) { } + + m_FilesDone += file.Length; + } + + if (copySubDirs) { + foreach (DirectoryInfo subdir in dirs) { + string temppath = Path.Combine(destDirName, subdir.Name); + DirectoryCopyStep(subdir.FullName, temppath, copySubDirs); + } + } + + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, "DirCopy.DirectoryCopyStep"); + } + } + + private long DirectoryCount(string sourceDirName) + { + long count = 0; + try { + + DirectoryInfo dir = new DirectoryInfo(sourceDirName); + DirectoryInfo[] dirs = dir.GetDirectories(); + + FileInfo[] files = dir.GetFiles(); + foreach (FileInfo file in files) { + if (Kill) return 0; + try { count += file.Length; } + catch (Exception ex) { } + } + + foreach (DirectoryInfo subdir in dirs) { + count += DirectoryCount(subdir.FullName); + } + + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, "DirCopy.DirectoryCopyStep"); + } + return count; + } + + } +} diff --git a/TequilaPC/Classes/DownloadItem.cs b/TequilaPC/Classes/DownloadItem.cs new file mode 100644 index 0000000..9233ec4 --- /dev/null +++ b/TequilaPC/Classes/DownloadItem.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections; + +namespace Tequila +{ + class DownloadItem + { + private ArrayList m_urls; + private string m_filePath; + + public DownloadItem(ArrayList URL, string filePath) + { + m_urls = URL; + m_filePath = MyToolkit.ValidPath(filePath); + } + + public ArrayList URLs + { + get { return m_urls; } + set { m_urls = URLs; } + } + public string FilePath { + get { return m_filePath; } + set { m_filePath = MyToolkit.ValidPath(FilePath); } + } + + } +} diff --git a/TequilaPC/Classes/Fingerprint.cs b/TequilaPC/Classes/Fingerprint.cs new file mode 100644 index 0000000..c982a79 --- /dev/null +++ b/TequilaPC/Classes/Fingerprint.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Security.Cryptography; + +/************************************************************************ +* This class exists for two purposes: either give it a path and it * +* will automatically load a file size and md5 checsum, or give * +* it all the size and checksum data in the constructor to package * +* pre-defined checksums, loaded possibly from a file. * +************************************************************************/ +public class Fingerprint +{ + private string m_FileName; + private string m_RootPath; + private long m_Size; + private string m_Checksum; + private bool m_mismatch = false; + private ArrayList m_DownloadURLs = new ArrayList(); + private bool m_warn = true; + private static Random rand = new Random(); + + /**********************************************************************/ + public string FileName { get { return m_FileName; } } + public string RootPath { get { return m_RootPath; } } + public string FullName { get { return MyToolkit.ValidPath(Path.Combine(m_RootPath, m_FileName)); } } + public long Size { get { return m_Size; } } + public string Checksum { get { return m_Checksum; } } + public bool Mismatch { get { return m_mismatch; } set { m_mismatch = value; } } + public bool Warn { get { return m_warn; } set { m_warn = Warn; } } + public string DownloadURL { + get { + if (m_DownloadURLs.Count >= 1) + { + int randomIndex = rand.Next(0, m_DownloadURLs.Count); + return m_DownloadURLs[randomIndex].ToString(); + } else { + return ""; + } + } + } + + /**********************************************************************/ + + public Fingerprint(string RootPath, string FileName) { + try { + m_RootPath = RootPath; + m_FileName = FileName.Replace(".EXE", ".exe"); + if (File.Exists(FullName)) m_Size = (new FileInfo(FullName)).Length; + else m_Size = 0; + m_Checksum = GenerateHash(); + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, "Fingerprint.Constructor1"); + } + } + + public Fingerprint(string RootPath, string FileName, string Checksum) + { + try{ + m_RootPath = RootPath; + m_FileName = FileName.Replace(".EXE", ".exe"); + + // Load size from the file info + m_Size = (new FileInfo(FileName)).Length; + + // Make sure the checksum is lowercase + m_Checksum = Checksum.ToLower(); + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, "Fingerprint.Constructor2"); + } + } + + public Fingerprint(string RootPath, string FileName, string Checksum, long Size) + { + try + { + m_RootPath = RootPath; + m_FileName = FileName.Replace(".EXE", ".exe"); + + // Make sure the checksum is lowercase + m_Checksum = Checksum.ToLower(); + + // ... yea... overcommenting! + m_Size = Size; + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, "Fingerprint.Constructor2"); + } + } + + /**********************************************************************/ + + public void AddDownloadURL(string URL) { + m_DownloadURLs.Add(URL.Trim()); + } + + /// + /// Compare to another Fingerprint object + /// + /// The object to compare to + /// True if they are equal, false otherwise. + + public bool Equals(Fingerprint other) + { + if (this.Size != other.Size) return false; + if (this.Checksum != other.Checksum) return false; + return true; + } + + /// + /// Generates md5 checksum. + /// + /// MD5 checksum + public string GenerateHash(string path) + { + try + { + MD5 md5Hash = MD5.Create(); + + var buffer = md5Hash.ComputeHash(File.ReadAllBytes(path)); + + var cs = new StringBuilder(); + + for (int i = 0; i < buffer.Length; i++) + { + cs.Append(buffer[i].ToString("x2")); + } + + // Return an uppercase version of the consolidated string. + return cs.ToString().ToLower(); + } + catch (Exception ex) + { + MyToolkit.ErrorReporter(ex, "Fingerprint.GenerateHash"); + return ""; + } + } + + /// + /// Short form overload that will use the member variable instead of taking it as a parameter. + /// + /// An md5 checksum, split in 4 chunks, each chunk inverted. + public string GenerateHash() + { + return GenerateHash(FullName); + } + +} \ No newline at end of file diff --git a/TequilaPC/Classes/FingerprintCoH.cs b/TequilaPC/Classes/FingerprintCoH.cs new file mode 100644 index 0000000..990b19d --- /dev/null +++ b/TequilaPC/Classes/FingerprintCoH.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Security.Cryptography; + +/************************************************************************ +* This class exists for two purposes: either give it a path and it * +* will automatically load a file size and md5 checsum, or give * +* it all the size and checksum data in the constructor to package * +* pre-defined checksums, loaded possibly from a file. * +************************************************************************/ +public class FingerprintCoH +{ + private string m_FileName; + private long m_Size; + private string m_Checksum; + private bool m_mismatch = false; + + /**********************************************************************/ + public string FileName { get { return m_FileName; } } + public long Size { get { return m_Size; } } + public string Checksum { get { return m_Checksum; } } + public bool Mismatch { get { return m_mismatch; } set { m_mismatch = value; } } + + /**********************************************************************/ + + public FingerprintCoH(string FileName) { + + if(FileName.Contains(":\\")) { + // Make sure the file name has propper direction slashes for Windows + m_FileName = FileName.Replace("/", "\\"); + } else { + // Make sure the file name has propper direction slashes for OSX + m_FileName = FileName.Replace("\\", "/"); + } + + + // Load size from the file info + m_Size = (new FileInfo(FileName)).Length; + + // Nuff said + m_Checksum = GenerateHash(); + } + + + public FingerprintCoH(string FileName, string Checksum) + { + if(FileName.Contains(":\\")) { + // Make sure the file name has propper direction slashes for Windows + m_FileName = FileName.Replace("/", "\\"); + } else { + // Make sure the file name has propper direction slashes for OSX + m_FileName = FileName.Replace("\\", "/"); + } + + // Load size from the file info + m_Size = (new FileInfo(FileName)).Length; + + // Make sure the checksum is uppercase + m_Checksum = Checksum.ToUpper(); + } + + public FingerprintCoH(string FileName, int Size, string Checksum) + { + if(FileName.Contains(":\\")) { + // Make sure the file name has propper direction slashes for Windows + m_FileName = FileName.Replace("/", "\\"); + } else { + // Make sure the file name has propper direction slashes for OSX + m_FileName = FileName.Replace("\\", "/"); + } + + // Make sure the checksum is uppercase + m_Checksum = Checksum.ToUpper(); + + // ... yea... overcommenting! + m_Size = Size; + } + + /**********************************************************************/ + + /// + /// Compare to another Fingerprint object + /// + /// The object to compare to + /// True if they are equal, false otherwise. + + public bool Equals(Fingerprint other) + { + if (this.FileName != other.FileName) return false; + if (this.Size != other.Size) return false; + if (this.Checksum != other.Checksum) return false; + return true; + } + + /// + /// Generates idiotic md5 checksum. + /// + /// An md5 checksum, split in 4 chunks, each chunk inverted. + public string GenerateHash(string path) + { + MD5 md5Hash = MD5.Create(); + + var buffer = md5Hash.ComputeHash(File.ReadAllBytes(path)); + + // We define 4 variables, one for each of the 4 chunks + var cs1 = new StringBuilder(); + var cs2 = new StringBuilder(); + var cs3 = new StringBuilder(); + var cs4 = new StringBuilder(); + + // We we do our looping backwards, and we will only do 4 loops. + for (int i = 4; i > 0; i--) + { + // Use the index multiplied by an offset to get + // the byte from the buffer and append it to it's + // respective group + cs1.Append(buffer[i + 4 * 0 - 1].ToString("x2")); + cs2.Append(buffer[i + 4 * 1 - 1].ToString("x2")); + cs3.Append(buffer[i + 4 * 2 - 1].ToString("x2")); + cs4.Append(buffer[i + 4 * 3 - 1].ToString("x2")); + } + + // Append spaces to the first 3 groups + cs1.Append(" "); cs2.Append(" "); cs3.Append(" "); + + // Consolidate all the blocks into one single checksum + var cs = new StringBuilder(); + cs.Append(cs1); cs.Append(cs2); cs.Append(cs3); cs.Append(cs4); + + // Return an uppercase version of the consolidated string. + return cs.ToString().ToUpper(); + } + + /// + /// Short form overload that will use the member variable instead of taking it as a parameter. + /// + /// An md5 checksum, split in 4 chunks, each chunk inverted. + public string GenerateHash() + { + return GenerateHash(FileName); + } + +} \ No newline at end of file diff --git a/TequilaPC/Classes/HTTP.cs b/TequilaPC/Classes/HTTP.cs new file mode 100644 index 0000000..d0bad57 --- /dev/null +++ b/TequilaPC/Classes/HTTP.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Net; + +namespace Tequila +{ + class HTTP + { + WebClient m_client; + + public HTTP() { + m_client = new WebClient(); + } + + public bool StartDownload(AsyncCompletedEventHandler dlFinishedCallback, + DownloadProgressChangedEventHandler dlProgressCallback, + string URL, + string SavePath){ + + Uri uri; + try + { + uri = new Uri(URL); + } + catch (Exception ex) { + return false; + } + m_client.DownloadFileCompleted += dlFinishedCallback; + m_client.DownloadProgressChanged += dlProgressCallback; + + int chrindex = SavePath.LastIndexOf(@"/"); + if (chrindex == -1) chrindex = SavePath.LastIndexOf(@"\"); + + string Path = SavePath.Substring(0, chrindex); + System.IO.Directory.CreateDirectory(Path); + + m_client.DownloadFileAsync(uri,MyToolkit.ValidPath(SavePath)); + + return true; + } + + public void CancelDownload() { + m_client.CancelAsync(); + } + + public bool Active { + get { return m_client.IsBusy; } + } + + public long Length { + get + { + try + { + return Convert.ToInt64(m_client.ResponseHeaders["Content-Length"]); + } + catch (Exception ex) + { + return 0; + } + } + } + } +} diff --git a/TequilaPC/Classes/ListBoxItem.cs b/TequilaPC/Classes/ListBoxItem.cs new file mode 100644 index 0000000..3e9030f --- /dev/null +++ b/TequilaPC/Classes/ListBoxItem.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Tequila +{ + class LaunchProfile + { + private string m_text = ""; + private string m_Exec = ""; + private string m_Params = ""; + + public string Text { get { return m_text; } } + public string Exec { get { return m_Exec; } } + public string Params { get { return m_Params; } } + + public LaunchProfile(string Text, string Exec, string Params) { + m_text = Text; + m_Exec = Exec; + m_Params = Params; + } + } +} diff --git a/TequilaPC/Classes/MyToolkit.cs b/TequilaPC/Classes/MyToolkit.cs new file mode 100644 index 0000000..ac83a21 --- /dev/null +++ b/TequilaPC/Classes/MyToolkit.cs @@ -0,0 +1,73 @@ +using System; +using System.IO; + +class MyToolkit +{ + + public static string[] args; + + public static string AllArgs() { + string strArgs = ""; + + foreach (string arg in args) { + strArgs += arg + " "; + } + + return strArgs.Trim(); + } + + /// + /// Static function to make sure dashes are appropiate for the specific OS. + /// Make sure all paths are absolute, windows paths must contain the drive name at the start for this to work. + /// + /// File path to validate + /// + public static string ValidPath(string Path) { + if (Path.Contains(":\\")) + { + // Make sure the file name has propper direction slashes for Windows + Path = Path.Replace("/", "\\"); + } else { + // Make sure the file name has propper direction slashes for OSX + Path = Path.Replace("\\", "/"); + } + + return Path; + } + + public static int MinMax(int Val, int Min, int Max) { + if (Val > Max) return Max; + else if (Val < Min) return Min; + else return Val; + } + + /// + /// Determines if the directorty where path will allow us to read and write. + /// + /// Install directory path + /// False if we cant write to the path. + public static bool InstallDirSafe(string path) { + try { + File.Move(Path.Combine(path, "icon.exe"), Path.Combine(path, "icon_rename.exe")); + if (File.Exists(Path.Combine(path, "icon_rename.exe"))) + { + File.Move(Path.Combine(path, "icon_rename.exe"), Path.Combine(path, "icon.exe")); + return true; + } else { + return false; + } + } catch (Exception ex) { + return false; + } + } + + public static bool CreateShortcut(string LinkPathName, string TargetPathName) + { + return true; + } + + public static void ErrorReporter(Exception ex, string source) { + System.Windows.Forms.MessageBox.Show(ex.Message, source); + } + +} \ No newline at end of file diff --git a/TequilaPC/Classes/Settings.cs b/TequilaPC/Classes/Settings.cs new file mode 100644 index 0000000..d24944b --- /dev/null +++ b/TequilaPC/Classes/Settings.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Win32; +using System.IO; +using System.Drawing; + +namespace Tequila +{ + class Settings + { + + public static bool SetupNeeded { + get { + return GamePath == "" || !File.Exists(Path.Combine(GamePath, "icon.exe")); + } + } + + public static string GamePath + { + get + { + FixRegistryPolution(); + return TequilaRegistry.GetValue("CoHPath", "").ToString(); + } + set + { + TequilaRegistry.SetValue("CoHPath", value); + } + } + + public static bool QuitOnLaunch + { + get + { + + return TequilaRegistry.GetValue("QuitOnLaunch", "FALSE").ToString().ToUpper() == "TRUE"; + } + set + { + if(value) + TequilaRegistry.SetValue("QuitOnLaunch", "TRUE"); + else + TequilaRegistry.SetValue("QuitOnLaunch", "FALSE"); + } + } + + public static string GameParams + { + get + { + return TequilaRegistry.GetValue("Parameters", "").ToString(); + } + set + { + TequilaRegistry.SetValue("Parameters", value); + } + } + + public static Color BGColor + { + get + { + int color; + bool success = int.TryParse(TequilaRegistry.GetValue("BGColor", -13017488).ToString(), out color); + if (success) return Color.FromArgb(color); + else return Color.Black; + } + set + { + TequilaRegistry.SetValue("BGColor", value.ToArgb()); + } + } + + public static Color TextColor + { + get + { + int color; + bool success = int.TryParse(TequilaRegistry.GetValue("TextColor", -1).ToString(), out color); + if (success) return Color.FromArgb(color); + else return Color.Black; + } + set + { + TequilaRegistry.SetValue("TextColor", value.ToArgb()); + } + } + + + + + public static void Reset() { + TequilaRegistry.DeleteValue("CoHPath"); + } + + private static RegistryKey TequilaRegistry { + get + { + RegistryKey r = Registry.CurrentUser.OpenSubKey(@"Software\Tequila\Settings", true); + + if (r == null) + { + r = Registry.CurrentUser.CreateSubKey(@"Software\Tequila\Settings"); + } + + return r; + } + } + + private static void FixRegistryPolution() + { + try + { + string s = Registry.CurrentUser.GetValue("CoHPath", "").ToString(); + if (s != "") + { + GamePath = s; + Registry.CurrentUser.DeleteValue("CoHPath"); + } + } + catch (Exception ex) { } + } + + + } +} diff --git a/TequilaPC/Classes/ShellLink.cs b/TequilaPC/Classes/ShellLink.cs new file mode 100644 index 0000000..f625046 --- /dev/null +++ b/TequilaPC/Classes/ShellLink.cs @@ -0,0 +1,876 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace Tequila +{ + #region ShellLink Object + /// + /// Summary description for ShellLink. + /// + public class ShellLink : IDisposable + { + #region ComInterop for IShellLink + + #region IPersist Interface + [ComImportAttribute()] + [GuidAttribute("0000010C-0000-0000-C000-000000000046")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + private interface IPersist + { + [PreserveSig] + //[helpstring("Returns the class identifier for the component object")] + void GetClassID(out Guid pClassID); + } + #endregion + + #region IPersistFile Interface + [ComImportAttribute()] + [GuidAttribute("0000010B-0000-0000-C000-000000000046")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + private interface IPersistFile + { + // can't get this to go if I extend IPersist, so put it here: + [PreserveSig] + void GetClassID(out Guid pClassID); + + //[helpstring("Checks for changes since last file write")] + void IsDirty(); + + //[helpstring("Opens the specified file and initializes the object from its contents")] + void Load( + [MarshalAs(UnmanagedType.LPWStr)] string pszFileName, + uint dwMode); + + //[helpstring("Saves the object into the specified file")] + void Save( + [MarshalAs(UnmanagedType.LPWStr)] string pszFileName, + [MarshalAs(UnmanagedType.Bool)] bool fRemember); + + //[helpstring("Notifies the object that save is completed")] + void SaveCompleted( + [MarshalAs(UnmanagedType.LPWStr)] string pszFileName); + + //[helpstring("Gets the current name of the file associated with the object")] + void GetCurFile( + [MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName); + } + #endregion + + #region IShellLink Interface + [ComImportAttribute()] + [GuidAttribute("000214EE-0000-0000-C000-000000000046")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + private interface IShellLinkA + { + //[helpstring("Retrieves the path and filename of a shell link object")] + void GetPath( + [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile, + int cchMaxPath, + ref _WIN32_FIND_DATAA pfd, + uint fFlags); + + //[helpstring("Retrieves the list of shell link item identifiers")] + void GetIDList(out IntPtr ppidl); + + //[helpstring("Sets the list of shell link item identifiers")] + void SetIDList(IntPtr pidl); + + //[helpstring("Retrieves the shell link description string")] + void GetDescription( + [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile, + int cchMaxName); + + //[helpstring("Sets the shell link description string")] + void SetDescription( + [MarshalAs(UnmanagedType.LPStr)] string pszName); + + //[helpstring("Retrieves the name of the shell link working directory")] + void GetWorkingDirectory( + [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszDir, + int cchMaxPath); + + //[helpstring("Sets the name of the shell link working directory")] + void SetWorkingDirectory( + [MarshalAs(UnmanagedType.LPStr)] string pszDir); + + //[helpstring("Retrieves the shell link command-line arguments")] + void GetArguments( + [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszArgs, + int cchMaxPath); + + //[helpstring("Sets the shell link command-line arguments")] + void SetArguments( + [MarshalAs(UnmanagedType.LPStr)] string pszArgs); + + //[propget, helpstring("Retrieves or sets the shell link hot key")] + void GetHotkey(out short pwHotkey); + //[propput, helpstring("Retrieves or sets the shell link hot key")] + void SetHotkey(short pwHotkey); + + //[propget, helpstring("Retrieves or sets the shell link show command")] + void GetShowCmd(out uint piShowCmd); + //[propput, helpstring("Retrieves or sets the shell link show command")] + void SetShowCmd(uint piShowCmd); + + //[helpstring("Retrieves the location (path and index) of the shell link icon")] + void GetIconLocation( + [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszIconPath, + int cchIconPath, + out int piIcon); + + //[helpstring("Sets the location (path and index) of the shell link icon")] + void SetIconLocation( + [MarshalAs(UnmanagedType.LPStr)] string pszIconPath, + int iIcon); + + //[helpstring("Sets the shell link relative path")] + void SetRelativePath( + [MarshalAs(UnmanagedType.LPStr)] string pszPathRel, + uint dwReserved); + + //[helpstring("Resolves a shell link. The system searches for the shell link object and updates the shell link path and its list of identifiers (if necessary)")] + void Resolve( + IntPtr hWnd, + uint fFlags); + + //[helpstring("Sets the shell link path and filename")] + void SetPath( + [MarshalAs(UnmanagedType.LPStr)] string pszFile); + } + + + [ComImportAttribute()] + [GuidAttribute("000214F9-0000-0000-C000-000000000046")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + private interface IShellLinkW + { + //[helpstring("Retrieves the path and filename of a shell link object")] + void GetPath( + [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, + int cchMaxPath, + ref _WIN32_FIND_DATAW pfd, + uint fFlags); + + //[helpstring("Retrieves the list of shell link item identifiers")] + void GetIDList(out IntPtr ppidl); + + //[helpstring("Sets the list of shell link item identifiers")] + void SetIDList(IntPtr pidl); + + //[helpstring("Retrieves the shell link description string")] + void GetDescription( + [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, + int cchMaxName); + + //[helpstring("Sets the shell link description string")] + void SetDescription( + [MarshalAs(UnmanagedType.LPWStr)] string pszName); + + //[helpstring("Retrieves the name of the shell link working directory")] + void GetWorkingDirectory( + [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, + int cchMaxPath); + + //[helpstring("Sets the name of the shell link working directory")] + void SetWorkingDirectory( + [MarshalAs(UnmanagedType.LPWStr)] string pszDir); + + //[helpstring("Retrieves the shell link command-line arguments")] + void GetArguments( + [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, + int cchMaxPath); + + //[helpstring("Sets the shell link command-line arguments")] + void SetArguments( + [MarshalAs(UnmanagedType.LPWStr)] string pszArgs); + + //[propget, helpstring("Retrieves or sets the shell link hot key")] + void GetHotkey(out short pwHotkey); + //[propput, helpstring("Retrieves or sets the shell link hot key")] + void SetHotkey(short pwHotkey); + + //[propget, helpstring("Retrieves or sets the shell link show command")] + void GetShowCmd(out uint piShowCmd); + //[propput, helpstring("Retrieves or sets the shell link show command")] + void SetShowCmd(uint piShowCmd); + + //[helpstring("Retrieves the location (path and index) of the shell link icon")] + void GetIconLocation( + [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, + int cchIconPath, + out int piIcon); + + //[helpstring("Sets the location (path and index) of the shell link icon")] + void SetIconLocation( + [MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, + int iIcon); + + //[helpstring("Sets the shell link relative path")] + void SetRelativePath( + [MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, + uint dwReserved); + + //[helpstring("Resolves a shell link. The system searches for the + // shell link object and updates the shell link path and its list of + // identifiers (if necessary)")] + void Resolve( + IntPtr hWnd, + uint fFlags); + + //[helpstring("Sets the shell link path and filename")] + void SetPath( + [MarshalAs(UnmanagedType.LPWStr)] string pszFile); + } + #endregion + + #region ShellLinkCoClass + [GuidAttribute("00021401-0000-0000-C000-000000000046")] + [ClassInterfaceAttribute(ClassInterfaceType.None)] + [ComImportAttribute()] + private class CShellLink{} + + #endregion + + #region Private IShellLink enumerations + private enum EShellLinkGP : uint + { + SLGP_SHORTPATH = 1, + SLGP_UNCPRIORITY = 2 + } + + [Flags] + private enum EShowWindowFlags : uint + { + SW_HIDE = 0, + SW_SHOWNORMAL = 1, + SW_NORMAL = 1, + SW_SHOWMINIMIZED = 2, + SW_SHOWMAXIMIZED = 3, + SW_MAXIMIZE = 3, + SW_SHOWNOACTIVATE = 4, + SW_SHOW = 5, + SW_MINIMIZE = 6, + SW_SHOWMINNOACTIVE = 7, + SW_SHOWNA = 8, + SW_RESTORE = 9, + SW_SHOWDEFAULT = 10, + SW_MAX = 10 + } + #endregion + + #region IShellLink Private structs + + [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, + CharSet=CharSet.Unicode)] + private struct _WIN32_FIND_DATAW + { + public uint dwFileAttributes; + public _FILETIME ftCreationTime; + public _FILETIME ftLastAccessTime; + public _FILETIME ftLastWriteTime; + public uint nFileSizeHigh; + public uint nFileSizeLow; + public uint dwReserved0; + public uint dwReserved1; + [MarshalAs(UnmanagedType.ByValTStr , SizeConst = 260)] // MAX_PATH + public string cFileName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] + public string cAlternateFileName; + } + + [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, + CharSet=CharSet.Ansi)] + private struct _WIN32_FIND_DATAA + { + public uint dwFileAttributes; + public _FILETIME ftCreationTime; + public _FILETIME ftLastAccessTime; + public _FILETIME ftLastWriteTime; + public uint nFileSizeHigh; + public uint nFileSizeLow; + public uint dwReserved0; + public uint dwReserved1; + [MarshalAs(UnmanagedType.ByValTStr , SizeConst = 260)] // MAX_PATH + public string cFileName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] + public string cAlternateFileName; + } + + [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0)] + private struct _FILETIME + { + public uint dwLowDateTime; + public uint dwHighDateTime; + } + #endregion + + #region UnManaged Methods + private class UnManagedMethods + { + [DllImport("Shell32", CharSet=CharSet.Auto)] + internal extern static int ExtractIconEx ( + [MarshalAs(UnmanagedType.LPTStr)] + string lpszFile, + int nIconIndex, + IntPtr[] phIconLarge, + IntPtr[] phIconSmall, + int nIcons); + + [DllImport("user32")] + internal static extern int DestroyIcon(IntPtr hIcon); + } + #endregion + + #endregion + + #region Enumerations + /// + /// Flags determining how the links with missing + /// targets are resolved. + /// + [Flags] + public enum EShellLinkResolveFlags : uint + { + /// + /// Allow any match during resolution. Has no effect + /// on ME/2000 or above, use the other flags instead. + /// + SLR_ANY_MATCH = 0x2, + /// + /// Call the Microsoft Windows Installer. + /// + SLR_INVOKE_MSI = 0x80, + /// + /// Disable distributed link tracking. By default, + /// distributed link tracking tracks removable media + /// across multiple devices based on the volume name. + /// It also uses the UNC path to track remote file + /// systems whose drive letter has changed. Setting + /// SLR_NOLINKINFO disables both types of tracking. + /// + SLR_NOLINKINFO = 0x40, + /// + /// Do not display a dialog box if the link cannot be resolved. + /// When SLR_NO_UI is set, a time-out value that specifies the + /// maximum amount of time to be spent resolving the link can + /// be specified in milliseconds. The function returns if the + /// link cannot be resolved within the time-out duration. + /// If the timeout is not set, the time-out duration will be + /// set to the default value of 3,000 milliseconds (3 seconds). + /// + SLR_NO_UI = 0x1, + /// + /// Not documented in SDK. Assume same as SLR_NO_UI but + /// intended for applications without a hWnd. + /// + SLR_NO_UI_WITH_MSG_PUMP = 0x101, + /// + /// Do not update the link information. + /// + SLR_NOUPDATE = 0x8, + /// + /// Do not execute the search heuristics. + /// + + + + + + + + + + SLR_NOSEARCH = 0x10, + /// + /// Do not use distributed link tracking. + /// + SLR_NOTRACK = 0x20, + /// + /// If the link object has changed, update its path and list + /// of identifiers. If SLR_UPDATE is set, you do not need to + /// call IPersistFile::IsDirty to determine whether or not + /// the link object has changed. + /// + SLR_UPDATE = 0x4 + } + + public enum LinkDisplayMode : uint + { + edmNormal = EShowWindowFlags.SW_NORMAL, + edmMinimized = EShowWindowFlags.SW_SHOWMINNOACTIVE, + edmMaximized = EShowWindowFlags.SW_MAXIMIZE + } + #endregion + + #region Member Variables + // Use Unicode (W) under NT, otherwise use ANSI + private IShellLinkW linkW; + private IShellLinkA linkA; + private string shortcutFile = ""; + #endregion + + #region Constructor + /// + /// Creates an instance of the Shell Link object. + /// + public ShellLink() + { + if (System.Environment.OSVersion.Platform == PlatformID.Win32NT) + { + linkW = (IShellLinkW)new CShellLink(); + } + else + { + linkA = (IShellLinkA)new CShellLink(); + } + } + + /// + /// Creates an instance of a Shell Link object + /// from the specified link file + /// + /// The Shortcut file to open + public ShellLink(string linkFile) : this() + { + Open(linkFile); + } + #endregion + + #region Destructor and Dispose + /// + /// Call dispose just in case it hasn't happened yet + /// + ~ShellLink() + { + Dispose(); + } + + /// + /// Dispose the object, releasing the COM ShellLink object + /// + public void Dispose() + { + if (linkW != null ) + { + Marshal.ReleaseComObject(linkW); + linkW = null; + } + if (linkA != null) + { + Marshal.ReleaseComObject(linkA); + linkA = null; + } + } + #endregion + + #region Implementation + public string ShortCutFile + { + get + { + return this.shortcutFile; + } + set + { + this.shortcutFile = value; + } + } + + /// + /// Gets the path to the file containing the icon for this shortcut. + /// + public string IconPath + { + get + { + StringBuilder iconPath = new StringBuilder(260, 260); + int iconIndex = 0; + if (linkA == null) + { + linkW.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + else + { + linkA.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + return iconPath.ToString(); + } + set + { + StringBuilder iconPath = new StringBuilder(260, 260); + int iconIndex = 0; + if (linkA == null) + { + linkW.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + else + { + linkA.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + if (linkA == null) + { + linkW.SetIconLocation(value, iconIndex); + } + else + { + linkA.SetIconLocation(value, iconIndex); + } + } + } + + /// + /// Gets the index of this icon within the icon path's resources + /// + public int IconIndex + { + get + { + StringBuilder iconPath = new StringBuilder(260, 260); + int iconIndex = 0; + if (linkA == null) + { + linkW.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + else + { + linkA.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + return iconIndex; + } + set + { + StringBuilder iconPath = new StringBuilder(260, 260); + int iconIndex = 0; + if (linkA == null) + { + linkW.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + else + { + linkA.GetIconLocation(iconPath, iconPath.Capacity, out + iconIndex); + } + if (linkA == null) + { + linkW.SetIconLocation(iconPath.ToString(), value); + } + else + { + linkA.SetIconLocation(iconPath.ToString(), value); + } + } + } + + /// + /// Gets/sets the fully qualified path to the link's target + /// + public string Target + { + get + { + StringBuilder target = new StringBuilder(260, 260); + if (linkA == null) + { + _WIN32_FIND_DATAW fd = new _WIN32_FIND_DATAW(); + linkW.GetPath(target, target.Capacity, ref fd, + (uint)EShellLinkGP.SLGP_UNCPRIORITY); + } + else + { + _WIN32_FIND_DATAA fd = new _WIN32_FIND_DATAA(); + linkA.GetPath(target, target.Capacity, ref fd, + (uint)EShellLinkGP.SLGP_UNCPRIORITY); + } + return target.ToString(); + } + set + { + if (linkA == null) + { + linkW.SetPath(value); + } + else + { + linkA.SetPath(value); + } + } + } + + /// + /// Gets/sets the Working Directory for the Link + /// + public string WorkingDirectory + { + get + { + StringBuilder path = new StringBuilder(260, 260); + if (linkA == null) + { + linkW.GetWorkingDirectory(path, path.Capacity); + } + else + { + linkA.GetWorkingDirectory(path, path.Capacity); + } + return path.ToString(); + } + set + { + if (linkA == null) + { + linkW.SetWorkingDirectory(value); + } + else + { + linkA.SetWorkingDirectory(value); + } + } + } + + /// + /// Gets/sets the description of the link + /// + public string Description + { + get + { + StringBuilder description = new StringBuilder(1024, 1024); + if (linkA == null) + { + linkW.GetDescription(description, description.Capacity); + } + else + { + linkA.GetDescription(description, description.Capacity); + } + return description.ToString(); + } + set + { + if (linkA == null) + { + linkW.SetDescription(value); + } + else + { + linkA.SetDescription(value); + } + } + } + + /// + /// Gets/sets any command line arguments associated with the link + /// + public string Arguments + { + get + { + StringBuilder arguments = new StringBuilder(260, 260); + if (linkA == null) + { + linkW.GetArguments(arguments, arguments.Capacity); + } + else + { + linkA.GetArguments(arguments, arguments.Capacity); + } + return arguments.ToString(); + } + set + { + if (linkA == null) + { + linkW.SetArguments(value); + } + else + { + linkA.SetArguments(value); + } + } + } + + /// + /// Gets/sets the initial display mode when the shortcut is + /// run + /// + public LinkDisplayMode DisplayMode + { + get + { + uint cmd = 0; + if (linkA == null) + { + linkW.GetShowCmd(out cmd); + } + else + { + linkA.GetShowCmd(out cmd); + } + return (LinkDisplayMode)cmd; + } + set + { + if (linkA == null) + { + linkW.SetShowCmd((uint)value); + } + else + { + linkA.SetShowCmd((uint)value); + } + } + } + + /// + /// Gets/sets the HotKey to start the shortcut (if any) + /// + public Keys HotKey + { + get + { + short key = 0; + if (linkA == null) + { + linkW.GetHotkey(out key); + } + else + { + linkA.GetHotkey(out key); + } + return (Keys)key; + } + set + { + if (linkA == null) + { + linkW.SetHotkey((short)value); + } + else + { + linkA.SetHotkey((short)value); + } + } + } + + /// + /// Saves the shortcut to ShortCutFile. + /// + public void Save() + { + Save(shortcutFile); + } + + /// + /// Saves the shortcut to the specified file + /// + /// The shortcut file (.lnk) + public void Save( + string linkFile + ) + { + // Save the object to disk + if (linkA == null) + { + ((IPersistFile)linkW).Save(linkFile, true); + shortcutFile = linkFile; + } + else + { + ((IPersistFile)linkA).Save(linkFile, true); + shortcutFile = linkFile; + } + } + + /// + /// Loads a shortcut from the specified file + /// + /// The shortcut file (.lnk) to load + public void Open( + string linkFile + ) + { + Open(linkFile, + IntPtr.Zero, + (EShellLinkResolveFlags.SLR_ANY_MATCH | + EShellLinkResolveFlags.SLR_NO_UI), + 1); + } + + /// + /// Loads a shortcut from the specified file, and allows flags controlling + /// the UI behaviour if the shortcut's target isn't found to be set. + /// + /// The shortcut file (.lnk) to load + /// The window handle of the application's UI, if any + /// Flags controlling resolution behaviour + public void Open( + string linkFile, + IntPtr hWnd, + EShellLinkResolveFlags resolveFlags + ) + { + Open(linkFile, + hWnd, + resolveFlags, + 1); + } + + /// + /// Loads a shortcut from the specified file, and allows flags controlling + /// the UI behaviour if the shortcut's target isn't found to be set. If + /// no SLR_NO_UI is specified, you can also specify a timeout. + /// + /// The shortcut file (.lnk) to load + /// The window handle of the application's UI, if any + /// Flags controlling resolution behaviour + /// Timeout if SLR_NO_UI is specified, in ms. + public void Open( + string linkFile, + IntPtr hWnd, + EShellLinkResolveFlags resolveFlags, + ushort timeOut + ) + { + uint flags; + + if ((resolveFlags & EShellLinkResolveFlags.SLR_NO_UI) + == EShellLinkResolveFlags.SLR_NO_UI) + { + flags = (uint)((int)resolveFlags | (timeOut << 16)); + } + else + { + flags = (uint)resolveFlags; + } + + if (linkA == null) + { + ((IPersistFile)linkW).Load(linkFile, 0); //STGM_DIRECT) + linkW.Resolve(hWnd, flags); + this.shortcutFile = linkFile; + } + else + { + ((IPersistFile)linkA).Load(linkFile, 0); //STGM_DIRECT) + linkA.Resolve(hWnd, flags); + this.shortcutFile = linkFile; + } + } + #endregion + } + #endregion + +} + + diff --git a/TequilaPC/Classes/WorkThread.cs b/TequilaPC/Classes/WorkThread.cs new file mode 100644 index 0000000..d3b1d85 --- /dev/null +++ b/TequilaPC/Classes/WorkThread.cs @@ -0,0 +1,552 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections; +using System.Threading; +using System.Xml; +using System.Xml.Linq; +using System.ComponentModel; +using System.Net; +using System.IO; +using System.Windows.Forms; +using System.Diagnostics; + +namespace Tequila +{ + class WorkThread + { + #region member declarations + public static bool DontDownloadManifest = false; + public static bool DontSelfUpdate = false; + public static bool GenerageChecksumToClipboard = false; + + private ArrayList m_ErrorLog = new ArrayList(); + private ArrayList m_WarningLog = new ArrayList(); + private ArrayList m_ManifestFileList; + private ArrayList m_DownloadQueue = new ArrayList(); + private long m_DownloadSize = 0; + private long m_Downloaded = 0; + private long m_CurrDownloadBytes = 0; + + private HTTP client = new HTTP(); + + public string LocalManifest = ""; + public string PathRoot = ""; + public string ManifestURL; + + private XElement Log; + private XElement LogNew = new XElement("files"); + + private string m_Status = ""; + private int m_progress = 0; + private string m_current = ""; + XElement m_manifest; + #endregion + + public static bool Kill = false; + private Thread myWorkThread; + + public XElement Manifest { + get { return m_manifest; } + } + + public WorkThread(string ManifestoURL) + { + ManifestURL = ManifestoURL; + } + + public string ErrorMessage + { + get + { + string Message = ""; + + foreach (string s in m_ErrorLog) + { + Message += s; + } + + return Message; + } + } + public string WarningMessage + { + get + { + string Message = ""; + + foreach (string s in m_WarningLog) + { + Message += s; + } + + return Message; + } + } + + public string Status { + get { + return m_Status; + } set { + m_Status = Status; + } + } + + public int CurProgress { get { return m_progress; } } + public string CurFile { get { return m_current; } } + + public string LogPath { + get { + return Path.Combine(Settings.GamePath, "tequilalog.xml"); + } + } + + public void LoadLog() + { + if (System.IO.File.Exists(LogPath)) + { + Log = XElement.Load(LogPath); + } + } + + private void FlagVerified(string file, long size, string md5) + { + try + { + FileInfo fi = new FileInfo(Path.Combine(Settings.GamePath, file)); + + XElement e = new XElement("file"); + e.Add(new XAttribute("name", file)); + e.Add(new XAttribute("size", size)); + e.Add(new XAttribute("md5", md5)); + e.Add(new XAttribute("ModDate", fi.LastWriteTime.ToString(fi.LastWriteTime.ToString("yyyy.MM.dd.HH.mm.ss")))); + + LogNew.Add(e); + + // Sometimes we may run this through too fast and the file may be locked + // we will retry a save attempt for up to 3 seconds, if we are not able + // to save without errors by then we do one final save attempt and + // report error. + bool saveSuccessful = false; + Stopwatch sw = new Stopwatch(); + sw.Start(); + + while (sw.ElapsedMilliseconds < 3000 && !saveSuccessful) { + try + { + LogNew.Save(LogPath); + saveSuccessful = true; + } catch (Exception ex) { + saveSuccessful = false; + } + } + + // OK, if we did not save, here is our last attempt! + if (!saveSuccessful) LogNew.Save(LogPath); + + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, "WorkThread.FlagVerified"); + } + } + + private bool AlreadyVerified(string file, long size, string md5) + { + try + { + if(!File.Exists(Path.Combine(Settings.GamePath, file))) return false; + + XElement match = (from el in Log.Descendants("file") + where (string)el.Attribute("name") == file + select el).First(); + + FileInfo fi = new FileInfo(Path.Combine(Settings.GamePath, file)); + + string lastModDate; + if (match.Attribute("ModDate") == null) + lastModDate = fi.LastWriteTime.ToString("yyyy.MM.dd.HH.mm.ss"); + else + lastModDate = match.Attribute("ModDate").Value; + + if(fi.Length != size) { + return false; + } + else if (lastModDate != fi.LastWriteTime.ToString(fi.LastWriteTime.ToString("yyyy.MM.dd.HH.mm.ss"))) + { + return false; + } else if (long.Parse(match.Attribute("size").Value) == size + && match.Attribute("md5").Value.ToLower() == md5) { + return true; + } else { + return false; + } + } + catch (Exception ex) { + return false; + } + } + + public void Validate() + { + long i = 0; + m_Status = "Validating"; + + LoadLog(); + + foreach (Fingerprint ManifestFingerprint in m_ManifestFileList) + { + if (Kill) return; + + i++; + m_current = ManifestFingerprint.FullName; + + ProgressEventArgs e = new ProgressEventArgs(i, m_ManifestFileList.Count); + + Fingerprint LocalFingerprint; + if (System.IO.File.Exists(ManifestFingerprint.FullName)) + { + // File exists locally, lets start verifying it. First check if + // the checksum matches the one in our last run log, if so there + // is no need to download the file nor do a checksum + if (AlreadyVerified(ManifestFingerprint.FileName, + ManifestFingerprint.Size, + ManifestFingerprint.Checksum)) + { + FlagVerified(ManifestFingerprint.FileName, ManifestFingerprint.Size, ManifestFingerprint.Checksum); + } + else + { + // Get an md5 checksum for the local copy of the file + LocalFingerprint = new Fingerprint(ManifestFingerprint.RootPath, ManifestFingerprint.FileName); + + if (LocalFingerprint.Equals(ManifestFingerprint)) + { + FlagVerified(ManifestFingerprint.FileName, ManifestFingerprint.Size, ManifestFingerprint.Checksum); + } else { + // There was no match, lets add the file to our download queue + AddToDownloadQueue(ManifestFingerprint); + } + } + } else { + // File does not exist locally, we must download it. Add to our download queue. + AddToDownloadQueue(ManifestFingerprint); + } + m_progress = (int)(Math.Round((i / 100.0f) * 100.0f)); + } + + DownloadFiles(); + } + + private void AddToDownloadQueue(Fingerprint file) { + if (file.DownloadURL != "") + { + m_DownloadQueue.Add(file); + m_DownloadSize += file.Size; + } else { + string Error; + Error = "The following file has an invalid checksum. You will need to obtain it from a valid game installation:\r\n" + file.FileName + "\r\n"; + m_ErrorLog.Add(Error); + } + } + + private bool m_DownloadActive = false; + public void DownloadFiles() { + + foreach (Fingerprint file in m_DownloadQueue) + { + if (Kill) return; + + HTTP client = new HTTP(); + + if (client.StartDownload(new AsyncCompletedEventHandler(DownloadFileComplete), + new DownloadProgressChangedEventHandler(dlProgress), + file.DownloadURL, + file.FullName + ".download")){ + m_Status = "Downloading"; + m_DownloadActive = true; + } + + m_current = file.FullName; + + while (m_DownloadActive) { + if (Kill) + { + client.CancelDownload(); + return; + } + System.Threading.Thread.Sleep(10); + } + + Fingerprint Downloaded = new Fingerprint(file.RootPath, file.FileName + ".download"); + + if (!Downloaded.Equals(file)) { + File.Delete(file.FullName + ".download"); + string Msg = "Download error: " + file.FileName; + + if (Downloaded.Size != file.Size) Msg += "\r\nSize mismatch (" + Downloaded.Size + " vs " + file.Size + ")"; + if (Downloaded.Checksum != file.Checksum) Msg += "\r\nChecksum Mismatch (" + Downloaded.Checksum + " vs " + file.Checksum + ")"; + + if (file.Warn) m_ErrorLog.Add(Msg); + else m_WarningLog.Add(Msg); + } else { + if (File.Exists(file.FullName)) + { + File.SetAttributes(file.FullName, File.GetAttributes(file.FullName) & ~FileAttributes.ReadOnly); + File.Delete(file.FullName); + } + + File.Move(file.FullName + ".download", file.FullName); + FlagVerified(file.FullName, file.Size, file.Checksum); + } + + m_Downloaded += file.Size; + } + + m_Status = "Done"; + m_current = ""; + } + + void DownloadFileComplete(object sender, AsyncCompletedEventArgs e) + { + m_current = ""; + m_DownloadActive = false; + } + + void dlProgress(object sender, DownloadProgressChangedEventArgs e) + { + m_CurrDownloadBytes = e.BytesReceived; + m_progress = (int)Math.Round(((float)(m_CurrDownloadBytes + m_Downloaded) / (float)m_DownloadSize) * 100.0f, 0); + } + + + public void DownloadManifest() { + if (DontDownloadManifest) { + + ManifestDownloadComplete(null, null); + } + + m_Status = "Fetching manifest..."; + LocalManifest = MyToolkit.ValidPath(Path.Combine(PathRoot, "rspatcher.xml")); + client.StartDownload(new AsyncCompletedEventHandler(ManifestDownloadComplete), + new DownloadProgressChangedEventHandler(dlProgress), + ManifestURL, + LocalManifest); + } + + void ManifestDownloadComplete(object sender, AsyncCompletedEventArgs e) + { + // Check if we had any HTTP download errors + if (e != null) if (e.Error != null) { + m_ErrorLog.Add("Manifest download error for " + ManifestURL + "\r\n" + e.Error.Message); + m_Status = "Done"; + return; + } + + // Check if the downloaded file is where it should be + if (!File.Exists(LocalManifest)) + { + m_ErrorLog.Add("Error downloading manifest"); + m_Status = "Done"; + return; + } + + // Make certain the downloaded manifest and the one we + // requested match in size + FileInfo dlInfo = new FileInfo(LocalManifest); + if (dlInfo.Length != client.Length) { + m_ErrorLog.Add("Error downloading manifest"); + m_Status = "Done"; + return; + } + + // We got a manifest, lets start reading through it + m_current = ""; + + m_ManifestFileList = new ArrayList(); + try + { + m_manifest = XElement.Load(LocalManifest); + + SelfPatch(); + + m_Status = "Reading Manifest"; + IEnumerable files = m_manifest.Descendants("file"); + + foreach (XElement file in files) + { + if (Kill) return; + + // Lets get this file's manifest information + long size; + bool parseSucceed = long.TryParse(file.Attribute("size").Value.ToString(), out size); + bool Warn = true; + if (file.Attribute("warn") != null) + if (file.Attribute("warn").Value == "no") + Warn = false; + string md5 = file.Attribute("md5").Value; + string fileName = file.Attribute("name").Value; + + if (fileName.Trim() != "") + { + Fingerprint ManifestFingerprint = new Fingerprint(PathRoot, fileName, md5, size); + ManifestFingerprint.Warn = Warn; + + IEnumerable URLs = file.Descendants("url"); + + foreach (XElement URL in URLs) + { + ManifestFingerprint.AddDownloadURL(URL.Value.ToString().Trim()); + } + + m_ManifestFileList.Add(ManifestFingerprint); + } + } + + m_progress = 0; + m_Status = "Verifying"; + myWorkThread = new Thread(new ThreadStart(Validate)); + myWorkThread.Start(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "WorkThread.ManifestDownloadComplete()"); + string a = ex.Message; + } + + } + + public void Cancel() { + if (myWorkThread != null) if (myWorkThread.IsAlive) { + try { myWorkThread.Abort(); } + catch (Exception ex) { } + } + } + + void SelfPatch() { + try + { + Fingerprint myFingerprint = new Fingerprint(Settings.GamePath, "Tequila.exe"); + + if (GenerageChecksumToClipboard) + { + Clipboard.SetText("md5=\"" + myFingerprint.Checksum + "\" size=" + myFingerprint.Size); + } + if (DontSelfUpdate) return; + + // Before we go far... lets see if there are any old temp files hanging around and get rid of them + + string[] oldFiles = Directory.GetFiles(Settings.GamePath, "*.old"); + foreach (string oldFile in oldFiles) { + try { File.Delete(oldFile); } + catch (Exception ex) { } + } + + // OK now thats out of the way, lets determine if we need to self patch or not!! + IEnumerable launchers = m_manifest.Descendants("launcher"); + m_Status = "Self Patching"; + foreach (XElement launcher in launchers) + { + if (launcher.Attribute("id").Value == "tequila") + { + + long size = 0; + long.TryParse(launcher.Attribute("size").Value.ToString(), out size); + string md5 = launcher.Attribute("md5").Value; + + Fingerprint remoteLauncher = new Fingerprint(Settings.GamePath, "Tequila.exe", md5, size); + + if (!myFingerprint.Equals(remoteLauncher)) + { + // We need to update!!! yay... + IEnumerable urls = launcher.Descendants("url"); + + // Get every possible download URL into the remoteLauncher fingerprint + foreach (XElement url in urls) + remoteLauncher.AddDownloadURL(url.Value); + + + // Start the download process + HTTP selfPatcherClient = new HTTP(); + + m_DownloadSize = remoteLauncher.Size; + if (selfPatcherClient.StartDownload(new AsyncCompletedEventHandler(DownloadFileComplete), + new DownloadProgressChangedEventHandler(dlProgress), + remoteLauncher.DownloadURL, + remoteLauncher.FullName + ".download")) + { + m_Status = "Downloading"; + m_DownloadActive = true; + } + + m_current = remoteLauncher.FullName; + + // Wait until download is complete + while (selfPatcherClient.Active) + { + if (Kill) { + selfPatcherClient.CancelDownload(); + return; + } + System.Threading.Thread.Sleep(10); + } + m_DownloadActive = false; + + // Make sure the downloaded file is not corrupted + + Fingerprint downloadedFile = new Fingerprint(remoteLauncher.RootPath, remoteLauncher.FileName + ".download"); + + if (!downloadedFile.Equals(remoteLauncher)) + { + string error = "Was unable to self patch. Downloaded file did not match expected checksum."; + error += "\r\n" + remoteLauncher.FileName + + "\r\n md5: " + remoteLauncher.Checksum + " vs " + downloadedFile.Checksum + + "\r\n size: " + remoteLauncher.Size + " vs " + downloadedFile.Size; + + File.Delete(downloadedFile.FullName + ".download"); + m_ErrorLog.Add(error); + m_Status = "Done"; + return; + } + else + { + // Find an available _#.old file name + long i = 0; + string TrashName = myFingerprint.FullName + "_"; + while (File.Exists(TrashName + i.ToString() + ".old")) i++; + + TrashName = TrashName + i.ToString() + ".old"; + File.Move(myFingerprint.FullName, TrashName); + File.Move(myFingerprint.FullName + ".download", myFingerprint.FullName); + + var startInfo = new ProcessStartInfo(); + startInfo.FileName = myFingerprint.FullName; + startInfo.Arguments = MyToolkit.AllArgs(); + + Process.Start(startInfo); + + Application.Exit(); + return; + } + } + } + } + } catch (Exception ex) { + MessageBox.Show(ex.Message, "WorkThread.SelfPatch()"); + } + } + } + + public class ProgressEventArgs : EventArgs { + private int m_progress; + + public ProgressEventArgs(long value, long max) { + m_progress = (int)(Math.Round(value / max * 100.0f)); + } + + public int Progress + { + get { return m_progress; } + set { m_progress = Progress; } + } + } +} diff --git a/TequilaPC/Form1.resources b/TequilaPC/Form1.resources new file mode 100644 index 0000000..06c24d0 Binary files /dev/null and b/TequilaPC/Form1.resources differ diff --git a/TequilaPC/Preferences.Designer.cs b/TequilaPC/Preferences.Designer.cs new file mode 100644 index 0000000..6c12101 --- /dev/null +++ b/TequilaPC/Preferences.Designer.cs @@ -0,0 +1,176 @@ +namespace Tequila +{ + partial class Preferences + { + /// + /// 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() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Preferences)); + this.colorDialog1 = new System.Windows.Forms.ColorDialog(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnColor = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.txtParameters = new System.Windows.Forms.TextBox(); + this.ckbQuitOnLaunch = new System.Windows.Forms.CheckBox(); + this.btnTextColor = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.btnRevalidate = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // colorDialog1 + // + this.colorDialog1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(94)))), ((int)(((byte)(112))))); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(141, 137); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(131, 33); + this.btnOK.TabIndex = 0; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnColor + // + this.btnColor.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(128))))); + this.btnColor.Location = new System.Drawing.Point(104, 64); + this.btnColor.Name = "btnColor"; + this.btnColor.Size = new System.Drawing.Size(168, 23); + this.btnColor.TabIndex = 1; + this.btnColor.UseVisualStyleBackColor = false; + this.btnColor.Click += new System.EventHandler(this.btnColor_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(6, 69); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(92, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Background Color"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(6, 15); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(99, 13); + this.label2.TabIndex = 3; + this.label2.Text = "Launch Parameters"; + // + // txtParameters + // + this.txtParameters.Location = new System.Drawing.Point(111, 12); + this.txtParameters.Name = "txtParameters"; + this.txtParameters.Size = new System.Drawing.Size(161, 20); + this.txtParameters.TabIndex = 4; + this.txtParameters.TextChanged += new System.EventHandler(this.textBox1_TextChanged); + // + // ckbQuitOnLaunch + // + this.ckbQuitOnLaunch.AutoSize = true; + this.ckbQuitOnLaunch.Location = new System.Drawing.Point(9, 41); + this.ckbQuitOnLaunch.Name = "ckbQuitOnLaunch"; + this.ckbQuitOnLaunch.Size = new System.Drawing.Size(154, 17); + this.ckbQuitOnLaunch.TabIndex = 6; + this.ckbQuitOnLaunch.Text = "Exit launcher on game start"; + this.ckbQuitOnLaunch.UseVisualStyleBackColor = true; + this.ckbQuitOnLaunch.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); + // + // btnTextColor + // + this.btnTextColor.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(128))))); + this.btnTextColor.Location = new System.Drawing.Point(104, 93); + this.btnTextColor.Name = "btnTextColor"; + this.btnTextColor.Size = new System.Drawing.Size(168, 23); + this.btnTextColor.TabIndex = 7; + this.btnTextColor.UseVisualStyleBackColor = false; + this.btnTextColor.Click += new System.EventHandler(this.btnTextColor_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(6, 98); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(55, 13); + this.label3.TabIndex = 8; + this.label3.Text = "Text Color"; + // + // btnRevalidate + // + this.btnRevalidate.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(0))); + this.btnRevalidate.Location = new System.Drawing.Point(6, 137); + this.btnRevalidate.Name = "btnRevalidate"; + this.btnRevalidate.Size = new System.Drawing.Size(129, 33); + this.btnRevalidate.TabIndex = 9; + this.btnRevalidate.Text = "Re-Validate"; + this.btnRevalidate.UseVisualStyleBackColor = true; + this.btnRevalidate.Click += new System.EventHandler(this.btnRevalidate_Click); + // + // Preferences + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(284, 182); + this.ControlBox = false; + this.Controls.Add(this.btnRevalidate); + this.Controls.Add(this.label3); + this.Controls.Add(this.btnTextColor); + this.Controls.Add(this.ckbQuitOnLaunch); + this.Controls.Add(this.txtParameters); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnColor); + this.Controls.Add(this.btnOK); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "Preferences"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Preferences"; + this.Load += new System.EventHandler(this.Preferences_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ColorDialog colorDialog1; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnColor; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtParameters; + private System.Windows.Forms.CheckBox ckbQuitOnLaunch; + private System.Windows.Forms.Button btnTextColor; + private System.Windows.Forms.Label label3; + public System.Windows.Forms.Button btnRevalidate; + } +} \ No newline at end of file diff --git a/TequilaPC/Preferences.cs b/TequilaPC/Preferences.cs new file mode 100644 index 0000000..3fcc9b6 --- /dev/null +++ b/TequilaPC/Preferences.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Tequila +{ + public partial class Preferences : Form + { + public bool ReValidate = false; + + public Preferences() + { + InitializeComponent(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void btnColor_Click(object sender, EventArgs e) + { + + colorDialog1.Color = Settings.BGColor; + colorDialog1.ShowDialog(this); + btnColor.BackColor = colorDialog1.Color; + Settings.BGColor = colorDialog1.Color; + + } + + private void btnTextColor_Click(object sender, EventArgs e) + { + colorDialog1.Color = Settings.TextColor; + colorDialog1.ShowDialog(this); + btnTextColor.BackColor = colorDialog1.Color; + Settings.TextColor = colorDialog1.Color; + } + + private void checkBox1_CheckedChanged(object sender, EventArgs e) + { + Settings.QuitOnLaunch = ckbQuitOnLaunch.Checked; + } + + private void textBox1_TextChanged(object sender, EventArgs e) + { + Settings.GameParams = txtParameters.Text.Trim(); + } + + private void Preferences_Load(object sender, EventArgs e) + { + ckbQuitOnLaunch.Checked = Settings.QuitOnLaunch; + txtParameters.Text = Settings.GameParams; + btnColor.BackColor = Settings.BGColor; + btnTextColor.BackColor = Settings.TextColor; + } + + private void btnRevalidate_Click(object sender, EventArgs e) + { + ReValidate = true; + this.Close(); + } + + } +} diff --git a/TequilaPC/Preferences.resx b/TequilaPC/Preferences.resx new file mode 100644 index 0000000..c9e5022 --- /dev/null +++ b/TequilaPC/Preferences.resx @@ -0,0 +1,799 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoqKgqqqqq166urv+2trb/u7u7/7y8vP+8vLz/vLy8/7y8vP+8 + vLz/vLy8/7u7u/+6urr/urq6/7q6uv+7u7v/vLy8/7y8vP+7u7v/sbGx/6SkpP+hoaHoo6OjPgAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCwsAytra3surq6/7+/v/+/v7//v7+//7y8vP+6 + urr/u7u7/729vf+/v7//vr6+/7u7u/+5ubn/t7e3/7S0tP+ysrL/sbGx/7Gxsf+zs7P/tra2/7e3t/+p + qan/oqKi8KampiUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqqjGvr6//v7+//8PDw//D + w8P/wsLC/8HBwf/CwsL/w8PD/8PDw//Dw8P/w8PD/8LCwv/BwcH/wMDA/76+vv+7u7v/t7e3/7Kysv+u + rq7/rKys/6mpqf+pqan/paWl/6WlpYsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK2trVGx + sbH/wsLC/8fHx//Hx8f/x8fH/8fHx//Hx8f/xsbG/8bGxv/Hx8f/xsbG/8bGxv/FxcX/xcXF/8XFxf/F + xcX/xsbG/8fHx//FxcX/v7+//7e3t/+srKz/qKio/6amptMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALCwsGu4uLj/x8fH/8PDw//BwcH/wcHB/8HBwf/Dw8P/xcXF/8jIyP/Kysr/yMjI/8XFxf/D + w8P/wcHB/76+vv+8vLz/urq6/7q6uv+9vb3/wcHB/8bGxv/IyMj/uLi4/6enp/yrq6sQAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAALOzs4S4uLj/urq6/7y8vP+/v7//wcHB/8PDw//Gxsb/yMjI/8vLy//N + zc3/zMzM/8nJyf/Hx8f/xMTE/8HBwf+/v7//vLy8/7q6uv+3t7f/tbW1/7Kysv+ysrL/uLi4/6urq/+p + qak/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALa2tp+8vLz/ycnJ/83Nzf/Jycn/xMTE/8fHx//J + ycn/zMzM/8/Pz//R0dH/z8/P/8zMzP/Kysr/x8fH/8XFxf/CwsL/wMDA/729vf+6urr/uLi4/7W1tf+z + s7P/sLCw/66urv+rq6tsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALm5ubbNzc3/1dXV/9TU1P/H + x8f/yMjI/8nJyf/Ly8v/x8fH/7y8vP+pqan/k5OT/35+fv9ra2v/b29v/4+Pj/+lpaX/urq6/8DAwP++ + vr7/u7u7/7i4uP+2trb/s7Oz/7Gxsf+tra2WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL6+vtTY + 2Nj/2NjY/83Nzf+pqan/hYWF/2JiYv9fX1//YGBg/1tbW/9bW1v/VlZW/1BQUP9LS0v/RUVF/0JCQv9D + Q0P/Tk5O/39/f/+fn5//u7u7/7u7u/+5ubn/tra2/7Ozs/+wsLC8AAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAsbGxAsXFxevc3Nz/u7u7/1dXV/9LS0v/XFxc/2NjY/9nZ2f/a2tr/3BwcP90dHT/cXFx/2xsbP9o + aGj/Y2Nj/19fX/9aWlr/VlZW/1FRUf9KSkr/RkZG/3R0dP+kpKT/ubm5/7a2tv+zs7PgAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAubm5FMvLy/nT09P/c3Nz/1xcXP9gYGD/Z2dn/25ubv9zc3P/eHh4/319ff+C + goL/f39//3l5ef90dHT/b29v/2pqav9lZWX/YGBg/1tbW/9XV1f/UFBQ/0VFRf9ISEj/cXFx/7Ozs/+2 + trb2sbGxDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvb29Lc7Ozv+3t7f/bGxs/2pqav9wcHD/dXV1/3p6ev+A + gID/hYWF/4uLi/+QkJD/jIyM/4eHh/+BgYH/e3t7/3Z2dv9wcHD/a2tr/2ZmZv9gYGD/XFxc/1ZWVv9R + UVH/TU1N/4yMjP+5ubn+tLS0JQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwcHBTc7Ozv+hoaH/cHBw/3V1df97 + e3v/gYGB/4eHh/+NjY3/k5OT/5mZmf+enp7/m5ub/5SUlP+Ojo7/iIiI/4GBgf98fHz/dnZ2/3BwcP9q + amr/ZWVl/2BgYP9aWlr/VVVV/4+Pj/+8vLz/t7e3QgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxsbGc7+/v/+b + m5v/enp6/4CAgP+Ghob/jY2N/5OTk/+ampr/oKCg/6enp/+tra3/qqqq/6Kiov+cnJz/lJSU/46Ojv+H + h4f/gYGB/3t7e/90dHT/b29v/2lpaf9jY2P/YGBg/4mJif+/v7//urq6XwAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAycnJnampqf+Xl5f/hYWF/4uLi/+SkpL/mZmZ/6CgoP+np6f/rq6u/7a2tv+8vLz/uLi4/7Gxsf+p + qan/oqKi/5qamv+Tk5P/jIyM/4WFhf9/f3//eHh4/3Jycv9sbGz/iYmJ/4GBgf/CwsL/vLy8dgAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAzc3NzZmZmf+SkpL/kJCQ/5eXl/+fn5//pqam/62trf+1tbX/vb29/8XFxf/M + zMz/yMjI/7+/v/+4uLj/r6+v/6enp/+fn5//mJiY/5GRkf+JiYn/goKC/3x8fP91dXX/i4uL/5GRkf/F + xcX/v7+/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCwsIQzs7O9pCQkP+UlJT/m5ub/6Ojo/+rq6v/s7Oz/7u7u//E + xMT/zMzM/9TU1P/c3Nz/19fX/87Ozv/Gxsb/vb29/7W1tf+srKz/pKSk/5ycnP+UlJT/jY2N/4aGhv9+ + fn7/hISE/6+vr//AwMD/wsLCqgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzMxJwMDA/5aWlv+fn5//pqam/6+vr/+3 + t7f/wMDA/8nJyf/S0tL/29vb/+Tk5P/s7Oz/5+fn/97e3v/V1dX/y8vL/8LCwv+5ubn/sLCw/6ioqP+f + n5//l5eX/5CQkP+Hh4f/hYWF/9TU1P+xsbH/xcXFzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NCTsLCw/52dnf+l + paX/rq6u/7e3t/+/v7//yMjI/9LS0v/c3Nz/5eXl/+/v7//4+Pj/8/Pz/+np6f/f39//1dXV/8zMzP/D + w8P/urq6/7Gxsf+oqKj/oKCg/5iYmP+Pj4//h4eH//Dw8P+lpaX/ycnJ7729vQgAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALe3twHV + 1dXgoKCg/56env+np6f/r6+v/7i4uP/CwsL/y8vL/9TU1P/e3t7/6Ojo//Ly8v/7+/v/9vb2/+vr6//i + 4uL/2NjY/87Ozv/FxcX/vLy8/7Ozs/+qqqr/oqKi/5mZmf+RkZH/iYmJ/+/v7/+mpqb/zMzM/sPDwyYA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAMnJyTXQ0ND/lpaW/56env+np6f/sLCw/7m5uf/CwsL/y8vL/9TU1P/e3t7/6Ojo//Ly8v/7 + +/v/9vb2/+zs7P/i4uL/2NjY/87Ozv/FxcX/vLy8/7Ozs/+qqqr/oqKi/5qamv+RkZH/iYmJ/+vr6//J + ycn/yMjI/8XFxVoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAM7Ozoy+vr7/lpaW/56env+np6f/urq6/7+/v//CwsL/y8vL/9TU1P/e + 3t7/6Ojo//Ly8v/7+/v/9vb2/+vr6//i4uL/2NjY/8/Pz//FxcX/vLy8/7Ozs/+qqqr/oqKi/5qamv+R + kZH/iYmJ/+rq6v/8/Pz/0dHR/8jIyJcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAubm5BdHR0eCqqqr/lpaW/56env/AwMD/5OTk/7m5uf/C + wsL/y8vL/9TU1P/e3t7/6Ojo//Ly8v/7+/v/9vb2/+vr6//i4uL/2NjY/8/Pz//FxcX/vLy8/7Ozs/+q + qqr/oqKi/5qamv+RkZH/iYmJ/+zs7P/+/v7/9/f3/87OztcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAycnJQdbW1v6VlZX/lpaW/8PDw//5 + +fn/vLy8/7i4uP/CwsL/zs7O/93d3f/p6en/8vLy//n5+f/9/f3/+vr6//X19f/w8PD/6urq/+Pj4//Z + 2dn/zs7O/8DAwP/R0dH/2dnZ/8PDw/+srKz/n5+f//T09P/+/v7//v7+/+vr6/69vb0fAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzc3Nn8LCwv+O + jo7/w8PD//7+/v/S0tL/v7+//9TU1P/l5eX/7+/v//Hx8f/y8vL/9PT0//b29v/4+Pj/9fX1//Ly8v/w + 8PD/7e3t/+vr6//p6en/5+fn/+Xl5f/i4uL/5OTk//Hx8f/9/f3//v7+//7+/v/+/v7//v7+//7+/v/U + 1NRqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADB + wcEP0dHR76Ojo/+3t7f//v7+//b29v/a2tr/2NjY/9XV1f/U1NT/1dXV/9fX1//a2tr/3t7e/+Hh4f/j + 4+P/4uLi/+Dg4P/e3t7/29vb/9nZ2f/X19f/1dXV/9PT0//S0tL/0tLS/9LS0v/Y2Nj/7u7u//7+/v/+ + /v7//v7+//7+/v/d3d27AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAADIyMhd0dHR/7y8vP/09PT/+Pj4/7+/v/+5ubn/vLy8/7+/v//CwsL/xsbG/8nJyf/M + zMz/0NDQ/9PT0//V1dX/1NTU/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP++ + vr7/vLy8/8rKyv/z8/P//v7+//7+/v/g4OD3v7+/GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLy8u+0NDQ/7S0tP/j4+P/vLy8/6mpqf+srKz/r6+v/7Kysv+1 + tbX/uLi4/7u7u/+/v7//wsLC/8XFxf/Hx8f/xsbG/8TExP/CwsL/wMDA/7+/v/+9vb3/u7u7/7m5uf+3 + t7f/tra2/7S0tP+ysrL/sLCw/66urv+wsLD/4uLi//7+/v/h4eH/zMzMagAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwCHQ0ND9paWl/5SUlP+oqKj/mZmZ/52dnf+f + n5//oqKi/6Wlpf+oqKj/q6ur/66urv+2trb/ubm5/8LCwv/Gxsb/ubm5/7a2tv+1tbX/uLi4/83Nzf/I + yMj/x8fH/76+vv+tra3/qamp/6enp/+mpqb/pKSk/6Kiov+goKD/oKCg/93d3f/d3d3/z8/Pxra2tgEA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjIyHzPz8//jIyM/4iIiP+L + i4v/np6e/7m5uf+tra3/np6e/5ycnP/CwsL/y8vL/8LCwv/y8vL/8/Pz//Pz8//6+vr/6Ojo/8LCwv+3 + t7f/5OTk//v7+//7+/v//Pz8//r6+v/r6+v/vr6+/93d3f/c3Nz/u7u7/5mZmf+VlZX/lJSU/5ubm//J + ycn/1NTU/MnJySsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7u7A8rKytfQ + 0ND/rKys/35+fv+CgoL/o6Oj//39/f/7+/v/9fX1//Ly8v/6+vr///////v7+//9/f3//f39//7+/v// + //////////39/f/29vb/7+/v//v7+//+/v7//v7+//7+/v/+/v7//Pz8//7+/v/+/v7//f39/9LS0v+U + lJT/jY2N/5SUlP/Ly8v/1dXV/9HR0Y0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAwsLCN83Nzf7f39//6urq/+Tk5P/q6ur/8PDw//r6+v/+/v7/4eHh/+fn5//g4OD/1tbW/9DQ0P/L + y8v/y8vL/87Ozv/a2tr/9fX1//Dw8P/U1NT/x8fH/8zMzP/Ly8v/1dXV//v7+//+/v7/8vLy/93d3f/h + 4eH//Pz8//7+/v/29vb/8fHx/+rq6v/Y2Nj/4eHh/+rq6uzQ0NALAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAyMjIjNvb2//r6+v/+/v7//z8/P/8/Pz//Pz8//z8/P/o6Oj/urq6/7q6uv+7 + u7v/vLy8/729vf+/v7//wMDA/8HBwf/CwsL/wsLC/8HBwf/AwMD/wMDA/8DAwP+/v7//v7+//8nJyf/E + xMT/vr6+/729vf++vr7/2NjY//Pz8//9/f3/+Pj4//j4+P/39/f/+vr6//r6+v/Ozs5ZAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAOTk5ATm5uZA4+Pj5Pv7+//7+/v/+Pj4/+7u7v/t7e3/7u7u//Dw8P/x + 8fH/7e3t/+Li4v/Y2Nj/0NDQ/8nJyf/ExMT/v7+//76+vv+9vb3/vLy8/7y8vP+8vLz/vLy8/729vf/A + wMD/xcXF/8vLy//S0tL/2tra/+Li4v/r6+v/6+vr/+np6f/q6ur/8vLy/+zs7P/9/f3//v7+//7+/v/u + 7u7P6+vrlurq6igAAAAAAAAAAAAAAAAAAAAAAAAAAOjo6Hj29vb/9vb2/+np6f/p6en/6urq/+vr6//t + 7e3/7u7u//Dw8P/x8fH/8/Pz//T09P/29vb/9/f3//n5+f/7+/v//Pz8//z8/P/7+/v/+Pj4//b29v/2 + 9vb/9fX1//b29v/19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6+vr/+np6f/n5+f/6Ojo/+fn5//3 + 9/f/+Pj4//39/f/+/v7//v7+//j4+LUAAAAAAAAAAAAAAAAAAAAAAAAAAPHx8YX+/v7/7u7u/+fn5//o + 6Oj/6urq/+vr6//t7e3/7u7u//Dw8P/x8fH/8/Pz//T09P/29vb/9/f3//n5+f/7+/v//Pz8//7+/v/+ + /v7//f39//v7+//6+vr/+Pj4//f39//19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6urq/+np6f/n + 5+f/5ubm/+fn5//39/f/6+vr//Hx8f/+/v7//v7+//j4+OPv7+8UAAAAAAAAAAAAAAAAAAAAAPDw8GT9 + /f3/8vLy/+7u7v/r6+v/6urq/+vr6//t7e3/7u7u//Dw8P/x8fH/8/Pz//T09P/29vb/9/f3//n5+f/7 + +/v//Pz8//7+/v/+/v7//f39//v7+//6+vr/+Pj4//f39//19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s + 7Oz/6urq/+np6f/n5+f/5ubm/+fn5//x8fH/6+vr//39/f/+/v7//f394/j4+Gnx8fEJAAAAAAAAAAAA + AAAAAAAAAOnp6Tf+/v7/+fn5//X19f/v7+//6urq/+vr6//t7e3/7+/v//Dw8P/x8fH/8/Pz//T09P/2 + 9vb/9/f3//n5+f/7+/v//Pz8//7+/v/+/v7//f39//v7+//6+vr/+Pj4//f39//19fX/8/Pz//Ly8v/w + 8PD/7+/v/+7u7v/s7Oz/6urq/+np6f/n5+f/5ubm/+fn5//q6ur/+Pj4//7+/v/+/v75+vr6LAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAOTk5AT7+/uV8PDw0Ovr6//o6Oj/6urq/+vr6//t7e3/7+/v//Dw8P/x + 8fH/8/Pz//T09P/29vb/+Pj4//n5+f/7+/v//Pz8//7+/v/+/v7//f39//v7+//6+vr/+Pj4//f39//1 + 9fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6urq/+np6f/n5+f/5ubm/+bm5v/n5+f/6+vr//r6+vz6 + +vq47OzsDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8fHxcP7+/v/6+vr/6enp/+rq6v/s + 7Oz/7+/v//Dw8P/x8fH/8/Pz//T09P/29vb/+Pj4//n5+f/7+/v//Pz8//7+/v/+/v7//f39//v7+//6 + +vr/+Pj4//b29v/19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6enp/+rq6v/v7+//9fX1//n5+f/9 + /f3//f398/f393gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9/f3C/n5+Xn6 + +vrs+fn5//n5+f/19fX/7u7u/+vr6//w8PD/8/Pz//T09P/29vb/9fX1//j4+P/7+/v//Pz8//7+/v/+ + /v7//f39//v7+//6+vr/+Pj4//b29v/19fX/8/Pz/+7u7v/r6+v/6+vr/+rq6v/p6en/9/f3//7+/v/+ + /v7//v7+//z8/O/6+vp27u7uFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAADz8/Mu+Pj4R/j4+Ej6+vqd9vb2+fr6+v/29vb/8vLy//Dw8P/u7u7/8fHx//X19f/4 + +Pj//Pz8//7+/v/+/v7//f39//r6+v/29vb/9PT0//Ly8v/y8vL/7u7u//j4+P/8/Pz//f39//39/f/7 + +/v//v7+//7+/v/+/v7//f394+/v7zMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2K/z8/Mr+/v7//v7+//////// + ///////////////5+fn/8vLy//Pz8//09PT/8vLy/+7u7v/29vb/9vb2//f39//39/f/+fn5//7+/v/+ + /v7//v7+//7+/v/6+vqU8/PzPPLy8i/y8vI58vLyJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8An0 + 9PQx9PT0MPn5+Wv7+/vZ/////////////////v7+//39/f/8/Pz//f39//7+/v/+/v7//v7+//7+/v/+ + /v7+/Pz81Pn5+WT29vY29/f3O/j4+Enz8/MfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADu7u4H9/f3RPb29jz4+Pgt+fn5X/v7+675+fmv+/v74vr6+q77 + +/uO+vr6tPj4+Jv19fUe8PDwAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AD//9Pz//+AAD//0/P//gAAD//T8// + 8AAAH/9Pz//gAAAP/0/P/+AAAA//T8//4AAAD/9Pz//gAAAH/0/P/+AAAAf/T8//4AAAB/9Pz//gAAAH + /0/P/+AAAAf/T8//wAAAB/9Pz//AAAAD/0/P/8AAAAP/T8//wAAAA/9Pz//AAAAD/0/P/8AAAAP/T8// + wAAAA/9Pz/+AAAAD/0/P/4AAAAP/T8//gAAAAf9Pz/8AAAAB/0/P/wAAAAH/T8//AAAAAf9Pz/4AAAAB + /0/P/gAAAAD/T8/+AAAAAP9Pz/wAAAAA/0/P/AAAAAB/T8/8AAAAAH9Pz/gAAAAAP0/P+AAAAAA/T8/w + AAAAAD9Pz/AAAAAAH0/P8AAAAAAfT8/AAAAAAAdPz8AAAAAAB0/PwAAAAAADT8/AAAAAAANPz8AAAAAA + D0/PwAAAAAAPT8/wAAAAAD9Pz/AAAAAAf0/P/AAAAAH/T8//wAAAA/9Pz//gAAA//0/P//4AB///T88o + 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 + u7v/wMDALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMvLy8Sb + m5v/qKio/7W1tf/CwsL/0NDQ/9/f3//t7e3/+Pj4/+zs7P/e3t7/z8/P/8HBwf+0tLT/p6en/5qamv+O + jo7/zc3N/7Kysv/GxsZXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJ + yckYv7+//JycnP+pqan/tra2/8TExP/S0tL/4eHh/+/v7//6+vr/7u7u/+Dg4P/R0dH/w8PD/7a2tv+o + qKj/nJyc/4+Pj//Kysr/wcHB/8jIyIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAM/Pz2ytra3/nJyc/7Gxsf/ExMT/xMTE/9LS0v/h4eH/7+/v//r6+v/u7u7/4ODg/9HR0f/D + w8P/tbW1/6ioqP+cnJz/j4+P/8nJyf/19fX/zs7OxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAA0tLSxpiYmP+tra3/5ubm/7i4uP/ExMT/19fX/+jo6P/19fX//Pz8//T09P/q + 6ur/3t7e/9DQ0P+/v7//xsbG/7q6uv+goKD/09PT///////r6+v6vr6+DgAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAMbGxiXDw8P+pKSk//b29v/R0dH/1tbW/+Tk5P/p6en/7Ozs//Dw8P/y + 8vL/7u7u/+rq6v/n5+f/5OTk/+Hh4f/e3t7/5+fn//f39/////////////7+/v/Z2dlUAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzc3NhLy8vP/v7+//3Nzc/8LCwv/CwsL/x8fH/8zMzP/R + 0dH/1tbW/9jY2P/W1tb/09PT/9DQ0P/Nzc3/ysrK/8fHx//ExMT/w8PD/9bW1v/6+vr//////9zc3KcA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALa2tgLOzs7hsLCw/87Ozv+mpqb/qamp/66urv+z + s7P/t7e3/7y8vP/BwcH/w8PD/8HBwf++vr7/vb29/7q6uv+3t7f/tLS0/7Gxsf+urq7/rKys/7Ozs//w + 8PD/29vb9MTExAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx8fHQ729vf+Kior/j4+P/6ysrP+l + paX/nZ2d/7y8vP+7u7v/39/f/+Pj4//n5+f/w8PD/7y8vP/t7e3/8PDw/+3t7f/Ozs7/wcHB/8TExP+g + oKD/l5eX/6SkpP/Q0ND/zs7OYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKysqg0dHR/6CgoP+g + oKD/6+vr//v7+//09PT/+vr6//Pz8//v7+//8PDw//v7+//+/v7/7Ozs/+np6f/x8fH//f39///////7 + +/v//f39/+rq6v+wsLD/qqqq/9DQ0P/W1tbEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAubm5CNLS0vHt + 7e3/+/v7//z8/P/9/f3/39/f/8LCwv++vr7/v7+//8HBwf/CwsL/xsbG/8/Pz//CwsL/wcHB/8HBwf/R + 0dH/1NTU/8LCwv/Kysr/9PT0//7+/v/4+Pj/7+/v//n5+f/Pz88tAAAAAAAAAAAAAAAAAAAAAOXl5Rjp + 6eme8/Pz//T09P/v7+//7e3t//Dw8P/x8fH/6urq/+Hh4f/a2tr/1dXV/9LS0v/Q0ND/zs7O/87Ozv/P + z8//09PT/9fX1//d3d3/5eXl/+vr6//p6en/7e3t/+rq6v/8/Pz///////Pz89Ly8vJzAAAAAAAAAAAA + AAAA7+/vWv39/f/n5+f/6enp/+vr6//t7e3/8PDw//Ly8v/09PT/9vb2//n5+f/7+/v//f39//7+/v/8 + /Pz/+fn5//f39//19fX/8vLy//Dw8P/u7u7/7Ozs/+np6f/n5+f/5+fn//T09P/y8vL///////v7++fv + 7+8JAAAAAAAAAADv7+88+/v7//T09P/t7e3/6+vr/+3t7f/w8PD/8vLy//T09P/29vb/+fn5//v7+//9 + /f3//v7+//z8/P/5+fn/9/f3//X19f/y8vL/8PDw/+7u7v/s7Oz/6enp/+fn5//n5+f/7+/v//r6+v/+ + /v7w+vr6XfLy8gQAAAAAAAAAAOfn5wv7+/u76+vr/+jo6P/r6+v/7e3t//Dw8P/y8vL/9PT0//b29v/5 + +fn/+/v7//39/f/+/v7//Pz8//n5+f/39/f/9fX1//Ly8v/w8PD/7u7u/+zs7P/p6en/5+fn/+bm5v/p + 6en/+Pj4/vr6+pMAAAAAAAAAAAAAAAAAAAAAAAAAAOfn5wL6+vrW9fX1/+zs7P/u7u7/8PDw//Ly8v/0 + 9PT/9vb2//n5+f/7+/v//f39//7+/v/8/Pz/+fn5//f39//19fX/8vLy//Dw8P/u7u7/6+vr/+/v7//1 + 9fX/+vr6//z8/OL4+PhqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLy8gX5+fl1/Pz8gfj4+NHz + 8/P/8/Pz//Ly8v/w8PD/9fX1//r6+v/9/f3//v7+//v7+//39/f/9PT0//Ly8v/y8vL/9fX1//b29v/4 + +Pj////////////4+PiR+Pj4BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAA9/f3Avr6+m/8/PzK/f394///////////+fn5//b29v/19fX/9PT0//n5+f/5+fn/+fn5//39/fH8 + /PzP/f392Pj4+F/x8fEh8/PzJ+zs7AIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADt7e0D+Pj4VPv7+4H7+/t5/Pz8vPv7+9L8/PzY/Pz8ufv7+8X6 + +vpf9fX1EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AB/// + gAH//wAA//4AAP/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//AAAf/wAAD/8AAA//AAAP/gAAD/4 + AAA/+AAAH/AAAB/wAAAf4AAAD+AAAA/gAAAPwAAAB4AAAAOAAAABgAAAAYAAAAfAAAAP4AAAH/wAAD// + gA//KAAAABgAAAAwAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACqqqoMq6urb66ursGysrLusLCw/KysrPKpqanKpaWlh6WlpSsAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKioqEOvr6/jtbW1/7m5uf+6 + urr/urq6/7m5uf+3t7f/tra2/62trf2jo6Omo6OjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAArKysD7a2tvrBwcH/wMDA/76+vv/AwMD/v7+//7y8vP+4uLj/s7Oz/7CwsP+t + ra3/pKSkqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr6+vL7y8vP/E + xMT/xMTE/8XFxf/IyMj/xsbG/8PDw//BwcH/wMDA/8DAwP+8vLz/q6ur86urqwQAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtLS0Sb6+vv/ExMT/xMTE/8nJyf/Ozs7/zMzM/8fHx//C + wsL/vb29/7i4uP+zs7P/sLCw/6qqqisAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAvLy8Y9XV1f/ExMT/np6e/5SUlP+Hh4f/bm5u/1tbW/9ubm7/kpKS/7W1tf+5ubn/s7Oz/6+vr1UA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxsbGf7e3t/9YWFj/ZWVl/29vb/95 + eXn/dXV1/2xsbP9iYmL/WVlZ/05OTv9paWn/paWl/7S0tHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAysrKno2Njf9zc3P/fn5+/4mJif+UlJT/kZGR/4SEhP95eXn/bm5u/2NjY/9Y + WFj/b29v/7m5uZkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvLy8xIyMjP+J + iYn/lpaW/6SkpP+ysrL/ra2t/5+fn/+RkZH/g4OD/3Z2dv9qamr/fX19/7+/v7UAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/v78EsLCw8JSUlP+hoaH/sLCw/8DAwP/Q0ND/y8vL/7q6uv+q + qqr/mpqa/4uLi/99fX3/lJSU/8LCws4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADP + z883qamp/6ampv+3t7f/ycnJ/9vb2//u7u7/6Ojo/9XV1f/Dw8P/sbGx/6CgoP+QkJD/tLS0/7i4uO69 + vb0CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NCFnZ2d/6urq/+9vb3/z8/P/+Pj4//2 + 9vb/8fHx/93d3f/Kysr/uLi4/6ampv+VlZX/u7u7/8HBwf/ExMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALm5uQHAwMDampqa/8HBwf+/v7//0NDQ/+Pj4//29vb/8fHx/93d3f/Kysr/uLi4/6ampv+V + lZX/urq6//Hx8f/Nzc1bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzDiurq7/xsbG/9LS0v/N + zc3/4+Pj//Dw8P/5+fn/9vb2/+7u7v/k5OT/1tbW/9zc3P/X19f/5OTk///////q6uqiAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAM7OzpfCwsL/6+vr/8rKyv/Ly8v/z8/P/9XV1f/b29v/2tra/9bW1v/S + 0tL/zs7O/8vLy//Kysr/3d3d//z8/P/v7+/sv7+/BgAAAAAAAAAAAAAAAAAAAAAAAAAAwMDACMTExO61 + tbX/p6en/6enp/+tra3/s7Oz/7y8vP/FxcX/vr6+/7y8vP/ExMT/vr6+/7Gxsf+tra3/qamp/7W1tf/m + 5ub/zs7OTAAAAAAAAAAAAAAAAAAAAAAAAAAAycnJVra2tv+FhYX/vr6+/8/Pz//S0tL/4uLi//j4+P/6 + +vr/6enp/+Dg4P/8/Pz//f39/+np6f/t7e3/ycnJ/5KSkv+xsbH/0tLSrQAAAAAAAAAAAAAAAAAAAAAA + AAAAz8/PsOzs7P/x8fH/+fn5/+Dg4P/Pz8//yMjI/8XFxf/Ly8v/2tra/8fHx//Gxsb/1tbW/9zc3P/O + zs7/8fHx//f39//s7Oz/8PDw+s/PzxkAAAAAAAAAAAAAAADv7+9v7+/v+PHx8f/t7e3/7+/v//Dw8P/p + 6en/4uLi/97e3v/c3Nz/2tra/9nZ2f/a2tr/3d3d/+Pj4//q6ur/6urq/+vr6//y8vL//f39//b29tn0 + 9PQ3AAAAAAAAAAD5+fm67e3t/+rq6v/s7Oz/7+/v//Ly8v/19fX/+Pj4//v7+//+/v7//Pz8//n5+f/2 + 9vb/8/Pz//Dw8P/t7e3/6urq/+fn5//t7e3/8fHx//7+/vj39/daAAAAAAAAAAD5+fl08vLy8+vr6//s + 7Oz/7+/v//Ly8v/19fX/+Pj4//v7+//+/v7//Pz8//n5+f/29vb/8/Pz//Dw8P/t7e3/6urq/+fn5//o + 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 + + + \ No newline at end of file diff --git a/TequilaPC/Program.cs b/TequilaPC/Program.cs new file mode 100644 index 0000000..4f70b92 --- /dev/null +++ b/TequilaPC/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace Tequila +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + MyToolkit.args = args; + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Tequila()); + } + } +} diff --git a/TequilaPC/Properties/AssemblyInfo.cs b/TequilaPC/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b039f41 --- /dev/null +++ b/TequilaPC/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Tequila")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tequila")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5726b772-bd5e-4c42-ba0a-6d4c03b9302c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.10")] +[assembly: AssemblyFileVersion("1.0.0.10")] diff --git a/TequilaPC/Properties/Resources.Designer.cs b/TequilaPC/Properties/Resources.Designer.cs new file mode 100644 index 0000000..b46981a --- /dev/null +++ b/TequilaPC/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18034 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tequila.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("Tequila.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Background { + get { + object obj = ResourceManager.GetObject("Background", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/TequilaPC/Properties/Settings.Designer.cs b/TequilaPC/Properties/Settings.Designer.cs new file mode 100644 index 0000000..52ad6b7 --- /dev/null +++ b/TequilaPC/Properties/Settings.Designer.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18047 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tequila.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string InstallationPath { + get { + return ((string)(this["InstallationPath"])); + } + set { + this["InstallationPath"] = value; + } + } + } +} diff --git a/TequilaPC/Properties/Settings.settings b/TequilaPC/Properties/Settings.settings new file mode 100644 index 0000000..1046018 --- /dev/null +++ b/TequilaPC/Properties/Settings.settings @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/TequilaPC/Properties/app.manifest b/TequilaPC/Properties/app.manifest new file mode 100644 index 0000000..42ff09e --- /dev/null +++ b/TequilaPC/Properties/app.manifest @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TequilaPC/Resources/tequila.ico b/TequilaPC/Resources/tequila.ico new file mode 100644 index 0000000..dc9b42e Binary files /dev/null and b/TequilaPC/Resources/tequila.ico differ diff --git a/TequilaPC/Tequila.Designer.cs b/TequilaPC/Tequila.Designer.cs new file mode 100644 index 0000000..d26e53c --- /dev/null +++ b/TequilaPC/Tequila.Designer.cs @@ -0,0 +1,219 @@ +namespace Tequila +{ + partial class Tequila + { + /// + /// 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(Tequila)); + this.lblStatus = new System.Windows.Forms.Label(); + this.Progress = new System.Windows.Forms.ProgressBar(); + this.txtErrors = new System.Windows.Forms.TextBox(); + this.pnlErrors = new System.Windows.Forms.Panel(); + this.label1 = new System.Windows.Forms.Label(); + this.btnPlay = new System.Windows.Forms.Button(); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.webBrowser1 = new System.Windows.Forms.WebBrowser(); + this.btnScreenshots = new System.Windows.Forms.Button(); + this.btnOptions = new System.Windows.Forms.Button(); + this.pnlErrors.SuspendLayout(); + this.SuspendLayout(); + // + // lblStatus + // + this.lblStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lblStatus.BackColor = System.Drawing.Color.Transparent; + this.lblStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(0))); + this.lblStatus.ForeColor = System.Drawing.SystemColors.ControlLightLight; + this.lblStatus.Location = new System.Drawing.Point(12, 423); + this.lblStatus.Name = "lblStatus"; + this.lblStatus.Size = new System.Drawing.Size(806, 23); + this.lblStatus.TabIndex = 0; + this.lblStatus.Text = "test"; + this.lblStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // Progress + // + this.Progress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.Progress.Location = new System.Drawing.Point(12, 391); + this.Progress.Name = "Progress"; + this.Progress.Size = new System.Drawing.Size(806, 23); + this.Progress.TabIndex = 1; + // + // txtErrors + // + this.txtErrors.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.txtErrors.Location = new System.Drawing.Point(3, 35); + this.txtErrors.Multiline = true; + this.txtErrors.Name = "txtErrors"; + this.txtErrors.Size = new System.Drawing.Size(556, 335); + this.txtErrors.TabIndex = 2; + // + // pnlErrors + // + this.pnlErrors.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.pnlErrors.BackColor = System.Drawing.Color.Transparent; + this.pnlErrors.Controls.Add(this.label1); + this.pnlErrors.Controls.Add(this.txtErrors); + this.pnlErrors.Location = new System.Drawing.Point(256, 12); + this.pnlErrors.Name = "pnlErrors"; + this.pnlErrors.Size = new System.Drawing.Size(562, 373); + this.pnlErrors.TabIndex = 3; + this.pnlErrors.Visible = false; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 17F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.ForeColor = System.Drawing.Color.White; + this.label1.Location = new System.Drawing.Point(-2, 3); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(92, 29); + this.label1.TabIndex = 3; + this.label1.Text = "Errors:"; + // + // btnPlay + // + this.btnPlay.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnPlay.Enabled = false; + this.btnPlay.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Pixel, ((byte)(0))); + this.btnPlay.Location = new System.Drawing.Point(12, 301); + this.btnPlay.Name = "btnPlay"; + this.btnPlay.Size = new System.Drawing.Size(238, 41); + this.btnPlay.TabIndex = 4; + this.btnPlay.Text = "Play"; + this.btnPlay.UseVisualStyleBackColor = true; + this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click); + // + // listBox1 + // + this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.listBox1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(94)))), ((int)(((byte)(112))))); + this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.listBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Pixel, ((byte)(0))); + this.listBox1.ForeColor = System.Drawing.SystemColors.Info; + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 25; + this.listBox1.Location = new System.Drawing.Point(12, 15); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(238, 275); + this.listBox1.TabIndex = 5; + // + // timer1 + // + this.timer1.Interval = 10; + this.timer1.Tick += new System.EventHandler(this.timer_Tick); + // + // webBrowser1 + // + this.webBrowser1.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.webBrowser1.Location = new System.Drawing.Point(259, 15); + this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); + this.webBrowser1.Name = "webBrowser1"; + this.webBrowser1.Size = new System.Drawing.Size(559, 370); + this.webBrowser1.TabIndex = 6; + this.webBrowser1.Url = new System.Uri("http://github.com/leandrotlz/Tequila", System.UriKind.Absolute); + // + // btnScreenshots + // + this.btnScreenshots.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(0))); + this.btnScreenshots.Location = new System.Drawing.Point(12, 348); + this.btnScreenshots.Name = "btnScreenshots"; + this.btnScreenshots.Size = new System.Drawing.Size(118, 34); + this.btnScreenshots.TabIndex = 8; + this.btnScreenshots.Text = "Screenshots"; + this.btnScreenshots.UseVisualStyleBackColor = true; + this.btnScreenshots.Click += new System.EventHandler(this.btnScreenshots_Click); + // + // btnOptions + // + this.btnOptions.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(0))); + this.btnOptions.Location = new System.Drawing.Point(132, 348); + this.btnOptions.Name = "btnOptions"; + this.btnOptions.Size = new System.Drawing.Size(118, 34); + this.btnOptions.TabIndex = 9; + this.btnOptions.Text = "Options"; + this.btnOptions.UseVisualStyleBackColor = true; + this.btnOptions.Click += new System.EventHandler(this.button1_Click); + // + // Tequila + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(94)))), ((int)(((byte)(112))))); + this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.ClientSize = new System.Drawing.Size(824, 455); + this.Controls.Add(this.btnOptions); + this.Controls.Add(this.btnScreenshots); + this.Controls.Add(this.btnPlay); + this.Controls.Add(this.webBrowser1); + this.Controls.Add(this.listBox1); + this.Controls.Add(this.pnlErrors); + this.Controls.Add(this.Progress); + this.Controls.Add(this.lblStatus); + this.DoubleBuffered = true; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximumSize = new System.Drawing.Size(834, 487); + this.MinimumSize = new System.Drawing.Size(834, 487); + this.Name = "Tequila"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Tequila"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form_FormClosing); + this.Load += new System.EventHandler(this.Form_Load); + this.pnlErrors.ResumeLayout(false); + this.pnlErrors.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label lblStatus; + private System.Windows.Forms.ProgressBar Progress; + private System.Windows.Forms.TextBox txtErrors; + private System.Windows.Forms.Panel pnlErrors; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnPlay; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.WebBrowser webBrowser1; + private System.Windows.Forms.Button btnScreenshots; + private System.Windows.Forms.Button btnOptions; + + } +} + diff --git a/TequilaPC/Tequila.cs b/TequilaPC/Tequila.cs new file mode 100644 index 0000000..21f9475 --- /dev/null +++ b/TequilaPC/Tequila.cs @@ -0,0 +1,423 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Security.Cryptography; +using System.Net; +using System.Xml; +using System.Xml.Linq; +using System.Collections; +using System.Diagnostics; +using System.Threading; + +namespace Tequila +{ + public partial class Tequila : Form + { + WorkThread myWorker; + DirCopy myCopyObj; + Thread myCopyDirThread; + + private bool NoMove = false; + private bool DevMode = false; + + string ManifestURL = "http://dl.dropboxusercontent.com/u/37952257/Tequila/titanicon.xml"; + + public Tequila() + { + InitializeComponent(); + } + + private bool Setup() { + try { + if (Settings.SetupNeeded) + { + string myPath = ""; + bool PathValid = false; + FolderBrowserDialog FileBox; + + do { + FileBox = new FolderBrowserDialog(); + + FileBox.Description = "Select the game directory"; + FileBox.SelectedPath = @"C:\Program Files (x86)\CohBeta"; + + if (FileBox.ShowDialog(this) == System.Windows.Forms.DialogResult.Cancel) { + MessageBox.Show("You must select a valid install directory to continue. \nLauncher will now quit. Relaunch the laucher once you have a valid installation path."); + Application.Exit(); + return false; + } + + myPath = FileBox.SelectedPath; // FileName.Substring(0, FileBox.FileName.LastIndexOf("\\") + 1); + + if (File.Exists(Path.Combine(myPath, "icon.exe"))) + { + PathValid = true; + } else { + PathValid = false; + MessageBox.Show("The selected directory does not contain a full game installation.\r\nPlease make sure you select a directory that is not missing any files.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } while (!PathValid); + + if (!MyToolkit.InstallDirSafe(myPath)) { + string warning = "The game files will be copied to AppData\\TitanIcon; click OK to continue, Cancel to relocate the folder yourself and relaunch Tequila"; + if (MessageBox.Show(warning, "test", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.Cancel) { + Application.Exit(); + return false; + } + + string DestPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + DestPath = Path.Combine(DestPath, "TitanIcon"); + + myCopyObj = new DirCopy(myPath, DestPath); + myPath = DestPath; + myCopyDirThread = new Thread(new ThreadStart(myCopyObj.DirectoryCopy)); + myCopyDirThread.Start(); + } + + Settings.GamePath = myPath; + } + + SelfRelocate(); + ConsolidateVirtualStore(); + + return true; + + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".Setup"); + return false; + } + } + + private void SelfRelocate() { + if (NoMove) return; + try { + if (Application.StartupPath == Settings.GamePath) return; + if (!File.Exists(Application.ExecutablePath)) return; + + string ShortcutPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); + string ShortcutTarget = Path.Combine(Settings.GamePath, "Tequila.exe"); + + if (!Directory.Exists(Settings.GamePath)) + Directory.CreateDirectory(Settings.GamePath); + + try { + if (File.Exists(ShortcutTarget)) File.Delete(ShortcutTarget); + File.Move(Application.ExecutablePath, ShortcutTarget); + } catch (Exception ex) { + File.Copy(Application.ExecutablePath, ShortcutTarget); + try { File.Move(Application.ExecutablePath, Path.Combine(Application.StartupPath, "deleteme.txt")); } + catch (Exception ex2) { } + } + + try { + using (ShellLink shortcut = new ShellLink()) { + shortcut.Target = ShortcutTarget; + //shortcut.WorkingDirectory = Path.GetDirectoryName(ShortcutTarget); + shortcut.Description = "Drink up!"; + shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal; + shortcut.Save(Path.Combine(ShortcutPath, "Tequila.lnk")); + } + } catch (Exception ex) { + MessageBox.Show(ex.Message); + } + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".SelfRelocate"); + } + } + + private void ConsolidateVirtualStore() { + try { + if (!Directory.Exists(Settings.GamePath)) + Directory.CreateDirectory(Settings.GamePath); + + string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + + if (Settings.GamePath != Path.Combine(localAppData, "TitanIcon")) return; + + string pathCoH = Path.Combine(localAppData, "VirtualStore\\Program Files (x86)\\TitanIcon"); + string pathCoHBeta = Path.Combine(localAppData, "VirtualStore\\Program Files (x86)\\TitanIcon"); + + if (Directory.Exists(pathCoH)) { + DirCopy myCopy = new DirCopy(pathCoH, Settings.GamePath); + myCopy.DirectoryCopyNoReplace(); + } + + if (Directory.Exists(pathCoHBeta)) + { + DirCopy myCopy = new DirCopy(pathCoHBeta, Settings.GamePath); + myCopy.DirectoryCopyNoReplace(); + } + + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".Form_Load"); + } + } + + private void Skin() + { + BackColor = Settings.BGColor; + label1.ForeColor = Settings.TextColor; + lblStatus.ForeColor = Settings.TextColor; + listBox1.BackColor = Settings.BGColor; + listBox1.ForeColor = Settings.TextColor; + } + + private void ScanParameters() { + for (int i = 0; i < MyToolkit.args.Length; i++) + { + + // Check for parameters overriding the download of a new manifest + if (MyToolkit.args[i].Trim() == "-o") + { + WorkThread.DontDownloadManifest = true; + } + // Check for parameters overriding self patching + else if (MyToolkit.args[i].Trim() == "-noselfpatch" || + MyToolkit.args[i].Trim() == "-noselfupdate" || + MyToolkit.args[i].Trim() == "-nodisassemblejohnny5") + { + WorkThread.DontSelfUpdate = true; + } + // Check for parameters overriding self patching + else if (MyToolkit.args[i].Trim() == "-md5") + { + WorkThread.GenerageChecksumToClipboard = true; + } + // Check for parameters disabling self relocate (this option also makes it not self patch) + else if (MyToolkit.args[i].Trim() == "-nomove") + { + NoMove = true; + WorkThread.DontSelfUpdate = true; + } + // Check for parameters disabling self relocate (this option also makes it not self patch) + else if (MyToolkit.args[i].Trim() == "-devmode" || + MyToolkit.args[i].Trim() == "-dev") + { + DevMode = true; + } + // Pick up manifest download override + else if (MyToolkit.args.Length > i + 1) + { + if (MyToolkit.args[i].Trim() == "-m") + { + if (MyToolkit.args[i + 1].Trim() == "") + { + MessageBox.Show("No manifest specified in parameter -m, using default."); + } + else + { + ManifestURL = MyToolkit.args[1]; + } + } + } + } + } + + private void ProcessKiller() { + try + { + + Process[] prs = Process.GetProcessesByName("tequila"); + Process me = Process.GetCurrentProcess(); + int killcount = 0; + int killfailcount = 0; + foreach (Process pr in prs) + { + if (pr.Id != me.Id) + { + killcount++; + try + { + pr.Kill(); + } catch (Exception ex) { + killfailcount++; + } + } + } + + if (killcount > 0) Thread.Sleep(2000); + if (killfailcount > 0) MessageBox.Show(null, "Found a running instance of Tequila but was not able to terminate it.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning); + + } catch (Exception ex) { } + } + + private void Form_Load(object sender, EventArgs e) + { + try + { + ProcessKiller(); + + this.Text += " " + Application.ProductVersion; + Skin(); + + ScanParameters(); + + timer1.Enabled = Setup(); + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".Form_Load"); + } + } + + private void StartUp() { + try + { + string PathRoot = Settings.GamePath; + string LocalManifest = PathRoot + @"rspatcher.xml"; + + btnPlay.Text = "..."; + btnPlay.Enabled = false; + + myWorker = new WorkThread(ManifestURL); + myWorker.LocalManifest = LocalManifest; + myWorker.PathRoot = PathRoot; + myWorker.DownloadManifest(); + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".StartUp"); + } + } + + private void Finish() { + try{ + Progress.Value = 100; + timer1.Enabled = false; + + if (myWorker.ErrorMessage != "") + { + txtErrors.Text = myWorker.ErrorMessage; + webBrowser1.Visible = false; + pnlErrors.Visible = true; + } else { + btnPlay.Enabled = true; + btnPlay.Text = "Play"; + } + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".Finish"); + } + } + + private void timer_Tick(object sender, EventArgs e) + { + try + { + if (myCopyObj != null) + { + if (myCopyObj.Active) + { + Progress.Value = myCopyObj.Progress; + return; + } + } + + if (myWorker == null) + { + StartUp(); + return; + } + + if (myWorker.Manifest != null) + + if (listBox1.Items.Count <= 1) + { + IEnumerable Profiles = myWorker.Manifest.Descendants("launch"); + List items = new List(); + + foreach (XElement profile in Profiles) + { + items.Add(new LaunchProfile(profile.Value.ToString().Replace("My App: ", "").Trim(), + profile.Attribute("exec").Value, + profile.Attribute("params").Value)); + } + + if (DevMode) { + Profiles = myWorker.Manifest.Descendants("devlaunch"); + + foreach (XElement profile in Profiles) + { + items.Add(new LaunchProfile(profile.Value.ToString().Replace("My App: ", "").Trim(), + profile.Attribute("exec").Value, + profile.Attribute("params").Value)); + } + } + + listBox1.DisplayMember = "Text"; + listBox1.DataSource = items; + listBox1.SelectedIndex = 0; + } + + Progress.Value = MyToolkit.MinMax(myWorker.CurProgress, 0, 100); + lblStatus.Text = myWorker.Status + "... " + myWorker.CurFile; + + if (myWorker.Status == "Done") Finish(); + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".Form_Load"); + } + } + + private void btnPlay_Click(object sender, EventArgs e) + { + try { + var startInfo = new ProcessStartInfo(); + startInfo.WorkingDirectory = Settings.GamePath; + startInfo.FileName = ((LaunchProfile)listBox1.SelectedItem).Exec; + startInfo.Arguments = ((LaunchProfile)listBox1.SelectedItem).Params; + startInfo.Arguments += " " + Settings.GameParams; + + Process.Start(startInfo); + if (Settings.QuitOnLaunch) Application.Exit(); + + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".btnPlay_Click"); + } + } + + private void btnScreenshots_Click(object sender, EventArgs e) + { + try { + string screenshotDir = Path.Combine(Settings.GamePath, "screenshots"); + + if (!Directory.Exists(screenshotDir)) { + Directory.CreateDirectory(screenshotDir); + } + System.Diagnostics.Process.Start("explorer.exe", screenshotDir); + } catch (Exception ex) { + MyToolkit.ErrorReporter(ex, this.Name + ".btScreenshots_Click"); + } + } + + private void Form_FormClosing(object sender, FormClosingEventArgs e) + { + WorkThread.Kill = true; + DirCopy.Kill = true; + + if(myCopyDirThread != null) if(myCopyDirThread.IsAlive) try { myCopyDirThread.Abort(); } catch (Exception ex) { } + } + + private void button1_Click(object sender, EventArgs e) + { + Preferences prefs = new Preferences(); + prefs.btnRevalidate.Enabled = (myWorker.Status == "Done"); + prefs.ShowDialog(this); + Skin(); + + if (prefs.ReValidate) + { + try + { + File.Delete(Path.Combine(Settings.GamePath, "tequilalog.xml")); + timer1.Enabled = Setup(); + StartUp(); + } + catch (Exception ex) + { + MyToolkit.ErrorReporter(ex, this.Name + ".Form_Load"); + } + } + } + + } +} diff --git a/TequilaPC/Tequila.resx b/TequilaPC/Tequila.resx new file mode 100644 index 0000000..555c870 --- /dev/null +++ b/TequilaPC/Tequila.resx @@ -0,0 +1,799 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoqKgqqqqq166urv+2trb/u7u7/7y8vP+8vLz/vLy8/7y8vP+8 + vLz/vLy8/7u7u/+6urr/urq6/7q6uv+7u7v/vLy8/7y8vP+7u7v/sbGx/6SkpP+hoaHoo6OjPgAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCwsAytra3surq6/7+/v/+/v7//v7+//7y8vP+6 + urr/u7u7/729vf+/v7//vr6+/7u7u/+5ubn/t7e3/7S0tP+ysrL/sbGx/7Gxsf+zs7P/tra2/7e3t/+p + qan/oqKi8KampiUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqqjGvr6//v7+//8PDw//D + w8P/wsLC/8HBwf/CwsL/w8PD/8PDw//Dw8P/w8PD/8LCwv/BwcH/wMDA/76+vv+7u7v/t7e3/7Kysv+u + rq7/rKys/6mpqf+pqan/paWl/6WlpYsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK2trVGx + sbH/wsLC/8fHx//Hx8f/x8fH/8fHx//Hx8f/xsbG/8bGxv/Hx8f/xsbG/8bGxv/FxcX/xcXF/8XFxf/F + xcX/xsbG/8fHx//FxcX/v7+//7e3t/+srKz/qKio/6amptMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALCwsGu4uLj/x8fH/8PDw//BwcH/wcHB/8HBwf/Dw8P/xcXF/8jIyP/Kysr/yMjI/8XFxf/D + w8P/wcHB/76+vv+8vLz/urq6/7q6uv+9vb3/wcHB/8bGxv/IyMj/uLi4/6enp/yrq6sQAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAALOzs4S4uLj/urq6/7y8vP+/v7//wcHB/8PDw//Gxsb/yMjI/8vLy//N + zc3/zMzM/8nJyf/Hx8f/xMTE/8HBwf+/v7//vLy8/7q6uv+3t7f/tbW1/7Kysv+ysrL/uLi4/6urq/+p + qak/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALa2tp+8vLz/ycnJ/83Nzf/Jycn/xMTE/8fHx//J + ycn/zMzM/8/Pz//R0dH/z8/P/8zMzP/Kysr/x8fH/8XFxf/CwsL/wMDA/729vf+6urr/uLi4/7W1tf+z + s7P/sLCw/66urv+rq6tsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALm5ubbNzc3/1dXV/9TU1P/H + x8f/yMjI/8nJyf/Ly8v/x8fH/7y8vP+pqan/k5OT/35+fv9ra2v/b29v/4+Pj/+lpaX/urq6/8DAwP++ + vr7/u7u7/7i4uP+2trb/s7Oz/7Gxsf+tra2WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL6+vtTY + 2Nj/2NjY/83Nzf+pqan/hYWF/2JiYv9fX1//YGBg/1tbW/9bW1v/VlZW/1BQUP9LS0v/RUVF/0JCQv9D + Q0P/Tk5O/39/f/+fn5//u7u7/7u7u/+5ubn/tra2/7Ozs/+wsLC8AAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAsbGxAsXFxevc3Nz/u7u7/1dXV/9LS0v/XFxc/2NjY/9nZ2f/a2tr/3BwcP90dHT/cXFx/2xsbP9o + aGj/Y2Nj/19fX/9aWlr/VlZW/1FRUf9KSkr/RkZG/3R0dP+kpKT/ubm5/7a2tv+zs7PgAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAubm5FMvLy/nT09P/c3Nz/1xcXP9gYGD/Z2dn/25ubv9zc3P/eHh4/319ff+C + goL/f39//3l5ef90dHT/b29v/2pqav9lZWX/YGBg/1tbW/9XV1f/UFBQ/0VFRf9ISEj/cXFx/7Ozs/+2 + trb2sbGxDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvb29Lc7Ozv+3t7f/bGxs/2pqav9wcHD/dXV1/3p6ev+A + gID/hYWF/4uLi/+QkJD/jIyM/4eHh/+BgYH/e3t7/3Z2dv9wcHD/a2tr/2ZmZv9gYGD/XFxc/1ZWVv9R + UVH/TU1N/4yMjP+5ubn+tLS0JQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwcHBTc7Ozv+hoaH/cHBw/3V1df97 + e3v/gYGB/4eHh/+NjY3/k5OT/5mZmf+enp7/m5ub/5SUlP+Ojo7/iIiI/4GBgf98fHz/dnZ2/3BwcP9q + amr/ZWVl/2BgYP9aWlr/VVVV/4+Pj/+8vLz/t7e3QgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxsbGc7+/v/+b + m5v/enp6/4CAgP+Ghob/jY2N/5OTk/+ampr/oKCg/6enp/+tra3/qqqq/6Kiov+cnJz/lJSU/46Ojv+H + h4f/gYGB/3t7e/90dHT/b29v/2lpaf9jY2P/YGBg/4mJif+/v7//urq6XwAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAycnJnampqf+Xl5f/hYWF/4uLi/+SkpL/mZmZ/6CgoP+np6f/rq6u/7a2tv+8vLz/uLi4/7Gxsf+p + qan/oqKi/5qamv+Tk5P/jIyM/4WFhf9/f3//eHh4/3Jycv9sbGz/iYmJ/4GBgf/CwsL/vLy8dgAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAzc3NzZmZmf+SkpL/kJCQ/5eXl/+fn5//pqam/62trf+1tbX/vb29/8XFxf/M + zMz/yMjI/7+/v/+4uLj/r6+v/6enp/+fn5//mJiY/5GRkf+JiYn/goKC/3x8fP91dXX/i4uL/5GRkf/F + xcX/v7+/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCwsIQzs7O9pCQkP+UlJT/m5ub/6Ojo/+rq6v/s7Oz/7u7u//E + xMT/zMzM/9TU1P/c3Nz/19fX/87Ozv/Gxsb/vb29/7W1tf+srKz/pKSk/5ycnP+UlJT/jY2N/4aGhv9+ + fn7/hISE/6+vr//AwMD/wsLCqgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzMxJwMDA/5aWlv+fn5//pqam/6+vr/+3 + t7f/wMDA/8nJyf/S0tL/29vb/+Tk5P/s7Oz/5+fn/97e3v/V1dX/y8vL/8LCwv+5ubn/sLCw/6ioqP+f + n5//l5eX/5CQkP+Hh4f/hYWF/9TU1P+xsbH/xcXFzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NCTsLCw/52dnf+l + paX/rq6u/7e3t/+/v7//yMjI/9LS0v/c3Nz/5eXl/+/v7//4+Pj/8/Pz/+np6f/f39//1dXV/8zMzP/D + w8P/urq6/7Gxsf+oqKj/oKCg/5iYmP+Pj4//h4eH//Dw8P+lpaX/ycnJ7729vQgAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALe3twHV + 1dXgoKCg/56env+np6f/r6+v/7i4uP/CwsL/y8vL/9TU1P/e3t7/6Ojo//Ly8v/7+/v/9vb2/+vr6//i + 4uL/2NjY/87Ozv/FxcX/vLy8/7Ozs/+qqqr/oqKi/5mZmf+RkZH/iYmJ/+/v7/+mpqb/zMzM/sPDwyYA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAMnJyTXQ0ND/lpaW/56env+np6f/sLCw/7m5uf/CwsL/y8vL/9TU1P/e3t7/6Ojo//Ly8v/7 + +/v/9vb2/+zs7P/i4uL/2NjY/87Ozv/FxcX/vLy8/7Ozs/+qqqr/oqKi/5qamv+RkZH/iYmJ/+vr6//J + ycn/yMjI/8XFxVoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAM7Ozoy+vr7/lpaW/56env+np6f/urq6/7+/v//CwsL/y8vL/9TU1P/e + 3t7/6Ojo//Ly8v/7+/v/9vb2/+vr6//i4uL/2NjY/8/Pz//FxcX/vLy8/7Ozs/+qqqr/oqKi/5qamv+R + kZH/iYmJ/+rq6v/8/Pz/0dHR/8jIyJcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAubm5BdHR0eCqqqr/lpaW/56env/AwMD/5OTk/7m5uf/C + wsL/y8vL/9TU1P/e3t7/6Ojo//Ly8v/7+/v/9vb2/+vr6//i4uL/2NjY/8/Pz//FxcX/vLy8/7Ozs/+q + qqr/oqKi/5qamv+RkZH/iYmJ/+zs7P/+/v7/9/f3/87OztcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAycnJQdbW1v6VlZX/lpaW/8PDw//5 + +fn/vLy8/7i4uP/CwsL/zs7O/93d3f/p6en/8vLy//n5+f/9/f3/+vr6//X19f/w8PD/6urq/+Pj4//Z + 2dn/zs7O/8DAwP/R0dH/2dnZ/8PDw/+srKz/n5+f//T09P/+/v7//v7+/+vr6/69vb0fAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzc3Nn8LCwv+O + jo7/w8PD//7+/v/S0tL/v7+//9TU1P/l5eX/7+/v//Hx8f/y8vL/9PT0//b29v/4+Pj/9fX1//Ly8v/w + 8PD/7e3t/+vr6//p6en/5+fn/+Xl5f/i4uL/5OTk//Hx8f/9/f3//v7+//7+/v/+/v7//v7+//7+/v/U + 1NRqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADB + wcEP0dHR76Ojo/+3t7f//v7+//b29v/a2tr/2NjY/9XV1f/U1NT/1dXV/9fX1//a2tr/3t7e/+Hh4f/j + 4+P/4uLi/+Dg4P/e3t7/29vb/9nZ2f/X19f/1dXV/9PT0//S0tL/0tLS/9LS0v/Y2Nj/7u7u//7+/v/+ + /v7//v7+//7+/v/d3d27AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAADIyMhd0dHR/7y8vP/09PT/+Pj4/7+/v/+5ubn/vLy8/7+/v//CwsL/xsbG/8nJyf/M + zMz/0NDQ/9PT0//V1dX/1NTU/9LS0v/Q0ND/zs7O/8zMzP/Kysr/yMjI/8bGxv/ExMT/wsLC/8DAwP++ + vr7/vLy8/8rKyv/z8/P//v7+//7+/v/g4OD3v7+/GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLy8u+0NDQ/7S0tP/j4+P/vLy8/6mpqf+srKz/r6+v/7Kysv+1 + tbX/uLi4/7u7u/+/v7//wsLC/8XFxf/Hx8f/xsbG/8TExP/CwsL/wMDA/7+/v/+9vb3/u7u7/7m5uf+3 + t7f/tra2/7S0tP+ysrL/sLCw/66urv+wsLD/4uLi//7+/v/h4eH/zMzMagAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwCHQ0ND9paWl/5SUlP+oqKj/mZmZ/52dnf+f + n5//oqKi/6Wlpf+oqKj/q6ur/66urv+2trb/ubm5/8LCwv/Gxsb/ubm5/7a2tv+1tbX/uLi4/83Nzf/I + yMj/x8fH/76+vv+tra3/qamp/6enp/+mpqb/pKSk/6Kiov+goKD/oKCg/93d3f/d3d3/z8/Pxra2tgEA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjIyHzPz8//jIyM/4iIiP+L + i4v/np6e/7m5uf+tra3/np6e/5ycnP/CwsL/y8vL/8LCwv/y8vL/8/Pz//Pz8//6+vr/6Ojo/8LCwv+3 + t7f/5OTk//v7+//7+/v//Pz8//r6+v/r6+v/vr6+/93d3f/c3Nz/u7u7/5mZmf+VlZX/lJSU/5ubm//J + ycn/1NTU/MnJySsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7u7A8rKytfQ + 0ND/rKys/35+fv+CgoL/o6Oj//39/f/7+/v/9fX1//Ly8v/6+vr///////v7+//9/f3//f39//7+/v// + //////////39/f/29vb/7+/v//v7+//+/v7//v7+//7+/v/+/v7//Pz8//7+/v/+/v7//f39/9LS0v+U + lJT/jY2N/5SUlP/Ly8v/1dXV/9HR0Y0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAwsLCN83Nzf7f39//6urq/+Tk5P/q6ur/8PDw//r6+v/+/v7/4eHh/+fn5//g4OD/1tbW/9DQ0P/L + y8v/y8vL/87Ozv/a2tr/9fX1//Dw8P/U1NT/x8fH/8zMzP/Ly8v/1dXV//v7+//+/v7/8vLy/93d3f/h + 4eH//Pz8//7+/v/29vb/8fHx/+rq6v/Y2Nj/4eHh/+rq6uzQ0NALAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAyMjIjNvb2//r6+v/+/v7//z8/P/8/Pz//Pz8//z8/P/o6Oj/urq6/7q6uv+7 + u7v/vLy8/729vf+/v7//wMDA/8HBwf/CwsL/wsLC/8HBwf/AwMD/wMDA/8DAwP+/v7//v7+//8nJyf/E + xMT/vr6+/729vf++vr7/2NjY//Pz8//9/f3/+Pj4//j4+P/39/f/+vr6//r6+v/Ozs5ZAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAOTk5ATm5uZA4+Pj5Pv7+//7+/v/+Pj4/+7u7v/t7e3/7u7u//Dw8P/x + 8fH/7e3t/+Li4v/Y2Nj/0NDQ/8nJyf/ExMT/v7+//76+vv+9vb3/vLy8/7y8vP+8vLz/vLy8/729vf/A + wMD/xcXF/8vLy//S0tL/2tra/+Li4v/r6+v/6+vr/+np6f/q6ur/8vLy/+zs7P/9/f3//v7+//7+/v/u + 7u7P6+vrlurq6igAAAAAAAAAAAAAAAAAAAAAAAAAAOjo6Hj29vb/9vb2/+np6f/p6en/6urq/+vr6//t + 7e3/7u7u//Dw8P/x8fH/8/Pz//T09P/29vb/9/f3//n5+f/7+/v//Pz8//z8/P/7+/v/+Pj4//b29v/2 + 9vb/9fX1//b29v/19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6+vr/+np6f/n5+f/6Ojo/+fn5//3 + 9/f/+Pj4//39/f/+/v7//v7+//j4+LUAAAAAAAAAAAAAAAAAAAAAAAAAAPHx8YX+/v7/7u7u/+fn5//o + 6Oj/6urq/+vr6//t7e3/7u7u//Dw8P/x8fH/8/Pz//T09P/29vb/9/f3//n5+f/7+/v//Pz8//7+/v/+ + /v7//f39//v7+//6+vr/+Pj4//f39//19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6urq/+np6f/n + 5+f/5ubm/+fn5//39/f/6+vr//Hx8f/+/v7//v7+//j4+OPv7+8UAAAAAAAAAAAAAAAAAAAAAPDw8GT9 + /f3/8vLy/+7u7v/r6+v/6urq/+vr6//t7e3/7u7u//Dw8P/x8fH/8/Pz//T09P/29vb/9/f3//n5+f/7 + +/v//Pz8//7+/v/+/v7//f39//v7+//6+vr/+Pj4//f39//19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s + 7Oz/6urq/+np6f/n5+f/5ubm/+fn5//x8fH/6+vr//39/f/+/v7//f394/j4+Gnx8fEJAAAAAAAAAAAA + AAAAAAAAAOnp6Tf+/v7/+fn5//X19f/v7+//6urq/+vr6//t7e3/7+/v//Dw8P/x8fH/8/Pz//T09P/2 + 9vb/9/f3//n5+f/7+/v//Pz8//7+/v/+/v7//f39//v7+//6+vr/+Pj4//f39//19fX/8/Pz//Ly8v/w + 8PD/7+/v/+7u7v/s7Oz/6urq/+np6f/n5+f/5ubm/+fn5//q6ur/+Pj4//7+/v/+/v75+vr6LAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAOTk5AT7+/uV8PDw0Ovr6//o6Oj/6urq/+vr6//t7e3/7+/v//Dw8P/x + 8fH/8/Pz//T09P/29vb/+Pj4//n5+f/7+/v//Pz8//7+/v/+/v7//f39//v7+//6+vr/+Pj4//f39//1 + 9fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6urq/+np6f/n5+f/5ubm/+bm5v/n5+f/6+vr//r6+vz6 + +vq47OzsDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8fHxcP7+/v/6+vr/6enp/+rq6v/s + 7Oz/7+/v//Dw8P/x8fH/8/Pz//T09P/29vb/+Pj4//n5+f/7+/v//Pz8//7+/v/+/v7//f39//v7+//6 + +vr/+Pj4//b29v/19fX/8/Pz//Ly8v/w8PD/7+/v/+7u7v/s7Oz/6enp/+rq6v/v7+//9fX1//n5+f/9 + /f3//f398/f393gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9/f3C/n5+Xn6 + +vrs+fn5//n5+f/19fX/7u7u/+vr6//w8PD/8/Pz//T09P/29vb/9fX1//j4+P/7+/v//Pz8//7+/v/+ + /v7//f39//v7+//6+vr/+Pj4//b29v/19fX/8/Pz/+7u7v/r6+v/6+vr/+rq6v/p6en/9/f3//7+/v/+ + /v7//v7+//z8/O/6+vp27u7uFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAADz8/Mu+Pj4R/j4+Ej6+vqd9vb2+fr6+v/29vb/8vLy//Dw8P/u7u7/8fHx//X19f/4 + +Pj//Pz8//7+/v/+/v7//f39//r6+v/29vb/9PT0//Ly8v/y8vL/7u7u//j4+P/8/Pz//f39//39/f/7 + +/v//v7+//7+/v/+/v7//f394+/v7zMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2K/z8/Mr+/v7//v7+//////// + ///////////////5+fn/8vLy//Pz8//09PT/8vLy/+7u7v/29vb/9vb2//f39//39/f/+fn5//7+/v/+ + /v7//v7+//7+/v/6+vqU8/PzPPLy8i/y8vI58vLyJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDw8An0 + 9PQx9PT0MPn5+Wv7+/vZ/////////////////v7+//39/f/8/Pz//f39//7+/v/+/v7//v7+//7+/v/+ + /v7+/Pz81Pn5+WT29vY29/f3O/j4+Enz8/MfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADu7u4H9/f3RPb29jz4+Pgt+fn5X/v7+675+fmv+/v74vr6+q77 + +/uO+vr6tPj4+Jv19fUe8PDwAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AD//9Pz//+AAD//0/P//gAAD//T8// + 8AAAH/9Pz//gAAAP/0/P/+AAAA//T8//4AAAD/9Pz//gAAAH/0/P/+AAAAf/T8//4AAAB/9Pz//gAAAH + /0/P/+AAAAf/T8//wAAAB/9Pz//AAAAD/0/P/8AAAAP/T8//wAAAA/9Pz//AAAAD/0/P/8AAAAP/T8// + wAAAA/9Pz/+AAAAD/0/P/4AAAAP/T8//gAAAAf9Pz/8AAAAB/0/P/wAAAAH/T8//AAAAAf9Pz/4AAAAB + /0/P/gAAAAD/T8/+AAAAAP9Pz/wAAAAA/0/P/AAAAAB/T8/8AAAAAH9Pz/gAAAAAP0/P+AAAAAA/T8/w + AAAAAD9Pz/AAAAAAH0/P8AAAAAAfT8/AAAAAAAdPz8AAAAAAB0/PwAAAAAADT8/AAAAAAANPz8AAAAAA + D0/PwAAAAAAPT8/wAAAAAD9Pz/AAAAAAf0/P/AAAAAH/T8//wAAAA/9Pz//gAAA//0/P//4AB///T88o + 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 + u7v/wMDALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMvLy8Sb + m5v/qKio/7W1tf/CwsL/0NDQ/9/f3//t7e3/+Pj4/+zs7P/e3t7/z8/P/8HBwf+0tLT/p6en/5qamv+O + jo7/zc3N/7Kysv/GxsZXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJ + yckYv7+//JycnP+pqan/tra2/8TExP/S0tL/4eHh/+/v7//6+vr/7u7u/+Dg4P/R0dH/w8PD/7a2tv+o + qKj/nJyc/4+Pj//Kysr/wcHB/8jIyIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAM/Pz2ytra3/nJyc/7Gxsf/ExMT/xMTE/9LS0v/h4eH/7+/v//r6+v/u7u7/4ODg/9HR0f/D + w8P/tbW1/6ioqP+cnJz/j4+P/8nJyf/19fX/zs7OxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAA0tLSxpiYmP+tra3/5ubm/7i4uP/ExMT/19fX/+jo6P/19fX//Pz8//T09P/q + 6ur/3t7e/9DQ0P+/v7//xsbG/7q6uv+goKD/09PT///////r6+v6vr6+DgAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAMbGxiXDw8P+pKSk//b29v/R0dH/1tbW/+Tk5P/p6en/7Ozs//Dw8P/y + 8vL/7u7u/+rq6v/n5+f/5OTk/+Hh4f/e3t7/5+fn//f39/////////////7+/v/Z2dlUAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzc3NhLy8vP/v7+//3Nzc/8LCwv/CwsL/x8fH/8zMzP/R + 0dH/1tbW/9jY2P/W1tb/09PT/9DQ0P/Nzc3/ysrK/8fHx//ExMT/w8PD/9bW1v/6+vr//////9zc3KcA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALa2tgLOzs7hsLCw/87Ozv+mpqb/qamp/66urv+z + s7P/t7e3/7y8vP/BwcH/w8PD/8HBwf++vr7/vb29/7q6uv+3t7f/tLS0/7Gxsf+urq7/rKys/7Ozs//w + 8PD/29vb9MTExAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx8fHQ729vf+Kior/j4+P/6ysrP+l + paX/nZ2d/7y8vP+7u7v/39/f/+Pj4//n5+f/w8PD/7y8vP/t7e3/8PDw/+3t7f/Ozs7/wcHB/8TExP+g + oKD/l5eX/6SkpP/Q0ND/zs7OYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKysqg0dHR/6CgoP+g + oKD/6+vr//v7+//09PT/+vr6//Pz8//v7+//8PDw//v7+//+/v7/7Ozs/+np6f/x8fH//f39///////7 + +/v//f39/+rq6v+wsLD/qqqq/9DQ0P/W1tbEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAubm5CNLS0vHt + 7e3/+/v7//z8/P/9/f3/39/f/8LCwv++vr7/v7+//8HBwf/CwsL/xsbG/8/Pz//CwsL/wcHB/8HBwf/R + 0dH/1NTU/8LCwv/Kysr/9PT0//7+/v/4+Pj/7+/v//n5+f/Pz88tAAAAAAAAAAAAAAAAAAAAAOXl5Rjp + 6eme8/Pz//T09P/v7+//7e3t//Dw8P/x8fH/6urq/+Hh4f/a2tr/1dXV/9LS0v/Q0ND/zs7O/87Ozv/P + z8//09PT/9fX1//d3d3/5eXl/+vr6//p6en/7e3t/+rq6v/8/Pz///////Pz89Ly8vJzAAAAAAAAAAAA + AAAA7+/vWv39/f/n5+f/6enp/+vr6//t7e3/8PDw//Ly8v/09PT/9vb2//n5+f/7+/v//f39//7+/v/8 + /Pz/+fn5//f39//19fX/8vLy//Dw8P/u7u7/7Ozs/+np6f/n5+f/5+fn//T09P/y8vL///////v7++fv + 7+8JAAAAAAAAAADv7+88+/v7//T09P/t7e3/6+vr/+3t7f/w8PD/8vLy//T09P/29vb/+fn5//v7+//9 + /f3//v7+//z8/P/5+fn/9/f3//X19f/y8vL/8PDw/+7u7v/s7Oz/6enp/+fn5//n5+f/7+/v//r6+v/+ + /v7w+vr6XfLy8gQAAAAAAAAAAOfn5wv7+/u76+vr/+jo6P/r6+v/7e3t//Dw8P/y8vL/9PT0//b29v/5 + +fn/+/v7//39/f/+/v7//Pz8//n5+f/39/f/9fX1//Ly8v/w8PD/7u7u/+zs7P/p6en/5+fn/+bm5v/p + 6en/+Pj4/vr6+pMAAAAAAAAAAAAAAAAAAAAAAAAAAOfn5wL6+vrW9fX1/+zs7P/u7u7/8PDw//Ly8v/0 + 9PT/9vb2//n5+f/7+/v//f39//7+/v/8/Pz/+fn5//f39//19fX/8vLy//Dw8P/u7u7/6+vr/+/v7//1 + 9fX/+vr6//z8/OL4+PhqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLy8gX5+fl1/Pz8gfj4+NHz + 8/P/8/Pz//Ly8v/w8PD/9fX1//r6+v/9/f3//v7+//v7+//39/f/9PT0//Ly8v/y8vL/9fX1//b29v/4 + +Pj////////////4+PiR+Pj4BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAA9/f3Avr6+m/8/PzK/f394///////////+fn5//b29v/19fX/9PT0//n5+f/5+fn/+fn5//39/fH8 + /PzP/f392Pj4+F/x8fEh8/PzJ+zs7AIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADt7e0D+Pj4VPv7+4H7+/t5/Pz8vPv7+9L8/PzY/Pz8ufv7+8X6 + +vpf9fX1EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AB/// + gAH//wAA//4AAP/+AAB//gAAf/4AAH/+AAB//gAAf/4AAH/+AAB//AAAf/wAAD/8AAA//AAAP/gAAD/4 + AAA/+AAAH/AAAB/wAAAf4AAAD+AAAA/gAAAPwAAAB4AAAAOAAAABgAAAAYAAAAfAAAAP4AAAH/wAAD// + gA//KAAAABgAAAAwAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACqqqoMq6urb66ursGysrLusLCw/KysrPKpqanKpaWlh6WlpSsAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKioqEOvr6/jtbW1/7m5uf+6 + urr/urq6/7m5uf+3t7f/tra2/62trf2jo6Omo6OjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAArKysD7a2tvrBwcH/wMDA/76+vv/AwMD/v7+//7y8vP+4uLj/s7Oz/7CwsP+t + ra3/pKSkqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr6+vL7y8vP/E + xMT/xMTE/8XFxf/IyMj/xsbG/8PDw//BwcH/wMDA/8DAwP+8vLz/q6ur86urqwQAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtLS0Sb6+vv/ExMT/xMTE/8nJyf/Ozs7/zMzM/8fHx//C + wsL/vb29/7i4uP+zs7P/sLCw/6qqqisAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAvLy8Y9XV1f/ExMT/np6e/5SUlP+Hh4f/bm5u/1tbW/9ubm7/kpKS/7W1tf+5ubn/s7Oz/6+vr1UA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxsbGf7e3t/9YWFj/ZWVl/29vb/95 + eXn/dXV1/2xsbP9iYmL/WVlZ/05OTv9paWn/paWl/7S0tHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAysrKno2Njf9zc3P/fn5+/4mJif+UlJT/kZGR/4SEhP95eXn/bm5u/2NjY/9Y + WFj/b29v/7m5uZkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvLy8xIyMjP+J + iYn/lpaW/6SkpP+ysrL/ra2t/5+fn/+RkZH/g4OD/3Z2dv9qamr/fX19/7+/v7UAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/v78EsLCw8JSUlP+hoaH/sLCw/8DAwP/Q0ND/y8vL/7q6uv+q + qqr/mpqa/4uLi/99fX3/lJSU/8LCws4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADP + z883qamp/6ampv+3t7f/ycnJ/9vb2//u7u7/6Ojo/9XV1f/Dw8P/sbGx/6CgoP+QkJD/tLS0/7i4uO69 + vb0CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NCFnZ2d/6urq/+9vb3/z8/P/+Pj4//2 + 9vb/8fHx/93d3f/Kysr/uLi4/6ampv+VlZX/u7u7/8HBwf/ExMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALm5uQHAwMDampqa/8HBwf+/v7//0NDQ/+Pj4//29vb/8fHx/93d3f/Kysr/uLi4/6ampv+V + lZX/urq6//Hx8f/Nzc1bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzDiurq7/xsbG/9LS0v/N + zc3/4+Pj//Dw8P/5+fn/9vb2/+7u7v/k5OT/1tbW/9zc3P/X19f/5OTk///////q6uqiAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAM7OzpfCwsL/6+vr/8rKyv/Ly8v/z8/P/9XV1f/b29v/2tra/9bW1v/S + 0tL/zs7O/8vLy//Kysr/3d3d//z8/P/v7+/sv7+/BgAAAAAAAAAAAAAAAAAAAAAAAAAAwMDACMTExO61 + tbX/p6en/6enp/+tra3/s7Oz/7y8vP/FxcX/vr6+/7y8vP/ExMT/vr6+/7Gxsf+tra3/qamp/7W1tf/m + 5ub/zs7OTAAAAAAAAAAAAAAAAAAAAAAAAAAAycnJVra2tv+FhYX/vr6+/8/Pz//S0tL/4uLi//j4+P/6 + +vr/6enp/+Dg4P/8/Pz//f39/+np6f/t7e3/ycnJ/5KSkv+xsbH/0tLSrQAAAAAAAAAAAAAAAAAAAAAA + AAAAz8/PsOzs7P/x8fH/+fn5/+Dg4P/Pz8//yMjI/8XFxf/Ly8v/2tra/8fHx//Gxsb/1tbW/9zc3P/O + zs7/8fHx//f39//s7Oz/8PDw+s/PzxkAAAAAAAAAAAAAAADv7+9v7+/v+PHx8f/t7e3/7+/v//Dw8P/p + 6en/4uLi/97e3v/c3Nz/2tra/9nZ2f/a2tr/3d3d/+Pj4//q6ur/6urq/+vr6//y8vL//f39//b29tn0 + 9PQ3AAAAAAAAAAD5+fm67e3t/+rq6v/s7Oz/7+/v//Ly8v/19fX/+Pj4//v7+//+/v7//Pz8//n5+f/2 + 9vb/8/Pz//Dw8P/t7e3/6urq/+fn5//t7e3/8fHx//7+/vj39/daAAAAAAAAAAD5+fl08vLy8+vr6//s + 7Oz/7+/v//Ly8v/19fX/+Pj4//v7+//+/v7//Pz8//n5+f/29vb/8/Pz//Dw8P/t7e3/6urq/+fn5//o + 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 + + + \ No newline at end of file diff --git a/TequilaPC/TequilaPC.csproj b/TequilaPC/TequilaPC.csproj new file mode 100644 index 0000000..a7fd8a6 --- /dev/null +++ b/TequilaPC/TequilaPC.csproj @@ -0,0 +1,161 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {18DD5C84-F8F4-4EBA-B2B5-5EA31D57C162} + WinExe + Properties + Tequila + tequila + v3.5 + + + 512 + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 7 + 1.0.0.7 + false + true + true + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Resources\tequila.ico + + + 59D9AD13731F0CA2776520BB4CB109298D08B8AD + + + TequilaPC_TemporaryKey.pfx + + + false + + + false + + + LocalIntranet + + + Properties\app.manifest + + + + + + + + + + + + + + + + + + + + + + + + Form + + + Preferences.cs + + + Form + + + Tequila.cs + + + + + + Preferences.cs + + + Tequila.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + False + Microsoft .NET Framework 4 Client Profile %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/TequilaPC/app.config b/TequilaPC/app.config new file mode 100644 index 0000000..53bdd04 --- /dev/null +++ b/TequilaPC/app.config @@ -0,0 +1,15 @@ + + + + +
+ + + + + + + + + +